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 *
get_func_name(uint16_t id)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 *
get_tlv_tag_name(uint32_t tag)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
dump_pdu(isns_pdu_t * pdu,int flag)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
dump_pdu1(isns_pdu_t * pdu)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
dump_pdu2(isns_pdu_t * pdu)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
dump_db()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
test_cli_help()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
getcmd(int * argc,int * argv,char * cmd)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
print_entity(char * ident,isns_obj_t * obj)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
print_iscsi(char * ident,isns_obj_t * obj)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
print_portal(char * ident,isns_obj_t * obj)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
print_pg(char * ident,isns_obj_t * obj)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
print_dd(char * ident,isns_obj_t * obj)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
print_dds(char * ident,isns_obj_t * obj)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
print_object(char * ident,isns_obj_t * obj)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
cb_print_obj_n(void * p1,void * p2)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
list_pg()1173 list_pg(
1174 )
1175 {
1176 cache_dump_htab(OBJ_PG);
1177 }
1178
1179 static void
list_portal()1180 list_portal(
1181 )
1182 {
1183 cache_dump_htab(OBJ_PORTAL);
1184 }
1185
1186 static void
list_node()1187 list_node(
1188 )
1189 {
1190 cache_dump_htab(OBJ_ISCSI);
1191 }
1192
1193 static void
list_entity()1194 list_entity(
1195 )
1196 {
1197 cache_dump_htab(OBJ_ENTITY);
1198 }
1199
1200 static void
list_dd()1201 list_dd(
1202 )
1203 {
1204 cache_dump_htab(OBJ_DD);
1205 }
1206
1207 static void
list_ddn(uint32_t uid)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
list_ddsn(uint32_t uid)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
list_dds()1266 list_dds(
1267 )
1268 {
1269 cache_dump_htab(OBJ_DDS);
1270 }
1271
1272 static void
new_dd_dds(int cmd_id,int argc,int * argv)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
del_dd_dds(int cmd_id,int uid)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
update_dds(int cmd_id,int uid)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
update_member(int cmd_id,int * argv)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
cmd_file(char * file)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
run_cmd(char * cmd)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*/
cli_test(void * arg)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