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