xref: /netbsd-src/sbin/iscsictl/iscsic_daemonif.c (revision 44f0e14601b1088fbb036e32df0ddc4b341209c0)
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