1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2000-2002 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 /* 30 * WARNING: The contents of this file are shared by all projects 31 * that wish to perform remote Dynamic Reconfiguration (DR) 32 * operations. Copies of this file can be found in the following 33 * locations: 34 * 35 * Project Location 36 * ------- -------- 37 * Solaris usr/src/cmd/dcs/sparc/sun4u/%M% 38 * SMS src/sms/lib/librdr/%M% 39 * 40 * In order for proper communication to occur, the files in the 41 * above locations must match exactly. Any changes that are made 42 * to this file should be made to all of the files in the list. 43 */ 44 45 /* 46 * This file is a module that contains an interface for performing 47 * remote Dynamic Reconfiguration (DR) operations. It hides all 48 * network operations such as establishing a connection, sending 49 * and receiving messages, and closing a connection. It also handles 50 * the packing and unpacking of messages for network transport. 51 */ 52 53 #include <stdio.h> 54 #include <stdlib.h> 55 #include <unistd.h> 56 #include <string.h> 57 #include <fcntl.h> 58 #include <errno.h> 59 #include <netdb.h> 60 #include <sys/socket.h> 61 #include <netinet/tcp.h> 62 63 #include "remote_cfg.h" 64 #include "rdr_param_types.h" 65 #include "rdr_messages.h" 66 67 68 /* 69 * Structure holding information about 70 * all possible variable length fields 71 * that can be present in an RDR message. 72 */ 73 typedef struct { 74 int ap_id_int_size; 75 int ap_id_char_size; 76 int *ap_id_sizes; 77 char *ap_id_chars; 78 int errstring_strlen; 79 int errstring_pad_sz; 80 int options_strlen; 81 int options_pad_sz; 82 int listopts_strlen; 83 int listopts_pad_sz; 84 int function_strlen; 85 int function_pad_sz; 86 } rdr_variable_message_info_t; 87 88 89 /* 90 * A table of maximum sizes for each message type. Message size is 91 * validated when the message header is first received. This prevents 92 * a situation where a corrupted or bad header can cause too much 93 * memory to be allocated. 94 * 95 * The message size limits were chosen to be a very generous upper bound 96 * on the amount of data each message can send. They are not intended to 97 * be a precise measurement of the data size. 98 */ 99 #define NOMSG 0 100 #define SHORTMSG (150 * 1024) /* 150 KB */ 101 #define LONGMSG (3 * 1024 * 1024) /* 3 MB */ 102 103 struct { 104 ulong_t req_max; 105 ulong_t reply_max; 106 } msg_sizes[] = { 107 /* 108 * request reply 109 * ------- ----- 110 */ 111 { NOMSG, NOMSG }, /* Invalid Opcode */ 112 { SHORTMSG, SHORTMSG }, /* RDR_SES_REQ */ 113 { NOMSG, NOMSG }, /* RDR_SES_ESTBL */ 114 { NOMSG, NOMSG }, /* RDR_SES_END */ 115 { SHORTMSG, SHORTMSG }, /* RDR_CONF_CHANGE_STATE */ 116 { SHORTMSG, SHORTMSG }, /* RDR_CONF_PRIVATE_FUNC */ 117 { SHORTMSG, SHORTMSG }, /* RDR_CONF_TEST */ 118 { SHORTMSG, LONGMSG }, /* RDR_CONF_LIST_EXT */ 119 { SHORTMSG, NOMSG }, /* RDR_CONF_HELP */ 120 { SHORTMSG, NOMSG }, /* RDR_CONF_AP_ID_CMP */ 121 { SHORTMSG, NOMSG }, /* RDR_CONF_ABORT_CMD */ 122 { SHORTMSG, SHORTMSG }, /* RDR_CONF_CONFIRM_CALLBACK */ 123 { SHORTMSG, NOMSG }, /* RDR_CONF_MSG_CALLBACK */ 124 { SHORTMSG, LONGMSG } /* RDR_RSRC_INFO */ 125 }; 126 127 128 #define RDR_BAD_FD (-1) 129 130 #define RDR_MSG_HDR_SIZE sizeof (rdr_msg_hdr_t) 131 132 static const int RDR_ALIGN_64_BIT = 8; /* 8 bytes */ 133 134 135 /* 136 * Static Function Declarations 137 */ 138 139 /* 140 * Socket Related Routines 141 */ 142 static int rdr_setopt(int fd, int name, int level); 143 144 static int rdr_bind(int fd, struct sockaddr *addr); 145 146 static int rdr_snd(int fd, rdr_msg_hdr_t *hdr, char *data, int data_sz, 147 int timeout); 148 static int rdr_snd_raw(int fd, char *msg, int data_sz, int timeout); 149 150 static int rdr_rcv(int fd, rdr_msg_hdr_t *hdr, char **data, int timeout); 151 152 static int rdr_rcv_raw(int fd, char *msg, int data_size, int timeout); 153 154 155 /* 156 * Data Validation Routines 157 */ 158 static int validate_header(rdr_msg_hdr_t *hdr); 159 160 161 /* 162 * Session Request Routines 163 */ 164 static int pack_ses_req_request(ses_req_params_t *params, char **buf, 165 int *buf_size); 166 static int unpack_ses_req_request(ses_req_params_t *params, const char *buf); 167 168 static int pack_ses_req_reply(ses_req_params_t *params, char **buf, 169 int *buf_size); 170 static int unpack_ses_req_reply(ses_req_params_t *params, const char *buf); 171 172 173 /* 174 * Change State Routines 175 */ 176 static int pack_change_state_request(change_state_params_t *params, 177 char **buf, int *buf_size); 178 static int unpack_change_state_request(change_state_params_t *params, 179 const char *buf); 180 static int pack_change_state_reply(change_state_params_t *params, 181 char **buf, int *buf_size); 182 static int unpack_change_state_reply(change_state_params_t *params, 183 const char *buf); 184 185 /* 186 * Private Func Routines 187 */ 188 static int pack_private_func_request(private_func_params_t *params, 189 char **buf, int *buf_size); 190 static int unpack_private_func_request(private_func_params_t *params, 191 const char *buf); 192 static int pack_private_func_reply(private_func_params_t *params, 193 char **buf, int *buf_size); 194 static int unpack_private_func_reply(private_func_params_t *params, 195 const char *buf); 196 197 /* 198 * Test Routines 199 */ 200 static int pack_test_request(test_params_t *params, char **buf, int *buf_size); 201 202 static int unpack_test_request(test_params_t *params, const char *buf); 203 204 static int pack_test_reply(test_params_t *params, char **buf, int *buf_size); 205 206 static int unpack_test_reply(test_params_t *params, const char *buf); 207 208 209 /* 210 * List Ext Routines 211 */ 212 static int pack_list_ext_request(list_ext_params_t *params, char **buf, 213 int *buf_size); 214 static int unpack_list_ext_request(list_ext_params_t *params, const char *buf); 215 216 static int pack_list_ext_reply(list_ext_params_t *params, char **buf, 217 int *buf_size); 218 static int unpack_list_ext_reply(list_ext_params_t *params, const char *buf); 219 220 221 /* 222 * Help Routines 223 */ 224 static int pack_help_request(help_params_t *params, char **buf, int *buf_size); 225 226 static int unpack_help_request(help_params_t *params, const char *buf); 227 228 229 /* 230 * Ap Id Cmp Routines 231 */ 232 static int pack_ap_id_cmp_request(ap_id_cmp_params_t *params, char **buf, 233 int *buf_size); 234 static int unpack_ap_id_cmp_request(ap_id_cmp_params_t *params, 235 const char *buf); 236 237 /* 238 * Abort Routines 239 */ 240 static int pack_abort_cmd_request(abort_cmd_params_t *params, char **buf, 241 int *buf_size); 242 static int unpack_abort_cmd_request(abort_cmd_params_t *params, 243 const char *buf); 244 245 /* 246 * Confirm Callback Routines 247 */ 248 static int pack_confirm_request(confirm_callback_params_t *params, char **buf, 249 int *buf_size); 250 static int unpack_confirm_request(confirm_callback_params_t *params, 251 const char *buf); 252 static int pack_confirm_reply(confirm_callback_params_t *params, 253 char **buf, int *buf_size); 254 static int unpack_confirm_reply(confirm_callback_params_t *params, 255 const char *buf); 256 257 /* 258 * Message Callback Routines 259 */ 260 static int pack_message_request(msg_callback_params_t *params, char **buf, 261 int *buf_size); 262 static int unpack_message_request(msg_callback_params_t *params, 263 const char *buf); 264 265 /* 266 * Resource Info Routines 267 */ 268 static int pack_rsrc_info_request(rsrc_info_params_t *params, char **buf, 269 int *buf_size); 270 static int unpack_rsrc_info_request(rsrc_info_params_t *params, 271 const char *buf); 272 static int pack_rsrc_info_reply(rsrc_info_params_t *params, char **buf, 273 int *buf_size); 274 static int unpack_rsrc_info_reply(rsrc_info_params_t *params, const char *buf); 275 276 /* 277 * General Pack/Unpack Routines 278 */ 279 static int pack_ap_ids(int num_ap_ids, char *const *ap_ids, 280 rdr_variable_message_info_t *var_msg_info); 281 static int unpack_ap_ids(int num_ap_ids, char **ap_ids, const char *buf, 282 rdr_variable_message_info_t *var_msg_info); 283 284 /* 285 * Find Variable Info Sizes 286 */ 287 static int find_options_sizes(char *options, 288 rdr_variable_message_info_t *var_msg_info); 289 static int find_listopts_sizes(char *listopts, 290 rdr_variable_message_info_t *var_msg_info); 291 static int find_function_sizes(char *function, 292 rdr_variable_message_info_t *var_msg_info); 293 static int find_errstring_sizes(char **errstring, 294 rdr_variable_message_info_t *var_msg_info); 295 296 /* 297 * Extract Info From Buffers 298 */ 299 static int get_ap_ids_from_buf(char ***ap_id_ptr, int num_ap_ids, 300 rdr_variable_message_info_t *var_msg_info, 301 const char *buf); 302 static int get_string_from_buf(char **stringptr, int strsize, const char *buf); 303 304 305 /* 306 * Cleanup Routines 307 */ 308 static int cleanup_ap_ids(int num_ap_ids, char **ap_ids); 309 310 static int cleanup_errstring(char **errstring); 311 312 static void cleanup_variable_ap_id_info( 313 rdr_variable_message_info_t *var_msg_info); 314 315 /* 316 * Public Functions 317 */ 318 319 320 /* 321 * rdr_open: 322 * 323 * Establish a transport endpoint to prepare for a new 324 * connection. Returns a file descriptor representing the 325 * new transport if successful or RDR_BAD_FD upon failure. 326 */ 327 int 328 rdr_open(int family) 329 { 330 int newfd; 331 332 333 if ((newfd = socket(family, SOCK_STREAM, 0)) == NULL) { 334 return (RDR_BAD_FD); 335 } 336 337 return (newfd); 338 } 339 340 341 /* 342 * rdr_init: 343 * 344 * Initialize a transport endpoint. This involves binding to 345 * a particular port and setting any user specified socket 346 * options. 347 */ 348 int 349 rdr_init(int fd, struct sockaddr *addr, int *opts, int num_opts, int blog) 350 { 351 int i; 352 353 354 /* sanity checks */ 355 if ((fd < 0) || (addr == NULL)) { 356 return (RDR_ERROR); 357 } 358 359 if ((opts == NULL) || (num_opts < 0)) { 360 num_opts = 0; 361 } 362 363 /* bind the address, if is not already bound */ 364 if (rdr_bind(fd, addr) != RDR_OK) { 365 return (RDR_NET_ERR); 366 } 367 368 /* 369 * Set TCP_NODELAY for this endpoint. This disables Nagle's 370 * algorithm that can cause a delay in sending small sized 371 * messages. Since most of the RDR messages are small, this 372 * is a restriction that negatively impacts performance. 373 */ 374 if (rdr_setopt(fd, TCP_NODELAY, IPPROTO_TCP) != RDR_OK) { 375 return (RDR_NET_ERR); 376 } 377 378 /* set the user specified socket options */ 379 for (i = 0; i < num_opts; i++) { 380 if (rdr_setopt(fd, opts[i], SOL_SOCKET) != RDR_OK) { 381 return (RDR_NET_ERR); 382 } 383 } 384 385 /* 386 * If blog is not zero, it is a server that is being 387 * initialized. In order for it to be able to accept 388 * connections, we have to set the size of the incoming 389 * connection queue. 390 */ 391 if (blog != 0) { 392 if (listen(fd, blog) == -1) { 393 return (RDR_NET_ERR); 394 } 395 } 396 397 return (RDR_OK); 398 } 399 400 401 /* 402 * rdr_connect_clnt: 403 * 404 * Perform the necessary steps for a client to connect to 405 * a server process. The required information is the file 406 * descriptor for the transport endpoint, and the remote 407 * address. 408 */ 409 int 410 rdr_connect_clnt(int fd, struct sockaddr *addr) 411 { 412 unsigned int addr_len; 413 414 415 /* sanity check */ 416 if (addr == NULL) { 417 return (RDR_ERROR); 418 } 419 420 /* initialize the address length */ 421 switch (addr->sa_family) { 422 423 case AF_INET: 424 addr_len = sizeof (struct sockaddr_in); 425 break; 426 427 case AF_INET6: 428 addr_len = sizeof (struct sockaddr_in6); 429 break; 430 431 default: 432 return (RDR_ERROR); 433 } 434 435 /* attempt the connection */ 436 if (connect(fd, addr, addr_len) == -1) { 437 return (RDR_NET_ERR); 438 } 439 440 return (RDR_OK); 441 } 442 443 444 /* 445 * rdr_connect_srv: 446 * 447 * Perform the necessary steps for a server to connect to a 448 * pending client request. The new connection is allocated a 449 * new file descriptor, separate from the one used to accept 450 * the connection. 451 */ 452 int 453 rdr_connect_srv(int fd) 454 { 455 int newfd; 456 unsigned int faddr_len; 457 struct sockaddr_storage faddr; 458 459 460 faddr_len = sizeof (faddr); 461 if ((newfd = accept(fd, (struct sockaddr *)&faddr, &faddr_len)) == -1) { 462 return (RDR_BAD_FD); 463 } 464 465 return (newfd); 466 } 467 468 469 /* 470 * rdr_reject: 471 * 472 * Reject an incoming connection attempt. This requires 473 * that the connection be accepted first. 474 */ 475 int 476 rdr_reject(int fd) 477 { 478 unsigned int faddr_len; 479 struct sockaddr_storage faddr; 480 481 482 /* first accept the connection */ 483 faddr_len = sizeof (faddr); 484 if (accept(fd, (struct sockaddr *)&faddr, &faddr_len) == -1) { 485 return (RDR_NET_ERR); 486 } 487 488 /* then close it */ 489 close(fd); 490 491 return (RDR_OK); 492 } 493 494 495 /* 496 * rdr_close: 497 * 498 * Close down an given connection. 499 */ 500 int 501 rdr_close(int fd) 502 { 503 close(fd); 504 505 return (RDR_OK); 506 } 507 508 509 /* 510 * rdr_snd_msg: 511 * 512 * Public interface for sending an RDR message. The data 513 * passed in through hdr and param are packed for network 514 * transport and sent. 515 */ 516 int 517 rdr_snd_msg(int fd, rdr_msg_hdr_t *hdr, cfga_params_t *param, int timeout) 518 { 519 int err; 520 char *pack_buf = NULL; 521 int pack_buf_sz = 0; 522 523 524 /* sanity checks */ 525 if ((hdr == NULL) || (param == NULL)) { 526 return (RDR_ERROR); 527 } 528 529 /* 530 * Pack the message for transport 531 */ 532 switch (hdr->message_opcode) { 533 534 case RDR_SES_REQ: { 535 536 ses_req_params_t *rparam; 537 rparam = (ses_req_params_t *)param; 538 539 if (hdr->data_type == RDR_REQUEST) { 540 err = pack_ses_req_request(rparam, 541 &pack_buf, &pack_buf_sz); 542 } else { 543 err = pack_ses_req_reply(rparam, 544 &pack_buf, &pack_buf_sz); 545 } 546 547 break; 548 } 549 550 case RDR_SES_ESTBL: 551 case RDR_SES_END: 552 553 /* 554 * This is not an error condition because 555 * there is no extra information to pack. 556 */ 557 err = RDR_OK; 558 break; 559 560 case RDR_CONF_CHANGE_STATE: { 561 562 change_state_params_t *cparam; 563 cparam = (change_state_params_t *)param; 564 565 if (hdr->data_type == RDR_REQUEST) { 566 err = pack_change_state_request(cparam, 567 &pack_buf, &pack_buf_sz); 568 } else { 569 err = pack_change_state_reply(cparam, 570 &pack_buf, &pack_buf_sz); 571 } 572 break; 573 } 574 575 case RDR_CONF_PRIVATE_FUNC: { 576 577 private_func_params_t *pparam; 578 pparam = (private_func_params_t *)param; 579 580 if (hdr->data_type == RDR_REQUEST) { 581 err = pack_private_func_request(pparam, 582 &pack_buf, &pack_buf_sz); 583 } else { 584 err = pack_private_func_reply(pparam, 585 &pack_buf, &pack_buf_sz); 586 } 587 break; 588 } 589 590 case RDR_CONF_TEST: { 591 592 test_params_t *tparam; 593 tparam = (test_params_t *)param; 594 595 if (hdr->data_type == RDR_REQUEST) { 596 err = pack_test_request(tparam, 597 &pack_buf, &pack_buf_sz); 598 } else { 599 err = pack_test_reply(tparam, 600 &pack_buf, &pack_buf_sz); 601 } 602 break; 603 } 604 605 case RDR_CONF_LIST_EXT: { 606 607 list_ext_params_t *lparam; 608 lparam = (list_ext_params_t *)param; 609 610 if (hdr->data_type == RDR_REQUEST) { 611 err = pack_list_ext_request(lparam, &pack_buf, 612 &pack_buf_sz); 613 } else { 614 err = pack_list_ext_reply(lparam, &pack_buf, 615 &pack_buf_sz); 616 } 617 break; 618 } 619 620 case RDR_CONF_HELP: { 621 622 help_params_t *hparam; 623 hparam = (help_params_t *)param; 624 625 if (hdr->data_type == RDR_REQUEST) { 626 err = pack_help_request(hparam, 627 &pack_buf, &pack_buf_sz); 628 } else { 629 630 /* 631 * This is not an error because help 632 * reply does not have any extra information 633 * to pack. 634 */ 635 err = RDR_OK; 636 } 637 break; 638 } 639 640 case RDR_CONF_AP_ID_CMP: { 641 642 ap_id_cmp_params_t *aparam; 643 aparam = (ap_id_cmp_params_t *)param; 644 645 if (hdr->data_type == RDR_REQUEST) { 646 err = pack_ap_id_cmp_request(aparam, 647 &pack_buf, &pack_buf_sz); 648 } else { 649 650 /* 651 * This is not an error because ap_id_cmp 652 * reply does not have any extra information 653 * to pack. 654 */ 655 err = RDR_OK; 656 } 657 break; 658 } 659 660 case RDR_CONF_ABORT_CMD: { 661 662 abort_cmd_params_t *aparam; 663 aparam = (abort_cmd_params_t *)param; 664 665 if (hdr->data_type == RDR_REQUEST) { 666 err = pack_abort_cmd_request(aparam, 667 &pack_buf, &pack_buf_sz); 668 } else { 669 /* 670 * This is not an error because session 671 * abort reply does not have any extra 672 * information to pack. 673 */ 674 err = RDR_OK; 675 } 676 break; 677 } 678 679 case RDR_CONF_CONFIRM_CALLBACK: { 680 681 confirm_callback_params_t *cparam; 682 cparam = (confirm_callback_params_t *)param; 683 684 if (hdr->data_type == RDR_REQUEST) { 685 err = pack_confirm_request(cparam, 686 &pack_buf, &pack_buf_sz); 687 } else { 688 err = pack_confirm_reply(cparam, &pack_buf, 689 &pack_buf_sz); 690 } 691 break; 692 } 693 694 case RDR_CONF_MSG_CALLBACK: { 695 696 msg_callback_params_t *mparam; 697 mparam = (msg_callback_params_t *)param; 698 699 if (hdr->data_type == RDR_REQUEST) { 700 err = pack_message_request(mparam, 701 &pack_buf, &pack_buf_sz); 702 } else { 703 /* 704 * It is an error to send a reply 705 * to a message callback. 706 */ 707 err = RDR_MSG_INVAL; 708 } 709 break; 710 } 711 712 case RDR_RSRC_INFO: { 713 714 rsrc_info_params_t *rparam; 715 rparam = (rsrc_info_params_t *)param; 716 717 if (hdr->data_type == RDR_REQUEST) { 718 err = pack_rsrc_info_request(rparam, &pack_buf, 719 &pack_buf_sz); 720 } else { 721 err = pack_rsrc_info_reply(rparam, &pack_buf, 722 &pack_buf_sz); 723 } 724 break; 725 } 726 727 default: 728 err = RDR_MSG_INVAL; 729 break; 730 } 731 732 /* check if packed correctly */ 733 if (err != RDR_OK) { 734 return (err); 735 } 736 737 /* send the message */ 738 err = rdr_snd(fd, hdr, pack_buf, pack_buf_sz, timeout); 739 740 free((void *)pack_buf); 741 742 return (err); 743 } 744 745 746 /* 747 * rdr_rcv_msg: 748 * 749 * Public interface for receiving an RDR message. Data is 750 * unpacked into the hdr and param paramters. 751 */ 752 int 753 rdr_rcv_msg(int fd, rdr_msg_hdr_t *hdr, cfga_params_t *param, int timeout) 754 { 755 int err; 756 char *unpack_buf = NULL; 757 758 759 /* sanity checks */ 760 if ((hdr == NULL) || (param == NULL)) { 761 return (RDR_ERROR); 762 } 763 764 (void) memset(param, 0, sizeof (cfga_params_t)); 765 766 /* receive the message */ 767 if ((err = rdr_rcv(fd, hdr, &unpack_buf, timeout)) != RDR_OK) { 768 return (err); 769 } 770 771 /* 772 * Unpack the message 773 */ 774 switch (hdr->message_opcode) { 775 776 case RDR_SES_REQ: { 777 778 ses_req_params_t *rparam; 779 rparam = (ses_req_params_t *)param; 780 781 if (hdr->data_type == RDR_REQUEST) { 782 err = unpack_ses_req_request(rparam, 783 unpack_buf); 784 } else { 785 err = unpack_ses_req_reply(rparam, unpack_buf); 786 } 787 break; 788 } 789 790 case RDR_SES_ESTBL: 791 case RDR_SES_END: 792 793 /* no information to unpack */ 794 (void) memset(param, 0, sizeof (cfga_params_t)); 795 err = RDR_OK; 796 break; 797 798 case RDR_CONF_CHANGE_STATE: { 799 800 change_state_params_t *cparam; 801 cparam = (change_state_params_t *)param; 802 803 if (hdr->data_type == RDR_REQUEST) { 804 err = unpack_change_state_request(cparam, 805 unpack_buf); 806 } else { 807 err = unpack_change_state_reply(cparam, 808 unpack_buf); 809 } 810 break; 811 } 812 813 case RDR_CONF_PRIVATE_FUNC: { 814 815 private_func_params_t *pparam; 816 pparam = (private_func_params_t *)param; 817 818 if (hdr->data_type == RDR_REQUEST) { 819 err = unpack_private_func_request(pparam, 820 unpack_buf); 821 } else { 822 err = unpack_private_func_reply(pparam, 823 unpack_buf); 824 } 825 break; 826 } 827 828 case RDR_CONF_TEST: { 829 830 test_params_t *tparam; 831 tparam = (test_params_t *)param; 832 833 if (hdr->data_type == RDR_REQUEST) { 834 err = unpack_test_request(tparam, unpack_buf); 835 } else { 836 err = unpack_test_reply(tparam, unpack_buf); 837 } 838 break; 839 } 840 841 case RDR_CONF_LIST_EXT: { 842 843 list_ext_params_t *lparam; 844 lparam = (list_ext_params_t *)param; 845 846 if (hdr->data_type == RDR_REQUEST) { 847 err = unpack_list_ext_request(lparam, 848 unpack_buf); 849 } else { 850 err = unpack_list_ext_reply(lparam, unpack_buf); 851 } 852 break; 853 } 854 855 case RDR_CONF_HELP: { 856 857 help_params_t *hparam; 858 hparam = (help_params_t *)param; 859 860 if (hdr->data_type == RDR_REQUEST) { 861 err = unpack_help_request(hparam, 862 unpack_buf); 863 } else { 864 /* 865 * This is not an error because help 866 * reply does not have any extra information 867 * to unpack. 868 */ 869 err = RDR_OK; 870 } 871 break; 872 } 873 874 case RDR_CONF_AP_ID_CMP: { 875 876 ap_id_cmp_params_t *aparam; 877 aparam = (ap_id_cmp_params_t *)param; 878 879 if (hdr->data_type == RDR_REQUEST) { 880 err = unpack_ap_id_cmp_request(aparam, 881 unpack_buf); 882 } else { 883 /* 884 * This is not an error because ap_id_cmp 885 * reply does not have any extra information 886 * to pack. 887 */ 888 err = RDR_OK; 889 } 890 break; 891 } 892 893 case RDR_CONF_ABORT_CMD: { 894 895 abort_cmd_params_t *aparam; 896 aparam = (abort_cmd_params_t *)param; 897 898 if (hdr->data_type == RDR_REQUEST) { 899 err = unpack_abort_cmd_request(aparam, 900 unpack_buf); 901 } else { 902 /* no information to unpack */ 903 (void) memset(param, 0, sizeof (cfga_params_t)); 904 err = RDR_OK; 905 } 906 907 break; 908 } 909 910 case RDR_CONF_CONFIRM_CALLBACK: { 911 912 confirm_callback_params_t *cparam; 913 cparam = (confirm_callback_params_t *)param; 914 915 if (hdr->data_type == RDR_REQUEST) { 916 err = unpack_confirm_request(cparam, 917 unpack_buf); 918 } else { 919 err = unpack_confirm_reply(cparam, unpack_buf); 920 } 921 break; 922 } 923 924 case RDR_CONF_MSG_CALLBACK: { 925 926 msg_callback_params_t *mparam; 927 mparam = (msg_callback_params_t *)param; 928 929 if (hdr->data_type == RDR_REQUEST) { 930 err = unpack_message_request(mparam, 931 unpack_buf); 932 } else { 933 /* 934 * It is an error to send a reply 935 * to a message callback. 936 */ 937 (void) memset(param, 0, sizeof (cfga_params_t)); 938 err = RDR_MSG_INVAL; 939 } 940 break; 941 } 942 943 case RDR_RSRC_INFO: { 944 945 rsrc_info_params_t *rparam; 946 rparam = (rsrc_info_params_t *)param; 947 948 if (hdr->data_type == RDR_REQUEST) { 949 err = unpack_rsrc_info_request(rparam, 950 unpack_buf); 951 } else { 952 err = unpack_rsrc_info_reply(rparam, 953 unpack_buf); 954 } 955 break; 956 } 957 958 default: 959 err = RDR_MSG_INVAL; 960 break; 961 } 962 963 free(unpack_buf); 964 965 /* check if unpacked correctly */ 966 if (err != RDR_OK) { 967 return (err); 968 } 969 970 return (RDR_OK); 971 } 972 973 974 /* 975 * rdr_cleanup_params: 976 * 977 * Deallocate any memory that was allocated in unpacking a 978 * message. 979 */ 980 int 981 rdr_cleanup_params(rdr_msg_opcode_t message_opcode, cfga_params_t *param) 982 { 983 /* sanity check */ 984 if ((param == NULL)) { 985 return (RDR_ERROR); 986 } 987 988 /* 989 * Deallocate memory depending on 990 * the operation. 991 */ 992 switch (message_opcode) { 993 994 case RDR_SES_REQ: { 995 996 ses_req_params_t *sparam; 997 sparam = (ses_req_params_t *)param; 998 999 if (sparam->locale_str != NULL) { 1000 free((void *)sparam->locale_str); 1001 sparam->locale_str = NULL; 1002 } 1003 break; 1004 } 1005 1006 case RDR_SES_ESTBL: 1007 case RDR_SES_END: 1008 1009 /* nothing to deallocate */ 1010 break; 1011 1012 case RDR_CONF_CHANGE_STATE: { 1013 1014 change_state_params_t *cparam; 1015 cparam = (change_state_params_t *)param; 1016 1017 cleanup_ap_ids(cparam->num_ap_ids, (char **)cparam->ap_ids); 1018 cparam->ap_ids = NULL; 1019 if (cparam->options != NULL) { 1020 free((void *)cparam->options); 1021 cparam->options = NULL; 1022 } 1023 if (cparam->confp != NULL) { 1024 free((void *)cparam->confp); 1025 cparam->confp = NULL; 1026 } 1027 if (cparam->msgp != NULL) { 1028 free((void *)cparam->msgp); 1029 cparam->msgp = NULL; 1030 } 1031 cleanup_errstring(cparam->errstring); 1032 break; 1033 } 1034 1035 case RDR_CONF_PRIVATE_FUNC: { 1036 1037 private_func_params_t *pparam; 1038 pparam = (private_func_params_t *)param; 1039 1040 cleanup_ap_ids(pparam->num_ap_ids, (char **)pparam->ap_ids); 1041 pparam->ap_ids = NULL; 1042 if (pparam->options != NULL) { 1043 free((void *)pparam->options); 1044 pparam->options = NULL; 1045 } 1046 if (pparam->confp != NULL) { 1047 free((void *)pparam->confp); 1048 pparam->confp = NULL; 1049 } 1050 if (pparam->msgp != NULL) { 1051 free((void *)pparam->msgp); 1052 pparam->msgp = NULL; 1053 } 1054 cleanup_errstring(pparam->errstring); 1055 break; 1056 } 1057 1058 case RDR_CONF_TEST: { 1059 1060 test_params_t *tparam; 1061 tparam = (test_params_t *)param; 1062 1063 cleanup_ap_ids(tparam->num_ap_ids, (char **)tparam->ap_ids); 1064 tparam->ap_ids = NULL; 1065 if (tparam->options != NULL) { 1066 free((void *)tparam->options); 1067 tparam->options = NULL; 1068 } 1069 if (tparam->msgp != NULL) { 1070 free((void *)tparam->msgp); 1071 tparam->msgp = NULL; 1072 } 1073 cleanup_errstring(tparam->errstring); 1074 break; 1075 } 1076 1077 case RDR_CONF_LIST_EXT: { 1078 1079 list_ext_params_t *lparam; 1080 lparam = (list_ext_params_t *)param; 1081 1082 cleanup_ap_ids(lparam->num_ap_ids, (char **)lparam->ap_ids); 1083 lparam->ap_ids = NULL; 1084 1085 if (lparam->nlist != NULL) { 1086 free((void *)lparam->nlist); 1087 lparam->nlist = NULL; 1088 } 1089 if (lparam->ap_id_list != NULL) { 1090 if (*lparam->ap_id_list != NULL) { 1091 free((void *)*lparam->ap_id_list); 1092 } 1093 free((void *)lparam->ap_id_list); 1094 lparam->ap_id_list = NULL; 1095 } 1096 if (lparam->ap_id_list != NULL) { 1097 free((void *)lparam->ap_id_list); 1098 lparam->ap_id_list = NULL; 1099 } 1100 1101 if (lparam->options != NULL) { 1102 free((void *)lparam->options); 1103 lparam->options = NULL; 1104 } 1105 if (lparam->listopts != NULL) { 1106 free((void *)lparam->listopts); 1107 lparam->listopts = NULL; 1108 } 1109 cleanup_errstring(lparam->errstring); 1110 break; 1111 } 1112 1113 case RDR_CONF_HELP: { 1114 1115 help_params_t *hparam; 1116 hparam = (help_params_t *)param; 1117 1118 cleanup_ap_ids(hparam->num_ap_ids, (char **)hparam->ap_ids); 1119 hparam->ap_ids = NULL; 1120 if (hparam->msgp != NULL) { 1121 free((void *)hparam->msgp); 1122 hparam->msgp = NULL; 1123 } 1124 if (hparam->options != NULL) { 1125 free((void *)hparam->options); 1126 hparam->options = NULL; 1127 } 1128 break; 1129 } 1130 1131 case RDR_CONF_AP_ID_CMP: { 1132 1133 ap_id_cmp_params_t *aparam; 1134 aparam = (ap_id_cmp_params_t *)param; 1135 1136 if (aparam->ap_log_id1 != NULL) { 1137 free((void *)aparam->ap_log_id1); 1138 aparam->ap_log_id1 = NULL; 1139 } 1140 if (aparam->ap_log_id2 != NULL) { 1141 free((void *)aparam->ap_log_id2); 1142 aparam->ap_log_id2 = NULL; 1143 } 1144 break; 1145 } 1146 1147 case RDR_CONF_ABORT_CMD: 1148 1149 /* nothing to deallocate */ 1150 break; 1151 1152 case RDR_CONF_CONFIRM_CALLBACK: { 1153 1154 confirm_callback_params_t *cparam; 1155 cparam = (confirm_callback_params_t *)param; 1156 1157 if (cparam->confp != NULL) { 1158 free((void *)cparam->confp); 1159 cparam->confp = NULL; 1160 } 1161 if (cparam->message != NULL) { 1162 free((void *)cparam->message); 1163 cparam->message = NULL; 1164 } 1165 break; 1166 } 1167 1168 case RDR_CONF_MSG_CALLBACK: { 1169 1170 msg_callback_params_t *mparam; 1171 mparam = (msg_callback_params_t *)param; 1172 1173 if (mparam->msgp != NULL) { 1174 free((void *)mparam->msgp); 1175 mparam->msgp = NULL; 1176 } 1177 if (mparam->message != NULL) { 1178 free((void *)mparam->message); 1179 mparam->message = NULL; 1180 } 1181 break; 1182 } 1183 1184 default: 1185 return (RDR_ERROR); 1186 /* NOTREACHED */ 1187 break; 1188 1189 } 1190 1191 return (RDR_OK); 1192 } 1193 1194 1195 /* 1196 * Private (static) Functions 1197 */ 1198 1199 1200 /* 1201 * rdr_setopt: 1202 * 1203 * Set the specified option for a given transport endpoint. 1204 * This function only sets boolean options. It does not 1205 * provide the ability to unset an option, or set a non- 1206 * boolean option. 1207 */ 1208 static int 1209 rdr_setopt(int fd, int name, int level) 1210 { 1211 int on = 1; 1212 1213 1214 if (setsockopt(fd, level, name, &on, sizeof (on)) == -1) { 1215 return (RDR_NET_ERR); 1216 } 1217 1218 return (RDR_OK); 1219 } 1220 1221 1222 /* 1223 * rdr_bind: 1224 * 1225 * Bind the specified file descriptor to a specified 1226 * address. If the address is already bound, no error is 1227 * returned. This is the expected behavior if a server 1228 * has been started by inetd (1M). 1229 */ 1230 static int 1231 rdr_bind(int fd, struct sockaddr *addr) 1232 { 1233 unsigned int addr_len; 1234 int rc; 1235 1236 1237 /* initialize the address */ 1238 switch (addr->sa_family) { 1239 1240 case AF_INET: 1241 addr_len = sizeof (struct sockaddr_in); 1242 break; 1243 1244 case AF_INET6: 1245 addr_len = sizeof (struct sockaddr_in6); 1246 break; 1247 1248 default: 1249 return (RDR_ERROR); 1250 } 1251 1252 /* attempt to bind the address */ 1253 rc = bind(fd, addr, addr_len); 1254 1255 /* 1256 * Ignore the error if EINVAL is returned. In 1257 * this case, we assume that this means that 1258 * the address was already bound. This is not 1259 * an error for servers started by inetd (1M). 1260 */ 1261 if ((rc == -1) && (errno != EINVAL)) { 1262 return (RDR_NET_ERR); 1263 } 1264 1265 /* 1266 * Retreive the address information of the 1267 * address that was actually bound. 1268 */ 1269 addr_len = sizeof (*addr); 1270 if (getsockname(fd, addr, &addr_len) == -1) { 1271 (void) memset(addr, 0, sizeof (*addr)); 1272 return (RDR_NET_ERR); 1273 } 1274 1275 return (RDR_OK); 1276 } 1277 1278 1279 /* 1280 * rdr_snd: 1281 * 1282 * Send a message in two stages. First the header is sent, 1283 * followed by the packed buffer containing the message 1284 * contents. 1285 */ 1286 static int 1287 rdr_snd(int fd, rdr_msg_hdr_t *hdr, char *data, int data_sz, int timeout) 1288 { 1289 int err; 1290 1291 1292 /* sanity check */ 1293 if (hdr == NULL) { 1294 return (RDR_ERROR); 1295 } 1296 1297 /* ensure null pad bytes */ 1298 hdr->pad_byte1 = 0; 1299 hdr->pad_byte2 = 0; 1300 1301 /* initialize size information */ 1302 hdr->data_length = data_sz; 1303 1304 /* send message header */ 1305 err = rdr_snd_raw(fd, (char *)hdr, RDR_MSG_HDR_SIZE, timeout); 1306 if (err != RDR_OK) { 1307 return (err); 1308 } 1309 1310 /* check if more to send */ 1311 if (data_sz == 0) { 1312 return (RDR_OK); 1313 } 1314 1315 /* send message data */ 1316 err = rdr_snd_raw(fd, data, data_sz, timeout); 1317 if (err != RDR_OK) { 1318 return (err); 1319 } 1320 1321 return (RDR_OK); 1322 } 1323 1324 1325 /* 1326 * rdr_snd_raw: 1327 * 1328 * Send a raw buffer of information. This function handles 1329 * the low level details of the send operation. 1330 */ 1331 static int 1332 rdr_snd_raw(int fd, char *msg, int data_sz, int timeout) 1333 { 1334 int err; 1335 int num_bytes; 1336 int bytes_left; 1337 char *bufp; 1338 struct pollfd pfd; 1339 1340 1341 bufp = (char *)msg; 1342 1343 bytes_left = data_sz; 1344 1345 pfd.fd = fd; 1346 pfd.events = POLLOUT; 1347 1348 while (bytes_left > 0) { 1349 1350 pfd.revents = 0; 1351 1352 /* wait until we can send the data */ 1353 if ((err = poll(&pfd, 1, timeout)) == -1) { 1354 1355 /* poll was interrupted */ 1356 if (errno == EINTR) { 1357 return (RDR_ABORTED); 1358 } 1359 1360 return (RDR_ERROR); 1361 1362 } else if (err == 0) { 1363 return (RDR_TIMEOUT); 1364 } 1365 1366 /* ready to send data */ 1367 if (pfd.revents & POLLOUT) { 1368 1369 num_bytes = write(fd, bufp, bytes_left); 1370 1371 if (num_bytes == -1) { 1372 1373 /* 1374 * Distinguish between an aborted 1375 * session and other network errors. 1376 */ 1377 if (errno == EPIPE) { 1378 return (RDR_ABORTED); 1379 } else { 1380 return (RDR_NET_ERR); 1381 } 1382 } 1383 1384 /* wrote 0 bytes, so operation was aborted */ 1385 if (num_bytes == 0) { 1386 return (RDR_ABORTED); 1387 } 1388 1389 } else { 1390 return (RDR_NET_ERR); 1391 } 1392 1393 bytes_left -= num_bytes; 1394 bufp += num_bytes; 1395 } 1396 1397 return (RDR_OK); 1398 } 1399 1400 1401 /* 1402 * rdr_rcv: 1403 * 1404 * Receive a message in two stages. First the header is 1405 * received, followed by the packed buffer containing the 1406 * message contents. 1407 */ 1408 static int 1409 rdr_rcv(int fd, rdr_msg_hdr_t *hdr, char **data, int timeout) 1410 { 1411 int err; 1412 int data_sz; 1413 char hdr_buf[RDR_MSG_HDR_SIZE]; 1414 char *buf = NULL; 1415 1416 1417 /* sanity check */ 1418 if (hdr == NULL) { 1419 return (RDR_ERROR); 1420 } 1421 1422 /* receive the header */ 1423 err = rdr_rcv_raw(fd, hdr_buf, RDR_MSG_HDR_SIZE, timeout); 1424 if (err != RDR_OK) { 1425 return (err); 1426 } 1427 1428 /* verify that the data is good */ 1429 /* LINTED Pointer Cast Alignment Warning */ 1430 if (validate_header((rdr_msg_hdr_t *)hdr_buf) != RDR_OK) { 1431 return (RDR_MSG_INVAL); 1432 } 1433 1434 /* LINTED Pointer Cast Alignment Warning */ 1435 data_sz = ((rdr_msg_hdr_t *)hdr_buf)->data_length; 1436 1437 buf = (char *)malloc(data_sz); 1438 if (!buf) { 1439 return (RDR_MEM_ALLOC); 1440 } 1441 1442 if (data_sz != 0) { 1443 1444 /* receive the rest of the message */ 1445 err = rdr_rcv_raw(fd, buf, data_sz, timeout); 1446 if (err != RDR_OK) { 1447 free((void *)buf); 1448 return (err); 1449 } 1450 } 1451 1452 /* copy out data */ 1453 *data = buf; 1454 (void) memcpy(hdr, hdr_buf, RDR_MSG_HDR_SIZE); 1455 1456 return (RDR_OK); 1457 } 1458 1459 1460 /* 1461 * rdr_rcv_raw: 1462 * 1463 * Receive a raw buffer of information. This function handles 1464 * the low level details of the receive operation. 1465 */ 1466 static int 1467 rdr_rcv_raw(int fd, char *msg, int data_size, int timeout) 1468 { 1469 int num_bytes; 1470 int err; 1471 int bytes_left; 1472 char *bufp; 1473 struct pollfd pollfd; 1474 1475 1476 bufp = (char *)msg; 1477 bytes_left = data_size; 1478 1479 pollfd.fd = fd; 1480 pollfd.events = POLLIN; 1481 1482 while (bytes_left > 0) { 1483 1484 errno = 0; 1485 pollfd.revents = 0; 1486 1487 if ((err = poll(&pollfd, 1, timeout)) == -1) { 1488 1489 /* 1490 * In the DCA, if a session is aborted, SIGINT 1491 * is delivered to all active sessions. This 1492 * mistakenly causes all sessions waiting in 1493 * the poll to be interrupted. So, if EINTR 1494 * is returned, it is ignored. If another error 1495 * occurs right away, the current session really 1496 * was aborted. All other sessions won't encounter 1497 * an error and will proceed normally. 1498 */ 1499 if ((errno == 0) || (errno == EINTR)) { 1500 continue; 1501 } 1502 1503 return (RDR_ABORTED); 1504 1505 } else if (err == 0) { 1506 return (RDR_TIMEOUT); 1507 } 1508 1509 /* ready to receive data */ 1510 if (pollfd.revents & POLLIN) { 1511 1512 num_bytes = read(fd, bufp, bytes_left); 1513 1514 if (num_bytes == -1) { 1515 1516 /* 1517 * Distinguish between an aborted 1518 * session and other network errors. 1519 */ 1520 if (errno == ECONNRESET) { 1521 return (RDR_ABORTED); 1522 } else { 1523 return (RDR_NET_ERR); 1524 } 1525 } 1526 1527 /* read 0 bytes, so operation was aborted */ 1528 if (num_bytes == 0) { 1529 return (RDR_ABORTED); 1530 } 1531 1532 } else { 1533 return (RDR_NET_ERR); 1534 } 1535 1536 bytes_left -= num_bytes; 1537 bufp += num_bytes; 1538 } 1539 1540 return (RDR_OK); 1541 } 1542 1543 1544 /* 1545 * validate_header: 1546 * 1547 * Perform a series of sanity checks on the header data that is 1548 * received. This gets called before the variable length data is 1549 * read in to make sure that the information in the header can 1550 * be trusted. 1551 */ 1552 static int 1553 validate_header(rdr_msg_hdr_t *hdr) 1554 { 1555 unsigned char op; 1556 1557 1558 if (hdr == NULL) { 1559 return (RDR_ERROR); 1560 } 1561 1562 op = hdr->message_opcode; 1563 1564 /* validate opcode */ 1565 if ((op < RDR_SES_REQ) || (op >= RDR_NUM_OPS)) { 1566 return (RDR_ERROR); 1567 } 1568 1569 /* validate message size (and type) for op */ 1570 switch (hdr->data_type) { 1571 1572 case RDR_REQUEST: 1573 if (hdr->data_length > msg_sizes[op].req_max) { 1574 return (RDR_ERROR); 1575 } 1576 break; 1577 1578 case RDR_REPLY: 1579 if (hdr->data_length > msg_sizes[op].reply_max) { 1580 return (RDR_ERROR); 1581 } 1582 break; 1583 1584 default: 1585 /* invalid data type */ 1586 return (RDR_ERROR); 1587 } 1588 1589 /* all checks passed */ 1590 return (RDR_OK); 1591 } 1592 1593 1594 /* 1595 * pack_ses_req_request: 1596 * 1597 * Handle packing a session request request message. 1598 */ 1599 static int 1600 pack_ses_req_request(ses_req_params_t *params, char **buf, int *buf_size) 1601 { 1602 char *bufptr; 1603 int locale_str_len; 1604 rdr_ses_req_t ses_req; 1605 1606 1607 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 1608 return (RDR_ERROR); 1609 } 1610 1611 /* 1612 * Determine the size of the locale string 1613 */ 1614 if (params->locale_str != NULL) { 1615 locale_str_len = strlen(params->locale_str) + 1; 1616 } else { 1617 locale_str_len = 0; 1618 } 1619 1620 /* 1621 * Collect size info specific to the ses_req request message 1622 * and allocate a buffer 1623 */ 1624 *buf_size = sizeof (rdr_ses_req_t); 1625 *buf_size += locale_str_len; 1626 1627 *buf = (char *)malloc(*buf_size); 1628 if (*buf == NULL) { 1629 return (RDR_MEM_ALLOC); 1630 } 1631 1632 /* 1633 * Set fixed locale size label by name 1634 */ 1635 ses_req.locale_size = locale_str_len; 1636 1637 /* 1638 * Set variable information using memcpy 1639 */ 1640 bufptr = *buf; 1641 1642 (void) memcpy(bufptr, &ses_req, sizeof (rdr_ses_req_t)); 1643 bufptr += sizeof (rdr_ses_req_t); 1644 1645 if (params->locale_str != NULL) { 1646 (void) memcpy(bufptr, params->locale_str, locale_str_len); 1647 bufptr += locale_str_len; 1648 } 1649 1650 return (RDR_OK); 1651 } 1652 1653 1654 /* 1655 * unpack_ses_req_request: 1656 * 1657 * Handle unpacking a session request request message. 1658 */ 1659 static int 1660 unpack_ses_req_request(ses_req_params_t *params, const char *buf) 1661 { 1662 char *bufptr; 1663 rdr_ses_req_t ses_req_data; 1664 1665 1666 if ((params == NULL) || (buf == NULL)) { 1667 return (RDR_ERROR); 1668 } 1669 1670 bufptr = (char *)buf; 1671 (void) memcpy(&ses_req_data, bufptr, sizeof (rdr_ses_req_t)); 1672 bufptr += sizeof (rdr_ses_req_t); 1673 1674 /* 1675 * handle getting the locale string 1676 */ 1677 if (get_string_from_buf(&(params->locale_str), 1678 ses_req_data.locale_size, bufptr)) { 1679 return (RDR_ERROR); 1680 } 1681 1682 return (RDR_OK); 1683 } 1684 1685 1686 /* 1687 * pack_ses_req_reply: 1688 * 1689 * Handle packing a session request reply message. 1690 */ 1691 static int 1692 pack_ses_req_reply(ses_req_params_t *params, char **buf, int *buf_size) 1693 { 1694 rdr_ses_req_reply_t ses_req_reply_data; 1695 1696 1697 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 1698 return (RDR_ERROR); 1699 } 1700 1701 /* 1702 * Collect size info specific to the session request reply 1703 * message and allocate a buffer 1704 */ 1705 *buf_size = sizeof (rdr_ses_req_reply_t); 1706 1707 *buf = (char *)malloc(*buf_size); 1708 if (*buf == NULL) { 1709 return (RDR_MEM_ALLOC); 1710 } 1711 1712 /* 1713 * Set fixed session identifier 1714 */ 1715 ses_req_reply_data.session_id = params->session_id; 1716 1717 /* 1718 * Copy information using memcpy 1719 */ 1720 (void) memcpy(*buf, &ses_req_reply_data, sizeof (rdr_ses_req_reply_t)); 1721 1722 return (RDR_OK); 1723 } 1724 1725 1726 /* 1727 * unpack_ses_req_request: 1728 * 1729 * Handle unpacking a session request reply message. 1730 */ 1731 static int 1732 unpack_ses_req_reply(ses_req_params_t *params, const char *buf) 1733 { 1734 rdr_ses_req_reply_t *ses_req_reply_datap; 1735 1736 1737 if ((params == NULL) || (buf == NULL)) { 1738 return (RDR_ERROR); 1739 } 1740 1741 /* LINTED Pointer Cast Alignment Warning */ 1742 ses_req_reply_datap = (rdr_ses_req_reply_t *)buf; 1743 1744 /* 1745 * copy out the session information 1746 */ 1747 params->session_id = ses_req_reply_datap->session_id; 1748 1749 return (RDR_OK); 1750 } 1751 1752 1753 /* 1754 * pack_change_state_request: 1755 * 1756 * Handle packing a change state request message. 1757 */ 1758 static int 1759 pack_change_state_request(change_state_params_t *params, char **buf, 1760 int *buf_size) 1761 { 1762 int i; 1763 char *bufptr; 1764 rdr_change_state_t change_state_data; 1765 rdr_variable_message_info_t var_msg_info; 1766 1767 1768 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 1769 return (RDR_ERROR); 1770 } 1771 1772 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 1773 1774 /* 1775 * Set variable length fields and make a call to partially 1776 * pack it. 1777 */ 1778 if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) { 1779 cleanup_variable_ap_id_info(&var_msg_info); 1780 return (RDR_ERROR); 1781 } 1782 if (find_options_sizes(params->options, &var_msg_info)) { 1783 cleanup_variable_ap_id_info(&var_msg_info); 1784 return (RDR_ERROR); 1785 } 1786 1787 /* 1788 * Collect size info specific to the change_state request 1789 * message and allocate a buffer 1790 */ 1791 *buf_size = sizeof (rdr_change_state_t); 1792 *buf_size += var_msg_info.ap_id_int_size; 1793 *buf_size += var_msg_info.ap_id_char_size; 1794 *buf_size += var_msg_info.options_strlen; 1795 *buf_size += var_msg_info.options_pad_sz; 1796 1797 *buf = (char *)malloc(*buf_size); 1798 if (*buf == NULL) { 1799 cleanup_variable_ap_id_info(&var_msg_info); 1800 return (RDR_MEM_ALLOC); 1801 } 1802 1803 /* 1804 * Set fixed address labels by name 1805 */ 1806 change_state_data.num_ap_ids = params->num_ap_ids; 1807 change_state_data.ap_id_char_size = var_msg_info.ap_id_char_size; 1808 change_state_data.options_size = var_msg_info.options_strlen + 1809 var_msg_info.options_pad_sz; 1810 1811 if (params->confp != NULL) { 1812 change_state_data.confirm_callback_id = 1813 (unsigned long)params->confp->confirm; 1814 change_state_data.confirm_appdata_ptr = 1815 (unsigned long)params->confp->appdata_ptr; 1816 } else { 1817 change_state_data.confirm_callback_id = 0; 1818 change_state_data.confirm_appdata_ptr = 0; 1819 } 1820 if (params->msgp != NULL) { 1821 change_state_data.msg_callback_id = 1822 (unsigned long)params->msgp->message_routine; 1823 change_state_data.msg_appdata_ptr = 1824 (unsigned long)params->msgp->appdata_ptr; 1825 } else { 1826 change_state_data.msg_callback_id = 0; 1827 change_state_data.msg_appdata_ptr = 0; 1828 } 1829 1830 change_state_data.flags = params->flags; 1831 change_state_data.timeval = params->timeval; 1832 change_state_data.state_change_cmd = params->state_change; 1833 if (params->errstring != NULL) { 1834 change_state_data.error_msg_ctl = RDR_GENERATE_ERR_MSGS; 1835 } else { 1836 change_state_data.error_msg_ctl = RDR_DONT_GENERATE_ERR_MSGS; 1837 } 1838 change_state_data.retries = params->retries; 1839 1840 /* 1841 * Set variable information using memcpy 1842 */ 1843 bufptr = *buf; 1844 1845 (void) memcpy(bufptr, &change_state_data, sizeof (rdr_change_state_t)); 1846 bufptr += sizeof (rdr_change_state_t); 1847 1848 if (var_msg_info.ap_id_sizes != NULL) { 1849 (void) memcpy(bufptr, var_msg_info.ap_id_sizes, 1850 var_msg_info.ap_id_int_size); 1851 bufptr += var_msg_info.ap_id_int_size; 1852 } 1853 1854 if (var_msg_info.ap_id_chars != NULL) { 1855 (void) memcpy(bufptr, var_msg_info.ap_id_chars, 1856 var_msg_info.ap_id_char_size); 1857 bufptr += var_msg_info.ap_id_char_size; 1858 } 1859 1860 if (params->options != NULL) { 1861 (void) memcpy(bufptr, params->options, 1862 var_msg_info.options_strlen); 1863 bufptr += var_msg_info.options_strlen; 1864 for (i = 0; i < var_msg_info.options_pad_sz; i++) { 1865 bufptr[i] = 0; 1866 } 1867 bufptr += var_msg_info.options_pad_sz; 1868 } 1869 1870 cleanup_variable_ap_id_info(&var_msg_info); 1871 1872 return (RDR_OK); 1873 } 1874 1875 1876 /* 1877 * unpack_change_state_request: 1878 * 1879 * Handle unpacking a change state request message. 1880 */ 1881 static int 1882 unpack_change_state_request(change_state_params_t *params, const char *buf) 1883 { 1884 char *bufptr; 1885 rdr_variable_message_info_t var_msg_info; 1886 rdr_change_state_t change_state_data; 1887 1888 1889 if ((params == NULL) || (buf == NULL)) { 1890 return (RDR_ERROR); 1891 } 1892 1893 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 1894 1895 bufptr = (char *)buf; 1896 (void) memcpy(&change_state_data, bufptr, sizeof (rdr_change_state_t)); 1897 bufptr += sizeof (rdr_change_state_t); 1898 1899 /* 1900 * handle getting the ap_ids 1901 */ 1902 var_msg_info.ap_id_char_size = change_state_data.ap_id_char_size; 1903 if (get_ap_ids_from_buf((char ***)&(params->ap_ids), 1904 change_state_data.num_ap_ids, &var_msg_info, bufptr)) { 1905 return (RDR_ERROR); 1906 } 1907 bufptr += var_msg_info.ap_id_int_size; 1908 bufptr += var_msg_info.ap_id_char_size; 1909 1910 /* 1911 * handle getting the options 1912 */ 1913 if (get_string_from_buf(&(params->options), 1914 change_state_data.options_size, bufptr)) { 1915 return (RDR_ERROR); 1916 } 1917 bufptr += change_state_data.options_size; 1918 1919 /* 1920 * Set fixed address labels by name 1921 */ 1922 params->state_change = (cfga_cmd_t)change_state_data.state_change_cmd; 1923 params->num_ap_ids = change_state_data.num_ap_ids; 1924 1925 params->confp = (struct cfga_confirm *) 1926 malloc(sizeof (struct cfga_confirm)); 1927 if (params->confp == NULL) { 1928 return (RDR_MEM_ALLOC); 1929 } 1930 1931 /* set params->confp->confirm using memcpy */ 1932 (void) memcpy((void*)params->confp, 1933 &(change_state_data.confirm_callback_id), sizeof (unsigned long)); 1934 params->confp->appdata_ptr = 1935 (void*)change_state_data.confirm_appdata_ptr; 1936 1937 params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg)); 1938 if (params->msgp == NULL) { 1939 return (RDR_MEM_ALLOC); 1940 } 1941 1942 /* set params->msgp->message_routine using memcpy */ 1943 (void) memcpy((void*)params->msgp, 1944 &(change_state_data.msg_callback_id), sizeof (unsigned long)); 1945 params->msgp->appdata_ptr = 1946 (void*)change_state_data.msg_appdata_ptr; 1947 1948 if (change_state_data.error_msg_ctl == RDR_GENERATE_ERR_MSGS) { 1949 params->errstring = (char **)malloc(sizeof (char *)); 1950 if (params->errstring == NULL) { 1951 return (RDR_MEM_ALLOC); 1952 } 1953 *(params->errstring) = NULL; 1954 } else { /* error_msg_ctl == RDR_DONT_GENERATE_ERR_MSGS */ 1955 params->errstring = NULL; 1956 } 1957 params->flags = change_state_data.flags; 1958 params->timeval = change_state_data.timeval; 1959 params->retries = change_state_data.retries; 1960 1961 return (RDR_OK); 1962 } 1963 1964 1965 /* 1966 * pack_change_state_reply: 1967 * 1968 * Handle packing a change state reply message. 1969 */ 1970 static int 1971 pack_change_state_reply(change_state_params_t *params, char **buf, 1972 int *buf_size) 1973 { 1974 int i; 1975 char *bufptr; 1976 rdr_change_state_reply_t change_state_data; 1977 rdr_variable_message_info_t var_msg_info; 1978 1979 1980 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 1981 1982 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 1983 return (RDR_ERROR); 1984 } 1985 1986 /* 1987 * Set variable length fields (size info) 1988 */ 1989 if (find_errstring_sizes(params->errstring, &var_msg_info)) { 1990 return (RDR_ERROR); 1991 } 1992 1993 /* 1994 * Collect size info specific to the change_state reply 1995 * message and allocate a buffer 1996 */ 1997 *buf_size = sizeof (rdr_change_state_reply_t); 1998 *buf_size += var_msg_info.errstring_strlen; 1999 *buf_size += var_msg_info.errstring_pad_sz; 2000 2001 *buf = (char *)malloc(*buf_size); 2002 if (*buf == NULL) { 2003 return (RDR_MEM_ALLOC); 2004 } 2005 2006 /* 2007 * Set fixed address labels by name 2008 */ 2009 change_state_data.errstring_size = var_msg_info.errstring_strlen + 2010 var_msg_info.errstring_pad_sz; 2011 2012 /* 2013 * Set variable information using memcpy 2014 */ 2015 bufptr = *buf; 2016 2017 (void) memcpy(bufptr, &change_state_data, 2018 sizeof (rdr_change_state_reply_t)); 2019 bufptr += sizeof (rdr_change_state_reply_t); 2020 2021 if ((params->errstring != NULL) && (*(params->errstring) != NULL)) { 2022 (void) memcpy(bufptr, *(params->errstring), 2023 var_msg_info.errstring_strlen); 2024 bufptr += var_msg_info.errstring_strlen; 2025 for (i = 0; i < var_msg_info.errstring_pad_sz; i++) { 2026 bufptr[i] = 0; 2027 } 2028 bufptr += var_msg_info.errstring_pad_sz; 2029 } 2030 2031 return (RDR_OK); 2032 } 2033 2034 2035 /* 2036 * unpack_change_state_reply: 2037 * 2038 * Handle unpacking a change state reply message. 2039 */ 2040 static int 2041 unpack_change_state_reply(change_state_params_t *params, const char *buf) 2042 { 2043 char *bufptr; 2044 rdr_change_state_reply_t change_state_data; 2045 2046 if ((params == NULL) || (buf == NULL)) { 2047 return (RDR_ERROR); 2048 } 2049 2050 bufptr = (char *)buf; 2051 (void) memcpy(&change_state_data, bufptr, 2052 sizeof (rdr_change_state_reply_t)); 2053 bufptr += sizeof (rdr_change_state_reply_t); 2054 2055 /* 2056 * handle getting the errstring 2057 */ 2058 params->errstring = (char **)malloc(sizeof (char *)); 2059 if (params->errstring == NULL) { 2060 return (RDR_MEM_ALLOC); 2061 } 2062 if (get_string_from_buf(params->errstring, 2063 change_state_data.errstring_size, bufptr)) { 2064 return (RDR_ERROR); 2065 } 2066 bufptr += change_state_data.errstring_size; 2067 2068 return (RDR_OK); 2069 } 2070 2071 2072 /* 2073 * pack_private_func_request: 2074 * 2075 * Handle packing a private function request message. 2076 */ 2077 static int 2078 pack_private_func_request(private_func_params_t *params, char **buf, 2079 int *buf_size) 2080 { 2081 int i; 2082 char *bufptr; 2083 rdr_private_func_t private_func_data; 2084 rdr_variable_message_info_t var_msg_info; 2085 2086 2087 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 2088 return (RDR_ERROR); 2089 } 2090 2091 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 2092 2093 /* 2094 * Set variable length fields and make a call to partially 2095 * pack it. 2096 */ 2097 if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) { 2098 cleanup_variable_ap_id_info(&var_msg_info); 2099 return (RDR_ERROR); 2100 } 2101 if (find_options_sizes(params->options, &var_msg_info)) { 2102 cleanup_variable_ap_id_info(&var_msg_info); 2103 return (RDR_ERROR); 2104 } 2105 if (find_function_sizes(params->function, &var_msg_info)) { 2106 cleanup_variable_ap_id_info(&var_msg_info); 2107 return (RDR_ERROR); 2108 } 2109 2110 /* 2111 * Collect size info specific to the private_func request 2112 * message and allocate a buffer 2113 */ 2114 *buf_size = sizeof (rdr_private_func_t); 2115 *buf_size += var_msg_info.ap_id_int_size; 2116 *buf_size += var_msg_info.ap_id_char_size; 2117 *buf_size += var_msg_info.options_strlen; 2118 *buf_size += var_msg_info.options_pad_sz; 2119 *buf_size += var_msg_info.function_strlen; 2120 *buf_size += var_msg_info.function_pad_sz; 2121 2122 *buf = (char *)malloc(*buf_size); 2123 if (*buf == NULL) { 2124 cleanup_variable_ap_id_info(&var_msg_info); 2125 return (RDR_MEM_ALLOC); 2126 } 2127 2128 /* 2129 * Set fixed address labels by name 2130 */ 2131 private_func_data.num_ap_ids = params->num_ap_ids; 2132 private_func_data.ap_id_char_size = var_msg_info.ap_id_char_size; 2133 private_func_data.options_size = var_msg_info.options_strlen + 2134 var_msg_info.options_pad_sz; 2135 private_func_data.function_size = var_msg_info.function_strlen + 2136 var_msg_info.function_pad_sz; 2137 2138 if (params->confp != NULL) { 2139 private_func_data.confirm_callback_id = 2140 (unsigned long)params->confp->confirm; 2141 private_func_data.confirm_appdata_ptr = 2142 (unsigned long)params->confp->appdata_ptr; 2143 } else { 2144 private_func_data.confirm_callback_id = 0; 2145 private_func_data.confirm_appdata_ptr = 0; 2146 } 2147 if (params->msgp != NULL) { 2148 private_func_data.msg_callback_id = 2149 (unsigned long)params->msgp->message_routine; 2150 private_func_data.msg_appdata_ptr = 2151 (unsigned long)params->msgp->appdata_ptr; 2152 } else { 2153 private_func_data.msg_callback_id = 0; 2154 private_func_data.msg_appdata_ptr = 0; 2155 } 2156 2157 private_func_data.flags = params->flags; 2158 2159 if (params->errstring != NULL) { 2160 private_func_data.error_msg_ctl = RDR_GENERATE_ERR_MSGS; 2161 } else { 2162 private_func_data.error_msg_ctl = RDR_DONT_GENERATE_ERR_MSGS; 2163 } 2164 2165 /* 2166 * Set variable information using memcpy 2167 */ 2168 bufptr = *buf; 2169 2170 (void) memcpy(bufptr, &private_func_data, sizeof (rdr_private_func_t)); 2171 bufptr += sizeof (rdr_private_func_t); 2172 2173 if (var_msg_info.ap_id_sizes != NULL) { 2174 (void) memcpy(bufptr, var_msg_info.ap_id_sizes, 2175 var_msg_info.ap_id_int_size); 2176 bufptr += var_msg_info.ap_id_int_size; 2177 } 2178 2179 if (var_msg_info.ap_id_chars != NULL) { 2180 (void) memcpy(bufptr, var_msg_info.ap_id_chars, 2181 var_msg_info.ap_id_char_size); 2182 bufptr += var_msg_info.ap_id_char_size; 2183 } 2184 2185 if (params->options != NULL) { 2186 (void) memcpy(bufptr, params->options, 2187 var_msg_info.options_strlen); 2188 bufptr += var_msg_info.options_strlen; 2189 for (i = 0; i < var_msg_info.options_pad_sz; i++) { 2190 bufptr[i] = 0; 2191 } 2192 bufptr += var_msg_info.options_pad_sz; 2193 } 2194 2195 if (params->function != NULL) { 2196 (void) memcpy(bufptr, params->function, 2197 var_msg_info.function_strlen); 2198 bufptr += var_msg_info.function_strlen; 2199 for (i = 0; i < var_msg_info.function_pad_sz; i++) { 2200 bufptr[i] = 0; 2201 } 2202 bufptr += var_msg_info.function_pad_sz; 2203 } 2204 2205 cleanup_variable_ap_id_info(&var_msg_info); 2206 2207 return (RDR_OK); 2208 } 2209 2210 2211 /* 2212 * unpack_private_func_request: 2213 * 2214 * Handle unpacking a private function request message. 2215 */ 2216 static int 2217 unpack_private_func_request(private_func_params_t *params, const char *buf) 2218 { 2219 char *bufptr; 2220 rdr_variable_message_info_t var_msg_info; 2221 rdr_private_func_t private_func_data; 2222 2223 2224 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 2225 2226 if ((params == NULL) || (buf == NULL)) { 2227 return (RDR_ERROR); 2228 } 2229 2230 bufptr = (char *)buf; 2231 (void) memcpy(&private_func_data, bufptr, sizeof (rdr_private_func_t)); 2232 bufptr += sizeof (rdr_private_func_t); 2233 2234 /* 2235 * handle getting the ap_ids 2236 */ 2237 var_msg_info.ap_id_char_size = private_func_data.ap_id_char_size; 2238 if (get_ap_ids_from_buf((char ***)&(params->ap_ids), 2239 private_func_data.num_ap_ids, &var_msg_info, bufptr)) { 2240 return (RDR_ERROR); 2241 } 2242 bufptr += var_msg_info.ap_id_int_size; 2243 bufptr += var_msg_info.ap_id_char_size; 2244 2245 /* 2246 * handle getting the options and function 2247 */ 2248 if (get_string_from_buf(&(params->options), 2249 private_func_data.options_size, bufptr)) { 2250 return (RDR_ERROR); 2251 } 2252 bufptr += private_func_data.options_size; 2253 2254 if (get_string_from_buf(&(params->function), 2255 private_func_data.function_size, bufptr)) { 2256 return (RDR_ERROR); 2257 } 2258 bufptr += private_func_data.function_size; 2259 2260 /* 2261 * Set fixed address labels by name 2262 */ 2263 params->num_ap_ids = private_func_data.num_ap_ids; 2264 2265 params->confp = (struct cfga_confirm *) 2266 malloc(sizeof (struct cfga_confirm)); 2267 if (params->confp == NULL) { 2268 return (RDR_MEM_ALLOC); 2269 } 2270 2271 /* set params->confp->confirm using memcpy */ 2272 (void) memcpy((void*)params->confp, 2273 &(private_func_data.confirm_callback_id), sizeof (unsigned long)); 2274 params->confp->appdata_ptr = 2275 (void*)private_func_data.confirm_appdata_ptr; 2276 2277 params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg)); 2278 if (params->msgp == NULL) { 2279 return (RDR_MEM_ALLOC); 2280 } 2281 2282 /* set params->msgp->message_routine using memcpy */ 2283 (void) memcpy((void*)params->msgp, 2284 &(private_func_data.msg_callback_id), sizeof (unsigned long)); 2285 params->msgp->appdata_ptr = 2286 (void*)private_func_data.msg_appdata_ptr; 2287 2288 if (private_func_data.error_msg_ctl == RDR_GENERATE_ERR_MSGS) { 2289 params->errstring = (char **)malloc(sizeof (char *)); 2290 if (params->errstring == NULL) { 2291 return (RDR_MEM_ALLOC); 2292 } 2293 *(params->errstring) = NULL; 2294 } else { /* error_msg_ctl == RDR_DONT_GENERATE_ERR_MSGS */ 2295 params->errstring = NULL; 2296 } 2297 params->flags = private_func_data.flags; 2298 2299 return (RDR_OK); 2300 } 2301 2302 2303 /* 2304 * pack_private_func_reply: 2305 * 2306 * Handle packing a private function reply message. 2307 */ 2308 static int 2309 pack_private_func_reply(private_func_params_t *params, char **buf, 2310 int *buf_size) 2311 { 2312 int i; 2313 char *bufptr; 2314 rdr_private_func_reply_t private_func_data; 2315 rdr_variable_message_info_t var_msg_info; 2316 2317 2318 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 2319 2320 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 2321 return (RDR_ERROR); 2322 } 2323 2324 /* 2325 * Set variable length fields (size info) 2326 */ 2327 if (find_errstring_sizes(params->errstring, &var_msg_info)) { 2328 return (RDR_ERROR); 2329 } 2330 2331 /* 2332 * Collect size info specific to the private_func reply 2333 * message and allocate a buffer 2334 */ 2335 *buf_size = sizeof (rdr_private_func_reply_t); 2336 *buf_size += var_msg_info.errstring_strlen; 2337 *buf_size += var_msg_info.errstring_pad_sz; 2338 2339 *buf = (char *)malloc(*buf_size); 2340 if (*buf == NULL) { 2341 return (RDR_MEM_ALLOC); 2342 } 2343 2344 /* 2345 * Set fixed address labels by name 2346 */ 2347 private_func_data.errstring_size = var_msg_info.errstring_strlen + 2348 var_msg_info.errstring_pad_sz; 2349 2350 /* 2351 * Set variable information using memcpy 2352 */ 2353 bufptr = *buf; 2354 2355 (void) memcpy(bufptr, &private_func_data, 2356 sizeof (rdr_private_func_reply_t)); 2357 bufptr += sizeof (rdr_private_func_reply_t); 2358 if ((params->errstring != NULL) && (*(params->errstring) != NULL)) { 2359 (void) memcpy(bufptr, *(params->errstring), 2360 var_msg_info.errstring_strlen); 2361 bufptr += var_msg_info.errstring_strlen; 2362 for (i = 0; i < var_msg_info.errstring_pad_sz; i++) { 2363 bufptr[i] = 0; 2364 } 2365 bufptr += var_msg_info.errstring_pad_sz; 2366 } 2367 2368 return (RDR_OK); 2369 } 2370 2371 2372 /* 2373 * unpack_private_func_reply: 2374 * 2375 * Handle unpacking a private function reply message. 2376 */ 2377 static int 2378 unpack_private_func_reply(private_func_params_t *params, const char *buf) 2379 { 2380 char *bufptr; 2381 rdr_private_func_reply_t private_func_data; 2382 2383 if ((params == NULL) || (buf == NULL)) { 2384 return (RDR_ERROR); 2385 } 2386 2387 bufptr = (char *)buf; 2388 (void) memcpy(&private_func_data, bufptr, 2389 sizeof (rdr_private_func_reply_t)); 2390 bufptr += sizeof (rdr_private_func_reply_t); 2391 2392 /* 2393 * handle getting the errstring 2394 */ 2395 params->errstring = (char **)malloc(sizeof (char *)); 2396 if (params->errstring == NULL) { 2397 return (RDR_MEM_ALLOC); 2398 } 2399 if (get_string_from_buf(params->errstring, 2400 private_func_data.errstring_size, bufptr)) { 2401 return (RDR_ERROR); 2402 } 2403 bufptr += private_func_data.errstring_size; 2404 2405 return (RDR_OK); 2406 } 2407 2408 2409 /* 2410 * pack_test_request: 2411 * 2412 * Handle packing a test request message. 2413 */ 2414 static int 2415 pack_test_request(test_params_t *params, char **buf, int *buf_size) 2416 { 2417 int i; 2418 char *bufptr; 2419 rdr_test_t test_data; 2420 rdr_variable_message_info_t var_msg_info; 2421 2422 2423 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 2424 return (RDR_ERROR); 2425 } 2426 2427 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 2428 2429 /* 2430 * Set variable length fields and make a call to partially 2431 * pack it. 2432 */ 2433 if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) { 2434 cleanup_variable_ap_id_info(&var_msg_info); 2435 return (RDR_ERROR); 2436 } 2437 if (find_options_sizes(params->options, &var_msg_info)) { 2438 cleanup_variable_ap_id_info(&var_msg_info); 2439 return (RDR_ERROR); 2440 } 2441 2442 /* 2443 * Collect size info specific to the test request 2444 * message and allocate a buffer 2445 */ 2446 *buf_size = sizeof (rdr_test_t); 2447 *buf_size += var_msg_info.ap_id_int_size; 2448 *buf_size += var_msg_info.ap_id_char_size; 2449 *buf_size += var_msg_info.options_strlen; 2450 *buf_size += var_msg_info.options_pad_sz; 2451 2452 *buf = (char *)malloc(*buf_size); 2453 if (*buf == NULL) { 2454 cleanup_variable_ap_id_info(&var_msg_info); 2455 return (RDR_MEM_ALLOC); 2456 } 2457 2458 /* 2459 * Set fixed address labels by name 2460 */ 2461 test_data.num_ap_ids = params->num_ap_ids; 2462 test_data.ap_id_char_size = var_msg_info.ap_id_char_size; 2463 test_data.options_size = var_msg_info.options_strlen + 2464 var_msg_info.options_pad_sz; 2465 2466 if (params->msgp != NULL) { 2467 test_data.msg_callback_id = 2468 (unsigned long)params->msgp->message_routine; 2469 test_data.msg_appdata_ptr = 2470 (unsigned long)params->msgp->appdata_ptr; 2471 } else { 2472 test_data.msg_callback_id = 0; 2473 test_data.msg_appdata_ptr = 0; 2474 } 2475 2476 test_data.flags = params->flags; 2477 2478 if (params->errstring != NULL) { 2479 test_data.error_msg_ctl = RDR_GENERATE_ERR_MSGS; 2480 } else { 2481 test_data.error_msg_ctl = RDR_DONT_GENERATE_ERR_MSGS; 2482 } 2483 2484 /* 2485 * Set variable information using memcpy 2486 */ 2487 bufptr = *buf; 2488 2489 (void) memcpy(bufptr, &test_data, sizeof (rdr_test_t)); 2490 bufptr += sizeof (rdr_test_t); 2491 2492 if (var_msg_info.ap_id_sizes != NULL) { 2493 (void) memcpy(bufptr, var_msg_info.ap_id_sizes, 2494 var_msg_info.ap_id_int_size); 2495 bufptr += var_msg_info.ap_id_int_size; 2496 } 2497 2498 if (var_msg_info.ap_id_chars != NULL) { 2499 (void) memcpy(bufptr, var_msg_info.ap_id_chars, 2500 var_msg_info.ap_id_char_size); 2501 bufptr += var_msg_info.ap_id_char_size; 2502 } 2503 2504 if (params->options != NULL) { 2505 (void) memcpy(bufptr, params->options, 2506 var_msg_info.options_strlen); 2507 bufptr += var_msg_info.options_strlen; 2508 for (i = 0; i < var_msg_info.options_pad_sz; i++) { 2509 bufptr[i] = 0; 2510 } 2511 bufptr += var_msg_info.options_pad_sz; 2512 } 2513 2514 cleanup_variable_ap_id_info(&var_msg_info); 2515 2516 return (RDR_OK); 2517 } 2518 2519 2520 /* 2521 * unpack_test_request: 2522 * 2523 * Handle unpacking a test request message. 2524 */ 2525 static int 2526 unpack_test_request(test_params_t *params, const char *buf) 2527 { 2528 char *bufptr; 2529 rdr_variable_message_info_t var_msg_info; 2530 rdr_test_t test_data; 2531 2532 2533 if ((params == NULL) || (buf == NULL)) { 2534 return (RDR_ERROR); 2535 } 2536 2537 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 2538 2539 bufptr = (char *)buf; 2540 (void) memcpy(&test_data, bufptr, sizeof (rdr_test_t)); 2541 bufptr += sizeof (rdr_test_t); 2542 2543 /* 2544 * handle getting the ap_ids 2545 */ 2546 var_msg_info.ap_id_char_size = test_data.ap_id_char_size; 2547 if (get_ap_ids_from_buf((char ***)&(params->ap_ids), 2548 test_data.num_ap_ids, &var_msg_info, bufptr)) { 2549 return (RDR_ERROR); 2550 } 2551 bufptr += var_msg_info.ap_id_int_size; 2552 bufptr += var_msg_info.ap_id_char_size; 2553 2554 /* 2555 * handle getting the options 2556 */ 2557 if (get_string_from_buf(&(params->options), 2558 test_data.options_size, bufptr)) { 2559 return (RDR_ERROR); 2560 } 2561 bufptr += test_data.options_size; 2562 2563 /* 2564 * Set fixed address labels by name 2565 */ 2566 params->num_ap_ids = test_data.num_ap_ids; 2567 2568 params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg)); 2569 if (params->msgp == NULL) { 2570 return (RDR_MEM_ALLOC); 2571 } 2572 2573 /* set params->msgp->message_routine using memcpy */ 2574 (void) memcpy((void*)params->msgp, 2575 &(test_data.msg_callback_id), sizeof (unsigned long)); 2576 params->msgp->appdata_ptr = 2577 (void*)test_data.msg_appdata_ptr; 2578 2579 if (test_data.error_msg_ctl == RDR_GENERATE_ERR_MSGS) { 2580 params->errstring = (char **)malloc(sizeof (char *)); 2581 if (params->errstring == NULL) { 2582 return (RDR_MEM_ALLOC); 2583 } 2584 *(params->errstring) = NULL; 2585 } else { /* error_msg_ctl == RDR_DONT_GENERATE_ERR_MSGS */ 2586 params->errstring = NULL; 2587 } 2588 params->flags = test_data.flags; 2589 2590 return (RDR_OK); 2591 } 2592 2593 2594 /* 2595 * pack_test_reply: 2596 * 2597 * Handle packing a test reply message. 2598 */ 2599 static int 2600 pack_test_reply(test_params_t *params, char **buf, int *buf_size) 2601 { 2602 int i; 2603 char *bufptr; 2604 rdr_test_reply_t test_data; 2605 rdr_variable_message_info_t var_msg_info; 2606 2607 2608 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 2609 return (RDR_ERROR); 2610 } 2611 2612 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 2613 2614 /* 2615 * Set variable length fields (size info) 2616 */ 2617 if (find_errstring_sizes(params->errstring, &var_msg_info)) { 2618 return (RDR_ERROR); 2619 } 2620 2621 /* 2622 * Collect size info specific to the test reply 2623 * message and allocate a buffer 2624 */ 2625 *buf_size = sizeof (rdr_test_reply_t); 2626 *buf_size += var_msg_info.errstring_strlen; 2627 *buf_size += var_msg_info.errstring_pad_sz; 2628 2629 *buf = (char *)malloc(*buf_size); 2630 if (*buf == NULL) { 2631 return (RDR_MEM_ALLOC); 2632 } 2633 2634 /* 2635 * Set fixed address labels by name 2636 */ 2637 test_data.errstring_size = var_msg_info.errstring_strlen + 2638 var_msg_info.errstring_pad_sz; 2639 2640 /* 2641 * Set variable information using memcpy 2642 */ 2643 bufptr = *buf; 2644 2645 (void) memcpy(bufptr, &test_data, sizeof (rdr_test_reply_t)); 2646 bufptr += sizeof (rdr_test_reply_t); 2647 if ((params->errstring != NULL) && (*(params->errstring) != NULL)) { 2648 (void) memcpy(bufptr, *(params->errstring), 2649 var_msg_info.errstring_strlen); 2650 bufptr += var_msg_info.errstring_strlen; 2651 for (i = 0; i < var_msg_info.errstring_pad_sz; i++) { 2652 bufptr[i] = 0; 2653 } 2654 bufptr += var_msg_info.errstring_pad_sz; 2655 } 2656 2657 return (RDR_OK); 2658 } 2659 2660 2661 /* 2662 * unpack_test_reply: 2663 * 2664 * Handle unpacking a test reply message. 2665 */ 2666 static int 2667 unpack_test_reply(test_params_t *params, const char *buf) 2668 { 2669 char *bufptr; 2670 rdr_test_reply_t test_data; 2671 2672 2673 if ((params == NULL) || (buf == NULL)) { 2674 return (RDR_ERROR); 2675 } 2676 2677 bufptr = (char *)buf; 2678 (void) memcpy(&test_data, bufptr, sizeof (rdr_test_reply_t)); 2679 bufptr += sizeof (rdr_test_reply_t); 2680 2681 /* 2682 * handle getting the errstring 2683 */ 2684 params->errstring = (char **)malloc(sizeof (char *)); 2685 if (params->errstring == NULL) { 2686 return (RDR_MEM_ALLOC); 2687 } 2688 if (get_string_from_buf(params->errstring, 2689 test_data.errstring_size, bufptr)) { 2690 return (RDR_ERROR); 2691 } 2692 bufptr += test_data.errstring_size; 2693 2694 return (RDR_OK); 2695 } 2696 2697 2698 /* 2699 * pack_list_ext_request: 2700 * 2701 * Handle packing a list request message. 2702 */ 2703 static int 2704 pack_list_ext_request(list_ext_params_t *params, char **buf, int *buf_size) 2705 { 2706 int i; 2707 char *bufptr; 2708 rdr_list_ext_t list_ext_data; 2709 rdr_variable_message_info_t var_msg_info; 2710 2711 2712 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 2713 return (RDR_ERROR); 2714 } 2715 2716 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 2717 2718 /* 2719 * Set variable length fields and make a call to partially 2720 * pack it. 2721 */ 2722 if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) { 2723 cleanup_variable_ap_id_info(&var_msg_info); 2724 return (RDR_ERROR); 2725 } 2726 if (find_options_sizes(params->options, &var_msg_info)) { 2727 cleanup_variable_ap_id_info(&var_msg_info); 2728 return (RDR_ERROR); 2729 } 2730 if (find_listopts_sizes(params->listopts, &var_msg_info)) { 2731 cleanup_variable_ap_id_info(&var_msg_info); 2732 return (RDR_ERROR); 2733 } 2734 2735 2736 /* 2737 * Collect size info specific to the list_ext request 2738 * message and allocate a buffer 2739 */ 2740 *buf_size = sizeof (rdr_list_ext_t); 2741 *buf_size += var_msg_info.ap_id_int_size; 2742 *buf_size += var_msg_info.ap_id_char_size; 2743 *buf_size += var_msg_info.options_strlen; 2744 *buf_size += var_msg_info.options_pad_sz; 2745 *buf_size += var_msg_info.listopts_strlen; 2746 *buf_size += var_msg_info.listopts_pad_sz; 2747 2748 *buf = (char *)malloc(*buf_size); 2749 if (*buf == NULL) { 2750 cleanup_variable_ap_id_info(&var_msg_info); 2751 return (RDR_MEM_ALLOC); 2752 } 2753 2754 /* 2755 * Set fixed address labels by name 2756 */ 2757 list_ext_data.num_ap_ids = params->num_ap_ids; 2758 list_ext_data.ap_id_char_size = var_msg_info.ap_id_char_size; 2759 list_ext_data.options_size = var_msg_info.options_strlen + 2760 var_msg_info.options_pad_sz; 2761 list_ext_data.listopts_size = var_msg_info.listopts_strlen + 2762 var_msg_info.listopts_pad_sz; 2763 if (params->errstring != NULL) { 2764 list_ext_data.error_msg_ctl = RDR_GENERATE_ERR_MSGS; 2765 } else { 2766 list_ext_data.error_msg_ctl = RDR_DONT_GENERATE_ERR_MSGS; 2767 } 2768 if ((params->num_ap_ids != 0) || (params->ap_ids != NULL)) { 2769 list_ext_data.list_msg_ctl = RDR_LIST_ONLY_PARAM_APS; 2770 } else { 2771 list_ext_data.list_msg_ctl = RDR_LIST_ALL_APS; 2772 } 2773 list_ext_data.flags = params->flags; 2774 list_ext_data.permissions = params->permissions; 2775 2776 /* 2777 * Set variable information using memcpy 2778 */ 2779 bufptr = *buf; 2780 2781 (void) memcpy(bufptr, &list_ext_data, sizeof (rdr_list_ext_t)); 2782 bufptr += sizeof (rdr_list_ext_t); 2783 2784 if (var_msg_info.ap_id_sizes != NULL) { 2785 (void) memcpy(bufptr, var_msg_info.ap_id_sizes, 2786 var_msg_info.ap_id_int_size); 2787 bufptr += var_msg_info.ap_id_int_size; 2788 } 2789 2790 if (var_msg_info.ap_id_chars != NULL) { 2791 (void) memcpy(bufptr, var_msg_info.ap_id_chars, 2792 var_msg_info.ap_id_char_size); 2793 bufptr += var_msg_info.ap_id_char_size; 2794 } 2795 2796 if (params->options != NULL) { 2797 (void) memcpy(bufptr, params->options, 2798 var_msg_info.options_strlen); 2799 bufptr += var_msg_info.options_strlen; 2800 for (i = 0; i < var_msg_info.options_pad_sz; i++) { 2801 bufptr[i] = 0; 2802 } 2803 bufptr += var_msg_info.options_pad_sz; 2804 } 2805 2806 if (params->listopts != NULL) { 2807 (void) memcpy(bufptr, params->listopts, 2808 var_msg_info.listopts_strlen); 2809 bufptr += var_msg_info.listopts_strlen; 2810 for (i = 0; i < var_msg_info.listopts_pad_sz; i++) { 2811 bufptr[i] = 0; 2812 } 2813 bufptr += var_msg_info.listopts_pad_sz; 2814 } 2815 2816 cleanup_variable_ap_id_info(&var_msg_info); 2817 2818 return (RDR_OK); 2819 } 2820 2821 2822 /* 2823 * unpack_list_ext_request: 2824 * 2825 * Handle unpacking a list request message. 2826 */ 2827 static int 2828 unpack_list_ext_request(list_ext_params_t *params, const char *buf) 2829 { 2830 char *bufptr; 2831 rdr_variable_message_info_t var_msg_info; 2832 rdr_list_ext_t list_ext_data; 2833 2834 2835 if ((params == NULL) || (buf == NULL)) { 2836 return (RDR_ERROR); 2837 } 2838 2839 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 2840 2841 bufptr = (char *)buf; 2842 (void) memcpy(&list_ext_data, bufptr, sizeof (rdr_list_ext_t)); 2843 bufptr += sizeof (rdr_list_ext_t); 2844 2845 /* 2846 * handle getting the ap_ids 2847 */ 2848 var_msg_info.ap_id_char_size = list_ext_data.ap_id_char_size; 2849 if (get_ap_ids_from_buf(&(params->ap_ids), list_ext_data.num_ap_ids, 2850 &var_msg_info, bufptr)) { 2851 return (RDR_ERROR); 2852 } 2853 bufptr += var_msg_info.ap_id_int_size; 2854 bufptr += var_msg_info.ap_id_char_size; 2855 2856 /* 2857 * handle getting the options 2858 */ 2859 if (get_string_from_buf(&(params->options), 2860 list_ext_data.options_size, bufptr)) { 2861 return (RDR_ERROR); 2862 } 2863 bufptr += list_ext_data.options_size; 2864 2865 /* 2866 * handle getting the listopts 2867 */ 2868 if (get_string_from_buf(&(params->listopts), 2869 list_ext_data.listopts_size, bufptr)) { 2870 return (RDR_ERROR); 2871 } 2872 bufptr += list_ext_data.listopts_size; 2873 2874 /* 2875 * Set fixed address labels by name 2876 */ 2877 params->num_ap_ids = list_ext_data.num_ap_ids; 2878 2879 params->ap_id_list = (rdr_list_t **)malloc(sizeof (rdr_list_t *)); 2880 if (params->ap_id_list == NULL) { 2881 return (RDR_MEM_ALLOC); 2882 } 2883 *(params->ap_id_list) = NULL; 2884 2885 params->nlist = (int *)malloc(sizeof (int)); 2886 if (params->nlist == NULL) { 2887 return (RDR_MEM_ALLOC); 2888 } 2889 if (list_ext_data.error_msg_ctl == RDR_GENERATE_ERR_MSGS) { 2890 params->errstring = (char **)malloc(sizeof (char *)); 2891 if (params->errstring == NULL) { 2892 return (RDR_MEM_ALLOC); 2893 } 2894 *(params->errstring) = NULL; 2895 } else { /* error_msg_ctl == RDR_DONT_GENERATE_ERR_MSGS */ 2896 params->errstring = NULL; 2897 } 2898 params->flags = list_ext_data.flags; 2899 params->permissions = list_ext_data.permissions; 2900 2901 return (RDR_OK); 2902 } 2903 2904 2905 /* 2906 * pack_list_ext_reply: 2907 * 2908 * Handle packing a list reply message. 2909 */ 2910 static int 2911 pack_list_ext_reply(list_ext_params_t *params, char **buf, int *buf_size) 2912 { 2913 int i; 2914 char *bufptr; 2915 rdr_list_ext_reply_t list_ext_data; 2916 rdr_variable_message_info_t var_msg_info; 2917 int list_data_size; 2918 2919 2920 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 2921 2922 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 2923 return (RDR_ERROR); 2924 } 2925 2926 /* 2927 * Set variable length fields (size info) 2928 */ 2929 if (find_errstring_sizes(params->errstring, &var_msg_info)) { 2930 return (RDR_ERROR); 2931 } 2932 2933 if (params->nlist == NULL) { 2934 list_data_size = 0; 2935 } else { 2936 list_data_size = *(params->nlist) * sizeof (rdr_list_t); 2937 } 2938 2939 /* 2940 * Collect size info specific to the list_ext reply 2941 * message and allocate a buffer 2942 */ 2943 *buf_size = sizeof (rdr_list_ext_reply_t); 2944 *buf_size += list_data_size; 2945 *buf_size += var_msg_info.errstring_strlen; 2946 *buf_size += var_msg_info.errstring_pad_sz; 2947 2948 *buf = (char *)malloc(*buf_size); 2949 if (*buf == NULL) { 2950 return (RDR_MEM_ALLOC); 2951 } 2952 2953 /* 2954 * Set fixed address labels by name 2955 */ 2956 list_ext_data.num_ap_ids = (params->nlist) ? *(params->nlist) : 0; 2957 list_ext_data.errstring_size = var_msg_info.errstring_strlen + 2958 var_msg_info.errstring_pad_sz; 2959 2960 /* 2961 * Set variable information using memcpy 2962 */ 2963 bufptr = *buf; 2964 2965 (void) memcpy(bufptr, &list_ext_data, sizeof (rdr_list_ext_reply_t)); 2966 bufptr += sizeof (rdr_list_ext_reply_t); 2967 2968 if ((params->ap_id_list != NULL) && (*(params->ap_id_list) != NULL)) { 2969 (void) memcpy(bufptr, *(params->ap_id_list), list_data_size); 2970 bufptr += list_data_size; 2971 } else if (list_data_size) { 2972 /* 2973 * Something is out of sync. We were expecting 2974 * some data to copy, but instead we found a 2975 * NULL pointer. 2976 */ 2977 (void) free((void *)*buf); 2978 *buf = NULL; 2979 return (RDR_ERROR); 2980 } 2981 2982 if ((params->errstring != NULL) && (*(params->errstring) != NULL)) { 2983 (void) memcpy(bufptr, *(params->errstring), 2984 var_msg_info.errstring_strlen); 2985 bufptr += var_msg_info.errstring_strlen; 2986 for (i = 0; i < var_msg_info.errstring_pad_sz; i++) { 2987 bufptr[i] = 0; 2988 } 2989 bufptr += var_msg_info.errstring_pad_sz; 2990 } 2991 2992 return (RDR_OK); 2993 } 2994 2995 2996 /* 2997 * unpack_list_ext_reply: 2998 * 2999 * Handle unpacking a list reply message. 3000 */ 3001 static int 3002 unpack_list_ext_reply(list_ext_params_t *params, const char *buf) 3003 { 3004 int list_data_size; 3005 char *bufptr; 3006 rdr_list_ext_reply_t list_ext_data; 3007 3008 3009 if ((params == NULL) || (buf == NULL)) { 3010 return (RDR_ERROR); 3011 } 3012 3013 bufptr = (char *)buf; 3014 (void) memcpy(&list_ext_data, bufptr, sizeof (rdr_list_ext_reply_t)); 3015 bufptr += sizeof (rdr_list_ext_reply_t); 3016 3017 /* 3018 * handle getting the ap_id rcfga_list_data_t's. 3019 */ 3020 if (list_ext_data.num_ap_ids > 0) { 3021 params->nlist = (int *)malloc(sizeof (int)); 3022 if (params->nlist == NULL) { 3023 return (RDR_MEM_ALLOC); 3024 } 3025 *(params->nlist) = list_ext_data.num_ap_ids; 3026 params->ap_id_list = (rdr_list_t **) 3027 malloc(sizeof (rdr_list_t *)); 3028 if (params->ap_id_list == NULL) { 3029 return (RDR_MEM_ALLOC); 3030 } 3031 *(params->ap_id_list) = (rdr_list_t *) 3032 malloc(sizeof (rdr_list_t) * list_ext_data.num_ap_ids); 3033 if (*(params->ap_id_list) == NULL) { 3034 return (RDR_MEM_ALLOC); 3035 } 3036 list_data_size = list_ext_data.num_ap_ids * sizeof (rdr_list_t); 3037 (void) memcpy(*(params->ap_id_list), bufptr, list_data_size); 3038 bufptr += list_data_size; 3039 } 3040 3041 /* 3042 * handle getting the errstring 3043 */ 3044 params->errstring = (char **)malloc(sizeof (char *)); 3045 if (params->errstring == NULL) { 3046 return (RDR_MEM_ALLOC); 3047 } 3048 if (get_string_from_buf(params->errstring, 3049 list_ext_data.errstring_size, bufptr)) { 3050 return (RDR_ERROR); 3051 } 3052 bufptr += list_ext_data.errstring_size; 3053 3054 return (RDR_OK); 3055 } 3056 3057 3058 /* 3059 * pack_help_request: 3060 * 3061 * Handle packing a help request message. 3062 */ 3063 static int 3064 pack_help_request(help_params_t *params, char **buf, int *buf_size) 3065 { 3066 int i; 3067 char *bufptr; 3068 rdr_help_t help_data; 3069 rdr_variable_message_info_t var_msg_info; 3070 3071 3072 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 3073 3074 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 3075 return (RDR_ERROR); 3076 } 3077 3078 /* 3079 * Set variable length fields and make a call to partially 3080 * pack it. 3081 */ 3082 if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) { 3083 cleanup_variable_ap_id_info(&var_msg_info); 3084 return (RDR_ERROR); 3085 } 3086 if (find_options_sizes(params->options, &var_msg_info)) { 3087 cleanup_variable_ap_id_info(&var_msg_info); 3088 return (RDR_ERROR); 3089 } 3090 3091 /* 3092 * Collect size info specific to the help request message and 3093 * and allocate a buffer 3094 */ 3095 *buf_size = sizeof (rdr_help_t); 3096 *buf_size += var_msg_info.ap_id_int_size; 3097 *buf_size += var_msg_info.ap_id_char_size; 3098 *buf_size += var_msg_info.options_strlen; 3099 *buf_size += var_msg_info.options_pad_sz; 3100 3101 *buf = (char *)malloc(*buf_size); 3102 if (*buf == NULL) { 3103 cleanup_variable_ap_id_info(&var_msg_info); 3104 return (RDR_MEM_ALLOC); 3105 } 3106 3107 /* 3108 * Set fixed address labels by name 3109 */ 3110 help_data.num_ap_ids = params->num_ap_ids; 3111 help_data.ap_id_char_size = var_msg_info.ap_id_char_size; 3112 help_data.options_size = var_msg_info.options_strlen + 3113 var_msg_info.options_pad_sz; 3114 3115 if (params->msgp != NULL) { 3116 help_data.msg_callback_id = 3117 (unsigned long)params->msgp->message_routine; 3118 help_data.msg_appdata_ptr = 3119 (unsigned long)params->msgp->appdata_ptr; 3120 } else { 3121 help_data.msg_callback_id = 0; 3122 help_data.msg_appdata_ptr = 0; 3123 } 3124 3125 help_data.flags = params->flags; 3126 3127 /* 3128 * Set variable information using memcpy 3129 */ 3130 bufptr = *buf; 3131 3132 (void) memcpy(bufptr, &help_data, sizeof (rdr_help_t)); 3133 bufptr += sizeof (rdr_help_t); 3134 3135 if (var_msg_info.ap_id_sizes != NULL) { 3136 (void) memcpy(bufptr, var_msg_info.ap_id_sizes, 3137 var_msg_info.ap_id_int_size); 3138 bufptr += var_msg_info.ap_id_int_size; 3139 } 3140 3141 if (var_msg_info.ap_id_chars != NULL) { 3142 (void) memcpy(bufptr, var_msg_info.ap_id_chars, 3143 var_msg_info.ap_id_char_size); 3144 bufptr += var_msg_info.ap_id_char_size; 3145 } 3146 3147 if (params->options != NULL) { 3148 (void) memcpy(bufptr, params->options, 3149 var_msg_info.options_strlen); 3150 bufptr += var_msg_info.options_strlen; 3151 for (i = 0; i < var_msg_info.options_pad_sz; i++) { 3152 bufptr[i] = 0; 3153 } 3154 bufptr += var_msg_info.options_pad_sz; 3155 } 3156 3157 cleanup_variable_ap_id_info(&var_msg_info); 3158 3159 return (RDR_OK); 3160 } 3161 3162 3163 /* 3164 * unpack_help_request: 3165 * 3166 * Handle unpacking a help request message. 3167 */ 3168 static int 3169 unpack_help_request(help_params_t *params, const char *buf) 3170 { 3171 char *bufptr; 3172 rdr_variable_message_info_t var_msg_info; 3173 rdr_help_t help_data; 3174 3175 3176 if ((params == NULL) || (buf == NULL)) { 3177 return (RDR_ERROR); 3178 } 3179 3180 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 3181 3182 bufptr = (char *)buf; 3183 (void) memcpy(&help_data, bufptr, sizeof (rdr_help_t)); 3184 bufptr += sizeof (rdr_help_t); 3185 3186 /* 3187 * handle getting the ap_ids 3188 */ 3189 var_msg_info.ap_id_char_size = help_data.ap_id_char_size; 3190 if (get_ap_ids_from_buf((char ***)&(params->ap_ids), 3191 help_data.num_ap_ids, &var_msg_info, bufptr)) { 3192 return (RDR_ERROR); 3193 } 3194 bufptr += var_msg_info.ap_id_int_size; 3195 bufptr += var_msg_info.ap_id_char_size; 3196 3197 /* 3198 * handle getting the options 3199 */ 3200 if (get_string_from_buf(&(params->options), 3201 help_data.options_size, bufptr)) { 3202 return (RDR_ERROR); 3203 } 3204 bufptr += help_data.options_size; 3205 3206 /* 3207 * Set fixed address labels by name 3208 */ 3209 params->num_ap_ids = help_data.num_ap_ids; 3210 3211 params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg)); 3212 if (params->msgp == NULL) { 3213 return (RDR_MEM_ALLOC); 3214 } 3215 3216 /* set params->msgp->message_routine using memcpy */ 3217 (void) memcpy((void*)params->msgp, &(help_data.msg_callback_id), 3218 sizeof (unsigned long)); 3219 3220 params->msgp->appdata_ptr = (void*)help_data.msg_appdata_ptr; 3221 params->flags = help_data.flags; 3222 3223 return (RDR_OK); 3224 } 3225 3226 3227 /* 3228 * pack_ap_id_cmp_request: 3229 * 3230 * Handle packing an attachment point comparison request message. 3231 */ 3232 static int 3233 pack_ap_id_cmp_request(ap_id_cmp_params_t *params, char **buf, int *buf_size) 3234 { 3235 int i; 3236 char *bufptr; 3237 rdr_ap_id_cmp_t ap_id_cmp_data; 3238 int ap_id1_strlen; 3239 int ap_id1_pad_sz; 3240 int ap_id2_strlen; 3241 int ap_id2_pad_sz; 3242 3243 3244 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 3245 return (RDR_ERROR); 3246 } 3247 3248 /* 3249 * Set variable length fields and make a call to partially 3250 * pack it. 3251 */ 3252 if (params->ap_log_id1 != NULL) { 3253 ap_id1_strlen = strlen(params->ap_log_id1) + 1; 3254 ap_id1_pad_sz = RDR_ALIGN_64_BIT - 3255 (ap_id1_strlen % RDR_ALIGN_64_BIT); 3256 } else { 3257 ap_id1_strlen = 0; 3258 ap_id1_pad_sz = 0; 3259 } 3260 3261 if (params->ap_log_id2 != NULL) { 3262 ap_id2_strlen = strlen(params->ap_log_id2) + 1; 3263 ap_id2_pad_sz = RDR_ALIGN_64_BIT - 3264 (ap_id2_strlen % RDR_ALIGN_64_BIT); 3265 } else { 3266 ap_id2_strlen = 0; 3267 ap_id2_pad_sz = 0; 3268 } 3269 3270 /* 3271 * Collect size info specific to the ap id compare request 3272 * message and allocate a buffer 3273 */ 3274 *buf_size = sizeof (rdr_ap_id_cmp_t); 3275 *buf_size += ap_id1_strlen; 3276 *buf_size += ap_id1_pad_sz; 3277 *buf_size += ap_id2_strlen; 3278 *buf_size += ap_id2_pad_sz; 3279 3280 *buf = (char *)malloc(*buf_size); 3281 if (*buf == NULL) { 3282 return (RDR_MEM_ALLOC); 3283 } 3284 3285 /* 3286 * Set fixed address labels by name 3287 */ 3288 ap_id_cmp_data.ap_id1_size = ap_id1_strlen + ap_id1_pad_sz; 3289 ap_id_cmp_data.ap_id2_size = ap_id2_strlen + ap_id2_pad_sz; 3290 3291 3292 /* 3293 * Set variable information using memcpy 3294 */ 3295 bufptr = *buf; 3296 3297 (void) memcpy(bufptr, &ap_id_cmp_data, sizeof (rdr_ap_id_cmp_t)); 3298 bufptr += sizeof (rdr_ap_id_cmp_t); 3299 3300 if (params->ap_log_id1 != NULL) { 3301 (void) memcpy(bufptr, params->ap_log_id1, ap_id1_strlen); 3302 bufptr += ap_id1_strlen; 3303 for (i = 0; i < ap_id1_pad_sz; i++) { 3304 bufptr[i] = 0; 3305 } 3306 bufptr += ap_id1_pad_sz; 3307 } 3308 3309 if (params->ap_log_id2 != NULL) { 3310 (void) memcpy(bufptr, params->ap_log_id2, ap_id2_strlen); 3311 bufptr += ap_id2_strlen; 3312 for (i = 0; i < ap_id2_pad_sz; i++) { 3313 bufptr[i] = 0; 3314 } 3315 bufptr += ap_id2_pad_sz; 3316 } 3317 3318 return (RDR_OK); 3319 } 3320 3321 3322 /* 3323 * unpack_ap_id_cmp_request: 3324 * 3325 * Handle unpacking an attachment point comparison request message. 3326 */ 3327 static int 3328 unpack_ap_id_cmp_request(ap_id_cmp_params_t *params, const char *buf) 3329 { 3330 char *bufptr; 3331 rdr_ap_id_cmp_t ap_id_cmp_data; 3332 3333 3334 if ((params == NULL) || (buf == NULL)) { 3335 return (RDR_ERROR); 3336 } 3337 3338 bufptr = (char *)buf; 3339 (void) memcpy(&ap_id_cmp_data, bufptr, sizeof (rdr_ap_id_cmp_t)); 3340 bufptr += sizeof (rdr_ap_id_cmp_t); 3341 3342 /* 3343 * handle getting the cmp ap ids 3344 */ 3345 if (get_string_from_buf(&(params->ap_log_id1), 3346 ap_id_cmp_data.ap_id1_size, bufptr)) { 3347 return (RDR_ERROR); 3348 } 3349 bufptr += ap_id_cmp_data.ap_id1_size; 3350 3351 if (get_string_from_buf(&(params->ap_log_id2), 3352 ap_id_cmp_data.ap_id2_size, bufptr)) { 3353 return (RDR_ERROR); 3354 } 3355 bufptr += ap_id_cmp_data.ap_id2_size; 3356 3357 return (RDR_OK); 3358 } 3359 3360 3361 /* 3362 * pack_abort_cmd_request: 3363 * 3364 * Handle packing an abort request message. 3365 */ 3366 static int 3367 pack_abort_cmd_request(abort_cmd_params_t *params, char **buf, int *buf_size) 3368 { 3369 rdr_abort_cmd_t abort_cmd_data; 3370 3371 3372 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 3373 return (RDR_ERROR); 3374 } 3375 3376 /* 3377 * Collect size info specific to the abort cmd request 3378 * message and allocate a buffer 3379 */ 3380 *buf_size = sizeof (rdr_abort_cmd_t); 3381 3382 *buf = (char *)malloc(*buf_size); 3383 if (*buf == NULL) { 3384 return (RDR_MEM_ALLOC); 3385 } 3386 3387 /* 3388 * Set fixed session identifier 3389 */ 3390 abort_cmd_data.session_id = params->session_id; 3391 3392 /* 3393 * Copy information using memcpy 3394 */ 3395 (void) memcpy(*buf, &abort_cmd_data, sizeof (rdr_abort_cmd_t)); 3396 3397 return (RDR_OK); 3398 } 3399 3400 3401 /* 3402 * unpack_abort_cmd_request: 3403 * 3404 * Handle unpacking an abort request message. 3405 */ 3406 static int 3407 unpack_abort_cmd_request(abort_cmd_params_t *params, const char *buf) 3408 { 3409 rdr_abort_cmd_t *abort_cmd_datap; 3410 3411 3412 if ((params == NULL) || (buf == NULL)) { 3413 return (RDR_ERROR); 3414 } 3415 3416 /* LINTED Pointer Cast Alignment Warning */ 3417 abort_cmd_datap = (rdr_abort_cmd_t *)buf; 3418 3419 /* 3420 * copy out the session information 3421 */ 3422 3423 params->session_id = abort_cmd_datap->session_id; 3424 3425 return (RDR_OK); 3426 } 3427 3428 3429 /* 3430 * pack_confirm_request: 3431 * 3432 * Handle packing a confirm callback request. 3433 */ 3434 static int 3435 pack_confirm_request(confirm_callback_params_t *params, char **buf, 3436 int *buf_size) 3437 { 3438 int i; 3439 char *bufptr; 3440 rdr_confirm_callback_t confirm_callback_data; 3441 int message_strlen; 3442 int message_pad_sz; 3443 3444 3445 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 3446 return (RDR_ERROR); 3447 } 3448 3449 /* 3450 * Set variable length fields and make a call to partially 3451 * pack it. 3452 */ 3453 if (params->message != NULL) { 3454 message_strlen = strlen(params->message) + 1; 3455 message_pad_sz = RDR_ALIGN_64_BIT - 3456 (message_strlen % RDR_ALIGN_64_BIT); 3457 } else { 3458 message_strlen = 0; 3459 message_pad_sz = 0; 3460 } 3461 3462 3463 /* 3464 * Collect size info specific to the confirm callback request 3465 * message and allocate a buffer 3466 */ 3467 *buf_size = sizeof (rdr_confirm_callback_t); 3468 *buf_size += message_strlen; 3469 *buf_size += message_pad_sz; 3470 3471 *buf = (char *)malloc(*buf_size); 3472 if (*buf == NULL) { 3473 return (RDR_MEM_ALLOC); 3474 } 3475 3476 /* 3477 * Set fixed address labels by name 3478 */ 3479 if (params->confp != NULL) { 3480 confirm_callback_data.confirm_callback_id = 3481 (unsigned long)params->confp->confirm; 3482 confirm_callback_data.appdata_ptr = 3483 (unsigned long)params->confp->appdata_ptr; 3484 } else { 3485 confirm_callback_data.confirm_callback_id = 0; 3486 confirm_callback_data.appdata_ptr = 0; 3487 } 3488 confirm_callback_data.message_size = message_strlen + message_pad_sz; 3489 3490 /* 3491 * Set variable information using memcpy 3492 */ 3493 bufptr = *buf; 3494 (void) memcpy(bufptr, &confirm_callback_data, 3495 sizeof (rdr_confirm_callback_t)); 3496 bufptr += sizeof (rdr_confirm_callback_t); 3497 3498 if (params->message != NULL) { 3499 (void) memcpy(bufptr, params->message, message_strlen); 3500 bufptr += message_strlen; 3501 for (i = 0; i < message_pad_sz; i++) { 3502 bufptr[i] = 0; 3503 } 3504 bufptr += message_pad_sz; 3505 } 3506 3507 return (RDR_OK); 3508 } 3509 3510 3511 /* 3512 * unpack_confirm_request: 3513 * 3514 * Handle unpacking a confirm callback request. 3515 */ 3516 static int 3517 unpack_confirm_request(confirm_callback_params_t *params, const char *buf) 3518 { 3519 char *bufptr; 3520 rdr_confirm_callback_t confirm_callback_data; 3521 3522 3523 if ((params == NULL) || (buf == NULL)) { 3524 return (RDR_ERROR); 3525 } 3526 3527 bufptr = (char *)buf; 3528 (void) memcpy(&confirm_callback_data, bufptr, 3529 sizeof (rdr_confirm_callback_t)); 3530 bufptr += sizeof (rdr_confirm_callback_t); 3531 3532 /* 3533 * handle getting the message text 3534 */ 3535 if (get_string_from_buf(&(params->message), 3536 confirm_callback_data.message_size, bufptr)) { 3537 return (RDR_ERROR); 3538 } 3539 bufptr += confirm_callback_data.message_size; 3540 3541 /* 3542 * Set fixed address labels by name 3543 */ 3544 params->confp = (struct cfga_confirm *) 3545 malloc(sizeof (struct cfga_confirm)); 3546 if (params->confp == NULL) { 3547 return (RDR_MEM_ALLOC); 3548 } 3549 3550 /* set params->confp->confirm using memcpy */ 3551 (void) memcpy((void*)params->confp, 3552 &(confirm_callback_data.confirm_callback_id), 3553 sizeof (unsigned long)); 3554 3555 params->confp->appdata_ptr = 3556 (void*)confirm_callback_data.appdata_ptr; 3557 3558 return (RDR_OK); 3559 } 3560 3561 3562 /* 3563 * pack_confirm_reply: 3564 * 3565 * Handle packing a confirm callback reply. 3566 */ 3567 static int 3568 pack_confirm_reply(confirm_callback_params_t *params, char **buf, int *buf_size) 3569 { 3570 char *bufptr; 3571 rdr_confirm_callback_reply_t confirm_callback_data; 3572 3573 3574 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 3575 return (RDR_ERROR); 3576 } 3577 3578 /* 3579 * Collect size info specific to the confirm callback reply 3580 * message and allocate a buffer 3581 */ 3582 *buf_size = sizeof (confirm_callback_params_t); 3583 *buf = (char *)malloc(*buf_size); 3584 if (*buf == NULL) { 3585 return (RDR_MEM_ALLOC); 3586 } 3587 3588 /* 3589 * Set fixed address labels by name 3590 */ 3591 if (params->confp != NULL) { 3592 confirm_callback_data.confirm_callback_id = 3593 (unsigned long)params->confp->confirm; 3594 confirm_callback_data.appdata_ptr = 3595 (unsigned long)params->confp->appdata_ptr; 3596 } else { 3597 confirm_callback_data.confirm_callback_id = 0; 3598 confirm_callback_data.appdata_ptr = 0; 3599 } 3600 confirm_callback_data.response = params->response; 3601 3602 /* 3603 * Set variable information using memcpy 3604 */ 3605 bufptr = *buf; 3606 3607 (void) memcpy(bufptr, &confirm_callback_data, 3608 sizeof (rdr_confirm_callback_reply_t)); 3609 3610 return (RDR_OK); 3611 } 3612 3613 3614 /* 3615 * unpack_confirm_reply: 3616 * 3617 * Handle unpacking a confirm callback reply. 3618 */ 3619 static int 3620 unpack_confirm_reply(confirm_callback_params_t *params, const char *buf) 3621 { 3622 char *bufptr; 3623 rdr_confirm_callback_reply_t confirm_callback_data; 3624 3625 if ((params == NULL) || (buf == NULL)) { 3626 return (RDR_ERROR); 3627 } 3628 3629 bufptr = (char *)buf; 3630 (void) memcpy(&confirm_callback_data, bufptr, 3631 sizeof (rdr_confirm_callback_reply_t)); 3632 bufptr += sizeof (confirm_callback_params_t); 3633 3634 /* 3635 * Set fixed address labels by name 3636 */ 3637 params->confp = (struct cfga_confirm *) 3638 malloc(sizeof (struct cfga_confirm)); 3639 if (params->confp == NULL) { 3640 return (RDR_MEM_ALLOC); 3641 } 3642 3643 /* set params->confp->confirm using memcpy */ 3644 (void) memcpy((void*)params->confp, 3645 &(confirm_callback_data.confirm_callback_id), 3646 sizeof (unsigned long)); 3647 3648 params->confp->appdata_ptr = 3649 (void*)confirm_callback_data.appdata_ptr; 3650 params->response = confirm_callback_data.response; 3651 3652 return (RDR_OK); 3653 } 3654 3655 3656 /* 3657 * pack_message_request: 3658 * 3659 * Handle packing a message callback request. 3660 */ 3661 static int 3662 pack_message_request(msg_callback_params_t *params, char **buf, int *buf_size) 3663 { 3664 int i; 3665 char *bufptr; 3666 rdr_msg_callback_t msg_callback_data; 3667 int message_strlen; 3668 int message_pad_sz; 3669 3670 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 3671 return (RDR_ERROR); 3672 } 3673 3674 /* 3675 * Set variable length fields and make a call to partially 3676 * pack it. 3677 */ 3678 if (params->message != NULL) { 3679 message_strlen = strlen(params->message) + 1; 3680 message_pad_sz = RDR_ALIGN_64_BIT - 3681 (message_strlen % RDR_ALIGN_64_BIT); 3682 } else { 3683 message_strlen = 0; 3684 message_pad_sz = 0; 3685 } 3686 3687 3688 /* 3689 * Collect size info specific to the message callback request 3690 * message and allocate a buffer 3691 */ 3692 *buf_size = sizeof (rdr_msg_callback_t); 3693 *buf_size += message_strlen; 3694 *buf_size += message_pad_sz; 3695 3696 *buf = (char *)malloc(*buf_size); 3697 if (*buf == NULL) { 3698 return (RDR_MEM_ALLOC); 3699 } 3700 3701 /* 3702 * Set fixed address labels by name 3703 */ 3704 if (params->msgp != NULL) { 3705 msg_callback_data.msg_callback_id = 3706 (unsigned long)params->msgp->message_routine; 3707 msg_callback_data.appdata_ptr = 3708 (unsigned long)params->msgp->appdata_ptr; 3709 } else { 3710 msg_callback_data.msg_callback_id = 0; 3711 msg_callback_data.appdata_ptr = 0; 3712 } 3713 msg_callback_data.message_size = message_strlen + message_pad_sz; 3714 3715 /* 3716 * Set variable information using memcpy 3717 */ 3718 bufptr = *buf; 3719 3720 (void) memcpy(bufptr, &msg_callback_data, sizeof (rdr_msg_callback_t)); 3721 bufptr += sizeof (rdr_msg_callback_t); 3722 3723 if (params->message != NULL) { 3724 (void) memcpy(bufptr, params->message, message_strlen); 3725 bufptr += message_strlen; 3726 for (i = 0; i < message_pad_sz; i++) { 3727 bufptr[i] = 0; 3728 } 3729 bufptr += message_pad_sz; 3730 } 3731 3732 return (RDR_OK); 3733 } 3734 3735 3736 /* 3737 * unpack_message_request: 3738 * 3739 * Handle unpacking a message callback request. 3740 */ 3741 static int 3742 unpack_message_request(msg_callback_params_t *params, const char *buf) 3743 { 3744 char *bufptr; 3745 rdr_msg_callback_t msg_callback_data; 3746 3747 if ((params == NULL) || (buf == NULL)) { 3748 return (RDR_ERROR); 3749 } 3750 3751 bufptr = (char *)buf; 3752 (void) memcpy(&msg_callback_data, bufptr, sizeof (rdr_msg_callback_t)); 3753 bufptr += sizeof (rdr_msg_callback_t); 3754 3755 /* 3756 * handle getting the message text 3757 */ 3758 if (get_string_from_buf(&(params->message), 3759 msg_callback_data.message_size, bufptr)) { 3760 return (RDR_ERROR); 3761 } 3762 bufptr += msg_callback_data.message_size; 3763 3764 /* 3765 * Set fixed address labels by name 3766 */ 3767 params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg)); 3768 if (params->msgp == NULL) { 3769 return (RDR_MEM_ALLOC); 3770 } 3771 3772 /* set params->msgp->message_routine using memcpy */ 3773 (void) memcpy((void*)params->msgp, &(msg_callback_data.msg_callback_id), 3774 sizeof (unsigned long)); 3775 3776 params->msgp->appdata_ptr = (void*)msg_callback_data.appdata_ptr; 3777 3778 return (RDR_OK); 3779 } 3780 3781 /* 3782 * pack_rsrc_info_request: 3783 * 3784 * Handle packing a resource info request. 3785 */ 3786 static int 3787 pack_rsrc_info_request(rsrc_info_params_t *params, char **buf, int *buf_size) 3788 { 3789 char *bufptr; 3790 rdr_rsrc_info_t rsrc_info_data; 3791 rdr_variable_message_info_t var_msg_info; 3792 3793 3794 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 3795 return (RDR_ERROR); 3796 } 3797 3798 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 3799 3800 /* 3801 * Set variable length fields and make a call to partially 3802 * pack it. 3803 */ 3804 if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) { 3805 cleanup_variable_ap_id_info(&var_msg_info); 3806 return (RDR_ERROR); 3807 } 3808 3809 /* 3810 * Collect size info specific to the resource info request 3811 * message and allocate a buffer. 3812 */ 3813 *buf_size = sizeof (rdr_rsrc_info_t); 3814 *buf_size += var_msg_info.ap_id_int_size; 3815 *buf_size += var_msg_info.ap_id_char_size; 3816 3817 *buf = (char *)malloc(*buf_size); 3818 if (*buf == NULL) { 3819 return (RDR_MEM_ALLOC); 3820 } 3821 3822 /* 3823 * Set fixed address labels by name. 3824 */ 3825 rsrc_info_data.num_ap_ids = params->num_ap_ids; 3826 rsrc_info_data.ap_id_char_size = var_msg_info.ap_id_char_size; 3827 rsrc_info_data.flags = params->flags; 3828 3829 /* 3830 * Set variable information using memcpy. 3831 */ 3832 bufptr = *buf; 3833 3834 (void) memcpy(bufptr, &rsrc_info_data, sizeof (rdr_rsrc_info_t)); 3835 bufptr += sizeof (rdr_rsrc_info_t); 3836 3837 if (var_msg_info.ap_id_sizes != NULL) { 3838 (void) memcpy(bufptr, var_msg_info.ap_id_sizes, 3839 var_msg_info.ap_id_int_size); 3840 bufptr += var_msg_info.ap_id_int_size; 3841 } 3842 3843 if (var_msg_info.ap_id_chars != NULL) { 3844 (void) memcpy(bufptr, var_msg_info.ap_id_chars, 3845 var_msg_info.ap_id_char_size); 3846 bufptr += var_msg_info.ap_id_char_size; 3847 } 3848 3849 cleanup_variable_ap_id_info(&var_msg_info); 3850 3851 return (RDR_OK); 3852 } 3853 3854 3855 /* 3856 * unpack_rsrc_info_request: 3857 * 3858 * Handle unpacking a resource info request message. 3859 */ 3860 static int 3861 unpack_rsrc_info_request(rsrc_info_params_t *params, const char *buf) 3862 { 3863 char *bufptr; 3864 rdr_variable_message_info_t var_msg_info; 3865 rdr_rsrc_info_t rsrc_info_data; 3866 3867 3868 if ((params == NULL) || (buf == NULL)) { 3869 return (RDR_ERROR); 3870 } 3871 3872 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 3873 3874 bufptr = (char *)buf; 3875 (void) memcpy(&rsrc_info_data, bufptr, sizeof (rdr_rsrc_info_t)); 3876 bufptr += sizeof (rdr_rsrc_info_t); 3877 3878 /* 3879 * Handle getting the ap_ids. 3880 */ 3881 var_msg_info.ap_id_char_size = rsrc_info_data.ap_id_char_size; 3882 if (get_ap_ids_from_buf(&(params->ap_ids), rsrc_info_data.num_ap_ids, 3883 &var_msg_info, bufptr)) { 3884 return (RDR_ERROR); 3885 } 3886 bufptr += var_msg_info.ap_id_int_size; 3887 bufptr += var_msg_info.ap_id_char_size; 3888 3889 /* 3890 * Set fixed address labels by name. 3891 */ 3892 params->num_ap_ids = rsrc_info_data.num_ap_ids; 3893 params->flags = rsrc_info_data.flags; 3894 3895 return (RDR_OK); 3896 } 3897 3898 3899 /* 3900 * pack_rsrc_info_reply: 3901 * 3902 * Handle packing a resource info reply message. 3903 */ 3904 static int 3905 pack_rsrc_info_reply(rsrc_info_params_t *params, char **buf, int *buf_size) 3906 { 3907 char *bufptr; 3908 rdr_rsrc_info_reply_t rsrc_info_data; 3909 int pack_status; 3910 caddr_t rsrc_info_bufp = NULL; 3911 size_t rsrc_info_size; 3912 3913 3914 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 3915 return (RDR_ERROR); 3916 } 3917 3918 /* 3919 * Pack snapshot handle data. 3920 */ 3921 pack_status = ri_pack(params->hdl, &rsrc_info_bufp, &rsrc_info_size); 3922 if (pack_status != 0) { 3923 return (RDR_ERROR); 3924 } 3925 3926 /* 3927 * Collect size info specific to the rsrc_info reply message 3928 * and allocate a buffer. 3929 */ 3930 *buf_size = sizeof (rdr_rsrc_info_reply_t); 3931 *buf_size += rsrc_info_size; 3932 3933 *buf = (char *)malloc(*buf_size); 3934 if (*buf == NULL) { 3935 free(rsrc_info_bufp); 3936 return (RDR_MEM_ALLOC); 3937 } 3938 3939 /* 3940 * Set fixed address labels by name. 3941 */ 3942 rsrc_info_data.packed_hdl_size = rsrc_info_size; 3943 3944 /* 3945 * Set variable information using memcpy. 3946 */ 3947 bufptr = *buf; 3948 3949 (void) memcpy(bufptr, &rsrc_info_data, sizeof (rdr_rsrc_info_reply_t)); 3950 bufptr += sizeof (rdr_rsrc_info_reply_t); 3951 3952 if (rsrc_info_bufp) { 3953 (void) memcpy(bufptr, rsrc_info_bufp, rsrc_info_size); 3954 free(rsrc_info_bufp); 3955 } 3956 3957 return (RDR_OK); 3958 } 3959 3960 3961 /* 3962 * unpack_rsrc_info_reply: 3963 * 3964 * Handle unpacking a resource info reply message. 3965 */ 3966 static int 3967 unpack_rsrc_info_reply(rsrc_info_params_t *params, const char *buf) 3968 { 3969 int unpack_status; 3970 char *bufptr; 3971 rdr_rsrc_info_reply_t rsrc_info_data; 3972 3973 3974 if ((params == NULL) || (buf == NULL)) { 3975 return (RDR_ERROR); 3976 } 3977 3978 bufptr = (char *)buf; 3979 (void) memcpy(&rsrc_info_data, bufptr, sizeof (rdr_rsrc_info_reply_t)); 3980 bufptr += sizeof (rdr_rsrc_info_reply_t); 3981 3982 /* 3983 * Unpack buf into resource info handle. 3984 */ 3985 unpack_status = ri_unpack(bufptr, rsrc_info_data.packed_hdl_size, 3986 ¶ms->hdl); 3987 3988 return ((unpack_status == 0) ? RDR_OK : RDR_ERROR); 3989 } 3990 3991 3992 /* 3993 * pack_ap_ids: 3994 * 3995 * Pack a list of attachment point identifiers into a single buffer. 3996 * This buffer is stored in the specified rdr_variable_message_info_t 3997 * and is padded to be 64-bit aligned. 3998 */ 3999 static int 4000 pack_ap_ids(int num_ap_ids, char *const *ap_ids, 4001 rdr_variable_message_info_t *var_msg_info) 4002 { 4003 int i; 4004 int ap_id_pad_sz; 4005 char *bufptr; 4006 4007 4008 if (var_msg_info == NULL) { 4009 return (RDR_ERROR); 4010 } 4011 4012 /* 4013 * NULL is a valid value for ap_ids in the list_ext 4014 * case. For list_ext, no specified attachment points 4015 * indicates that _all_ attachment points should be 4016 * displayed. However, if ap_ids is NULL, num_ap_ids 4017 * should be 0. 4018 */ 4019 if ((ap_ids == NULL) && (num_ap_ids != 0)) { 4020 num_ap_ids = 0; 4021 } 4022 4023 var_msg_info->ap_id_int_size = sizeof (int) * num_ap_ids; 4024 if (num_ap_ids > 0) { 4025 var_msg_info->ap_id_sizes = (int *)malloc(sizeof (int) * 4026 var_msg_info->ap_id_int_size); 4027 if (var_msg_info->ap_id_sizes == NULL) { 4028 return (RDR_MEM_ALLOC); 4029 } 4030 } 4031 for (i = 0; i < num_ap_ids; i++) { 4032 if (ap_ids[i] != NULL) { 4033 var_msg_info->ap_id_sizes[i] = strlen(ap_ids[i]) + 1; 4034 var_msg_info->ap_id_char_size += 4035 var_msg_info->ap_id_sizes[i]; 4036 } 4037 } 4038 if (var_msg_info->ap_id_char_size > 0) { 4039 ap_id_pad_sz = RDR_ALIGN_64_BIT - 4040 (var_msg_info->ap_id_char_size % RDR_ALIGN_64_BIT); 4041 var_msg_info->ap_id_char_size += ap_id_pad_sz; 4042 var_msg_info->ap_id_chars = (char *) 4043 malloc(var_msg_info->ap_id_char_size); 4044 if (var_msg_info->ap_id_chars == NULL) { 4045 return (RDR_MEM_ALLOC); 4046 } 4047 4048 bufptr = var_msg_info->ap_id_chars; 4049 for (i = 0; i < num_ap_ids; i++) { 4050 (void) memcpy(bufptr, ap_ids[i], 4051 var_msg_info->ap_id_sizes[i]); 4052 bufptr += var_msg_info->ap_id_sizes[i]; 4053 } 4054 for (i = 0; i < ap_id_pad_sz; i++) { 4055 bufptr[i] = 0; 4056 } 4057 } else { 4058 ap_id_pad_sz = 0; 4059 } 4060 4061 return (RDR_OK); 4062 } 4063 4064 4065 /* 4066 * unpack_ap_ids: 4067 * 4068 * Unpack a buffer containing a concatenation of a list of 4069 * attachment point identifiers. The resulting list of strings 4070 * are stored in an array in the specified rdr_variable_message_info_t. 4071 */ 4072 static int 4073 unpack_ap_ids(int num_ap_ids, char **ap_ids, const char *buf, 4074 rdr_variable_message_info_t *var_msg_info) 4075 { 4076 int i; 4077 int ap_id_size; 4078 int chars_copied; 4079 char *bufptr; 4080 4081 4082 if ((ap_ids == NULL) || (buf == NULL) || (var_msg_info == NULL)) { 4083 return (RDR_ERROR); 4084 } 4085 bufptr = (char *)buf; 4086 4087 var_msg_info->ap_id_int_size = sizeof (int) * num_ap_ids; 4088 if (num_ap_ids > 0) { 4089 var_msg_info->ap_id_sizes = (int *) 4090 malloc(sizeof (int) * var_msg_info->ap_id_int_size); 4091 if (var_msg_info->ap_id_sizes == NULL) { 4092 return (RDR_MEM_ALLOC); 4093 } 4094 (void) memcpy(var_msg_info->ap_id_sizes, bufptr, 4095 var_msg_info->ap_id_int_size); 4096 } 4097 bufptr += var_msg_info->ap_id_int_size; 4098 4099 chars_copied = 0; 4100 for (i = 0; i < num_ap_ids; i++) { 4101 ap_id_size = var_msg_info->ap_id_sizes[i]; 4102 if (ap_id_size <= 0) { 4103 continue; 4104 } 4105 if ((chars_copied + ap_id_size) > 4106 var_msg_info->ap_id_char_size) { 4107 return (RDR_ERROR); 4108 } 4109 ap_ids[i] = (char *)malloc(ap_id_size); 4110 if (ap_ids[i] == NULL) { 4111 return (RDR_MEM_ALLOC); 4112 } 4113 (void) memcpy(ap_ids[i], bufptr, ap_id_size); 4114 bufptr += ap_id_size; 4115 chars_copied += ap_id_size; 4116 } 4117 return (RDR_OK); 4118 } 4119 4120 4121 /* 4122 * find_options_sizes: 4123 * 4124 * Determine the size of a specified option string. The information 4125 * is stored in the specified rdr_variable_message_info_t. 4126 */ 4127 static int 4128 find_options_sizes(char *options, rdr_variable_message_info_t *var_msg_info) 4129 { 4130 if (var_msg_info == NULL) { 4131 return (RDR_ERROR); 4132 } 4133 if (options != NULL) { 4134 var_msg_info->options_strlen = strlen(options) + 1; 4135 var_msg_info->options_pad_sz = RDR_ALIGN_64_BIT - 4136 (var_msg_info->options_strlen % RDR_ALIGN_64_BIT); 4137 } else { 4138 var_msg_info->options_strlen = 0; 4139 var_msg_info->options_pad_sz = 0; 4140 } 4141 return (RDR_OK); 4142 } 4143 4144 4145 /* 4146 * find_listopts_sizes: 4147 * 4148 * Determine the size of a specified list option string. The information 4149 * is stored in the specified rdr_variable_message_info_t. 4150 */ 4151 static int 4152 find_listopts_sizes(char *listopts, rdr_variable_message_info_t *var_msg_info) 4153 { 4154 if (var_msg_info == NULL) { 4155 return (RDR_ERROR); 4156 } 4157 if (listopts != NULL) { 4158 var_msg_info->listopts_strlen = strlen(listopts) + 1; 4159 var_msg_info->listopts_pad_sz = RDR_ALIGN_64_BIT - 4160 (var_msg_info->listopts_strlen % RDR_ALIGN_64_BIT); 4161 } else { 4162 var_msg_info->listopts_strlen = 0; 4163 var_msg_info->listopts_pad_sz = 0; 4164 } 4165 return (RDR_OK); 4166 } 4167 4168 4169 /* 4170 * find_function_size: 4171 * 4172 * Determine the size of a specified private function string. The 4173 * information is stored in the specified rdr_variable_message_info_t. 4174 */ 4175 static int 4176 find_function_sizes(char *function, rdr_variable_message_info_t *var_msg_info) 4177 { 4178 if (var_msg_info == NULL) { 4179 return (RDR_ERROR); 4180 } 4181 if (function != NULL) { 4182 var_msg_info->function_strlen = strlen(function) + 1; 4183 var_msg_info->function_pad_sz = RDR_ALIGN_64_BIT - 4184 (var_msg_info->function_strlen % RDR_ALIGN_64_BIT); 4185 } else { 4186 var_msg_info->function_strlen = 0; 4187 var_msg_info->function_pad_sz = 0; 4188 } 4189 return (RDR_OK); 4190 } 4191 4192 4193 /* 4194 * find_errstring_sizes: 4195 * 4196 * Determine the size of a specified error string. The information 4197 * is stored in the specified rdr_variable_message_info_t. 4198 */ 4199 static int 4200 find_errstring_sizes(char **errstring, 4201 rdr_variable_message_info_t *var_msg_info) 4202 { 4203 if ((errstring != NULL) && (*errstring != NULL)) { 4204 var_msg_info->errstring_strlen = strlen(*errstring) + 1; 4205 var_msg_info->errstring_pad_sz = RDR_ALIGN_64_BIT - 4206 (var_msg_info->errstring_strlen % RDR_ALIGN_64_BIT); 4207 } else { 4208 var_msg_info->errstring_strlen = 0; 4209 var_msg_info->errstring_pad_sz = 0; 4210 } 4211 return (RDR_OK); 4212 } 4213 4214 4215 /* 4216 * get_ap_ids_from_buf: 4217 * 4218 * Unpack a buffer containing a concatenation of a list of attachment 4219 * point identifiers. An appropriately sized buffer is allocated and 4220 * the resulting list of strings are stored in an array in the specified 4221 * rdr_variable_message_info_t. 4222 */ 4223 static int 4224 get_ap_ids_from_buf(char ***ap_id_ptr, int num_ap_ids, 4225 rdr_variable_message_info_t *var_msg_info, const char *buf) 4226 { 4227 if ((ap_id_ptr == NULL) || (buf == NULL) || (var_msg_info == NULL)) { 4228 return (RDR_ERROR); 4229 } 4230 if (num_ap_ids > 0) { 4231 *ap_id_ptr = (char **)malloc(sizeof (char *) * num_ap_ids); 4232 if (*ap_id_ptr == NULL) { 4233 return (RDR_MEM_ALLOC); 4234 } 4235 if (unpack_ap_ids(num_ap_ids, *ap_id_ptr, buf, var_msg_info)) { 4236 cleanup_variable_ap_id_info(var_msg_info); 4237 return (RDR_ERROR); 4238 } 4239 4240 } else if (num_ap_ids < 0) { 4241 return (RDR_ERROR); 4242 } 4243 4244 cleanup_variable_ap_id_info(var_msg_info); 4245 4246 return (RDR_OK); 4247 } 4248 4249 4250 /* 4251 * get_string_from_buf: 4252 * 4253 * Copy a string to a new buffer. Memory is allocated for the 4254 * new buffer and the original string is copied to the new buffer. 4255 * This is primarily used when a string is located in a packed 4256 * buffer that will eventually get deallocated. 4257 */ 4258 static int 4259 get_string_from_buf(char **stringptr, int strsize, const char *buf) 4260 { 4261 if (buf == NULL) { 4262 return (RDR_ERROR); 4263 } 4264 4265 /* 4266 * A stringptr of NULL is a valid value. The errstring param 4267 * in an rconfig_xxx call is valid and is passed to this 4268 * function. For example, see errstring in the call to this 4269 * function in unpack_change_state_reply. 4270 */ 4271 if (stringptr != NULL) { 4272 if (strsize > 0) { 4273 *stringptr = (char *)malloc(strsize); 4274 if (*stringptr == NULL) { 4275 return (RDR_MEM_ALLOC); 4276 } 4277 (void) memcpy(*stringptr, buf, strsize); 4278 } else if (strsize == 0) { 4279 *stringptr = NULL; 4280 } else if (strsize < 0) { 4281 *stringptr = NULL; 4282 return (RDR_ERROR); 4283 } 4284 } 4285 return (RDR_OK); 4286 } 4287 4288 4289 /* 4290 * cleanup_ap_ids: 4291 * 4292 * Deallocate the specified array of attachment point identifiers. 4293 */ 4294 static int 4295 cleanup_ap_ids(int num_ap_ids, char ** ap_ids) 4296 { 4297 int i; 4298 4299 if (ap_ids == NULL) { 4300 return (RDR_ERROR); 4301 } 4302 for (i = 0; i < num_ap_ids; i++) { 4303 if (ap_ids[i] != NULL) { 4304 free((void *)ap_ids[i]); 4305 ap_ids[i] = NULL; 4306 } 4307 } 4308 return (RDR_OK); 4309 } 4310 4311 4312 /* 4313 * cleanup_errstring: 4314 * 4315 * Deallocate the specified error string. 4316 */ 4317 static int 4318 cleanup_errstring(char **errstring) 4319 { 4320 if (errstring) { 4321 if (*errstring) { 4322 free((void *)*errstring); 4323 } 4324 free((void *)errstring); 4325 errstring = NULL; 4326 } 4327 4328 return (RDR_OK); 4329 } 4330 4331 4332 /* 4333 * cleanup_variable_ap_id_info: 4334 * 4335 * Deallocate the ap_id information from the specified 4336 * rdr_variable_message_info_t. 4337 */ 4338 static void 4339 cleanup_variable_ap_id_info(rdr_variable_message_info_t *var_msg_info) 4340 { 4341 if (var_msg_info != NULL) { 4342 if (var_msg_info->ap_id_sizes != NULL) { 4343 free((void *)var_msg_info->ap_id_sizes); 4344 var_msg_info->ap_id_sizes = NULL; 4345 } 4346 if (var_msg_info->ap_id_chars != NULL) { 4347 free((void *)var_msg_info->ap_id_chars); 4348 var_msg_info->ap_id_chars = NULL; 4349 } 4350 } 4351 } 4352