1/* $NetBSD: iscsic_daemonif.c,v 1.1 2011/10/23 21:11:23 agc 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 44STATIC int 45do_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 130STATIC int 131do_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 179STATIC int 180do_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 237int 238add_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 253int 254remove_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 271int 272/*ARGSUSED*/ 273slp_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 289int 290refresh_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 306int 307add_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 346STATIC void 347show_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 414STATIC int 415do_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 451int 452list_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 467int 468add_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 483int 484remove_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 499int 500list_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 515int 516add_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 552int 553remove_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 598int 599/*ARGSUSED*/ 600find_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 616int 617list_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 664int 665refresh_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 680int 681add_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 716int 717remove_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 748int 749list_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 800STATIC void 801login_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 894int 895login(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 931int 932logout(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 963int 964add_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 999int 1000remove_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 1036int 1037list_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 1118int 1119set_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 1156int 1157/*ARGSUSED*/ 1158get_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 1175 1176#ifdef ISCSI_DEBUG 1177/* 1178 * kill_daemon: 1179 * Handle kill_daemon command. 1180 * 1181 * Parameter: argc, argv (shifted) 1182 * 1183 * Returns: Always 0. 1184*/ 1185 1186int 1187kill_daemon(int argc, char **argv) 1188{ 1189 check_extra_args(argc, argv); 1190 1191 send_request(ISCSID_DAEMON_TERMINATE, 0, NULL); 1192 return 0; 1193} 1194#endif 1195