1171568Sscottl /*- 2211095Sdes * Copyright (c) 2005-2009 Daniel Braniss <danny@cs.huji.ac.il> 3171568Sscottl * All rights reserved. 4171568Sscottl * 5171568Sscottl * Redistribution and use in source and binary forms, with or without 6171568Sscottl * modification, are permitted provided that the following conditions 7171568Sscottl * are met: 8171568Sscottl * 1. Redistributions of source code must retain the above copyright 9171568Sscottl * notice, this list of conditions and the following disclaimer. 10171568Sscottl * 2. Redistributions in binary form must reproduce the above copyright 11171568Sscottl * notice, this list of conditions and the following disclaimer in the 12171568Sscottl * documentation and/or other materials provided with the distribution. 13171568Sscottl * 14171568Sscottl * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15171568Sscottl * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16171568Sscottl * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17171568Sscottl * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18171568Sscottl * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19171568Sscottl * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20171568Sscottl * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21171568Sscottl * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22171568Sscottl * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23171568Sscottl * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24171568Sscottl * SUCH DAMAGE. 25171568Sscottl * 26171568Sscottl */ 27171568Sscottl/* 28171568Sscottl | $Id: config.c,v 2.1 2006/11/12 08:06:51 danny Exp danny $ 29171568Sscottl */ 30171568Sscottl 31171568Sscottl#include <sys/cdefs.h> 32171568Sscottl__FBSDID("$FreeBSD$"); 33171568Sscottl 34171568Sscottl#include <stdlib.h> 35171568Sscottl#include <unistd.h> 36171568Sscottl#include <stdio.h> 37171568Sscottl#include <string.h> 38171568Sscottl#include <errno.h> 39171568Sscottl#include <fcntl.h> 40171568Sscottl#include <time.h> 41171568Sscottl#include <ctype.h> 42171568Sscottl#include <camlib.h> 43171568Sscottl 44211095Sdes#include <dev/iscsi/initiator/iscsi.h> 45171568Sscottl#include "iscontrol.h" 46171568Sscottl 47171568Sscottl/* 48171568Sscottl | ints 49171568Sscottl */ 50171568Sscottl#define OPT_port 1 51171568Sscottl#define OPT_tags 2 52171568Sscottl 53171568Sscottl#define OPT_maxConnections 3 54171568Sscottl#define OPT_maxRecvDataSegmentLength 4 55171568Sscottl#define OPT_maxXmitDataSegmentLength 5 56171568Sscottl#define OPT_maxBurstLength 6 57171568Sscottl#define OPT_firstBurstLength 7 58171568Sscottl#define OPT_defaultTime2Wait 8 59171568Sscottl#define OPT_defaultTime2Retain 9 60171568Sscottl#define OPT_maxOutstandingR2T 10 61171568Sscottl#define OPT_errorRecoveryLevel 11 62171568Sscottl#define OPT_targetPortalGroupTag 12 63171568Sscottl#define OPT_headerDigest 13 64171568Sscottl#define OPT_dataDigest 14 65171568Sscottl/* 66171568Sscottl | Booleans 67171568Sscottl */ 68171568Sscottl#define OPT_initialR2T 16 69171568Sscottl#define OPT_immediateData 17 70171568Sscottl#define OPT_dataPDUInOrder 18 71171568Sscottl#define OPT_dataSequenceInOrder 19 72171568Sscottl/* 73171568Sscottl | strings 74171568Sscottl */ 75171568Sscottl#define OPT_sessionType 15 76171568Sscottl 77171568Sscottl#define OPT_targetAddress 21 78171568Sscottl#define OPT_targetAlias 22 79171568Sscottl#define OPT_targetName 23 80171568Sscottl#define OPT_initiatorName 24 81171568Sscottl#define OPT_initiatorAlias 25 82171568Sscottl#define OPT_authMethod 26 83171568Sscottl 84171568Sscottl#define OPT_chapSecret 27 85171568Sscottl#define OPT_chapIName 28 86171568Sscottl#define OPT_chapDigest 29 87171568Sscottl#define OPT_tgtChapName 30 88171568Sscottl#define OPT_tgtChapSecret 31 89171568Sscottl#define OPT_tgtChallengeLen 32 90171568Sscottl/* 91171568Sscottl | private 92171568Sscottl */ 93171568Sscottl#define OPT_maxluns 33 94171568Sscottl#define OPT_iqn 34 95171568Sscottl#define OPT_sockbufsize 35 96171568Sscottl 97211095Sdes/* 98211095Sdes | sentinel 99211095Sdes */ 100211095Sdes#define OPT_end 0 101211095Sdes 102171568Sscottl#define _OFF(v) ((int)&((isc_opt_t *)NULL)->v) 103171568Sscottl#define _E(u, s, v) {.usage=u, .scope=s, .name=#v, .tokenID=OPT_##v} 104171568Sscottl 105171568Sscottltextkey_t keyMap[] = { 106171568Sscottl _E(U_PR, S_PR, port), 107171568Sscottl _E(U_PR, S_PR, tags), 108171568Sscottl _E(U_PR, S_PR, maxluns), 109171568Sscottl _E(U_PR, S_PR, sockbufsize), 110171568Sscottl 111171568Sscottl _E(U_PR, S_PR, iqn), 112171568Sscottl _E(U_PR, S_PR, chapSecret), 113171568Sscottl _E(U_PR, S_PR, chapIName), 114171568Sscottl _E(U_PR, S_PR, chapDigest), 115171568Sscottl _E(U_PR, S_PR, tgtChapName), 116171568Sscottl _E(U_PR, S_PR, tgtChapSecret), 117171568Sscottl _E(U_PR, S_PR, tgtChallengeLen), 118171568Sscottl 119171568Sscottl _E(U_IO, S_CO, headerDigest), 120171568Sscottl _E(U_IO, S_CO, dataDigest), 121171568Sscottl 122171568Sscottl _E(U_IO, S_CO, authMethod), 123171568Sscottl 124171568Sscottl _E(U_LO, S_SW, maxConnections), 125171568Sscottl _E(U_IO, S_SW, targetName), 126171568Sscottl 127171568Sscottl _E(U_IO, S_SW, initiatorName), 128171568Sscottl _E(U_ALL,S_SW, targetAlias), 129171568Sscottl _E(U_ALL,S_SW, initiatorAlias), 130171568Sscottl _E(U_ALL,S_SW, targetAddress), 131171568Sscottl 132171568Sscottl _E(U_ALL,S_SW, targetPortalGroupTag), 133171568Sscottl 134171568Sscottl _E(U_LO, S_SW, initialR2T), 135171568Sscottl _E(U_LO, S_SW, immediateData), 136171568Sscottl 137171568Sscottl _E(U_ALL,S_CO, maxRecvDataSegmentLength), 138171568Sscottl _E(U_ALL,S_CO, maxXmitDataSegmentLength), 139171568Sscottl 140171568Sscottl _E(U_LO, S_SW, maxBurstLength), 141171568Sscottl _E(U_LO, S_SW, firstBurstLength), 142171568Sscottl _E(U_LO, S_SW, defaultTime2Wait), 143171568Sscottl _E(U_LO, S_SW, defaultTime2Retain), 144171568Sscottl 145171568Sscottl _E(U_LO, S_SW, maxOutstandingR2T), 146171568Sscottl _E(U_LO, S_SW, dataPDUInOrder), 147171568Sscottl _E(U_LO, S_SW, dataSequenceInOrder), 148171568Sscottl 149171568Sscottl _E(U_LO, S_SW, errorRecoveryLevel), 150171568Sscottl 151171568Sscottl _E(U_LO, S_SW, sessionType), 152171568Sscottl 153211095Sdes _E(0, 0, end) 154171568Sscottl}; 155171568Sscottl 156171568Sscottl#define _OPT_INT(w) strtol((char *)w, NULL, 0) 157171568Sscottl#define _OPT_STR(w) (char *)(w) 158171568Sscottl 159171568Sscottlstatic __inline int 160171568Sscottl_OPT_BOOL(char *w) 161171568Sscottl{ 162211095Sdes if(isalpha((unsigned char)*w)) 163171568Sscottl return strcasecmp(w, "TRUE") == 0; 164171568Sscottl else 165171568Sscottl return _OPT_INT(w); 166171568Sscottl} 167171568Sscottl 168171568Sscottl#define _CASE(k, v) case OPT_##k: op->k = v; break 169171568Sscottlstatic void 170171568SscottlsetOption(isc_opt_t *op, int which, void *rval) 171171568Sscottl{ 172171568Sscottl switch(which) { 173171568Sscottl _CASE(port, _OPT_INT(rval)); 174171568Sscottl _CASE(tags, _OPT_INT(rval)); 175171568Sscottl _CASE(maxluns, _OPT_INT(rval)); 176171568Sscottl _CASE(iqn, _OPT_STR(rval)); 177171568Sscottl _CASE(sockbufsize, _OPT_INT(rval)); 178171568Sscottl 179171568Sscottl _CASE(maxConnections, _OPT_INT(rval)); 180171568Sscottl _CASE(maxRecvDataSegmentLength, _OPT_INT(rval)); 181171568Sscottl _CASE(maxXmitDataSegmentLength, _OPT_INT(rval)); 182171568Sscottl _CASE(maxBurstLength, _OPT_INT(rval)); 183171568Sscottl _CASE(firstBurstLength, _OPT_INT(rval)); 184171568Sscottl _CASE(defaultTime2Wait, _OPT_INT(rval)); 185171568Sscottl _CASE(defaultTime2Retain, _OPT_INT(rval)); 186171568Sscottl _CASE(maxOutstandingR2T, _OPT_INT(rval)); 187171568Sscottl _CASE(errorRecoveryLevel, _OPT_INT(rval)); 188171568Sscottl _CASE(targetPortalGroupTag, _OPT_INT(rval)); 189171568Sscottl _CASE(headerDigest, _OPT_STR(rval)); 190171568Sscottl _CASE(dataDigest, _OPT_STR(rval)); 191171568Sscottl 192171568Sscottl _CASE(targetAddress, _OPT_STR(rval)); 193171568Sscottl _CASE(targetAlias, _OPT_STR(rval)); 194171568Sscottl _CASE(targetName, _OPT_STR(rval)); 195171568Sscottl _CASE(initiatorName, _OPT_STR(rval)); 196171568Sscottl _CASE(initiatorAlias, _OPT_STR(rval)); 197171568Sscottl _CASE(authMethod, _OPT_STR(rval)); 198171568Sscottl _CASE(chapSecret, _OPT_STR(rval)); 199171568Sscottl _CASE(chapIName, _OPT_STR(rval)); 200171568Sscottl _CASE(chapDigest, _OPT_STR(rval)); 201171568Sscottl 202171568Sscottl _CASE(tgtChapName, _OPT_STR(rval)); 203171568Sscottl _CASE(tgtChapSecret, _OPT_STR(rval)); 204171568Sscottl 205171568Sscottl _CASE(initialR2T, _OPT_BOOL(rval)); 206171568Sscottl _CASE(immediateData, _OPT_BOOL(rval)); 207171568Sscottl _CASE(dataPDUInOrder, _OPT_BOOL(rval)); 208171568Sscottl _CASE(dataSequenceInOrder, _OPT_BOOL(rval)); 209171568Sscottl } 210171568Sscottl} 211171568Sscottl 212171568Sscottlstatic char * 213171568Sscottlgetline(FILE *fd) 214171568Sscottl{ 215171568Sscottl static char *sp, line[BUFSIZ]; 216171568Sscottl char *lp, *p; 217171568Sscottl 218171568Sscottl do { 219171568Sscottl if(sp == NULL) 220171568Sscottl sp = fgets(line, sizeof line, fd); 221171568Sscottl 222171568Sscottl if((lp = sp) == NULL) 223171568Sscottl break; 224171568Sscottl if((p = strchr(lp, '\n')) != NULL) 225171568Sscottl *p = 0; 226171568Sscottl if((p = strchr(lp, '#')) != NULL) 227171568Sscottl *p = 0; 228171568Sscottl if((p = strchr(lp, ';')) != NULL) { 229171568Sscottl *p++ = 0; 230171568Sscottl sp = p; 231171568Sscottl } else 232171568Sscottl sp = NULL; 233171568Sscottl if(*lp) 234171568Sscottl return lp; 235171568Sscottl } while (feof(fd) == 0); 236171568Sscottl return NULL; 237171568Sscottl} 238171568Sscottl 239171568Sscottlstatic int 240171568SscottlgetConfig(FILE *fd, char *key, char **Ar, int *nargs) 241171568Sscottl{ 242171568Sscottl char *lp, *p, **ar; 243171568Sscottl int state, len, n; 244171568Sscottl 245171568Sscottl ar = Ar; 246171568Sscottl if(key) 247171568Sscottl len = strlen(key); 248171568Sscottl else 249171568Sscottl len = 0; 250171568Sscottl state = 0; 251171568Sscottl while((lp = getline(fd)) != NULL) { 252211095Sdes for(; isspace((unsigned char)*lp); lp++) 253171568Sscottl ; 254171568Sscottl switch(state) { 255171568Sscottl case 0: 256171568Sscottl if((p = strchr(lp, '{')) != NULL) { 257211095Sdes while((--p > lp) && *p && isspace((unsigned char)*p)); 258171568Sscottl n = p - lp; 259171568Sscottl if(len && strncmp(lp, key, MAX(n, len)) == 0) 260171568Sscottl state = 2; 261171568Sscottl else 262171568Sscottl state = 1; 263171568Sscottl continue; 264171568Sscottl } 265171568Sscottl break; 266171568Sscottl 267171568Sscottl case 1: 268171568Sscottl if(*lp == '}') 269171568Sscottl state = 0; 270171568Sscottl continue; 271171568Sscottl 272171568Sscottl case 2: 273171568Sscottl if(*lp == '}') 274171568Sscottl goto done; 275171568Sscottl 276171568Sscottl break; 277171568Sscottl } 278171568Sscottl 279171568Sscottl 280211095Sdes for(p = &lp[strlen(lp)-1]; isspace((unsigned char)*p); p--) 281171568Sscottl *p = 0; 282171568Sscottl if((*nargs)-- > 0) 283171568Sscottl *ar++ = strdup(lp); 284171568Sscottl } 285171568Sscottl 286171568Sscottl done: 287171568Sscottl if(*nargs > 0) 288171568Sscottl *ar = 0; 289171568Sscottl *nargs = ar - Ar; 290171568Sscottl return ar - Ar; 291171568Sscottl} 292171568Sscottl 293171568Sscottlstatic textkey_t * 294171568SscottlkeyLookup(char *key) 295171568Sscottl{ 296171568Sscottl textkey_t *tk; 297171568Sscottl 298217859Scracauer for(tk = keyMap; tk->name && strcmp(tk->name, "end"); tk++) { 299171568Sscottl if(strcasecmp(key, tk->name) == 0) 300171568Sscottl return tk; 301171568Sscottl } 302171568Sscottl return NULL; 303171568Sscottl} 304171568Sscottl 305171568Sscottlstatic void 306171568Sscottlpuke(isc_opt_t *op) 307171568Sscottl{ 308171568Sscottl printf("%24s = %d\n", "port", op->port); 309171568Sscottl printf("%24s = %d\n", "tags", op->tags); 310171568Sscottl printf("%24s = %d\n", "maxluns", op->maxluns); 311171568Sscottl printf("%24s = %s\n", "iqn", op->iqn); 312171568Sscottl 313171568Sscottl printf("%24s = %d\n", "maxConnections", op->maxConnections); 314171568Sscottl printf("%24s = %d\n", "maxRecvDataSegmentLength", op->maxRecvDataSegmentLength); 315171568Sscottl printf("%24s = %d\n", "maxXmitDataSegmentLength", op->maxRecvDataSegmentLength); 316171568Sscottl printf("%24s = %d\n", "maxBurstLength", op->maxBurstLength); 317171568Sscottl printf("%24s = %d\n", "firstBurstLength", op->firstBurstLength); 318171568Sscottl printf("%24s = %d\n", "defaultTime2Wait", op->defaultTime2Wait); 319171568Sscottl printf("%24s = %d\n", "defaultTime2Retain", op->defaultTime2Retain); 320171568Sscottl printf("%24s = %d\n", "maxOutstandingR2T", op->maxOutstandingR2T); 321171568Sscottl printf("%24s = %d\n", "errorRecoveryLevel", op->errorRecoveryLevel); 322171568Sscottl printf("%24s = %d\n", "targetPortalGroupTag", op->targetPortalGroupTag); 323171568Sscottl 324171568Sscottl printf("%24s = %s\n", "headerDigest", op->headerDigest); 325171568Sscottl printf("%24s = %s\n", "dataDigest", op->dataDigest); 326171568Sscottl 327171568Sscottl printf("%24s = %d\n", "initialR2T", op->initialR2T); 328171568Sscottl printf("%24s = %d\n", "immediateData", op->immediateData); 329171568Sscottl printf("%24s = %d\n", "dataPDUInOrder", op->dataPDUInOrder); 330171568Sscottl printf("%24s = %d\n", "dataSequenceInOrder", op->dataSequenceInOrder); 331171568Sscottl 332171568Sscottl printf("%24s = %s\n", "sessionType", op->sessionType); 333171568Sscottl printf("%24s = %s\n", "targetAddress", op->targetAddress); 334171568Sscottl printf("%24s = %s\n", "targetAlias", op->targetAlias); 335171568Sscottl printf("%24s = %s\n", "targetName", op->targetName); 336171568Sscottl printf("%24s = %s\n", "initiatorName", op->initiatorName); 337171568Sscottl printf("%24s = %s\n", "initiatorAlias", op->initiatorAlias); 338171568Sscottl printf("%24s = %s\n", "authMethod", op->authMethod); 339171568Sscottl printf("%24s = %s\n", "chapSecret", op->chapSecret); 340171568Sscottl printf("%24s = %s\n", "chapIName", op->chapIName); 341171568Sscottl printf("%24s = %s\n", "tgtChapName", op->tgtChapName); 342171568Sscottl printf("%24s = %s\n", "tgtChapSecret", op->tgtChapSecret); 343171568Sscottl printf("%24s = %d\n", "tgttgtChallengeLen", op->tgtChallengeLen); 344171568Sscottl} 345171568Sscottl 346171568Sscottlvoid 347171568SscottlparseArgs(int nargs, char **args, isc_opt_t *op) 348171568Sscottl{ 349171568Sscottl char **ar; 350171568Sscottl char *p, *v; 351171568Sscottl textkey_t *tk; 352171568Sscottl 353171568Sscottl for(ar = args; nargs > 0; nargs--, ar++) { 354171568Sscottl p = strchr(*ar, '='); 355171568Sscottl if(p == NULL) 356171568Sscottl continue; 357171568Sscottl *p = 0; 358171568Sscottl v = p + 1; 359211095Sdes while(isspace((unsigned char)*--p)) 360171568Sscottl *p = 0; 361211095Sdes while(isspace((unsigned char)*v)) 362171568Sscottl v++; 363171568Sscottl if((tk = keyLookup(*ar)) == NULL) 364171568Sscottl continue; 365171568Sscottl setOption(op, tk->tokenID, v); 366171568Sscottl } 367171568Sscottl} 368171568Sscottl 369171568Sscottlvoid 370171568SscottlparseConfig(FILE *fd, char *key, isc_opt_t *op) 371171568Sscottl{ 372171568Sscottl char *Ar[256]; 373171568Sscottl int cc; 374171568Sscottl 375171568Sscottl cc = 256; 376171568Sscottl if(getConfig(fd, key, Ar, &cc)) 377171568Sscottl parseArgs(cc, Ar, op); 378171568Sscottl if(vflag) 379171568Sscottl puke(op); 380171568Sscottl} 381