1 /* $NetBSD: iscsic_daemonif.c,v 1.3 2015/05/30 15:57:32 joerg Exp $ */
2
3 /*-
4 * Copyright (c) 2005,2006,2011 The NetBSD Foundation, Inc.
5 * All rights reserved.
6 *
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Wasabi Systems, Inc.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
30 */
31 #include "iscsic_globals.h"
32
33 /*
34 * do_add_target:
35 * Handle both the add_target and add_send_target commands.
36 *
37 * Parameter:
38 * argc, argv Shifted arguments
39 * kind Which list
40 *
41 * Returns: 0 if OK - else it doesn't return at all.
42 */
43
44 STATIC int
do_add_target(int argc,char ** argv,iscsid_list_kind_t kind)45 do_add_target(int argc, char **argv, iscsid_list_kind_t kind)
46 {
47 iscsid_add_target_req_t *targ;
48 iscsid_set_target_authentication_req_t auth;
49 iscsid_get_set_target_options_t opt;
50 iscsid_response_t *rsp;
51 iscsid_add_target_rsp_t *res;
52 unsigned i;
53 int opts, auths, tlen;
54 uint32_t tid;
55
56 tlen = cl_get_target(&targ, argc, argv, kind != SEND_TARGETS_LIST);
57 if (tlen == 0) {
58 arg_missing("Target");
59 }
60 if (kind == SEND_TARGETS_LIST && !targ->num_portals) {
61 arg_missing("Target Address");
62 }
63 opts = cl_get_target_opts(&opt, argc, argv);
64 auths = cl_get_auth_opts(&auth, argc, argv);
65 cl_get_symname(targ->sym_name, argc, argv);
66 check_extra_args(argc, argv);
67
68 targ->list_kind = kind;
69
70 send_request(ISCSID_ADD_TARGET, tlen, targ);
71 rsp = get_response(FALSE);
72
73 if (rsp->status) {
74 status_error(rsp->status);
75 }
76 res = (iscsid_add_target_rsp_t *)(void *)rsp->parameter;
77 tid = res->target_id;
78
79 if (kind == SEND_TARGETS_LIST) {
80 printf("Added Send Target %d\n", res->target_id);
81 } else {
82 printf("Added Target %d", res->target_id);
83 if (res->num_portals) {
84 printf(", Portal ");
85 for (i = 0; i < res->num_portals; i++)
86 printf("%d ", res->portal_id[i]);
87 }
88 printf("\n");
89 }
90
91 free_response(rsp);
92
93 if (opts) {
94 opt.list_kind = kind;
95 opt.target_id.id = tid;
96 send_request(ISCSID_SET_TARGET_OPTIONS, sizeof(opt), &opt);
97 rsp = get_response(FALSE);
98 if (rsp->status) {
99 status_error(rsp->status);
100 }
101 free_response(rsp);
102 }
103
104 if (auths) {
105 auth.list_kind = kind;
106 auth.target_id.id = tid;
107 send_request(ISCSID_SET_TARGET_AUTHENTICATION, sizeof(auth), &auth);
108 rsp = get_response(FALSE);
109 if (rsp->status) {
110 status_error(rsp->status);
111 }
112 free_response(rsp);
113 }
114
115 return 0;
116 }
117
118
119 /*
120 * do_remove_target:
121 * Handle both the remove_target and remove_send_target commands.
122 *
123 * Parameter:
124 * argc, argv Shifted arguments
125 * kind Which list
126 *
127 * Returns: 0 if OK - else it doesn't return at all.
128 */
129
130 STATIC int
do_remove_target(int argc,char ** argv,iscsid_list_kind_t kind)131 do_remove_target(int argc, char **argv, iscsid_list_kind_t kind)
132 {
133 iscsid_list_id_t req;
134 iscsid_search_list_req_t srch;
135 iscsid_response_t *rsp;
136
137 if (!cl_get_id('I', &req.id, argc, argv)) {
138 if (!cl_get_string('n', (char *)srch.strval, argc, argv)) {
139 arg_missing("Target ID or Name");
140 }
141 check_extra_args(argc, argv);
142
143 srch.search_kind = FIND_TARGET_NAME;
144 srch.list_kind = kind;
145
146 send_request(ISCSID_SEARCH_LIST, sizeof(srch), &srch);
147 rsp = get_response(FALSE);
148 if (rsp->status) {
149 status_error_slist(rsp->status);
150 }
151 GET_SYM_ID(req.id.id, rsp->parameter);
152 free_response(rsp);
153 } else {
154 check_extra_args(argc, argv);
155 }
156 req.list_kind = kind;
157 send_request(ISCSID_REMOVE_TARGET, sizeof(req), &req);
158 rsp = get_response(TRUE);
159 if (rsp->status) {
160 status_error(rsp->status);
161 }
162 free_response(rsp);
163 printf("OK\n");
164 return 0;
165 }
166
167
168 /*
169 * do_refresh:
170 * Handle the refresh_targets and refresh_isns commands.
171 *
172 * Parameter:
173 * argc, argv Shifted arguments
174 * kind Which list
175 *
176 * Returns: 0 if OK - else it doesn't return at all.
177 */
178
179 STATIC int
do_refresh(int argc,char ** argv,iscsid_list_kind_t kind)180 do_refresh(int argc, char **argv, iscsid_list_kind_t kind)
181 {
182 iscsid_sym_id_t id;
183 iscsid_response_t *rsp;
184 iscsid_refresh_req_t req;
185
186 req.kind = kind;
187
188 if (cl_get_id('I', &id, argc, argv)) {
189 check_extra_args(argc, argv);
190
191 if (!id.id) {
192 iscsid_search_list_req_t srch;
193
194 srch.search_kind = FIND_NAME;
195 srch.list_kind = kind;
196 strlcpy((char *)srch.strval, (char *)id.name,
197 sizeof(srch.strval));
198
199 send_request(ISCSID_SEARCH_LIST, sizeof(srch), &srch);
200 rsp = get_response(FALSE);
201 if (rsp->status) {
202 status_error_slist(rsp->status);
203 }
204 GET_SYM_ID(req.id[0], rsp->parameter);
205 free_response(rsp);
206 } else {
207 req.id[0] = id.id;
208 }
209 req.num_ids = 1;
210 } else {
211 req.num_ids = 0;
212 check_extra_args(argc, argv);
213 }
214
215 req.kind = kind;
216 send_request(ISCSID_REFRESH_TARGETS, sizeof(req), &req);
217
218 rsp = get_response(FALSE);
219 if (rsp->status) {
220 status_error(rsp->status);
221 }
222 printf("OK\n");
223 free_response(rsp);
224 return 0;
225 }
226
227
228 /*
229 * add_target:
230 * Handle the add_target command.
231 *
232 * Parameter: argc, argv (shifted)
233 *
234 * Returns: 0 if OK - else it doesn't return at all.
235 */
236
237 int
add_target(int argc,char ** argv)238 add_target(int argc, char **argv)
239 {
240 return do_add_target(argc, argv, TARGET_LIST);
241 }
242
243
244 /*
245 * remove_target:
246 * Handle the remove_target command.
247 *
248 * Parameter: argc, argv (shifted)
249 *
250 * Returns: 0 if OK - else it doesn't return at all.
251 */
252
253 int
remove_target(int argc,char ** argv)254 remove_target(int argc, char **argv)
255 {
256 return do_remove_target(argc, argv, TARGET_LIST);
257 }
258
259
260 /*
261 * slp_find_targets:
262 * Handle the slp_find_targets command.
263 *
264 * Parameter: argc, argv (shifted)
265 *
266 * Returns: 0 if OK - else it doesn't return at all.
267 *
268 * ToDo: Implement.
269 */
270
271 int
272 /*ARGSUSED*/
slp_find_targets(int argc,char ** argv)273 slp_find_targets(int argc, char **argv)
274 {
275 printf("Not implemented\n");
276 return 5;
277 }
278
279
280 /*
281 * refresh_targets:
282 * Handle the refresh_targets command.
283 *
284 * Parameter: argc, argv (shifted)
285 *
286 * Returns: 0 if OK - else it doesn't return at all.
287 */
288
289 int
refresh_targets(int argc,char ** argv)290 refresh_targets(int argc, char **argv)
291 {
292 return do_refresh(argc, argv, SEND_TARGETS_LIST);
293 }
294
295
296 /*
297 * add_portal:
298 * Handle the add_portal command.
299 *
300 * Parameter:
301 * argc, argv Shifted arguments
302 *
303 * Returns: 0 if OK - else it doesn't return at all.
304 */
305
306 int
add_portal(int argc,char ** argv)307 add_portal(int argc, char **argv)
308 {
309 iscsid_add_portal_req_t port;
310 iscsid_response_t *rsp;
311 iscsid_add_portal_rsp_t *res;
312
313 if (!cl_get_portal(&port, argc, argv)) {
314 arg_missing("Portal Address");
315 }
316 if (!cl_get_id('I', &port.target_id, argc, argv)) {
317 arg_missing("Target ID");
318 }
319 cl_get_symname(port.sym_name, argc, argv);
320 check_extra_args(argc, argv);
321
322 send_request(ISCSID_ADD_PORTAL, sizeof(port), &port);
323 rsp = get_response(FALSE);
324
325 if (rsp->status) {
326 status_error(rsp->status);
327 }
328 res = (iscsid_add_portal_rsp_t *)(void *)rsp->parameter;
329
330 printf("Added Portal %d to Target %d\n",
331 res->portal_id.id, res->target_id.id);
332 free_response(rsp);
333 return 0;
334 }
335
336
337 /*
338 * show_target:
339 * Get information about and display a target entry (including its portals).
340 *
341 * Parameter:
342 * target ID
343 * list kind
344 */
345
346 STATIC void
show_target(uint32_t id,iscsid_list_kind_t kind)347 show_target(uint32_t id, iscsid_list_kind_t kind)
348 {
349 iscsid_list_id_t req;
350 iscsid_response_t *trsp, *prsp;
351 iscsid_get_target_rsp_t *targ;
352 iscsid_get_portal_rsp_t *port;
353 unsigned i;
354
355 /* get target info */
356 req.list_kind = kind;
357 req.id.id = id;
358 req.id.name[0] = '\0';
359 send_request(ISCSID_GET_TARGET_INFO, sizeof(req), &req);
360
361 trsp = get_response(TRUE);
362 if (trsp->status) {
363 status_error(trsp->status);
364 }
365 targ = (iscsid_get_target_rsp_t *)(void *)trsp->parameter;
366
367 /* display basic target info */
368 printf("%6d", targ->target_id.id);
369 if (targ->target_id.name[0]) {
370 printf(" [%s]", targ->target_id.name);
371 }
372 printf(": %s", targ->TargetName);
373 if (targ->TargetAlias[0]) {
374 printf(" (%s)", targ->TargetAlias);
375 }
376 printf("\n");
377
378 /* now get and display info on the target's portals */
379 for (i = 0; i < targ->num_portals; i++) {
380 req.id.id = targ->portal[i];
381 send_request(ISCSID_GET_PORTAL_INFO, sizeof(req), &req);
382 prsp = get_response(FALSE);
383 if (prsp->status) {
384 status_error(prsp->status);
385 }
386 port = (iscsid_get_portal_rsp_t *)(void *)prsp->parameter;
387
388 printf(" %6d", port->portal_id.id);
389 if (port->portal_id.name[0]) {
390 printf(" [%s]", port->portal_id.name);
391 }
392 printf(": %s:%d", port->portal.address, port->portal.port);
393 if (kind != SEND_TARGETS_LIST) {
394 printf(",%d", port->portal.group_tag);
395 }
396 printf("\n");
397 free_response(prsp);
398 }
399 free_response(trsp);
400 }
401
402
403 /*
404 * do_list_targets:
405 * Handle both the list_targets and list_send_targets commands.
406 *
407 * Parameter:
408 * argc, argv Shifted arguments
409 * kind Which list
410 *
411 * Returns: 0 if OK - else it doesn't return at all.
412 */
413
414 STATIC int
do_list_targets(int argc,char ** argv,iscsid_list_kind_t kind)415 do_list_targets(int argc, char **argv, iscsid_list_kind_t kind)
416 {
417 iscsid_get_list_req_t lst;
418 iscsid_response_t *rsp;
419 iscsid_get_list_rsp_t *list;
420 unsigned i;
421
422 check_extra_args(argc, argv);
423
424 /* get the list of targets */
425 lst.list_kind = kind;
426 send_request(ISCSID_GET_LIST, sizeof(lst), &lst);
427 rsp = get_response(TRUE);
428 if (rsp->status) {
429 status_error(rsp->status);
430 }
431 list = (iscsid_get_list_rsp_t *)(void *)rsp->parameter;
432
433 /* display all targets */
434 for (i = 0; i < list->num_entries; i++) {
435 show_target(list->id[i], kind);
436 }
437 free_response(rsp);
438 return 0;
439 }
440
441
442 /*
443 * list_targets:
444 * Handle the list_targets command.
445 *
446 * Parameter: argc, argv (shifted)
447 *
448 * Returns: 0 if OK - else it doesn't return at all.
449 */
450
451 int
list_targets(int argc,char ** argv)452 list_targets(int argc, char **argv)
453 {
454 return do_list_targets(argc, argv, TARGET_LIST);
455 }
456
457
458 /*
459 * add_send_target:
460 * Handle the add_target command.
461 *
462 * Parameter: argc, argv (shifted)
463 *
464 * Returns: 0 if OK - else it doesn't return at all.
465 */
466
467 int
add_send_target(int argc,char ** argv)468 add_send_target(int argc, char **argv)
469 {
470 return do_add_target(argc, argv, SEND_TARGETS_LIST);
471 }
472
473
474 /*
475 * remove_send_target:
476 * Handle the remove_target command.
477 *
478 * Parameter: argc, argv (shifted)
479 *
480 * Returns: 0 if OK - else it doesn't return at all.
481 */
482
483 int
remove_send_target(int argc,char ** argv)484 remove_send_target(int argc, char **argv)
485 {
486 return do_remove_target(argc, argv, SEND_TARGETS_LIST);
487 }
488
489
490 /*
491 * list_send_targets:
492 * Handle the list_send_targets command.
493 *
494 * Parameter: argc, argv (shifted)
495 *
496 * Returns: 0 if OK - else it doesn't return at all.
497 */
498
499 int
list_send_targets(int argc,char ** argv)500 list_send_targets(int argc, char **argv)
501 {
502 return do_list_targets(argc, argv, SEND_TARGETS_LIST);
503 }
504
505
506 /*
507 * add_isns_server:
508 * Handle the add_isns_server command.
509 *
510 * Parameter: argc, argv (shifted)
511 *
512 * Returns: 0 if OK - else it doesn't return at all.
513 */
514
515 int
add_isns_server(int argc,char ** argv)516 add_isns_server(int argc, char **argv)
517 {
518 iscsid_add_isns_server_req_t arg;
519 iscsid_add_isns_server_rsp_t *res;
520 iscsid_response_t *rsp;
521
522 memset(&arg, 0x0, sizeof(arg));
523 if (!(cl_get_isns(&arg, argc, argv))) {
524 arg_missing("Server Address");
525 }
526 check_extra_args(argc, argv);
527
528 send_request(ISCSID_ADD_ISNS_SERVER, sizeof(arg), &arg);
529 rsp = get_response(FALSE);
530
531 if (rsp->status) {
532 status_error(rsp->status);
533 }
534 res = (iscsid_add_isns_server_rsp_t *)(void *)rsp->parameter;
535
536 printf("Added iSNS Server ID %d\n", res->server_id);
537
538 free_response(rsp);
539 return 0;
540 }
541
542
543 /*
544 * remove_isns_server:
545 * Handle the add_isns_server command.
546 *
547 * Parameter: argc, argv (shifted)
548 *
549 * Returns: 0 if OK - else it doesn't return at all.
550 */
551
552 int
remove_isns_server(int argc,char ** argv)553 remove_isns_server(int argc, char **argv)
554 {
555 iscsid_sym_id_t req;
556 iscsid_search_list_req_t srch;
557 iscsid_response_t *rsp;
558
559 if (!cl_get_id('I', &req, argc, argv)) {
560 if (!cl_get_string('a', (char *)srch.strval, argc, argv)) {
561 arg_missing("Server Address");
562 }
563 check_extra_args(argc, argv);
564 srch.search_kind = FIND_ADDRESS;
565 srch.list_kind = ISNS_LIST;
566
567 send_request(ISCSID_SEARCH_LIST, sizeof(srch), &srch);
568 rsp = get_response(FALSE);
569 if (rsp->status) {
570 status_error_slist(rsp->status);
571 }
572 GET_SYM_ID(req.id, rsp->parameter);
573 free_response(rsp);
574 } else {
575 check_extra_args(argc, argv);
576 }
577 send_request(ISCSID_REMOVE_ISNS_SERVER, sizeof(req), &req);
578 rsp = get_response(TRUE);
579 if (rsp->status) {
580 status_error(rsp->status);
581 }
582 free_response(rsp);
583
584 printf("OK\n");
585 return 0;
586 }
587
588
589 /*
590 * find_isns_servers:
591 * Handle the find_isns_servers command.
592 *
593 * Parameter: argc, argv (shifted)
594 *
595 * Returns: 0 if OK - else it doesn't return at all.
596 */
597
598 int
599 /*ARGSUSED*/
find_isns_servers(int argc,char ** argv)600 find_isns_servers(int argc, char **argv)
601 {
602 printf("Not implemented\n");
603 return 5;
604 }
605
606
607 /*
608 * list_isns_servers:
609 * Handle the list_isns_servers command.
610 *
611 * Parameter: argc, argv (shifted)
612 *
613 * Returns: 0 if OK - else it doesn't return at all.
614 */
615
616 int
list_isns_servers(int argc,char ** argv)617 list_isns_servers(int argc, char **argv)
618 {
619 iscsid_get_list_req_t lst;
620 iscsid_response_t *rsp, *prsp;
621 iscsid_get_list_rsp_t *list;
622 iscsid_get_isns_server_rsp_t *isns;
623 iscsid_sym_id_t req;
624 unsigned i;
625
626 memset(&req, 0x0, sizeof(req));
627 check_extra_args(argc, argv);
628
629 /* get the list of servers */
630 lst.list_kind = ISNS_LIST;
631 send_request(ISCSID_GET_LIST, sizeof(lst), &lst);
632 rsp = get_response(TRUE);
633 if (rsp->status) {
634 status_error(rsp->status);
635 }
636 list = (iscsid_get_list_rsp_t *)(void *)rsp->parameter;
637
638 /* display all servers */
639 for (i = 0; i < list->num_entries; i++) {
640 req.id = list->id[i];
641 send_request(ISCSID_GET_ISNS_SERVER, sizeof(req), &req);
642 prsp = get_response(FALSE);
643 if (prsp->status)
644 status_error(prsp->status);
645
646 isns = (iscsid_get_isns_server_rsp_t *)(void *)prsp->parameter;
647 printf("%6d: %s\n", list->id[i], isns->address);
648 free_response(prsp);
649 }
650 free_response(rsp);
651 return 0;
652 }
653
654
655 /*
656 * refresh_isns:
657 * Handle the refresh_isns command.
658 *
659 * Parameter: argc, argv (shifted)
660 *
661 * Returns: 0 if OK - else it doesn't return at all.
662 */
663
664 int
refresh_isns(int argc,char ** argv)665 refresh_isns(int argc, char **argv)
666 {
667 return do_refresh(argc, argv, ISNS_LIST);
668 }
669
670
671 /*
672 * add_initiator:
673 * Handle the add_initiator command.
674 *
675 * Parameter: argc, argv (shifted)
676 *
677 * Returns: 0 if OK - else it doesn't return at all.
678 */
679
680 int
add_initiator(int argc,char ** argv)681 add_initiator(int argc, char **argv)
682 {
683 iscsid_add_initiator_req_t req;
684 iscsid_add_initiator_rsp_t *res;
685 iscsid_response_t *rsp;
686
687 memset(&req, 0x0, sizeof(req));
688 if (!cl_get_string('a', (char *)req.address, argc, argv)) {
689 arg_missing("Interface Address");
690 }
691 cl_get_symname(req.name, argc, argv);
692 check_extra_args(argc, argv);
693
694 send_request(ISCSID_ADD_INITIATOR_PORTAL, sizeof(req), &req);
695 rsp = get_response(FALSE);
696 if (rsp->status) {
697 status_error(rsp->status);
698 }
699 res = (iscsid_add_initiator_rsp_t *)(void *)rsp->parameter;
700 printf("Added Initiator Portal %d\n", res->portal_id);
701
702 free_response(rsp);
703 return 0;
704 }
705
706
707 /*
708 * remove_initiator:
709 * Handle the remove_initiator command.
710 *
711 * Parameter: argc, argv (shifted)
712 *
713 * Returns: 0 if OK - else it doesn't return at all.
714 */
715
716 int
remove_initiator(int argc,char ** argv)717 remove_initiator(int argc, char **argv)
718 {
719 iscsid_sym_id_t req;
720 iscsid_response_t *rsp;
721
722 memset(&req, 0x0, sizeof(req));
723 if (!cl_get_id('I', &req, argc, argv)) {
724 arg_missing("Initiator Portal ID");
725 }
726 check_extra_args(argc, argv);
727
728 send_request(ISCSID_REMOVE_INITIATOR_PORTAL, sizeof(req), &req);
729 rsp = get_response(FALSE);
730 if (rsp->status) {
731 status_error(rsp->status);
732 }
733 free_response(rsp);
734
735 printf("OK\n");
736 return 0;
737 }
738
739 /*
740 * list_initiators:
741 * Handle the list_initiators command.
742 *
743 * Parameter: argc, argv (shifted)
744 *
745 * Returns: 0 if OK - else it doesn't return at all.
746 */
747
748 int
list_initiators(int argc,char ** argv)749 list_initiators(int argc, char **argv)
750 {
751 iscsid_get_list_req_t lst;
752 iscsid_response_t *rsp, *prsp;
753 iscsid_get_list_rsp_t *list;
754 iscsid_get_initiator_rsp_t *init;
755 iscsid_sym_id_t req;
756 unsigned i;
757
758 memset(&req, 0x0, sizeof(req));
759 check_extra_args(argc, argv);
760
761 /* get the list of servers */
762 lst.list_kind = INITIATOR_LIST;
763 send_request(ISCSID_GET_LIST, sizeof(lst), &lst);
764 rsp = get_response(TRUE);
765 if (rsp->status) {
766 status_error(rsp->status);
767 }
768 list = (iscsid_get_list_rsp_t *)(void *)rsp->parameter;
769
770 /* display all servers */
771 for (i = 0; i < list->num_entries; i++) {
772 req.id = list->id[i];
773 send_request(ISCSID_GET_INITIATOR_PORTAL, sizeof(req), &req);
774 prsp = get_response(FALSE);
775 if (prsp->status) {
776 status_error(prsp->status);
777 }
778 init = (iscsid_get_initiator_rsp_t *)(void *)prsp->parameter;
779 printf("%6d", init->portal_id.id);
780 if (init->portal_id.name[0]) {
781 printf("[%s]", init->portal_id.name);
782 }
783 printf(": %s\n", init->address);
784 free_response(prsp);
785 }
786 free_response(rsp);
787 return 0;
788 }
789
790
791 /*
792 * login_or_add:
793 * Common routine for login and add_connection. Handles the actual command,
794 * the only pre-initialized component is the session ID in the login request
795 * for add_connection.
796 *
797 * Parameters: the login request, plus argc & argv
798 */
799
800 STATIC void
login_or_add(iscsid_login_req_t * loginp,int argc,char ** argv)801 login_or_add(iscsid_login_req_t * loginp, int argc, char **argv)
802 {
803 iscsid_add_target_req_t *targ = NULL;
804 iscsid_add_target_rsp_t *tgtrsp;
805 iscsid_set_target_authentication_req_t auth;
806 iscsid_get_set_target_options_t opt;
807 iscsid_search_list_req_t srch;
808 iscsid_response_t *rsp;
809 int opts, auths, tlen;
810
811 /* get the remaining parameters */
812 opts = cl_get_target_opts(&opt, argc, argv);
813 auths = cl_get_auth_opts(&auth, argc, argv);
814 cl_get_symname(loginp->sym_name, argc, argv);
815 cl_get_id ('i', &loginp->initiator_id, argc, argv);
816
817 /* do we have a portal ID? */
818 if (!cl_get_id('P', &loginp->portal_id, argc, argv)) {
819 /* No portal ID - then we must have a target name */
820 if (!(tlen = cl_get_target(&targ, argc, argv, TRUE))) {
821 if (NO_ID(&loginp->session_id)) {
822 arg_missing("Target");
823 }
824 }
825
826 check_extra_args(argc, argv);
827
828 if (targ != NULL) {
829 /* was a complete target with portal specified? */
830 if (targ->num_portals) {
831 /* then add it like in an add_target command */
832 targ->list_kind = TARGET_LIST;
833 send_request(ISCSID_ADD_TARGET, tlen, targ);
834 rsp = get_response(FALSE);
835 if (rsp->status) {
836 status_error(rsp->status);
837 }
838 tgtrsp = (iscsid_add_target_rsp_t *)(void *)(rsp->parameter);
839 (void) memcpy(&loginp->portal_id.id, &tgtrsp->target_id,
840 sizeof(loginp->portal_id.id));
841 } else {
842 /* else find the target by its TargetName */
843 srch.search_kind = FIND_TARGET_NAME;
844 srch.list_kind = TARGET_LIST;
845 strlcpy((char *)srch.strval, (char *)targ->TargetName,
846 sizeof(srch.strval));
847
848 send_request(ISCSID_SEARCH_LIST, sizeof(srch), &srch);
849 rsp = get_response(FALSE);
850 if (rsp->status) {
851 status_error_slist(rsp->status);
852 }
853 GET_SYM_ID(loginp->portal_id.id, rsp->parameter);
854 }
855 free_response(rsp);
856 }
857 } else
858 check_extra_args(argc, argv);
859
860 /* Options specified? Then set them */
861 if (opts) {
862 opt.target_id = loginp->portal_id;
863 opt.list_kind = TARGET_LIST;
864 send_request(ISCSID_SET_TARGET_OPTIONS, sizeof(opt), &opt);
865 rsp = get_response(FALSE);
866 if (rsp->status) {
867 status_error(rsp->status);
868 }
869 free_response(rsp);
870 }
871 /* Authentication options specified? Then set them */
872 if (auths) {
873 auth.target_id = loginp->portal_id;
874 auth.list_kind = TARGET_LIST;
875 send_request(ISCSID_SET_TARGET_AUTHENTICATION, sizeof(auth), &auth);
876 rsp = get_response(FALSE);
877 if (rsp->status) {
878 status_error(rsp->status);
879 }
880 free_response(rsp);
881 }
882 }
883
884
885 /*
886 * login:
887 * Handle login command.
888 *
889 * Parameter: argc, argv (shifted)
890 *
891 * Returns: 0 if OK - else it doesn't return at all.
892 */
893
894 int
login(int argc,char ** argv)895 login(int argc, char **argv)
896 {
897 iscsid_login_req_t loginp;
898 iscsid_login_rsp_t *res;
899 iscsid_response_t *rsp;
900
901 memset(&loginp, 0x0, sizeof(loginp));
902 loginp.login_type = (cl_get_opt('m', argc, argv))
903 ? ISCSI_LOGINTYPE_NOMAP : ISCSI_LOGINTYPE_MAP;
904
905 login_or_add(&loginp, argc, argv);
906
907 send_request(ISCSID_LOGIN, sizeof(loginp), &loginp);
908
909 rsp = get_response(FALSE);
910 if (rsp->status) {
911 status_error(rsp->status);
912 }
913 res = (iscsid_login_rsp_t *)(void *)rsp->parameter;
914 printf("Created Session %d, Connection %d\n",
915 res->session_id.id, res->connection_id.id);
916
917 free_response(rsp);
918 return 0;
919 }
920
921
922 /*
923 * logout:
924 * Handle logout command.
925 *
926 * Parameter: argc, argv (shifted)
927 *
928 * Returns: 0 if OK - else it doesn't return at all.
929 */
930
931 int
logout(int argc,char ** argv)932 logout(int argc, char **argv)
933 {
934 iscsid_sym_id_t req;
935 iscsid_response_t *rsp;
936
937 if (!cl_get_id('I', &req, argc, argv)) {
938 arg_missing("Session");
939 }
940 check_extra_args(argc, argv);
941
942 send_request(ISCSID_LOGOUT, sizeof(req), &req);
943 rsp = get_response(FALSE);
944 if (rsp->status) {
945 status_error(rsp->status);
946 }
947 free_response(rsp);
948
949 printf("OK\n");
950 return 0;
951 }
952
953
954 /*
955 * add_connection:
956 * Handle add_connection command.
957 *
958 * Parameter: argc, argv (shifted)
959 *
960 * Returns: 0 if OK - else it doesn't return at all.
961 */
962
963 int
add_connection(int argc,char ** argv)964 add_connection(int argc, char **argv)
965 {
966 iscsid_login_req_t loginp;
967 iscsid_login_rsp_t *loginrsp;
968 iscsid_response_t *rsp;
969
970 memset(&loginp, 0x0, sizeof(loginp));
971 loginp.login_type = ISCSI_LOGINTYPE_MAP;
972 cl_get_id('I', &loginp.session_id, argc, argv);
973
974 login_or_add(&loginp, argc, argv);
975
976 send_request(ISCSID_ADD_CONNECTION, sizeof(loginp), &loginp);
977
978 rsp = get_response(FALSE);
979 if (rsp->status) {
980 status_error(rsp->status);
981 }
982 loginrsp = (iscsid_login_rsp_t *)(void *)(rsp->parameter);
983 printf("Added Connection %d\n", loginrsp->connection_id.id);
984
985 free_response(rsp);
986 return 0;
987 }
988
989
990 /*
991 * remove_connection:
992 * Handle remove connection command
993 *
994 * Parameter: argc, argv (shifted)
995 *
996 * Returns: 0 if OK - else it doesn't return at all.
997 */
998
999 int
remove_connection(int argc,char ** argv)1000 remove_connection(int argc, char **argv)
1001 {
1002 iscsid_remove_connection_req_t req;
1003 iscsid_response_t *rsp;
1004
1005 if (!cl_get_id('I', &req.session_id, argc, argv)) {
1006 arg_missing("Session");
1007 }
1008 if (!cl_get_id('C', &req.connection_id, argc, argv)) {
1009 arg_missing("Connection");
1010 }
1011 check_extra_args(argc, argv);
1012
1013 send_request(ISCSID_REMOVE_CONNECTION, sizeof(req), &req);
1014 rsp = get_response(FALSE);
1015 if (rsp->status) {
1016 status_error(rsp->status);
1017 }
1018 free_response(rsp);
1019
1020 printf("OK\n");
1021 return 0;
1022 }
1023
1024
1025 /*
1026 * list_sessions:
1027 * Handle list_sessions command.
1028 *
1029 * Parameter: argc, argv (shifted)
1030 *
1031 * Returns: 0 if OK - else it doesn't return at all.
1032 *
1033 * ToDo: initiator portals, connection recurse
1034 */
1035
1036 int
list_sessions(int argc,char ** argv)1037 list_sessions(int argc, char **argv)
1038 {
1039 iscsid_response_t *lrsp, *rsp;
1040 iscsid_get_session_list_rsp_t *list;
1041 iscsid_session_list_entry_t *ent;
1042 iscsid_get_connection_info_req_t creq;
1043 iscsid_get_connection_info_rsp_t *info;
1044 iscsid_sym_id_t clreq;
1045 iscsid_get_connection_list_rsp_t *clinfo;
1046 iscsid_connection_list_entry_t *clent;
1047 unsigned i;
1048 unsigned j;
1049 int lconn;
1050
1051 memset(&creq, 0x0, sizeof(creq));
1052 memset(&clreq, 0x0, sizeof(clreq));
1053 lconn = cl_get_opt('c', argc, argv);
1054
1055 check_extra_args(argc, argv);
1056
1057 send_request(ISCSID_GET_SESSION_LIST, 0, NULL);
1058 lrsp = get_response(TRUE);
1059 if (lrsp->status) {
1060 status_error(lrsp->status);
1061 }
1062 list = (iscsid_get_session_list_rsp_t *)(void *)lrsp->parameter;
1063
1064 for (i = 0, ent = list->session; i < list->num_entries; i++, ent++) {
1065 creq.session_id.id = ent->session_id.id;
1066 send_request(ISCSID_GET_CONNECTION_INFO, sizeof(creq), &creq);
1067 rsp = get_response(FALSE);
1068 if (rsp->status) {
1069 status_error(rsp->status);
1070 }
1071 info = (iscsid_get_connection_info_rsp_t *)(void *)rsp->parameter;
1072
1073 printf("Session %d", info->session_id.id);
1074 if (info->session_id.name[0]) {
1075 printf("[%s]", info->session_id.name);
1076 }
1077 printf(": Target %s", info->TargetName);
1078 if (info->target_portal_id.name[0]) {
1079 printf(" [%s]", info->target_portal_id.name);
1080 }
1081 printf("\n");
1082
1083 if (lconn) {
1084 clreq.id = info->session_id.id;
1085 send_request(ISCSID_GET_CONNECTION_LIST, sizeof(clreq), &clreq);
1086 rsp = get_response(FALSE);
1087 if (rsp->status) {
1088 status_error(rsp->status);
1089 }
1090 clinfo = (iscsid_get_connection_list_rsp_t *)(void *)rsp->parameter;
1091
1092 for (j = 0, clent = clinfo->connection;
1093 j < clinfo->num_connections; j++, clent++) {
1094 printf(" Connection %d", clent->connection_id.id);
1095 if (clent->connection_id.name[0]) {
1096 printf("[%s]", clent->connection_id.name);
1097 }
1098 printf(" Address %s:%d,%d\n", clent->target_portal.address,
1099 clent->target_portal.port,
1100 clent->target_portal.group_tag);
1101 }
1102 }
1103 }
1104
1105 return 0;
1106 }
1107
1108
1109 /*
1110 * set_node_name:
1111 * Handle the set_node_name command.
1112 *
1113 * Parameter: argc, argv (shifted)
1114 *
1115 * Returns: 0 if OK - else it doesn't return at all.
1116 */
1117
1118 int
set_node_name(int argc,char ** argv)1119 set_node_name(int argc, char **argv)
1120 {
1121 iscsid_set_node_name_req_t req;
1122 iscsid_response_t *rsp;
1123 uint64_t isid;
1124
1125 memset(&req, 0x0, sizeof(req));
1126 if (!cl_get_string('n', (char *)req.InitiatorName, argc, argv)) {
1127 arg_missing("Initiator Name");
1128 }
1129 cl_get_string('A', (char *)req.InitiatorAlias, argc, argv);
1130 isid = cl_get_longlong('i', argc, argv);
1131 hton6(req.ISID, isid);
1132
1133 check_extra_args(argc, argv);
1134
1135 send_request(ISCSID_SET_NODE_NAME, sizeof(req), &req);
1136
1137 rsp = get_response(FALSE);
1138 if (rsp->status) {
1139 status_error(rsp->status);
1140 }
1141 free_response(rsp);
1142
1143 printf("OK\n");
1144 return 0;
1145 }
1146
1147 /*
1148 * get_version:
1149 * Handle the version command.
1150 *
1151 * Parameter: argc, argv (shifted)
1152 *
1153 * Returns: 0 if OK - else it doesn't return at all.
1154 */
1155
1156 int
1157 /*ARGSUSED*/
get_version(int argc,char ** argv)1158 get_version(int argc, char **argv)
1159 {
1160 iscsid_response_t *rsp;
1161 iscsid_get_version_rsp_t *ver;
1162
1163 send_request(ISCSID_GET_VERSION, 0, NULL);
1164 rsp = get_response(FALSE);
1165 if (rsp->status) {
1166 status_error(rsp->status);
1167 }
1168 ver = (iscsid_get_version_rsp_t *)(void *)rsp->parameter;
1169 printf("%s\n%s\n%s\n", VERSION_STRING, ver->version_string,
1170 ver->driver_version_string);
1171
1172 return 0;
1173 }
1174