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