1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 /* This file is getting large unexpectly, a lex & yacc */ 28 /* implementation is expected. */ 29 30 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <string.h> 34 #include <sys/types.h> 35 #include <sys/stat.h> 36 #include <sys/socket.h> 37 #include <netinet/in.h> 38 #include <arpa/inet.h> 39 #include <fcntl.h> 40 #include <unistd.h> 41 #include <pthread.h> 42 43 #include "isns_server.h" 44 #include "isns_htab.h" 45 #include "isns_msgq.h" 46 #include "isns_obj.h" 47 #include "isns_func.h" 48 #include "isns_dd.h" 49 #include "isns_cache.h" 50 #include "isns_pdu.h" 51 52 #ifdef DEBUG 53 /* 54 * external variables 55 */ 56 extern const int NUM_OF_CHILD[MAX_OBJ_TYPE]; 57 extern const int TYPE_OF_CHILD[MAX_OBJ_TYPE][MAX_CHILD_TYPE]; 58 extern const int UID_ATTR_INDEX[MAX_OBJ_TYPE_FOR_SIZE]; 59 extern const int NUM_OF_REF[MAX_OBJ_TYPE_FOR_SIZE]; 60 61 extern lookup_ctrl_t *setup_ddid_lcp(lookup_ctrl_t *, uint32_t); 62 extern lookup_ctrl_t *setup_ddsid_lcp(lookup_ctrl_t *, uint32_t); 63 64 /* 65 * global variables 66 */ 67 int verbose_mc = 0; 68 int verbose_tc = 0; 69 int verbose_lock = 0; 70 int verbose_net = 0; 71 int verbose_parser = 0; 72 73 /* 74 * local variables 75 */ 76 static void print_entity(char *, isns_obj_t *); 77 static void print_iscsi(char *, isns_obj_t *); 78 static void print_portal(char *, isns_obj_t *); 79 static void print_pg(char *, isns_obj_t *); 80 static void print_dd(char *, isns_obj_t *); 81 static void print_dds(char *, isns_obj_t *); 82 static void (*const print_func[MAX_OBJ_TYPE])(char *, isns_obj_t *) = { 83 NULL, 84 &print_entity, 85 &print_iscsi, 86 &print_portal, 87 &print_pg, 88 &print_dd, 89 &print_dds 90 }; 91 static int run_cmd(char *); 92 93 typedef struct { 94 uint16_t func_id; 95 char *fname; 96 } isnsp_fnames_t; 97 isnsp_fnames_t fnames[] = { 98 { ISNS_DEV_ATTR_REG, "DevAttrReg" }, 99 { ISNS_DEV_ATTR_QRY, "DevAttrQry" }, 100 { ISNS_DEV_GET_NEXT, "DevGetNext" }, 101 { ISNS_DEV_DEREG, "DevDereg" }, 102 { ISNS_SCN_REG, "SCNReg" }, 103 { ISNS_SCN_DEREG, "SCNDereg" }, 104 { ISNS_DD_REG, "DDReg" }, 105 { ISNS_DD_DEREG, "DDDereg" }, 106 { ISNS_DDS_REG, "DDSReg" }, 107 { ISNS_DDS_DEREG, "DDSDereg" }, 108 { ISNS_SCN, "SCN" }, 109 { ISNS_ESI, "ESI" }, 110 { ISNS_HEARTBEAT, "Heartbeat" }, 111 { ISNS_DEV_ATTR_REG_RSP, "DevAttrRegRsp" }, 112 { ISNS_DEV_ATTR_QRY_RSP, "DevAttrQryRsp" }, 113 { ISNS_DEV_GET_NEXT_RSP, "DevGetNextRsp" }, 114 { ISNS_DEV_DEREG_RSP, "DevDeregRsp" }, 115 { ISNS_SCN_REG_RSP, "SCNRegRsp" }, 116 { ISNS_SCN_DEREG_RSP, "SCNDeregRsp" }, 117 { ISNS_SCN_RSP, "SCNRsp" }, 118 { ISNS_ESI_RSP, "ESIRsp" }, 119 { 0xFFFF, "Unknown" } }; 120 121 static char * 122 get_func_name( 123 uint16_t id 124 ) 125 { 126 int i = 0; 127 isnsp_fnames_t *fp = &fnames[i ++]; 128 while (fp->func_id != 0xFFFF) { 129 if (fp->func_id == id) { 130 return (fp->fname); 131 } 132 fp = &fnames[i ++]; 133 } 134 135 return ("UNKNOWN"); 136 } 137 138 static char * 139 get_tlv_tag_name( 140 uint32_t tag 141 ) 142 { 143 switch (tag) { 144 case ISNS_DELIMITER_ATTR_ID: 145 return ("Delimiter"); 146 case ISNS_EID_ATTR_ID: 147 return ("Entity Identifier"); 148 case ISNS_ENTITY_PROTOCOL_ATTR_ID: 149 return ("Entity Protocol"); 150 case ISNS_ENTITY_REG_PERIOD_ATTR_ID: 151 return ("Registration Period"); 152 case ISNS_TIMESTAMP_ATTR_ID: 153 return ("Timestamp"); 154 case ISNS_PORTAL_IP_ADDR_ATTR_ID: 155 return ("Portal IP Address"); 156 case ISNS_PORTAL_PORT_ATTR_ID: 157 return ("Portal TCP/UDP Port"); 158 case ISNS_PORTAL_NAME_ATTR_ID: 159 return ("Portal Symbolic Name"); 160 case ISNS_ESI_INTERVAL_ATTR_ID: 161 return ("ESI Interval"); 162 case ISNS_ESI_PORT_ATTR_ID: 163 return ("ESI Port"); 164 case ISNS_SCN_PORT_ATTR_ID: 165 return ("SCN Port"); 166 case ISNS_PORTAL_SEC_BMP_ATTR_ID: 167 return ("Portal Security Bitmap"); 168 case ISNS_ISCSI_NAME_ATTR_ID: 169 return ("iSCSI Name"); 170 case ISNS_ISCSI_NODE_TYPE_ATTR_ID: 171 return ("iSCSI Node Type"); 172 case ISNS_ISCSI_ALIAS_ATTR_ID: 173 return ("iSCSI Alias"); 174 case ISNS_ISCSI_AUTH_METHOD_ATTR_ID: 175 return ("iSCSI Auth Method"); 176 case ISNS_ISCSI_SCN_BITMAP_ATTR_ID: 177 return ("iSCSI SCN Bitmap"); 178 case ISNS_PG_ISCSI_NAME_ATTR_ID: 179 return ("PG iSCSI Name"); 180 case ISNS_PG_PORTAL_IP_ADDR_ATTR_ID: 181 return ("PG Portal IP Addr"); 182 case ISNS_PG_PORTAL_PORT_ATTR_ID: 183 return ("PG Portal TCP/UDP Port"); 184 case ISNS_PG_TAG_ATTR_ID: 185 return ("PG Tag (PGT)"); 186 case ISNS_PG_INDEX_ATTR_ID: 187 return ("PG Index"); 188 case ISNS_DD_NAME_ATTR_ID: 189 return ("DD Name"); 190 case ISNS_DD_ID_ATTR_ID: 191 return ("DD Index"); 192 case ISNS_DD_ISCSI_INDEX_ATTR_ID: 193 return ("DD ISCSI Node Index"); 194 case ISNS_DD_ISCSI_NAME_ATTR_ID: 195 return ("DD ISCSI Node Name"); 196 case ISNS_DD_SET_NAME_ATTR_ID: 197 return ("DDS Name"); 198 case ISNS_DD_SET_ID_ATTR_ID: 199 return ("DDS Index"); 200 case ISNS_DD_SET_STATUS_ATTR_ID: 201 return ("DDS Status"); 202 default: 203 return ("Unknown"); 204 } 205 } 206 207 static void 208 dump_pdu( 209 isns_pdu_t *pdu, 210 int flag 211 ) 212 { 213 short ver, id, len, flags, xid, seq; 214 215 uint8_t *payload = pdu->payload; 216 isns_resp_t *resp; 217 218 /* convert the data */ 219 if (flag) { 220 ver = ntohs(pdu->version); 221 id = ntohs(pdu->func_id); 222 len = ntohs(pdu->payload_len); 223 flags = ntohs(pdu->flags) & 0xFFFF; 224 xid = ntohs(pdu->xid); 225 seq = ntohs(pdu->seq); 226 } else { 227 ver = pdu->version; 228 id = pdu->func_id; 229 len = pdu->payload_len; 230 flags = pdu->flags & 0xFFFF; 231 xid = pdu->xid; 232 seq = pdu->seq; 233 } 234 235 /* print the pdu header */ 236 printf("iSNSP Version: %d\n", ver); 237 printf("Function ID: %s\n", get_func_name(id)); 238 printf("PDU Length: %d\n", len); 239 printf("Flags: %x\n", flags); 240 printf(" %d... .... .... .... : ISNS_FLAG_CLIENT\n", 241 ((flags & ISNS_FLAG_CLIENT) == 0) ? 0 : 1); 242 printf(" .%d.. .... .... .... : ISNS_FLAG_SERVER\n", 243 ((flags & ISNS_FLAG_SERVER) == 0) ? 0 : 1); 244 printf(" ..%d. .... .... .... : ISNS_FLAG_AUTH_BLK_PRESENTED\n", 245 ((flags & ISNS_FLAG_AUTH_BLK_PRESENTED) == 0) ? 0 : 1); 246 printf(" ...%d .... .... .... : ISNS_FLAG_REPLACE_REG\n", 247 ((flags & ISNS_FLAG_REPLACE_REG) == 0) ? 0 : 1); 248 printf(" .... %d... .... .... : ISNS_FLAG_LAST_PDU\n", 249 ((flags & ISNS_FLAG_LAST_PDU) == 0) ? 0 : 1); 250 printf(" .... .%d.. .... .... : ISNS_FLAG_FIRST_PDU\n", 251 ((flags & ISNS_FLAG_FIRST_PDU) == 0) ? 0 : 1); 252 printf("Transaction ID: %d\n", xid); 253 printf("Sequence ID: %d\n", seq); 254 255 printf("Payload: ...\n"); 256 if (id & ISNS_RSP_MASK) { 257 resp = (isns_resp_t *)payload; 258 printf(" ErrorCode: %d\n", ntohl(resp->status)); 259 len -= 4; 260 payload += 4; 261 } 262 263 /* print the payload */ 264 while (len > 0) { 265 isns_tlv_t *tlvp; 266 int t, l; 267 uint8_t *v; 268 char *s; 269 int i; 270 in6_addr_t *ip; 271 char pbuff[256] = { 0 }; 272 273 tlvp = (isns_tlv_t *)payload; 274 275 /* convert the data */ 276 t = ntohl(tlvp->attr_id); 277 l = ntohl(tlvp->attr_len); 278 v = &(tlvp->attr_value[0]); 279 280 /* print payload */ 281 if (l > 0) { 282 printf("%s: ", get_tlv_tag_name(t)); 283 switch (t) { 284 case ISNS_EID_ATTR_ID: 285 case ISNS_ISCSI_NAME_ATTR_ID: 286 case ISNS_ISCSI_ALIAS_ATTR_ID: 287 case ISNS_ISCSI_AUTH_METHOD_ATTR_ID: 288 case ISNS_PG_ISCSI_NAME_ATTR_ID: 289 case ISNS_DD_NAME_ATTR_ID: 290 case ISNS_DD_SET_NAME_ATTR_ID: 291 s = (char *)v; 292 printf("%s\n", s); 293 break; 294 case ISNS_ENTITY_PROTOCOL_ATTR_ID: 295 i = ntohl(*(uint32_t *)v); 296 printf("%s (%d)\n", 297 ((i == 1) ? "No Protocol" : 298 ((i == 2) ? "iSCSI" : 299 ((i == 3) ? "iFCP" : 300 "Others"))), 301 i); 302 break; 303 case ISNS_PORTAL_IP_ADDR_ATTR_ID: 304 case ISNS_PG_PORTAL_IP_ADDR_ATTR_ID: 305 ip = (in6_addr_t *)v; 306 inet_ntop(AF_INET6, (void *)ip, 307 pbuff, sizeof (pbuff)); 308 printf("%s\n", pbuff); 309 break; 310 case ISNS_PORTAL_PORT_ATTR_ID: 311 case ISNS_ESI_PORT_ATTR_ID: 312 case ISNS_SCN_PORT_ATTR_ID: 313 i = ntohl(*(uint32_t *)v); 314 printf("%d\n", (i & 0x0000FFFF)); 315 printf(" .... .... %d... .... : " 316 "0=TCP\n", 317 ((i & 0x10000) == 0) ? 0 : 1); 318 break; 319 case ISNS_ISCSI_NODE_TYPE_ATTR_ID: 320 i = ntohl(*(uint32_t *)v); 321 printf("0x%x\t", i); 322 if (i & ISNS_CONTROL_NODE_TYPE) { 323 printf("Control "); 324 } 325 if (i & ISNS_INITIATOR_NODE_TYPE) { 326 printf("Initiator "); 327 } 328 if (i & ISNS_TARGET_NODE_TYPE) { 329 printf("Target "); 330 } 331 printf("\n"); 332 break; 333 case ISNS_PG_TAG_ATTR_ID: 334 default: 335 i = ntohl(*(uint32_t *)v); 336 printf("%d\n", i); 337 break; 338 } 339 printf(" Attribute Tag: %s (%d)\n", 340 get_tlv_tag_name(t), t); 341 printf(" Attribute Length: %d\n", l); 342 } else { 343 printf("%s: (%d)\n", get_tlv_tag_name(t), t); 344 } 345 346 len -= (sizeof (uint32_t) * 2 + l); 347 payload += (sizeof (uint32_t) * 2 + l); 348 } 349 } 350 351 void 352 dump_pdu1( 353 isns_pdu_t *pdu 354 ) 355 { 356 if (verbose_net) { 357 printf("### PDU RECEIVED ###\n"); 358 dump_pdu(pdu, 0); 359 } 360 } 361 362 void 363 dump_pdu2( 364 isns_pdu_t *pdu 365 ) 366 { 367 if (verbose_net) { 368 printf("### PDU SENT ###\n"); 369 dump_pdu(pdu, 1); 370 } 371 } 372 373 void 374 dump_db( 375 ) 376 { 377 #if 0 378 isns_list_t *list, *lista, *listb; 379 isns_dds_t *dds; 380 isns_dd_t *dd; 381 isns_iscsi2_t *iscsi2; 382 383 printf("### DUMP DATABASE ###\n"); 384 /* dump dds(s) */ 385 list = dds_list; 386 while (list != NULL) { 387 dds = list->obj.dds; 388 printf("[DDS:%d]%s(%s)\n", dds->id, dds->name, 389 dds->status ? "enabled" : "disabled"); 390 lista = dds->dd_list; 391 /* dd(s) that belong to this dds */ 392 while (lista != NULL) { 393 dd = lista->obj.dd; 394 printf("\t[DD:%d]%s\n", dd->id, dd->name); 395 lista = lista->next; 396 } 397 list = list->next; 398 } 399 /* dump dd(s) */ 400 list = dd_list; 401 while (list != NULL) { 402 dd = list->obj.dd; 403 printf("[DD:%d]%s\n", dd->id, dd->name); 404 /* dds(s) this dd belongs to */ 405 lista = dd->dds_list; 406 while (lista != NULL) { 407 dds = lista->obj.dds; 408 printf("\t[DDS:%d]%s\n", dds->id, dds->name); 409 lista = lista->next; 410 } 411 /* node(s) that this dd have */ 412 listb = dd->iscsi_list; 413 while (listb != NULL) { 414 iscsi2 = listb->obj.iscsi2; 415 printf("\t[ISCSI:%d]%s\n", iscsi2->id, iscsi2->name); 416 listb = listb->next; 417 } 418 list = list->next; 419 } 420 /* dump node(s) */ 421 list = iscsi_list; 422 while (list != NULL) { 423 iscsi2 = list->obj.iscsi2; 424 printf("[ISCSI:%d]%s\n", iscsi2->id, iscsi2->name); 425 lista = iscsi2->dd_list; 426 /* dd(s) that this node belongs to */ 427 while (lista != NULL) { 428 dd = lista->obj.dd; 429 printf("\t[DD:%d]%s\n", dd->id, dd->name); 430 lista = lista->next; 431 } 432 list = list->next; 433 } 434 #endif 435 } 436 437 static void 438 test_cli_help( 439 ) 440 { 441 printf("list - list all of storage node.\n"); 442 printf("list dd [id] - list all of dd or one with member.\n"); 443 printf("list dds [id] - list all of dd-set or one with member.\n"); 444 445 printf("\n"); 446 printf("new dd <name> - create a dd with name.\n"); 447 printf("new dds <name> - create a dd-set with name.\n"); 448 printf("new ddn <id> <name> - create a dd with id and name.\n"); 449 printf("new ddsn <id> <name> - create a dd-set with id and name.\n"); 450 printf("del dd <id> - delete a dd.\n"); 451 printf("del dds <id> - delete a dd-set.\n"); 452 453 printf("\n"); 454 printf("add dd <dd_id> <node_name> - add a node to dd.\n"); 455 printf("add ddn <dd_id> <node_id> - add a node to dd.\n"); 456 printf("add ddsn <dds_id> <dd_id> - add a dd to dd-set.\n"); 457 printf("remove dd <dd_id> <node_name> - remove a node from dd.\n"); 458 printf("remove ddn <dd_id> <node_id> - remove a node from dd.\n"); 459 printf("remove ddsn <dds_id> <dd_id> - remove a dd from dd-set.\n"); 460 461 printf("\n"); 462 printf("enable <dds_id> - enable a dd-set.\n"); 463 printf("disable <dds_id> - disable a dd-set.\n"); 464 465 printf("\n"); 466 printf("file <f> - loading command from a file.\n"); 467 printf("pause - suspend batch until enter key is pressed.\n"); 468 469 printf("help - print this help.\n"); 470 printf("quit - stop iSNS server and quit.\n"); 471 } 472 473 static enum { 474 CMD_LIST, CMD_LISTNE, CMD_LISTP, CMD_LISTPG, 475 CMD_LISTDD, CMD_LISTDDS, CMD_LISTDDN, CMD_LISTDDSN, 476 CMD_NEWDD, CMD_NEWDDS, CMD_NEWDDN, CMD_NEWDDSN, 477 CMD_DELDD, CMD_DELDDS, 478 CMD_ENABLE, CMD_DISABLE, 479 CMD_ADDDD, CMD_ADDDDN, CMD_ADDDDSN, 480 CMD_REMDD, CMD_REMDDN, CMD_REMDDSN, 481 CMD_VIEW, 482 CMD_FILE, CMD_PAUSE, 483 CMD_HELP, 484 CMD_VERBOSE_MEMORY, CMD_VERBOSE_NET, 485 CMD_VERBOSE_PARSER, CMD_VERBOSE_TIME, 486 CMD_VERBOSE_LOCK, 487 CMD_QUIT, 488 CMD_NONE, CMD_INVALID 489 }; 490 491 static int 492 getcmd( 493 int *argc, int *argv, char *cmd 494 ) 495 { 496 int j = 0; 497 char tmp[256] = { 0 }; 498 *argc = 0; 499 while (*cmd == ' ') cmd ++; 500 501 if (*cmd == 0) { 502 return (CMD_NONE); 503 } else if (*cmd == '?') { 504 return (CMD_HELP); 505 } 506 507 /* list, list dd, list dds, list dd 0 */ 508 if (strncmp(cmd, "list ", 5) == 0) { 509 cmd += 5; 510 while (*cmd == ' ') cmd ++; 511 if (*cmd == 0) { 512 return (CMD_LIST); 513 } else if (*cmd == 'p') { 514 cmd ++; 515 while (*cmd == ' ') cmd ++; 516 if (*cmd == 0) { 517 return (CMD_LISTP); 518 } 519 } else if (*cmd == 'g') { 520 cmd ++; 521 while (*cmd == ' ') cmd ++; 522 if (*cmd == 0) { 523 return (CMD_LISTPG); 524 } 525 } else if (*cmd == 'e') { 526 cmd ++; 527 while (*cmd == ' ') cmd ++; 528 if (*cmd == 0) { 529 return (CMD_LISTNE); 530 } 531 } else if (strncmp(cmd, "dds ", 4) == 0) { 532 cmd += 4; 533 while (*cmd == ' ') cmd ++; 534 if (*cmd == 0) { 535 return (CMD_LISTDDS); 536 } 537 j = 0; 538 while (*cmd >= '0' && *cmd <= '9') { 539 tmp[j++] = *cmd ++; 540 } 541 tmp[j] = 0; 542 while (*cmd == ' ') cmd ++; 543 if (*cmd == 0 && j > 0) { 544 argv[(*argc)++] = atoi(tmp); 545 return (CMD_LISTDDSN); 546 } 547 } else if (strncmp(cmd, "dd ", 3) == 0) { 548 cmd += 3; 549 while (*cmd == ' ') cmd ++; 550 if (*cmd == 0) { 551 return (CMD_LISTDD); 552 } 553 j = 0; 554 while (*cmd >= '0' && *cmd <= '9') { 555 tmp[j++] = *cmd ++; 556 } 557 tmp[j] = 0; 558 while (*cmd == ' ') cmd ++; 559 if (*cmd == 0 && j > 0) { 560 argv[(*argc)++] = atoi(tmp); 561 return (CMD_LISTDDN); 562 } 563 } 564 return (CMD_INVALID); 565 } 566 567 /* view 0 */ 568 if (strncmp(cmd, "view ", 5) == 0) { 569 cmd += 5; 570 while (*cmd == ' ') cmd ++; 571 j = 0; 572 while (*cmd >= '0' && *cmd <= '9') { 573 tmp[j++] = *cmd ++; 574 } 575 tmp[j] = 0; 576 while (*cmd == ' ') cmd ++; 577 if (*cmd == 0 && j > 0) { 578 argv[(*argc)++] = atoi(tmp); 579 return (CMD_VIEW); 580 } 581 return (CMD_INVALID); 582 } 583 584 /* add dd name */ 585 /* add ddn/ddsn id id */ 586 if (strncmp(cmd, "add ", 4) == 0) { 587 int addcmd = CMD_INVALID; 588 cmd += 4; 589 while (*cmd == ' ') cmd ++; 590 if (strncmp(cmd, "dd ", 3) == 0) { 591 cmd += 3; 592 addcmd = CMD_ADDDD; 593 } else if (strncmp(cmd, "ddn ", 4) == 0) { 594 cmd += 4; 595 addcmd = CMD_ADDDDN; 596 } else if (strncmp(cmd, "ddsn ", 5) == 0) { 597 cmd += 5; 598 addcmd = CMD_ADDDDSN; 599 } else { 600 return (CMD_INVALID); 601 } 602 while (*cmd == ' ') cmd ++; 603 j = 0; 604 while (*cmd >= '0' && *cmd <= '9') { 605 tmp[j++] = *cmd ++; 606 } 607 tmp[j] = 0; 608 if (j > 0) { 609 argv[(*argc)++] = atoi(tmp); 610 } else { 611 return (CMD_INVALID); 612 } 613 while (*cmd == ' ') cmd ++; 614 if (*cmd != 0) { 615 switch (addcmd) { 616 case CMD_ADDDDN: 617 case CMD_ADDDDSN: 618 j = 0; 619 while (*cmd >= '0' && *cmd <= '9') { 620 tmp[j++] = *cmd ++; 621 } 622 tmp[j] = 0; 623 while (*cmd == ' ') cmd ++; 624 if (*cmd == 0 && j > 0) { 625 argv[(*argc)++] = atoi(tmp); 626 } else { 627 return (CMD_INVALID); 628 } 629 break; 630 case CMD_ADDDD: 631 j = strlen(cmd); 632 while (j > 0) { 633 /* get rid of trail blank space */ 634 if (cmd[j - 1] == ' ') { 635 cmd[--j] = 0; 636 } else { 637 break; 638 } 639 } 640 if (j > 0) { 641 cmd[j] = 0; 642 argv[(*argc)++] = (int)cmd; 643 } else { 644 return (CMD_INVALID); 645 } 646 break; 647 } 648 return (addcmd); 649 } 650 return (CMD_INVALID); 651 } 652 653 /* remove dd name */ 654 /* remove ddn/ddsn id id */ 655 if (strncmp(cmd, "remove ", 7) == 0) { 656 int rmcmd = CMD_INVALID; 657 cmd += 7; 658 while (*cmd == ' ') cmd ++; 659 if (strncmp(cmd, "dd ", 3) == 0) { 660 cmd += 3; 661 while (*cmd == ' ') cmd ++; 662 rmcmd = CMD_REMDD; 663 } else if (strncmp(cmd, "ddn ", 4) == 0) { 664 cmd += 4; 665 while (*cmd == ' ') cmd ++; 666 rmcmd = CMD_REMDDN; 667 } else if (strncmp(cmd, "ddsn ", 5) == 0) { 668 cmd += 5; 669 while (*cmd == ' ') cmd ++; 670 rmcmd = CMD_REMDDSN; 671 } else { 672 return (CMD_INVALID); 673 } 674 j = 0; 675 while (*cmd >= '0' && *cmd <= '9') { 676 tmp[j++] = *cmd ++; 677 } 678 tmp[j] = 0; 679 if (j > 0) { 680 argv[(*argc)++] = atoi(tmp); 681 } else { 682 return (CMD_INVALID); 683 } 684 while (*cmd == ' ') cmd ++; 685 if (*cmd != 0) { 686 switch (rmcmd) { 687 case CMD_REMDDN: 688 case CMD_REMDDSN: 689 j = 0; 690 while (*cmd >= '0' && *cmd <= '9') { 691 tmp[j++] = *cmd ++; 692 } 693 tmp[j] = 0; 694 while (*cmd == ' ') cmd ++; 695 if (*cmd == 0 && j > 0) { 696 argv[(*argc)++] = atoi(tmp); 697 } else { 698 return (CMD_INVALID); 699 } 700 break; 701 case CMD_REMDD: 702 j = strlen(cmd); 703 while (j > 0) { 704 /* get rid of trail blank space */ 705 if (cmd[j - 1] == ' ') { 706 cmd[--j] = 0; 707 } else { 708 break; 709 } 710 } 711 if (j > 0) { 712 cmd[j] = 0; 713 argv[(*argc)++] = (int)cmd; 714 } else { 715 return (CMD_INVALID); 716 } 717 break; 718 } 719 return (rmcmd); 720 } 721 return (CMD_INVALID); 722 } 723 724 /* new dd, new dds */ 725 if (strncmp(cmd, "new ", 4) == 0) { 726 int newcmd = CMD_INVALID; 727 cmd += 4; 728 while (*cmd == ' ') cmd ++; 729 if (strncmp(cmd, "dd ", 3) == 0) { 730 cmd += 3; 731 newcmd = CMD_NEWDD; 732 } else if (strncmp(cmd, "dds ", 4) == 0) { 733 cmd += 4; 734 newcmd = CMD_NEWDDS; 735 } else if (strncmp(cmd, "ddn ", 4) == 0) { 736 cmd += 4; 737 newcmd = CMD_NEWDDN; 738 } else if (strncmp(cmd, "ddsn ", 5) == 0) { 739 cmd += 5; 740 newcmd = CMD_NEWDDSN; 741 } 742 if (newcmd != CMD_INVALID) { 743 while (*cmd == ' ') cmd ++; 744 if (*cmd == 0) { 745 return (newcmd); 746 } 747 switch (newcmd) { 748 case CMD_NEWDDN: 749 case CMD_NEWDDSN: 750 j = 0; 751 while (*cmd >= '0' && *cmd <= '9') { 752 tmp[j++] = *cmd ++; 753 } 754 tmp[j] = 0; 755 if (*cmd == ' ' && j > 0) { 756 argv[(*argc)++] = atoi(tmp); 757 } else { 758 return (CMD_INVALID); 759 } 760 case CMD_NEWDD: 761 case CMD_NEWDDS: 762 while (*cmd == ' ') cmd ++; 763 if (*cmd != 0) { 764 j = strlen(cmd); 765 } else { 766 j = 0; 767 } 768 while (j > 0) { 769 /* get rid of trail blank space */ 770 if (cmd[j - 1] == ' ') { 771 cmd[--j] = 0; 772 } else { 773 break; 774 } 775 } 776 if (j > 0) { 777 cmd[j] = 0; 778 argv[(*argc)++] = (int)cmd; 779 } 780 } 781 return (newcmd); 782 } 783 return (CMD_INVALID); 784 } 785 786 /* del dd, del dds, disable 0 */ 787 if (strncmp(cmd, "del ", 4) == 0) { 788 int delcmd = CMD_INVALID; 789 cmd += 4; 790 while (*cmd == ' ') cmd ++; 791 if (strncmp(cmd, "dds ", 4) == 0) { 792 cmd += 4; 793 delcmd = CMD_DELDDS; 794 } else if (strncmp(cmd, "dd ", 3) == 0) { 795 cmd += 3; 796 delcmd = CMD_DELDD; 797 } 798 if (delcmd != CMD_INVALID) { 799 while (*cmd == ' ') cmd ++; 800 j = 0; 801 while (*cmd >= '0' && *cmd <= '9') { 802 tmp[j++] = *cmd ++; 803 } 804 tmp[j] = 0; 805 while (*cmd == ' ') cmd ++; 806 if (*cmd == 0 && j > 0) { 807 argv[(*argc)++] = atoi(tmp); 808 return (delcmd); 809 } 810 } 811 return (CMD_INVALID); 812 } 813 814 /* enable 0 */ 815 if (strncmp(cmd, "enable ", 7) == 0) { 816 cmd += 7; 817 while (*cmd == ' ') cmd ++; 818 j = 0; 819 while (*cmd >= '0' && *cmd <= '9') { 820 tmp[j++] = *cmd ++; 821 } 822 tmp[j] = 0; 823 while (*cmd == ' ') cmd ++; 824 if (*cmd == 0 && j > 0) { 825 argv[(*argc)++] = atoi(tmp); 826 return (CMD_ENABLE); 827 } 828 return (CMD_INVALID); 829 } 830 831 /* disable 0 */ 832 if (strncmp(cmd, "disable ", 8) == 0) { 833 cmd += 8; 834 while (*cmd == ' ') cmd ++; 835 j = 0; 836 while (*cmd >= '0' && *cmd <= '9') { 837 tmp[j++] = *cmd ++; 838 } 839 tmp[j] = 0; 840 while (*cmd == ' ') cmd ++; 841 if (*cmd == 0 && j > 0) { 842 argv[(*argc)++] = atoi(tmp); 843 return (CMD_DISABLE); 844 } 845 return (CMD_INVALID); 846 } 847 848 /* file */ 849 if (strncmp(cmd, "file ", 5) == 0) { 850 cmd += 5; 851 while (*cmd == ' ') cmd ++; 852 if (*cmd != 0) { 853 j = strlen(cmd); 854 } else { 855 j = 0; 856 } 857 while (j > 0) { 858 /* get rid of trail blank space */ 859 if (cmd[j - 1] == ' ') { 860 cmd[--j] = 0; 861 } else { 862 break; 863 } 864 } 865 if (j > 0) { 866 cmd[j] = 0; 867 argv[(*argc)++] = (int)cmd; 868 return (CMD_FILE); 869 } 870 return (CMD_INVALID); 871 } 872 873 /* pause */ 874 if (strncmp(cmd, "pause ", 6) == 0) { 875 cmd += 6; 876 while (*cmd == ' ') cmd ++; 877 if (*cmd == 0) { 878 return (CMD_PAUSE); 879 } 880 return (CMD_INVALID); 881 } 882 883 /* help */ 884 if (strncmp(cmd, "help ", 5) == 0) { 885 cmd += 5; 886 while (*cmd == ' ') cmd ++; 887 if (*cmd == 0) { 888 return (CMD_HELP); 889 } 890 return (CMD_INVALID); 891 } 892 893 /* verbose */ 894 if (strncmp(cmd, "verbose ", 8) == 0) { 895 cmd += 8; 896 while (*cmd == ' ') cmd ++; 897 if (*cmd == 0) { 898 return (CMD_VERBOSE_PARSER); 899 } else if (*cmd == 'm') { 900 cmd ++; 901 while (*cmd == ' ') cmd ++; 902 if (*cmd == 0) { 903 return (CMD_VERBOSE_MEMORY); 904 } 905 } else if (*cmd == 'n') { 906 cmd ++; 907 while (*cmd == ' ') cmd ++; 908 if (*cmd == 0) { 909 return (CMD_VERBOSE_NET); 910 } 911 } else if (*cmd == 'p') { 912 cmd ++; 913 while (*cmd == ' ') cmd ++; 914 if (*cmd == 0) { 915 return (CMD_VERBOSE_PARSER); 916 } 917 } else if (*cmd == 't') { 918 cmd ++; 919 while (*cmd == ' ') cmd ++; 920 if (*cmd == 0) { 921 return (CMD_VERBOSE_TIME); 922 } 923 } else if (*cmd == 'l') { 924 cmd ++; 925 while (*cmd == ' ') cmd ++; 926 if (*cmd == 0) { 927 return (CMD_VERBOSE_LOCK); 928 } 929 } 930 return (CMD_INVALID); 931 } 932 933 /* quit */ 934 if (strncmp(cmd, "quit ", 5) == 0) { 935 cmd += 5; 936 while (*cmd == ' ') cmd ++; 937 if (*cmd == 0) { 938 return (CMD_QUIT); 939 } 940 return (CMD_INVALID); 941 } 942 943 return (CMD_INVALID); 944 } 945 946 static void 947 print_entity( 948 char *ident, 949 isns_obj_t *obj 950 ) 951 { 952 uint32_t uid; 953 uchar_t *eid; 954 uint32_t *cuid; 955 int i, num; 956 957 eid = obj->attrs[ 958 ATTR_INDEX_ENTITY(ISNS_EID_ATTR_ID)].value.ptr; 959 uid = get_obj_uid(obj); 960 961 if (ident != NULL) { 962 printf("%s%d\t%s\n", ident, uid, (const char *)eid); 963 } else { 964 printf("%d\t%s\n", uid, (const char *)eid); 965 } 966 967 i = 0; 968 while (i < NUM_OF_CHILD[obj->type]) { 969 cuid = get_child_n(obj, i); 970 if (ident != NULL) { 971 printf("%s\t%s%d:", "child", i); 972 } else { 973 printf("\t%s%d:", "child", i); 974 } 975 if (cuid != NULL) { 976 num = *cuid ++; 977 } else { 978 num = 0; 979 } 980 while (num > 0) { 981 printf("\t%d", *cuid ++); 982 num --; 983 } 984 printf("\n"); 985 i ++; 986 } 987 } 988 989 static void 990 print_iscsi( 991 char *ident, 992 isns_obj_t *obj 993 ) 994 { 995 uchar_t *name = obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_NAME_ATTR_ID)] 996 .value.ptr; 997 uchar_t *alias = obj->attrs[ATTR_INDEX_ISCSI(ISNS_ISCSI_ALIAS_ATTR_ID)] 998 .value.ptr; 999 uint32_t type = obj->attrs[ 1000 ATTR_INDEX_ISCSI(ISNS_ISCSI_NODE_TYPE_ATTR_ID)].value.ui; 1001 uint32_t uid = get_obj_uid(obj); 1002 uint32_t puid = get_parent_uid(obj); 1003 1004 if (!alias) { 1005 alias = (uchar_t *)"-"; 1006 } 1007 1008 if (ident != NULL) { 1009 printf("%s%d[%d]\t%s\n", ident, 1010 uid, puid, (const char *)name); 1011 printf("%s\t%s", ident, alias); 1012 } else { 1013 printf("%d[%d]\t%s\n", 1014 uid, puid, (const char *)name); 1015 printf("\t%s", alias); 1016 } 1017 if (IS_TYPE_TARGET(type)) { 1018 printf("\tTarget"); 1019 } 1020 if (IS_TYPE_INITIATOR(type)) { 1021 printf("\tInitiator"); 1022 } 1023 if (IS_TYPE_CONTROL(type)) { 1024 printf("\tControl"); 1025 } 1026 if (IS_TYPE_UNKNOWN(type)) { 1027 printf("\t-"); 1028 } 1029 printf("\n"); 1030 } 1031 1032 static void 1033 print_portal( 1034 char *ident, 1035 isns_obj_t *obj 1036 ) 1037 { 1038 char pbuff[256] = { 0 }; 1039 in6_addr_t *ip = obj->attrs[ 1040 ATTR_INDEX_PORTAL(ISNS_PORTAL_IP_ADDR_ATTR_ID)].value.ip; 1041 uint32_t port = obj->attrs[ 1042 ATTR_INDEX_PORTAL(ISNS_PORTAL_PORT_ATTR_ID)].value.ui; 1043 uint32_t uid = get_obj_uid(obj); 1044 uint32_t puid = get_parent_uid(obj); 1045 1046 inet_ntop(AF_INET6, (void *)ip, pbuff, sizeof (pbuff)); 1047 if (ident != NULL) { 1048 printf("%s%d[%d]\t%s:%d", ident, 1049 uid, puid, pbuff, PORT_NUMBER(port)); 1050 } else { 1051 printf("%d[%d]\t%s:%d", 1052 uid, puid, pbuff, PORT_NUMBER(port)); 1053 } 1054 printf(" %s\n", IS_PORT_UDP(port) ? "UDP" : "TCP"); 1055 } 1056 1057 static void 1058 print_pg( 1059 char *ident, 1060 isns_obj_t *obj 1061 ) 1062 { 1063 uint32_t ref; 1064 int i; 1065 1066 char pbuff[256] = { 0 }; 1067 uchar_t *name = obj->attrs[ATTR_INDEX_PG(ISNS_PG_ISCSI_NAME_ATTR_ID)] 1068 .value.ptr; 1069 in6_addr_t *ip = obj->attrs[ 1070 ATTR_INDEX_PG(ISNS_PG_PORTAL_IP_ADDR_ATTR_ID)].value.ip; 1071 uint32_t port = obj->attrs[ 1072 ATTR_INDEX_PG(ISNS_PG_PORTAL_PORT_ATTR_ID)].value.ui; 1073 uint32_t tag = obj->attrs[ 1074 ATTR_INDEX_PG(ISNS_PG_TAG_ATTR_ID)].value.ui; 1075 uint32_t uid = get_obj_uid(obj); 1076 uint32_t puid = get_parent_uid(obj); 1077 1078 inet_ntop(AF_INET6, (void *)ip, pbuff, sizeof (pbuff)); 1079 if (ident != NULL) { 1080 printf("%s%d[%d]\t[%d] %s\n", ident, 1081 uid, puid, tag, (const char *)name); 1082 printf("%s\t%s:%d", ident, pbuff, PORT_NUMBER(port)); 1083 } else { 1084 printf("%d[%d]\t[%d] %s\n", 1085 uid, puid, tag, (const char *)name); 1086 printf("\t%s:%d", pbuff, PORT_NUMBER(port)); 1087 } 1088 printf(" %s\n", IS_PORT_UDP(port) ? "UDP" : "TCP"); 1089 1090 if (NUM_OF_REF[obj->type] > 0) { 1091 if (ident != NULL) { 1092 printf("%s\t%s:", "ref"); 1093 } else { 1094 printf("\t%s:", "ref"); 1095 } 1096 } 1097 i = 0; 1098 while (i < NUM_OF_REF[obj->type]) { 1099 ref = get_ref_n(obj, i); 1100 printf("\t%d", ref); 1101 i ++; 1102 } 1103 if (i > 0) { 1104 printf("\n"); 1105 } 1106 } 1107 1108 static void 1109 print_dd( 1110 char *ident, 1111 isns_obj_t *obj 1112 ) 1113 { 1114 uchar_t *name = obj->attrs[ATTR_INDEX_DD(ISNS_DD_NAME_ATTR_ID)] 1115 .value.ptr; 1116 uint32_t uid = obj->attrs[UID_ATTR_INDEX[OBJ_DD]].value.ui; 1117 1118 if (ident != NULL) { 1119 printf("%s%d\t%s\n", ident, uid, (const char *)name); 1120 } else { 1121 printf("%d\t%s\n", uid, (const char *)name); 1122 } 1123 } 1124 1125 static void 1126 print_dds( 1127 char *ident, 1128 isns_obj_t *obj 1129 ) 1130 { 1131 uchar_t *name = obj->attrs[ATTR_INDEX_DDS( 1132 ISNS_DD_SET_NAME_ATTR_ID)].value.ptr; 1133 uint32_t uid = obj->attrs[UID_ATTR_INDEX[OBJ_DDS]].value.ui; 1134 uint32_t enabled = obj->attrs[ATTR_INDEX_DDS( 1135 ISNS_DD_SET_STATUS_ATTR_ID)].value.ui; 1136 1137 if (ident != NULL) { 1138 printf("%s%d\t%s\t\t(%s)\n", ident, uid, 1139 (const char *)name, enabled ? "enabled" : "disabled"); 1140 } else { 1141 printf("%d\t%s\t\t(%s)\n", uid, 1142 (const char *)name, enabled ? "enabled" : "disabled"); 1143 } 1144 } 1145 1146 void 1147 print_object( 1148 char *ident, 1149 isns_obj_t *obj 1150 ) 1151 { 1152 print_func[obj->type](ident, obj); 1153 } 1154 1155 /*ARGSUSED*/ 1156 static int 1157 cb_print_obj_n( 1158 void *p1, 1159 void *p2 1160 ) 1161 { 1162 isns_obj_t *obj = (isns_obj_t *)p1; 1163 print_func[obj->type](NULL, obj); 1164 1165 return (0); 1166 } 1167 1168 static void 1169 list_pg( 1170 ) 1171 { 1172 cache_dump_htab(OBJ_PG); 1173 } 1174 1175 static void 1176 list_portal( 1177 ) 1178 { 1179 cache_dump_htab(OBJ_PORTAL); 1180 } 1181 1182 static void 1183 list_node( 1184 ) 1185 { 1186 cache_dump_htab(OBJ_ISCSI); 1187 } 1188 1189 static void 1190 list_entity( 1191 ) 1192 { 1193 cache_dump_htab(OBJ_ENTITY); 1194 } 1195 1196 static void 1197 list_dd( 1198 ) 1199 { 1200 cache_dump_htab(OBJ_DD); 1201 } 1202 1203 static void 1204 list_ddn( 1205 uint32_t uid 1206 ) 1207 { 1208 lookup_ctrl_t lc; 1209 1210 bmp_t *p; 1211 uint32_t n; 1212 1213 if (uid != 0) { 1214 setup_ddid_lcp(&lc, uid); 1215 cache_lookup(&lc, &uid, cb_print_obj_n); 1216 } 1217 1218 if (uid != 0) { 1219 printf("--------------------------------\n"); 1220 get_dd_matrix(uid, &p, &n); 1221 SET_UID_LCP(&lc, OBJ_ISCSI, 0); 1222 FOR_EACH_MEMBER(p, n, uid, { 1223 lc.data[0].ui = uid; 1224 cache_lookup(&lc, NULL, cb_print_obj_n); 1225 }); 1226 free(p); 1227 } else { 1228 printf("no such dd.\n"); 1229 } 1230 } 1231 1232 static void 1233 list_ddsn( 1234 uint32_t uid 1235 ) 1236 { 1237 lookup_ctrl_t lc; 1238 1239 bmp_t *p; 1240 uint32_t n; 1241 1242 if (uid != 0) { 1243 setup_ddsid_lcp(&lc, uid); 1244 cache_lookup(&lc, &uid, cb_print_obj_n); 1245 } 1246 1247 if (uid != 0) { 1248 printf("--------------------------------\n"); 1249 get_dds_matrix(uid, &p, &n); 1250 SET_UID_LCP(&lc, OBJ_DD, 0); 1251 FOR_EACH_MEMBER(p, n, uid, { 1252 lc.data[0].ui = uid; 1253 cache_lookup(&lc, NULL, cb_print_obj_n); 1254 }); 1255 free(p); 1256 } else { 1257 printf("no such dd-set.\n"); 1258 } 1259 } 1260 1261 static void 1262 list_dds( 1263 ) 1264 { 1265 cache_dump_htab(OBJ_DDS); 1266 } 1267 1268 static void 1269 new_dd_dds( 1270 int cmd_id, 1271 int argc, 1272 int *argv 1273 ) 1274 { 1275 uint32_t buff[256]; 1276 isns_pdu_t *pdu = (isns_pdu_t *)buff; 1277 uint8_t *payload = &pdu->payload[0]; 1278 uint16_t payload_len = 0; 1279 isns_tlv_t *tlv; 1280 1281 int len = 0; 1282 uint32_t uid = 0; 1283 char *name; 1284 1285 conn_arg_t conn; 1286 1287 pdu->version = ISNSP_VERSION; 1288 1289 /* source attribute */ 1290 tlv = (isns_tlv_t *)payload; 1291 tlv->attr_id = htonl(ISNS_ISCSI_NAME_ATTR_ID); 1292 tlv->attr_len = htonl(32); 1293 strcpy((char *)tlv->attr_value, "i am a control node."); 1294 payload += 8 + 32; 1295 payload_len += 8 + 32; 1296 1297 /* key attributes */ 1298 1299 /* delimiter */ 1300 tlv = (isns_tlv_t *)payload; 1301 tlv->attr_id = htonl(ISNS_DELIMITER_ATTR_ID); 1302 tlv->attr_len = htonl(0); 1303 payload += 8 + 0; 1304 payload_len += 8 + 0; 1305 1306 /* operating attributes */ 1307 switch (cmd_id) { 1308 case CMD_NEWDD: 1309 pdu->func_id = ISNS_DD_REG; 1310 if (argc == 1) { 1311 name = (char *)argv[0]; 1312 len = strlen(name) + 1; 1313 len += 4 - (len % 4); 1314 } 1315 tlv = (isns_tlv_t *)payload; 1316 tlv->attr_id = htonl(ISNS_DD_NAME_ATTR_ID); 1317 tlv->attr_len = htonl(len); 1318 if (len > 0) { 1319 strcpy((char *)tlv->attr_value, name); 1320 } 1321 payload_len += 8 + len; 1322 break; 1323 case CMD_NEWDDS: 1324 pdu->func_id = ISNS_DDS_REG; 1325 if (argc == 1) { 1326 name = (char *)argv[0]; 1327 len = strlen(name) + 1; 1328 len += 4 - (len % 4); 1329 } 1330 tlv = (isns_tlv_t *)payload; 1331 tlv->attr_id = htonl(ISNS_DD_SET_NAME_ATTR_ID); 1332 tlv->attr_len = htonl(len); 1333 if (len > 0) { 1334 strcpy((char *)tlv->attr_value, name); 1335 } 1336 payload_len += 8 + len; 1337 break; 1338 case CMD_NEWDDN: 1339 pdu->func_id = ISNS_DD_REG; 1340 switch (argc) { 1341 case 2: 1342 name = (char *)argv[1]; 1343 len = strlen(name) + 1; 1344 len += 4 - (len % 4); 1345 case 1: 1346 uid = argv[0]; 1347 } 1348 tlv = (isns_tlv_t *)payload; 1349 tlv->attr_id = htonl(ISNS_DD_NAME_ATTR_ID); 1350 tlv->attr_len = htonl(len); 1351 if (len > 0) { 1352 strcpy((char *)tlv->attr_value, name); 1353 } 1354 payload += 8 + len; 1355 payload_len += 8 + len; 1356 if (uid > 0) { 1357 tlv = (isns_tlv_t *)payload; 1358 tlv->attr_id = htonl(ISNS_DD_ID_ATTR_ID); 1359 tlv->attr_len = htonl(4); 1360 *(uint32_t *)tlv->attr_value = htonl(uid); 1361 payload_len += 8 + 4; 1362 } 1363 break; 1364 case CMD_NEWDDSN: 1365 pdu->func_id = ISNS_DDS_REG; 1366 switch (argc) { 1367 case 2: 1368 name = (char *)argv[1]; 1369 len = strlen(name) + 1; 1370 len += 4 - (len % 4); 1371 case 1: 1372 uid = argv[0]; 1373 } 1374 tlv = (isns_tlv_t *)payload; 1375 tlv->attr_id = htonl(ISNS_DD_SET_NAME_ATTR_ID); 1376 tlv->attr_len = htonl(len); 1377 if (len > 0) { 1378 strcpy((char *)tlv->attr_value, name); 1379 } 1380 payload_len += 8 + len; 1381 payload += 8 + len; 1382 if (uid > 0) { 1383 tlv = (isns_tlv_t *)payload; 1384 tlv->attr_id = htonl(ISNS_DD_SET_ID_ATTR_ID); 1385 tlv->attr_len = htonl(4); 1386 *(uint32_t *)tlv->attr_value = htonl(uid); 1387 payload_len += 8 + 4; 1388 } 1389 break; 1390 default: 1391 break; 1392 } 1393 1394 pdu->payload_len = payload_len; 1395 1396 dump_pdu1(pdu); 1397 1398 conn.in_packet.pdu = pdu; 1399 conn.out_packet.pdu = NULL; 1400 conn.out_packet.sz = 0; 1401 1402 if (packet_split_verify(&conn) == 0) { 1403 cache_lock(conn.lock); 1404 conn.handler(&conn); 1405 conn.ec = cache_unlock(conn.lock, conn.ec); 1406 } 1407 1408 if (conn.out_packet.pdu != NULL) { 1409 pdu_update_code(conn.out_packet.pdu, 1410 &conn.out_packet.pl, conn.ec); 1411 dump_pdu2(conn.out_packet.pdu); 1412 free(conn.out_packet.pdu); 1413 } else if (conn.ec != 0) { 1414 printf("operation failed[%d].\n", conn.ec); 1415 } 1416 } 1417 1418 static void 1419 del_dd_dds( 1420 int cmd_id, 1421 int uid 1422 ) 1423 { 1424 uint32_t buff[256]; 1425 isns_pdu_t *pdu = (isns_pdu_t *)buff; 1426 uint8_t *payload = &pdu->payload[0]; 1427 uint16_t payload_len = 0; 1428 isns_tlv_t *tlv; 1429 1430 uint32_t tag; 1431 1432 conn_arg_t conn; 1433 1434 if (uid == 0) { 1435 return; 1436 } 1437 1438 pdu->version = ISNSP_VERSION; 1439 1440 if (cmd_id == CMD_DELDD) { 1441 tag = ISNS_DD_ID_ATTR_ID; 1442 pdu->func_id = ISNS_DD_DEREG; 1443 } else { 1444 tag = ISNS_DD_SET_ID_ATTR_ID; 1445 pdu->func_id = ISNS_DDS_DEREG; 1446 } 1447 1448 /* source attribute */ 1449 tlv = (isns_tlv_t *)payload; 1450 tlv->attr_id = htonl(ISNS_ISCSI_NAME_ATTR_ID); 1451 tlv->attr_len = htonl(32); 1452 strcpy((char *)tlv->attr_value, "i am a control node."); 1453 payload_len += 8 + 32; 1454 payload += 8 + 32; 1455 1456 /* key attributes */ 1457 tlv = (isns_tlv_t *)payload; 1458 tlv->attr_id = htonl(tag); 1459 tlv->attr_len = htonl(4); 1460 *(uint32_t *)tlv->attr_value = htonl(uid); 1461 payload_len += 8 + 4; 1462 payload += 8 + 4; 1463 1464 /* delimiter */ 1465 tlv = (isns_tlv_t *)payload; 1466 tlv->attr_id = htonl(ISNS_DELIMITER_ATTR_ID); 1467 tlv->attr_len = htonl(0); 1468 payload_len += 8 + 0; 1469 payload += 8 + 0; 1470 1471 /* operating attributes */ 1472 1473 pdu->payload_len = payload_len; 1474 1475 dump_pdu1(pdu); 1476 1477 conn.in_packet.pdu = pdu; 1478 conn.out_packet.pdu = NULL; 1479 conn.out_packet.sz = 0; 1480 1481 if (packet_split_verify(&conn) == 0) { 1482 cache_lock(conn.lock); 1483 conn.handler(&conn); 1484 conn.ec = cache_unlock(conn.lock, conn.ec); 1485 } 1486 1487 if (conn.out_packet.pdu != NULL) { 1488 pdu_update_code(conn.out_packet.pdu, 1489 &conn.out_packet.pl, conn.ec); 1490 dump_pdu2(conn.out_packet.pdu); 1491 free(conn.out_packet.pdu); 1492 } else if (conn.ec != 0) { 1493 printf("operation failed[%d].\n", conn.ec); 1494 } 1495 } 1496 1497 static void 1498 update_dds( 1499 int cmd_id, 1500 int uid 1501 ) 1502 { 1503 uint32_t buff[256]; 1504 isns_pdu_t *pdu = (isns_pdu_t *)buff; 1505 uint8_t *payload = &pdu->payload[0]; 1506 uint16_t payload_len = 0; 1507 isns_tlv_t *tlv; 1508 1509 conn_arg_t conn; 1510 1511 if (uid == 0) { 1512 return; 1513 } 1514 1515 pdu->version = ISNSP_VERSION; 1516 1517 pdu->func_id = ISNS_DDS_REG; 1518 1519 /* source attribute */ 1520 tlv = (isns_tlv_t *)payload; 1521 tlv->attr_id = htonl(ISNS_ISCSI_NAME_ATTR_ID); 1522 tlv->attr_len = htonl(32); 1523 strcpy((char *)tlv->attr_value, "i am a control node."); 1524 payload_len += 8 + 32; 1525 payload += 8 + 32; 1526 1527 /* key attributes */ 1528 tlv = (isns_tlv_t *)payload; 1529 tlv->attr_id = htonl(ISNS_DD_SET_ID_ATTR_ID); 1530 tlv->attr_len = htonl(4); 1531 *(uint32_t *)tlv->attr_value = htonl(uid); 1532 payload_len += 8 + 4; 1533 payload += 8 + 4; 1534 1535 /* delimiter */ 1536 tlv = (isns_tlv_t *)payload; 1537 tlv->attr_id = htonl(ISNS_DELIMITER_ATTR_ID); 1538 tlv->attr_len = htonl(0); 1539 payload_len += 8 + 0; 1540 payload += 8 + 0; 1541 1542 /* operating attributes */ 1543 tlv = (isns_tlv_t *)payload; 1544 tlv->attr_id = htonl(ISNS_DD_SET_STATUS_ATTR_ID); 1545 tlv->attr_len = htonl(4); 1546 if (cmd_id == CMD_ENABLE) { 1547 *(uint32_t *)tlv->attr_value = htonl(1); 1548 } else { 1549 *(uint32_t *)tlv->attr_value = htonl(0); 1550 } 1551 payload_len += 8 + 4; 1552 1553 pdu->payload_len = payload_len; 1554 1555 dump_pdu1(pdu); 1556 1557 conn.in_packet.pdu = pdu; 1558 conn.out_packet.pdu = NULL; 1559 conn.out_packet.sz = 0; 1560 1561 if (packet_split_verify(&conn) == 0) { 1562 cache_lock(conn.lock); 1563 conn.handler(&conn); 1564 conn.ec = cache_unlock(conn.lock, conn.ec); 1565 } 1566 1567 if (conn.out_packet.pdu != NULL) { 1568 pdu_update_code(conn.out_packet.pdu, 1569 &conn.out_packet.pl, conn.ec); 1570 dump_pdu2(conn.out_packet.pdu); 1571 free(conn.out_packet.pdu); 1572 } else if (conn.ec != 0) { 1573 printf("operation failed[%d].\n", conn.ec); 1574 } 1575 } 1576 1577 static void 1578 update_member( 1579 int cmd_id, 1580 int *argv 1581 ) 1582 { 1583 uint32_t buff[256]; 1584 isns_pdu_t *pdu = (isns_pdu_t *)buff; 1585 uint8_t *payload = &pdu->payload[0]; 1586 uint16_t payload_len = 0; 1587 isns_tlv_t *tlv; 1588 uint32_t key_tag, op_tag, op_len; 1589 1590 uint32_t uid = argv[0]; 1591 uint32_t m_id; 1592 char *m_name; 1593 1594 conn_arg_t conn; 1595 1596 if (uid == 0) { 1597 printf("operation failed.\n"); 1598 return; 1599 } 1600 1601 pdu->version = ISNSP_VERSION; 1602 1603 switch (cmd_id) { 1604 case CMD_ADDDD: 1605 case CMD_ADDDDN: 1606 pdu->func_id = ISNS_DD_REG; 1607 break; 1608 case CMD_REMDD: 1609 case CMD_REMDDN: 1610 pdu->func_id = ISNS_DD_DEREG; 1611 break; 1612 case CMD_ADDDDSN: 1613 pdu->func_id = ISNS_DDS_REG; 1614 break; 1615 case CMD_REMDDSN: 1616 pdu->func_id = ISNS_DDS_DEREG; 1617 break; 1618 } 1619 switch (cmd_id) { 1620 case CMD_ADDDD: 1621 case CMD_REMDD: 1622 key_tag = ISNS_DD_ID_ATTR_ID; 1623 op_tag = ISNS_DD_ISCSI_NAME_ATTR_ID; 1624 m_name = (char *)argv[1]; 1625 op_len = strlen(m_name); 1626 op_len += 4 - (op_len % 4); 1627 break; 1628 case CMD_ADDDDN: 1629 case CMD_REMDDN: 1630 key_tag = ISNS_DD_ID_ATTR_ID; 1631 op_tag = ISNS_DD_ISCSI_INDEX_ATTR_ID; 1632 m_id = argv[1]; 1633 op_len = 4; 1634 break; 1635 case CMD_ADDDDSN: 1636 case CMD_REMDDSN: 1637 key_tag = ISNS_DD_SET_ID_ATTR_ID; 1638 op_tag = ISNS_DD_ID_ATTR_ID; 1639 m_id = argv[1]; 1640 op_len = 4; 1641 break; 1642 } 1643 1644 /* source attribute */ 1645 tlv = (isns_tlv_t *)payload; 1646 tlv->attr_id = htonl(ISNS_ISCSI_NAME_ATTR_ID); 1647 tlv->attr_len = htonl(32); 1648 strcpy((char *)tlv->attr_value, "i am a control node."); 1649 payload_len += 8 + 32; 1650 payload += 8 + 32; 1651 1652 /* key attributes */ 1653 tlv = (isns_tlv_t *)payload; 1654 tlv->attr_id = htonl(key_tag); 1655 tlv->attr_len = htonl(4); 1656 *(uint32_t *)tlv->attr_value = htonl(uid); 1657 payload_len += 8 + 4; 1658 payload += 8 + 4; 1659 1660 /* delimiter */ 1661 tlv = (isns_tlv_t *)payload; 1662 tlv->attr_id = htonl(ISNS_DELIMITER_ATTR_ID); 1663 tlv->attr_len = htonl(0); 1664 payload_len += 8 + 0; 1665 payload += 8 + 0; 1666 1667 /* operating attributes */ 1668 tlv = (isns_tlv_t *)payload; 1669 tlv->attr_id = htonl(op_tag); 1670 tlv->attr_len = htonl(op_len); 1671 switch (cmd_id) { 1672 case CMD_ADDDD: 1673 case CMD_REMDD: 1674 strcpy((char *)tlv->attr_value, m_name); 1675 break; 1676 case CMD_ADDDDN: 1677 case CMD_ADDDDSN: 1678 case CMD_REMDDN: 1679 case CMD_REMDDSN: 1680 *(uint32_t *)tlv->attr_value = htonl(m_id); 1681 break; 1682 } 1683 payload_len += 8 + op_len; 1684 1685 pdu->payload_len = payload_len; 1686 1687 dump_pdu1(pdu); 1688 1689 conn.in_packet.pdu = pdu; 1690 conn.out_packet.pdu = NULL; 1691 conn.out_packet.sz = 0; 1692 1693 if (packet_split_verify(&conn) == 0) { 1694 cache_lock(conn.lock); 1695 conn.handler(&conn); 1696 conn.ec = cache_unlock(conn.lock, conn.ec); 1697 } 1698 1699 if (conn.out_packet.pdu != NULL) { 1700 pdu_update_code(conn.out_packet.pdu, 1701 &conn.out_packet.pl, conn.ec); 1702 dump_pdu2(conn.out_packet.pdu); 1703 free(conn.out_packet.pdu); 1704 } else if (conn.ec != 0) { 1705 printf("operation failed[%d].\n", conn.ec); 1706 } 1707 } 1708 1709 static void 1710 cmd_file( 1711 char *file 1712 ) 1713 { 1714 char i = 0, ch, cmd[256]; 1715 FILE *f = fopen(file, "r"); 1716 if (f != NULL) { 1717 while ((ch = fgetc(f)) != 0 && ch != EOF) { 1718 if (ch == '\t') { 1719 cmd[i++] = ' '; 1720 } else if (ch != '\n') { 1721 cmd[i++] = ch; 1722 } else { 1723 cmd[i ++] = ' '; 1724 cmd[i] = 0; 1725 i = 0; 1726 printf("%s\n", cmd); 1727 if (run_cmd(cmd) != 0) { 1728 break; 1729 } 1730 } 1731 } 1732 fclose(f); 1733 } else { 1734 printf("Cannot open file %s.\n", file); 1735 } 1736 } 1737 1738 static int 1739 run_cmd( 1740 char *cmd 1741 ) 1742 { 1743 int argc, argv[32]; 1744 int cmd_id; 1745 cmd_id = getcmd(&argc, argv, cmd); 1746 switch (cmd_id) { 1747 case CMD_LIST: 1748 list_node(); 1749 break; 1750 case CMD_LISTNE: 1751 list_entity(); 1752 break; 1753 case CMD_LISTP: 1754 list_portal(); 1755 break; 1756 case CMD_LISTPG: 1757 list_pg(); 1758 break; 1759 case CMD_LISTDD: 1760 list_dd(); 1761 break; 1762 case CMD_LISTDDS: 1763 list_dds(); 1764 break; 1765 case CMD_LISTDDN: 1766 list_ddn(argv[0]); 1767 break; 1768 case CMD_LISTDDSN: 1769 list_ddsn(argv[0]); 1770 break; 1771 case CMD_NEWDD: 1772 case CMD_NEWDDS: 1773 case CMD_NEWDDN: 1774 case CMD_NEWDDSN: 1775 new_dd_dds(cmd_id, argc, argv); 1776 break; 1777 case CMD_DELDD: 1778 case CMD_DELDDS: 1779 del_dd_dds(cmd_id, argv[0]); 1780 break; 1781 case CMD_ENABLE: 1782 case CMD_DISABLE: 1783 update_dds(cmd_id, argv[0]); 1784 break; 1785 case CMD_ADDDD: 1786 case CMD_ADDDDN: 1787 case CMD_ADDDDSN: 1788 case CMD_REMDD: 1789 case CMD_REMDDN: 1790 case CMD_REMDDSN: 1791 update_member(cmd_id, argv); 1792 break; 1793 case CMD_PAUSE: 1794 printf("Press enter to continue..."); 1795 getchar(); 1796 break; 1797 case CMD_FILE: 1798 cmd_file((char *)argv[0]); 1799 break; 1800 case CMD_HELP: 1801 test_cli_help(); 1802 break; 1803 case CMD_VERBOSE_MEMORY: 1804 verbose_mc = !verbose_mc; 1805 break; 1806 case CMD_VERBOSE_NET: 1807 verbose_net = !verbose_net; 1808 break; 1809 case CMD_VERBOSE_TIME: 1810 verbose_tc = !verbose_tc; 1811 break; 1812 case CMD_VERBOSE_LOCK: 1813 verbose_lock = !verbose_lock; 1814 break; 1815 case CMD_VERBOSE_PARSER: 1816 verbose_parser = !verbose_parser; 1817 break; 1818 case CMD_QUIT: 1819 /* clean up cli */ 1820 /* notify sys control */ 1821 shutdown_server(); 1822 return (1); 1823 case CMD_NONE: 1824 break; 1825 default: 1826 printf("invalid command\n"); 1827 break; 1828 } 1829 if (cmd_id != CMD_NONE) { 1830 printf("\n>"); 1831 } else { 1832 printf(">"); 1833 } 1834 return (0); 1835 } 1836 1837 /*ARGSUSED*/ 1838 void *cli_test(void *arg) { 1839 char i = 0, ch, cmd[256]; 1840 1841 printf("iSNS Server test CLI.\n"); 1842 printf("Copyright 2007 Sun Microsystems, Inc.\n"); 1843 1844 printf("\n>"); 1845 while ((ch = getchar()) != 0 && ch != EOF) { 1846 if (ch == '\t') { 1847 cmd[i++] = ' '; 1848 } else if (ch != '\n') { 1849 cmd[i++] = ch; 1850 } else { 1851 cmd[i ++] = ' '; 1852 cmd[i] = 0; 1853 i = 0; 1854 if (run_cmd(cmd) != 0) { 1855 break; 1856 } 1857 } 1858 } 1859 1860 return (NULL); 1861 } 1862 #endif 1863