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