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