iscontrol.c revision 171568
1193323Sed/*-
2193323Sed * Copyright (c) 2005 Daniel Braniss <danny@cs.huji.ac.il>
3193323Sed * All rights reserved.
4193323Sed *
5193323Sed * Redistribution and use in source and binary forms, with or without
6193323Sed * modification, are permitted provided that the following conditions
7193323Sed * are met:
8193323Sed * 1. Redistributions of source code must retain the above copyright
9193323Sed *    notice, this list of conditions and the following disclaimer.
10193323Sed * 2. Redistributions in binary form must reproduce the above copyright
11193323Sed *    notice, this list of conditions and the following disclaimer in the
12193323Sed *    documentation and/or other materials provided with the distribution.
13193323Sed *
14193323Sed * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15193323Sed * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16193323Sed * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17218893Sdim * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18239462Sdim * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19239462Sdim * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20193323Sed * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21193323Sed * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22193323Sed * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23239462Sdim * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24193323Sed * SUCH DAMAGE.
25193323Sed *
26218893Sdim */
27193323Sed/*
28193323Sed | $Id: iscontrol.c,v 2.2 2006/12/01 09:11:56 danny Exp danny $
29198090Srdivacky */
30193323Sed/*
31221345Sdim | the user level initiator (client)
32239462Sdim */
33193323Sed
34193323Sed#include <sys/cdefs.h>
35193323Sed__FBSDID("$FreeBSD: head/sbin/iscontrol/iscontrol.c 171568 2007-07-24 15:35:02Z scottl $");
36193323Sed
37193323Sed#include <sys/param.h>
38198090Srdivacky#include <sys/types.h>
39218893Sdim#include <sys/socket.h>
40193323Sed#include <sys/sysctl.h>
41193323Sed
42218893Sdim#include <netinet/in.h>
43193323Sed#include <netinet/tcp.h>
44193323Sed#include <arpa/inet.h>
45193323Sed#include <sys/ioctl.h>
46193323Sed#include <netdb.h>
47239462Sdim#include <stdlib.h>
48193323Sed#include <unistd.h>
49193323Sed#include <stdio.h>
50193323Sed#include <string.h>
51193323Sed#include <errno.h>
52193323Sed#include <fcntl.h>
53193323Sed#include <time.h>
54193323Sed#include <camlib.h>
55193323Sed
56193323Sed#include "iscsi.h"
57226633Sdim#include "iscontrol.h"
58193323Sed//#include "pdu.h"
59193323Sed
60193323Sed#define USAGE "[-v] [-d] [-c config] [-n name] [-t target] "
61239462Sdim#define OPTIONS	"vdc:t:n:"
62193323Sed
63193323Sed#ifndef DEBUG
64193323Sed//int	vflag;
65193323Sed#endif
66193323Sed
67193323Sedtoken_t AuthMethods[] = {
68193323Sed     {"None",	NONE},
69193323Sed     {"KRB5",	KRB5},
70193323Sed     {"SPKM1",	SPKM1},
71193323Sed     {"SPKM2",	SPKM2},
72193323Sed     {"SRP",	SRP},
73193323Sed     {"CHAP",	CHAP},
74193323Sed     {0}
75218893Sdim};
76218893Sdim
77218893Sdimtoken_t	DigestMethods[] = {
78218893Sdim     {"None",	0},
79218893Sdim     {"CRC32",	1},
80239462Sdim     {"CRC32C",	1},
81218893Sdim     {0}
82218893Sdim};
83218893Sdim
84218893Sdimu_char	isid[6 + 6];
85218893Sdim/*
86218893Sdim | Default values
87218893Sdim */
88218893Sdimisc_opt_t opvals = {
89218893Sdim     .port			= 3260,
90218893Sdim     .sockbufsize		= 128,
91218893Sdim     .iqn			= "iqn.2005-01.il.ac.huji.cs:",
92218893Sdim
93218893Sdim     .sessionType		= "Normal",
94239462Sdim     .targetAddress		= 0,
95193323Sed     .targetName		= 0,
96193323Sed     .initiatorName		= 0,
97193323Sed     .authMethod		= "None",
98193323Sed     .headerDigest		= "None,CRC32C",
99193323Sed     .dataDigest		= "None,CRC32C",
100193323Sed     .maxConnections		= 1,
101193323Sed     .maxRecvDataSegmentLength	= 64 * 1024,
102239462Sdim     .maxXmitDataSegmentLength	= 8 * 1024, // 64 * 1024,
103193323Sed     .maxBurstLength		= 128 * 1024,
104193323Sed     .firstBurstLength		= 64 * 1024, // must be less than maxBurstLength
105193323Sed     .defaultTime2Wait		= 0,
106193323Sed     .defaultTime2Retain	= 0,
107193323Sed     .maxOutstandingR2T		= 1,
108193323Sed     .errorRecoveryLevel	= 0,
109193323Sed
110193323Sed     .dataPDUInOrder		= TRUE,
111193323Sed     .dataSequenceInOrder	= TRUE,
112239462Sdim
113193323Sed     .initialR2T		= TRUE,
114193323Sed     .immediateData		= TRUE,
115193323Sed};
116193323Sed
117193323Sedint
118193323Sedlookup(token_t *tbl, char *m)
119193323Sed{
120193323Sed     token_t	*tp;
121193323Sed
122193323Sed     for(tp = tbl; tp->name != NULL; tp++)
123193323Sed	  if(strcasecmp(tp->name, m) == 0)
124193323Sed	       return tp->val;
125193323Sed     return 0;
126193323Sed}
127193323Sed
128193323Sedint
129193323Sedmain(int cc, char **vv)
130193323Sed{
131239462Sdim     int	ch, disco;
132193323Sed     char	*pname, *p, *ta, *kw;
133193323Sed     isc_opt_t	*op;
134193323Sed     FILE	*fd;
135193323Sed
136193323Sed     op = &opvals;
137239462Sdim     iscsidev = "/dev/"ISCSIDEV;
138193323Sed     fd = NULL;
139193323Sed     pname = vv[0];
140239462Sdim     if((p = strrchr(pname, '/')) != NULL)
141193323Sed	  pname = p + 1;
142218893Sdim
143239462Sdim     kw = ta = 0;
144193323Sed     disco = 0;
145193323Sed
146193323Sed     while((ch = getopt(cc, vv, OPTIONS)) != -1) {
147193323Sed	  switch(ch) {
148193323Sed	  case 'v':
149193323Sed	       vflag++;
150234353Sdim	       break;
151234353Sdim	  case 'c':
152218893Sdim	       fd = fopen(optarg, "r");
153218893Sdim	       if(fd == NULL) {
154218893Sdim		    perror(optarg);
155239462Sdim		    exit(1);
156218893Sdim	       }
157218893Sdim	       break;
158218893Sdim	  case 'd':
159218893Sdim	       disco = 1;
160218893Sdim	       break;
161239462Sdim	  case 't':
162193323Sed	       ta = optarg;
163193323Sed	       break;
164218893Sdim	  case 'n':
165239462Sdim	       kw = optarg;
166193323Sed	       break;
167193323Sed	  default:
168193323Sed	  badu:
169193323Sed	       fprintf(stderr, "Usage: %s %s\n", pname, USAGE);
170193323Sed	       exit(1);
171193323Sed	  }
172193323Sed     }
173193323Sed     if(fd == NULL)
174193323Sed	  fd = fopen("/etc/iscsi.conf", "r");
175193323Sed
176193323Sed     if(fd != NULL) {
177193323Sed	  parseConfig(fd, kw, op);
178239462Sdim	  fclose(fd);
179193323Sed     }
180193323Sed     cc -= optind;
181239462Sdim     vv += optind;
182193323Sed     if(cc > 0) {
183193323Sed	  if(vflag)
184193323Sed	       printf("adding '%s'\n", *vv);
185193323Sed	  parseArgs(cc, vv, op);
186239462Sdim     }
187193323Sed     if(ta)
188193323Sed	  op->targetAddress = ta;
189193323Sed
190193323Sed     if(op->targetAddress == NULL) {
191193323Sed	  fprintf(stderr, "No target!\n");
192193323Sed	  goto badu;
193193323Sed     }
194193323Sed     if((p = strchr(op->targetAddress, ':')) != NULL) {
195218893Sdim	  *p++ = 0;
196193323Sed	  op->port = atoi(p);
197218893Sdim	  p = strchr(p, ',');
198239462Sdim     }
199193323Sed     if(p || ((p = strchr(op->targetAddress, ',')) != NULL)) {
200193323Sed	  *p++ = 0;
201193323Sed	  op->targetPortalGroupTag = atoi(p);
202193323Sed     }
203239462Sdim     if(op->initiatorName == 0) {
204218893Sdim	  char	hostname[256];
205218893Sdim
206218893Sdim	  if(op->iqn) {
207218893Sdim	       if(gethostname(hostname, sizeof(hostname)) == 0)
208218893Sdim		    asprintf(&op->initiatorName, "%s:%s", op->iqn, hostname);
209218893Sdim	       else
210218893Sdim		    asprintf(&op->initiatorName, "%s:%d", op->iqn, (int)time(0) & 0xff); // XXX:
211218893Sdim	  }
212218893Sdim	  else {
213239462Sdim	       if(gethostname(hostname, sizeof(hostname)) == 0)
214218893Sdim		    asprintf(&op->initiatorName, "%s", hostname);
215218893Sdim	       else
216218893Sdim		    asprintf(&op->initiatorName, "%d", (int)time(0) & 0xff); // XXX:
217239462Sdim	  }
218218893Sdim     }
219218893Sdim     if(disco) {
220218893Sdim	  op->sessionType = "Discovery";
221218893Sdim	  op->targetName = 0;
222239462Sdim     }
223218893Sdim
224218893Sdim     fsm(op);
225218893Sdim
226193323Sed     exit(0);
227239462Sdim}
228193323Sed