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 2005 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 * rdr_setsockopt: 1196 * 1197 * Wrapper of the setsockopt(3SOCKET) library function. 1198 */ 1199 int 1200 rdr_setsockopt(int fd, int level, int optname, const void *optval, int optlen) 1201 { 1202 if (setsockopt(fd, level, optname, optval, optlen) == -1) 1203 return (RDR_NET_ERR); 1204 else 1205 return (RDR_OK); 1206 } 1207 1208 1209 /* 1210 * Private (static) Functions 1211 */ 1212 1213 1214 /* 1215 * rdr_setopt: 1216 * 1217 * Set the specified option for a given transport endpoint. 1218 * This function only sets boolean options. It does not 1219 * provide the ability to unset an option, or set a non- 1220 * boolean option. 1221 */ 1222 static int 1223 rdr_setopt(int fd, int name, int level) 1224 { 1225 int on = 1; 1226 1227 1228 if (setsockopt(fd, level, name, &on, sizeof (on)) == -1) { 1229 return (RDR_NET_ERR); 1230 } 1231 1232 return (RDR_OK); 1233 } 1234 1235 1236 /* 1237 * rdr_bind: 1238 * 1239 * Bind the specified file descriptor to a specified 1240 * address. If the address is already bound, no error is 1241 * returned. This is the expected behavior if a server 1242 * has been started by inetd (1M). 1243 */ 1244 static int 1245 rdr_bind(int fd, struct sockaddr *addr) 1246 { 1247 unsigned int addr_len; 1248 int rc; 1249 1250 1251 /* initialize the address */ 1252 switch (addr->sa_family) { 1253 1254 case AF_INET: 1255 addr_len = sizeof (struct sockaddr_in); 1256 break; 1257 1258 case AF_INET6: 1259 addr_len = sizeof (struct sockaddr_in6); 1260 break; 1261 1262 default: 1263 return (RDR_ERROR); 1264 } 1265 1266 /* attempt to bind the address */ 1267 rc = bind(fd, addr, addr_len); 1268 1269 /* 1270 * Ignore the error if EINVAL is returned. In 1271 * this case, we assume that this means that 1272 * the address was already bound. This is not 1273 * an error for servers started by inetd (1M). 1274 */ 1275 if ((rc == -1) && (errno != EINVAL)) { 1276 return (RDR_NET_ERR); 1277 } 1278 1279 /* 1280 * Retreive the address information of the 1281 * address that was actually bound. 1282 */ 1283 addr_len = sizeof (*addr); 1284 if (getsockname(fd, addr, &addr_len) == -1) { 1285 (void) memset(addr, 0, sizeof (*addr)); 1286 return (RDR_NET_ERR); 1287 } 1288 1289 return (RDR_OK); 1290 } 1291 1292 1293 /* 1294 * rdr_snd: 1295 * 1296 * Send a message in two stages. First the header is sent, 1297 * followed by the packed buffer containing the message 1298 * contents. 1299 */ 1300 static int 1301 rdr_snd(int fd, rdr_msg_hdr_t *hdr, char *data, int data_sz, int timeout) 1302 { 1303 int err; 1304 1305 1306 /* sanity check */ 1307 if (hdr == NULL) { 1308 return (RDR_ERROR); 1309 } 1310 1311 /* ensure null pad bytes */ 1312 hdr->pad_byte1 = 0; 1313 hdr->pad_byte2 = 0; 1314 1315 /* initialize size information */ 1316 hdr->data_length = data_sz; 1317 1318 /* send message header */ 1319 err = rdr_snd_raw(fd, (char *)hdr, RDR_MSG_HDR_SIZE, timeout); 1320 if (err != RDR_OK) { 1321 return (err); 1322 } 1323 1324 /* check if more to send */ 1325 if (data_sz == 0) { 1326 return (RDR_OK); 1327 } 1328 1329 /* send message data */ 1330 err = rdr_snd_raw(fd, data, data_sz, timeout); 1331 if (err != RDR_OK) { 1332 return (err); 1333 } 1334 1335 return (RDR_OK); 1336 } 1337 1338 1339 /* 1340 * rdr_snd_raw: 1341 * 1342 * Send a raw buffer of information. This function handles 1343 * the low level details of the send operation. 1344 */ 1345 static int 1346 rdr_snd_raw(int fd, char *msg, int data_sz, int timeout) 1347 { 1348 int err; 1349 int num_bytes; 1350 int bytes_left; 1351 char *bufp; 1352 struct pollfd pfd; 1353 1354 1355 bufp = (char *)msg; 1356 1357 bytes_left = data_sz; 1358 1359 pfd.fd = fd; 1360 pfd.events = POLLOUT; 1361 1362 while (bytes_left > 0) { 1363 1364 pfd.revents = 0; 1365 1366 /* wait until we can send the data */ 1367 if ((err = poll(&pfd, 1, timeout)) == -1) { 1368 1369 /* poll was interrupted */ 1370 if (errno == EINTR) { 1371 return (RDR_ABORTED); 1372 } 1373 1374 return (RDR_ERROR); 1375 1376 } else if (err == 0) { 1377 return (RDR_TIMEOUT); 1378 } 1379 1380 /* ready to send data */ 1381 if (pfd.revents & POLLOUT) { 1382 1383 num_bytes = write(fd, bufp, bytes_left); 1384 1385 if (num_bytes == -1) { 1386 1387 /* 1388 * Distinguish between an aborted 1389 * session and other network errors. 1390 */ 1391 if (errno == EPIPE) { 1392 return (RDR_ABORTED); 1393 } else { 1394 return (RDR_NET_ERR); 1395 } 1396 } 1397 1398 /* wrote 0 bytes, so operation was aborted */ 1399 if (num_bytes == 0) { 1400 return (RDR_ABORTED); 1401 } 1402 1403 } else { 1404 return (RDR_NET_ERR); 1405 } 1406 1407 bytes_left -= num_bytes; 1408 bufp += num_bytes; 1409 } 1410 1411 return (RDR_OK); 1412 } 1413 1414 1415 /* 1416 * rdr_rcv: 1417 * 1418 * Receive a message in two stages. First the header is 1419 * received, followed by the packed buffer containing the 1420 * message contents. 1421 */ 1422 static int 1423 rdr_rcv(int fd, rdr_msg_hdr_t *hdr, char **data, int timeout) 1424 { 1425 int err; 1426 int data_sz; 1427 char hdr_buf[RDR_MSG_HDR_SIZE]; 1428 char *buf = NULL; 1429 1430 1431 /* sanity check */ 1432 if (hdr == NULL) { 1433 return (RDR_ERROR); 1434 } 1435 1436 /* receive the header */ 1437 err = rdr_rcv_raw(fd, hdr_buf, RDR_MSG_HDR_SIZE, timeout); 1438 if (err != RDR_OK) { 1439 return (err); 1440 } 1441 1442 /* verify that the data is good */ 1443 /* LINTED Pointer Cast Alignment Warning */ 1444 if (validate_header((rdr_msg_hdr_t *)hdr_buf) != RDR_OK) { 1445 return (RDR_MSG_INVAL); 1446 } 1447 1448 /* LINTED Pointer Cast Alignment Warning */ 1449 data_sz = ((rdr_msg_hdr_t *)hdr_buf)->data_length; 1450 1451 buf = (char *)malloc(data_sz); 1452 if (!buf) { 1453 return (RDR_MEM_ALLOC); 1454 } 1455 1456 if (data_sz != 0) { 1457 1458 /* receive the rest of the message */ 1459 err = rdr_rcv_raw(fd, buf, data_sz, timeout); 1460 if (err != RDR_OK) { 1461 free((void *)buf); 1462 return (err); 1463 } 1464 } 1465 1466 /* copy out data */ 1467 *data = buf; 1468 (void) memcpy(hdr, hdr_buf, RDR_MSG_HDR_SIZE); 1469 1470 return (RDR_OK); 1471 } 1472 1473 1474 /* 1475 * rdr_rcv_raw: 1476 * 1477 * Receive a raw buffer of information. This function handles 1478 * the low level details of the receive operation. 1479 */ 1480 static int 1481 rdr_rcv_raw(int fd, char *msg, int data_size, int timeout) 1482 { 1483 int num_bytes; 1484 int err; 1485 int bytes_left; 1486 char *bufp; 1487 struct pollfd pollfd; 1488 1489 1490 bufp = (char *)msg; 1491 bytes_left = data_size; 1492 1493 pollfd.fd = fd; 1494 pollfd.events = POLLIN; 1495 1496 while (bytes_left > 0) { 1497 1498 errno = 0; 1499 pollfd.revents = 0; 1500 1501 if ((err = poll(&pollfd, 1, timeout)) == -1) { 1502 1503 /* 1504 * In the DCA, if a session is aborted, SIGINT 1505 * is delivered to all active sessions. This 1506 * mistakenly causes all sessions waiting in 1507 * the poll to be interrupted. So, if EINTR 1508 * is returned, it is ignored. If another error 1509 * occurs right away, the current session really 1510 * was aborted. All other sessions won't encounter 1511 * an error and will proceed normally. 1512 */ 1513 if ((errno == 0) || (errno == EINTR)) { 1514 continue; 1515 } 1516 1517 return (RDR_ABORTED); 1518 1519 } else if (err == 0) { 1520 return (RDR_TIMEOUT); 1521 } 1522 1523 /* ready to receive data */ 1524 if (pollfd.revents & POLLIN) { 1525 1526 num_bytes = read(fd, bufp, bytes_left); 1527 1528 if (num_bytes == -1) { 1529 1530 /* 1531 * Distinguish between an aborted 1532 * session and other network errors. 1533 */ 1534 if (errno == ECONNRESET) { 1535 return (RDR_ABORTED); 1536 } else { 1537 return (RDR_NET_ERR); 1538 } 1539 } 1540 1541 /* read 0 bytes, so operation was aborted */ 1542 if (num_bytes == 0) { 1543 return (RDR_ABORTED); 1544 } 1545 1546 } else { 1547 return (RDR_NET_ERR); 1548 } 1549 1550 bytes_left -= num_bytes; 1551 bufp += num_bytes; 1552 } 1553 1554 return (RDR_OK); 1555 } 1556 1557 1558 /* 1559 * validate_header: 1560 * 1561 * Perform a series of sanity checks on the header data that is 1562 * received. This gets called before the variable length data is 1563 * read in to make sure that the information in the header can 1564 * be trusted. 1565 */ 1566 static int 1567 validate_header(rdr_msg_hdr_t *hdr) 1568 { 1569 unsigned char op; 1570 1571 1572 if (hdr == NULL) { 1573 return (RDR_ERROR); 1574 } 1575 1576 op = hdr->message_opcode; 1577 1578 /* validate opcode */ 1579 if ((op < RDR_SES_REQ) || (op >= RDR_NUM_OPS)) { 1580 return (RDR_ERROR); 1581 } 1582 1583 /* validate message size (and type) for op */ 1584 switch (hdr->data_type) { 1585 1586 case RDR_REQUEST: 1587 if (hdr->data_length > msg_sizes[op].req_max) { 1588 return (RDR_ERROR); 1589 } 1590 break; 1591 1592 case RDR_REPLY: 1593 if (hdr->data_length > msg_sizes[op].reply_max) { 1594 return (RDR_ERROR); 1595 } 1596 break; 1597 1598 default: 1599 /* invalid data type */ 1600 return (RDR_ERROR); 1601 } 1602 1603 /* all checks passed */ 1604 return (RDR_OK); 1605 } 1606 1607 1608 /* 1609 * pack_ses_req_request: 1610 * 1611 * Handle packing a session request request message. 1612 */ 1613 static int 1614 pack_ses_req_request(ses_req_params_t *params, char **buf, int *buf_size) 1615 { 1616 char *bufptr; 1617 int locale_str_len; 1618 rdr_ses_req_t ses_req; 1619 1620 1621 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 1622 return (RDR_ERROR); 1623 } 1624 1625 /* 1626 * Determine the size of the locale string 1627 */ 1628 if (params->locale_str != NULL) { 1629 locale_str_len = strlen(params->locale_str) + 1; 1630 } else { 1631 locale_str_len = 0; 1632 } 1633 1634 /* 1635 * Collect size info specific to the ses_req request message 1636 * and allocate a buffer 1637 */ 1638 *buf_size = sizeof (rdr_ses_req_t); 1639 *buf_size += locale_str_len; 1640 1641 *buf = (char *)malloc(*buf_size); 1642 if (*buf == NULL) { 1643 return (RDR_MEM_ALLOC); 1644 } 1645 1646 /* 1647 * Set fixed locale size label by name 1648 */ 1649 ses_req.locale_size = locale_str_len; 1650 1651 /* 1652 * Set variable information using memcpy 1653 */ 1654 bufptr = *buf; 1655 1656 (void) memcpy(bufptr, &ses_req, sizeof (rdr_ses_req_t)); 1657 bufptr += sizeof (rdr_ses_req_t); 1658 1659 if (params->locale_str != NULL) { 1660 (void) memcpy(bufptr, params->locale_str, locale_str_len); 1661 bufptr += locale_str_len; 1662 } 1663 1664 return (RDR_OK); 1665 } 1666 1667 1668 /* 1669 * unpack_ses_req_request: 1670 * 1671 * Handle unpacking a session request request message. 1672 */ 1673 static int 1674 unpack_ses_req_request(ses_req_params_t *params, const char *buf) 1675 { 1676 char *bufptr; 1677 rdr_ses_req_t ses_req_data; 1678 1679 1680 if ((params == NULL) || (buf == NULL)) { 1681 return (RDR_ERROR); 1682 } 1683 1684 bufptr = (char *)buf; 1685 (void) memcpy(&ses_req_data, bufptr, sizeof (rdr_ses_req_t)); 1686 bufptr += sizeof (rdr_ses_req_t); 1687 1688 /* 1689 * handle getting the locale string 1690 */ 1691 if (get_string_from_buf(&(params->locale_str), 1692 ses_req_data.locale_size, bufptr)) { 1693 return (RDR_ERROR); 1694 } 1695 1696 return (RDR_OK); 1697 } 1698 1699 1700 /* 1701 * pack_ses_req_reply: 1702 * 1703 * Handle packing a session request reply message. 1704 */ 1705 static int 1706 pack_ses_req_reply(ses_req_params_t *params, char **buf, int *buf_size) 1707 { 1708 rdr_ses_req_reply_t ses_req_reply_data; 1709 1710 1711 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 1712 return (RDR_ERROR); 1713 } 1714 1715 /* 1716 * Collect size info specific to the session request reply 1717 * message and allocate a buffer 1718 */ 1719 *buf_size = sizeof (rdr_ses_req_reply_t); 1720 1721 *buf = (char *)malloc(*buf_size); 1722 if (*buf == NULL) { 1723 return (RDR_MEM_ALLOC); 1724 } 1725 1726 /* 1727 * Set fixed session identifier 1728 */ 1729 ses_req_reply_data.session_id = params->session_id; 1730 1731 /* 1732 * Copy information using memcpy 1733 */ 1734 (void) memcpy(*buf, &ses_req_reply_data, sizeof (rdr_ses_req_reply_t)); 1735 1736 return (RDR_OK); 1737 } 1738 1739 1740 /* 1741 * unpack_ses_req_request: 1742 * 1743 * Handle unpacking a session request reply message. 1744 */ 1745 static int 1746 unpack_ses_req_reply(ses_req_params_t *params, const char *buf) 1747 { 1748 rdr_ses_req_reply_t *ses_req_reply_datap; 1749 1750 1751 if ((params == NULL) || (buf == NULL)) { 1752 return (RDR_ERROR); 1753 } 1754 1755 /* LINTED Pointer Cast Alignment Warning */ 1756 ses_req_reply_datap = (rdr_ses_req_reply_t *)buf; 1757 1758 /* 1759 * copy out the session information 1760 */ 1761 params->session_id = ses_req_reply_datap->session_id; 1762 1763 return (RDR_OK); 1764 } 1765 1766 1767 /* 1768 * pack_change_state_request: 1769 * 1770 * Handle packing a change state request message. 1771 */ 1772 static int 1773 pack_change_state_request(change_state_params_t *params, char **buf, 1774 int *buf_size) 1775 { 1776 int i; 1777 char *bufptr; 1778 rdr_change_state_t change_state_data; 1779 rdr_variable_message_info_t var_msg_info; 1780 1781 1782 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 1783 return (RDR_ERROR); 1784 } 1785 1786 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 1787 1788 /* 1789 * Set variable length fields and make a call to partially 1790 * pack it. 1791 */ 1792 if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) { 1793 cleanup_variable_ap_id_info(&var_msg_info); 1794 return (RDR_ERROR); 1795 } 1796 if (find_options_sizes(params->options, &var_msg_info)) { 1797 cleanup_variable_ap_id_info(&var_msg_info); 1798 return (RDR_ERROR); 1799 } 1800 1801 /* 1802 * Collect size info specific to the change_state request 1803 * message and allocate a buffer 1804 */ 1805 *buf_size = sizeof (rdr_change_state_t); 1806 *buf_size += var_msg_info.ap_id_int_size; 1807 *buf_size += var_msg_info.ap_id_char_size; 1808 *buf_size += var_msg_info.options_strlen; 1809 *buf_size += var_msg_info.options_pad_sz; 1810 1811 *buf = (char *)malloc(*buf_size); 1812 if (*buf == NULL) { 1813 cleanup_variable_ap_id_info(&var_msg_info); 1814 return (RDR_MEM_ALLOC); 1815 } 1816 1817 /* 1818 * Set fixed address labels by name 1819 */ 1820 change_state_data.num_ap_ids = params->num_ap_ids; 1821 change_state_data.ap_id_char_size = var_msg_info.ap_id_char_size; 1822 change_state_data.options_size = var_msg_info.options_strlen + 1823 var_msg_info.options_pad_sz; 1824 1825 if (params->confp != NULL) { 1826 change_state_data.confirm_callback_id = 1827 (unsigned long)params->confp->confirm; 1828 change_state_data.confirm_appdata_ptr = 1829 (unsigned long)params->confp->appdata_ptr; 1830 } else { 1831 change_state_data.confirm_callback_id = 0; 1832 change_state_data.confirm_appdata_ptr = 0; 1833 } 1834 if (params->msgp != NULL) { 1835 change_state_data.msg_callback_id = 1836 (unsigned long)params->msgp->message_routine; 1837 change_state_data.msg_appdata_ptr = 1838 (unsigned long)params->msgp->appdata_ptr; 1839 } else { 1840 change_state_data.msg_callback_id = 0; 1841 change_state_data.msg_appdata_ptr = 0; 1842 } 1843 1844 change_state_data.flags = params->flags; 1845 change_state_data.timeval = params->timeval; 1846 change_state_data.state_change_cmd = params->state_change; 1847 if (params->errstring != NULL) { 1848 change_state_data.error_msg_ctl = RDR_GENERATE_ERR_MSGS; 1849 } else { 1850 change_state_data.error_msg_ctl = RDR_DONT_GENERATE_ERR_MSGS; 1851 } 1852 change_state_data.retries = params->retries; 1853 1854 /* 1855 * Set variable information using memcpy 1856 */ 1857 bufptr = *buf; 1858 1859 (void) memcpy(bufptr, &change_state_data, sizeof (rdr_change_state_t)); 1860 bufptr += sizeof (rdr_change_state_t); 1861 1862 if (var_msg_info.ap_id_sizes != NULL) { 1863 (void) memcpy(bufptr, var_msg_info.ap_id_sizes, 1864 var_msg_info.ap_id_int_size); 1865 bufptr += var_msg_info.ap_id_int_size; 1866 } 1867 1868 if (var_msg_info.ap_id_chars != NULL) { 1869 (void) memcpy(bufptr, var_msg_info.ap_id_chars, 1870 var_msg_info.ap_id_char_size); 1871 bufptr += var_msg_info.ap_id_char_size; 1872 } 1873 1874 if (params->options != NULL) { 1875 (void) memcpy(bufptr, params->options, 1876 var_msg_info.options_strlen); 1877 bufptr += var_msg_info.options_strlen; 1878 for (i = 0; i < var_msg_info.options_pad_sz; i++) { 1879 bufptr[i] = 0; 1880 } 1881 bufptr += var_msg_info.options_pad_sz; 1882 } 1883 1884 cleanup_variable_ap_id_info(&var_msg_info); 1885 1886 return (RDR_OK); 1887 } 1888 1889 1890 /* 1891 * unpack_change_state_request: 1892 * 1893 * Handle unpacking a change state request message. 1894 */ 1895 static int 1896 unpack_change_state_request(change_state_params_t *params, const char *buf) 1897 { 1898 char *bufptr; 1899 rdr_variable_message_info_t var_msg_info; 1900 rdr_change_state_t change_state_data; 1901 1902 1903 if ((params == NULL) || (buf == NULL)) { 1904 return (RDR_ERROR); 1905 } 1906 1907 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 1908 1909 bufptr = (char *)buf; 1910 (void) memcpy(&change_state_data, bufptr, sizeof (rdr_change_state_t)); 1911 bufptr += sizeof (rdr_change_state_t); 1912 1913 /* 1914 * handle getting the ap_ids 1915 */ 1916 var_msg_info.ap_id_char_size = change_state_data.ap_id_char_size; 1917 if (get_ap_ids_from_buf((char ***)&(params->ap_ids), 1918 change_state_data.num_ap_ids, &var_msg_info, bufptr)) { 1919 return (RDR_ERROR); 1920 } 1921 bufptr += var_msg_info.ap_id_int_size; 1922 bufptr += var_msg_info.ap_id_char_size; 1923 1924 /* 1925 * handle getting the options 1926 */ 1927 if (get_string_from_buf(&(params->options), 1928 change_state_data.options_size, bufptr)) { 1929 return (RDR_ERROR); 1930 } 1931 bufptr += change_state_data.options_size; 1932 1933 /* 1934 * Set fixed address labels by name 1935 */ 1936 params->state_change = (cfga_cmd_t)change_state_data.state_change_cmd; 1937 params->num_ap_ids = change_state_data.num_ap_ids; 1938 1939 params->confp = (struct cfga_confirm *) 1940 malloc(sizeof (struct cfga_confirm)); 1941 if (params->confp == NULL) { 1942 return (RDR_MEM_ALLOC); 1943 } 1944 1945 /* set params->confp->confirm using memcpy */ 1946 (void) memcpy((void*)params->confp, 1947 &(change_state_data.confirm_callback_id), sizeof (unsigned long)); 1948 params->confp->appdata_ptr = 1949 (void*)change_state_data.confirm_appdata_ptr; 1950 1951 params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg)); 1952 if (params->msgp == NULL) { 1953 return (RDR_MEM_ALLOC); 1954 } 1955 1956 /* set params->msgp->message_routine using memcpy */ 1957 (void) memcpy((void*)params->msgp, 1958 &(change_state_data.msg_callback_id), sizeof (unsigned long)); 1959 params->msgp->appdata_ptr = 1960 (void*)change_state_data.msg_appdata_ptr; 1961 1962 if (change_state_data.error_msg_ctl == RDR_GENERATE_ERR_MSGS) { 1963 params->errstring = (char **)malloc(sizeof (char *)); 1964 if (params->errstring == NULL) { 1965 return (RDR_MEM_ALLOC); 1966 } 1967 *(params->errstring) = NULL; 1968 } else { /* error_msg_ctl == RDR_DONT_GENERATE_ERR_MSGS */ 1969 params->errstring = NULL; 1970 } 1971 params->flags = change_state_data.flags; 1972 params->timeval = change_state_data.timeval; 1973 params->retries = change_state_data.retries; 1974 1975 return (RDR_OK); 1976 } 1977 1978 1979 /* 1980 * pack_change_state_reply: 1981 * 1982 * Handle packing a change state reply message. 1983 */ 1984 static int 1985 pack_change_state_reply(change_state_params_t *params, char **buf, 1986 int *buf_size) 1987 { 1988 int i; 1989 char *bufptr; 1990 rdr_change_state_reply_t change_state_data; 1991 rdr_variable_message_info_t var_msg_info; 1992 1993 1994 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 1995 1996 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 1997 return (RDR_ERROR); 1998 } 1999 2000 /* 2001 * Set variable length fields (size info) 2002 */ 2003 if (find_errstring_sizes(params->errstring, &var_msg_info)) { 2004 return (RDR_ERROR); 2005 } 2006 2007 /* 2008 * Collect size info specific to the change_state reply 2009 * message and allocate a buffer 2010 */ 2011 *buf_size = sizeof (rdr_change_state_reply_t); 2012 *buf_size += var_msg_info.errstring_strlen; 2013 *buf_size += var_msg_info.errstring_pad_sz; 2014 2015 *buf = (char *)malloc(*buf_size); 2016 if (*buf == NULL) { 2017 return (RDR_MEM_ALLOC); 2018 } 2019 2020 /* 2021 * Set fixed address labels by name 2022 */ 2023 change_state_data.errstring_size = var_msg_info.errstring_strlen + 2024 var_msg_info.errstring_pad_sz; 2025 2026 /* 2027 * Set variable information using memcpy 2028 */ 2029 bufptr = *buf; 2030 2031 (void) memcpy(bufptr, &change_state_data, 2032 sizeof (rdr_change_state_reply_t)); 2033 bufptr += sizeof (rdr_change_state_reply_t); 2034 2035 if ((params->errstring != NULL) && (*(params->errstring) != NULL)) { 2036 (void) memcpy(bufptr, *(params->errstring), 2037 var_msg_info.errstring_strlen); 2038 bufptr += var_msg_info.errstring_strlen; 2039 for (i = 0; i < var_msg_info.errstring_pad_sz; i++) { 2040 bufptr[i] = 0; 2041 } 2042 bufptr += var_msg_info.errstring_pad_sz; 2043 } 2044 2045 return (RDR_OK); 2046 } 2047 2048 2049 /* 2050 * unpack_change_state_reply: 2051 * 2052 * Handle unpacking a change state reply message. 2053 */ 2054 static int 2055 unpack_change_state_reply(change_state_params_t *params, const char *buf) 2056 { 2057 char *bufptr; 2058 rdr_change_state_reply_t change_state_data; 2059 2060 if ((params == NULL) || (buf == NULL)) { 2061 return (RDR_ERROR); 2062 } 2063 2064 bufptr = (char *)buf; 2065 (void) memcpy(&change_state_data, bufptr, 2066 sizeof (rdr_change_state_reply_t)); 2067 bufptr += sizeof (rdr_change_state_reply_t); 2068 2069 /* 2070 * handle getting the errstring 2071 */ 2072 params->errstring = (char **)malloc(sizeof (char *)); 2073 if (params->errstring == NULL) { 2074 return (RDR_MEM_ALLOC); 2075 } 2076 if (get_string_from_buf(params->errstring, 2077 change_state_data.errstring_size, bufptr)) { 2078 return (RDR_ERROR); 2079 } 2080 bufptr += change_state_data.errstring_size; 2081 2082 return (RDR_OK); 2083 } 2084 2085 2086 /* 2087 * pack_private_func_request: 2088 * 2089 * Handle packing a private function request message. 2090 */ 2091 static int 2092 pack_private_func_request(private_func_params_t *params, char **buf, 2093 int *buf_size) 2094 { 2095 int i; 2096 char *bufptr; 2097 rdr_private_func_t private_func_data; 2098 rdr_variable_message_info_t var_msg_info; 2099 2100 2101 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 2102 return (RDR_ERROR); 2103 } 2104 2105 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 2106 2107 /* 2108 * Set variable length fields and make a call to partially 2109 * pack it. 2110 */ 2111 if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) { 2112 cleanup_variable_ap_id_info(&var_msg_info); 2113 return (RDR_ERROR); 2114 } 2115 if (find_options_sizes(params->options, &var_msg_info)) { 2116 cleanup_variable_ap_id_info(&var_msg_info); 2117 return (RDR_ERROR); 2118 } 2119 if (find_function_sizes(params->function, &var_msg_info)) { 2120 cleanup_variable_ap_id_info(&var_msg_info); 2121 return (RDR_ERROR); 2122 } 2123 2124 /* 2125 * Collect size info specific to the private_func request 2126 * message and allocate a buffer 2127 */ 2128 *buf_size = sizeof (rdr_private_func_t); 2129 *buf_size += var_msg_info.ap_id_int_size; 2130 *buf_size += var_msg_info.ap_id_char_size; 2131 *buf_size += var_msg_info.options_strlen; 2132 *buf_size += var_msg_info.options_pad_sz; 2133 *buf_size += var_msg_info.function_strlen; 2134 *buf_size += var_msg_info.function_pad_sz; 2135 2136 *buf = (char *)malloc(*buf_size); 2137 if (*buf == NULL) { 2138 cleanup_variable_ap_id_info(&var_msg_info); 2139 return (RDR_MEM_ALLOC); 2140 } 2141 2142 /* 2143 * Set fixed address labels by name 2144 */ 2145 private_func_data.num_ap_ids = params->num_ap_ids; 2146 private_func_data.ap_id_char_size = var_msg_info.ap_id_char_size; 2147 private_func_data.options_size = var_msg_info.options_strlen + 2148 var_msg_info.options_pad_sz; 2149 private_func_data.function_size = var_msg_info.function_strlen + 2150 var_msg_info.function_pad_sz; 2151 2152 if (params->confp != NULL) { 2153 private_func_data.confirm_callback_id = 2154 (unsigned long)params->confp->confirm; 2155 private_func_data.confirm_appdata_ptr = 2156 (unsigned long)params->confp->appdata_ptr; 2157 } else { 2158 private_func_data.confirm_callback_id = 0; 2159 private_func_data.confirm_appdata_ptr = 0; 2160 } 2161 if (params->msgp != NULL) { 2162 private_func_data.msg_callback_id = 2163 (unsigned long)params->msgp->message_routine; 2164 private_func_data.msg_appdata_ptr = 2165 (unsigned long)params->msgp->appdata_ptr; 2166 } else { 2167 private_func_data.msg_callback_id = 0; 2168 private_func_data.msg_appdata_ptr = 0; 2169 } 2170 2171 private_func_data.flags = params->flags; 2172 2173 if (params->errstring != NULL) { 2174 private_func_data.error_msg_ctl = RDR_GENERATE_ERR_MSGS; 2175 } else { 2176 private_func_data.error_msg_ctl = RDR_DONT_GENERATE_ERR_MSGS; 2177 } 2178 2179 /* 2180 * Set variable information using memcpy 2181 */ 2182 bufptr = *buf; 2183 2184 (void) memcpy(bufptr, &private_func_data, sizeof (rdr_private_func_t)); 2185 bufptr += sizeof (rdr_private_func_t); 2186 2187 if (var_msg_info.ap_id_sizes != NULL) { 2188 (void) memcpy(bufptr, var_msg_info.ap_id_sizes, 2189 var_msg_info.ap_id_int_size); 2190 bufptr += var_msg_info.ap_id_int_size; 2191 } 2192 2193 if (var_msg_info.ap_id_chars != NULL) { 2194 (void) memcpy(bufptr, var_msg_info.ap_id_chars, 2195 var_msg_info.ap_id_char_size); 2196 bufptr += var_msg_info.ap_id_char_size; 2197 } 2198 2199 if (params->options != NULL) { 2200 (void) memcpy(bufptr, params->options, 2201 var_msg_info.options_strlen); 2202 bufptr += var_msg_info.options_strlen; 2203 for (i = 0; i < var_msg_info.options_pad_sz; i++) { 2204 bufptr[i] = 0; 2205 } 2206 bufptr += var_msg_info.options_pad_sz; 2207 } 2208 2209 if (params->function != NULL) { 2210 (void) memcpy(bufptr, params->function, 2211 var_msg_info.function_strlen); 2212 bufptr += var_msg_info.function_strlen; 2213 for (i = 0; i < var_msg_info.function_pad_sz; i++) { 2214 bufptr[i] = 0; 2215 } 2216 bufptr += var_msg_info.function_pad_sz; 2217 } 2218 2219 cleanup_variable_ap_id_info(&var_msg_info); 2220 2221 return (RDR_OK); 2222 } 2223 2224 2225 /* 2226 * unpack_private_func_request: 2227 * 2228 * Handle unpacking a private function request message. 2229 */ 2230 static int 2231 unpack_private_func_request(private_func_params_t *params, const char *buf) 2232 { 2233 char *bufptr; 2234 rdr_variable_message_info_t var_msg_info; 2235 rdr_private_func_t private_func_data; 2236 2237 2238 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 2239 2240 if ((params == NULL) || (buf == NULL)) { 2241 return (RDR_ERROR); 2242 } 2243 2244 bufptr = (char *)buf; 2245 (void) memcpy(&private_func_data, bufptr, sizeof (rdr_private_func_t)); 2246 bufptr += sizeof (rdr_private_func_t); 2247 2248 /* 2249 * handle getting the ap_ids 2250 */ 2251 var_msg_info.ap_id_char_size = private_func_data.ap_id_char_size; 2252 if (get_ap_ids_from_buf((char ***)&(params->ap_ids), 2253 private_func_data.num_ap_ids, &var_msg_info, bufptr)) { 2254 return (RDR_ERROR); 2255 } 2256 bufptr += var_msg_info.ap_id_int_size; 2257 bufptr += var_msg_info.ap_id_char_size; 2258 2259 /* 2260 * handle getting the options and function 2261 */ 2262 if (get_string_from_buf(&(params->options), 2263 private_func_data.options_size, bufptr)) { 2264 return (RDR_ERROR); 2265 } 2266 bufptr += private_func_data.options_size; 2267 2268 if (get_string_from_buf(&(params->function), 2269 private_func_data.function_size, bufptr)) { 2270 return (RDR_ERROR); 2271 } 2272 bufptr += private_func_data.function_size; 2273 2274 /* 2275 * Set fixed address labels by name 2276 */ 2277 params->num_ap_ids = private_func_data.num_ap_ids; 2278 2279 params->confp = (struct cfga_confirm *) 2280 malloc(sizeof (struct cfga_confirm)); 2281 if (params->confp == NULL) { 2282 return (RDR_MEM_ALLOC); 2283 } 2284 2285 /* set params->confp->confirm using memcpy */ 2286 (void) memcpy((void*)params->confp, 2287 &(private_func_data.confirm_callback_id), sizeof (unsigned long)); 2288 params->confp->appdata_ptr = 2289 (void*)private_func_data.confirm_appdata_ptr; 2290 2291 params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg)); 2292 if (params->msgp == NULL) { 2293 return (RDR_MEM_ALLOC); 2294 } 2295 2296 /* set params->msgp->message_routine using memcpy */ 2297 (void) memcpy((void*)params->msgp, 2298 &(private_func_data.msg_callback_id), sizeof (unsigned long)); 2299 params->msgp->appdata_ptr = 2300 (void*)private_func_data.msg_appdata_ptr; 2301 2302 if (private_func_data.error_msg_ctl == RDR_GENERATE_ERR_MSGS) { 2303 params->errstring = (char **)malloc(sizeof (char *)); 2304 if (params->errstring == NULL) { 2305 return (RDR_MEM_ALLOC); 2306 } 2307 *(params->errstring) = NULL; 2308 } else { /* error_msg_ctl == RDR_DONT_GENERATE_ERR_MSGS */ 2309 params->errstring = NULL; 2310 } 2311 params->flags = private_func_data.flags; 2312 2313 return (RDR_OK); 2314 } 2315 2316 2317 /* 2318 * pack_private_func_reply: 2319 * 2320 * Handle packing a private function reply message. 2321 */ 2322 static int 2323 pack_private_func_reply(private_func_params_t *params, char **buf, 2324 int *buf_size) 2325 { 2326 int i; 2327 char *bufptr; 2328 rdr_private_func_reply_t private_func_data; 2329 rdr_variable_message_info_t var_msg_info; 2330 2331 2332 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 2333 2334 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 2335 return (RDR_ERROR); 2336 } 2337 2338 /* 2339 * Set variable length fields (size info) 2340 */ 2341 if (find_errstring_sizes(params->errstring, &var_msg_info)) { 2342 return (RDR_ERROR); 2343 } 2344 2345 /* 2346 * Collect size info specific to the private_func reply 2347 * message and allocate a buffer 2348 */ 2349 *buf_size = sizeof (rdr_private_func_reply_t); 2350 *buf_size += var_msg_info.errstring_strlen; 2351 *buf_size += var_msg_info.errstring_pad_sz; 2352 2353 *buf = (char *)malloc(*buf_size); 2354 if (*buf == NULL) { 2355 return (RDR_MEM_ALLOC); 2356 } 2357 2358 /* 2359 * Set fixed address labels by name 2360 */ 2361 private_func_data.errstring_size = var_msg_info.errstring_strlen + 2362 var_msg_info.errstring_pad_sz; 2363 2364 /* 2365 * Set variable information using memcpy 2366 */ 2367 bufptr = *buf; 2368 2369 (void) memcpy(bufptr, &private_func_data, 2370 sizeof (rdr_private_func_reply_t)); 2371 bufptr += sizeof (rdr_private_func_reply_t); 2372 if ((params->errstring != NULL) && (*(params->errstring) != NULL)) { 2373 (void) memcpy(bufptr, *(params->errstring), 2374 var_msg_info.errstring_strlen); 2375 bufptr += var_msg_info.errstring_strlen; 2376 for (i = 0; i < var_msg_info.errstring_pad_sz; i++) { 2377 bufptr[i] = 0; 2378 } 2379 bufptr += var_msg_info.errstring_pad_sz; 2380 } 2381 2382 return (RDR_OK); 2383 } 2384 2385 2386 /* 2387 * unpack_private_func_reply: 2388 * 2389 * Handle unpacking a private function reply message. 2390 */ 2391 static int 2392 unpack_private_func_reply(private_func_params_t *params, const char *buf) 2393 { 2394 char *bufptr; 2395 rdr_private_func_reply_t private_func_data; 2396 2397 if ((params == NULL) || (buf == NULL)) { 2398 return (RDR_ERROR); 2399 } 2400 2401 bufptr = (char *)buf; 2402 (void) memcpy(&private_func_data, bufptr, 2403 sizeof (rdr_private_func_reply_t)); 2404 bufptr += sizeof (rdr_private_func_reply_t); 2405 2406 /* 2407 * handle getting the errstring 2408 */ 2409 params->errstring = (char **)malloc(sizeof (char *)); 2410 if (params->errstring == NULL) { 2411 return (RDR_MEM_ALLOC); 2412 } 2413 if (get_string_from_buf(params->errstring, 2414 private_func_data.errstring_size, bufptr)) { 2415 return (RDR_ERROR); 2416 } 2417 bufptr += private_func_data.errstring_size; 2418 2419 return (RDR_OK); 2420 } 2421 2422 2423 /* 2424 * pack_test_request: 2425 * 2426 * Handle packing a test request message. 2427 */ 2428 static int 2429 pack_test_request(test_params_t *params, char **buf, int *buf_size) 2430 { 2431 int i; 2432 char *bufptr; 2433 rdr_test_t test_data; 2434 rdr_variable_message_info_t var_msg_info; 2435 2436 2437 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 2438 return (RDR_ERROR); 2439 } 2440 2441 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 2442 2443 /* 2444 * Set variable length fields and make a call to partially 2445 * pack it. 2446 */ 2447 if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) { 2448 cleanup_variable_ap_id_info(&var_msg_info); 2449 return (RDR_ERROR); 2450 } 2451 if (find_options_sizes(params->options, &var_msg_info)) { 2452 cleanup_variable_ap_id_info(&var_msg_info); 2453 return (RDR_ERROR); 2454 } 2455 2456 /* 2457 * Collect size info specific to the test request 2458 * message and allocate a buffer 2459 */ 2460 *buf_size = sizeof (rdr_test_t); 2461 *buf_size += var_msg_info.ap_id_int_size; 2462 *buf_size += var_msg_info.ap_id_char_size; 2463 *buf_size += var_msg_info.options_strlen; 2464 *buf_size += var_msg_info.options_pad_sz; 2465 2466 *buf = (char *)malloc(*buf_size); 2467 if (*buf == NULL) { 2468 cleanup_variable_ap_id_info(&var_msg_info); 2469 return (RDR_MEM_ALLOC); 2470 } 2471 2472 /* 2473 * Set fixed address labels by name 2474 */ 2475 test_data.num_ap_ids = params->num_ap_ids; 2476 test_data.ap_id_char_size = var_msg_info.ap_id_char_size; 2477 test_data.options_size = var_msg_info.options_strlen + 2478 var_msg_info.options_pad_sz; 2479 2480 if (params->msgp != NULL) { 2481 test_data.msg_callback_id = 2482 (unsigned long)params->msgp->message_routine; 2483 test_data.msg_appdata_ptr = 2484 (unsigned long)params->msgp->appdata_ptr; 2485 } else { 2486 test_data.msg_callback_id = 0; 2487 test_data.msg_appdata_ptr = 0; 2488 } 2489 2490 test_data.flags = params->flags; 2491 2492 if (params->errstring != NULL) { 2493 test_data.error_msg_ctl = RDR_GENERATE_ERR_MSGS; 2494 } else { 2495 test_data.error_msg_ctl = RDR_DONT_GENERATE_ERR_MSGS; 2496 } 2497 2498 /* 2499 * Set variable information using memcpy 2500 */ 2501 bufptr = *buf; 2502 2503 (void) memcpy(bufptr, &test_data, sizeof (rdr_test_t)); 2504 bufptr += sizeof (rdr_test_t); 2505 2506 if (var_msg_info.ap_id_sizes != NULL) { 2507 (void) memcpy(bufptr, var_msg_info.ap_id_sizes, 2508 var_msg_info.ap_id_int_size); 2509 bufptr += var_msg_info.ap_id_int_size; 2510 } 2511 2512 if (var_msg_info.ap_id_chars != NULL) { 2513 (void) memcpy(bufptr, var_msg_info.ap_id_chars, 2514 var_msg_info.ap_id_char_size); 2515 bufptr += var_msg_info.ap_id_char_size; 2516 } 2517 2518 if (params->options != NULL) { 2519 (void) memcpy(bufptr, params->options, 2520 var_msg_info.options_strlen); 2521 bufptr += var_msg_info.options_strlen; 2522 for (i = 0; i < var_msg_info.options_pad_sz; i++) { 2523 bufptr[i] = 0; 2524 } 2525 bufptr += var_msg_info.options_pad_sz; 2526 } 2527 2528 cleanup_variable_ap_id_info(&var_msg_info); 2529 2530 return (RDR_OK); 2531 } 2532 2533 2534 /* 2535 * unpack_test_request: 2536 * 2537 * Handle unpacking a test request message. 2538 */ 2539 static int 2540 unpack_test_request(test_params_t *params, const char *buf) 2541 { 2542 char *bufptr; 2543 rdr_variable_message_info_t var_msg_info; 2544 rdr_test_t test_data; 2545 2546 2547 if ((params == NULL) || (buf == NULL)) { 2548 return (RDR_ERROR); 2549 } 2550 2551 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 2552 2553 bufptr = (char *)buf; 2554 (void) memcpy(&test_data, bufptr, sizeof (rdr_test_t)); 2555 bufptr += sizeof (rdr_test_t); 2556 2557 /* 2558 * handle getting the ap_ids 2559 */ 2560 var_msg_info.ap_id_char_size = test_data.ap_id_char_size; 2561 if (get_ap_ids_from_buf((char ***)&(params->ap_ids), 2562 test_data.num_ap_ids, &var_msg_info, bufptr)) { 2563 return (RDR_ERROR); 2564 } 2565 bufptr += var_msg_info.ap_id_int_size; 2566 bufptr += var_msg_info.ap_id_char_size; 2567 2568 /* 2569 * handle getting the options 2570 */ 2571 if (get_string_from_buf(&(params->options), 2572 test_data.options_size, bufptr)) { 2573 return (RDR_ERROR); 2574 } 2575 bufptr += test_data.options_size; 2576 2577 /* 2578 * Set fixed address labels by name 2579 */ 2580 params->num_ap_ids = test_data.num_ap_ids; 2581 2582 params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg)); 2583 if (params->msgp == NULL) { 2584 return (RDR_MEM_ALLOC); 2585 } 2586 2587 /* set params->msgp->message_routine using memcpy */ 2588 (void) memcpy((void*)params->msgp, 2589 &(test_data.msg_callback_id), sizeof (unsigned long)); 2590 params->msgp->appdata_ptr = 2591 (void*)test_data.msg_appdata_ptr; 2592 2593 if (test_data.error_msg_ctl == RDR_GENERATE_ERR_MSGS) { 2594 params->errstring = (char **)malloc(sizeof (char *)); 2595 if (params->errstring == NULL) { 2596 return (RDR_MEM_ALLOC); 2597 } 2598 *(params->errstring) = NULL; 2599 } else { /* error_msg_ctl == RDR_DONT_GENERATE_ERR_MSGS */ 2600 params->errstring = NULL; 2601 } 2602 params->flags = test_data.flags; 2603 2604 return (RDR_OK); 2605 } 2606 2607 2608 /* 2609 * pack_test_reply: 2610 * 2611 * Handle packing a test reply message. 2612 */ 2613 static int 2614 pack_test_reply(test_params_t *params, char **buf, int *buf_size) 2615 { 2616 int i; 2617 char *bufptr; 2618 rdr_test_reply_t test_data; 2619 rdr_variable_message_info_t var_msg_info; 2620 2621 2622 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 2623 return (RDR_ERROR); 2624 } 2625 2626 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 2627 2628 /* 2629 * Set variable length fields (size info) 2630 */ 2631 if (find_errstring_sizes(params->errstring, &var_msg_info)) { 2632 return (RDR_ERROR); 2633 } 2634 2635 /* 2636 * Collect size info specific to the test reply 2637 * message and allocate a buffer 2638 */ 2639 *buf_size = sizeof (rdr_test_reply_t); 2640 *buf_size += var_msg_info.errstring_strlen; 2641 *buf_size += var_msg_info.errstring_pad_sz; 2642 2643 *buf = (char *)malloc(*buf_size); 2644 if (*buf == NULL) { 2645 return (RDR_MEM_ALLOC); 2646 } 2647 2648 /* 2649 * Set fixed address labels by name 2650 */ 2651 test_data.errstring_size = var_msg_info.errstring_strlen + 2652 var_msg_info.errstring_pad_sz; 2653 2654 /* 2655 * Set variable information using memcpy 2656 */ 2657 bufptr = *buf; 2658 2659 (void) memcpy(bufptr, &test_data, sizeof (rdr_test_reply_t)); 2660 bufptr += sizeof (rdr_test_reply_t); 2661 if ((params->errstring != NULL) && (*(params->errstring) != NULL)) { 2662 (void) memcpy(bufptr, *(params->errstring), 2663 var_msg_info.errstring_strlen); 2664 bufptr += var_msg_info.errstring_strlen; 2665 for (i = 0; i < var_msg_info.errstring_pad_sz; i++) { 2666 bufptr[i] = 0; 2667 } 2668 bufptr += var_msg_info.errstring_pad_sz; 2669 } 2670 2671 return (RDR_OK); 2672 } 2673 2674 2675 /* 2676 * unpack_test_reply: 2677 * 2678 * Handle unpacking a test reply message. 2679 */ 2680 static int 2681 unpack_test_reply(test_params_t *params, const char *buf) 2682 { 2683 char *bufptr; 2684 rdr_test_reply_t test_data; 2685 2686 2687 if ((params == NULL) || (buf == NULL)) { 2688 return (RDR_ERROR); 2689 } 2690 2691 bufptr = (char *)buf; 2692 (void) memcpy(&test_data, bufptr, sizeof (rdr_test_reply_t)); 2693 bufptr += sizeof (rdr_test_reply_t); 2694 2695 /* 2696 * handle getting the errstring 2697 */ 2698 params->errstring = (char **)malloc(sizeof (char *)); 2699 if (params->errstring == NULL) { 2700 return (RDR_MEM_ALLOC); 2701 } 2702 if (get_string_from_buf(params->errstring, 2703 test_data.errstring_size, bufptr)) { 2704 return (RDR_ERROR); 2705 } 2706 bufptr += test_data.errstring_size; 2707 2708 return (RDR_OK); 2709 } 2710 2711 2712 /* 2713 * pack_list_ext_request: 2714 * 2715 * Handle packing a list request message. 2716 */ 2717 static int 2718 pack_list_ext_request(list_ext_params_t *params, char **buf, int *buf_size) 2719 { 2720 int i; 2721 char *bufptr; 2722 rdr_list_ext_t list_ext_data; 2723 rdr_variable_message_info_t var_msg_info; 2724 2725 2726 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 2727 return (RDR_ERROR); 2728 } 2729 2730 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 2731 2732 /* 2733 * Set variable length fields and make a call to partially 2734 * pack it. 2735 */ 2736 if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) { 2737 cleanup_variable_ap_id_info(&var_msg_info); 2738 return (RDR_ERROR); 2739 } 2740 if (find_options_sizes(params->options, &var_msg_info)) { 2741 cleanup_variable_ap_id_info(&var_msg_info); 2742 return (RDR_ERROR); 2743 } 2744 if (find_listopts_sizes(params->listopts, &var_msg_info)) { 2745 cleanup_variable_ap_id_info(&var_msg_info); 2746 return (RDR_ERROR); 2747 } 2748 2749 2750 /* 2751 * Collect size info specific to the list_ext request 2752 * message and allocate a buffer 2753 */ 2754 *buf_size = sizeof (rdr_list_ext_t); 2755 *buf_size += var_msg_info.ap_id_int_size; 2756 *buf_size += var_msg_info.ap_id_char_size; 2757 *buf_size += var_msg_info.options_strlen; 2758 *buf_size += var_msg_info.options_pad_sz; 2759 *buf_size += var_msg_info.listopts_strlen; 2760 *buf_size += var_msg_info.listopts_pad_sz; 2761 2762 *buf = (char *)malloc(*buf_size); 2763 if (*buf == NULL) { 2764 cleanup_variable_ap_id_info(&var_msg_info); 2765 return (RDR_MEM_ALLOC); 2766 } 2767 2768 /* 2769 * Set fixed address labels by name 2770 */ 2771 list_ext_data.num_ap_ids = params->num_ap_ids; 2772 list_ext_data.ap_id_char_size = var_msg_info.ap_id_char_size; 2773 list_ext_data.options_size = var_msg_info.options_strlen + 2774 var_msg_info.options_pad_sz; 2775 list_ext_data.listopts_size = var_msg_info.listopts_strlen + 2776 var_msg_info.listopts_pad_sz; 2777 if (params->errstring != NULL) { 2778 list_ext_data.error_msg_ctl = RDR_GENERATE_ERR_MSGS; 2779 } else { 2780 list_ext_data.error_msg_ctl = RDR_DONT_GENERATE_ERR_MSGS; 2781 } 2782 if ((params->num_ap_ids != 0) || (params->ap_ids != NULL)) { 2783 list_ext_data.list_msg_ctl = RDR_LIST_ONLY_PARAM_APS; 2784 } else { 2785 list_ext_data.list_msg_ctl = RDR_LIST_ALL_APS; 2786 } 2787 list_ext_data.flags = params->flags; 2788 list_ext_data.permissions = params->permissions; 2789 2790 /* 2791 * Set variable information using memcpy 2792 */ 2793 bufptr = *buf; 2794 2795 (void) memcpy(bufptr, &list_ext_data, sizeof (rdr_list_ext_t)); 2796 bufptr += sizeof (rdr_list_ext_t); 2797 2798 if (var_msg_info.ap_id_sizes != NULL) { 2799 (void) memcpy(bufptr, var_msg_info.ap_id_sizes, 2800 var_msg_info.ap_id_int_size); 2801 bufptr += var_msg_info.ap_id_int_size; 2802 } 2803 2804 if (var_msg_info.ap_id_chars != NULL) { 2805 (void) memcpy(bufptr, var_msg_info.ap_id_chars, 2806 var_msg_info.ap_id_char_size); 2807 bufptr += var_msg_info.ap_id_char_size; 2808 } 2809 2810 if (params->options != NULL) { 2811 (void) memcpy(bufptr, params->options, 2812 var_msg_info.options_strlen); 2813 bufptr += var_msg_info.options_strlen; 2814 for (i = 0; i < var_msg_info.options_pad_sz; i++) { 2815 bufptr[i] = 0; 2816 } 2817 bufptr += var_msg_info.options_pad_sz; 2818 } 2819 2820 if (params->listopts != NULL) { 2821 (void) memcpy(bufptr, params->listopts, 2822 var_msg_info.listopts_strlen); 2823 bufptr += var_msg_info.listopts_strlen; 2824 for (i = 0; i < var_msg_info.listopts_pad_sz; i++) { 2825 bufptr[i] = 0; 2826 } 2827 bufptr += var_msg_info.listopts_pad_sz; 2828 } 2829 2830 cleanup_variable_ap_id_info(&var_msg_info); 2831 2832 return (RDR_OK); 2833 } 2834 2835 2836 /* 2837 * unpack_list_ext_request: 2838 * 2839 * Handle unpacking a list request message. 2840 */ 2841 static int 2842 unpack_list_ext_request(list_ext_params_t *params, const char *buf) 2843 { 2844 char *bufptr; 2845 rdr_variable_message_info_t var_msg_info; 2846 rdr_list_ext_t list_ext_data; 2847 2848 2849 if ((params == NULL) || (buf == NULL)) { 2850 return (RDR_ERROR); 2851 } 2852 2853 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 2854 2855 bufptr = (char *)buf; 2856 (void) memcpy(&list_ext_data, bufptr, sizeof (rdr_list_ext_t)); 2857 bufptr += sizeof (rdr_list_ext_t); 2858 2859 /* 2860 * handle getting the ap_ids 2861 */ 2862 var_msg_info.ap_id_char_size = list_ext_data.ap_id_char_size; 2863 if (get_ap_ids_from_buf(&(params->ap_ids), list_ext_data.num_ap_ids, 2864 &var_msg_info, bufptr)) { 2865 return (RDR_ERROR); 2866 } 2867 bufptr += var_msg_info.ap_id_int_size; 2868 bufptr += var_msg_info.ap_id_char_size; 2869 2870 /* 2871 * handle getting the options 2872 */ 2873 if (get_string_from_buf(&(params->options), 2874 list_ext_data.options_size, bufptr)) { 2875 return (RDR_ERROR); 2876 } 2877 bufptr += list_ext_data.options_size; 2878 2879 /* 2880 * handle getting the listopts 2881 */ 2882 if (get_string_from_buf(&(params->listopts), 2883 list_ext_data.listopts_size, bufptr)) { 2884 return (RDR_ERROR); 2885 } 2886 bufptr += list_ext_data.listopts_size; 2887 2888 /* 2889 * Set fixed address labels by name 2890 */ 2891 params->num_ap_ids = list_ext_data.num_ap_ids; 2892 2893 params->ap_id_list = (rdr_list_t **)malloc(sizeof (rdr_list_t *)); 2894 if (params->ap_id_list == NULL) { 2895 return (RDR_MEM_ALLOC); 2896 } 2897 *(params->ap_id_list) = NULL; 2898 2899 params->nlist = (int *)malloc(sizeof (int)); 2900 if (params->nlist == NULL) { 2901 return (RDR_MEM_ALLOC); 2902 } 2903 if (list_ext_data.error_msg_ctl == RDR_GENERATE_ERR_MSGS) { 2904 params->errstring = (char **)malloc(sizeof (char *)); 2905 if (params->errstring == NULL) { 2906 return (RDR_MEM_ALLOC); 2907 } 2908 *(params->errstring) = NULL; 2909 } else { /* error_msg_ctl == RDR_DONT_GENERATE_ERR_MSGS */ 2910 params->errstring = NULL; 2911 } 2912 params->flags = list_ext_data.flags; 2913 params->permissions = list_ext_data.permissions; 2914 2915 return (RDR_OK); 2916 } 2917 2918 2919 /* 2920 * pack_list_ext_reply: 2921 * 2922 * Handle packing a list reply message. 2923 */ 2924 static int 2925 pack_list_ext_reply(list_ext_params_t *params, char **buf, int *buf_size) 2926 { 2927 int i; 2928 char *bufptr; 2929 rdr_list_ext_reply_t list_ext_data; 2930 rdr_variable_message_info_t var_msg_info; 2931 int list_data_size; 2932 2933 2934 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 2935 2936 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 2937 return (RDR_ERROR); 2938 } 2939 2940 /* 2941 * Set variable length fields (size info) 2942 */ 2943 if (find_errstring_sizes(params->errstring, &var_msg_info)) { 2944 return (RDR_ERROR); 2945 } 2946 2947 if (params->nlist == NULL) { 2948 list_data_size = 0; 2949 } else { 2950 list_data_size = *(params->nlist) * sizeof (rdr_list_t); 2951 } 2952 2953 /* 2954 * Collect size info specific to the list_ext reply 2955 * message and allocate a buffer 2956 */ 2957 *buf_size = sizeof (rdr_list_ext_reply_t); 2958 *buf_size += list_data_size; 2959 *buf_size += var_msg_info.errstring_strlen; 2960 *buf_size += var_msg_info.errstring_pad_sz; 2961 2962 *buf = (char *)malloc(*buf_size); 2963 if (*buf == NULL) { 2964 return (RDR_MEM_ALLOC); 2965 } 2966 2967 /* 2968 * Set fixed address labels by name 2969 */ 2970 list_ext_data.num_ap_ids = (params->nlist) ? *(params->nlist) : 0; 2971 list_ext_data.errstring_size = var_msg_info.errstring_strlen + 2972 var_msg_info.errstring_pad_sz; 2973 2974 /* 2975 * Set variable information using memcpy 2976 */ 2977 bufptr = *buf; 2978 2979 (void) memcpy(bufptr, &list_ext_data, sizeof (rdr_list_ext_reply_t)); 2980 bufptr += sizeof (rdr_list_ext_reply_t); 2981 2982 if ((params->ap_id_list != NULL) && (*(params->ap_id_list) != NULL)) { 2983 (void) memcpy(bufptr, *(params->ap_id_list), list_data_size); 2984 bufptr += list_data_size; 2985 } else if (list_data_size) { 2986 /* 2987 * Something is out of sync. We were expecting 2988 * some data to copy, but instead we found a 2989 * NULL pointer. 2990 */ 2991 (void) free((void *)*buf); 2992 *buf = NULL; 2993 return (RDR_ERROR); 2994 } 2995 2996 if ((params->errstring != NULL) && (*(params->errstring) != NULL)) { 2997 (void) memcpy(bufptr, *(params->errstring), 2998 var_msg_info.errstring_strlen); 2999 bufptr += var_msg_info.errstring_strlen; 3000 for (i = 0; i < var_msg_info.errstring_pad_sz; i++) { 3001 bufptr[i] = 0; 3002 } 3003 bufptr += var_msg_info.errstring_pad_sz; 3004 } 3005 3006 return (RDR_OK); 3007 } 3008 3009 3010 /* 3011 * unpack_list_ext_reply: 3012 * 3013 * Handle unpacking a list reply message. 3014 */ 3015 static int 3016 unpack_list_ext_reply(list_ext_params_t *params, const char *buf) 3017 { 3018 int list_data_size; 3019 char *bufptr; 3020 rdr_list_ext_reply_t list_ext_data; 3021 3022 3023 if ((params == NULL) || (buf == NULL)) { 3024 return (RDR_ERROR); 3025 } 3026 3027 bufptr = (char *)buf; 3028 (void) memcpy(&list_ext_data, bufptr, sizeof (rdr_list_ext_reply_t)); 3029 bufptr += sizeof (rdr_list_ext_reply_t); 3030 3031 /* 3032 * handle getting the ap_id rcfga_list_data_t's. 3033 */ 3034 if (list_ext_data.num_ap_ids > 0) { 3035 params->nlist = (int *)malloc(sizeof (int)); 3036 if (params->nlist == NULL) { 3037 return (RDR_MEM_ALLOC); 3038 } 3039 *(params->nlist) = list_ext_data.num_ap_ids; 3040 params->ap_id_list = (rdr_list_t **) 3041 malloc(sizeof (rdr_list_t *)); 3042 if (params->ap_id_list == NULL) { 3043 return (RDR_MEM_ALLOC); 3044 } 3045 *(params->ap_id_list) = (rdr_list_t *) 3046 malloc(sizeof (rdr_list_t) * list_ext_data.num_ap_ids); 3047 if (*(params->ap_id_list) == NULL) { 3048 return (RDR_MEM_ALLOC); 3049 } 3050 list_data_size = list_ext_data.num_ap_ids * sizeof (rdr_list_t); 3051 (void) memcpy(*(params->ap_id_list), bufptr, list_data_size); 3052 bufptr += list_data_size; 3053 } 3054 3055 /* 3056 * handle getting the errstring 3057 */ 3058 params->errstring = (char **)malloc(sizeof (char *)); 3059 if (params->errstring == NULL) { 3060 return (RDR_MEM_ALLOC); 3061 } 3062 if (get_string_from_buf(params->errstring, 3063 list_ext_data.errstring_size, bufptr)) { 3064 return (RDR_ERROR); 3065 } 3066 bufptr += list_ext_data.errstring_size; 3067 3068 return (RDR_OK); 3069 } 3070 3071 3072 /* 3073 * pack_help_request: 3074 * 3075 * Handle packing a help request message. 3076 */ 3077 static int 3078 pack_help_request(help_params_t *params, char **buf, int *buf_size) 3079 { 3080 int i; 3081 char *bufptr; 3082 rdr_help_t help_data; 3083 rdr_variable_message_info_t var_msg_info; 3084 3085 3086 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 3087 3088 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 3089 return (RDR_ERROR); 3090 } 3091 3092 /* 3093 * Set variable length fields and make a call to partially 3094 * pack it. 3095 */ 3096 if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) { 3097 cleanup_variable_ap_id_info(&var_msg_info); 3098 return (RDR_ERROR); 3099 } 3100 if (find_options_sizes(params->options, &var_msg_info)) { 3101 cleanup_variable_ap_id_info(&var_msg_info); 3102 return (RDR_ERROR); 3103 } 3104 3105 /* 3106 * Collect size info specific to the help request message and 3107 * and allocate a buffer 3108 */ 3109 *buf_size = sizeof (rdr_help_t); 3110 *buf_size += var_msg_info.ap_id_int_size; 3111 *buf_size += var_msg_info.ap_id_char_size; 3112 *buf_size += var_msg_info.options_strlen; 3113 *buf_size += var_msg_info.options_pad_sz; 3114 3115 *buf = (char *)malloc(*buf_size); 3116 if (*buf == NULL) { 3117 cleanup_variable_ap_id_info(&var_msg_info); 3118 return (RDR_MEM_ALLOC); 3119 } 3120 3121 /* 3122 * Set fixed address labels by name 3123 */ 3124 help_data.num_ap_ids = params->num_ap_ids; 3125 help_data.ap_id_char_size = var_msg_info.ap_id_char_size; 3126 help_data.options_size = var_msg_info.options_strlen + 3127 var_msg_info.options_pad_sz; 3128 3129 if (params->msgp != NULL) { 3130 help_data.msg_callback_id = 3131 (unsigned long)params->msgp->message_routine; 3132 help_data.msg_appdata_ptr = 3133 (unsigned long)params->msgp->appdata_ptr; 3134 } else { 3135 help_data.msg_callback_id = 0; 3136 help_data.msg_appdata_ptr = 0; 3137 } 3138 3139 help_data.flags = params->flags; 3140 3141 /* 3142 * Set variable information using memcpy 3143 */ 3144 bufptr = *buf; 3145 3146 (void) memcpy(bufptr, &help_data, sizeof (rdr_help_t)); 3147 bufptr += sizeof (rdr_help_t); 3148 3149 if (var_msg_info.ap_id_sizes != NULL) { 3150 (void) memcpy(bufptr, var_msg_info.ap_id_sizes, 3151 var_msg_info.ap_id_int_size); 3152 bufptr += var_msg_info.ap_id_int_size; 3153 } 3154 3155 if (var_msg_info.ap_id_chars != NULL) { 3156 (void) memcpy(bufptr, var_msg_info.ap_id_chars, 3157 var_msg_info.ap_id_char_size); 3158 bufptr += var_msg_info.ap_id_char_size; 3159 } 3160 3161 if (params->options != NULL) { 3162 (void) memcpy(bufptr, params->options, 3163 var_msg_info.options_strlen); 3164 bufptr += var_msg_info.options_strlen; 3165 for (i = 0; i < var_msg_info.options_pad_sz; i++) { 3166 bufptr[i] = 0; 3167 } 3168 bufptr += var_msg_info.options_pad_sz; 3169 } 3170 3171 cleanup_variable_ap_id_info(&var_msg_info); 3172 3173 return (RDR_OK); 3174 } 3175 3176 3177 /* 3178 * unpack_help_request: 3179 * 3180 * Handle unpacking a help request message. 3181 */ 3182 static int 3183 unpack_help_request(help_params_t *params, const char *buf) 3184 { 3185 char *bufptr; 3186 rdr_variable_message_info_t var_msg_info; 3187 rdr_help_t help_data; 3188 3189 3190 if ((params == NULL) || (buf == NULL)) { 3191 return (RDR_ERROR); 3192 } 3193 3194 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 3195 3196 bufptr = (char *)buf; 3197 (void) memcpy(&help_data, bufptr, sizeof (rdr_help_t)); 3198 bufptr += sizeof (rdr_help_t); 3199 3200 /* 3201 * handle getting the ap_ids 3202 */ 3203 var_msg_info.ap_id_char_size = help_data.ap_id_char_size; 3204 if (get_ap_ids_from_buf((char ***)&(params->ap_ids), 3205 help_data.num_ap_ids, &var_msg_info, bufptr)) { 3206 return (RDR_ERROR); 3207 } 3208 bufptr += var_msg_info.ap_id_int_size; 3209 bufptr += var_msg_info.ap_id_char_size; 3210 3211 /* 3212 * handle getting the options 3213 */ 3214 if (get_string_from_buf(&(params->options), 3215 help_data.options_size, bufptr)) { 3216 return (RDR_ERROR); 3217 } 3218 bufptr += help_data.options_size; 3219 3220 /* 3221 * Set fixed address labels by name 3222 */ 3223 params->num_ap_ids = help_data.num_ap_ids; 3224 3225 params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg)); 3226 if (params->msgp == NULL) { 3227 return (RDR_MEM_ALLOC); 3228 } 3229 3230 /* set params->msgp->message_routine using memcpy */ 3231 (void) memcpy((void*)params->msgp, &(help_data.msg_callback_id), 3232 sizeof (unsigned long)); 3233 3234 params->msgp->appdata_ptr = (void*)help_data.msg_appdata_ptr; 3235 params->flags = help_data.flags; 3236 3237 return (RDR_OK); 3238 } 3239 3240 3241 /* 3242 * pack_ap_id_cmp_request: 3243 * 3244 * Handle packing an attachment point comparison request message. 3245 */ 3246 static int 3247 pack_ap_id_cmp_request(ap_id_cmp_params_t *params, char **buf, int *buf_size) 3248 { 3249 int i; 3250 char *bufptr; 3251 rdr_ap_id_cmp_t ap_id_cmp_data; 3252 int ap_id1_strlen; 3253 int ap_id1_pad_sz; 3254 int ap_id2_strlen; 3255 int ap_id2_pad_sz; 3256 3257 3258 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 3259 return (RDR_ERROR); 3260 } 3261 3262 /* 3263 * Set variable length fields and make a call to partially 3264 * pack it. 3265 */ 3266 if (params->ap_log_id1 != NULL) { 3267 ap_id1_strlen = strlen(params->ap_log_id1) + 1; 3268 ap_id1_pad_sz = RDR_ALIGN_64_BIT - 3269 (ap_id1_strlen % RDR_ALIGN_64_BIT); 3270 } else { 3271 ap_id1_strlen = 0; 3272 ap_id1_pad_sz = 0; 3273 } 3274 3275 if (params->ap_log_id2 != NULL) { 3276 ap_id2_strlen = strlen(params->ap_log_id2) + 1; 3277 ap_id2_pad_sz = RDR_ALIGN_64_BIT - 3278 (ap_id2_strlen % RDR_ALIGN_64_BIT); 3279 } else { 3280 ap_id2_strlen = 0; 3281 ap_id2_pad_sz = 0; 3282 } 3283 3284 /* 3285 * Collect size info specific to the ap id compare request 3286 * message and allocate a buffer 3287 */ 3288 *buf_size = sizeof (rdr_ap_id_cmp_t); 3289 *buf_size += ap_id1_strlen; 3290 *buf_size += ap_id1_pad_sz; 3291 *buf_size += ap_id2_strlen; 3292 *buf_size += ap_id2_pad_sz; 3293 3294 *buf = (char *)malloc(*buf_size); 3295 if (*buf == NULL) { 3296 return (RDR_MEM_ALLOC); 3297 } 3298 3299 /* 3300 * Set fixed address labels by name 3301 */ 3302 ap_id_cmp_data.ap_id1_size = ap_id1_strlen + ap_id1_pad_sz; 3303 ap_id_cmp_data.ap_id2_size = ap_id2_strlen + ap_id2_pad_sz; 3304 3305 3306 /* 3307 * Set variable information using memcpy 3308 */ 3309 bufptr = *buf; 3310 3311 (void) memcpy(bufptr, &ap_id_cmp_data, sizeof (rdr_ap_id_cmp_t)); 3312 bufptr += sizeof (rdr_ap_id_cmp_t); 3313 3314 if (params->ap_log_id1 != NULL) { 3315 (void) memcpy(bufptr, params->ap_log_id1, ap_id1_strlen); 3316 bufptr += ap_id1_strlen; 3317 for (i = 0; i < ap_id1_pad_sz; i++) { 3318 bufptr[i] = 0; 3319 } 3320 bufptr += ap_id1_pad_sz; 3321 } 3322 3323 if (params->ap_log_id2 != NULL) { 3324 (void) memcpy(bufptr, params->ap_log_id2, ap_id2_strlen); 3325 bufptr += ap_id2_strlen; 3326 for (i = 0; i < ap_id2_pad_sz; i++) { 3327 bufptr[i] = 0; 3328 } 3329 bufptr += ap_id2_pad_sz; 3330 } 3331 3332 return (RDR_OK); 3333 } 3334 3335 3336 /* 3337 * unpack_ap_id_cmp_request: 3338 * 3339 * Handle unpacking an attachment point comparison request message. 3340 */ 3341 static int 3342 unpack_ap_id_cmp_request(ap_id_cmp_params_t *params, const char *buf) 3343 { 3344 char *bufptr; 3345 rdr_ap_id_cmp_t ap_id_cmp_data; 3346 3347 3348 if ((params == NULL) || (buf == NULL)) { 3349 return (RDR_ERROR); 3350 } 3351 3352 bufptr = (char *)buf; 3353 (void) memcpy(&ap_id_cmp_data, bufptr, sizeof (rdr_ap_id_cmp_t)); 3354 bufptr += sizeof (rdr_ap_id_cmp_t); 3355 3356 /* 3357 * handle getting the cmp ap ids 3358 */ 3359 if (get_string_from_buf(&(params->ap_log_id1), 3360 ap_id_cmp_data.ap_id1_size, bufptr)) { 3361 return (RDR_ERROR); 3362 } 3363 bufptr += ap_id_cmp_data.ap_id1_size; 3364 3365 if (get_string_from_buf(&(params->ap_log_id2), 3366 ap_id_cmp_data.ap_id2_size, bufptr)) { 3367 return (RDR_ERROR); 3368 } 3369 bufptr += ap_id_cmp_data.ap_id2_size; 3370 3371 return (RDR_OK); 3372 } 3373 3374 3375 /* 3376 * pack_abort_cmd_request: 3377 * 3378 * Handle packing an abort request message. 3379 */ 3380 static int 3381 pack_abort_cmd_request(abort_cmd_params_t *params, char **buf, int *buf_size) 3382 { 3383 rdr_abort_cmd_t abort_cmd_data; 3384 3385 3386 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 3387 return (RDR_ERROR); 3388 } 3389 3390 /* 3391 * Collect size info specific to the abort cmd request 3392 * message and allocate a buffer 3393 */ 3394 *buf_size = sizeof (rdr_abort_cmd_t); 3395 3396 *buf = (char *)malloc(*buf_size); 3397 if (*buf == NULL) { 3398 return (RDR_MEM_ALLOC); 3399 } 3400 3401 /* 3402 * Set fixed session identifier 3403 */ 3404 abort_cmd_data.session_id = params->session_id; 3405 3406 /* 3407 * Copy information using memcpy 3408 */ 3409 (void) memcpy(*buf, &abort_cmd_data, sizeof (rdr_abort_cmd_t)); 3410 3411 return (RDR_OK); 3412 } 3413 3414 3415 /* 3416 * unpack_abort_cmd_request: 3417 * 3418 * Handle unpacking an abort request message. 3419 */ 3420 static int 3421 unpack_abort_cmd_request(abort_cmd_params_t *params, const char *buf) 3422 { 3423 rdr_abort_cmd_t *abort_cmd_datap; 3424 3425 3426 if ((params == NULL) || (buf == NULL)) { 3427 return (RDR_ERROR); 3428 } 3429 3430 /* LINTED Pointer Cast Alignment Warning */ 3431 abort_cmd_datap = (rdr_abort_cmd_t *)buf; 3432 3433 /* 3434 * copy out the session information 3435 */ 3436 3437 params->session_id = abort_cmd_datap->session_id; 3438 3439 return (RDR_OK); 3440 } 3441 3442 3443 /* 3444 * pack_confirm_request: 3445 * 3446 * Handle packing a confirm callback request. 3447 */ 3448 static int 3449 pack_confirm_request(confirm_callback_params_t *params, char **buf, 3450 int *buf_size) 3451 { 3452 int i; 3453 char *bufptr; 3454 rdr_confirm_callback_t confirm_callback_data; 3455 int message_strlen; 3456 int message_pad_sz; 3457 3458 3459 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 3460 return (RDR_ERROR); 3461 } 3462 3463 /* 3464 * Set variable length fields and make a call to partially 3465 * pack it. 3466 */ 3467 if (params->message != NULL) { 3468 message_strlen = strlen(params->message) + 1; 3469 message_pad_sz = RDR_ALIGN_64_BIT - 3470 (message_strlen % RDR_ALIGN_64_BIT); 3471 } else { 3472 message_strlen = 0; 3473 message_pad_sz = 0; 3474 } 3475 3476 3477 /* 3478 * Collect size info specific to the confirm callback request 3479 * message and allocate a buffer 3480 */ 3481 *buf_size = sizeof (rdr_confirm_callback_t); 3482 *buf_size += message_strlen; 3483 *buf_size += message_pad_sz; 3484 3485 *buf = (char *)malloc(*buf_size); 3486 if (*buf == NULL) { 3487 return (RDR_MEM_ALLOC); 3488 } 3489 3490 /* 3491 * Set fixed address labels by name 3492 */ 3493 if (params->confp != NULL) { 3494 confirm_callback_data.confirm_callback_id = 3495 (unsigned long)params->confp->confirm; 3496 confirm_callback_data.appdata_ptr = 3497 (unsigned long)params->confp->appdata_ptr; 3498 } else { 3499 confirm_callback_data.confirm_callback_id = 0; 3500 confirm_callback_data.appdata_ptr = 0; 3501 } 3502 confirm_callback_data.message_size = message_strlen + message_pad_sz; 3503 3504 /* 3505 * Set variable information using memcpy 3506 */ 3507 bufptr = *buf; 3508 (void) memcpy(bufptr, &confirm_callback_data, 3509 sizeof (rdr_confirm_callback_t)); 3510 bufptr += sizeof (rdr_confirm_callback_t); 3511 3512 if (params->message != NULL) { 3513 (void) memcpy(bufptr, params->message, message_strlen); 3514 bufptr += message_strlen; 3515 for (i = 0; i < message_pad_sz; i++) { 3516 bufptr[i] = 0; 3517 } 3518 bufptr += message_pad_sz; 3519 } 3520 3521 return (RDR_OK); 3522 } 3523 3524 3525 /* 3526 * unpack_confirm_request: 3527 * 3528 * Handle unpacking a confirm callback request. 3529 */ 3530 static int 3531 unpack_confirm_request(confirm_callback_params_t *params, const char *buf) 3532 { 3533 char *bufptr; 3534 rdr_confirm_callback_t confirm_callback_data; 3535 3536 3537 if ((params == NULL) || (buf == NULL)) { 3538 return (RDR_ERROR); 3539 } 3540 3541 bufptr = (char *)buf; 3542 (void) memcpy(&confirm_callback_data, bufptr, 3543 sizeof (rdr_confirm_callback_t)); 3544 bufptr += sizeof (rdr_confirm_callback_t); 3545 3546 /* 3547 * handle getting the message text 3548 */ 3549 if (get_string_from_buf(&(params->message), 3550 confirm_callback_data.message_size, bufptr)) { 3551 return (RDR_ERROR); 3552 } 3553 bufptr += confirm_callback_data.message_size; 3554 3555 /* 3556 * Set fixed address labels by name 3557 */ 3558 params->confp = (struct cfga_confirm *) 3559 malloc(sizeof (struct cfga_confirm)); 3560 if (params->confp == NULL) { 3561 return (RDR_MEM_ALLOC); 3562 } 3563 3564 /* set params->confp->confirm using memcpy */ 3565 (void) memcpy((void*)params->confp, 3566 &(confirm_callback_data.confirm_callback_id), 3567 sizeof (unsigned long)); 3568 3569 params->confp->appdata_ptr = 3570 (void*)confirm_callback_data.appdata_ptr; 3571 3572 return (RDR_OK); 3573 } 3574 3575 3576 /* 3577 * pack_confirm_reply: 3578 * 3579 * Handle packing a confirm callback reply. 3580 */ 3581 static int 3582 pack_confirm_reply(confirm_callback_params_t *params, char **buf, int *buf_size) 3583 { 3584 char *bufptr; 3585 rdr_confirm_callback_reply_t confirm_callback_data; 3586 3587 3588 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 3589 return (RDR_ERROR); 3590 } 3591 3592 /* 3593 * Collect size info specific to the confirm callback reply 3594 * message and allocate a buffer 3595 */ 3596 *buf_size = sizeof (confirm_callback_params_t); 3597 *buf = (char *)malloc(*buf_size); 3598 if (*buf == NULL) { 3599 return (RDR_MEM_ALLOC); 3600 } 3601 3602 /* 3603 * Set fixed address labels by name 3604 */ 3605 if (params->confp != NULL) { 3606 confirm_callback_data.confirm_callback_id = 3607 (unsigned long)params->confp->confirm; 3608 confirm_callback_data.appdata_ptr = 3609 (unsigned long)params->confp->appdata_ptr; 3610 } else { 3611 confirm_callback_data.confirm_callback_id = 0; 3612 confirm_callback_data.appdata_ptr = 0; 3613 } 3614 confirm_callback_data.response = params->response; 3615 3616 /* 3617 * Set variable information using memcpy 3618 */ 3619 bufptr = *buf; 3620 3621 (void) memcpy(bufptr, &confirm_callback_data, 3622 sizeof (rdr_confirm_callback_reply_t)); 3623 3624 return (RDR_OK); 3625 } 3626 3627 3628 /* 3629 * unpack_confirm_reply: 3630 * 3631 * Handle unpacking a confirm callback reply. 3632 */ 3633 static int 3634 unpack_confirm_reply(confirm_callback_params_t *params, const char *buf) 3635 { 3636 char *bufptr; 3637 rdr_confirm_callback_reply_t confirm_callback_data; 3638 3639 if ((params == NULL) || (buf == NULL)) { 3640 return (RDR_ERROR); 3641 } 3642 3643 bufptr = (char *)buf; 3644 (void) memcpy(&confirm_callback_data, bufptr, 3645 sizeof (rdr_confirm_callback_reply_t)); 3646 bufptr += sizeof (confirm_callback_params_t); 3647 3648 /* 3649 * Set fixed address labels by name 3650 */ 3651 params->confp = (struct cfga_confirm *) 3652 malloc(sizeof (struct cfga_confirm)); 3653 if (params->confp == NULL) { 3654 return (RDR_MEM_ALLOC); 3655 } 3656 3657 /* set params->confp->confirm using memcpy */ 3658 (void) memcpy((void*)params->confp, 3659 &(confirm_callback_data.confirm_callback_id), 3660 sizeof (unsigned long)); 3661 3662 params->confp->appdata_ptr = 3663 (void*)confirm_callback_data.appdata_ptr; 3664 params->response = confirm_callback_data.response; 3665 3666 return (RDR_OK); 3667 } 3668 3669 3670 /* 3671 * pack_message_request: 3672 * 3673 * Handle packing a message callback request. 3674 */ 3675 static int 3676 pack_message_request(msg_callback_params_t *params, char **buf, int *buf_size) 3677 { 3678 int i; 3679 char *bufptr; 3680 rdr_msg_callback_t msg_callback_data; 3681 int message_strlen; 3682 int message_pad_sz; 3683 3684 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 3685 return (RDR_ERROR); 3686 } 3687 3688 /* 3689 * Set variable length fields and make a call to partially 3690 * pack it. 3691 */ 3692 if (params->message != NULL) { 3693 message_strlen = strlen(params->message) + 1; 3694 message_pad_sz = RDR_ALIGN_64_BIT - 3695 (message_strlen % RDR_ALIGN_64_BIT); 3696 } else { 3697 message_strlen = 0; 3698 message_pad_sz = 0; 3699 } 3700 3701 3702 /* 3703 * Collect size info specific to the message callback request 3704 * message and allocate a buffer 3705 */ 3706 *buf_size = sizeof (rdr_msg_callback_t); 3707 *buf_size += message_strlen; 3708 *buf_size += message_pad_sz; 3709 3710 *buf = (char *)malloc(*buf_size); 3711 if (*buf == NULL) { 3712 return (RDR_MEM_ALLOC); 3713 } 3714 3715 /* 3716 * Set fixed address labels by name 3717 */ 3718 if (params->msgp != NULL) { 3719 msg_callback_data.msg_callback_id = 3720 (unsigned long)params->msgp->message_routine; 3721 msg_callback_data.appdata_ptr = 3722 (unsigned long)params->msgp->appdata_ptr; 3723 } else { 3724 msg_callback_data.msg_callback_id = 0; 3725 msg_callback_data.appdata_ptr = 0; 3726 } 3727 msg_callback_data.message_size = message_strlen + message_pad_sz; 3728 3729 /* 3730 * Set variable information using memcpy 3731 */ 3732 bufptr = *buf; 3733 3734 (void) memcpy(bufptr, &msg_callback_data, sizeof (rdr_msg_callback_t)); 3735 bufptr += sizeof (rdr_msg_callback_t); 3736 3737 if (params->message != NULL) { 3738 (void) memcpy(bufptr, params->message, message_strlen); 3739 bufptr += message_strlen; 3740 for (i = 0; i < message_pad_sz; i++) { 3741 bufptr[i] = 0; 3742 } 3743 bufptr += message_pad_sz; 3744 } 3745 3746 return (RDR_OK); 3747 } 3748 3749 3750 /* 3751 * unpack_message_request: 3752 * 3753 * Handle unpacking a message callback request. 3754 */ 3755 static int 3756 unpack_message_request(msg_callback_params_t *params, const char *buf) 3757 { 3758 char *bufptr; 3759 rdr_msg_callback_t msg_callback_data; 3760 3761 if ((params == NULL) || (buf == NULL)) { 3762 return (RDR_ERROR); 3763 } 3764 3765 bufptr = (char *)buf; 3766 (void) memcpy(&msg_callback_data, bufptr, sizeof (rdr_msg_callback_t)); 3767 bufptr += sizeof (rdr_msg_callback_t); 3768 3769 /* 3770 * handle getting the message text 3771 */ 3772 if (get_string_from_buf(&(params->message), 3773 msg_callback_data.message_size, bufptr)) { 3774 return (RDR_ERROR); 3775 } 3776 bufptr += msg_callback_data.message_size; 3777 3778 /* 3779 * Set fixed address labels by name 3780 */ 3781 params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg)); 3782 if (params->msgp == NULL) { 3783 return (RDR_MEM_ALLOC); 3784 } 3785 3786 /* set params->msgp->message_routine using memcpy */ 3787 (void) memcpy((void*)params->msgp, &(msg_callback_data.msg_callback_id), 3788 sizeof (unsigned long)); 3789 3790 params->msgp->appdata_ptr = (void*)msg_callback_data.appdata_ptr; 3791 3792 return (RDR_OK); 3793 } 3794 3795 /* 3796 * pack_rsrc_info_request: 3797 * 3798 * Handle packing a resource info request. 3799 */ 3800 static int 3801 pack_rsrc_info_request(rsrc_info_params_t *params, char **buf, int *buf_size) 3802 { 3803 char *bufptr; 3804 rdr_rsrc_info_t rsrc_info_data; 3805 rdr_variable_message_info_t var_msg_info; 3806 3807 3808 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 3809 return (RDR_ERROR); 3810 } 3811 3812 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 3813 3814 /* 3815 * Set variable length fields and make a call to partially 3816 * pack it. 3817 */ 3818 if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) { 3819 cleanup_variable_ap_id_info(&var_msg_info); 3820 return (RDR_ERROR); 3821 } 3822 3823 /* 3824 * Collect size info specific to the resource info request 3825 * message and allocate a buffer. 3826 */ 3827 *buf_size = sizeof (rdr_rsrc_info_t); 3828 *buf_size += var_msg_info.ap_id_int_size; 3829 *buf_size += var_msg_info.ap_id_char_size; 3830 3831 *buf = (char *)malloc(*buf_size); 3832 if (*buf == NULL) { 3833 return (RDR_MEM_ALLOC); 3834 } 3835 3836 /* 3837 * Set fixed address labels by name. 3838 */ 3839 rsrc_info_data.num_ap_ids = params->num_ap_ids; 3840 rsrc_info_data.ap_id_char_size = var_msg_info.ap_id_char_size; 3841 rsrc_info_data.flags = params->flags; 3842 3843 /* 3844 * Set variable information using memcpy. 3845 */ 3846 bufptr = *buf; 3847 3848 (void) memcpy(bufptr, &rsrc_info_data, sizeof (rdr_rsrc_info_t)); 3849 bufptr += sizeof (rdr_rsrc_info_t); 3850 3851 if (var_msg_info.ap_id_sizes != NULL) { 3852 (void) memcpy(bufptr, var_msg_info.ap_id_sizes, 3853 var_msg_info.ap_id_int_size); 3854 bufptr += var_msg_info.ap_id_int_size; 3855 } 3856 3857 if (var_msg_info.ap_id_chars != NULL) { 3858 (void) memcpy(bufptr, var_msg_info.ap_id_chars, 3859 var_msg_info.ap_id_char_size); 3860 bufptr += var_msg_info.ap_id_char_size; 3861 } 3862 3863 cleanup_variable_ap_id_info(&var_msg_info); 3864 3865 return (RDR_OK); 3866 } 3867 3868 3869 /* 3870 * unpack_rsrc_info_request: 3871 * 3872 * Handle unpacking a resource info request message. 3873 */ 3874 static int 3875 unpack_rsrc_info_request(rsrc_info_params_t *params, const char *buf) 3876 { 3877 char *bufptr; 3878 rdr_variable_message_info_t var_msg_info; 3879 rdr_rsrc_info_t rsrc_info_data; 3880 3881 3882 if ((params == NULL) || (buf == NULL)) { 3883 return (RDR_ERROR); 3884 } 3885 3886 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t)); 3887 3888 bufptr = (char *)buf; 3889 (void) memcpy(&rsrc_info_data, bufptr, sizeof (rdr_rsrc_info_t)); 3890 bufptr += sizeof (rdr_rsrc_info_t); 3891 3892 /* 3893 * Handle getting the ap_ids. 3894 */ 3895 var_msg_info.ap_id_char_size = rsrc_info_data.ap_id_char_size; 3896 if (get_ap_ids_from_buf(&(params->ap_ids), rsrc_info_data.num_ap_ids, 3897 &var_msg_info, bufptr)) { 3898 return (RDR_ERROR); 3899 } 3900 bufptr += var_msg_info.ap_id_int_size; 3901 bufptr += var_msg_info.ap_id_char_size; 3902 3903 /* 3904 * Set fixed address labels by name. 3905 */ 3906 params->num_ap_ids = rsrc_info_data.num_ap_ids; 3907 params->flags = rsrc_info_data.flags; 3908 3909 return (RDR_OK); 3910 } 3911 3912 3913 /* 3914 * pack_rsrc_info_reply: 3915 * 3916 * Handle packing a resource info reply message. 3917 */ 3918 static int 3919 pack_rsrc_info_reply(rsrc_info_params_t *params, char **buf, int *buf_size) 3920 { 3921 char *bufptr; 3922 rdr_rsrc_info_reply_t rsrc_info_data; 3923 int pack_status; 3924 caddr_t rsrc_info_bufp = NULL; 3925 size_t rsrc_info_size; 3926 3927 3928 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) { 3929 return (RDR_ERROR); 3930 } 3931 3932 /* 3933 * Pack snapshot handle data. 3934 */ 3935 pack_status = ri_pack(params->hdl, &rsrc_info_bufp, &rsrc_info_size); 3936 if (pack_status != 0) { 3937 return (RDR_ERROR); 3938 } 3939 3940 /* 3941 * Collect size info specific to the rsrc_info reply message 3942 * and allocate a buffer. 3943 */ 3944 *buf_size = sizeof (rdr_rsrc_info_reply_t); 3945 *buf_size += rsrc_info_size; 3946 3947 *buf = (char *)malloc(*buf_size); 3948 if (*buf == NULL) { 3949 free(rsrc_info_bufp); 3950 return (RDR_MEM_ALLOC); 3951 } 3952 3953 /* 3954 * Set fixed address labels by name. 3955 */ 3956 rsrc_info_data.packed_hdl_size = rsrc_info_size; 3957 3958 /* 3959 * Set variable information using memcpy. 3960 */ 3961 bufptr = *buf; 3962 3963 (void) memcpy(bufptr, &rsrc_info_data, sizeof (rdr_rsrc_info_reply_t)); 3964 bufptr += sizeof (rdr_rsrc_info_reply_t); 3965 3966 if (rsrc_info_bufp) { 3967 (void) memcpy(bufptr, rsrc_info_bufp, rsrc_info_size); 3968 free(rsrc_info_bufp); 3969 } 3970 3971 return (RDR_OK); 3972 } 3973 3974 3975 /* 3976 * unpack_rsrc_info_reply: 3977 * 3978 * Handle unpacking a resource info reply message. 3979 */ 3980 static int 3981 unpack_rsrc_info_reply(rsrc_info_params_t *params, const char *buf) 3982 { 3983 int unpack_status; 3984 char *bufptr; 3985 rdr_rsrc_info_reply_t rsrc_info_data; 3986 3987 3988 if ((params == NULL) || (buf == NULL)) { 3989 return (RDR_ERROR); 3990 } 3991 3992 bufptr = (char *)buf; 3993 (void) memcpy(&rsrc_info_data, bufptr, sizeof (rdr_rsrc_info_reply_t)); 3994 bufptr += sizeof (rdr_rsrc_info_reply_t); 3995 3996 /* 3997 * Unpack buf into resource info handle. 3998 */ 3999 unpack_status = ri_unpack(bufptr, rsrc_info_data.packed_hdl_size, 4000 ¶ms->hdl); 4001 4002 return ((unpack_status == 0) ? RDR_OK : RDR_ERROR); 4003 } 4004 4005 4006 /* 4007 * pack_ap_ids: 4008 * 4009 * Pack a list of attachment point identifiers into a single buffer. 4010 * This buffer is stored in the specified rdr_variable_message_info_t 4011 * and is padded to be 64-bit aligned. 4012 */ 4013 static int 4014 pack_ap_ids(int num_ap_ids, char *const *ap_ids, 4015 rdr_variable_message_info_t *var_msg_info) 4016 { 4017 int i; 4018 int ap_id_pad_sz; 4019 char *bufptr; 4020 4021 4022 if (var_msg_info == NULL) { 4023 return (RDR_ERROR); 4024 } 4025 4026 /* 4027 * NULL is a valid value for ap_ids in the list_ext 4028 * case. For list_ext, no specified attachment points 4029 * indicates that _all_ attachment points should be 4030 * displayed. However, if ap_ids is NULL, num_ap_ids 4031 * should be 0. 4032 */ 4033 if ((ap_ids == NULL) && (num_ap_ids != 0)) { 4034 num_ap_ids = 0; 4035 } 4036 4037 var_msg_info->ap_id_int_size = sizeof (int) * num_ap_ids; 4038 if (num_ap_ids > 0) { 4039 var_msg_info->ap_id_sizes = (int *)malloc(sizeof (int) * 4040 var_msg_info->ap_id_int_size); 4041 if (var_msg_info->ap_id_sizes == NULL) { 4042 return (RDR_MEM_ALLOC); 4043 } 4044 } 4045 for (i = 0; i < num_ap_ids; i++) { 4046 if (ap_ids[i] != NULL) { 4047 var_msg_info->ap_id_sizes[i] = strlen(ap_ids[i]) + 1; 4048 var_msg_info->ap_id_char_size += 4049 var_msg_info->ap_id_sizes[i]; 4050 } 4051 } 4052 if (var_msg_info->ap_id_char_size > 0) { 4053 ap_id_pad_sz = RDR_ALIGN_64_BIT - 4054 (var_msg_info->ap_id_char_size % RDR_ALIGN_64_BIT); 4055 var_msg_info->ap_id_char_size += ap_id_pad_sz; 4056 var_msg_info->ap_id_chars = (char *) 4057 malloc(var_msg_info->ap_id_char_size); 4058 if (var_msg_info->ap_id_chars == NULL) { 4059 return (RDR_MEM_ALLOC); 4060 } 4061 4062 bufptr = var_msg_info->ap_id_chars; 4063 for (i = 0; i < num_ap_ids; i++) { 4064 (void) memcpy(bufptr, ap_ids[i], 4065 var_msg_info->ap_id_sizes[i]); 4066 bufptr += var_msg_info->ap_id_sizes[i]; 4067 } 4068 for (i = 0; i < ap_id_pad_sz; i++) { 4069 bufptr[i] = 0; 4070 } 4071 } else { 4072 ap_id_pad_sz = 0; 4073 } 4074 4075 return (RDR_OK); 4076 } 4077 4078 4079 /* 4080 * unpack_ap_ids: 4081 * 4082 * Unpack a buffer containing a concatenation of a list of 4083 * attachment point identifiers. The resulting list of strings 4084 * are stored in an array in the specified rdr_variable_message_info_t. 4085 */ 4086 static int 4087 unpack_ap_ids(int num_ap_ids, char **ap_ids, const char *buf, 4088 rdr_variable_message_info_t *var_msg_info) 4089 { 4090 int i; 4091 int ap_id_size; 4092 int chars_copied; 4093 char *bufptr; 4094 4095 4096 if ((ap_ids == NULL) || (buf == NULL) || (var_msg_info == NULL)) { 4097 return (RDR_ERROR); 4098 } 4099 bufptr = (char *)buf; 4100 4101 var_msg_info->ap_id_int_size = sizeof (int) * num_ap_ids; 4102 if (num_ap_ids > 0) { 4103 var_msg_info->ap_id_sizes = (int *) 4104 malloc(sizeof (int) * var_msg_info->ap_id_int_size); 4105 if (var_msg_info->ap_id_sizes == NULL) { 4106 return (RDR_MEM_ALLOC); 4107 } 4108 (void) memcpy(var_msg_info->ap_id_sizes, bufptr, 4109 var_msg_info->ap_id_int_size); 4110 } 4111 bufptr += var_msg_info->ap_id_int_size; 4112 4113 chars_copied = 0; 4114 for (i = 0; i < num_ap_ids; i++) { 4115 ap_id_size = var_msg_info->ap_id_sizes[i]; 4116 if (ap_id_size <= 0) { 4117 continue; 4118 } 4119 if ((chars_copied + ap_id_size) > 4120 var_msg_info->ap_id_char_size) { 4121 return (RDR_ERROR); 4122 } 4123 ap_ids[i] = (char *)malloc(ap_id_size); 4124 if (ap_ids[i] == NULL) { 4125 return (RDR_MEM_ALLOC); 4126 } 4127 (void) memcpy(ap_ids[i], bufptr, ap_id_size); 4128 bufptr += ap_id_size; 4129 chars_copied += ap_id_size; 4130 } 4131 return (RDR_OK); 4132 } 4133 4134 4135 /* 4136 * find_options_sizes: 4137 * 4138 * Determine the size of a specified option string. The information 4139 * is stored in the specified rdr_variable_message_info_t. 4140 */ 4141 static int 4142 find_options_sizes(char *options, rdr_variable_message_info_t *var_msg_info) 4143 { 4144 if (var_msg_info == NULL) { 4145 return (RDR_ERROR); 4146 } 4147 if (options != NULL) { 4148 var_msg_info->options_strlen = strlen(options) + 1; 4149 var_msg_info->options_pad_sz = RDR_ALIGN_64_BIT - 4150 (var_msg_info->options_strlen % RDR_ALIGN_64_BIT); 4151 } else { 4152 var_msg_info->options_strlen = 0; 4153 var_msg_info->options_pad_sz = 0; 4154 } 4155 return (RDR_OK); 4156 } 4157 4158 4159 /* 4160 * find_listopts_sizes: 4161 * 4162 * Determine the size of a specified list option string. The information 4163 * is stored in the specified rdr_variable_message_info_t. 4164 */ 4165 static int 4166 find_listopts_sizes(char *listopts, rdr_variable_message_info_t *var_msg_info) 4167 { 4168 if (var_msg_info == NULL) { 4169 return (RDR_ERROR); 4170 } 4171 if (listopts != NULL) { 4172 var_msg_info->listopts_strlen = strlen(listopts) + 1; 4173 var_msg_info->listopts_pad_sz = RDR_ALIGN_64_BIT - 4174 (var_msg_info->listopts_strlen % RDR_ALIGN_64_BIT); 4175 } else { 4176 var_msg_info->listopts_strlen = 0; 4177 var_msg_info->listopts_pad_sz = 0; 4178 } 4179 return (RDR_OK); 4180 } 4181 4182 4183 /* 4184 * find_function_size: 4185 * 4186 * Determine the size of a specified private function string. The 4187 * information is stored in the specified rdr_variable_message_info_t. 4188 */ 4189 static int 4190 find_function_sizes(char *function, rdr_variable_message_info_t *var_msg_info) 4191 { 4192 if (var_msg_info == NULL) { 4193 return (RDR_ERROR); 4194 } 4195 if (function != NULL) { 4196 var_msg_info->function_strlen = strlen(function) + 1; 4197 var_msg_info->function_pad_sz = RDR_ALIGN_64_BIT - 4198 (var_msg_info->function_strlen % RDR_ALIGN_64_BIT); 4199 } else { 4200 var_msg_info->function_strlen = 0; 4201 var_msg_info->function_pad_sz = 0; 4202 } 4203 return (RDR_OK); 4204 } 4205 4206 4207 /* 4208 * find_errstring_sizes: 4209 * 4210 * Determine the size of a specified error string. The information 4211 * is stored in the specified rdr_variable_message_info_t. 4212 */ 4213 static int 4214 find_errstring_sizes(char **errstring, 4215 rdr_variable_message_info_t *var_msg_info) 4216 { 4217 if ((errstring != NULL) && (*errstring != NULL)) { 4218 var_msg_info->errstring_strlen = strlen(*errstring) + 1; 4219 var_msg_info->errstring_pad_sz = RDR_ALIGN_64_BIT - 4220 (var_msg_info->errstring_strlen % RDR_ALIGN_64_BIT); 4221 } else { 4222 var_msg_info->errstring_strlen = 0; 4223 var_msg_info->errstring_pad_sz = 0; 4224 } 4225 return (RDR_OK); 4226 } 4227 4228 4229 /* 4230 * get_ap_ids_from_buf: 4231 * 4232 * Unpack a buffer containing a concatenation of a list of attachment 4233 * point identifiers. An appropriately sized buffer is allocated and 4234 * the resulting list of strings are stored in an array in the specified 4235 * rdr_variable_message_info_t. 4236 */ 4237 static int 4238 get_ap_ids_from_buf(char ***ap_id_ptr, int num_ap_ids, 4239 rdr_variable_message_info_t *var_msg_info, const char *buf) 4240 { 4241 if ((ap_id_ptr == NULL) || (buf == NULL) || (var_msg_info == NULL)) { 4242 return (RDR_ERROR); 4243 } 4244 if (num_ap_ids > 0) { 4245 *ap_id_ptr = (char **)malloc(sizeof (char *) * num_ap_ids); 4246 if (*ap_id_ptr == NULL) { 4247 return (RDR_MEM_ALLOC); 4248 } 4249 if (unpack_ap_ids(num_ap_ids, *ap_id_ptr, buf, var_msg_info)) { 4250 cleanup_variable_ap_id_info(var_msg_info); 4251 return (RDR_ERROR); 4252 } 4253 4254 } else if (num_ap_ids < 0) { 4255 return (RDR_ERROR); 4256 } 4257 4258 cleanup_variable_ap_id_info(var_msg_info); 4259 4260 return (RDR_OK); 4261 } 4262 4263 4264 /* 4265 * get_string_from_buf: 4266 * 4267 * Copy a string to a new buffer. Memory is allocated for the 4268 * new buffer and the original string is copied to the new buffer. 4269 * This is primarily used when a string is located in a packed 4270 * buffer that will eventually get deallocated. 4271 */ 4272 static int 4273 get_string_from_buf(char **stringptr, int strsize, const char *buf) 4274 { 4275 if (buf == NULL) { 4276 return (RDR_ERROR); 4277 } 4278 4279 /* 4280 * A stringptr of NULL is a valid value. The errstring param 4281 * in an rconfig_xxx call is valid and is passed to this 4282 * function. For example, see errstring in the call to this 4283 * function in unpack_change_state_reply. 4284 */ 4285 if (stringptr != NULL) { 4286 if (strsize > 0) { 4287 *stringptr = (char *)malloc(strsize); 4288 if (*stringptr == NULL) { 4289 return (RDR_MEM_ALLOC); 4290 } 4291 (void) memcpy(*stringptr, buf, strsize); 4292 } else if (strsize == 0) { 4293 *stringptr = NULL; 4294 } else if (strsize < 0) { 4295 *stringptr = NULL; 4296 return (RDR_ERROR); 4297 } 4298 } 4299 return (RDR_OK); 4300 } 4301 4302 4303 /* 4304 * cleanup_ap_ids: 4305 * 4306 * Deallocate the specified array of attachment point identifiers. 4307 */ 4308 static int 4309 cleanup_ap_ids(int num_ap_ids, char ** ap_ids) 4310 { 4311 int i; 4312 4313 if (ap_ids == NULL) { 4314 return (RDR_ERROR); 4315 } 4316 for (i = 0; i < num_ap_ids; i++) { 4317 if (ap_ids[i] != NULL) { 4318 free((void *)ap_ids[i]); 4319 ap_ids[i] = NULL; 4320 } 4321 } 4322 return (RDR_OK); 4323 } 4324 4325 4326 /* 4327 * cleanup_errstring: 4328 * 4329 * Deallocate the specified error string. 4330 */ 4331 static int 4332 cleanup_errstring(char **errstring) 4333 { 4334 if (errstring) { 4335 if (*errstring) { 4336 free((void *)*errstring); 4337 } 4338 free((void *)errstring); 4339 errstring = NULL; 4340 } 4341 4342 return (RDR_OK); 4343 } 4344 4345 4346 /* 4347 * cleanup_variable_ap_id_info: 4348 * 4349 * Deallocate the ap_id information from the specified 4350 * rdr_variable_message_info_t. 4351 */ 4352 static void 4353 cleanup_variable_ap_id_info(rdr_variable_message_info_t *var_msg_info) 4354 { 4355 if (var_msg_info != NULL) { 4356 if (var_msg_info->ap_id_sizes != NULL) { 4357 free((void *)var_msg_info->ap_id_sizes); 4358 var_msg_info->ap_id_sizes = NULL; 4359 } 4360 if (var_msg_info->ap_id_chars != NULL) { 4361 free((void *)var_msg_info->ap_id_chars); 4362 var_msg_info->ap_id_chars = NULL; 4363 } 4364 } 4365 } 4366