xref: /onnv-gate/usr/src/cmd/dcs/sparc/sun4u/rdr_messages.c (revision 1772:78cca3d2cc4b)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*1772Sjl139090  * Common Development and Distribution License (the "License").
6*1772Sjl139090  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
22*1772Sjl139090  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
230Sstevel@tonic-gate  * Use is subject to license terms.
240Sstevel@tonic-gate  */
250Sstevel@tonic-gate 
260Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
270Sstevel@tonic-gate 
280Sstevel@tonic-gate /*
290Sstevel@tonic-gate  * WARNING: The contents of this file are shared by all projects
300Sstevel@tonic-gate  * that  wish to  perform  remote  Dynamic Reconfiguration  (DR)
310Sstevel@tonic-gate  * operations. Copies of this file can be found in the following
320Sstevel@tonic-gate  * locations:
330Sstevel@tonic-gate  *
340Sstevel@tonic-gate  *	Project	    Location
350Sstevel@tonic-gate  *	-------	    --------
360Sstevel@tonic-gate  *	Solaris	    usr/src/cmd/dcs/sparc/sun4u/%M%
370Sstevel@tonic-gate  *	SMS	    src/sms/lib/librdr/%M%
380Sstevel@tonic-gate  *
390Sstevel@tonic-gate  * In order for proper communication to occur,  the files in the
400Sstevel@tonic-gate  * above locations must match exactly. Any changes that are made
410Sstevel@tonic-gate  * to this file should  be made to all of the files in the list.
420Sstevel@tonic-gate  */
430Sstevel@tonic-gate 
440Sstevel@tonic-gate /*
450Sstevel@tonic-gate  * This file is a module that contains an interface for performing
460Sstevel@tonic-gate  * remote Dynamic Reconfiguration (DR) operations. It hides all
470Sstevel@tonic-gate  * network operations such as establishing a connection, sending
480Sstevel@tonic-gate  * and receiving messages, and closing a connection. It also handles
490Sstevel@tonic-gate  * the packing and unpacking of messages for network transport.
500Sstevel@tonic-gate  */
510Sstevel@tonic-gate 
520Sstevel@tonic-gate #include <stdio.h>
530Sstevel@tonic-gate #include <stdlib.h>
540Sstevel@tonic-gate #include <unistd.h>
550Sstevel@tonic-gate #include <string.h>
560Sstevel@tonic-gate #include <fcntl.h>
570Sstevel@tonic-gate #include <errno.h>
58*1772Sjl139090 #include <dlfcn.h>
590Sstevel@tonic-gate #include <netdb.h>
60*1772Sjl139090 #include <libdscp.h>
610Sstevel@tonic-gate #include <sys/socket.h>
62*1772Sjl139090 #include <sys/systeminfo.h>
630Sstevel@tonic-gate #include <netinet/tcp.h>
640Sstevel@tonic-gate 
65*1772Sjl139090 #include "dcs.h"
660Sstevel@tonic-gate #include "remote_cfg.h"
670Sstevel@tonic-gate #include "rdr_param_types.h"
680Sstevel@tonic-gate #include "rdr_messages.h"
690Sstevel@tonic-gate 
700Sstevel@tonic-gate 
710Sstevel@tonic-gate /*
720Sstevel@tonic-gate  * Structure holding information about
730Sstevel@tonic-gate  * all possible variable length fields
740Sstevel@tonic-gate  * that can be present in an RDR message.
750Sstevel@tonic-gate  */
760Sstevel@tonic-gate typedef struct {
770Sstevel@tonic-gate 	int	ap_id_int_size;
780Sstevel@tonic-gate 	int	ap_id_char_size;
790Sstevel@tonic-gate 	int	*ap_id_sizes;
800Sstevel@tonic-gate 	char	*ap_id_chars;
810Sstevel@tonic-gate 	int	errstring_strlen;
820Sstevel@tonic-gate 	int	errstring_pad_sz;
830Sstevel@tonic-gate 	int	options_strlen;
840Sstevel@tonic-gate 	int	options_pad_sz;
850Sstevel@tonic-gate 	int	listopts_strlen;
860Sstevel@tonic-gate 	int	listopts_pad_sz;
870Sstevel@tonic-gate 	int	function_strlen;
880Sstevel@tonic-gate 	int	function_pad_sz;
890Sstevel@tonic-gate } rdr_variable_message_info_t;
900Sstevel@tonic-gate 
910Sstevel@tonic-gate /*
920Sstevel@tonic-gate  * A table of maximum sizes for each message type. Message size is
930Sstevel@tonic-gate  * validated when the message header is first received. This prevents
940Sstevel@tonic-gate  * a situation where a corrupted or bad header can cause too much
950Sstevel@tonic-gate  * memory to be allocated.
960Sstevel@tonic-gate  *
970Sstevel@tonic-gate  * The message size limits were chosen to be a very generous upper bound
980Sstevel@tonic-gate  * on the amount of data each message can send. They are not intended to
990Sstevel@tonic-gate  * be a precise measurement of the data size.
1000Sstevel@tonic-gate  */
1010Sstevel@tonic-gate #define	NOMSG		0
1020Sstevel@tonic-gate #define	SHORTMSG	(150 * 1024)		/* 150 KB */
1030Sstevel@tonic-gate #define	LONGMSG		(3 * 1024 * 1024)	/* 3 MB */
1040Sstevel@tonic-gate 
1050Sstevel@tonic-gate struct {
1060Sstevel@tonic-gate 	ulong_t	req_max;
1070Sstevel@tonic-gate 	ulong_t	reply_max;
1080Sstevel@tonic-gate } msg_sizes[] = {
1090Sstevel@tonic-gate 	/*
1100Sstevel@tonic-gate 	 * request	reply
1110Sstevel@tonic-gate 	 * -------	-----
1120Sstevel@tonic-gate 	 */
1130Sstevel@tonic-gate 	{  NOMSG,	NOMSG	  },	/*  Invalid Opcode		*/
1140Sstevel@tonic-gate 	{  SHORTMSG,	SHORTMSG  },	/*  RDR_SES_REQ			*/
1150Sstevel@tonic-gate 	{  NOMSG,	NOMSG	  },	/*  RDR_SES_ESTBL		*/
1160Sstevel@tonic-gate 	{  NOMSG,	NOMSG	  },	/*  RDR_SES_END			*/
1170Sstevel@tonic-gate 	{  SHORTMSG,	SHORTMSG  },	/*  RDR_CONF_CHANGE_STATE	*/
1180Sstevel@tonic-gate 	{  SHORTMSG,	SHORTMSG  },	/*  RDR_CONF_PRIVATE_FUNC	*/
1190Sstevel@tonic-gate 	{  SHORTMSG,	SHORTMSG  },	/*  RDR_CONF_TEST		*/
1200Sstevel@tonic-gate 	{  SHORTMSG,	LONGMSG	  },	/*  RDR_CONF_LIST_EXT		*/
1210Sstevel@tonic-gate 	{  SHORTMSG,	NOMSG	  },	/*  RDR_CONF_HELP		*/
1220Sstevel@tonic-gate 	{  SHORTMSG,	NOMSG	  },	/*  RDR_CONF_AP_ID_CMP		*/
1230Sstevel@tonic-gate 	{  SHORTMSG,	NOMSG	  },	/*  RDR_CONF_ABORT_CMD		*/
1240Sstevel@tonic-gate 	{  SHORTMSG,	SHORTMSG  },	/*  RDR_CONF_CONFIRM_CALLBACK 	*/
1250Sstevel@tonic-gate 	{  SHORTMSG,	NOMSG	  },	/*  RDR_CONF_MSG_CALLBACK	*/
1260Sstevel@tonic-gate 	{  SHORTMSG,	LONGMSG	  }	/*  RDR_RSRC_INFO		*/
1270Sstevel@tonic-gate };
1280Sstevel@tonic-gate 
1290Sstevel@tonic-gate 
1300Sstevel@tonic-gate #define	RDR_BAD_FD		(-1)
1310Sstevel@tonic-gate 
1320Sstevel@tonic-gate #define	RDR_MSG_HDR_SIZE 	sizeof (rdr_msg_hdr_t)
1330Sstevel@tonic-gate 
1340Sstevel@tonic-gate static const int RDR_ALIGN_64_BIT = 8;   /* 8 bytes */
1350Sstevel@tonic-gate 
136*1772Sjl139090 /*
137*1772Sjl139090  * Interfaces for dynamic use of libdscp.
138*1772Sjl139090  */
139*1772Sjl139090 
140*1772Sjl139090 #define	LIBDSCP_PATH	"/usr/platform/%s/lib/libdscp.so.1"
141*1772Sjl139090 
142*1772Sjl139090 #define	LIBDSCP_BIND	"dscpBind"
143*1772Sjl139090 #define	LIBDSCP_SECURE	"dscpSecure"
144*1772Sjl139090 #define	LIBDSCP_AUTH	"dscpAuth"
145*1772Sjl139090 
146*1772Sjl139090 typedef enum {
147*1772Sjl139090 	LIBDSCP_UNKNOWN = 0,
148*1772Sjl139090 	LIBDSCP_AVAILABLE,
149*1772Sjl139090 	LIBDSCP_UNAVAILABLE
150*1772Sjl139090 } dscp_status_t;
151*1772Sjl139090 
152*1772Sjl139090 typedef struct {
153*1772Sjl139090 	dscp_status_t	status;
154*1772Sjl139090 	int		(*bind)(int, int, int);
155*1772Sjl139090 	int		(*secure)(int, int);
156*1772Sjl139090 	int		(*auth)(int, struct sockaddr *, int);
157*1772Sjl139090 } libdscp_t;
158*1772Sjl139090 
159*1772Sjl139090 static libdscp_t libdscp;
1600Sstevel@tonic-gate 
1610Sstevel@tonic-gate /*
1620Sstevel@tonic-gate  * Static Function Declarations
1630Sstevel@tonic-gate  */
1640Sstevel@tonic-gate 
1650Sstevel@tonic-gate /*
1660Sstevel@tonic-gate  * Socket Related Routines
1670Sstevel@tonic-gate  */
1680Sstevel@tonic-gate static int rdr_setopt(int fd, int name, int level);
1690Sstevel@tonic-gate 
1700Sstevel@tonic-gate static int rdr_bind(int fd, struct sockaddr *addr);
1710Sstevel@tonic-gate 
172*1772Sjl139090 static int rdr_secure(int fd, struct sockaddr *addr);
173*1772Sjl139090 
174*1772Sjl139090 static int rdr_auth(struct sockaddr *addr, int len);
175*1772Sjl139090 
1760Sstevel@tonic-gate static int rdr_snd(int fd, rdr_msg_hdr_t *hdr, char *data, int data_sz,
1770Sstevel@tonic-gate 			int timeout);
1780Sstevel@tonic-gate static int rdr_snd_raw(int fd, char *msg, int data_sz, int timeout);
1790Sstevel@tonic-gate 
1800Sstevel@tonic-gate static int rdr_rcv(int fd, rdr_msg_hdr_t *hdr, char **data, int timeout);
1810Sstevel@tonic-gate 
1820Sstevel@tonic-gate static int rdr_rcv_raw(int fd, char *msg, int data_size, int timeout);
1830Sstevel@tonic-gate 
1840Sstevel@tonic-gate /*
1850Sstevel@tonic-gate  * Data Validation Routines
1860Sstevel@tonic-gate  */
1870Sstevel@tonic-gate static int validate_header(rdr_msg_hdr_t *hdr);
1880Sstevel@tonic-gate 
1890Sstevel@tonic-gate 
1900Sstevel@tonic-gate /*
1910Sstevel@tonic-gate  * Session Request Routines
1920Sstevel@tonic-gate  */
1930Sstevel@tonic-gate static int pack_ses_req_request(ses_req_params_t *params, char **buf,
1940Sstevel@tonic-gate 			int *buf_size);
1950Sstevel@tonic-gate static int unpack_ses_req_request(ses_req_params_t *params, const char *buf);
1960Sstevel@tonic-gate 
1970Sstevel@tonic-gate static int pack_ses_req_reply(ses_req_params_t *params, char **buf,
1980Sstevel@tonic-gate 			int *buf_size);
1990Sstevel@tonic-gate static int unpack_ses_req_reply(ses_req_params_t *params, const char *buf);
2000Sstevel@tonic-gate 
2010Sstevel@tonic-gate 
2020Sstevel@tonic-gate /*
2030Sstevel@tonic-gate  * Change State Routines
2040Sstevel@tonic-gate  */
2050Sstevel@tonic-gate static int pack_change_state_request(change_state_params_t *params,
2060Sstevel@tonic-gate 			char **buf, int *buf_size);
2070Sstevel@tonic-gate static int unpack_change_state_request(change_state_params_t *params,
2080Sstevel@tonic-gate 			const char *buf);
2090Sstevel@tonic-gate static int pack_change_state_reply(change_state_params_t *params,
2100Sstevel@tonic-gate 			char **buf, int *buf_size);
2110Sstevel@tonic-gate static int unpack_change_state_reply(change_state_params_t *params,
2120Sstevel@tonic-gate 			const char *buf);
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate /*
2150Sstevel@tonic-gate  * Private Func Routines
2160Sstevel@tonic-gate  */
2170Sstevel@tonic-gate static int pack_private_func_request(private_func_params_t *params,
2180Sstevel@tonic-gate 			char **buf, int *buf_size);
2190Sstevel@tonic-gate static int unpack_private_func_request(private_func_params_t *params,
2200Sstevel@tonic-gate 			const char *buf);
2210Sstevel@tonic-gate static int pack_private_func_reply(private_func_params_t *params,
2220Sstevel@tonic-gate 			char **buf, int *buf_size);
2230Sstevel@tonic-gate static int unpack_private_func_reply(private_func_params_t *params,
2240Sstevel@tonic-gate 			const char *buf);
2250Sstevel@tonic-gate 
2260Sstevel@tonic-gate /*
2270Sstevel@tonic-gate  * Test Routines
2280Sstevel@tonic-gate  */
2290Sstevel@tonic-gate static int pack_test_request(test_params_t *params, char **buf, int *buf_size);
2300Sstevel@tonic-gate 
2310Sstevel@tonic-gate static int unpack_test_request(test_params_t *params, const char *buf);
2320Sstevel@tonic-gate 
2330Sstevel@tonic-gate static int pack_test_reply(test_params_t *params, char **buf, int *buf_size);
2340Sstevel@tonic-gate 
2350Sstevel@tonic-gate static int unpack_test_reply(test_params_t *params, const char *buf);
2360Sstevel@tonic-gate 
2370Sstevel@tonic-gate 
2380Sstevel@tonic-gate /*
2390Sstevel@tonic-gate  * List Ext Routines
2400Sstevel@tonic-gate  */
2410Sstevel@tonic-gate static int pack_list_ext_request(list_ext_params_t *params, char **buf,
2420Sstevel@tonic-gate 			int *buf_size);
2430Sstevel@tonic-gate static int unpack_list_ext_request(list_ext_params_t *params, const char *buf);
2440Sstevel@tonic-gate 
2450Sstevel@tonic-gate static int pack_list_ext_reply(list_ext_params_t *params, char **buf,
2460Sstevel@tonic-gate 			int *buf_size);
2470Sstevel@tonic-gate static int unpack_list_ext_reply(list_ext_params_t *params, const char *buf);
2480Sstevel@tonic-gate 
2490Sstevel@tonic-gate 
2500Sstevel@tonic-gate /*
2510Sstevel@tonic-gate  * Help Routines
2520Sstevel@tonic-gate  */
2530Sstevel@tonic-gate static int pack_help_request(help_params_t *params, char **buf, int *buf_size);
2540Sstevel@tonic-gate 
2550Sstevel@tonic-gate static int unpack_help_request(help_params_t *params, const char *buf);
2560Sstevel@tonic-gate 
2570Sstevel@tonic-gate 
2580Sstevel@tonic-gate /*
2590Sstevel@tonic-gate  * Ap Id Cmp Routines
2600Sstevel@tonic-gate  */
2610Sstevel@tonic-gate static int pack_ap_id_cmp_request(ap_id_cmp_params_t *params, char **buf,
2620Sstevel@tonic-gate 			int *buf_size);
2630Sstevel@tonic-gate static int unpack_ap_id_cmp_request(ap_id_cmp_params_t *params,
2640Sstevel@tonic-gate 			const char *buf);
2650Sstevel@tonic-gate 
2660Sstevel@tonic-gate /*
2670Sstevel@tonic-gate  * Abort Routines
2680Sstevel@tonic-gate  */
2690Sstevel@tonic-gate static int pack_abort_cmd_request(abort_cmd_params_t *params, char **buf,
2700Sstevel@tonic-gate 			int *buf_size);
2710Sstevel@tonic-gate static int unpack_abort_cmd_request(abort_cmd_params_t *params,
2720Sstevel@tonic-gate 			const char *buf);
2730Sstevel@tonic-gate 
2740Sstevel@tonic-gate /*
2750Sstevel@tonic-gate  * Confirm Callback Routines
2760Sstevel@tonic-gate  */
2770Sstevel@tonic-gate static int pack_confirm_request(confirm_callback_params_t *params, char **buf,
2780Sstevel@tonic-gate 			int *buf_size);
2790Sstevel@tonic-gate static int unpack_confirm_request(confirm_callback_params_t *params,
2800Sstevel@tonic-gate 			const char *buf);
2810Sstevel@tonic-gate static int pack_confirm_reply(confirm_callback_params_t *params,
2820Sstevel@tonic-gate 			char **buf, int *buf_size);
2830Sstevel@tonic-gate static int unpack_confirm_reply(confirm_callback_params_t *params,
2840Sstevel@tonic-gate 			const char *buf);
2850Sstevel@tonic-gate 
2860Sstevel@tonic-gate /*
2870Sstevel@tonic-gate  * Message Callback Routines
2880Sstevel@tonic-gate  */
2890Sstevel@tonic-gate static int pack_message_request(msg_callback_params_t *params, char **buf,
2900Sstevel@tonic-gate 			int *buf_size);
2910Sstevel@tonic-gate static int unpack_message_request(msg_callback_params_t *params,
2920Sstevel@tonic-gate 			const char *buf);
2930Sstevel@tonic-gate 
2940Sstevel@tonic-gate /*
2950Sstevel@tonic-gate  * Resource Info Routines
2960Sstevel@tonic-gate  */
2970Sstevel@tonic-gate static int pack_rsrc_info_request(rsrc_info_params_t *params, char **buf,
2980Sstevel@tonic-gate 			int *buf_size);
2990Sstevel@tonic-gate static int unpack_rsrc_info_request(rsrc_info_params_t *params,
3000Sstevel@tonic-gate 			const char *buf);
3010Sstevel@tonic-gate static int pack_rsrc_info_reply(rsrc_info_params_t *params, char **buf,
302*1772Sjl139090 			int *buf_size, int encoding);
3030Sstevel@tonic-gate static int unpack_rsrc_info_reply(rsrc_info_params_t *params, const char *buf);
3040Sstevel@tonic-gate 
3050Sstevel@tonic-gate /*
3060Sstevel@tonic-gate  * General Pack/Unpack Routines
3070Sstevel@tonic-gate  */
3080Sstevel@tonic-gate static int pack_ap_ids(int num_ap_ids, char *const *ap_ids,
3090Sstevel@tonic-gate 			rdr_variable_message_info_t *var_msg_info);
3100Sstevel@tonic-gate static int unpack_ap_ids(int num_ap_ids, char **ap_ids, const char *buf,
3110Sstevel@tonic-gate 			rdr_variable_message_info_t *var_msg_info);
3120Sstevel@tonic-gate 
3130Sstevel@tonic-gate /*
3140Sstevel@tonic-gate  * Find Variable Info Sizes
3150Sstevel@tonic-gate  */
3160Sstevel@tonic-gate static int find_options_sizes(char *options,
3170Sstevel@tonic-gate 			rdr_variable_message_info_t *var_msg_info);
3180Sstevel@tonic-gate static int find_listopts_sizes(char *listopts,
3190Sstevel@tonic-gate 			rdr_variable_message_info_t *var_msg_info);
3200Sstevel@tonic-gate static int find_function_sizes(char *function,
3210Sstevel@tonic-gate 			rdr_variable_message_info_t *var_msg_info);
3220Sstevel@tonic-gate static int find_errstring_sizes(char **errstring,
3230Sstevel@tonic-gate 			rdr_variable_message_info_t *var_msg_info);
3240Sstevel@tonic-gate 
3250Sstevel@tonic-gate /*
3260Sstevel@tonic-gate  * Extract Info From Buffers
3270Sstevel@tonic-gate  */
3280Sstevel@tonic-gate static int get_ap_ids_from_buf(char ***ap_id_ptr, int num_ap_ids,
3290Sstevel@tonic-gate 			rdr_variable_message_info_t *var_msg_info,
3300Sstevel@tonic-gate 			const char *buf);
3310Sstevel@tonic-gate static int get_string_from_buf(char **stringptr, int strsize, const char *buf);
3320Sstevel@tonic-gate 
3330Sstevel@tonic-gate 
3340Sstevel@tonic-gate /*
3350Sstevel@tonic-gate  * Cleanup Routines
3360Sstevel@tonic-gate  */
3370Sstevel@tonic-gate static int cleanup_ap_ids(int num_ap_ids, char **ap_ids);
3380Sstevel@tonic-gate 
3390Sstevel@tonic-gate static int cleanup_errstring(char **errstring);
3400Sstevel@tonic-gate 
3410Sstevel@tonic-gate static void cleanup_variable_ap_id_info(
3420Sstevel@tonic-gate 			rdr_variable_message_info_t *var_msg_info);
3430Sstevel@tonic-gate 
3440Sstevel@tonic-gate /*
345*1772Sjl139090  * Functions for loading libdscp.
346*1772Sjl139090  */
347*1772Sjl139090 static int load_libdscp(libdscp_t *libdscp);
348*1772Sjl139090 
349*1772Sjl139090 /*
3500Sstevel@tonic-gate  * Public Functions
3510Sstevel@tonic-gate  */
3520Sstevel@tonic-gate 
3530Sstevel@tonic-gate 
3540Sstevel@tonic-gate /*
3550Sstevel@tonic-gate  * rdr_open:
3560Sstevel@tonic-gate  *
3570Sstevel@tonic-gate  * Establish a transport endpoint to prepare for a new
3580Sstevel@tonic-gate  * connection. Returns a file descriptor representing the
3590Sstevel@tonic-gate  * new transport if successful or RDR_BAD_FD upon failure.
3600Sstevel@tonic-gate  */
3610Sstevel@tonic-gate int
rdr_open(int family)3620Sstevel@tonic-gate rdr_open(int family)
3630Sstevel@tonic-gate {
3640Sstevel@tonic-gate 	int	newfd;
3650Sstevel@tonic-gate 
3660Sstevel@tonic-gate 
3670Sstevel@tonic-gate 	if ((newfd = socket(family, SOCK_STREAM, 0)) == NULL) {
3680Sstevel@tonic-gate 		return (RDR_BAD_FD);
3690Sstevel@tonic-gate 	}
3700Sstevel@tonic-gate 
3710Sstevel@tonic-gate 	return (newfd);
3720Sstevel@tonic-gate }
3730Sstevel@tonic-gate 
3740Sstevel@tonic-gate 
3750Sstevel@tonic-gate /*
3760Sstevel@tonic-gate  * rdr_init:
3770Sstevel@tonic-gate  *
3780Sstevel@tonic-gate  * Initialize a transport endpoint. This involves binding to
3790Sstevel@tonic-gate  * a particular port and setting any user specified socket
3800Sstevel@tonic-gate  * options.
3810Sstevel@tonic-gate  */
3820Sstevel@tonic-gate int
rdr_init(int fd,struct sockaddr * addr,int * opts,int num_opts,int blog)3830Sstevel@tonic-gate rdr_init(int fd, struct sockaddr *addr, int *opts, int num_opts, int blog)
3840Sstevel@tonic-gate {
3850Sstevel@tonic-gate 	int	i;
3860Sstevel@tonic-gate 
3870Sstevel@tonic-gate 
3880Sstevel@tonic-gate 	/* sanity checks */
3890Sstevel@tonic-gate 	if ((fd < 0) || (addr == NULL)) {
3900Sstevel@tonic-gate 		return (RDR_ERROR);
3910Sstevel@tonic-gate 	}
3920Sstevel@tonic-gate 
3930Sstevel@tonic-gate 	if ((opts == NULL) || (num_opts < 0)) {
3940Sstevel@tonic-gate 		num_opts = 0;
3950Sstevel@tonic-gate 	}
3960Sstevel@tonic-gate 
397*1772Sjl139090 	/* turn on security features */
398*1772Sjl139090 	if (rdr_secure(fd, addr) != RDR_OK) {
399*1772Sjl139090 		return (RDR_NET_ERR);
400*1772Sjl139090 	}
401*1772Sjl139090 
4020Sstevel@tonic-gate 	/* bind the address, if is not already bound */
4030Sstevel@tonic-gate 	if (rdr_bind(fd, addr) != RDR_OK) {
4040Sstevel@tonic-gate 		return (RDR_NET_ERR);
4050Sstevel@tonic-gate 	}
4060Sstevel@tonic-gate 
4070Sstevel@tonic-gate 	/*
4080Sstevel@tonic-gate 	 * Set TCP_NODELAY for this endpoint. This disables Nagle's
4090Sstevel@tonic-gate 	 * algorithm that can cause a delay in sending small sized
4100Sstevel@tonic-gate 	 * messages. Since most of the RDR messages are small, this
4110Sstevel@tonic-gate 	 * is a restriction that negatively impacts performance.
4120Sstevel@tonic-gate 	 */
4130Sstevel@tonic-gate 	if (rdr_setopt(fd, TCP_NODELAY, IPPROTO_TCP) != RDR_OK) {
4140Sstevel@tonic-gate 		return (RDR_NET_ERR);
4150Sstevel@tonic-gate 	}
4160Sstevel@tonic-gate 
4170Sstevel@tonic-gate 	/* set the user specified socket options */
4180Sstevel@tonic-gate 	for (i = 0; i < num_opts; i++) {
4190Sstevel@tonic-gate 		if (rdr_setopt(fd, opts[i], SOL_SOCKET) != RDR_OK) {
4200Sstevel@tonic-gate 			return (RDR_NET_ERR);
4210Sstevel@tonic-gate 		}
4220Sstevel@tonic-gate 	}
4230Sstevel@tonic-gate 
4240Sstevel@tonic-gate 	/*
4250Sstevel@tonic-gate 	 * If blog is not zero, it is a server that is being
4260Sstevel@tonic-gate 	 * initialized. In order for it to be able to accept
4270Sstevel@tonic-gate 	 * connections, we have to set the size of the incoming
4280Sstevel@tonic-gate 	 * connection queue.
4290Sstevel@tonic-gate 	 */
4300Sstevel@tonic-gate 	if (blog != 0) {
4310Sstevel@tonic-gate 		if (listen(fd, blog) == -1) {
4320Sstevel@tonic-gate 			return (RDR_NET_ERR);
4330Sstevel@tonic-gate 		}
4340Sstevel@tonic-gate 	}
4350Sstevel@tonic-gate 
4360Sstevel@tonic-gate 	return (RDR_OK);
4370Sstevel@tonic-gate }
4380Sstevel@tonic-gate 
4390Sstevel@tonic-gate 
4400Sstevel@tonic-gate /*
4410Sstevel@tonic-gate  * rdr_connect_clnt:
4420Sstevel@tonic-gate  *
4430Sstevel@tonic-gate  * Perform the necessary steps for a client to connect to
4440Sstevel@tonic-gate  * a server process. The required information is the file
4450Sstevel@tonic-gate  * descriptor for the transport endpoint, and the remote
4460Sstevel@tonic-gate  * address.
4470Sstevel@tonic-gate  */
4480Sstevel@tonic-gate int
rdr_connect_clnt(int fd,struct sockaddr * addr)4490Sstevel@tonic-gate rdr_connect_clnt(int fd, struct sockaddr *addr)
4500Sstevel@tonic-gate {
4510Sstevel@tonic-gate 	unsigned int	addr_len;
4520Sstevel@tonic-gate 
4530Sstevel@tonic-gate 
4540Sstevel@tonic-gate 	/* sanity check */
4550Sstevel@tonic-gate 	if (addr == NULL) {
4560Sstevel@tonic-gate 		return (RDR_ERROR);
4570Sstevel@tonic-gate 	}
4580Sstevel@tonic-gate 
4590Sstevel@tonic-gate 	/* initialize the address length */
4600Sstevel@tonic-gate 	switch (addr->sa_family) {
4610Sstevel@tonic-gate 
4620Sstevel@tonic-gate 	case AF_INET:
4630Sstevel@tonic-gate 		addr_len = sizeof (struct sockaddr_in);
4640Sstevel@tonic-gate 		break;
4650Sstevel@tonic-gate 
4660Sstevel@tonic-gate 	case AF_INET6:
4670Sstevel@tonic-gate 		addr_len = sizeof (struct sockaddr_in6);
4680Sstevel@tonic-gate 		break;
4690Sstevel@tonic-gate 
4700Sstevel@tonic-gate 	default:
4710Sstevel@tonic-gate 		return (RDR_ERROR);
4720Sstevel@tonic-gate 	}
4730Sstevel@tonic-gate 
4740Sstevel@tonic-gate 	/* attempt the connection */
4750Sstevel@tonic-gate 	if (connect(fd, addr, addr_len) == -1) {
4760Sstevel@tonic-gate 		return (RDR_NET_ERR);
4770Sstevel@tonic-gate 	}
4780Sstevel@tonic-gate 
4790Sstevel@tonic-gate 	return (RDR_OK);
4800Sstevel@tonic-gate }
4810Sstevel@tonic-gate 
4820Sstevel@tonic-gate 
4830Sstevel@tonic-gate /*
4840Sstevel@tonic-gate  * rdr_connect_srv:
4850Sstevel@tonic-gate  *
4860Sstevel@tonic-gate  * Perform the necessary steps for a server to connect to a
4870Sstevel@tonic-gate  * pending client request. The new connection is allocated a
4880Sstevel@tonic-gate  * new file descriptor, separate from the one used to accept
4890Sstevel@tonic-gate  * the connection.
4900Sstevel@tonic-gate  */
4910Sstevel@tonic-gate int
rdr_connect_srv(int fd)4920Sstevel@tonic-gate rdr_connect_srv(int fd)
4930Sstevel@tonic-gate {
4940Sstevel@tonic-gate 	int			newfd;
4950Sstevel@tonic-gate 	unsigned int		faddr_len;
4960Sstevel@tonic-gate 	struct sockaddr_storage	faddr;
4970Sstevel@tonic-gate 
4980Sstevel@tonic-gate 
499*1772Sjl139090 	/* accept the connection */
5000Sstevel@tonic-gate 	faddr_len = sizeof (faddr);
5010Sstevel@tonic-gate 	if ((newfd = accept(fd, (struct sockaddr *)&faddr, &faddr_len)) == -1) {
5020Sstevel@tonic-gate 		return (RDR_BAD_FD);
5030Sstevel@tonic-gate 	}
5040Sstevel@tonic-gate 
505*1772Sjl139090 	/* if the peer doesn't authenticate properly, reject */
506*1772Sjl139090 	if (rdr_auth((struct sockaddr *)&faddr, faddr_len) != RDR_OK) {
507*1772Sjl139090 		(void) close(newfd);
508*1772Sjl139090 		return (RDR_BAD_FD);
509*1772Sjl139090 	}
510*1772Sjl139090 
5110Sstevel@tonic-gate 	return (newfd);
5120Sstevel@tonic-gate }
5130Sstevel@tonic-gate 
5140Sstevel@tonic-gate 
5150Sstevel@tonic-gate /*
5160Sstevel@tonic-gate  * rdr_reject:
5170Sstevel@tonic-gate  *
5180Sstevel@tonic-gate  * Reject an incoming connection attempt. This requires
5190Sstevel@tonic-gate  * that the connection be accepted first.
5200Sstevel@tonic-gate  */
5210Sstevel@tonic-gate int
rdr_reject(int fd)5220Sstevel@tonic-gate rdr_reject(int fd)
5230Sstevel@tonic-gate {
5240Sstevel@tonic-gate 	unsigned int		faddr_len;
5250Sstevel@tonic-gate 	struct sockaddr_storage	faddr;
5260Sstevel@tonic-gate 
5270Sstevel@tonic-gate 
5280Sstevel@tonic-gate 	/* first accept the connection */
5290Sstevel@tonic-gate 	faddr_len = sizeof (faddr);
5300Sstevel@tonic-gate 	if (accept(fd, (struct sockaddr *)&faddr, &faddr_len) == -1) {
5310Sstevel@tonic-gate 		return (RDR_NET_ERR);
5320Sstevel@tonic-gate 	}
5330Sstevel@tonic-gate 
5340Sstevel@tonic-gate 	/* then close it */
535*1772Sjl139090 	(void) close(fd);
5360Sstevel@tonic-gate 
5370Sstevel@tonic-gate 	return (RDR_OK);
5380Sstevel@tonic-gate }
5390Sstevel@tonic-gate 
5400Sstevel@tonic-gate 
5410Sstevel@tonic-gate /*
5420Sstevel@tonic-gate  * rdr_close:
5430Sstevel@tonic-gate  *
5440Sstevel@tonic-gate  * Close down an given connection.
5450Sstevel@tonic-gate  */
5460Sstevel@tonic-gate int
rdr_close(int fd)5470Sstevel@tonic-gate rdr_close(int fd)
5480Sstevel@tonic-gate {
549*1772Sjl139090 	(void) close(fd);
5500Sstevel@tonic-gate 
5510Sstevel@tonic-gate 	return (RDR_OK);
5520Sstevel@tonic-gate }
5530Sstevel@tonic-gate 
5540Sstevel@tonic-gate 
5550Sstevel@tonic-gate /*
5560Sstevel@tonic-gate  * rdr_snd_msg:
5570Sstevel@tonic-gate  *
5580Sstevel@tonic-gate  * Public interface for sending an RDR message. The data
5590Sstevel@tonic-gate  * passed in through hdr and param are packed for network
5600Sstevel@tonic-gate  * transport and sent.
5610Sstevel@tonic-gate  */
5620Sstevel@tonic-gate int
rdr_snd_msg(int fd,rdr_msg_hdr_t * hdr,cfga_params_t * param,int timeout)5630Sstevel@tonic-gate rdr_snd_msg(int fd, rdr_msg_hdr_t *hdr, cfga_params_t *param, int timeout)
5640Sstevel@tonic-gate {
5650Sstevel@tonic-gate 	int	err;
5660Sstevel@tonic-gate 	char	*pack_buf = NULL;
5670Sstevel@tonic-gate 	int	pack_buf_sz = 0;
5680Sstevel@tonic-gate 
5690Sstevel@tonic-gate 
5700Sstevel@tonic-gate 	/* sanity checks */
5710Sstevel@tonic-gate 	if ((hdr == NULL) || (param == NULL)) {
5720Sstevel@tonic-gate 		return (RDR_ERROR);
5730Sstevel@tonic-gate 	}
5740Sstevel@tonic-gate 
5750Sstevel@tonic-gate 	/*
5760Sstevel@tonic-gate 	 * Pack the message for transport
5770Sstevel@tonic-gate 	 */
5780Sstevel@tonic-gate 	switch (hdr->message_opcode) {
5790Sstevel@tonic-gate 
5800Sstevel@tonic-gate 		case RDR_SES_REQ: {
5810Sstevel@tonic-gate 
5820Sstevel@tonic-gate 			ses_req_params_t *rparam;
5830Sstevel@tonic-gate 			rparam = (ses_req_params_t *)param;
5840Sstevel@tonic-gate 
5850Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
5860Sstevel@tonic-gate 				err = pack_ses_req_request(rparam,
5870Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
5880Sstevel@tonic-gate 			} else {
5890Sstevel@tonic-gate 				err = pack_ses_req_reply(rparam,
5900Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
5910Sstevel@tonic-gate 			}
5920Sstevel@tonic-gate 
5930Sstevel@tonic-gate 			break;
5940Sstevel@tonic-gate 		}
5950Sstevel@tonic-gate 
5960Sstevel@tonic-gate 		case RDR_SES_ESTBL:
5970Sstevel@tonic-gate 		case RDR_SES_END:
5980Sstevel@tonic-gate 
5990Sstevel@tonic-gate 			/*
6000Sstevel@tonic-gate 			 * This is not an error condition because
6010Sstevel@tonic-gate 			 * there is no extra information to pack.
6020Sstevel@tonic-gate 			 */
6030Sstevel@tonic-gate 			err = RDR_OK;
6040Sstevel@tonic-gate 			break;
6050Sstevel@tonic-gate 
6060Sstevel@tonic-gate 		case RDR_CONF_CHANGE_STATE: {
6070Sstevel@tonic-gate 
6080Sstevel@tonic-gate 			change_state_params_t *cparam;
6090Sstevel@tonic-gate 			cparam = (change_state_params_t *)param;
6100Sstevel@tonic-gate 
6110Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
6120Sstevel@tonic-gate 				err = pack_change_state_request(cparam,
6130Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
6140Sstevel@tonic-gate 			} else {
6150Sstevel@tonic-gate 				err = pack_change_state_reply(cparam,
6160Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
6170Sstevel@tonic-gate 			}
6180Sstevel@tonic-gate 			break;
6190Sstevel@tonic-gate 		}
6200Sstevel@tonic-gate 
6210Sstevel@tonic-gate 		case RDR_CONF_PRIVATE_FUNC: {
6220Sstevel@tonic-gate 
6230Sstevel@tonic-gate 			private_func_params_t *pparam;
6240Sstevel@tonic-gate 			pparam = (private_func_params_t *)param;
6250Sstevel@tonic-gate 
6260Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
6270Sstevel@tonic-gate 				err = pack_private_func_request(pparam,
6280Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
6290Sstevel@tonic-gate 			} else {
6300Sstevel@tonic-gate 				err = pack_private_func_reply(pparam,
6310Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
6320Sstevel@tonic-gate 			}
6330Sstevel@tonic-gate 			break;
6340Sstevel@tonic-gate 		}
6350Sstevel@tonic-gate 
6360Sstevel@tonic-gate 		case RDR_CONF_TEST: {
6370Sstevel@tonic-gate 
6380Sstevel@tonic-gate 			test_params_t *tparam;
6390Sstevel@tonic-gate 			tparam = (test_params_t *)param;
6400Sstevel@tonic-gate 
6410Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
6420Sstevel@tonic-gate 				err = pack_test_request(tparam,
6430Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
6440Sstevel@tonic-gate 			} else {
6450Sstevel@tonic-gate 				err = pack_test_reply(tparam,
6460Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
6470Sstevel@tonic-gate 			}
6480Sstevel@tonic-gate 			break;
6490Sstevel@tonic-gate 		}
6500Sstevel@tonic-gate 
6510Sstevel@tonic-gate 		case RDR_CONF_LIST_EXT: {
6520Sstevel@tonic-gate 
6530Sstevel@tonic-gate 			list_ext_params_t *lparam;
6540Sstevel@tonic-gate 			lparam = (list_ext_params_t *)param;
6550Sstevel@tonic-gate 
6560Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
6570Sstevel@tonic-gate 				err = pack_list_ext_request(lparam, &pack_buf,
6580Sstevel@tonic-gate 				    &pack_buf_sz);
6590Sstevel@tonic-gate 			} else {
6600Sstevel@tonic-gate 				err = pack_list_ext_reply(lparam, &pack_buf,
6610Sstevel@tonic-gate 				    &pack_buf_sz);
6620Sstevel@tonic-gate 			}
6630Sstevel@tonic-gate 			break;
6640Sstevel@tonic-gate 		}
6650Sstevel@tonic-gate 
6660Sstevel@tonic-gate 		case RDR_CONF_HELP: {
6670Sstevel@tonic-gate 
6680Sstevel@tonic-gate 			help_params_t *hparam;
6690Sstevel@tonic-gate 			hparam = (help_params_t *)param;
6700Sstevel@tonic-gate 
6710Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
6720Sstevel@tonic-gate 				err = pack_help_request(hparam,
6730Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
6740Sstevel@tonic-gate 			} else {
6750Sstevel@tonic-gate 
6760Sstevel@tonic-gate 				/*
6770Sstevel@tonic-gate 				 * This is not an error because help
6780Sstevel@tonic-gate 				 * reply does not have any extra information
6790Sstevel@tonic-gate 				 * to pack.
6800Sstevel@tonic-gate 				 */
6810Sstevel@tonic-gate 				err = RDR_OK;
6820Sstevel@tonic-gate 			}
6830Sstevel@tonic-gate 			break;
6840Sstevel@tonic-gate 		}
6850Sstevel@tonic-gate 
6860Sstevel@tonic-gate 		case RDR_CONF_AP_ID_CMP: {
6870Sstevel@tonic-gate 
6880Sstevel@tonic-gate 			ap_id_cmp_params_t *aparam;
6890Sstevel@tonic-gate 			aparam = (ap_id_cmp_params_t *)param;
6900Sstevel@tonic-gate 
6910Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
6920Sstevel@tonic-gate 				err = pack_ap_id_cmp_request(aparam,
6930Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
6940Sstevel@tonic-gate 			} else {
6950Sstevel@tonic-gate 
6960Sstevel@tonic-gate 				/*
6970Sstevel@tonic-gate 				 * This is not an error because ap_id_cmp
6980Sstevel@tonic-gate 				 * reply does not have any extra information
6990Sstevel@tonic-gate 				 * to pack.
7000Sstevel@tonic-gate 				 */
7010Sstevel@tonic-gate 				err = RDR_OK;
7020Sstevel@tonic-gate 			}
7030Sstevel@tonic-gate 			break;
7040Sstevel@tonic-gate 		}
7050Sstevel@tonic-gate 
7060Sstevel@tonic-gate 		case RDR_CONF_ABORT_CMD: {
7070Sstevel@tonic-gate 
7080Sstevel@tonic-gate 			abort_cmd_params_t *aparam;
7090Sstevel@tonic-gate 			aparam = (abort_cmd_params_t *)param;
7100Sstevel@tonic-gate 
7110Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
7120Sstevel@tonic-gate 				err = pack_abort_cmd_request(aparam,
7130Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
7140Sstevel@tonic-gate 			} else {
7150Sstevel@tonic-gate 				/*
7160Sstevel@tonic-gate 				 * This is not an error because session
7170Sstevel@tonic-gate 				 * abort reply does not have any extra
7180Sstevel@tonic-gate 				 * information to pack.
7190Sstevel@tonic-gate 				 */
7200Sstevel@tonic-gate 				err = RDR_OK;
7210Sstevel@tonic-gate 			}
7220Sstevel@tonic-gate 			break;
7230Sstevel@tonic-gate 		}
7240Sstevel@tonic-gate 
7250Sstevel@tonic-gate 		case RDR_CONF_CONFIRM_CALLBACK: {
7260Sstevel@tonic-gate 
7270Sstevel@tonic-gate 			confirm_callback_params_t *cparam;
7280Sstevel@tonic-gate 			cparam = (confirm_callback_params_t *)param;
7290Sstevel@tonic-gate 
7300Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
7310Sstevel@tonic-gate 				err = pack_confirm_request(cparam,
7320Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
7330Sstevel@tonic-gate 			} else {
7340Sstevel@tonic-gate 				err = pack_confirm_reply(cparam, &pack_buf,
7350Sstevel@tonic-gate 				    &pack_buf_sz);
7360Sstevel@tonic-gate 			}
7370Sstevel@tonic-gate 			break;
7380Sstevel@tonic-gate 		}
7390Sstevel@tonic-gate 
7400Sstevel@tonic-gate 		case RDR_CONF_MSG_CALLBACK: {
7410Sstevel@tonic-gate 
7420Sstevel@tonic-gate 			msg_callback_params_t *mparam;
7430Sstevel@tonic-gate 			mparam = (msg_callback_params_t *)param;
7440Sstevel@tonic-gate 
7450Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
7460Sstevel@tonic-gate 				err = pack_message_request(mparam,
7470Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
7480Sstevel@tonic-gate 			} else {
7490Sstevel@tonic-gate 				/*
7500Sstevel@tonic-gate 				 * It is an error to send a reply
7510Sstevel@tonic-gate 				 * to a message callback.
7520Sstevel@tonic-gate 				 */
7530Sstevel@tonic-gate 				err = RDR_MSG_INVAL;
7540Sstevel@tonic-gate 			}
7550Sstevel@tonic-gate 			break;
7560Sstevel@tonic-gate 		}
7570Sstevel@tonic-gate 
7580Sstevel@tonic-gate 		case RDR_RSRC_INFO: {
7590Sstevel@tonic-gate 
7600Sstevel@tonic-gate 			rsrc_info_params_t *rparam;
7610Sstevel@tonic-gate 			rparam = (rsrc_info_params_t *)param;
7620Sstevel@tonic-gate 
7630Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
7640Sstevel@tonic-gate 				err = pack_rsrc_info_request(rparam, &pack_buf,
7650Sstevel@tonic-gate 				    &pack_buf_sz);
7660Sstevel@tonic-gate 			} else {
767*1772Sjl139090 				if ((hdr->major_version == 1) &&
768*1772Sjl139090 				    (hdr->minor_version == 0)) {
769*1772Sjl139090 					err = pack_rsrc_info_reply(rparam,
770*1772Sjl139090 					    &pack_buf, &pack_buf_sz,
771*1772Sjl139090 					    NV_ENCODE_NATIVE);
772*1772Sjl139090 				} else {
773*1772Sjl139090 					err = pack_rsrc_info_reply(rparam,
774*1772Sjl139090 					    &pack_buf, &pack_buf_sz,
775*1772Sjl139090 					    NV_ENCODE_XDR);
776*1772Sjl139090 				}
7770Sstevel@tonic-gate 			}
7780Sstevel@tonic-gate 			break;
7790Sstevel@tonic-gate 		}
7800Sstevel@tonic-gate 
7810Sstevel@tonic-gate 		default:
7820Sstevel@tonic-gate 			err = RDR_MSG_INVAL;
7830Sstevel@tonic-gate 			break;
7840Sstevel@tonic-gate 	}
7850Sstevel@tonic-gate 
7860Sstevel@tonic-gate 	/* check if packed correctly */
7870Sstevel@tonic-gate 	if (err != RDR_OK) {
7880Sstevel@tonic-gate 		return (err);
7890Sstevel@tonic-gate 	}
7900Sstevel@tonic-gate 
7910Sstevel@tonic-gate 	/* send the message */
7920Sstevel@tonic-gate 	err = rdr_snd(fd, hdr, pack_buf, pack_buf_sz, timeout);
7930Sstevel@tonic-gate 
7940Sstevel@tonic-gate 	free((void *)pack_buf);
7950Sstevel@tonic-gate 
7960Sstevel@tonic-gate 	return (err);
7970Sstevel@tonic-gate }
7980Sstevel@tonic-gate 
7990Sstevel@tonic-gate 
8000Sstevel@tonic-gate /*
8010Sstevel@tonic-gate  * rdr_rcv_msg:
8020Sstevel@tonic-gate  *
8030Sstevel@tonic-gate  * Public interface for receiving an RDR message. Data is
8040Sstevel@tonic-gate  * unpacked into the hdr and param paramters.
8050Sstevel@tonic-gate  */
8060Sstevel@tonic-gate int
rdr_rcv_msg(int fd,rdr_msg_hdr_t * hdr,cfga_params_t * param,int timeout)8070Sstevel@tonic-gate rdr_rcv_msg(int fd, rdr_msg_hdr_t *hdr, cfga_params_t *param, int timeout)
8080Sstevel@tonic-gate {
8090Sstevel@tonic-gate 	int	err;
8100Sstevel@tonic-gate 	char	*unpack_buf = NULL;
8110Sstevel@tonic-gate 
8120Sstevel@tonic-gate 
8130Sstevel@tonic-gate 	/* sanity checks */
8140Sstevel@tonic-gate 	if ((hdr == NULL) || (param == NULL)) {
8150Sstevel@tonic-gate 		return (RDR_ERROR);
8160Sstevel@tonic-gate 	}
8170Sstevel@tonic-gate 
8180Sstevel@tonic-gate 	(void) memset(param, 0, sizeof (cfga_params_t));
8190Sstevel@tonic-gate 
8200Sstevel@tonic-gate 	/* receive the message */
8210Sstevel@tonic-gate 	if ((err = rdr_rcv(fd, hdr, &unpack_buf, timeout)) != RDR_OK) {
8220Sstevel@tonic-gate 		return (err);
8230Sstevel@tonic-gate 	}
8240Sstevel@tonic-gate 
8250Sstevel@tonic-gate 	/*
8260Sstevel@tonic-gate 	 * Unpack the message
8270Sstevel@tonic-gate 	 */
8280Sstevel@tonic-gate 	switch (hdr->message_opcode) {
8290Sstevel@tonic-gate 
8300Sstevel@tonic-gate 		case RDR_SES_REQ: {
8310Sstevel@tonic-gate 
8320Sstevel@tonic-gate 			ses_req_params_t *rparam;
8330Sstevel@tonic-gate 			rparam = (ses_req_params_t *)param;
8340Sstevel@tonic-gate 
8350Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
8360Sstevel@tonic-gate 				err = unpack_ses_req_request(rparam,
8370Sstevel@tonic-gate 				    unpack_buf);
8380Sstevel@tonic-gate 			} else {
8390Sstevel@tonic-gate 				err = unpack_ses_req_reply(rparam, unpack_buf);
8400Sstevel@tonic-gate 			}
8410Sstevel@tonic-gate 			break;
8420Sstevel@tonic-gate 		}
8430Sstevel@tonic-gate 
8440Sstevel@tonic-gate 		case RDR_SES_ESTBL:
8450Sstevel@tonic-gate 		case RDR_SES_END:
8460Sstevel@tonic-gate 
8470Sstevel@tonic-gate 			/* no information to unpack */
8480Sstevel@tonic-gate 			(void) memset(param, 0, sizeof (cfga_params_t));
8490Sstevel@tonic-gate 			err = RDR_OK;
8500Sstevel@tonic-gate 			break;
8510Sstevel@tonic-gate 
8520Sstevel@tonic-gate 		case RDR_CONF_CHANGE_STATE: {
8530Sstevel@tonic-gate 
8540Sstevel@tonic-gate 			change_state_params_t *cparam;
8550Sstevel@tonic-gate 			cparam = (change_state_params_t *)param;
8560Sstevel@tonic-gate 
8570Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
8580Sstevel@tonic-gate 				err = unpack_change_state_request(cparam,
8590Sstevel@tonic-gate 				    unpack_buf);
8600Sstevel@tonic-gate 			} else {
8610Sstevel@tonic-gate 				err = unpack_change_state_reply(cparam,
8620Sstevel@tonic-gate 				    unpack_buf);
8630Sstevel@tonic-gate 			}
8640Sstevel@tonic-gate 			break;
8650Sstevel@tonic-gate 		}
8660Sstevel@tonic-gate 
8670Sstevel@tonic-gate 		case RDR_CONF_PRIVATE_FUNC: {
8680Sstevel@tonic-gate 
8690Sstevel@tonic-gate 			private_func_params_t *pparam;
8700Sstevel@tonic-gate 			pparam = (private_func_params_t *)param;
8710Sstevel@tonic-gate 
8720Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
8730Sstevel@tonic-gate 				err = unpack_private_func_request(pparam,
8740Sstevel@tonic-gate 				    unpack_buf);
8750Sstevel@tonic-gate 			} else {
8760Sstevel@tonic-gate 				err = unpack_private_func_reply(pparam,
8770Sstevel@tonic-gate 				    unpack_buf);
8780Sstevel@tonic-gate 			}
8790Sstevel@tonic-gate 			break;
8800Sstevel@tonic-gate 		}
8810Sstevel@tonic-gate 
8820Sstevel@tonic-gate 		case RDR_CONF_TEST: {
8830Sstevel@tonic-gate 
8840Sstevel@tonic-gate 			test_params_t *tparam;
8850Sstevel@tonic-gate 			tparam = (test_params_t *)param;
8860Sstevel@tonic-gate 
8870Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
8880Sstevel@tonic-gate 				err = unpack_test_request(tparam, unpack_buf);
8890Sstevel@tonic-gate 			} else {
8900Sstevel@tonic-gate 				err = unpack_test_reply(tparam, unpack_buf);
8910Sstevel@tonic-gate 			}
8920Sstevel@tonic-gate 			break;
8930Sstevel@tonic-gate 		}
8940Sstevel@tonic-gate 
8950Sstevel@tonic-gate 		case RDR_CONF_LIST_EXT: {
8960Sstevel@tonic-gate 
8970Sstevel@tonic-gate 			list_ext_params_t *lparam;
8980Sstevel@tonic-gate 			lparam = (list_ext_params_t *)param;
8990Sstevel@tonic-gate 
9000Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
9010Sstevel@tonic-gate 				err = unpack_list_ext_request(lparam,
9020Sstevel@tonic-gate 				    unpack_buf);
9030Sstevel@tonic-gate 			} else {
9040Sstevel@tonic-gate 				err = unpack_list_ext_reply(lparam, unpack_buf);
9050Sstevel@tonic-gate 			}
9060Sstevel@tonic-gate 			break;
9070Sstevel@tonic-gate 		}
9080Sstevel@tonic-gate 
9090Sstevel@tonic-gate 		case RDR_CONF_HELP: {
9100Sstevel@tonic-gate 
9110Sstevel@tonic-gate 			help_params_t *hparam;
9120Sstevel@tonic-gate 			hparam = (help_params_t *)param;
9130Sstevel@tonic-gate 
9140Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
9150Sstevel@tonic-gate 				err = unpack_help_request(hparam,
9160Sstevel@tonic-gate 				    unpack_buf);
9170Sstevel@tonic-gate 			} else {
9180Sstevel@tonic-gate 				/*
9190Sstevel@tonic-gate 				 * This is not an error because help
9200Sstevel@tonic-gate 				 * reply does not have any extra information
9210Sstevel@tonic-gate 				 * to unpack.
9220Sstevel@tonic-gate 				 */
9230Sstevel@tonic-gate 				err = RDR_OK;
9240Sstevel@tonic-gate 			}
9250Sstevel@tonic-gate 			break;
9260Sstevel@tonic-gate 		}
9270Sstevel@tonic-gate 
9280Sstevel@tonic-gate 		case RDR_CONF_AP_ID_CMP: {
9290Sstevel@tonic-gate 
9300Sstevel@tonic-gate 			ap_id_cmp_params_t *aparam;
9310Sstevel@tonic-gate 			aparam = (ap_id_cmp_params_t *)param;
9320Sstevel@tonic-gate 
9330Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
9340Sstevel@tonic-gate 				err = unpack_ap_id_cmp_request(aparam,
9350Sstevel@tonic-gate 				    unpack_buf);
9360Sstevel@tonic-gate 			} else {
9370Sstevel@tonic-gate 				/*
9380Sstevel@tonic-gate 				 * This is not an error because ap_id_cmp
9390Sstevel@tonic-gate 				 * reply does not have any extra information
9400Sstevel@tonic-gate 				 * to pack.
9410Sstevel@tonic-gate 				 */
9420Sstevel@tonic-gate 				err = RDR_OK;
9430Sstevel@tonic-gate 			}
9440Sstevel@tonic-gate 			break;
9450Sstevel@tonic-gate 		}
9460Sstevel@tonic-gate 
9470Sstevel@tonic-gate 		case RDR_CONF_ABORT_CMD: {
9480Sstevel@tonic-gate 
9490Sstevel@tonic-gate 			abort_cmd_params_t *aparam;
9500Sstevel@tonic-gate 			aparam = (abort_cmd_params_t *)param;
9510Sstevel@tonic-gate 
9520Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
9530Sstevel@tonic-gate 				err = unpack_abort_cmd_request(aparam,
9540Sstevel@tonic-gate 				    unpack_buf);
9550Sstevel@tonic-gate 			} else {
9560Sstevel@tonic-gate 				/* no information to unpack */
9570Sstevel@tonic-gate 				(void) memset(param, 0, sizeof (cfga_params_t));
9580Sstevel@tonic-gate 				err = RDR_OK;
9590Sstevel@tonic-gate 			}
9600Sstevel@tonic-gate 
9610Sstevel@tonic-gate 			break;
9620Sstevel@tonic-gate 		}
9630Sstevel@tonic-gate 
9640Sstevel@tonic-gate 		case RDR_CONF_CONFIRM_CALLBACK: {
9650Sstevel@tonic-gate 
9660Sstevel@tonic-gate 			confirm_callback_params_t *cparam;
9670Sstevel@tonic-gate 			cparam = (confirm_callback_params_t *)param;
9680Sstevel@tonic-gate 
9690Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
9700Sstevel@tonic-gate 				err = unpack_confirm_request(cparam,
9710Sstevel@tonic-gate 				    unpack_buf);
9720Sstevel@tonic-gate 			} else {
9730Sstevel@tonic-gate 				err = unpack_confirm_reply(cparam, unpack_buf);
9740Sstevel@tonic-gate 			}
9750Sstevel@tonic-gate 			break;
9760Sstevel@tonic-gate 		}
9770Sstevel@tonic-gate 
9780Sstevel@tonic-gate 		case RDR_CONF_MSG_CALLBACK: {
9790Sstevel@tonic-gate 
9800Sstevel@tonic-gate 			msg_callback_params_t *mparam;
9810Sstevel@tonic-gate 			mparam = (msg_callback_params_t *)param;
9820Sstevel@tonic-gate 
9830Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
9840Sstevel@tonic-gate 				err = unpack_message_request(mparam,
9850Sstevel@tonic-gate 				    unpack_buf);
9860Sstevel@tonic-gate 			} else {
9870Sstevel@tonic-gate 				/*
9880Sstevel@tonic-gate 				 * It is an error to send a reply
9890Sstevel@tonic-gate 				 * to a message callback.
9900Sstevel@tonic-gate 				 */
9910Sstevel@tonic-gate 				(void) memset(param, 0, sizeof (cfga_params_t));
9920Sstevel@tonic-gate 				err = RDR_MSG_INVAL;
9930Sstevel@tonic-gate 			}
9940Sstevel@tonic-gate 			break;
9950Sstevel@tonic-gate 		}
9960Sstevel@tonic-gate 
9970Sstevel@tonic-gate 		case RDR_RSRC_INFO: {
9980Sstevel@tonic-gate 
9990Sstevel@tonic-gate 			rsrc_info_params_t *rparam;
10000Sstevel@tonic-gate 			rparam = (rsrc_info_params_t *)param;
10010Sstevel@tonic-gate 
10020Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
10030Sstevel@tonic-gate 				err = unpack_rsrc_info_request(rparam,
10040Sstevel@tonic-gate 				    unpack_buf);
10050Sstevel@tonic-gate 			} else {
10060Sstevel@tonic-gate 				err = unpack_rsrc_info_reply(rparam,
10070Sstevel@tonic-gate 				    unpack_buf);
10080Sstevel@tonic-gate 			}
10090Sstevel@tonic-gate 			break;
10100Sstevel@tonic-gate 		}
10110Sstevel@tonic-gate 
10120Sstevel@tonic-gate 		default:
10130Sstevel@tonic-gate 			err = RDR_MSG_INVAL;
10140Sstevel@tonic-gate 			break;
10150Sstevel@tonic-gate 	}
10160Sstevel@tonic-gate 
10170Sstevel@tonic-gate 	free(unpack_buf);
10180Sstevel@tonic-gate 
10190Sstevel@tonic-gate 	/* check if unpacked correctly */
10200Sstevel@tonic-gate 	if (err != RDR_OK) {
10210Sstevel@tonic-gate 		return (err);
10220Sstevel@tonic-gate 	}
10230Sstevel@tonic-gate 
10240Sstevel@tonic-gate 	return (RDR_OK);
10250Sstevel@tonic-gate }
10260Sstevel@tonic-gate 
10270Sstevel@tonic-gate 
10280Sstevel@tonic-gate /*
10290Sstevel@tonic-gate  * rdr_cleanup_params:
10300Sstevel@tonic-gate  *
10310Sstevel@tonic-gate  * Deallocate any memory that was allocated in unpacking a
10320Sstevel@tonic-gate  * message.
10330Sstevel@tonic-gate  */
10340Sstevel@tonic-gate int
rdr_cleanup_params(rdr_msg_opcode_t message_opcode,cfga_params_t * param)10350Sstevel@tonic-gate rdr_cleanup_params(rdr_msg_opcode_t message_opcode, cfga_params_t *param)
10360Sstevel@tonic-gate {
10370Sstevel@tonic-gate 	/* sanity check */
10380Sstevel@tonic-gate 	if ((param == NULL)) {
10390Sstevel@tonic-gate 		return (RDR_ERROR);
10400Sstevel@tonic-gate 	}
10410Sstevel@tonic-gate 
10420Sstevel@tonic-gate 	/*
10430Sstevel@tonic-gate 	 * Deallocate memory depending on
10440Sstevel@tonic-gate 	 * the operation.
10450Sstevel@tonic-gate 	 */
10460Sstevel@tonic-gate 	switch (message_opcode) {
10470Sstevel@tonic-gate 
10480Sstevel@tonic-gate 	case RDR_SES_REQ: {
10490Sstevel@tonic-gate 
10500Sstevel@tonic-gate 		ses_req_params_t *sparam;
10510Sstevel@tonic-gate 		sparam = (ses_req_params_t *)param;
10520Sstevel@tonic-gate 
10530Sstevel@tonic-gate 		if (sparam->locale_str != NULL) {
10540Sstevel@tonic-gate 			free((void *)sparam->locale_str);
10550Sstevel@tonic-gate 			sparam->locale_str = NULL;
10560Sstevel@tonic-gate 		}
10570Sstevel@tonic-gate 		break;
10580Sstevel@tonic-gate 	}
10590Sstevel@tonic-gate 
10600Sstevel@tonic-gate 	case RDR_SES_ESTBL:
10610Sstevel@tonic-gate 	case RDR_SES_END:
10620Sstevel@tonic-gate 
10630Sstevel@tonic-gate 		/* nothing to deallocate */
10640Sstevel@tonic-gate 		break;
10650Sstevel@tonic-gate 
10660Sstevel@tonic-gate 	case RDR_CONF_CHANGE_STATE: {
10670Sstevel@tonic-gate 
10680Sstevel@tonic-gate 		change_state_params_t *cparam;
10690Sstevel@tonic-gate 		cparam = (change_state_params_t *)param;
10700Sstevel@tonic-gate 
10710Sstevel@tonic-gate 		cleanup_ap_ids(cparam->num_ap_ids, (char **)cparam->ap_ids);
10720Sstevel@tonic-gate 		cparam->ap_ids = NULL;
10730Sstevel@tonic-gate 		if (cparam->options != NULL) {
10740Sstevel@tonic-gate 			free((void *)cparam->options);
10750Sstevel@tonic-gate 			cparam->options = NULL;
10760Sstevel@tonic-gate 		}
10770Sstevel@tonic-gate 		if (cparam->confp != NULL) {
10780Sstevel@tonic-gate 			free((void *)cparam->confp);
10790Sstevel@tonic-gate 			cparam->confp = NULL;
10800Sstevel@tonic-gate 		}
10810Sstevel@tonic-gate 		if (cparam->msgp != NULL) {
10820Sstevel@tonic-gate 			free((void *)cparam->msgp);
10830Sstevel@tonic-gate 			cparam->msgp = NULL;
10840Sstevel@tonic-gate 		}
10850Sstevel@tonic-gate 		cleanup_errstring(cparam->errstring);
10860Sstevel@tonic-gate 		break;
10870Sstevel@tonic-gate 	}
10880Sstevel@tonic-gate 
10890Sstevel@tonic-gate 	case RDR_CONF_PRIVATE_FUNC: {
10900Sstevel@tonic-gate 
10910Sstevel@tonic-gate 		private_func_params_t *pparam;
10920Sstevel@tonic-gate 		pparam = (private_func_params_t *)param;
10930Sstevel@tonic-gate 
10940Sstevel@tonic-gate 		cleanup_ap_ids(pparam->num_ap_ids, (char **)pparam->ap_ids);
10950Sstevel@tonic-gate 		pparam->ap_ids = NULL;
10960Sstevel@tonic-gate 		if (pparam->options != NULL) {
10970Sstevel@tonic-gate 			free((void *)pparam->options);
10980Sstevel@tonic-gate 			pparam->options = NULL;
10990Sstevel@tonic-gate 		}
11000Sstevel@tonic-gate 		if (pparam->confp != NULL) {
11010Sstevel@tonic-gate 			free((void *)pparam->confp);
11020Sstevel@tonic-gate 			pparam->confp = NULL;
11030Sstevel@tonic-gate 		}
11040Sstevel@tonic-gate 		if (pparam->msgp != NULL) {
11050Sstevel@tonic-gate 			free((void *)pparam->msgp);
11060Sstevel@tonic-gate 			pparam->msgp = NULL;
11070Sstevel@tonic-gate 		}
11080Sstevel@tonic-gate 		cleanup_errstring(pparam->errstring);
11090Sstevel@tonic-gate 		break;
11100Sstevel@tonic-gate 	}
11110Sstevel@tonic-gate 
11120Sstevel@tonic-gate 	case RDR_CONF_TEST: {
11130Sstevel@tonic-gate 
11140Sstevel@tonic-gate 		test_params_t *tparam;
11150Sstevel@tonic-gate 		tparam = (test_params_t *)param;
11160Sstevel@tonic-gate 
11170Sstevel@tonic-gate 		cleanup_ap_ids(tparam->num_ap_ids, (char **)tparam->ap_ids);
11180Sstevel@tonic-gate 		tparam->ap_ids = NULL;
11190Sstevel@tonic-gate 		if (tparam->options != NULL) {
11200Sstevel@tonic-gate 			free((void *)tparam->options);
11210Sstevel@tonic-gate 			tparam->options = NULL;
11220Sstevel@tonic-gate 		}
11230Sstevel@tonic-gate 		if (tparam->msgp != NULL) {
11240Sstevel@tonic-gate 			free((void *)tparam->msgp);
11250Sstevel@tonic-gate 			tparam->msgp = NULL;
11260Sstevel@tonic-gate 		}
11270Sstevel@tonic-gate 		cleanup_errstring(tparam->errstring);
11280Sstevel@tonic-gate 		break;
11290Sstevel@tonic-gate 	}
11300Sstevel@tonic-gate 
11310Sstevel@tonic-gate 	case RDR_CONF_LIST_EXT: {
11320Sstevel@tonic-gate 
11330Sstevel@tonic-gate 		list_ext_params_t *lparam;
11340Sstevel@tonic-gate 		lparam = (list_ext_params_t *)param;
11350Sstevel@tonic-gate 
11360Sstevel@tonic-gate 		cleanup_ap_ids(lparam->num_ap_ids, (char **)lparam->ap_ids);
11370Sstevel@tonic-gate 		lparam->ap_ids = NULL;
11380Sstevel@tonic-gate 
11390Sstevel@tonic-gate 		if (lparam->nlist != NULL) {
11400Sstevel@tonic-gate 			free((void *)lparam->nlist);
11410Sstevel@tonic-gate 			lparam->nlist = NULL;
11420Sstevel@tonic-gate 		}
11430Sstevel@tonic-gate 		if (lparam->ap_id_list != NULL) {
11440Sstevel@tonic-gate 			if (*lparam->ap_id_list != NULL) {
11450Sstevel@tonic-gate 				free((void *)*lparam->ap_id_list);
11460Sstevel@tonic-gate 			}
11470Sstevel@tonic-gate 			free((void *)lparam->ap_id_list);
11480Sstevel@tonic-gate 			lparam->ap_id_list = NULL;
11490Sstevel@tonic-gate 		}
11500Sstevel@tonic-gate 		if (lparam->ap_id_list != NULL) {
11510Sstevel@tonic-gate 			free((void *)lparam->ap_id_list);
11520Sstevel@tonic-gate 			lparam->ap_id_list = NULL;
11530Sstevel@tonic-gate 		}
11540Sstevel@tonic-gate 
11550Sstevel@tonic-gate 		if (lparam->options != NULL) {
11560Sstevel@tonic-gate 			free((void *)lparam->options);
11570Sstevel@tonic-gate 			lparam->options = NULL;
11580Sstevel@tonic-gate 		}
11590Sstevel@tonic-gate 		if (lparam->listopts != NULL) {
11600Sstevel@tonic-gate 			free((void *)lparam->listopts);
11610Sstevel@tonic-gate 			lparam->listopts = NULL;
11620Sstevel@tonic-gate 		}
11630Sstevel@tonic-gate 		cleanup_errstring(lparam->errstring);
11640Sstevel@tonic-gate 		break;
11650Sstevel@tonic-gate 	}
11660Sstevel@tonic-gate 
11670Sstevel@tonic-gate 	case RDR_CONF_HELP: {
11680Sstevel@tonic-gate 
11690Sstevel@tonic-gate 		help_params_t *hparam;
11700Sstevel@tonic-gate 		hparam = (help_params_t *)param;
11710Sstevel@tonic-gate 
11720Sstevel@tonic-gate 		cleanup_ap_ids(hparam->num_ap_ids, (char **)hparam->ap_ids);
11730Sstevel@tonic-gate 		hparam->ap_ids = NULL;
11740Sstevel@tonic-gate 		if (hparam->msgp != NULL) {
11750Sstevel@tonic-gate 			free((void *)hparam->msgp);
11760Sstevel@tonic-gate 			hparam->msgp = NULL;
11770Sstevel@tonic-gate 		}
11780Sstevel@tonic-gate 		if (hparam->options != NULL) {
11790Sstevel@tonic-gate 			free((void *)hparam->options);
11800Sstevel@tonic-gate 			hparam->options = NULL;
11810Sstevel@tonic-gate 		}
11820Sstevel@tonic-gate 		break;
11830Sstevel@tonic-gate 	}
11840Sstevel@tonic-gate 
11850Sstevel@tonic-gate 	case RDR_CONF_AP_ID_CMP: {
11860Sstevel@tonic-gate 
11870Sstevel@tonic-gate 		ap_id_cmp_params_t *aparam;
11880Sstevel@tonic-gate 		aparam = (ap_id_cmp_params_t *)param;
11890Sstevel@tonic-gate 
11900Sstevel@tonic-gate 		if (aparam->ap_log_id1 != NULL) {
11910Sstevel@tonic-gate 			free((void *)aparam->ap_log_id1);
11920Sstevel@tonic-gate 			aparam->ap_log_id1 = NULL;
11930Sstevel@tonic-gate 		}
11940Sstevel@tonic-gate 		if (aparam->ap_log_id2 != NULL) {
11950Sstevel@tonic-gate 			free((void *)aparam->ap_log_id2);
11960Sstevel@tonic-gate 			aparam->ap_log_id2 = NULL;
11970Sstevel@tonic-gate 		}
11980Sstevel@tonic-gate 		break;
11990Sstevel@tonic-gate 	}
12000Sstevel@tonic-gate 
12010Sstevel@tonic-gate 	case RDR_CONF_ABORT_CMD:
12020Sstevel@tonic-gate 
12030Sstevel@tonic-gate 		/* nothing to deallocate */
12040Sstevel@tonic-gate 		break;
12050Sstevel@tonic-gate 
12060Sstevel@tonic-gate 	case RDR_CONF_CONFIRM_CALLBACK: {
12070Sstevel@tonic-gate 
12080Sstevel@tonic-gate 		confirm_callback_params_t *cparam;
12090Sstevel@tonic-gate 		cparam = (confirm_callback_params_t *)param;
12100Sstevel@tonic-gate 
12110Sstevel@tonic-gate 		if (cparam->confp != NULL) {
12120Sstevel@tonic-gate 			free((void *)cparam->confp);
12130Sstevel@tonic-gate 			cparam->confp = NULL;
12140Sstevel@tonic-gate 		}
12150Sstevel@tonic-gate 		if (cparam->message != NULL) {
12160Sstevel@tonic-gate 			free((void *)cparam->message);
12170Sstevel@tonic-gate 			cparam->message = NULL;
12180Sstevel@tonic-gate 		}
12190Sstevel@tonic-gate 		break;
12200Sstevel@tonic-gate 	}
12210Sstevel@tonic-gate 
12220Sstevel@tonic-gate 	case RDR_CONF_MSG_CALLBACK: {
12230Sstevel@tonic-gate 
12240Sstevel@tonic-gate 		msg_callback_params_t *mparam;
12250Sstevel@tonic-gate 		mparam = (msg_callback_params_t *)param;
12260Sstevel@tonic-gate 
12270Sstevel@tonic-gate 		if (mparam->msgp != NULL) {
12280Sstevel@tonic-gate 			free((void *)mparam->msgp);
12290Sstevel@tonic-gate 			mparam->msgp = NULL;
12300Sstevel@tonic-gate 		}
12310Sstevel@tonic-gate 		if (mparam->message != NULL) {
12320Sstevel@tonic-gate 			free((void *)mparam->message);
12330Sstevel@tonic-gate 			mparam->message = NULL;
12340Sstevel@tonic-gate 		}
12350Sstevel@tonic-gate 		break;
12360Sstevel@tonic-gate 	}
12370Sstevel@tonic-gate 
12380Sstevel@tonic-gate 	default:
12390Sstevel@tonic-gate 		return (RDR_ERROR);
12400Sstevel@tonic-gate 		/* NOTREACHED */
12410Sstevel@tonic-gate 		break;
12420Sstevel@tonic-gate 
12430Sstevel@tonic-gate 	}
12440Sstevel@tonic-gate 
12450Sstevel@tonic-gate 	return (RDR_OK);
12460Sstevel@tonic-gate }
12470Sstevel@tonic-gate 
12481120Smb158278 /*
12491120Smb158278  * rdr_setsockopt:
12501120Smb158278  *
12511120Smb158278  * Wrapper of the setsockopt(3SOCKET) library function.
12521120Smb158278  */
12531120Smb158278 int
rdr_setsockopt(int fd,int level,int optname,const void * optval,int optlen)12541120Smb158278 rdr_setsockopt(int fd, int level, int optname, const void *optval, int optlen)
12551120Smb158278 {
12561120Smb158278 	if (setsockopt(fd, level, optname, optval, optlen) == -1)
12571120Smb158278 		return (RDR_NET_ERR);
12581120Smb158278 	else
12591120Smb158278 		return (RDR_OK);
12601120Smb158278 }
12611120Smb158278 
12620Sstevel@tonic-gate 
12630Sstevel@tonic-gate /*
12640Sstevel@tonic-gate  * Private (static) Functions
12650Sstevel@tonic-gate  */
12660Sstevel@tonic-gate 
12670Sstevel@tonic-gate 
12680Sstevel@tonic-gate /*
12690Sstevel@tonic-gate  * rdr_setopt:
12700Sstevel@tonic-gate  *
12710Sstevel@tonic-gate  * Set the specified option for a given transport endpoint.
12720Sstevel@tonic-gate  * This function only sets boolean options. It does not
12730Sstevel@tonic-gate  * provide the ability to unset an option, or set a non-
12740Sstevel@tonic-gate  * boolean option.
12750Sstevel@tonic-gate  */
12760Sstevel@tonic-gate static int
rdr_setopt(int fd,int name,int level)12770Sstevel@tonic-gate rdr_setopt(int fd, int name, int level)
12780Sstevel@tonic-gate {
12790Sstevel@tonic-gate 	int	on = 1;
12800Sstevel@tonic-gate 
12810Sstevel@tonic-gate 
12820Sstevel@tonic-gate 	if (setsockopt(fd, level, name, &on, sizeof (on)) == -1) {
12830Sstevel@tonic-gate 		return (RDR_NET_ERR);
12840Sstevel@tonic-gate 	}
12850Sstevel@tonic-gate 
12860Sstevel@tonic-gate 	return (RDR_OK);
12870Sstevel@tonic-gate }
12880Sstevel@tonic-gate 
12890Sstevel@tonic-gate 
12900Sstevel@tonic-gate /*
12910Sstevel@tonic-gate  * rdr_bind:
12920Sstevel@tonic-gate  *
12930Sstevel@tonic-gate  * Bind the specified file descriptor to a specified
12940Sstevel@tonic-gate  * address. If the address is already bound, no error is
12950Sstevel@tonic-gate  * returned. This is the expected behavior if a server
12960Sstevel@tonic-gate  * has been started by inetd (1M).
12970Sstevel@tonic-gate  */
12980Sstevel@tonic-gate static int
rdr_bind(int fd,struct sockaddr * addr)12990Sstevel@tonic-gate rdr_bind(int fd, struct sockaddr *addr)
13000Sstevel@tonic-gate {
13010Sstevel@tonic-gate 	unsigned int		addr_len;
13020Sstevel@tonic-gate 	int			rc;
13030Sstevel@tonic-gate 
13040Sstevel@tonic-gate 
13050Sstevel@tonic-gate 	/* initialize the address */
13060Sstevel@tonic-gate 	switch (addr->sa_family) {
13070Sstevel@tonic-gate 
13080Sstevel@tonic-gate 	case AF_INET:
13090Sstevel@tonic-gate 		addr_len = sizeof (struct sockaddr_in);
13100Sstevel@tonic-gate 		break;
13110Sstevel@tonic-gate 
13120Sstevel@tonic-gate 	case AF_INET6:
13130Sstevel@tonic-gate 		addr_len = sizeof (struct sockaddr_in6);
13140Sstevel@tonic-gate 		break;
13150Sstevel@tonic-gate 
13160Sstevel@tonic-gate 	default:
13170Sstevel@tonic-gate 		return (RDR_ERROR);
13180Sstevel@tonic-gate 	}
13190Sstevel@tonic-gate 
13200Sstevel@tonic-gate 	/* attempt to bind the address */
13210Sstevel@tonic-gate 	rc = bind(fd, addr, addr_len);
13220Sstevel@tonic-gate 
13230Sstevel@tonic-gate 	/*
13240Sstevel@tonic-gate 	 * Ignore the error if EINVAL is returned. In
13250Sstevel@tonic-gate 	 * this case, we assume that this means that
13260Sstevel@tonic-gate 	 * the address was already bound. This is not
13270Sstevel@tonic-gate 	 * an error for servers started by inetd (1M).
13280Sstevel@tonic-gate 	 */
13290Sstevel@tonic-gate 	if ((rc == -1) && (errno != EINVAL)) {
13300Sstevel@tonic-gate 		return (RDR_NET_ERR);
13310Sstevel@tonic-gate 	}
13320Sstevel@tonic-gate 
13330Sstevel@tonic-gate 	/*
13340Sstevel@tonic-gate 	 * Retreive the address information of the
13350Sstevel@tonic-gate 	 * address that was actually bound.
13360Sstevel@tonic-gate 	 */
13370Sstevel@tonic-gate 	addr_len = sizeof (*addr);
13380Sstevel@tonic-gate 	if (getsockname(fd, addr, &addr_len) == -1) {
13390Sstevel@tonic-gate 		(void) memset(addr, 0, sizeof (*addr));
13400Sstevel@tonic-gate 		return (RDR_NET_ERR);
13410Sstevel@tonic-gate 	}
13420Sstevel@tonic-gate 
13430Sstevel@tonic-gate 	return (RDR_OK);
13440Sstevel@tonic-gate }
13450Sstevel@tonic-gate 
13460Sstevel@tonic-gate 
13470Sstevel@tonic-gate /*
1348*1772Sjl139090  * rdr_secure:
1349*1772Sjl139090  *
1350*1772Sjl139090  * Activate security features for a socket.
1351*1772Sjl139090  *
1352*1772Sjl139090  * Some platforms have libdscp, which provides additional
1353*1772Sjl139090  * security features.  An attempt is made to load libdscp
1354*1772Sjl139090  * and use these features.
1355*1772Sjl139090  *
1356*1772Sjl139090  * Nothing is done if libdscp is not available.
1357*1772Sjl139090  */
1358*1772Sjl139090 static int
rdr_secure(int fd,struct sockaddr * addr)1359*1772Sjl139090 rdr_secure(int fd, struct sockaddr *addr)
1360*1772Sjl139090 {
1361*1772Sjl139090 	struct sockaddr_in	*sin;
1362*1772Sjl139090 	int			port;
1363*1772Sjl139090 	int			error;
1364*1772Sjl139090 
1365*1772Sjl139090 	if (use_libdscp == 0) {
1366*1772Sjl139090 		return (RDR_OK);
1367*1772Sjl139090 	}
1368*1772Sjl139090 
1369*1772Sjl139090 	if (load_libdscp(&libdscp) != 1) {
1370*1772Sjl139090 		return (RDR_ERROR);
1371*1772Sjl139090 	}
1372*1772Sjl139090 
1373*1772Sjl139090 	/* LINTED E_BAD_PTR_CAST_ALIGN */
1374*1772Sjl139090 	sin = (struct sockaddr_in *)addr;
1375*1772Sjl139090 	port = ntohs(sin->sin_port);
1376*1772Sjl139090 	error = libdscp.bind(0, fd, port);
1377*1772Sjl139090 
1378*1772Sjl139090 	if ((error != DSCP_OK) && (error != DSCP_ERROR_ALREADY)) {
1379*1772Sjl139090 		return (RDR_ERROR);
1380*1772Sjl139090 	}
1381*1772Sjl139090 
1382*1772Sjl139090 	if (libdscp.secure(0, fd) != DSCP_OK) {
1383*1772Sjl139090 		return (RDR_ERROR);
1384*1772Sjl139090 	}
1385*1772Sjl139090 	return (RDR_OK);
1386*1772Sjl139090 }
1387*1772Sjl139090 
1388*1772Sjl139090 /*
1389*1772Sjl139090  * rdr_auth:
1390*1772Sjl139090  *
1391*1772Sjl139090  * Authenticate if a connection is really from the service
1392*1772Sjl139090  * processor.  This is dependent upon functionality from
1393*1772Sjl139090  * libdscp, so an attempt to load and use libdscp is made.
1394*1772Sjl139090  *
1395*1772Sjl139090  * Without libdscp, this function does nothing.
1396*1772Sjl139090  */
1397*1772Sjl139090 static int
rdr_auth(struct sockaddr * addr,int len)1398*1772Sjl139090 rdr_auth(struct sockaddr *addr, int len)
1399*1772Sjl139090 {
1400*1772Sjl139090 	if (use_libdscp != 0) {
1401*1772Sjl139090 		if ((load_libdscp(&libdscp) == 0) ||
1402*1772Sjl139090 		    (libdscp.auth(0, addr, len) != DSCP_OK)) {
1403*1772Sjl139090 			return (RDR_ERROR);
1404*1772Sjl139090 		}
1405*1772Sjl139090 	}
1406*1772Sjl139090 
1407*1772Sjl139090 	return (RDR_OK);
1408*1772Sjl139090 }
1409*1772Sjl139090 
1410*1772Sjl139090 /*
14110Sstevel@tonic-gate  * rdr_snd:
14120Sstevel@tonic-gate  *
14130Sstevel@tonic-gate  * Send a message in two stages. First the header is sent,
14140Sstevel@tonic-gate  * followed by the packed buffer containing the message
14150Sstevel@tonic-gate  * contents.
14160Sstevel@tonic-gate  */
14170Sstevel@tonic-gate static int
rdr_snd(int fd,rdr_msg_hdr_t * hdr,char * data,int data_sz,int timeout)14180Sstevel@tonic-gate rdr_snd(int fd, rdr_msg_hdr_t *hdr, char *data, int data_sz, int timeout)
14190Sstevel@tonic-gate {
14200Sstevel@tonic-gate 	int	err;
14210Sstevel@tonic-gate 
14220Sstevel@tonic-gate 
14230Sstevel@tonic-gate 	/* sanity check */
14240Sstevel@tonic-gate 	if (hdr == NULL) {
14250Sstevel@tonic-gate 		return (RDR_ERROR);
14260Sstevel@tonic-gate 	}
14270Sstevel@tonic-gate 
14280Sstevel@tonic-gate 	/* ensure null pad bytes */
14290Sstevel@tonic-gate 	hdr->pad_byte1 = 0;
14300Sstevel@tonic-gate 	hdr->pad_byte2 = 0;
14310Sstevel@tonic-gate 
14320Sstevel@tonic-gate 	/* initialize size information */
14330Sstevel@tonic-gate 	hdr->data_length = data_sz;
14340Sstevel@tonic-gate 
14350Sstevel@tonic-gate 	/* send message header */
14360Sstevel@tonic-gate 	err = rdr_snd_raw(fd, (char *)hdr, RDR_MSG_HDR_SIZE, timeout);
14370Sstevel@tonic-gate 	if (err != RDR_OK) {
14380Sstevel@tonic-gate 		return (err);
14390Sstevel@tonic-gate 	}
14400Sstevel@tonic-gate 
14410Sstevel@tonic-gate 	/* check if more to send */
14420Sstevel@tonic-gate 	if (data_sz == 0) {
14430Sstevel@tonic-gate 		return (RDR_OK);
14440Sstevel@tonic-gate 	}
14450Sstevel@tonic-gate 
14460Sstevel@tonic-gate 	/* send message data */
14470Sstevel@tonic-gate 	err = rdr_snd_raw(fd, data, data_sz, timeout);
14480Sstevel@tonic-gate 	if (err != RDR_OK) {
14490Sstevel@tonic-gate 		return (err);
14500Sstevel@tonic-gate 	}
14510Sstevel@tonic-gate 
14520Sstevel@tonic-gate 	return (RDR_OK);
14530Sstevel@tonic-gate }
14540Sstevel@tonic-gate 
14550Sstevel@tonic-gate 
14560Sstevel@tonic-gate /*
14570Sstevel@tonic-gate  * rdr_snd_raw:
14580Sstevel@tonic-gate  *
14590Sstevel@tonic-gate  * Send a raw buffer of information. This function handles
14600Sstevel@tonic-gate  * the low level details of the send operation.
14610Sstevel@tonic-gate  */
14620Sstevel@tonic-gate static int
rdr_snd_raw(int fd,char * msg,int data_sz,int timeout)14630Sstevel@tonic-gate rdr_snd_raw(int fd, char *msg, int data_sz, int timeout)
14640Sstevel@tonic-gate {
14650Sstevel@tonic-gate 	int		err;
14660Sstevel@tonic-gate 	int		num_bytes;
14670Sstevel@tonic-gate 	int		bytes_left;
14680Sstevel@tonic-gate 	char		*bufp;
14690Sstevel@tonic-gate 	struct pollfd	pfd;
14700Sstevel@tonic-gate 
14710Sstevel@tonic-gate 
14720Sstevel@tonic-gate 	bufp = (char *)msg;
14730Sstevel@tonic-gate 
14740Sstevel@tonic-gate 	bytes_left = data_sz;
14750Sstevel@tonic-gate 
14760Sstevel@tonic-gate 	pfd.fd = fd;
14770Sstevel@tonic-gate 	pfd.events = POLLOUT;
14780Sstevel@tonic-gate 
14790Sstevel@tonic-gate 	while (bytes_left > 0) {
14800Sstevel@tonic-gate 
14810Sstevel@tonic-gate 		pfd.revents = 0;
14820Sstevel@tonic-gate 
14830Sstevel@tonic-gate 		/* wait until we can send the data */
14840Sstevel@tonic-gate 		if ((err = poll(&pfd, 1, timeout)) == -1) {
14850Sstevel@tonic-gate 
14860Sstevel@tonic-gate 			/* poll was interrupted */
14870Sstevel@tonic-gate 			if (errno == EINTR) {
14880Sstevel@tonic-gate 				return (RDR_ABORTED);
14890Sstevel@tonic-gate 			}
14900Sstevel@tonic-gate 
14910Sstevel@tonic-gate 			return (RDR_ERROR);
14920Sstevel@tonic-gate 
14930Sstevel@tonic-gate 		} else if (err == 0) {
14940Sstevel@tonic-gate 			return (RDR_TIMEOUT);
14950Sstevel@tonic-gate 		}
14960Sstevel@tonic-gate 
14970Sstevel@tonic-gate 		/* ready to send data */
14980Sstevel@tonic-gate 		if (pfd.revents & POLLOUT) {
14990Sstevel@tonic-gate 
15000Sstevel@tonic-gate 			num_bytes = write(fd, bufp, bytes_left);
15010Sstevel@tonic-gate 
15020Sstevel@tonic-gate 			if (num_bytes == -1) {
15030Sstevel@tonic-gate 
15040Sstevel@tonic-gate 				/*
15050Sstevel@tonic-gate 				 * Distinguish between an aborted
15060Sstevel@tonic-gate 				 * session and other network errors.
15070Sstevel@tonic-gate 				 */
15080Sstevel@tonic-gate 				if (errno == EPIPE) {
15090Sstevel@tonic-gate 					return (RDR_ABORTED);
15100Sstevel@tonic-gate 				} else {
15110Sstevel@tonic-gate 					return (RDR_NET_ERR);
15120Sstevel@tonic-gate 				}
15130Sstevel@tonic-gate 			}
15140Sstevel@tonic-gate 
15150Sstevel@tonic-gate 			/* wrote 0 bytes, so operation was aborted */
15160Sstevel@tonic-gate 			if (num_bytes == 0) {
15170Sstevel@tonic-gate 				return (RDR_ABORTED);
15180Sstevel@tonic-gate 			}
15190Sstevel@tonic-gate 
15200Sstevel@tonic-gate 		} else {
15210Sstevel@tonic-gate 			return (RDR_NET_ERR);
15220Sstevel@tonic-gate 		}
15230Sstevel@tonic-gate 
15240Sstevel@tonic-gate 		bytes_left -= num_bytes;
15250Sstevel@tonic-gate 		bufp += num_bytes;
15260Sstevel@tonic-gate 	}
15270Sstevel@tonic-gate 
15280Sstevel@tonic-gate 	return (RDR_OK);
15290Sstevel@tonic-gate }
15300Sstevel@tonic-gate 
15310Sstevel@tonic-gate 
15320Sstevel@tonic-gate /*
15330Sstevel@tonic-gate  * rdr_rcv:
15340Sstevel@tonic-gate  *
15350Sstevel@tonic-gate  * Receive a message in two stages. First the header is
15360Sstevel@tonic-gate  * received, followed by the packed buffer containing the
15370Sstevel@tonic-gate  * message contents.
15380Sstevel@tonic-gate  */
15390Sstevel@tonic-gate static int
rdr_rcv(int fd,rdr_msg_hdr_t * hdr,char ** data,int timeout)15400Sstevel@tonic-gate rdr_rcv(int fd, rdr_msg_hdr_t *hdr, char **data, int timeout)
15410Sstevel@tonic-gate {
15420Sstevel@tonic-gate 	int	err;
15430Sstevel@tonic-gate 	int	data_sz;
15440Sstevel@tonic-gate 	char	hdr_buf[RDR_MSG_HDR_SIZE];
15450Sstevel@tonic-gate 	char	*buf = NULL;
15460Sstevel@tonic-gate 
15470Sstevel@tonic-gate 
15480Sstevel@tonic-gate 	/* sanity check */
15490Sstevel@tonic-gate 	if (hdr == NULL) {
15500Sstevel@tonic-gate 		return (RDR_ERROR);
15510Sstevel@tonic-gate 	}
15520Sstevel@tonic-gate 
15530Sstevel@tonic-gate 	/* receive the header */
15540Sstevel@tonic-gate 	err = rdr_rcv_raw(fd, hdr_buf, RDR_MSG_HDR_SIZE, timeout);
15550Sstevel@tonic-gate 	if (err != RDR_OK) {
15560Sstevel@tonic-gate 		return (err);
15570Sstevel@tonic-gate 	}
15580Sstevel@tonic-gate 
15590Sstevel@tonic-gate 	/* verify that the data is good */
15600Sstevel@tonic-gate 	/* LINTED Pointer Cast Alignment Warning */
15610Sstevel@tonic-gate 	if (validate_header((rdr_msg_hdr_t *)hdr_buf) != RDR_OK) {
15620Sstevel@tonic-gate 		return (RDR_MSG_INVAL);
15630Sstevel@tonic-gate 	}
15640Sstevel@tonic-gate 
15650Sstevel@tonic-gate 	/* LINTED Pointer Cast Alignment Warning */
15660Sstevel@tonic-gate 	data_sz = ((rdr_msg_hdr_t *)hdr_buf)->data_length;
15670Sstevel@tonic-gate 
15680Sstevel@tonic-gate 	buf = (char *)malloc(data_sz);
15690Sstevel@tonic-gate 	if (!buf) {
15700Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
15710Sstevel@tonic-gate 	}
15720Sstevel@tonic-gate 
15730Sstevel@tonic-gate 	if (data_sz != 0) {
15740Sstevel@tonic-gate 
15750Sstevel@tonic-gate 		/* receive the rest of the message */
15760Sstevel@tonic-gate 		err = rdr_rcv_raw(fd, buf, data_sz, timeout);
15770Sstevel@tonic-gate 		if (err != RDR_OK) {
15780Sstevel@tonic-gate 			free((void *)buf);
15790Sstevel@tonic-gate 			return (err);
15800Sstevel@tonic-gate 		}
15810Sstevel@tonic-gate 	}
15820Sstevel@tonic-gate 
15830Sstevel@tonic-gate 	/* copy out data */
15840Sstevel@tonic-gate 	*data = buf;
15850Sstevel@tonic-gate 	(void) memcpy(hdr, hdr_buf, RDR_MSG_HDR_SIZE);
15860Sstevel@tonic-gate 
15870Sstevel@tonic-gate 	return (RDR_OK);
15880Sstevel@tonic-gate }
15890Sstevel@tonic-gate 
15900Sstevel@tonic-gate 
15910Sstevel@tonic-gate /*
15920Sstevel@tonic-gate  * rdr_rcv_raw:
15930Sstevel@tonic-gate  *
15940Sstevel@tonic-gate  * Receive a raw buffer of information. This function handles
15950Sstevel@tonic-gate  * the low level details of the receive operation.
15960Sstevel@tonic-gate  */
15970Sstevel@tonic-gate static int
rdr_rcv_raw(int fd,char * msg,int data_size,int timeout)15980Sstevel@tonic-gate rdr_rcv_raw(int fd, char *msg, int data_size, int timeout)
15990Sstevel@tonic-gate {
16000Sstevel@tonic-gate 	int		num_bytes;
16010Sstevel@tonic-gate 	int		err;
16020Sstevel@tonic-gate 	int		bytes_left;
16030Sstevel@tonic-gate 	char		*bufp;
16040Sstevel@tonic-gate 	struct pollfd	pollfd;
16050Sstevel@tonic-gate 
16060Sstevel@tonic-gate 
16070Sstevel@tonic-gate 	bufp = (char *)msg;
16080Sstevel@tonic-gate 	bytes_left = data_size;
16090Sstevel@tonic-gate 
16100Sstevel@tonic-gate 	pollfd.fd = fd;
16110Sstevel@tonic-gate 	pollfd.events = POLLIN;
16120Sstevel@tonic-gate 
16130Sstevel@tonic-gate 	while (bytes_left > 0) {
16140Sstevel@tonic-gate 
16150Sstevel@tonic-gate 		errno = 0;
16160Sstevel@tonic-gate 		pollfd.revents = 0;
16170Sstevel@tonic-gate 
16180Sstevel@tonic-gate 		if ((err = poll(&pollfd, 1, timeout)) == -1) {
16190Sstevel@tonic-gate 
16200Sstevel@tonic-gate 			/*
16210Sstevel@tonic-gate 			 * In the DCA, if a session is aborted, SIGINT
16220Sstevel@tonic-gate 			 * is delivered to all active sessions. This
16230Sstevel@tonic-gate 			 * mistakenly causes all sessions waiting in
16240Sstevel@tonic-gate 			 * the poll to be interrupted. So, if EINTR
16250Sstevel@tonic-gate 			 * is returned, it is ignored. If another error
16260Sstevel@tonic-gate 			 * occurs right away, the current session really
16270Sstevel@tonic-gate 			 * was aborted. All other sessions won't encounter
16280Sstevel@tonic-gate 			 * an error and will proceed normally.
16290Sstevel@tonic-gate 			 */
16300Sstevel@tonic-gate 			if ((errno == 0) || (errno == EINTR)) {
16310Sstevel@tonic-gate 				continue;
16320Sstevel@tonic-gate 			}
16330Sstevel@tonic-gate 
16340Sstevel@tonic-gate 			return (RDR_ABORTED);
16350Sstevel@tonic-gate 
16360Sstevel@tonic-gate 		} else if (err == 0) {
16370Sstevel@tonic-gate 			return (RDR_TIMEOUT);
16380Sstevel@tonic-gate 		}
16390Sstevel@tonic-gate 
16400Sstevel@tonic-gate 		/* ready to receive data */
16410Sstevel@tonic-gate 		if (pollfd.revents & POLLIN) {
16420Sstevel@tonic-gate 
16430Sstevel@tonic-gate 			num_bytes = read(fd, bufp, bytes_left);
16440Sstevel@tonic-gate 
16450Sstevel@tonic-gate 			if (num_bytes == -1) {
16460Sstevel@tonic-gate 
16470Sstevel@tonic-gate 				/*
16480Sstevel@tonic-gate 				 * Distinguish between an aborted
16490Sstevel@tonic-gate 				 * session and other network errors.
16500Sstevel@tonic-gate 				 */
16510Sstevel@tonic-gate 				if (errno == ECONNRESET) {
16520Sstevel@tonic-gate 					return (RDR_ABORTED);
16530Sstevel@tonic-gate 				} else {
16540Sstevel@tonic-gate 					return (RDR_NET_ERR);
16550Sstevel@tonic-gate 				}
16560Sstevel@tonic-gate 			}
16570Sstevel@tonic-gate 
16580Sstevel@tonic-gate 			/* read 0 bytes, so operation was aborted */
16590Sstevel@tonic-gate 			if (num_bytes == 0) {
16600Sstevel@tonic-gate 				return (RDR_ABORTED);
16610Sstevel@tonic-gate 			}
16620Sstevel@tonic-gate 
16630Sstevel@tonic-gate 		} else {
16640Sstevel@tonic-gate 			return (RDR_NET_ERR);
16650Sstevel@tonic-gate 		}
16660Sstevel@tonic-gate 
16670Sstevel@tonic-gate 		bytes_left -= num_bytes;
16680Sstevel@tonic-gate 		bufp += num_bytes;
16690Sstevel@tonic-gate 	}
16700Sstevel@tonic-gate 
16710Sstevel@tonic-gate 	return (RDR_OK);
16720Sstevel@tonic-gate }
16730Sstevel@tonic-gate 
16740Sstevel@tonic-gate 
16750Sstevel@tonic-gate /*
16760Sstevel@tonic-gate  * validate_header:
16770Sstevel@tonic-gate  *
16780Sstevel@tonic-gate  * Perform a series of sanity checks on the header data that is
16790Sstevel@tonic-gate  * received. This gets called before the variable length data is
16800Sstevel@tonic-gate  * read in to make sure that the information in the header can
16810Sstevel@tonic-gate  * be trusted.
16820Sstevel@tonic-gate  */
16830Sstevel@tonic-gate static int
validate_header(rdr_msg_hdr_t * hdr)16840Sstevel@tonic-gate validate_header(rdr_msg_hdr_t *hdr)
16850Sstevel@tonic-gate {
16860Sstevel@tonic-gate 	unsigned char	op;
16870Sstevel@tonic-gate 
16880Sstevel@tonic-gate 
16890Sstevel@tonic-gate 	if (hdr == NULL) {
16900Sstevel@tonic-gate 		return (RDR_ERROR);
16910Sstevel@tonic-gate 	}
16920Sstevel@tonic-gate 
16930Sstevel@tonic-gate 	op = hdr->message_opcode;
16940Sstevel@tonic-gate 
16950Sstevel@tonic-gate 	/* validate opcode */
16960Sstevel@tonic-gate 	if ((op < RDR_SES_REQ) || (op >= RDR_NUM_OPS)) {
16970Sstevel@tonic-gate 		return (RDR_ERROR);
16980Sstevel@tonic-gate 	}
16990Sstevel@tonic-gate 
17000Sstevel@tonic-gate 	/* validate message size (and type) for op */
17010Sstevel@tonic-gate 	switch (hdr->data_type) {
17020Sstevel@tonic-gate 
17030Sstevel@tonic-gate 	case RDR_REQUEST:
17040Sstevel@tonic-gate 		if (hdr->data_length > msg_sizes[op].req_max) {
17050Sstevel@tonic-gate 			return (RDR_ERROR);
17060Sstevel@tonic-gate 		}
17070Sstevel@tonic-gate 		break;
17080Sstevel@tonic-gate 
17090Sstevel@tonic-gate 	case RDR_REPLY:
17100Sstevel@tonic-gate 		if (hdr->data_length > msg_sizes[op].reply_max) {
17110Sstevel@tonic-gate 			return (RDR_ERROR);
17120Sstevel@tonic-gate 		}
17130Sstevel@tonic-gate 		break;
17140Sstevel@tonic-gate 
17150Sstevel@tonic-gate 	default:
17160Sstevel@tonic-gate 		/* invalid data type */
17170Sstevel@tonic-gate 		return (RDR_ERROR);
17180Sstevel@tonic-gate 	}
17190Sstevel@tonic-gate 
17200Sstevel@tonic-gate 	/* all checks passed */
17210Sstevel@tonic-gate 	return (RDR_OK);
17220Sstevel@tonic-gate }
17230Sstevel@tonic-gate 
17240Sstevel@tonic-gate 
17250Sstevel@tonic-gate /*
17260Sstevel@tonic-gate  * pack_ses_req_request:
17270Sstevel@tonic-gate  *
17280Sstevel@tonic-gate  * Handle packing a session request request message.
17290Sstevel@tonic-gate  */
17300Sstevel@tonic-gate static int
pack_ses_req_request(ses_req_params_t * params,char ** buf,int * buf_size)17310Sstevel@tonic-gate pack_ses_req_request(ses_req_params_t *params, char **buf, int *buf_size)
17320Sstevel@tonic-gate {
17330Sstevel@tonic-gate 	char		*bufptr;
17340Sstevel@tonic-gate 	int		locale_str_len;
17350Sstevel@tonic-gate 	rdr_ses_req_t	ses_req;
17360Sstevel@tonic-gate 
17370Sstevel@tonic-gate 
17380Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
17390Sstevel@tonic-gate 		return (RDR_ERROR);
17400Sstevel@tonic-gate 	}
17410Sstevel@tonic-gate 
17420Sstevel@tonic-gate 	/*
17430Sstevel@tonic-gate 	 * Determine the size of the locale string
17440Sstevel@tonic-gate 	 */
17450Sstevel@tonic-gate 	if (params->locale_str != NULL) {
17460Sstevel@tonic-gate 		locale_str_len = strlen(params->locale_str) + 1;
17470Sstevel@tonic-gate 	} else {
17480Sstevel@tonic-gate 		locale_str_len = 0;
17490Sstevel@tonic-gate 	}
17500Sstevel@tonic-gate 
17510Sstevel@tonic-gate 	/*
17520Sstevel@tonic-gate 	 * Collect size info specific to the ses_req request message
17530Sstevel@tonic-gate 	 * and allocate a buffer
17540Sstevel@tonic-gate 	 */
17550Sstevel@tonic-gate 	*buf_size = sizeof (rdr_ses_req_t);
17560Sstevel@tonic-gate 	*buf_size += locale_str_len;
17570Sstevel@tonic-gate 
17580Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
17590Sstevel@tonic-gate 	if (*buf == NULL) {
17600Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
17610Sstevel@tonic-gate 	}
17620Sstevel@tonic-gate 
17630Sstevel@tonic-gate 	/*
17640Sstevel@tonic-gate 	 * Set fixed locale size label by name
17650Sstevel@tonic-gate 	 */
17660Sstevel@tonic-gate 	ses_req.locale_size = locale_str_len;
17670Sstevel@tonic-gate 
17680Sstevel@tonic-gate 	/*
17690Sstevel@tonic-gate 	 * Set variable information using memcpy
17700Sstevel@tonic-gate 	 */
17710Sstevel@tonic-gate 	bufptr = *buf;
17720Sstevel@tonic-gate 
17730Sstevel@tonic-gate 	(void) memcpy(bufptr, &ses_req, sizeof (rdr_ses_req_t));
17740Sstevel@tonic-gate 	bufptr += sizeof (rdr_ses_req_t);
17750Sstevel@tonic-gate 
17760Sstevel@tonic-gate 	if (params->locale_str != NULL) {
17770Sstevel@tonic-gate 		(void) memcpy(bufptr, params->locale_str, locale_str_len);
17780Sstevel@tonic-gate 		bufptr += locale_str_len;
17790Sstevel@tonic-gate 	}
17800Sstevel@tonic-gate 
17810Sstevel@tonic-gate 	return (RDR_OK);
17820Sstevel@tonic-gate }
17830Sstevel@tonic-gate 
17840Sstevel@tonic-gate 
17850Sstevel@tonic-gate /*
17860Sstevel@tonic-gate  * unpack_ses_req_request:
17870Sstevel@tonic-gate  *
17880Sstevel@tonic-gate  * Handle unpacking a session request request message.
17890Sstevel@tonic-gate  */
17900Sstevel@tonic-gate static int
unpack_ses_req_request(ses_req_params_t * params,const char * buf)17910Sstevel@tonic-gate unpack_ses_req_request(ses_req_params_t *params, const char *buf)
17920Sstevel@tonic-gate {
17930Sstevel@tonic-gate 	char		*bufptr;
17940Sstevel@tonic-gate 	rdr_ses_req_t	ses_req_data;
17950Sstevel@tonic-gate 
17960Sstevel@tonic-gate 
17970Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
17980Sstevel@tonic-gate 		return (RDR_ERROR);
17990Sstevel@tonic-gate 	}
18000Sstevel@tonic-gate 
18010Sstevel@tonic-gate 	bufptr = (char *)buf;
18020Sstevel@tonic-gate 	(void) memcpy(&ses_req_data, bufptr, sizeof (rdr_ses_req_t));
18030Sstevel@tonic-gate 	bufptr += sizeof (rdr_ses_req_t);
18040Sstevel@tonic-gate 
18050Sstevel@tonic-gate 	/*
18060Sstevel@tonic-gate 	 * handle getting the locale string
18070Sstevel@tonic-gate 	 */
18080Sstevel@tonic-gate 	if (get_string_from_buf(&(params->locale_str),
18090Sstevel@tonic-gate 	    ses_req_data.locale_size, bufptr)) {
18100Sstevel@tonic-gate 		return (RDR_ERROR);
18110Sstevel@tonic-gate 	}
18120Sstevel@tonic-gate 
18130Sstevel@tonic-gate 	return (RDR_OK);
18140Sstevel@tonic-gate }
18150Sstevel@tonic-gate 
18160Sstevel@tonic-gate 
18170Sstevel@tonic-gate /*
18180Sstevel@tonic-gate  * pack_ses_req_reply:
18190Sstevel@tonic-gate  *
18200Sstevel@tonic-gate  * Handle packing a session request reply message.
18210Sstevel@tonic-gate  */
18220Sstevel@tonic-gate static int
pack_ses_req_reply(ses_req_params_t * params,char ** buf,int * buf_size)18230Sstevel@tonic-gate pack_ses_req_reply(ses_req_params_t *params, char **buf, int *buf_size)
18240Sstevel@tonic-gate {
18250Sstevel@tonic-gate 	rdr_ses_req_reply_t	ses_req_reply_data;
18260Sstevel@tonic-gate 
18270Sstevel@tonic-gate 
18280Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
18290Sstevel@tonic-gate 		return (RDR_ERROR);
18300Sstevel@tonic-gate 	}
18310Sstevel@tonic-gate 
18320Sstevel@tonic-gate 	/*
18330Sstevel@tonic-gate 	 * Collect size info specific to the session request reply
18340Sstevel@tonic-gate 	 * message and allocate a buffer
18350Sstevel@tonic-gate 	 */
18360Sstevel@tonic-gate 	*buf_size = sizeof (rdr_ses_req_reply_t);
18370Sstevel@tonic-gate 
18380Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
18390Sstevel@tonic-gate 	if (*buf == NULL) {
18400Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
18410Sstevel@tonic-gate 	}
18420Sstevel@tonic-gate 
18430Sstevel@tonic-gate 	/*
18440Sstevel@tonic-gate 	 * Set fixed session identifier
18450Sstevel@tonic-gate 	 */
18460Sstevel@tonic-gate 	ses_req_reply_data.session_id = params->session_id;
18470Sstevel@tonic-gate 
18480Sstevel@tonic-gate 	/*
18490Sstevel@tonic-gate 	 * Copy information using memcpy
18500Sstevel@tonic-gate 	 */
18510Sstevel@tonic-gate 	(void) memcpy(*buf, &ses_req_reply_data, sizeof (rdr_ses_req_reply_t));
18520Sstevel@tonic-gate 
18530Sstevel@tonic-gate 	return (RDR_OK);
18540Sstevel@tonic-gate }
18550Sstevel@tonic-gate 
18560Sstevel@tonic-gate 
18570Sstevel@tonic-gate /*
18580Sstevel@tonic-gate  * unpack_ses_req_request:
18590Sstevel@tonic-gate  *
18600Sstevel@tonic-gate  * Handle unpacking a session request reply message.
18610Sstevel@tonic-gate  */
18620Sstevel@tonic-gate static int
unpack_ses_req_reply(ses_req_params_t * params,const char * buf)18630Sstevel@tonic-gate unpack_ses_req_reply(ses_req_params_t *params, const char *buf)
18640Sstevel@tonic-gate {
18650Sstevel@tonic-gate 	rdr_ses_req_reply_t	*ses_req_reply_datap;
18660Sstevel@tonic-gate 
18670Sstevel@tonic-gate 
18680Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
18690Sstevel@tonic-gate 		return (RDR_ERROR);
18700Sstevel@tonic-gate 	}
18710Sstevel@tonic-gate 
18720Sstevel@tonic-gate 	/* LINTED Pointer Cast Alignment Warning */
18730Sstevel@tonic-gate 	ses_req_reply_datap = (rdr_ses_req_reply_t *)buf;
18740Sstevel@tonic-gate 
18750Sstevel@tonic-gate 	/*
18760Sstevel@tonic-gate 	 * copy out the session information
18770Sstevel@tonic-gate 	 */
18780Sstevel@tonic-gate 	params->session_id = ses_req_reply_datap->session_id;
18790Sstevel@tonic-gate 
18800Sstevel@tonic-gate 	return (RDR_OK);
18810Sstevel@tonic-gate }
18820Sstevel@tonic-gate 
18830Sstevel@tonic-gate 
18840Sstevel@tonic-gate /*
18850Sstevel@tonic-gate  * pack_change_state_request:
18860Sstevel@tonic-gate  *
18870Sstevel@tonic-gate  * Handle packing a change state request message.
18880Sstevel@tonic-gate  */
18890Sstevel@tonic-gate static int
pack_change_state_request(change_state_params_t * params,char ** buf,int * buf_size)18900Sstevel@tonic-gate pack_change_state_request(change_state_params_t *params, char **buf,
18910Sstevel@tonic-gate     int *buf_size)
18920Sstevel@tonic-gate {
18930Sstevel@tonic-gate 	int				i;
18940Sstevel@tonic-gate 	char				*bufptr;
18950Sstevel@tonic-gate 	rdr_change_state_t		change_state_data;
18960Sstevel@tonic-gate 	rdr_variable_message_info_t	var_msg_info;
18970Sstevel@tonic-gate 
18980Sstevel@tonic-gate 
18990Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
19000Sstevel@tonic-gate 		return (RDR_ERROR);
19010Sstevel@tonic-gate 	}
19020Sstevel@tonic-gate 
19030Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
19040Sstevel@tonic-gate 
19050Sstevel@tonic-gate 	/*
19060Sstevel@tonic-gate 	 * Set variable length fields and make a call to partially
19070Sstevel@tonic-gate 	 * pack it.
19080Sstevel@tonic-gate 	 */
19090Sstevel@tonic-gate 	if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) {
19100Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
19110Sstevel@tonic-gate 		return (RDR_ERROR);
19120Sstevel@tonic-gate 	}
19130Sstevel@tonic-gate 	if (find_options_sizes(params->options, &var_msg_info)) {
19140Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
19150Sstevel@tonic-gate 		return (RDR_ERROR);
19160Sstevel@tonic-gate 	}
19170Sstevel@tonic-gate 
19180Sstevel@tonic-gate 	/*
19190Sstevel@tonic-gate 	 * Collect size info specific to the change_state request
19200Sstevel@tonic-gate 	 * message and allocate a buffer
19210Sstevel@tonic-gate 	 */
19220Sstevel@tonic-gate 	*buf_size = sizeof (rdr_change_state_t);
19230Sstevel@tonic-gate 	*buf_size += var_msg_info.ap_id_int_size;
19240Sstevel@tonic-gate 	*buf_size += var_msg_info.ap_id_char_size;
19250Sstevel@tonic-gate 	*buf_size += var_msg_info.options_strlen;
19260Sstevel@tonic-gate 	*buf_size += var_msg_info.options_pad_sz;
19270Sstevel@tonic-gate 
19280Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
19290Sstevel@tonic-gate 	if (*buf == NULL) {
19300Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
19310Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
19320Sstevel@tonic-gate 	}
19330Sstevel@tonic-gate 
19340Sstevel@tonic-gate 	/*
19350Sstevel@tonic-gate 	 * Set fixed address labels by name
19360Sstevel@tonic-gate 	 */
19370Sstevel@tonic-gate 	change_state_data.num_ap_ids = params->num_ap_ids;
19380Sstevel@tonic-gate 	change_state_data.ap_id_char_size = var_msg_info.ap_id_char_size;
19390Sstevel@tonic-gate 	change_state_data.options_size = var_msg_info.options_strlen +
19400Sstevel@tonic-gate 	    var_msg_info.options_pad_sz;
19410Sstevel@tonic-gate 
19420Sstevel@tonic-gate 	if (params->confp != NULL) {
19430Sstevel@tonic-gate 		change_state_data.confirm_callback_id =
19440Sstevel@tonic-gate 		    (unsigned long)params->confp->confirm;
19450Sstevel@tonic-gate 		change_state_data.confirm_appdata_ptr =
19460Sstevel@tonic-gate 		    (unsigned long)params->confp->appdata_ptr;
19470Sstevel@tonic-gate 	} else {
19480Sstevel@tonic-gate 		change_state_data.confirm_callback_id = 0;
19490Sstevel@tonic-gate 		change_state_data.confirm_appdata_ptr = 0;
19500Sstevel@tonic-gate 	}
19510Sstevel@tonic-gate 	if (params->msgp != NULL) {
19520Sstevel@tonic-gate 		change_state_data.msg_callback_id =
19530Sstevel@tonic-gate 		    (unsigned long)params->msgp->message_routine;
19540Sstevel@tonic-gate 		change_state_data.msg_appdata_ptr =
19550Sstevel@tonic-gate 		    (unsigned long)params->msgp->appdata_ptr;
19560Sstevel@tonic-gate 	} else {
19570Sstevel@tonic-gate 		change_state_data.msg_callback_id = 0;
19580Sstevel@tonic-gate 		change_state_data.msg_appdata_ptr = 0;
19590Sstevel@tonic-gate 	}
19600Sstevel@tonic-gate 
19610Sstevel@tonic-gate 	change_state_data.flags = params->flags;
19620Sstevel@tonic-gate 	change_state_data.timeval = params->timeval;
19630Sstevel@tonic-gate 	change_state_data.state_change_cmd = params->state_change;
19640Sstevel@tonic-gate 	if (params->errstring != NULL) {
19650Sstevel@tonic-gate 		change_state_data.error_msg_ctl = RDR_GENERATE_ERR_MSGS;
19660Sstevel@tonic-gate 	} else {
19670Sstevel@tonic-gate 		change_state_data.error_msg_ctl = RDR_DONT_GENERATE_ERR_MSGS;
19680Sstevel@tonic-gate 	}
19690Sstevel@tonic-gate 	change_state_data.retries = params->retries;
19700Sstevel@tonic-gate 
19710Sstevel@tonic-gate 	/*
19720Sstevel@tonic-gate 	 * Set variable information using memcpy
19730Sstevel@tonic-gate 	 */
19740Sstevel@tonic-gate 	bufptr = *buf;
19750Sstevel@tonic-gate 
19760Sstevel@tonic-gate 	(void) memcpy(bufptr, &change_state_data, sizeof (rdr_change_state_t));
19770Sstevel@tonic-gate 	bufptr += sizeof (rdr_change_state_t);
19780Sstevel@tonic-gate 
19790Sstevel@tonic-gate 	if (var_msg_info.ap_id_sizes != NULL) {
19800Sstevel@tonic-gate 		(void) memcpy(bufptr, var_msg_info.ap_id_sizes,
19810Sstevel@tonic-gate 		    var_msg_info.ap_id_int_size);
19820Sstevel@tonic-gate 		bufptr += var_msg_info.ap_id_int_size;
19830Sstevel@tonic-gate 	}
19840Sstevel@tonic-gate 
19850Sstevel@tonic-gate 	if (var_msg_info.ap_id_chars != NULL) {
19860Sstevel@tonic-gate 		(void) memcpy(bufptr, var_msg_info.ap_id_chars,
19870Sstevel@tonic-gate 		    var_msg_info.ap_id_char_size);
19880Sstevel@tonic-gate 		bufptr += var_msg_info.ap_id_char_size;
19890Sstevel@tonic-gate 	}
19900Sstevel@tonic-gate 
19910Sstevel@tonic-gate 	if (params->options != NULL) {
19920Sstevel@tonic-gate 		(void) memcpy(bufptr, params->options,
19930Sstevel@tonic-gate 		    var_msg_info.options_strlen);
19940Sstevel@tonic-gate 		bufptr += var_msg_info.options_strlen;
19950Sstevel@tonic-gate 		for (i = 0; i < var_msg_info.options_pad_sz; i++) {
19960Sstevel@tonic-gate 			bufptr[i] = 0;
19970Sstevel@tonic-gate 		}
19980Sstevel@tonic-gate 		bufptr += var_msg_info.options_pad_sz;
19990Sstevel@tonic-gate 	}
20000Sstevel@tonic-gate 
20010Sstevel@tonic-gate 	cleanup_variable_ap_id_info(&var_msg_info);
20020Sstevel@tonic-gate 
20030Sstevel@tonic-gate 	return (RDR_OK);
20040Sstevel@tonic-gate }
20050Sstevel@tonic-gate 
20060Sstevel@tonic-gate 
20070Sstevel@tonic-gate /*
20080Sstevel@tonic-gate  * unpack_change_state_request:
20090Sstevel@tonic-gate  *
20100Sstevel@tonic-gate  * Handle unpacking a change state request message.
20110Sstevel@tonic-gate  */
20120Sstevel@tonic-gate static int
unpack_change_state_request(change_state_params_t * params,const char * buf)20130Sstevel@tonic-gate unpack_change_state_request(change_state_params_t *params, const char *buf)
20140Sstevel@tonic-gate {
20150Sstevel@tonic-gate 	char				*bufptr;
20160Sstevel@tonic-gate 	rdr_variable_message_info_t 	var_msg_info;
20170Sstevel@tonic-gate 	rdr_change_state_t		change_state_data;
20180Sstevel@tonic-gate 
20190Sstevel@tonic-gate 
20200Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
20210Sstevel@tonic-gate 		return (RDR_ERROR);
20220Sstevel@tonic-gate 	}
20230Sstevel@tonic-gate 
20240Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
20250Sstevel@tonic-gate 
20260Sstevel@tonic-gate 	bufptr = (char *)buf;
20270Sstevel@tonic-gate 	(void) memcpy(&change_state_data, bufptr, sizeof (rdr_change_state_t));
20280Sstevel@tonic-gate 	bufptr += sizeof (rdr_change_state_t);
20290Sstevel@tonic-gate 
20300Sstevel@tonic-gate 	/*
20310Sstevel@tonic-gate 	 * handle getting the ap_ids
20320Sstevel@tonic-gate 	 */
20330Sstevel@tonic-gate 	var_msg_info.ap_id_char_size = change_state_data.ap_id_char_size;
20340Sstevel@tonic-gate 	if (get_ap_ids_from_buf((char ***)&(params->ap_ids),
20350Sstevel@tonic-gate 	    change_state_data.num_ap_ids, &var_msg_info, bufptr)) {
20360Sstevel@tonic-gate 		return (RDR_ERROR);
20370Sstevel@tonic-gate 	}
20380Sstevel@tonic-gate 	bufptr += var_msg_info.ap_id_int_size;
20390Sstevel@tonic-gate 	bufptr += var_msg_info.ap_id_char_size;
20400Sstevel@tonic-gate 
20410Sstevel@tonic-gate 	/*
20420Sstevel@tonic-gate 	 * handle getting the options
20430Sstevel@tonic-gate 	 */
20440Sstevel@tonic-gate 	if (get_string_from_buf(&(params->options),
20450Sstevel@tonic-gate 	    change_state_data.options_size, bufptr)) {
20460Sstevel@tonic-gate 		return (RDR_ERROR);
20470Sstevel@tonic-gate 	}
20480Sstevel@tonic-gate 	bufptr += change_state_data.options_size;
20490Sstevel@tonic-gate 
20500Sstevel@tonic-gate 	/*
20510Sstevel@tonic-gate 	 * Set fixed address labels by name
20520Sstevel@tonic-gate 	 */
20530Sstevel@tonic-gate 	params->state_change = (cfga_cmd_t)change_state_data.state_change_cmd;
20540Sstevel@tonic-gate 	params->num_ap_ids = change_state_data.num_ap_ids;
20550Sstevel@tonic-gate 
20560Sstevel@tonic-gate 	params->confp = (struct cfga_confirm *)
20570Sstevel@tonic-gate 	    malloc(sizeof (struct cfga_confirm));
20580Sstevel@tonic-gate 	if (params->confp == NULL) {
20590Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
20600Sstevel@tonic-gate 	}
20610Sstevel@tonic-gate 
20620Sstevel@tonic-gate 	/* set params->confp->confirm using memcpy */
20630Sstevel@tonic-gate 	(void) memcpy((void*)params->confp,
20640Sstevel@tonic-gate 	    &(change_state_data.confirm_callback_id), sizeof (unsigned long));
20650Sstevel@tonic-gate 	params->confp->appdata_ptr =
20660Sstevel@tonic-gate 	    (void*)change_state_data.confirm_appdata_ptr;
20670Sstevel@tonic-gate 
20680Sstevel@tonic-gate 	params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg));
20690Sstevel@tonic-gate 	if (params->msgp == NULL) {
20700Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
20710Sstevel@tonic-gate 	}
20720Sstevel@tonic-gate 
20730Sstevel@tonic-gate 	/* set params->msgp->message_routine using memcpy */
20740Sstevel@tonic-gate 	(void) memcpy((void*)params->msgp,
20750Sstevel@tonic-gate 	    &(change_state_data.msg_callback_id), sizeof (unsigned long));
20760Sstevel@tonic-gate 	params->msgp->appdata_ptr =
20770Sstevel@tonic-gate 	    (void*)change_state_data.msg_appdata_ptr;
20780Sstevel@tonic-gate 
20790Sstevel@tonic-gate 	if (change_state_data.error_msg_ctl == RDR_GENERATE_ERR_MSGS) {
20800Sstevel@tonic-gate 		params->errstring = (char **)malloc(sizeof (char *));
20810Sstevel@tonic-gate 		if (params->errstring == NULL) {
20820Sstevel@tonic-gate 			return (RDR_MEM_ALLOC);
20830Sstevel@tonic-gate 		}
20840Sstevel@tonic-gate 		*(params->errstring) = NULL;
20850Sstevel@tonic-gate 	} else {	/* error_msg_ctl == RDR_DONT_GENERATE_ERR_MSGS */
20860Sstevel@tonic-gate 		params->errstring = NULL;
20870Sstevel@tonic-gate 	}
20880Sstevel@tonic-gate 	params->flags = change_state_data.flags;
20890Sstevel@tonic-gate 	params->timeval = change_state_data.timeval;
20900Sstevel@tonic-gate 	params->retries = change_state_data.retries;
20910Sstevel@tonic-gate 
20920Sstevel@tonic-gate 	return (RDR_OK);
20930Sstevel@tonic-gate }
20940Sstevel@tonic-gate 
20950Sstevel@tonic-gate 
20960Sstevel@tonic-gate /*
20970Sstevel@tonic-gate  * pack_change_state_reply:
20980Sstevel@tonic-gate  *
20990Sstevel@tonic-gate  * Handle packing a change state reply message.
21000Sstevel@tonic-gate  */
21010Sstevel@tonic-gate static int
pack_change_state_reply(change_state_params_t * params,char ** buf,int * buf_size)21020Sstevel@tonic-gate pack_change_state_reply(change_state_params_t *params, char **buf,
21030Sstevel@tonic-gate     int *buf_size)
21040Sstevel@tonic-gate {
21050Sstevel@tonic-gate 	int				i;
21060Sstevel@tonic-gate 	char				*bufptr;
21070Sstevel@tonic-gate 	rdr_change_state_reply_t	change_state_data;
21080Sstevel@tonic-gate 	rdr_variable_message_info_t 	var_msg_info;
21090Sstevel@tonic-gate 
21100Sstevel@tonic-gate 
21110Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
21120Sstevel@tonic-gate 
21130Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
21140Sstevel@tonic-gate 		return (RDR_ERROR);
21150Sstevel@tonic-gate 	}
21160Sstevel@tonic-gate 
21170Sstevel@tonic-gate 	/*
21180Sstevel@tonic-gate 	 * Set variable length fields (size info)
21190Sstevel@tonic-gate 	 */
21200Sstevel@tonic-gate 	if (find_errstring_sizes(params->errstring, &var_msg_info)) {
21210Sstevel@tonic-gate 		return (RDR_ERROR);
21220Sstevel@tonic-gate 	}
21230Sstevel@tonic-gate 
21240Sstevel@tonic-gate 	/*
21250Sstevel@tonic-gate 	 * Collect size info specific to the change_state reply
21260Sstevel@tonic-gate 	 * message and allocate a buffer
21270Sstevel@tonic-gate 	 */
21280Sstevel@tonic-gate 	*buf_size = sizeof (rdr_change_state_reply_t);
21290Sstevel@tonic-gate 	*buf_size += var_msg_info.errstring_strlen;
21300Sstevel@tonic-gate 	*buf_size += var_msg_info.errstring_pad_sz;
21310Sstevel@tonic-gate 
21320Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
21330Sstevel@tonic-gate 	if (*buf == NULL) {
21340Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
21350Sstevel@tonic-gate 	}
21360Sstevel@tonic-gate 
21370Sstevel@tonic-gate 	/*
21380Sstevel@tonic-gate 	 * Set fixed address labels by name
21390Sstevel@tonic-gate 	 */
21400Sstevel@tonic-gate 	change_state_data.errstring_size = var_msg_info.errstring_strlen +
21410Sstevel@tonic-gate 	    var_msg_info.errstring_pad_sz;
21420Sstevel@tonic-gate 
21430Sstevel@tonic-gate 	/*
21440Sstevel@tonic-gate 	 * Set variable information using memcpy
21450Sstevel@tonic-gate 	 */
21460Sstevel@tonic-gate 	bufptr = *buf;
21470Sstevel@tonic-gate 
21480Sstevel@tonic-gate 	(void) memcpy(bufptr, &change_state_data,
21490Sstevel@tonic-gate 	    sizeof (rdr_change_state_reply_t));
21500Sstevel@tonic-gate 	bufptr += sizeof (rdr_change_state_reply_t);
21510Sstevel@tonic-gate 
21520Sstevel@tonic-gate 	if ((params->errstring != NULL) && (*(params->errstring) != NULL)) {
21530Sstevel@tonic-gate 		(void) memcpy(bufptr, *(params->errstring),
21540Sstevel@tonic-gate 		    var_msg_info.errstring_strlen);
21550Sstevel@tonic-gate 		bufptr += var_msg_info.errstring_strlen;
21560Sstevel@tonic-gate 		for (i = 0; i < var_msg_info.errstring_pad_sz; i++) {
21570Sstevel@tonic-gate 			bufptr[i] = 0;
21580Sstevel@tonic-gate 		}
21590Sstevel@tonic-gate 		bufptr += var_msg_info.errstring_pad_sz;
21600Sstevel@tonic-gate 	}
21610Sstevel@tonic-gate 
21620Sstevel@tonic-gate 	return (RDR_OK);
21630Sstevel@tonic-gate }
21640Sstevel@tonic-gate 
21650Sstevel@tonic-gate 
21660Sstevel@tonic-gate /*
21670Sstevel@tonic-gate  * unpack_change_state_reply:
21680Sstevel@tonic-gate  *
21690Sstevel@tonic-gate  * Handle unpacking a change state reply message.
21700Sstevel@tonic-gate  */
21710Sstevel@tonic-gate static int
unpack_change_state_reply(change_state_params_t * params,const char * buf)21720Sstevel@tonic-gate unpack_change_state_reply(change_state_params_t *params, const char *buf)
21730Sstevel@tonic-gate {
21740Sstevel@tonic-gate 	char				*bufptr;
21750Sstevel@tonic-gate 	rdr_change_state_reply_t	change_state_data;
21760Sstevel@tonic-gate 
21770Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
21780Sstevel@tonic-gate 		return (RDR_ERROR);
21790Sstevel@tonic-gate 	}
21800Sstevel@tonic-gate 
21810Sstevel@tonic-gate 	bufptr = (char *)buf;
21820Sstevel@tonic-gate 	(void) memcpy(&change_state_data, bufptr,
21830Sstevel@tonic-gate 	    sizeof (rdr_change_state_reply_t));
21840Sstevel@tonic-gate 	bufptr += sizeof (rdr_change_state_reply_t);
21850Sstevel@tonic-gate 
21860Sstevel@tonic-gate 	/*
21870Sstevel@tonic-gate 	 * handle getting the errstring
21880Sstevel@tonic-gate 	 */
21890Sstevel@tonic-gate 	params->errstring = (char **)malloc(sizeof (char *));
21900Sstevel@tonic-gate 	if (params->errstring == NULL) {
21910Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
21920Sstevel@tonic-gate 	}
21930Sstevel@tonic-gate 	if (get_string_from_buf(params->errstring,
21940Sstevel@tonic-gate 	    change_state_data.errstring_size, bufptr)) {
21950Sstevel@tonic-gate 		return (RDR_ERROR);
21960Sstevel@tonic-gate 	}
21970Sstevel@tonic-gate 	bufptr += change_state_data.errstring_size;
21980Sstevel@tonic-gate 
21990Sstevel@tonic-gate 	return (RDR_OK);
22000Sstevel@tonic-gate }
22010Sstevel@tonic-gate 
22020Sstevel@tonic-gate 
22030Sstevel@tonic-gate /*
22040Sstevel@tonic-gate  * pack_private_func_request:
22050Sstevel@tonic-gate  *
22060Sstevel@tonic-gate  * Handle packing a private function request message.
22070Sstevel@tonic-gate  */
22080Sstevel@tonic-gate static int
pack_private_func_request(private_func_params_t * params,char ** buf,int * buf_size)22090Sstevel@tonic-gate pack_private_func_request(private_func_params_t *params, char **buf,
22100Sstevel@tonic-gate     int *buf_size)
22110Sstevel@tonic-gate {
22120Sstevel@tonic-gate 	int				i;
22130Sstevel@tonic-gate 	char				*bufptr;
22140Sstevel@tonic-gate 	rdr_private_func_t		private_func_data;
22150Sstevel@tonic-gate 	rdr_variable_message_info_t	var_msg_info;
22160Sstevel@tonic-gate 
22170Sstevel@tonic-gate 
22180Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
22190Sstevel@tonic-gate 		return (RDR_ERROR);
22200Sstevel@tonic-gate 	}
22210Sstevel@tonic-gate 
22220Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
22230Sstevel@tonic-gate 
22240Sstevel@tonic-gate 	/*
22250Sstevel@tonic-gate 	 * Set variable length fields and make a call to partially
22260Sstevel@tonic-gate 	 * pack it.
22270Sstevel@tonic-gate 	 */
22280Sstevel@tonic-gate 	if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) {
22290Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
22300Sstevel@tonic-gate 		return (RDR_ERROR);
22310Sstevel@tonic-gate 	}
22320Sstevel@tonic-gate 	if (find_options_sizes(params->options, &var_msg_info)) {
22330Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
22340Sstevel@tonic-gate 		return (RDR_ERROR);
22350Sstevel@tonic-gate 	}
22360Sstevel@tonic-gate 	if (find_function_sizes(params->function, &var_msg_info)) {
22370Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
22380Sstevel@tonic-gate 		return (RDR_ERROR);
22390Sstevel@tonic-gate 	}
22400Sstevel@tonic-gate 
22410Sstevel@tonic-gate 	/*
22420Sstevel@tonic-gate 	 * Collect size info specific to the private_func request
22430Sstevel@tonic-gate 	 * message and allocate a buffer
22440Sstevel@tonic-gate 	 */
22450Sstevel@tonic-gate 	*buf_size = sizeof (rdr_private_func_t);
22460Sstevel@tonic-gate 	*buf_size += var_msg_info.ap_id_int_size;
22470Sstevel@tonic-gate 	*buf_size += var_msg_info.ap_id_char_size;
22480Sstevel@tonic-gate 	*buf_size += var_msg_info.options_strlen;
22490Sstevel@tonic-gate 	*buf_size += var_msg_info.options_pad_sz;
22500Sstevel@tonic-gate 	*buf_size += var_msg_info.function_strlen;
22510Sstevel@tonic-gate 	*buf_size += var_msg_info.function_pad_sz;
22520Sstevel@tonic-gate 
22530Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
22540Sstevel@tonic-gate 	if (*buf == NULL) {
22550Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
22560Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
22570Sstevel@tonic-gate 	}
22580Sstevel@tonic-gate 
22590Sstevel@tonic-gate 	/*
22600Sstevel@tonic-gate 	 * Set fixed address labels by name
22610Sstevel@tonic-gate 	 */
22620Sstevel@tonic-gate 	private_func_data.num_ap_ids = params->num_ap_ids;
22630Sstevel@tonic-gate 	private_func_data.ap_id_char_size = var_msg_info.ap_id_char_size;
22640Sstevel@tonic-gate 	private_func_data.options_size = var_msg_info.options_strlen +
22650Sstevel@tonic-gate 	    var_msg_info.options_pad_sz;
22660Sstevel@tonic-gate 	private_func_data.function_size = var_msg_info.function_strlen +
22670Sstevel@tonic-gate 	    var_msg_info.function_pad_sz;
22680Sstevel@tonic-gate 
22690Sstevel@tonic-gate 	if (params->confp != NULL) {
22700Sstevel@tonic-gate 		private_func_data.confirm_callback_id =
22710Sstevel@tonic-gate 		    (unsigned long)params->confp->confirm;
22720Sstevel@tonic-gate 		private_func_data.confirm_appdata_ptr =
22730Sstevel@tonic-gate 		    (unsigned long)params->confp->appdata_ptr;
22740Sstevel@tonic-gate 	} else {
22750Sstevel@tonic-gate 		private_func_data.confirm_callback_id = 0;
22760Sstevel@tonic-gate 		private_func_data.confirm_appdata_ptr = 0;
22770Sstevel@tonic-gate 	}
22780Sstevel@tonic-gate 	if (params->msgp != NULL) {
22790Sstevel@tonic-gate 		private_func_data.msg_callback_id =
22800Sstevel@tonic-gate 		    (unsigned long)params->msgp->message_routine;
22810Sstevel@tonic-gate 		private_func_data.msg_appdata_ptr =
22820Sstevel@tonic-gate 		    (unsigned long)params->msgp->appdata_ptr;
22830Sstevel@tonic-gate 	} else {
22840Sstevel@tonic-gate 		private_func_data.msg_callback_id = 0;
22850Sstevel@tonic-gate 		private_func_data.msg_appdata_ptr = 0;
22860Sstevel@tonic-gate 	}
22870Sstevel@tonic-gate 
22880Sstevel@tonic-gate 	private_func_data.flags = params->flags;
22890Sstevel@tonic-gate 
22900Sstevel@tonic-gate 	if (params->errstring != NULL) {
22910Sstevel@tonic-gate 		private_func_data.error_msg_ctl = RDR_GENERATE_ERR_MSGS;
22920Sstevel@tonic-gate 	} else {
22930Sstevel@tonic-gate 		private_func_data.error_msg_ctl = RDR_DONT_GENERATE_ERR_MSGS;
22940Sstevel@tonic-gate 	}
22950Sstevel@tonic-gate 
22960Sstevel@tonic-gate 	/*
22970Sstevel@tonic-gate 	 * Set variable information using memcpy
22980Sstevel@tonic-gate 	 */
22990Sstevel@tonic-gate 	bufptr = *buf;
23000Sstevel@tonic-gate 
23010Sstevel@tonic-gate 	(void) memcpy(bufptr, &private_func_data, sizeof (rdr_private_func_t));
23020Sstevel@tonic-gate 	bufptr += sizeof (rdr_private_func_t);
23030Sstevel@tonic-gate 
23040Sstevel@tonic-gate 	if (var_msg_info.ap_id_sizes != NULL) {
23050Sstevel@tonic-gate 		(void) memcpy(bufptr, var_msg_info.ap_id_sizes,
23060Sstevel@tonic-gate 		    var_msg_info.ap_id_int_size);
23070Sstevel@tonic-gate 		bufptr += var_msg_info.ap_id_int_size;
23080Sstevel@tonic-gate 	}
23090Sstevel@tonic-gate 
23100Sstevel@tonic-gate 	if (var_msg_info.ap_id_chars != NULL) {
23110Sstevel@tonic-gate 		(void) memcpy(bufptr, var_msg_info.ap_id_chars,
23120Sstevel@tonic-gate 		    var_msg_info.ap_id_char_size);
23130Sstevel@tonic-gate 		bufptr += var_msg_info.ap_id_char_size;
23140Sstevel@tonic-gate 	}
23150Sstevel@tonic-gate 
23160Sstevel@tonic-gate 	if (params->options != NULL) {
23170Sstevel@tonic-gate 		(void) memcpy(bufptr, params->options,
23180Sstevel@tonic-gate 		    var_msg_info.options_strlen);
23190Sstevel@tonic-gate 		bufptr += var_msg_info.options_strlen;
23200Sstevel@tonic-gate 		for (i = 0; i < var_msg_info.options_pad_sz; i++) {
23210Sstevel@tonic-gate 			bufptr[i] = 0;
23220Sstevel@tonic-gate 		}
23230Sstevel@tonic-gate 		bufptr += var_msg_info.options_pad_sz;
23240Sstevel@tonic-gate 	}
23250Sstevel@tonic-gate 
23260Sstevel@tonic-gate 	if (params->function != NULL) {
23270Sstevel@tonic-gate 		(void) memcpy(bufptr, params->function,
23280Sstevel@tonic-gate 		    var_msg_info.function_strlen);
23290Sstevel@tonic-gate 		bufptr += var_msg_info.function_strlen;
23300Sstevel@tonic-gate 		for (i = 0; i < var_msg_info.function_pad_sz; i++) {
23310Sstevel@tonic-gate 			bufptr[i] = 0;
23320Sstevel@tonic-gate 		}
23330Sstevel@tonic-gate 		bufptr += var_msg_info.function_pad_sz;
23340Sstevel@tonic-gate 	}
23350Sstevel@tonic-gate 
23360Sstevel@tonic-gate 	cleanup_variable_ap_id_info(&var_msg_info);
23370Sstevel@tonic-gate 
23380Sstevel@tonic-gate 	return (RDR_OK);
23390Sstevel@tonic-gate }
23400Sstevel@tonic-gate 
23410Sstevel@tonic-gate 
23420Sstevel@tonic-gate /*
23430Sstevel@tonic-gate  * unpack_private_func_request:
23440Sstevel@tonic-gate  *
23450Sstevel@tonic-gate  * Handle unpacking a private function request message.
23460Sstevel@tonic-gate  */
23470Sstevel@tonic-gate static int
unpack_private_func_request(private_func_params_t * params,const char * buf)23480Sstevel@tonic-gate unpack_private_func_request(private_func_params_t *params, const char *buf)
23490Sstevel@tonic-gate {
23500Sstevel@tonic-gate 	char				*bufptr;
23510Sstevel@tonic-gate 	rdr_variable_message_info_t 	var_msg_info;
23520Sstevel@tonic-gate 	rdr_private_func_t		private_func_data;
23530Sstevel@tonic-gate 
23540Sstevel@tonic-gate 
23550Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
23560Sstevel@tonic-gate 
23570Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
23580Sstevel@tonic-gate 		return (RDR_ERROR);
23590Sstevel@tonic-gate 	}
23600Sstevel@tonic-gate 
23610Sstevel@tonic-gate 	bufptr = (char *)buf;
23620Sstevel@tonic-gate 	(void) memcpy(&private_func_data, bufptr, sizeof (rdr_private_func_t));
23630Sstevel@tonic-gate 	bufptr += sizeof (rdr_private_func_t);
23640Sstevel@tonic-gate 
23650Sstevel@tonic-gate 	/*
23660Sstevel@tonic-gate 	 * handle getting the ap_ids
23670Sstevel@tonic-gate 	 */
23680Sstevel@tonic-gate 	var_msg_info.ap_id_char_size = private_func_data.ap_id_char_size;
23690Sstevel@tonic-gate 	if (get_ap_ids_from_buf((char ***)&(params->ap_ids),
23700Sstevel@tonic-gate 	    private_func_data.num_ap_ids, &var_msg_info, bufptr)) {
23710Sstevel@tonic-gate 		return (RDR_ERROR);
23720Sstevel@tonic-gate 	}
23730Sstevel@tonic-gate 	bufptr += var_msg_info.ap_id_int_size;
23740Sstevel@tonic-gate 	bufptr += var_msg_info.ap_id_char_size;
23750Sstevel@tonic-gate 
23760Sstevel@tonic-gate 	/*
23770Sstevel@tonic-gate 	 * handle getting the options and function
23780Sstevel@tonic-gate 	 */
23790Sstevel@tonic-gate 	if (get_string_from_buf(&(params->options),
23800Sstevel@tonic-gate 	    private_func_data.options_size, bufptr)) {
23810Sstevel@tonic-gate 		return (RDR_ERROR);
23820Sstevel@tonic-gate 	}
23830Sstevel@tonic-gate 	bufptr += private_func_data.options_size;
23840Sstevel@tonic-gate 
23850Sstevel@tonic-gate 	if (get_string_from_buf(&(params->function),
23860Sstevel@tonic-gate 	    private_func_data.function_size, bufptr)) {
23870Sstevel@tonic-gate 		return (RDR_ERROR);
23880Sstevel@tonic-gate 	}
23890Sstevel@tonic-gate 	bufptr += private_func_data.function_size;
23900Sstevel@tonic-gate 
23910Sstevel@tonic-gate 	/*
23920Sstevel@tonic-gate 	 * Set fixed address labels by name
23930Sstevel@tonic-gate 	 */
23940Sstevel@tonic-gate 	params->num_ap_ids = private_func_data.num_ap_ids;
23950Sstevel@tonic-gate 
23960Sstevel@tonic-gate 	params->confp = (struct cfga_confirm *)
23970Sstevel@tonic-gate 	    malloc(sizeof (struct cfga_confirm));
23980Sstevel@tonic-gate 	if (params->confp == NULL) {
23990Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
24000Sstevel@tonic-gate 	}
24010Sstevel@tonic-gate 
24020Sstevel@tonic-gate 	/* set params->confp->confirm using memcpy */
24030Sstevel@tonic-gate 	(void) memcpy((void*)params->confp,
24040Sstevel@tonic-gate 	    &(private_func_data.confirm_callback_id), sizeof (unsigned long));
24050Sstevel@tonic-gate 	params->confp->appdata_ptr =
24060Sstevel@tonic-gate 	    (void*)private_func_data.confirm_appdata_ptr;
24070Sstevel@tonic-gate 
24080Sstevel@tonic-gate 	params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg));
24090Sstevel@tonic-gate 	if (params->msgp == NULL) {
24100Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
24110Sstevel@tonic-gate 	}
24120Sstevel@tonic-gate 
24130Sstevel@tonic-gate 	/* set params->msgp->message_routine using memcpy */
24140Sstevel@tonic-gate 	(void) memcpy((void*)params->msgp,
24150Sstevel@tonic-gate 	    &(private_func_data.msg_callback_id), sizeof (unsigned long));
24160Sstevel@tonic-gate 	params->msgp->appdata_ptr =
24170Sstevel@tonic-gate 	    (void*)private_func_data.msg_appdata_ptr;
24180Sstevel@tonic-gate 
24190Sstevel@tonic-gate 	if (private_func_data.error_msg_ctl == RDR_GENERATE_ERR_MSGS) {
24200Sstevel@tonic-gate 		params->errstring = (char **)malloc(sizeof (char *));
24210Sstevel@tonic-gate 		if (params->errstring == NULL) {
24220Sstevel@tonic-gate 			return (RDR_MEM_ALLOC);
24230Sstevel@tonic-gate 		}
24240Sstevel@tonic-gate 		*(params->errstring) = NULL;
24250Sstevel@tonic-gate 	} else {	/* error_msg_ctl == RDR_DONT_GENERATE_ERR_MSGS */
24260Sstevel@tonic-gate 		params->errstring = NULL;
24270Sstevel@tonic-gate 	}
24280Sstevel@tonic-gate 	params->flags = private_func_data.flags;
24290Sstevel@tonic-gate 
24300Sstevel@tonic-gate 	return (RDR_OK);
24310Sstevel@tonic-gate }
24320Sstevel@tonic-gate 
24330Sstevel@tonic-gate 
24340Sstevel@tonic-gate /*
24350Sstevel@tonic-gate  * pack_private_func_reply:
24360Sstevel@tonic-gate  *
24370Sstevel@tonic-gate  * Handle packing a private function reply message.
24380Sstevel@tonic-gate  */
24390Sstevel@tonic-gate static int
pack_private_func_reply(private_func_params_t * params,char ** buf,int * buf_size)24400Sstevel@tonic-gate pack_private_func_reply(private_func_params_t *params, char **buf,
24410Sstevel@tonic-gate     int *buf_size)
24420Sstevel@tonic-gate {
24430Sstevel@tonic-gate 	int				i;
24440Sstevel@tonic-gate 	char				*bufptr;
24450Sstevel@tonic-gate 	rdr_private_func_reply_t	private_func_data;
24460Sstevel@tonic-gate 	rdr_variable_message_info_t 	var_msg_info;
24470Sstevel@tonic-gate 
24480Sstevel@tonic-gate 
24490Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
24500Sstevel@tonic-gate 
24510Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
24520Sstevel@tonic-gate 		return (RDR_ERROR);
24530Sstevel@tonic-gate 	}
24540Sstevel@tonic-gate 
24550Sstevel@tonic-gate 	/*
24560Sstevel@tonic-gate 	 * Set variable length fields (size info)
24570Sstevel@tonic-gate 	 */
24580Sstevel@tonic-gate 	if (find_errstring_sizes(params->errstring, &var_msg_info)) {
24590Sstevel@tonic-gate 		return (RDR_ERROR);
24600Sstevel@tonic-gate 	}
24610Sstevel@tonic-gate 
24620Sstevel@tonic-gate 	/*
24630Sstevel@tonic-gate 	 * Collect size info specific to the private_func reply
24640Sstevel@tonic-gate 	 * message and allocate a buffer
24650Sstevel@tonic-gate 	 */
24660Sstevel@tonic-gate 	*buf_size = sizeof (rdr_private_func_reply_t);
24670Sstevel@tonic-gate 	*buf_size += var_msg_info.errstring_strlen;
24680Sstevel@tonic-gate 	*buf_size += var_msg_info.errstring_pad_sz;
24690Sstevel@tonic-gate 
24700Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
24710Sstevel@tonic-gate 	if (*buf == NULL) {
24720Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
24730Sstevel@tonic-gate 	}
24740Sstevel@tonic-gate 
24750Sstevel@tonic-gate 	/*
24760Sstevel@tonic-gate 	 * Set fixed address labels by name
24770Sstevel@tonic-gate 	 */
24780Sstevel@tonic-gate 	private_func_data.errstring_size = var_msg_info.errstring_strlen +
24790Sstevel@tonic-gate 	    var_msg_info.errstring_pad_sz;
24800Sstevel@tonic-gate 
24810Sstevel@tonic-gate 	/*
24820Sstevel@tonic-gate 	 * Set variable information using memcpy
24830Sstevel@tonic-gate 	 */
24840Sstevel@tonic-gate 	bufptr = *buf;
24850Sstevel@tonic-gate 
24860Sstevel@tonic-gate 	(void) memcpy(bufptr, &private_func_data,
24870Sstevel@tonic-gate 	    sizeof (rdr_private_func_reply_t));
24880Sstevel@tonic-gate 	bufptr += sizeof (rdr_private_func_reply_t);
24890Sstevel@tonic-gate 	if ((params->errstring != NULL) && (*(params->errstring) != NULL)) {
24900Sstevel@tonic-gate 		(void) memcpy(bufptr, *(params->errstring),
24910Sstevel@tonic-gate 		    var_msg_info.errstring_strlen);
24920Sstevel@tonic-gate 		bufptr += var_msg_info.errstring_strlen;
24930Sstevel@tonic-gate 		for (i = 0; i < var_msg_info.errstring_pad_sz; i++) {
24940Sstevel@tonic-gate 			bufptr[i] = 0;
24950Sstevel@tonic-gate 		}
24960Sstevel@tonic-gate 		bufptr += var_msg_info.errstring_pad_sz;
24970Sstevel@tonic-gate 	}
24980Sstevel@tonic-gate 
24990Sstevel@tonic-gate 	return (RDR_OK);
25000Sstevel@tonic-gate }
25010Sstevel@tonic-gate 
25020Sstevel@tonic-gate 
25030Sstevel@tonic-gate /*
25040Sstevel@tonic-gate  * unpack_private_func_reply:
25050Sstevel@tonic-gate  *
25060Sstevel@tonic-gate  * Handle unpacking a private function reply message.
25070Sstevel@tonic-gate  */
25080Sstevel@tonic-gate static int
unpack_private_func_reply(private_func_params_t * params,const char * buf)25090Sstevel@tonic-gate unpack_private_func_reply(private_func_params_t *params, const char *buf)
25100Sstevel@tonic-gate {
25110Sstevel@tonic-gate 	char				*bufptr;
25120Sstevel@tonic-gate 	rdr_private_func_reply_t	private_func_data;
25130Sstevel@tonic-gate 
25140Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
25150Sstevel@tonic-gate 		return (RDR_ERROR);
25160Sstevel@tonic-gate 	}
25170Sstevel@tonic-gate 
25180Sstevel@tonic-gate 	bufptr = (char *)buf;
25190Sstevel@tonic-gate 	(void) memcpy(&private_func_data, bufptr,
25200Sstevel@tonic-gate 	    sizeof (rdr_private_func_reply_t));
25210Sstevel@tonic-gate 	bufptr += sizeof (rdr_private_func_reply_t);
25220Sstevel@tonic-gate 
25230Sstevel@tonic-gate 	/*
25240Sstevel@tonic-gate 	 * handle getting the errstring
25250Sstevel@tonic-gate 	 */
25260Sstevel@tonic-gate 	params->errstring = (char **)malloc(sizeof (char *));
25270Sstevel@tonic-gate 	if (params->errstring == NULL) {
25280Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
25290Sstevel@tonic-gate 	}
25300Sstevel@tonic-gate 	if (get_string_from_buf(params->errstring,
25310Sstevel@tonic-gate 	    private_func_data.errstring_size, bufptr)) {
25320Sstevel@tonic-gate 		return (RDR_ERROR);
25330Sstevel@tonic-gate 	}
25340Sstevel@tonic-gate 	bufptr += private_func_data.errstring_size;
25350Sstevel@tonic-gate 
25360Sstevel@tonic-gate 	return (RDR_OK);
25370Sstevel@tonic-gate }
25380Sstevel@tonic-gate 
25390Sstevel@tonic-gate 
25400Sstevel@tonic-gate /*
25410Sstevel@tonic-gate  * pack_test_request:
25420Sstevel@tonic-gate  *
25430Sstevel@tonic-gate  * Handle packing a test request message.
25440Sstevel@tonic-gate  */
25450Sstevel@tonic-gate static int
pack_test_request(test_params_t * params,char ** buf,int * buf_size)25460Sstevel@tonic-gate pack_test_request(test_params_t *params, char **buf, int *buf_size)
25470Sstevel@tonic-gate {
25480Sstevel@tonic-gate 	int				i;
25490Sstevel@tonic-gate 	char				*bufptr;
25500Sstevel@tonic-gate 	rdr_test_t			test_data;
25510Sstevel@tonic-gate 	rdr_variable_message_info_t	var_msg_info;
25520Sstevel@tonic-gate 
25530Sstevel@tonic-gate 
25540Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
25550Sstevel@tonic-gate 		return (RDR_ERROR);
25560Sstevel@tonic-gate 	}
25570Sstevel@tonic-gate 
25580Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
25590Sstevel@tonic-gate 
25600Sstevel@tonic-gate 	/*
25610Sstevel@tonic-gate 	 * Set variable length fields and make a call to partially
25620Sstevel@tonic-gate 	 * pack it.
25630Sstevel@tonic-gate 	 */
25640Sstevel@tonic-gate 	if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) {
25650Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
25660Sstevel@tonic-gate 		return (RDR_ERROR);
25670Sstevel@tonic-gate 	}
25680Sstevel@tonic-gate 	if (find_options_sizes(params->options, &var_msg_info)) {
25690Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
25700Sstevel@tonic-gate 		return (RDR_ERROR);
25710Sstevel@tonic-gate 	}
25720Sstevel@tonic-gate 
25730Sstevel@tonic-gate 	/*
25740Sstevel@tonic-gate 	 * Collect size info specific to the test request
25750Sstevel@tonic-gate 	 * message and allocate a buffer
25760Sstevel@tonic-gate 	 */
25770Sstevel@tonic-gate 	*buf_size = sizeof (rdr_test_t);
25780Sstevel@tonic-gate 	*buf_size += var_msg_info.ap_id_int_size;
25790Sstevel@tonic-gate 	*buf_size += var_msg_info.ap_id_char_size;
25800Sstevel@tonic-gate 	*buf_size += var_msg_info.options_strlen;
25810Sstevel@tonic-gate 	*buf_size += var_msg_info.options_pad_sz;
25820Sstevel@tonic-gate 
25830Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
25840Sstevel@tonic-gate 	if (*buf == NULL) {
25850Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
25860Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
25870Sstevel@tonic-gate 	}
25880Sstevel@tonic-gate 
25890Sstevel@tonic-gate 	/*
25900Sstevel@tonic-gate 	 * Set fixed address labels by name
25910Sstevel@tonic-gate 	 */
25920Sstevel@tonic-gate 	test_data.num_ap_ids = params->num_ap_ids;
25930Sstevel@tonic-gate 	test_data.ap_id_char_size = var_msg_info.ap_id_char_size;
25940Sstevel@tonic-gate 	test_data.options_size = var_msg_info.options_strlen +
25950Sstevel@tonic-gate 	    var_msg_info.options_pad_sz;
25960Sstevel@tonic-gate 
25970Sstevel@tonic-gate 	if (params->msgp != NULL) {
25980Sstevel@tonic-gate 		test_data.msg_callback_id =
25990Sstevel@tonic-gate 		    (unsigned long)params->msgp->message_routine;
26000Sstevel@tonic-gate 		test_data.msg_appdata_ptr =
26010Sstevel@tonic-gate 		    (unsigned long)params->msgp->appdata_ptr;
26020Sstevel@tonic-gate 	} else {
26030Sstevel@tonic-gate 		test_data.msg_callback_id = 0;
26040Sstevel@tonic-gate 		test_data.msg_appdata_ptr = 0;
26050Sstevel@tonic-gate 	}
26060Sstevel@tonic-gate 
26070Sstevel@tonic-gate 	test_data.flags = params->flags;
26080Sstevel@tonic-gate 
26090Sstevel@tonic-gate 	if (params->errstring != NULL) {
26100Sstevel@tonic-gate 		test_data.error_msg_ctl = RDR_GENERATE_ERR_MSGS;
26110Sstevel@tonic-gate 	} else {
26120Sstevel@tonic-gate 		test_data.error_msg_ctl = RDR_DONT_GENERATE_ERR_MSGS;
26130Sstevel@tonic-gate 	}
26140Sstevel@tonic-gate 
26150Sstevel@tonic-gate 	/*
26160Sstevel@tonic-gate 	 * Set variable information using memcpy
26170Sstevel@tonic-gate 	 */
26180Sstevel@tonic-gate 	bufptr = *buf;
26190Sstevel@tonic-gate 
26200Sstevel@tonic-gate 	(void) memcpy(bufptr, &test_data, sizeof (rdr_test_t));
26210Sstevel@tonic-gate 	bufptr += sizeof (rdr_test_t);
26220Sstevel@tonic-gate 
26230Sstevel@tonic-gate 	if (var_msg_info.ap_id_sizes != NULL) {
26240Sstevel@tonic-gate 		(void) memcpy(bufptr, var_msg_info.ap_id_sizes,
26250Sstevel@tonic-gate 		    var_msg_info.ap_id_int_size);
26260Sstevel@tonic-gate 		bufptr += var_msg_info.ap_id_int_size;
26270Sstevel@tonic-gate 	}
26280Sstevel@tonic-gate 
26290Sstevel@tonic-gate 	if (var_msg_info.ap_id_chars != NULL) {
26300Sstevel@tonic-gate 		(void) memcpy(bufptr, var_msg_info.ap_id_chars,
26310Sstevel@tonic-gate 		    var_msg_info.ap_id_char_size);
26320Sstevel@tonic-gate 		bufptr += var_msg_info.ap_id_char_size;
26330Sstevel@tonic-gate 	}
26340Sstevel@tonic-gate 
26350Sstevel@tonic-gate 	if (params->options != NULL) {
26360Sstevel@tonic-gate 		(void) memcpy(bufptr, params->options,
26370Sstevel@tonic-gate 		    var_msg_info.options_strlen);
26380Sstevel@tonic-gate 		bufptr += var_msg_info.options_strlen;
26390Sstevel@tonic-gate 		for (i = 0; i < var_msg_info.options_pad_sz; i++) {
26400Sstevel@tonic-gate 			bufptr[i] = 0;
26410Sstevel@tonic-gate 		}
26420Sstevel@tonic-gate 		bufptr += var_msg_info.options_pad_sz;
26430Sstevel@tonic-gate 	}
26440Sstevel@tonic-gate 
26450Sstevel@tonic-gate 	cleanup_variable_ap_id_info(&var_msg_info);
26460Sstevel@tonic-gate 
26470Sstevel@tonic-gate 	return (RDR_OK);
26480Sstevel@tonic-gate }
26490Sstevel@tonic-gate 
26500Sstevel@tonic-gate 
26510Sstevel@tonic-gate /*
26520Sstevel@tonic-gate  * unpack_test_request:
26530Sstevel@tonic-gate  *
26540Sstevel@tonic-gate  * Handle unpacking a test request message.
26550Sstevel@tonic-gate  */
26560Sstevel@tonic-gate static int
unpack_test_request(test_params_t * params,const char * buf)26570Sstevel@tonic-gate unpack_test_request(test_params_t *params, const char *buf)
26580Sstevel@tonic-gate {
26590Sstevel@tonic-gate 	char				*bufptr;
26600Sstevel@tonic-gate 	rdr_variable_message_info_t 	var_msg_info;
26610Sstevel@tonic-gate 	rdr_test_t			test_data;
26620Sstevel@tonic-gate 
26630Sstevel@tonic-gate 
26640Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
26650Sstevel@tonic-gate 		return (RDR_ERROR);
26660Sstevel@tonic-gate 	}
26670Sstevel@tonic-gate 
26680Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
26690Sstevel@tonic-gate 
26700Sstevel@tonic-gate 	bufptr = (char *)buf;
26710Sstevel@tonic-gate 	(void) memcpy(&test_data, bufptr, sizeof (rdr_test_t));
26720Sstevel@tonic-gate 	bufptr += sizeof (rdr_test_t);
26730Sstevel@tonic-gate 
26740Sstevel@tonic-gate 	/*
26750Sstevel@tonic-gate 	 * handle getting the ap_ids
26760Sstevel@tonic-gate 	 */
26770Sstevel@tonic-gate 	var_msg_info.ap_id_char_size = test_data.ap_id_char_size;
26780Sstevel@tonic-gate 	if (get_ap_ids_from_buf((char ***)&(params->ap_ids),
26790Sstevel@tonic-gate 	    test_data.num_ap_ids, &var_msg_info, bufptr)) {
26800Sstevel@tonic-gate 		return (RDR_ERROR);
26810Sstevel@tonic-gate 	}
26820Sstevel@tonic-gate 	bufptr += var_msg_info.ap_id_int_size;
26830Sstevel@tonic-gate 	bufptr += var_msg_info.ap_id_char_size;
26840Sstevel@tonic-gate 
26850Sstevel@tonic-gate 	/*
26860Sstevel@tonic-gate 	 * handle getting the options
26870Sstevel@tonic-gate 	 */
26880Sstevel@tonic-gate 	if (get_string_from_buf(&(params->options),
26890Sstevel@tonic-gate 	    test_data.options_size, bufptr)) {
26900Sstevel@tonic-gate 		return (RDR_ERROR);
26910Sstevel@tonic-gate 	}
26920Sstevel@tonic-gate 	bufptr += test_data.options_size;
26930Sstevel@tonic-gate 
26940Sstevel@tonic-gate 	/*
26950Sstevel@tonic-gate 	 * Set fixed address labels by name
26960Sstevel@tonic-gate 	 */
26970Sstevel@tonic-gate 	params->num_ap_ids = test_data.num_ap_ids;
26980Sstevel@tonic-gate 
26990Sstevel@tonic-gate 	params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg));
27000Sstevel@tonic-gate 	if (params->msgp == NULL) {
27010Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
27020Sstevel@tonic-gate 	}
27030Sstevel@tonic-gate 
27040Sstevel@tonic-gate 	/* set params->msgp->message_routine using memcpy */
27050Sstevel@tonic-gate 	(void) memcpy((void*)params->msgp,
27060Sstevel@tonic-gate 	    &(test_data.msg_callback_id), sizeof (unsigned long));
27070Sstevel@tonic-gate 	params->msgp->appdata_ptr =
27080Sstevel@tonic-gate 	    (void*)test_data.msg_appdata_ptr;
27090Sstevel@tonic-gate 
27100Sstevel@tonic-gate 	if (test_data.error_msg_ctl == RDR_GENERATE_ERR_MSGS) {
27110Sstevel@tonic-gate 		params->errstring = (char **)malloc(sizeof (char *));
27120Sstevel@tonic-gate 		if (params->errstring == NULL) {
27130Sstevel@tonic-gate 			return (RDR_MEM_ALLOC);
27140Sstevel@tonic-gate 		}
27150Sstevel@tonic-gate 		*(params->errstring) = NULL;
27160Sstevel@tonic-gate 	} else {	/* error_msg_ctl == RDR_DONT_GENERATE_ERR_MSGS */
27170Sstevel@tonic-gate 		params->errstring = NULL;
27180Sstevel@tonic-gate 	}
27190Sstevel@tonic-gate 	params->flags = test_data.flags;
27200Sstevel@tonic-gate 
27210Sstevel@tonic-gate 	return (RDR_OK);
27220Sstevel@tonic-gate }
27230Sstevel@tonic-gate 
27240Sstevel@tonic-gate 
27250Sstevel@tonic-gate /*
27260Sstevel@tonic-gate  * pack_test_reply:
27270Sstevel@tonic-gate  *
27280Sstevel@tonic-gate  * Handle packing a test reply message.
27290Sstevel@tonic-gate  */
27300Sstevel@tonic-gate static int
pack_test_reply(test_params_t * params,char ** buf,int * buf_size)27310Sstevel@tonic-gate pack_test_reply(test_params_t *params, char **buf, int *buf_size)
27320Sstevel@tonic-gate {
27330Sstevel@tonic-gate 	int				i;
27340Sstevel@tonic-gate 	char				*bufptr;
27350Sstevel@tonic-gate 	rdr_test_reply_t		test_data;
27360Sstevel@tonic-gate 	rdr_variable_message_info_t 	var_msg_info;
27370Sstevel@tonic-gate 
27380Sstevel@tonic-gate 
27390Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
27400Sstevel@tonic-gate 		return (RDR_ERROR);
27410Sstevel@tonic-gate 	}
27420Sstevel@tonic-gate 
27430Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
27440Sstevel@tonic-gate 
27450Sstevel@tonic-gate 	/*
27460Sstevel@tonic-gate 	 * Set variable length fields (size info)
27470Sstevel@tonic-gate 	 */
27480Sstevel@tonic-gate 	if (find_errstring_sizes(params->errstring, &var_msg_info)) {
27490Sstevel@tonic-gate 		return (RDR_ERROR);
27500Sstevel@tonic-gate 	}
27510Sstevel@tonic-gate 
27520Sstevel@tonic-gate 	/*
27530Sstevel@tonic-gate 	 * Collect size info specific to the test reply
27540Sstevel@tonic-gate 	 * message and allocate a buffer
27550Sstevel@tonic-gate 	 */
27560Sstevel@tonic-gate 	*buf_size = sizeof (rdr_test_reply_t);
27570Sstevel@tonic-gate 	*buf_size += var_msg_info.errstring_strlen;
27580Sstevel@tonic-gate 	*buf_size += var_msg_info.errstring_pad_sz;
27590Sstevel@tonic-gate 
27600Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
27610Sstevel@tonic-gate 	if (*buf == NULL) {
27620Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
27630Sstevel@tonic-gate 	}
27640Sstevel@tonic-gate 
27650Sstevel@tonic-gate 	/*
27660Sstevel@tonic-gate 	 * Set fixed address labels by name
27670Sstevel@tonic-gate 	 */
27680Sstevel@tonic-gate 	test_data.errstring_size = var_msg_info.errstring_strlen +
27690Sstevel@tonic-gate 	    var_msg_info.errstring_pad_sz;
27700Sstevel@tonic-gate 
27710Sstevel@tonic-gate 	/*
27720Sstevel@tonic-gate 	 * Set variable information using memcpy
27730Sstevel@tonic-gate 	 */
27740Sstevel@tonic-gate 	bufptr = *buf;
27750Sstevel@tonic-gate 
27760Sstevel@tonic-gate 	(void) memcpy(bufptr, &test_data, sizeof (rdr_test_reply_t));
27770Sstevel@tonic-gate 	bufptr += sizeof (rdr_test_reply_t);
27780Sstevel@tonic-gate 	if ((params->errstring != NULL) && (*(params->errstring) != NULL)) {
27790Sstevel@tonic-gate 		(void) memcpy(bufptr, *(params->errstring),
27800Sstevel@tonic-gate 		    var_msg_info.errstring_strlen);
27810Sstevel@tonic-gate 		bufptr += var_msg_info.errstring_strlen;
27820Sstevel@tonic-gate 		for (i = 0; i < var_msg_info.errstring_pad_sz; i++) {
27830Sstevel@tonic-gate 			bufptr[i] = 0;
27840Sstevel@tonic-gate 		}
27850Sstevel@tonic-gate 		bufptr += var_msg_info.errstring_pad_sz;
27860Sstevel@tonic-gate 	}
27870Sstevel@tonic-gate 
27880Sstevel@tonic-gate 	return (RDR_OK);
27890Sstevel@tonic-gate }
27900Sstevel@tonic-gate 
27910Sstevel@tonic-gate 
27920Sstevel@tonic-gate /*
27930Sstevel@tonic-gate  * unpack_test_reply:
27940Sstevel@tonic-gate  *
27950Sstevel@tonic-gate  * Handle unpacking a test reply message.
27960Sstevel@tonic-gate  */
27970Sstevel@tonic-gate static int
unpack_test_reply(test_params_t * params,const char * buf)27980Sstevel@tonic-gate unpack_test_reply(test_params_t *params, const char *buf)
27990Sstevel@tonic-gate {
28000Sstevel@tonic-gate 	char			*bufptr;
28010Sstevel@tonic-gate 	rdr_test_reply_t	test_data;
28020Sstevel@tonic-gate 
28030Sstevel@tonic-gate 
28040Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
28050Sstevel@tonic-gate 		return (RDR_ERROR);
28060Sstevel@tonic-gate 	}
28070Sstevel@tonic-gate 
28080Sstevel@tonic-gate 	bufptr = (char *)buf;
28090Sstevel@tonic-gate 	(void) memcpy(&test_data, bufptr, sizeof (rdr_test_reply_t));
28100Sstevel@tonic-gate 	bufptr += sizeof (rdr_test_reply_t);
28110Sstevel@tonic-gate 
28120Sstevel@tonic-gate 	/*
28130Sstevel@tonic-gate 	 * handle getting the errstring
28140Sstevel@tonic-gate 	 */
28150Sstevel@tonic-gate 	params->errstring = (char **)malloc(sizeof (char *));
28160Sstevel@tonic-gate 	if (params->errstring == NULL) {
28170Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
28180Sstevel@tonic-gate 	}
28190Sstevel@tonic-gate 	if (get_string_from_buf(params->errstring,
28200Sstevel@tonic-gate 	    test_data.errstring_size, bufptr)) {
28210Sstevel@tonic-gate 		return (RDR_ERROR);
28220Sstevel@tonic-gate 	}
28230Sstevel@tonic-gate 	bufptr += test_data.errstring_size;
28240Sstevel@tonic-gate 
28250Sstevel@tonic-gate 	return (RDR_OK);
28260Sstevel@tonic-gate }
28270Sstevel@tonic-gate 
28280Sstevel@tonic-gate 
28290Sstevel@tonic-gate /*
28300Sstevel@tonic-gate  * pack_list_ext_request:
28310Sstevel@tonic-gate  *
28320Sstevel@tonic-gate  * Handle packing a list request message.
28330Sstevel@tonic-gate  */
28340Sstevel@tonic-gate static int
pack_list_ext_request(list_ext_params_t * params,char ** buf,int * buf_size)28350Sstevel@tonic-gate pack_list_ext_request(list_ext_params_t *params, char **buf, int *buf_size)
28360Sstevel@tonic-gate {
28370Sstevel@tonic-gate 	int				i;
28380Sstevel@tonic-gate 	char				*bufptr;
28390Sstevel@tonic-gate 	rdr_list_ext_t 			list_ext_data;
28400Sstevel@tonic-gate 	rdr_variable_message_info_t 	var_msg_info;
28410Sstevel@tonic-gate 
28420Sstevel@tonic-gate 
28430Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
28440Sstevel@tonic-gate 		return (RDR_ERROR);
28450Sstevel@tonic-gate 	}
28460Sstevel@tonic-gate 
28470Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
28480Sstevel@tonic-gate 
28490Sstevel@tonic-gate 	/*
28500Sstevel@tonic-gate 	 * Set variable length fields and make a call to partially
28510Sstevel@tonic-gate 	 * pack it.
28520Sstevel@tonic-gate 	 */
28530Sstevel@tonic-gate 	if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) {
28540Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
28550Sstevel@tonic-gate 		return (RDR_ERROR);
28560Sstevel@tonic-gate 	}
28570Sstevel@tonic-gate 	if (find_options_sizes(params->options, &var_msg_info)) {
28580Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
28590Sstevel@tonic-gate 		return (RDR_ERROR);
28600Sstevel@tonic-gate 	}
28610Sstevel@tonic-gate 	if (find_listopts_sizes(params->listopts, &var_msg_info)) {
28620Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
28630Sstevel@tonic-gate 		return (RDR_ERROR);
28640Sstevel@tonic-gate 	}
28650Sstevel@tonic-gate 
28660Sstevel@tonic-gate 
28670Sstevel@tonic-gate 	/*
28680Sstevel@tonic-gate 	 * Collect size info specific to the list_ext request
28690Sstevel@tonic-gate 	 * message and allocate a buffer
28700Sstevel@tonic-gate 	 */
28710Sstevel@tonic-gate 	*buf_size = sizeof (rdr_list_ext_t);
28720Sstevel@tonic-gate 	*buf_size += var_msg_info.ap_id_int_size;
28730Sstevel@tonic-gate 	*buf_size += var_msg_info.ap_id_char_size;
28740Sstevel@tonic-gate 	*buf_size += var_msg_info.options_strlen;
28750Sstevel@tonic-gate 	*buf_size += var_msg_info.options_pad_sz;
28760Sstevel@tonic-gate 	*buf_size += var_msg_info.listopts_strlen;
28770Sstevel@tonic-gate 	*buf_size += var_msg_info.listopts_pad_sz;
28780Sstevel@tonic-gate 
28790Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
28800Sstevel@tonic-gate 	if (*buf == NULL) {
28810Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
28820Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
28830Sstevel@tonic-gate 	}
28840Sstevel@tonic-gate 
28850Sstevel@tonic-gate 	/*
28860Sstevel@tonic-gate 	 * Set fixed address labels by name
28870Sstevel@tonic-gate 	 */
28880Sstevel@tonic-gate 	list_ext_data.num_ap_ids = params->num_ap_ids;
28890Sstevel@tonic-gate 	list_ext_data.ap_id_char_size = var_msg_info.ap_id_char_size;
28900Sstevel@tonic-gate 	list_ext_data.options_size = var_msg_info.options_strlen +
28910Sstevel@tonic-gate 	    var_msg_info.options_pad_sz;
28920Sstevel@tonic-gate 	list_ext_data.listopts_size = var_msg_info.listopts_strlen +
28930Sstevel@tonic-gate 	    var_msg_info.listopts_pad_sz;
28940Sstevel@tonic-gate 	if (params->errstring != NULL) {
28950Sstevel@tonic-gate 		list_ext_data.error_msg_ctl = RDR_GENERATE_ERR_MSGS;
28960Sstevel@tonic-gate 	} else {
28970Sstevel@tonic-gate 		list_ext_data.error_msg_ctl = RDR_DONT_GENERATE_ERR_MSGS;
28980Sstevel@tonic-gate 	}
28990Sstevel@tonic-gate 	if ((params->num_ap_ids != 0) || (params->ap_ids != NULL)) {
29000Sstevel@tonic-gate 		list_ext_data.list_msg_ctl = RDR_LIST_ONLY_PARAM_APS;
29010Sstevel@tonic-gate 	} else {
29020Sstevel@tonic-gate 		list_ext_data.list_msg_ctl = RDR_LIST_ALL_APS;
29030Sstevel@tonic-gate 	}
29040Sstevel@tonic-gate 	list_ext_data.flags = params->flags;
29050Sstevel@tonic-gate 	list_ext_data.permissions = params->permissions;
29060Sstevel@tonic-gate 
29070Sstevel@tonic-gate 	/*
29080Sstevel@tonic-gate 	 * Set variable information using memcpy
29090Sstevel@tonic-gate 	 */
29100Sstevel@tonic-gate 	bufptr = *buf;
29110Sstevel@tonic-gate 
29120Sstevel@tonic-gate 	(void) memcpy(bufptr, &list_ext_data, sizeof (rdr_list_ext_t));
29130Sstevel@tonic-gate 	bufptr += sizeof (rdr_list_ext_t);
29140Sstevel@tonic-gate 
29150Sstevel@tonic-gate 	if (var_msg_info.ap_id_sizes != NULL) {
29160Sstevel@tonic-gate 		(void) memcpy(bufptr, var_msg_info.ap_id_sizes,
29170Sstevel@tonic-gate 		    var_msg_info.ap_id_int_size);
29180Sstevel@tonic-gate 		bufptr += var_msg_info.ap_id_int_size;
29190Sstevel@tonic-gate 	}
29200Sstevel@tonic-gate 
29210Sstevel@tonic-gate 	if (var_msg_info.ap_id_chars != NULL) {
29220Sstevel@tonic-gate 		(void) memcpy(bufptr, var_msg_info.ap_id_chars,
29230Sstevel@tonic-gate 		    var_msg_info.ap_id_char_size);
29240Sstevel@tonic-gate 		bufptr += var_msg_info.ap_id_char_size;
29250Sstevel@tonic-gate 	}
29260Sstevel@tonic-gate 
29270Sstevel@tonic-gate 	if (params->options != NULL) {
29280Sstevel@tonic-gate 		(void) memcpy(bufptr, params->options,
29290Sstevel@tonic-gate 		    var_msg_info.options_strlen);
29300Sstevel@tonic-gate 		bufptr += var_msg_info.options_strlen;
29310Sstevel@tonic-gate 		for (i = 0; i < var_msg_info.options_pad_sz; i++) {
29320Sstevel@tonic-gate 			bufptr[i] = 0;
29330Sstevel@tonic-gate 		}
29340Sstevel@tonic-gate 		bufptr += var_msg_info.options_pad_sz;
29350Sstevel@tonic-gate 	}
29360Sstevel@tonic-gate 
29370Sstevel@tonic-gate 	if (params->listopts != NULL) {
29380Sstevel@tonic-gate 		(void) memcpy(bufptr, params->listopts,
29390Sstevel@tonic-gate 		    var_msg_info.listopts_strlen);
29400Sstevel@tonic-gate 		bufptr += var_msg_info.listopts_strlen;
29410Sstevel@tonic-gate 		for (i = 0; i < var_msg_info.listopts_pad_sz; i++) {
29420Sstevel@tonic-gate 			bufptr[i] = 0;
29430Sstevel@tonic-gate 		}
29440Sstevel@tonic-gate 		bufptr += var_msg_info.listopts_pad_sz;
29450Sstevel@tonic-gate 	}
29460Sstevel@tonic-gate 
29470Sstevel@tonic-gate 	cleanup_variable_ap_id_info(&var_msg_info);
29480Sstevel@tonic-gate 
29490Sstevel@tonic-gate 	return (RDR_OK);
29500Sstevel@tonic-gate }
29510Sstevel@tonic-gate 
29520Sstevel@tonic-gate 
29530Sstevel@tonic-gate /*
29540Sstevel@tonic-gate  * unpack_list_ext_request:
29550Sstevel@tonic-gate  *
29560Sstevel@tonic-gate  * Handle unpacking a list request message.
29570Sstevel@tonic-gate  */
29580Sstevel@tonic-gate static int
unpack_list_ext_request(list_ext_params_t * params,const char * buf)29590Sstevel@tonic-gate unpack_list_ext_request(list_ext_params_t *params, const char *buf)
29600Sstevel@tonic-gate {
29610Sstevel@tonic-gate 	char				*bufptr;
29620Sstevel@tonic-gate 	rdr_variable_message_info_t 	var_msg_info;
29630Sstevel@tonic-gate 	rdr_list_ext_t			list_ext_data;
29640Sstevel@tonic-gate 
29650Sstevel@tonic-gate 
29660Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
29670Sstevel@tonic-gate 		return (RDR_ERROR);
29680Sstevel@tonic-gate 	}
29690Sstevel@tonic-gate 
29700Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
29710Sstevel@tonic-gate 
29720Sstevel@tonic-gate 	bufptr = (char *)buf;
29730Sstevel@tonic-gate 	(void) memcpy(&list_ext_data, bufptr, sizeof (rdr_list_ext_t));
29740Sstevel@tonic-gate 	bufptr += sizeof (rdr_list_ext_t);
29750Sstevel@tonic-gate 
29760Sstevel@tonic-gate 	/*
29770Sstevel@tonic-gate 	 * handle getting the ap_ids
29780Sstevel@tonic-gate 	 */
29790Sstevel@tonic-gate 	var_msg_info.ap_id_char_size = list_ext_data.ap_id_char_size;
29800Sstevel@tonic-gate 	if (get_ap_ids_from_buf(&(params->ap_ids), list_ext_data.num_ap_ids,
29810Sstevel@tonic-gate 	    &var_msg_info, bufptr)) {
29820Sstevel@tonic-gate 		return (RDR_ERROR);
29830Sstevel@tonic-gate 	}
29840Sstevel@tonic-gate 	bufptr += var_msg_info.ap_id_int_size;
29850Sstevel@tonic-gate 	bufptr += var_msg_info.ap_id_char_size;
29860Sstevel@tonic-gate 
29870Sstevel@tonic-gate 	/*
29880Sstevel@tonic-gate 	 * handle getting the options
29890Sstevel@tonic-gate 	 */
29900Sstevel@tonic-gate 	if (get_string_from_buf(&(params->options),
29910Sstevel@tonic-gate 	    list_ext_data.options_size, bufptr)) {
29920Sstevel@tonic-gate 		return (RDR_ERROR);
29930Sstevel@tonic-gate 	}
29940Sstevel@tonic-gate 	bufptr += list_ext_data.options_size;
29950Sstevel@tonic-gate 
29960Sstevel@tonic-gate 	/*
29970Sstevel@tonic-gate 	 * handle getting the listopts
29980Sstevel@tonic-gate 	 */
29990Sstevel@tonic-gate 	if (get_string_from_buf(&(params->listopts),
30000Sstevel@tonic-gate 	    list_ext_data.listopts_size, bufptr)) {
30010Sstevel@tonic-gate 		return (RDR_ERROR);
30020Sstevel@tonic-gate 	}
30030Sstevel@tonic-gate 	bufptr += list_ext_data.listopts_size;
30040Sstevel@tonic-gate 
30050Sstevel@tonic-gate 	/*
30060Sstevel@tonic-gate 	 * Set fixed address labels by name
30070Sstevel@tonic-gate 	 */
30080Sstevel@tonic-gate 	params->num_ap_ids = list_ext_data.num_ap_ids;
30090Sstevel@tonic-gate 
30100Sstevel@tonic-gate 	params->ap_id_list = (rdr_list_t **)malloc(sizeof (rdr_list_t *));
30110Sstevel@tonic-gate 	if (params->ap_id_list == NULL) {
30120Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
30130Sstevel@tonic-gate 	}
30140Sstevel@tonic-gate 	*(params->ap_id_list) = NULL;
30150Sstevel@tonic-gate 
30160Sstevel@tonic-gate 	params->nlist = (int *)malloc(sizeof (int));
30170Sstevel@tonic-gate 	if (params->nlist == NULL) {
30180Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
30190Sstevel@tonic-gate 	}
30200Sstevel@tonic-gate 	if (list_ext_data.error_msg_ctl == RDR_GENERATE_ERR_MSGS) {
30210Sstevel@tonic-gate 		params->errstring = (char **)malloc(sizeof (char *));
30220Sstevel@tonic-gate 		if (params->errstring == NULL) {
30230Sstevel@tonic-gate 			return (RDR_MEM_ALLOC);
30240Sstevel@tonic-gate 		}
30250Sstevel@tonic-gate 		*(params->errstring) = NULL;
30260Sstevel@tonic-gate 	} else {	/* error_msg_ctl == RDR_DONT_GENERATE_ERR_MSGS */
30270Sstevel@tonic-gate 	    params->errstring = NULL;
30280Sstevel@tonic-gate 	}
30290Sstevel@tonic-gate 	params->flags = list_ext_data.flags;
30300Sstevel@tonic-gate 	params->permissions = list_ext_data.permissions;
30310Sstevel@tonic-gate 
30320Sstevel@tonic-gate 	return (RDR_OK);
30330Sstevel@tonic-gate }
30340Sstevel@tonic-gate 
30350Sstevel@tonic-gate 
30360Sstevel@tonic-gate /*
30370Sstevel@tonic-gate  * pack_list_ext_reply:
30380Sstevel@tonic-gate  *
30390Sstevel@tonic-gate  * Handle packing a list reply message.
30400Sstevel@tonic-gate  */
30410Sstevel@tonic-gate static int
pack_list_ext_reply(list_ext_params_t * params,char ** buf,int * buf_size)30420Sstevel@tonic-gate pack_list_ext_reply(list_ext_params_t *params, char **buf, int *buf_size)
30430Sstevel@tonic-gate {
30440Sstevel@tonic-gate 	int				i;
30450Sstevel@tonic-gate 	char				*bufptr;
30460Sstevel@tonic-gate 	rdr_list_ext_reply_t		list_ext_data;
30470Sstevel@tonic-gate 	rdr_variable_message_info_t 	var_msg_info;
30480Sstevel@tonic-gate 	int 				list_data_size;
30490Sstevel@tonic-gate 
30500Sstevel@tonic-gate 
30510Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
30520Sstevel@tonic-gate 
30530Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
30540Sstevel@tonic-gate 		return (RDR_ERROR);
30550Sstevel@tonic-gate 	}
30560Sstevel@tonic-gate 
30570Sstevel@tonic-gate 	/*
30580Sstevel@tonic-gate 	 * Set variable length fields (size info)
30590Sstevel@tonic-gate 	 */
30600Sstevel@tonic-gate 	if (find_errstring_sizes(params->errstring, &var_msg_info)) {
30610Sstevel@tonic-gate 		return (RDR_ERROR);
30620Sstevel@tonic-gate 	}
30630Sstevel@tonic-gate 
30640Sstevel@tonic-gate 	if (params->nlist == NULL) {
30650Sstevel@tonic-gate 		list_data_size = 0;
30660Sstevel@tonic-gate 	} else {
30670Sstevel@tonic-gate 		list_data_size = *(params->nlist) * sizeof (rdr_list_t);
30680Sstevel@tonic-gate 	}
30690Sstevel@tonic-gate 
30700Sstevel@tonic-gate 	/*
30710Sstevel@tonic-gate 	 * Collect size info specific to the list_ext reply
30720Sstevel@tonic-gate 	 * message and allocate a buffer
30730Sstevel@tonic-gate 	 */
30740Sstevel@tonic-gate 	*buf_size = sizeof (rdr_list_ext_reply_t);
30750Sstevel@tonic-gate 	*buf_size += list_data_size;
30760Sstevel@tonic-gate 	*buf_size += var_msg_info.errstring_strlen;
30770Sstevel@tonic-gate 	*buf_size += var_msg_info.errstring_pad_sz;
30780Sstevel@tonic-gate 
30790Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
30800Sstevel@tonic-gate 	if (*buf == NULL) {
30810Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
30820Sstevel@tonic-gate 	}
30830Sstevel@tonic-gate 
30840Sstevel@tonic-gate 	/*
30850Sstevel@tonic-gate 	 * Set fixed address labels by name
30860Sstevel@tonic-gate 	 */
30870Sstevel@tonic-gate 	list_ext_data.num_ap_ids = (params->nlist) ? *(params->nlist) : 0;
30880Sstevel@tonic-gate 	list_ext_data.errstring_size = var_msg_info.errstring_strlen +
30890Sstevel@tonic-gate 	    var_msg_info.errstring_pad_sz;
30900Sstevel@tonic-gate 
30910Sstevel@tonic-gate 	/*
30920Sstevel@tonic-gate 	 * Set variable information using memcpy
30930Sstevel@tonic-gate 	 */
30940Sstevel@tonic-gate 	bufptr = *buf;
30950Sstevel@tonic-gate 
30960Sstevel@tonic-gate 	(void) memcpy(bufptr, &list_ext_data, sizeof (rdr_list_ext_reply_t));
30970Sstevel@tonic-gate 	bufptr += sizeof (rdr_list_ext_reply_t);
30980Sstevel@tonic-gate 
30990Sstevel@tonic-gate 	if ((params->ap_id_list != NULL) && (*(params->ap_id_list) != NULL)) {
31000Sstevel@tonic-gate 		(void) memcpy(bufptr, *(params->ap_id_list), list_data_size);
31010Sstevel@tonic-gate 		bufptr += list_data_size;
31020Sstevel@tonic-gate 	} else if (list_data_size) {
31030Sstevel@tonic-gate 		/*
31040Sstevel@tonic-gate 		 * Something is out of sync. We were expecting
31050Sstevel@tonic-gate 		 * some data to copy, but instead we found a
31060Sstevel@tonic-gate 		 * NULL pointer.
31070Sstevel@tonic-gate 		 */
31080Sstevel@tonic-gate 		(void) free((void *)*buf);
31090Sstevel@tonic-gate 		*buf = NULL;
31100Sstevel@tonic-gate 		return (RDR_ERROR);
31110Sstevel@tonic-gate 	}
31120Sstevel@tonic-gate 
31130Sstevel@tonic-gate 	if ((params->errstring != NULL) && (*(params->errstring) != NULL)) {
31140Sstevel@tonic-gate 		(void) memcpy(bufptr, *(params->errstring),
31150Sstevel@tonic-gate 		    var_msg_info.errstring_strlen);
31160Sstevel@tonic-gate 		bufptr += var_msg_info.errstring_strlen;
31170Sstevel@tonic-gate 		for (i = 0; i < var_msg_info.errstring_pad_sz; i++) {
31180Sstevel@tonic-gate 			bufptr[i] = 0;
31190Sstevel@tonic-gate 		}
31200Sstevel@tonic-gate 		bufptr += var_msg_info.errstring_pad_sz;
31210Sstevel@tonic-gate 	}
31220Sstevel@tonic-gate 
31230Sstevel@tonic-gate 	return (RDR_OK);
31240Sstevel@tonic-gate }
31250Sstevel@tonic-gate 
31260Sstevel@tonic-gate 
31270Sstevel@tonic-gate /*
31280Sstevel@tonic-gate  * unpack_list_ext_reply:
31290Sstevel@tonic-gate  *
31300Sstevel@tonic-gate  * Handle unpacking a list reply message.
31310Sstevel@tonic-gate  */
31320Sstevel@tonic-gate static int
unpack_list_ext_reply(list_ext_params_t * params,const char * buf)31330Sstevel@tonic-gate unpack_list_ext_reply(list_ext_params_t *params, const char *buf)
31340Sstevel@tonic-gate {
31350Sstevel@tonic-gate 	int 			list_data_size;
31360Sstevel@tonic-gate 	char 			*bufptr;
31370Sstevel@tonic-gate 	rdr_list_ext_reply_t	list_ext_data;
31380Sstevel@tonic-gate 
31390Sstevel@tonic-gate 
31400Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
31410Sstevel@tonic-gate 		return (RDR_ERROR);
31420Sstevel@tonic-gate 	}
31430Sstevel@tonic-gate 
31440Sstevel@tonic-gate 	bufptr = (char *)buf;
31450Sstevel@tonic-gate 	(void) memcpy(&list_ext_data, bufptr, sizeof (rdr_list_ext_reply_t));
31460Sstevel@tonic-gate 	bufptr += sizeof (rdr_list_ext_reply_t);
31470Sstevel@tonic-gate 
31480Sstevel@tonic-gate 	/*
31490Sstevel@tonic-gate 	 * handle getting the ap_id rcfga_list_data_t's.
31500Sstevel@tonic-gate 	 */
31510Sstevel@tonic-gate 	if (list_ext_data.num_ap_ids > 0) {
31520Sstevel@tonic-gate 		params->nlist = (int *)malloc(sizeof (int));
31530Sstevel@tonic-gate 		if (params->nlist == NULL) {
31540Sstevel@tonic-gate 			return (RDR_MEM_ALLOC);
31550Sstevel@tonic-gate 		}
31560Sstevel@tonic-gate 		*(params->nlist) = list_ext_data.num_ap_ids;
31570Sstevel@tonic-gate 		params->ap_id_list = (rdr_list_t **)
31580Sstevel@tonic-gate 		    malloc(sizeof (rdr_list_t *));
31590Sstevel@tonic-gate 		if (params->ap_id_list == NULL) {
31600Sstevel@tonic-gate 			return (RDR_MEM_ALLOC);
31610Sstevel@tonic-gate 		}
31620Sstevel@tonic-gate 		*(params->ap_id_list) = (rdr_list_t *)
31630Sstevel@tonic-gate 		malloc(sizeof (rdr_list_t) * list_ext_data.num_ap_ids);
31640Sstevel@tonic-gate 		if (*(params->ap_id_list) == NULL) {
31650Sstevel@tonic-gate 			return (RDR_MEM_ALLOC);
31660Sstevel@tonic-gate 		}
31670Sstevel@tonic-gate 		list_data_size = list_ext_data.num_ap_ids * sizeof (rdr_list_t);
31680Sstevel@tonic-gate 		(void) memcpy(*(params->ap_id_list), bufptr, list_data_size);
31690Sstevel@tonic-gate 		bufptr += list_data_size;
31700Sstevel@tonic-gate 	}
31710Sstevel@tonic-gate 
31720Sstevel@tonic-gate 	/*
31730Sstevel@tonic-gate 	 * handle getting the errstring
31740Sstevel@tonic-gate 	 */
31750Sstevel@tonic-gate 	params->errstring = (char **)malloc(sizeof (char *));
31760Sstevel@tonic-gate 	if (params->errstring == NULL) {
31770Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
31780Sstevel@tonic-gate 	}
31790Sstevel@tonic-gate 	if (get_string_from_buf(params->errstring,
31800Sstevel@tonic-gate 			list_ext_data.errstring_size, bufptr)) {
31810Sstevel@tonic-gate 		return (RDR_ERROR);
31820Sstevel@tonic-gate 	}
31830Sstevel@tonic-gate 	bufptr += list_ext_data.errstring_size;
31840Sstevel@tonic-gate 
31850Sstevel@tonic-gate 	return (RDR_OK);
31860Sstevel@tonic-gate }
31870Sstevel@tonic-gate 
31880Sstevel@tonic-gate 
31890Sstevel@tonic-gate /*
31900Sstevel@tonic-gate  * pack_help_request:
31910Sstevel@tonic-gate  *
31920Sstevel@tonic-gate  * Handle packing a help request message.
31930Sstevel@tonic-gate  */
31940Sstevel@tonic-gate static int
pack_help_request(help_params_t * params,char ** buf,int * buf_size)31950Sstevel@tonic-gate pack_help_request(help_params_t *params, char **buf, int *buf_size)
31960Sstevel@tonic-gate {
31970Sstevel@tonic-gate 	int				i;
31980Sstevel@tonic-gate 	char				*bufptr;
31990Sstevel@tonic-gate 	rdr_help_t			help_data;
32000Sstevel@tonic-gate 	rdr_variable_message_info_t	var_msg_info;
32010Sstevel@tonic-gate 
32020Sstevel@tonic-gate 
32030Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
32040Sstevel@tonic-gate 
32050Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
32060Sstevel@tonic-gate 		return (RDR_ERROR);
32070Sstevel@tonic-gate 	}
32080Sstevel@tonic-gate 
32090Sstevel@tonic-gate 	/*
32100Sstevel@tonic-gate 	 * Set variable length fields and make a call to partially
32110Sstevel@tonic-gate 	 * pack it.
32120Sstevel@tonic-gate 	 */
32130Sstevel@tonic-gate 	if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) {
32140Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
32150Sstevel@tonic-gate 		return (RDR_ERROR);
32160Sstevel@tonic-gate 	}
32170Sstevel@tonic-gate 	if (find_options_sizes(params->options, &var_msg_info)) {
32180Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
32190Sstevel@tonic-gate 		return (RDR_ERROR);
32200Sstevel@tonic-gate 	}
32210Sstevel@tonic-gate 
32220Sstevel@tonic-gate 	/*
32230Sstevel@tonic-gate 	 * Collect size info specific to the help request message and
32240Sstevel@tonic-gate 	 * and allocate a buffer
32250Sstevel@tonic-gate 	 */
32260Sstevel@tonic-gate 	*buf_size = sizeof (rdr_help_t);
32270Sstevel@tonic-gate 	*buf_size += var_msg_info.ap_id_int_size;
32280Sstevel@tonic-gate 	*buf_size += var_msg_info.ap_id_char_size;
32290Sstevel@tonic-gate 	*buf_size += var_msg_info.options_strlen;
32300Sstevel@tonic-gate 	*buf_size += var_msg_info.options_pad_sz;
32310Sstevel@tonic-gate 
32320Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
32330Sstevel@tonic-gate 	if (*buf == NULL) {
32340Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
32350Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
32360Sstevel@tonic-gate 	}
32370Sstevel@tonic-gate 
32380Sstevel@tonic-gate 	/*
32390Sstevel@tonic-gate 	 * Set fixed address labels by name
32400Sstevel@tonic-gate 	 */
32410Sstevel@tonic-gate 	help_data.num_ap_ids = params->num_ap_ids;
32420Sstevel@tonic-gate 	help_data.ap_id_char_size = var_msg_info.ap_id_char_size;
32430Sstevel@tonic-gate 	help_data.options_size = var_msg_info.options_strlen +
32440Sstevel@tonic-gate 	    var_msg_info.options_pad_sz;
32450Sstevel@tonic-gate 
32460Sstevel@tonic-gate 	if (params->msgp != NULL) {
32470Sstevel@tonic-gate 		help_data.msg_callback_id =
32480Sstevel@tonic-gate 		    (unsigned long)params->msgp->message_routine;
32490Sstevel@tonic-gate 		help_data.msg_appdata_ptr =
32500Sstevel@tonic-gate 		    (unsigned long)params->msgp->appdata_ptr;
32510Sstevel@tonic-gate 	} else {
32520Sstevel@tonic-gate 		help_data.msg_callback_id = 0;
32530Sstevel@tonic-gate 		help_data.msg_appdata_ptr = 0;
32540Sstevel@tonic-gate 	}
32550Sstevel@tonic-gate 
32560Sstevel@tonic-gate 	help_data.flags = params->flags;
32570Sstevel@tonic-gate 
32580Sstevel@tonic-gate 	/*
32590Sstevel@tonic-gate 	 * Set variable information using memcpy
32600Sstevel@tonic-gate 	 */
32610Sstevel@tonic-gate 	bufptr = *buf;
32620Sstevel@tonic-gate 
32630Sstevel@tonic-gate 	(void) memcpy(bufptr, &help_data, sizeof (rdr_help_t));
32640Sstevel@tonic-gate 	bufptr += sizeof (rdr_help_t);
32650Sstevel@tonic-gate 
32660Sstevel@tonic-gate 	if (var_msg_info.ap_id_sizes != NULL) {
32670Sstevel@tonic-gate 		(void) memcpy(bufptr, var_msg_info.ap_id_sizes,
32680Sstevel@tonic-gate 		    var_msg_info.ap_id_int_size);
32690Sstevel@tonic-gate 		bufptr += var_msg_info.ap_id_int_size;
32700Sstevel@tonic-gate 	}
32710Sstevel@tonic-gate 
32720Sstevel@tonic-gate 	if (var_msg_info.ap_id_chars != NULL) {
32730Sstevel@tonic-gate 		(void) memcpy(bufptr, var_msg_info.ap_id_chars,
32740Sstevel@tonic-gate 		    var_msg_info.ap_id_char_size);
32750Sstevel@tonic-gate 		bufptr += var_msg_info.ap_id_char_size;
32760Sstevel@tonic-gate 	}
32770Sstevel@tonic-gate 
32780Sstevel@tonic-gate 	if (params->options != NULL) {
32790Sstevel@tonic-gate 		(void) memcpy(bufptr, params->options,
32800Sstevel@tonic-gate 		    var_msg_info.options_strlen);
32810Sstevel@tonic-gate 		bufptr += var_msg_info.options_strlen;
32820Sstevel@tonic-gate 		for (i = 0; i < var_msg_info.options_pad_sz; i++) {
32830Sstevel@tonic-gate 			bufptr[i] = 0;
32840Sstevel@tonic-gate 		}
32850Sstevel@tonic-gate 		bufptr += var_msg_info.options_pad_sz;
32860Sstevel@tonic-gate 	}
32870Sstevel@tonic-gate 
32880Sstevel@tonic-gate 	cleanup_variable_ap_id_info(&var_msg_info);
32890Sstevel@tonic-gate 
32900Sstevel@tonic-gate 	return (RDR_OK);
32910Sstevel@tonic-gate }
32920Sstevel@tonic-gate 
32930Sstevel@tonic-gate 
32940Sstevel@tonic-gate /*
32950Sstevel@tonic-gate  * unpack_help_request:
32960Sstevel@tonic-gate  *
32970Sstevel@tonic-gate  * Handle unpacking a help request message.
32980Sstevel@tonic-gate  */
32990Sstevel@tonic-gate static int
unpack_help_request(help_params_t * params,const char * buf)33000Sstevel@tonic-gate unpack_help_request(help_params_t *params, const char *buf)
33010Sstevel@tonic-gate {
33020Sstevel@tonic-gate 	char				*bufptr;
33030Sstevel@tonic-gate 	rdr_variable_message_info_t 	var_msg_info;
33040Sstevel@tonic-gate 	rdr_help_t			help_data;
33050Sstevel@tonic-gate 
33060Sstevel@tonic-gate 
33070Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
33080Sstevel@tonic-gate 		return (RDR_ERROR);
33090Sstevel@tonic-gate 	}
33100Sstevel@tonic-gate 
33110Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
33120Sstevel@tonic-gate 
33130Sstevel@tonic-gate 	bufptr = (char *)buf;
33140Sstevel@tonic-gate 	(void) memcpy(&help_data, bufptr, sizeof (rdr_help_t));
33150Sstevel@tonic-gate 	bufptr += sizeof (rdr_help_t);
33160Sstevel@tonic-gate 
33170Sstevel@tonic-gate 	/*
33180Sstevel@tonic-gate 	 * handle getting the ap_ids
33190Sstevel@tonic-gate 	 */
33200Sstevel@tonic-gate 	var_msg_info.ap_id_char_size = help_data.ap_id_char_size;
33210Sstevel@tonic-gate 	if (get_ap_ids_from_buf((char ***)&(params->ap_ids),
33220Sstevel@tonic-gate 	    help_data.num_ap_ids, &var_msg_info, bufptr)) {
33230Sstevel@tonic-gate 		return (RDR_ERROR);
33240Sstevel@tonic-gate 	}
33250Sstevel@tonic-gate 	bufptr += var_msg_info.ap_id_int_size;
33260Sstevel@tonic-gate 	bufptr += var_msg_info.ap_id_char_size;
33270Sstevel@tonic-gate 
33280Sstevel@tonic-gate 	/*
33290Sstevel@tonic-gate 	 * handle getting the options
33300Sstevel@tonic-gate 	 */
33310Sstevel@tonic-gate 	if (get_string_from_buf(&(params->options),
33320Sstevel@tonic-gate 	    help_data.options_size, bufptr)) {
33330Sstevel@tonic-gate 		return (RDR_ERROR);
33340Sstevel@tonic-gate 	}
33350Sstevel@tonic-gate 	bufptr += help_data.options_size;
33360Sstevel@tonic-gate 
33370Sstevel@tonic-gate 	/*
33380Sstevel@tonic-gate 	 * Set fixed address labels by name
33390Sstevel@tonic-gate 	 */
33400Sstevel@tonic-gate 	params->num_ap_ids = help_data.num_ap_ids;
33410Sstevel@tonic-gate 
33420Sstevel@tonic-gate 	params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg));
33430Sstevel@tonic-gate 	if (params->msgp == NULL) {
33440Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
33450Sstevel@tonic-gate 	}
33460Sstevel@tonic-gate 
33470Sstevel@tonic-gate 	/* set params->msgp->message_routine using memcpy */
33480Sstevel@tonic-gate 	(void) memcpy((void*)params->msgp, &(help_data.msg_callback_id),
33490Sstevel@tonic-gate 	    sizeof (unsigned long));
33500Sstevel@tonic-gate 
33510Sstevel@tonic-gate 	params->msgp->appdata_ptr = (void*)help_data.msg_appdata_ptr;
33520Sstevel@tonic-gate 	params->flags = help_data.flags;
33530Sstevel@tonic-gate 
33540Sstevel@tonic-gate 	return (RDR_OK);
33550Sstevel@tonic-gate }
33560Sstevel@tonic-gate 
33570Sstevel@tonic-gate 
33580Sstevel@tonic-gate /*
33590Sstevel@tonic-gate  * pack_ap_id_cmp_request:
33600Sstevel@tonic-gate  *
33610Sstevel@tonic-gate  * Handle packing an attachment point comparison request message.
33620Sstevel@tonic-gate  */
33630Sstevel@tonic-gate static int
pack_ap_id_cmp_request(ap_id_cmp_params_t * params,char ** buf,int * buf_size)33640Sstevel@tonic-gate pack_ap_id_cmp_request(ap_id_cmp_params_t *params, char **buf, int *buf_size)
33650Sstevel@tonic-gate {
33660Sstevel@tonic-gate 	int			i;
33670Sstevel@tonic-gate 	char			*bufptr;
33680Sstevel@tonic-gate 	rdr_ap_id_cmp_t		ap_id_cmp_data;
33690Sstevel@tonic-gate 	int			ap_id1_strlen;
33700Sstevel@tonic-gate 	int			ap_id1_pad_sz;
33710Sstevel@tonic-gate 	int			ap_id2_strlen;
33720Sstevel@tonic-gate 	int			ap_id2_pad_sz;
33730Sstevel@tonic-gate 
33740Sstevel@tonic-gate 
33750Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
33760Sstevel@tonic-gate 		return (RDR_ERROR);
33770Sstevel@tonic-gate 	}
33780Sstevel@tonic-gate 
33790Sstevel@tonic-gate 	/*
33800Sstevel@tonic-gate 	 * Set variable length fields and make a call to partially
33810Sstevel@tonic-gate 	 * pack it.
33820Sstevel@tonic-gate 	 */
33830Sstevel@tonic-gate 	if (params->ap_log_id1 != NULL) {
33840Sstevel@tonic-gate 		ap_id1_strlen = strlen(params->ap_log_id1) + 1;
33850Sstevel@tonic-gate 		ap_id1_pad_sz = RDR_ALIGN_64_BIT -
33860Sstevel@tonic-gate 		    (ap_id1_strlen % RDR_ALIGN_64_BIT);
33870Sstevel@tonic-gate 	} else {
33880Sstevel@tonic-gate 		ap_id1_strlen = 0;
33890Sstevel@tonic-gate 		ap_id1_pad_sz = 0;
33900Sstevel@tonic-gate 	}
33910Sstevel@tonic-gate 
33920Sstevel@tonic-gate 	if (params->ap_log_id2 != NULL) {
33930Sstevel@tonic-gate 		ap_id2_strlen = strlen(params->ap_log_id2) + 1;
33940Sstevel@tonic-gate 		ap_id2_pad_sz = RDR_ALIGN_64_BIT -
33950Sstevel@tonic-gate 		    (ap_id2_strlen % RDR_ALIGN_64_BIT);
33960Sstevel@tonic-gate 	} else {
33970Sstevel@tonic-gate 		ap_id2_strlen = 0;
33980Sstevel@tonic-gate 		ap_id2_pad_sz = 0;
33990Sstevel@tonic-gate 	}
34000Sstevel@tonic-gate 
34010Sstevel@tonic-gate 	/*
34020Sstevel@tonic-gate 	 * Collect size info specific to the ap id compare request
34030Sstevel@tonic-gate 	 * message and allocate a buffer
34040Sstevel@tonic-gate 	 */
34050Sstevel@tonic-gate 	*buf_size = sizeof (rdr_ap_id_cmp_t);
34060Sstevel@tonic-gate 	*buf_size += ap_id1_strlen;
34070Sstevel@tonic-gate 	*buf_size += ap_id1_pad_sz;
34080Sstevel@tonic-gate 	*buf_size += ap_id2_strlen;
34090Sstevel@tonic-gate 	*buf_size += ap_id2_pad_sz;
34100Sstevel@tonic-gate 
34110Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
34120Sstevel@tonic-gate 	if (*buf == NULL) {
34130Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
34140Sstevel@tonic-gate 	}
34150Sstevel@tonic-gate 
34160Sstevel@tonic-gate 	/*
34170Sstevel@tonic-gate 	 * Set fixed address labels by name
34180Sstevel@tonic-gate 	 */
34190Sstevel@tonic-gate 	ap_id_cmp_data.ap_id1_size = ap_id1_strlen + ap_id1_pad_sz;
34200Sstevel@tonic-gate 	ap_id_cmp_data.ap_id2_size = ap_id2_strlen + ap_id2_pad_sz;
34210Sstevel@tonic-gate 
34220Sstevel@tonic-gate 
34230Sstevel@tonic-gate 	/*
34240Sstevel@tonic-gate 	 * Set variable information using memcpy
34250Sstevel@tonic-gate 	 */
34260Sstevel@tonic-gate 	bufptr = *buf;
34270Sstevel@tonic-gate 
34280Sstevel@tonic-gate 	(void) memcpy(bufptr, &ap_id_cmp_data, sizeof (rdr_ap_id_cmp_t));
34290Sstevel@tonic-gate 	bufptr += sizeof (rdr_ap_id_cmp_t);
34300Sstevel@tonic-gate 
34310Sstevel@tonic-gate 	if (params->ap_log_id1 != NULL) {
34320Sstevel@tonic-gate 		(void) memcpy(bufptr, params->ap_log_id1, ap_id1_strlen);
34330Sstevel@tonic-gate 		bufptr += ap_id1_strlen;
34340Sstevel@tonic-gate 		for (i = 0; i < ap_id1_pad_sz; i++) {
34350Sstevel@tonic-gate 			bufptr[i] = 0;
34360Sstevel@tonic-gate 		}
34370Sstevel@tonic-gate 		bufptr += ap_id1_pad_sz;
34380Sstevel@tonic-gate 	}
34390Sstevel@tonic-gate 
34400Sstevel@tonic-gate 	if (params->ap_log_id2 != NULL) {
34410Sstevel@tonic-gate 		(void) memcpy(bufptr, params->ap_log_id2, ap_id2_strlen);
34420Sstevel@tonic-gate 		bufptr += ap_id2_strlen;
34430Sstevel@tonic-gate 		for (i = 0; i < ap_id2_pad_sz; i++) {
34440Sstevel@tonic-gate 			bufptr[i] = 0;
34450Sstevel@tonic-gate 		}
34460Sstevel@tonic-gate 		bufptr += ap_id2_pad_sz;
34470Sstevel@tonic-gate 	}
34480Sstevel@tonic-gate 
34490Sstevel@tonic-gate 	return (RDR_OK);
34500Sstevel@tonic-gate }
34510Sstevel@tonic-gate 
34520Sstevel@tonic-gate 
34530Sstevel@tonic-gate /*
34540Sstevel@tonic-gate  * unpack_ap_id_cmp_request:
34550Sstevel@tonic-gate  *
34560Sstevel@tonic-gate  * Handle unpacking an attachment point comparison request message.
34570Sstevel@tonic-gate  */
34580Sstevel@tonic-gate static int
unpack_ap_id_cmp_request(ap_id_cmp_params_t * params,const char * buf)34590Sstevel@tonic-gate unpack_ap_id_cmp_request(ap_id_cmp_params_t *params, const char *buf)
34600Sstevel@tonic-gate {
34610Sstevel@tonic-gate 	char			*bufptr;
34620Sstevel@tonic-gate 	rdr_ap_id_cmp_t		ap_id_cmp_data;
34630Sstevel@tonic-gate 
34640Sstevel@tonic-gate 
34650Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
34660Sstevel@tonic-gate 		return (RDR_ERROR);
34670Sstevel@tonic-gate 	}
34680Sstevel@tonic-gate 
34690Sstevel@tonic-gate 	bufptr = (char *)buf;
34700Sstevel@tonic-gate 	(void) memcpy(&ap_id_cmp_data, bufptr, sizeof (rdr_ap_id_cmp_t));
34710Sstevel@tonic-gate 	bufptr += sizeof (rdr_ap_id_cmp_t);
34720Sstevel@tonic-gate 
34730Sstevel@tonic-gate 	/*
34740Sstevel@tonic-gate 	 * handle getting the cmp ap ids
34750Sstevel@tonic-gate 	 */
34760Sstevel@tonic-gate 	if (get_string_from_buf(&(params->ap_log_id1),
34770Sstevel@tonic-gate 	    ap_id_cmp_data.ap_id1_size, bufptr)) {
34780Sstevel@tonic-gate 		return (RDR_ERROR);
34790Sstevel@tonic-gate 	}
34800Sstevel@tonic-gate 	bufptr += ap_id_cmp_data.ap_id1_size;
34810Sstevel@tonic-gate 
34820Sstevel@tonic-gate 	if (get_string_from_buf(&(params->ap_log_id2),
34830Sstevel@tonic-gate 	    ap_id_cmp_data.ap_id2_size, bufptr)) {
34840Sstevel@tonic-gate 		return (RDR_ERROR);
34850Sstevel@tonic-gate 	}
34860Sstevel@tonic-gate 	bufptr += ap_id_cmp_data.ap_id2_size;
34870Sstevel@tonic-gate 
34880Sstevel@tonic-gate 	return (RDR_OK);
34890Sstevel@tonic-gate }
34900Sstevel@tonic-gate 
34910Sstevel@tonic-gate 
34920Sstevel@tonic-gate /*
34930Sstevel@tonic-gate  * pack_abort_cmd_request:
34940Sstevel@tonic-gate  *
34950Sstevel@tonic-gate  * Handle packing an abort request message.
34960Sstevel@tonic-gate  */
34970Sstevel@tonic-gate static int
pack_abort_cmd_request(abort_cmd_params_t * params,char ** buf,int * buf_size)34980Sstevel@tonic-gate pack_abort_cmd_request(abort_cmd_params_t *params, char **buf, int *buf_size)
34990Sstevel@tonic-gate {
35000Sstevel@tonic-gate 	rdr_abort_cmd_t		abort_cmd_data;
35010Sstevel@tonic-gate 
35020Sstevel@tonic-gate 
35030Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
35040Sstevel@tonic-gate 		return (RDR_ERROR);
35050Sstevel@tonic-gate 	}
35060Sstevel@tonic-gate 
35070Sstevel@tonic-gate 	/*
35080Sstevel@tonic-gate 	 * Collect size info specific to the abort cmd request
35090Sstevel@tonic-gate 	 * message and allocate a buffer
35100Sstevel@tonic-gate 	 */
35110Sstevel@tonic-gate 	*buf_size = sizeof (rdr_abort_cmd_t);
35120Sstevel@tonic-gate 
35130Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
35140Sstevel@tonic-gate 	if (*buf == NULL) {
35150Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
35160Sstevel@tonic-gate 	}
35170Sstevel@tonic-gate 
35180Sstevel@tonic-gate 	/*
35190Sstevel@tonic-gate 	 * Set fixed session identifier
35200Sstevel@tonic-gate 	 */
35210Sstevel@tonic-gate 	abort_cmd_data.session_id = params->session_id;
35220Sstevel@tonic-gate 
35230Sstevel@tonic-gate 	/*
35240Sstevel@tonic-gate 	 * Copy information using memcpy
35250Sstevel@tonic-gate 	 */
35260Sstevel@tonic-gate 	(void) memcpy(*buf, &abort_cmd_data, sizeof (rdr_abort_cmd_t));
35270Sstevel@tonic-gate 
35280Sstevel@tonic-gate 	return (RDR_OK);
35290Sstevel@tonic-gate }
35300Sstevel@tonic-gate 
35310Sstevel@tonic-gate 
35320Sstevel@tonic-gate /*
35330Sstevel@tonic-gate  * unpack_abort_cmd_request:
35340Sstevel@tonic-gate  *
35350Sstevel@tonic-gate  * Handle unpacking an abort request message.
35360Sstevel@tonic-gate  */
35370Sstevel@tonic-gate static int
unpack_abort_cmd_request(abort_cmd_params_t * params,const char * buf)35380Sstevel@tonic-gate unpack_abort_cmd_request(abort_cmd_params_t *params, const char *buf)
35390Sstevel@tonic-gate {
35400Sstevel@tonic-gate 	rdr_abort_cmd_t		*abort_cmd_datap;
35410Sstevel@tonic-gate 
35420Sstevel@tonic-gate 
35430Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
35440Sstevel@tonic-gate 		return (RDR_ERROR);
35450Sstevel@tonic-gate 	}
35460Sstevel@tonic-gate 
35470Sstevel@tonic-gate 	/* LINTED Pointer Cast Alignment Warning */
35480Sstevel@tonic-gate 	abort_cmd_datap = (rdr_abort_cmd_t *)buf;
35490Sstevel@tonic-gate 
35500Sstevel@tonic-gate 	/*
35510Sstevel@tonic-gate 	 * copy out the session information
35520Sstevel@tonic-gate 	 */
35530Sstevel@tonic-gate 
35540Sstevel@tonic-gate 	params->session_id = abort_cmd_datap->session_id;
35550Sstevel@tonic-gate 
35560Sstevel@tonic-gate 	return (RDR_OK);
35570Sstevel@tonic-gate }
35580Sstevel@tonic-gate 
35590Sstevel@tonic-gate 
35600Sstevel@tonic-gate /*
35610Sstevel@tonic-gate  * pack_confirm_request:
35620Sstevel@tonic-gate  *
35630Sstevel@tonic-gate  * Handle packing a confirm callback request.
35640Sstevel@tonic-gate  */
35650Sstevel@tonic-gate static int
pack_confirm_request(confirm_callback_params_t * params,char ** buf,int * buf_size)35660Sstevel@tonic-gate pack_confirm_request(confirm_callback_params_t *params, char **buf,
35670Sstevel@tonic-gate     int *buf_size)
35680Sstevel@tonic-gate {
35690Sstevel@tonic-gate 	int				i;
35700Sstevel@tonic-gate 	char				*bufptr;
35710Sstevel@tonic-gate 	rdr_confirm_callback_t		confirm_callback_data;
35720Sstevel@tonic-gate 	int 				message_strlen;
35730Sstevel@tonic-gate 	int 				message_pad_sz;
35740Sstevel@tonic-gate 
35750Sstevel@tonic-gate 
35760Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
35770Sstevel@tonic-gate 		return (RDR_ERROR);
35780Sstevel@tonic-gate 	}
35790Sstevel@tonic-gate 
35800Sstevel@tonic-gate 	/*
35810Sstevel@tonic-gate 	 * Set variable length fields and make a call to partially
35820Sstevel@tonic-gate 	 * pack it.
35830Sstevel@tonic-gate 	 */
35840Sstevel@tonic-gate 	if (params->message != NULL) {
35850Sstevel@tonic-gate 		message_strlen = strlen(params->message) + 1;
35860Sstevel@tonic-gate 		message_pad_sz = RDR_ALIGN_64_BIT -
35870Sstevel@tonic-gate 		    (message_strlen % RDR_ALIGN_64_BIT);
35880Sstevel@tonic-gate 	} else {
35890Sstevel@tonic-gate 		message_strlen = 0;
35900Sstevel@tonic-gate 		message_pad_sz = 0;
35910Sstevel@tonic-gate 	}
35920Sstevel@tonic-gate 
35930Sstevel@tonic-gate 
35940Sstevel@tonic-gate 	/*
35950Sstevel@tonic-gate 	 * Collect size info specific to the confirm callback request
35960Sstevel@tonic-gate 	 * message and allocate a buffer
35970Sstevel@tonic-gate 	 */
35980Sstevel@tonic-gate 	*buf_size = sizeof (rdr_confirm_callback_t);
35990Sstevel@tonic-gate 	*buf_size += message_strlen;
36000Sstevel@tonic-gate 	*buf_size += message_pad_sz;
36010Sstevel@tonic-gate 
36020Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
36030Sstevel@tonic-gate 	if (*buf == NULL) {
36040Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
36050Sstevel@tonic-gate 	}
36060Sstevel@tonic-gate 
36070Sstevel@tonic-gate 	/*
36080Sstevel@tonic-gate 	 * Set fixed address labels by name
36090Sstevel@tonic-gate 	 */
36100Sstevel@tonic-gate 	if (params->confp != NULL) {
36110Sstevel@tonic-gate 		confirm_callback_data.confirm_callback_id =
36120Sstevel@tonic-gate 		    (unsigned long)params->confp->confirm;
36130Sstevel@tonic-gate 		confirm_callback_data.appdata_ptr =
36140Sstevel@tonic-gate 		    (unsigned long)params->confp->appdata_ptr;
36150Sstevel@tonic-gate 	} else {
36160Sstevel@tonic-gate 		confirm_callback_data.confirm_callback_id = 0;
36170Sstevel@tonic-gate 		confirm_callback_data.appdata_ptr = 0;
36180Sstevel@tonic-gate 	}
36190Sstevel@tonic-gate 	confirm_callback_data.message_size = message_strlen + message_pad_sz;
36200Sstevel@tonic-gate 
36210Sstevel@tonic-gate 	/*
36220Sstevel@tonic-gate 	 * Set variable information using memcpy
36230Sstevel@tonic-gate 	 */
36240Sstevel@tonic-gate 	bufptr = *buf;
36250Sstevel@tonic-gate 	(void) memcpy(bufptr, &confirm_callback_data,
36260Sstevel@tonic-gate 	    sizeof (rdr_confirm_callback_t));
36270Sstevel@tonic-gate 	bufptr += sizeof (rdr_confirm_callback_t);
36280Sstevel@tonic-gate 
36290Sstevel@tonic-gate 	if (params->message != NULL) {
36300Sstevel@tonic-gate 		(void) memcpy(bufptr, params->message, message_strlen);
36310Sstevel@tonic-gate 		bufptr += message_strlen;
36320Sstevel@tonic-gate 		for (i = 0; i < message_pad_sz; i++) {
36330Sstevel@tonic-gate 			bufptr[i] = 0;
36340Sstevel@tonic-gate 		}
36350Sstevel@tonic-gate 		bufptr += message_pad_sz;
36360Sstevel@tonic-gate 	}
36370Sstevel@tonic-gate 
36380Sstevel@tonic-gate 	return (RDR_OK);
36390Sstevel@tonic-gate }
36400Sstevel@tonic-gate 
36410Sstevel@tonic-gate 
36420Sstevel@tonic-gate /*
36430Sstevel@tonic-gate  * unpack_confirm_request:
36440Sstevel@tonic-gate  *
36450Sstevel@tonic-gate  * Handle unpacking a confirm callback request.
36460Sstevel@tonic-gate  */
36470Sstevel@tonic-gate static int
unpack_confirm_request(confirm_callback_params_t * params,const char * buf)36480Sstevel@tonic-gate unpack_confirm_request(confirm_callback_params_t *params, const char *buf)
36490Sstevel@tonic-gate {
36500Sstevel@tonic-gate 	char				*bufptr;
36510Sstevel@tonic-gate 	rdr_confirm_callback_t		confirm_callback_data;
36520Sstevel@tonic-gate 
36530Sstevel@tonic-gate 
36540Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
36550Sstevel@tonic-gate 		return (RDR_ERROR);
36560Sstevel@tonic-gate 	}
36570Sstevel@tonic-gate 
36580Sstevel@tonic-gate 	bufptr = (char *)buf;
36590Sstevel@tonic-gate 	(void) memcpy(&confirm_callback_data, bufptr,
36600Sstevel@tonic-gate 	    sizeof (rdr_confirm_callback_t));
36610Sstevel@tonic-gate 	bufptr += sizeof (rdr_confirm_callback_t);
36620Sstevel@tonic-gate 
36630Sstevel@tonic-gate 	/*
36640Sstevel@tonic-gate 	 * handle getting the message text
36650Sstevel@tonic-gate 	 */
36660Sstevel@tonic-gate 	if (get_string_from_buf(&(params->message),
36670Sstevel@tonic-gate 	    confirm_callback_data.message_size, bufptr)) {
36680Sstevel@tonic-gate 		return (RDR_ERROR);
36690Sstevel@tonic-gate 	}
36700Sstevel@tonic-gate 	bufptr += confirm_callback_data.message_size;
36710Sstevel@tonic-gate 
36720Sstevel@tonic-gate 	/*
36730Sstevel@tonic-gate 	 * Set fixed address labels by name
36740Sstevel@tonic-gate 	 */
36750Sstevel@tonic-gate 	params->confp = (struct cfga_confirm *)
36760Sstevel@tonic-gate 	    malloc(sizeof (struct cfga_confirm));
36770Sstevel@tonic-gate 	if (params->confp == NULL) {
36780Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
36790Sstevel@tonic-gate 	}
36800Sstevel@tonic-gate 
36810Sstevel@tonic-gate 	/* set params->confp->confirm using memcpy */
36820Sstevel@tonic-gate 	(void) memcpy((void*)params->confp,
36830Sstevel@tonic-gate 	    &(confirm_callback_data.confirm_callback_id),
36840Sstevel@tonic-gate 	    sizeof (unsigned long));
36850Sstevel@tonic-gate 
36860Sstevel@tonic-gate 	params->confp->appdata_ptr =
36870Sstevel@tonic-gate 	    (void*)confirm_callback_data.appdata_ptr;
36880Sstevel@tonic-gate 
36890Sstevel@tonic-gate 	return (RDR_OK);
36900Sstevel@tonic-gate }
36910Sstevel@tonic-gate 
36920Sstevel@tonic-gate 
36930Sstevel@tonic-gate /*
36940Sstevel@tonic-gate  * pack_confirm_reply:
36950Sstevel@tonic-gate  *
36960Sstevel@tonic-gate  * Handle packing a confirm callback reply.
36970Sstevel@tonic-gate  */
36980Sstevel@tonic-gate static int
pack_confirm_reply(confirm_callback_params_t * params,char ** buf,int * buf_size)36990Sstevel@tonic-gate pack_confirm_reply(confirm_callback_params_t *params, char **buf, int *buf_size)
37000Sstevel@tonic-gate {
37010Sstevel@tonic-gate 	char				*bufptr;
37020Sstevel@tonic-gate 	rdr_confirm_callback_reply_t	confirm_callback_data;
37030Sstevel@tonic-gate 
37040Sstevel@tonic-gate 
37050Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
37060Sstevel@tonic-gate 		return (RDR_ERROR);
37070Sstevel@tonic-gate 	}
37080Sstevel@tonic-gate 
37090Sstevel@tonic-gate 	/*
37100Sstevel@tonic-gate 	 * Collect size info specific to the confirm callback reply
37110Sstevel@tonic-gate 	 * message and allocate a buffer
37120Sstevel@tonic-gate 	 */
37130Sstevel@tonic-gate 	*buf_size = sizeof (confirm_callback_params_t);
37140Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
37150Sstevel@tonic-gate 	if (*buf == NULL) {
37160Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
37170Sstevel@tonic-gate 	}
37180Sstevel@tonic-gate 
37190Sstevel@tonic-gate 	/*
37200Sstevel@tonic-gate 	 * Set fixed address labels by name
37210Sstevel@tonic-gate 	 */
37220Sstevel@tonic-gate 	if (params->confp != NULL) {
37230Sstevel@tonic-gate 		confirm_callback_data.confirm_callback_id =
37240Sstevel@tonic-gate 		    (unsigned long)params->confp->confirm;
37250Sstevel@tonic-gate 		confirm_callback_data.appdata_ptr =
37260Sstevel@tonic-gate 		    (unsigned long)params->confp->appdata_ptr;
37270Sstevel@tonic-gate 	} else {
37280Sstevel@tonic-gate 		confirm_callback_data.confirm_callback_id = 0;
37290Sstevel@tonic-gate 		confirm_callback_data.appdata_ptr = 0;
37300Sstevel@tonic-gate 	}
37310Sstevel@tonic-gate 	confirm_callback_data.response = params->response;
37320Sstevel@tonic-gate 
37330Sstevel@tonic-gate 	/*
37340Sstevel@tonic-gate 	 * Set variable information using memcpy
37350Sstevel@tonic-gate 	 */
37360Sstevel@tonic-gate 	bufptr = *buf;
37370Sstevel@tonic-gate 
37380Sstevel@tonic-gate 	(void) memcpy(bufptr, &confirm_callback_data,
37390Sstevel@tonic-gate 	    sizeof (rdr_confirm_callback_reply_t));
37400Sstevel@tonic-gate 
37410Sstevel@tonic-gate 	return (RDR_OK);
37420Sstevel@tonic-gate }
37430Sstevel@tonic-gate 
37440Sstevel@tonic-gate 
37450Sstevel@tonic-gate /*
37460Sstevel@tonic-gate  * unpack_confirm_reply:
37470Sstevel@tonic-gate  *
37480Sstevel@tonic-gate  * Handle unpacking a confirm callback reply.
37490Sstevel@tonic-gate  */
37500Sstevel@tonic-gate static int
unpack_confirm_reply(confirm_callback_params_t * params,const char * buf)37510Sstevel@tonic-gate unpack_confirm_reply(confirm_callback_params_t *params, const char *buf)
37520Sstevel@tonic-gate {
37530Sstevel@tonic-gate 	char				*bufptr;
37540Sstevel@tonic-gate 	rdr_confirm_callback_reply_t	confirm_callback_data;
37550Sstevel@tonic-gate 
37560Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
37570Sstevel@tonic-gate 		return (RDR_ERROR);
37580Sstevel@tonic-gate 	}
37590Sstevel@tonic-gate 
37600Sstevel@tonic-gate 	bufptr = (char *)buf;
37610Sstevel@tonic-gate 	(void) memcpy(&confirm_callback_data, bufptr,
37620Sstevel@tonic-gate 	    sizeof (rdr_confirm_callback_reply_t));
37630Sstevel@tonic-gate 	bufptr += sizeof (confirm_callback_params_t);
37640Sstevel@tonic-gate 
37650Sstevel@tonic-gate 	/*
37660Sstevel@tonic-gate 	 * Set fixed address labels by name
37670Sstevel@tonic-gate 	 */
37680Sstevel@tonic-gate 	params->confp = (struct cfga_confirm *)
37690Sstevel@tonic-gate 	    malloc(sizeof (struct cfga_confirm));
37700Sstevel@tonic-gate 	if (params->confp == NULL) {
37710Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
37720Sstevel@tonic-gate 	}
37730Sstevel@tonic-gate 
37740Sstevel@tonic-gate 	/* set params->confp->confirm using memcpy */
37750Sstevel@tonic-gate 	(void) memcpy((void*)params->confp,
37760Sstevel@tonic-gate 	    &(confirm_callback_data.confirm_callback_id),
37770Sstevel@tonic-gate 	    sizeof (unsigned long));
37780Sstevel@tonic-gate 
37790Sstevel@tonic-gate 	params->confp->appdata_ptr =
37800Sstevel@tonic-gate 	    (void*)confirm_callback_data.appdata_ptr;
37810Sstevel@tonic-gate 	params->response = confirm_callback_data.response;
37820Sstevel@tonic-gate 
37830Sstevel@tonic-gate 	return (RDR_OK);
37840Sstevel@tonic-gate }
37850Sstevel@tonic-gate 
37860Sstevel@tonic-gate 
37870Sstevel@tonic-gate /*
37880Sstevel@tonic-gate  * pack_message_request:
37890Sstevel@tonic-gate  *
37900Sstevel@tonic-gate  * Handle packing a message callback request.
37910Sstevel@tonic-gate  */
37920Sstevel@tonic-gate static int
pack_message_request(msg_callback_params_t * params,char ** buf,int * buf_size)37930Sstevel@tonic-gate pack_message_request(msg_callback_params_t *params, char **buf, int *buf_size)
37940Sstevel@tonic-gate {
37950Sstevel@tonic-gate 	int			i;
37960Sstevel@tonic-gate 	char			*bufptr;
37970Sstevel@tonic-gate 	rdr_msg_callback_t	msg_callback_data;
37980Sstevel@tonic-gate 	int			message_strlen;
37990Sstevel@tonic-gate 	int			message_pad_sz;
38000Sstevel@tonic-gate 
38010Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
38020Sstevel@tonic-gate 		return (RDR_ERROR);
38030Sstevel@tonic-gate 	}
38040Sstevel@tonic-gate 
38050Sstevel@tonic-gate 	/*
38060Sstevel@tonic-gate 	 * Set variable length fields and make a call to partially
38070Sstevel@tonic-gate 	 * pack it.
38080Sstevel@tonic-gate 	 */
38090Sstevel@tonic-gate 	if (params->message != NULL) {
38100Sstevel@tonic-gate 		message_strlen = strlen(params->message) + 1;
38110Sstevel@tonic-gate 		message_pad_sz = RDR_ALIGN_64_BIT -
38120Sstevel@tonic-gate 		    (message_strlen % RDR_ALIGN_64_BIT);
38130Sstevel@tonic-gate 	} else {
38140Sstevel@tonic-gate 		message_strlen = 0;
38150Sstevel@tonic-gate 		message_pad_sz = 0;
38160Sstevel@tonic-gate 	}
38170Sstevel@tonic-gate 
38180Sstevel@tonic-gate 
38190Sstevel@tonic-gate 	/*
38200Sstevel@tonic-gate 	 * Collect size info specific to the message callback request
38210Sstevel@tonic-gate 	 * message and allocate a buffer
38220Sstevel@tonic-gate 	 */
38230Sstevel@tonic-gate 	*buf_size = sizeof (rdr_msg_callback_t);
38240Sstevel@tonic-gate 	*buf_size += message_strlen;
38250Sstevel@tonic-gate 	*buf_size += message_pad_sz;
38260Sstevel@tonic-gate 
38270Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
38280Sstevel@tonic-gate 	if (*buf == NULL) {
38290Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
38300Sstevel@tonic-gate 	}
38310Sstevel@tonic-gate 
38320Sstevel@tonic-gate 	/*
38330Sstevel@tonic-gate 	 * Set fixed address labels by name
38340Sstevel@tonic-gate 	 */
38350Sstevel@tonic-gate 	if (params->msgp != NULL) {
38360Sstevel@tonic-gate 		msg_callback_data.msg_callback_id =
38370Sstevel@tonic-gate 		    (unsigned long)params->msgp->message_routine;
38380Sstevel@tonic-gate 		msg_callback_data.appdata_ptr =
38390Sstevel@tonic-gate 		    (unsigned long)params->msgp->appdata_ptr;
38400Sstevel@tonic-gate 	} else {
38410Sstevel@tonic-gate 		msg_callback_data.msg_callback_id = 0;
38420Sstevel@tonic-gate 		msg_callback_data.appdata_ptr = 0;
38430Sstevel@tonic-gate 	}
38440Sstevel@tonic-gate 	msg_callback_data.message_size = message_strlen + message_pad_sz;
38450Sstevel@tonic-gate 
38460Sstevel@tonic-gate 	/*
38470Sstevel@tonic-gate 	 * Set variable information using memcpy
38480Sstevel@tonic-gate 	 */
38490Sstevel@tonic-gate 	bufptr = *buf;
38500Sstevel@tonic-gate 
38510Sstevel@tonic-gate 	(void) memcpy(bufptr, &msg_callback_data, sizeof (rdr_msg_callback_t));
38520Sstevel@tonic-gate 	bufptr += sizeof (rdr_msg_callback_t);
38530Sstevel@tonic-gate 
38540Sstevel@tonic-gate 	if (params->message != NULL) {
38550Sstevel@tonic-gate 		(void) memcpy(bufptr, params->message, message_strlen);
38560Sstevel@tonic-gate 		bufptr += message_strlen;
38570Sstevel@tonic-gate 		for (i = 0; i < message_pad_sz; i++) {
38580Sstevel@tonic-gate 			bufptr[i] = 0;
38590Sstevel@tonic-gate 		}
38600Sstevel@tonic-gate 		bufptr += message_pad_sz;
38610Sstevel@tonic-gate 	}
38620Sstevel@tonic-gate 
38630Sstevel@tonic-gate 	return (RDR_OK);
38640Sstevel@tonic-gate }
38650Sstevel@tonic-gate 
38660Sstevel@tonic-gate 
38670Sstevel@tonic-gate /*
38680Sstevel@tonic-gate  * unpack_message_request:
38690Sstevel@tonic-gate  *
38700Sstevel@tonic-gate  * Handle unpacking a message callback request.
38710Sstevel@tonic-gate  */
38720Sstevel@tonic-gate static int
unpack_message_request(msg_callback_params_t * params,const char * buf)38730Sstevel@tonic-gate unpack_message_request(msg_callback_params_t *params, const char *buf)
38740Sstevel@tonic-gate {
38750Sstevel@tonic-gate 	char			*bufptr;
38760Sstevel@tonic-gate 	rdr_msg_callback_t	msg_callback_data;
38770Sstevel@tonic-gate 
38780Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
38790Sstevel@tonic-gate 		return (RDR_ERROR);
38800Sstevel@tonic-gate 	}
38810Sstevel@tonic-gate 
38820Sstevel@tonic-gate 	bufptr = (char *)buf;
38830Sstevel@tonic-gate 	(void) memcpy(&msg_callback_data, bufptr, sizeof (rdr_msg_callback_t));
38840Sstevel@tonic-gate 	bufptr += sizeof (rdr_msg_callback_t);
38850Sstevel@tonic-gate 
38860Sstevel@tonic-gate 	/*
38870Sstevel@tonic-gate 	 * handle getting the message text
38880Sstevel@tonic-gate 	 */
38890Sstevel@tonic-gate 	if (get_string_from_buf(&(params->message),
38900Sstevel@tonic-gate 	    msg_callback_data.message_size, bufptr)) {
38910Sstevel@tonic-gate 		return (RDR_ERROR);
38920Sstevel@tonic-gate 	}
38930Sstevel@tonic-gate 	bufptr += msg_callback_data.message_size;
38940Sstevel@tonic-gate 
38950Sstevel@tonic-gate 	/*
38960Sstevel@tonic-gate 	 * Set fixed address labels by name
38970Sstevel@tonic-gate 	 */
38980Sstevel@tonic-gate 	params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg));
38990Sstevel@tonic-gate 	if (params->msgp == NULL) {
39000Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
39010Sstevel@tonic-gate 	}
39020Sstevel@tonic-gate 
39030Sstevel@tonic-gate 	/* set params->msgp->message_routine using memcpy */
39040Sstevel@tonic-gate 	(void) memcpy((void*)params->msgp, &(msg_callback_data.msg_callback_id),
39050Sstevel@tonic-gate 	    sizeof (unsigned long));
39060Sstevel@tonic-gate 
39070Sstevel@tonic-gate 	params->msgp->appdata_ptr = (void*)msg_callback_data.appdata_ptr;
39080Sstevel@tonic-gate 
39090Sstevel@tonic-gate 	return (RDR_OK);
39100Sstevel@tonic-gate }
39110Sstevel@tonic-gate 
39120Sstevel@tonic-gate /*
39130Sstevel@tonic-gate  * pack_rsrc_info_request:
39140Sstevel@tonic-gate  *
39150Sstevel@tonic-gate  * Handle packing a resource info request.
39160Sstevel@tonic-gate  */
39170Sstevel@tonic-gate static int
pack_rsrc_info_request(rsrc_info_params_t * params,char ** buf,int * buf_size)39180Sstevel@tonic-gate pack_rsrc_info_request(rsrc_info_params_t *params, char **buf, int *buf_size)
39190Sstevel@tonic-gate {
39200Sstevel@tonic-gate 	char				*bufptr;
39210Sstevel@tonic-gate 	rdr_rsrc_info_t			rsrc_info_data;
39220Sstevel@tonic-gate 	rdr_variable_message_info_t 	var_msg_info;
39230Sstevel@tonic-gate 
39240Sstevel@tonic-gate 
39250Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
39260Sstevel@tonic-gate 		return (RDR_ERROR);
39270Sstevel@tonic-gate 	}
39280Sstevel@tonic-gate 
39290Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
39300Sstevel@tonic-gate 
39310Sstevel@tonic-gate 	/*
39320Sstevel@tonic-gate 	 * Set variable length fields and make a call to partially
39330Sstevel@tonic-gate 	 * pack it.
39340Sstevel@tonic-gate 	 */
39350Sstevel@tonic-gate 	if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) {
39360Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
39370Sstevel@tonic-gate 		return (RDR_ERROR);
39380Sstevel@tonic-gate 	}
39390Sstevel@tonic-gate 
39400Sstevel@tonic-gate 	/*
39410Sstevel@tonic-gate 	 * Collect size info specific to the resource info request
39420Sstevel@tonic-gate 	 * message and allocate a buffer.
39430Sstevel@tonic-gate 	 */
39440Sstevel@tonic-gate 	*buf_size = sizeof (rdr_rsrc_info_t);
39450Sstevel@tonic-gate 	*buf_size += var_msg_info.ap_id_int_size;
39460Sstevel@tonic-gate 	*buf_size += var_msg_info.ap_id_char_size;
39470Sstevel@tonic-gate 
39480Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
39490Sstevel@tonic-gate 	if (*buf == NULL) {
39500Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
39510Sstevel@tonic-gate 	}
39520Sstevel@tonic-gate 
39530Sstevel@tonic-gate 	/*
39540Sstevel@tonic-gate 	 * Set fixed address labels by name.
39550Sstevel@tonic-gate 	 */
39560Sstevel@tonic-gate 	rsrc_info_data.num_ap_ids = params->num_ap_ids;
39570Sstevel@tonic-gate 	rsrc_info_data.ap_id_char_size = var_msg_info.ap_id_char_size;
39580Sstevel@tonic-gate 	rsrc_info_data.flags = params->flags;
39590Sstevel@tonic-gate 
39600Sstevel@tonic-gate 	/*
39610Sstevel@tonic-gate 	 * Set variable information using memcpy.
39620Sstevel@tonic-gate 	 */
39630Sstevel@tonic-gate 	bufptr = *buf;
39640Sstevel@tonic-gate 
39650Sstevel@tonic-gate 	(void) memcpy(bufptr, &rsrc_info_data, sizeof (rdr_rsrc_info_t));
39660Sstevel@tonic-gate 	bufptr += sizeof (rdr_rsrc_info_t);
39670Sstevel@tonic-gate 
39680Sstevel@tonic-gate 	if (var_msg_info.ap_id_sizes != NULL) {
39690Sstevel@tonic-gate 		(void) memcpy(bufptr, var_msg_info.ap_id_sizes,
39700Sstevel@tonic-gate 		    var_msg_info.ap_id_int_size);
39710Sstevel@tonic-gate 		bufptr += var_msg_info.ap_id_int_size;
39720Sstevel@tonic-gate 	}
39730Sstevel@tonic-gate 
39740Sstevel@tonic-gate 	if (var_msg_info.ap_id_chars != NULL) {
39750Sstevel@tonic-gate 		(void) memcpy(bufptr, var_msg_info.ap_id_chars,
39760Sstevel@tonic-gate 		    var_msg_info.ap_id_char_size);
39770Sstevel@tonic-gate 		bufptr += var_msg_info.ap_id_char_size;
39780Sstevel@tonic-gate 	}
39790Sstevel@tonic-gate 
39800Sstevel@tonic-gate 	cleanup_variable_ap_id_info(&var_msg_info);
39810Sstevel@tonic-gate 
39820Sstevel@tonic-gate 	return (RDR_OK);
39830Sstevel@tonic-gate }
39840Sstevel@tonic-gate 
39850Sstevel@tonic-gate 
39860Sstevel@tonic-gate /*
39870Sstevel@tonic-gate  * unpack_rsrc_info_request:
39880Sstevel@tonic-gate  *
39890Sstevel@tonic-gate  * Handle unpacking a resource info request message.
39900Sstevel@tonic-gate  */
39910Sstevel@tonic-gate static int
unpack_rsrc_info_request(rsrc_info_params_t * params,const char * buf)39920Sstevel@tonic-gate unpack_rsrc_info_request(rsrc_info_params_t *params, const char *buf)
39930Sstevel@tonic-gate {
39940Sstevel@tonic-gate 	char				*bufptr;
39950Sstevel@tonic-gate 	rdr_variable_message_info_t 	var_msg_info;
39960Sstevel@tonic-gate 	rdr_rsrc_info_t			rsrc_info_data;
39970Sstevel@tonic-gate 
39980Sstevel@tonic-gate 
39990Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
40000Sstevel@tonic-gate 		return (RDR_ERROR);
40010Sstevel@tonic-gate 	}
40020Sstevel@tonic-gate 
40030Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
40040Sstevel@tonic-gate 
40050Sstevel@tonic-gate 	bufptr = (char *)buf;
40060Sstevel@tonic-gate 	(void) memcpy(&rsrc_info_data, bufptr, sizeof (rdr_rsrc_info_t));
40070Sstevel@tonic-gate 	bufptr += sizeof (rdr_rsrc_info_t);
40080Sstevel@tonic-gate 
40090Sstevel@tonic-gate 	/*
40100Sstevel@tonic-gate 	 * Handle getting the ap_ids.
40110Sstevel@tonic-gate 	 */
40120Sstevel@tonic-gate 	var_msg_info.ap_id_char_size = rsrc_info_data.ap_id_char_size;
40130Sstevel@tonic-gate 	if (get_ap_ids_from_buf(&(params->ap_ids), rsrc_info_data.num_ap_ids,
40140Sstevel@tonic-gate 	    &var_msg_info, bufptr)) {
40150Sstevel@tonic-gate 		return (RDR_ERROR);
40160Sstevel@tonic-gate 	}
40170Sstevel@tonic-gate 	bufptr += var_msg_info.ap_id_int_size;
40180Sstevel@tonic-gate 	bufptr += var_msg_info.ap_id_char_size;
40190Sstevel@tonic-gate 
40200Sstevel@tonic-gate 	/*
40210Sstevel@tonic-gate 	 * Set fixed address labels by name.
40220Sstevel@tonic-gate 	 */
40230Sstevel@tonic-gate 	params->num_ap_ids = rsrc_info_data.num_ap_ids;
40240Sstevel@tonic-gate 	params->flags = rsrc_info_data.flags;
40250Sstevel@tonic-gate 
40260Sstevel@tonic-gate 	return (RDR_OK);
40270Sstevel@tonic-gate }
40280Sstevel@tonic-gate 
40290Sstevel@tonic-gate 
40300Sstevel@tonic-gate /*
40310Sstevel@tonic-gate  * pack_rsrc_info_reply:
40320Sstevel@tonic-gate  *
40330Sstevel@tonic-gate  * Handle packing a resource info reply message.
40340Sstevel@tonic-gate  */
40350Sstevel@tonic-gate static int
pack_rsrc_info_reply(rsrc_info_params_t * params,char ** buf,int * buf_size,int encoding)4036*1772Sjl139090 pack_rsrc_info_reply(rsrc_info_params_t *params, char **buf, int *buf_size,
4037*1772Sjl139090     int encoding)
40380Sstevel@tonic-gate {
40390Sstevel@tonic-gate 	char				*bufptr;
40400Sstevel@tonic-gate 	rdr_rsrc_info_reply_t		rsrc_info_data;
40410Sstevel@tonic-gate 	int				pack_status;
40420Sstevel@tonic-gate 	caddr_t				rsrc_info_bufp = NULL;
40430Sstevel@tonic-gate 	size_t 				rsrc_info_size;
40440Sstevel@tonic-gate 
40450Sstevel@tonic-gate 
40460Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
40470Sstevel@tonic-gate 		return (RDR_ERROR);
40480Sstevel@tonic-gate 	}
40490Sstevel@tonic-gate 
40500Sstevel@tonic-gate 	/*
40510Sstevel@tonic-gate 	 * Pack snapshot handle data.
40520Sstevel@tonic-gate 	 */
4053*1772Sjl139090 	pack_status = ri_pack(params->hdl, &rsrc_info_bufp, &rsrc_info_size,
4054*1772Sjl139090 	    encoding);
40550Sstevel@tonic-gate 	if (pack_status != 0) {
40560Sstevel@tonic-gate 		return (RDR_ERROR);
40570Sstevel@tonic-gate 	}
40580Sstevel@tonic-gate 
40590Sstevel@tonic-gate 	/*
40600Sstevel@tonic-gate 	 * Collect size info specific to the rsrc_info reply message
40610Sstevel@tonic-gate 	 * and allocate a buffer.
40620Sstevel@tonic-gate 	 */
40630Sstevel@tonic-gate 	*buf_size = sizeof (rdr_rsrc_info_reply_t);
40640Sstevel@tonic-gate 	*buf_size += rsrc_info_size;
40650Sstevel@tonic-gate 
40660Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
40670Sstevel@tonic-gate 	if (*buf == NULL) {
40680Sstevel@tonic-gate 		free(rsrc_info_bufp);
40690Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
40700Sstevel@tonic-gate 	}
40710Sstevel@tonic-gate 
40720Sstevel@tonic-gate 	/*
40730Sstevel@tonic-gate 	 * Set fixed address labels by name.
40740Sstevel@tonic-gate 	 */
40750Sstevel@tonic-gate 	rsrc_info_data.packed_hdl_size = rsrc_info_size;
40760Sstevel@tonic-gate 
40770Sstevel@tonic-gate 	/*
40780Sstevel@tonic-gate 	 * Set variable information using memcpy.
40790Sstevel@tonic-gate 	 */
40800Sstevel@tonic-gate 	bufptr = *buf;
40810Sstevel@tonic-gate 
40820Sstevel@tonic-gate 	(void) memcpy(bufptr, &rsrc_info_data, sizeof (rdr_rsrc_info_reply_t));
40830Sstevel@tonic-gate 	bufptr += sizeof (rdr_rsrc_info_reply_t);
40840Sstevel@tonic-gate 
40850Sstevel@tonic-gate 	if (rsrc_info_bufp) {
40860Sstevel@tonic-gate 		(void) memcpy(bufptr, rsrc_info_bufp, rsrc_info_size);
40870Sstevel@tonic-gate 		free(rsrc_info_bufp);
40880Sstevel@tonic-gate 	}
40890Sstevel@tonic-gate 
40900Sstevel@tonic-gate 	return (RDR_OK);
40910Sstevel@tonic-gate }
40920Sstevel@tonic-gate 
40930Sstevel@tonic-gate 
40940Sstevel@tonic-gate /*
40950Sstevel@tonic-gate  * unpack_rsrc_info_reply:
40960Sstevel@tonic-gate  *
40970Sstevel@tonic-gate  * Handle unpacking a resource info reply message.
40980Sstevel@tonic-gate  */
40990Sstevel@tonic-gate static int
unpack_rsrc_info_reply(rsrc_info_params_t * params,const char * buf)41000Sstevel@tonic-gate unpack_rsrc_info_reply(rsrc_info_params_t *params, const char *buf)
41010Sstevel@tonic-gate {
41020Sstevel@tonic-gate 	int			unpack_status;
41030Sstevel@tonic-gate 	char 			*bufptr;
41040Sstevel@tonic-gate 	rdr_rsrc_info_reply_t	rsrc_info_data;
41050Sstevel@tonic-gate 
41060Sstevel@tonic-gate 
41070Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
41080Sstevel@tonic-gate 		return (RDR_ERROR);
41090Sstevel@tonic-gate 	}
41100Sstevel@tonic-gate 
41110Sstevel@tonic-gate 	bufptr = (char *)buf;
41120Sstevel@tonic-gate 	(void) memcpy(&rsrc_info_data, bufptr, sizeof (rdr_rsrc_info_reply_t));
41130Sstevel@tonic-gate 	bufptr += sizeof (rdr_rsrc_info_reply_t);
41140Sstevel@tonic-gate 
41150Sstevel@tonic-gate 	/*
41160Sstevel@tonic-gate 	 * Unpack buf into resource info handle.
41170Sstevel@tonic-gate 	 */
41180Sstevel@tonic-gate 	unpack_status = ri_unpack(bufptr, rsrc_info_data.packed_hdl_size,
41190Sstevel@tonic-gate 	    &params->hdl);
41200Sstevel@tonic-gate 
41210Sstevel@tonic-gate 	return ((unpack_status == 0) ? RDR_OK : RDR_ERROR);
41220Sstevel@tonic-gate }
41230Sstevel@tonic-gate 
41240Sstevel@tonic-gate 
41250Sstevel@tonic-gate /*
41260Sstevel@tonic-gate  * pack_ap_ids:
41270Sstevel@tonic-gate  *
41280Sstevel@tonic-gate  * Pack a list of attachment point identifiers into a single buffer.
41290Sstevel@tonic-gate  * This buffer is stored in the specified rdr_variable_message_info_t
41300Sstevel@tonic-gate  * and is padded to be 64-bit aligned.
41310Sstevel@tonic-gate  */
41320Sstevel@tonic-gate static int
pack_ap_ids(int num_ap_ids,char * const * ap_ids,rdr_variable_message_info_t * var_msg_info)41330Sstevel@tonic-gate pack_ap_ids(int num_ap_ids, char *const *ap_ids,
41340Sstevel@tonic-gate     rdr_variable_message_info_t *var_msg_info)
41350Sstevel@tonic-gate {
41360Sstevel@tonic-gate 	int	i;
41370Sstevel@tonic-gate 	int	ap_id_pad_sz;
41380Sstevel@tonic-gate 	char	*bufptr;
41390Sstevel@tonic-gate 
41400Sstevel@tonic-gate 
41410Sstevel@tonic-gate 	if (var_msg_info == NULL) {
41420Sstevel@tonic-gate 		return (RDR_ERROR);
41430Sstevel@tonic-gate 	}
41440Sstevel@tonic-gate 
41450Sstevel@tonic-gate 	/*
41460Sstevel@tonic-gate 	 * NULL is a valid value for ap_ids in the list_ext
41470Sstevel@tonic-gate 	 * case. For list_ext, no specified attachment points
41480Sstevel@tonic-gate 	 * indicates that _all_ attachment points should be
41490Sstevel@tonic-gate 	 * displayed. However, if ap_ids is NULL, num_ap_ids
41500Sstevel@tonic-gate 	 * should be 0.
41510Sstevel@tonic-gate 	 */
41520Sstevel@tonic-gate 	if ((ap_ids == NULL) && (num_ap_ids != 0)) {
41530Sstevel@tonic-gate 		num_ap_ids = 0;
41540Sstevel@tonic-gate 	}
41550Sstevel@tonic-gate 
41560Sstevel@tonic-gate 	var_msg_info->ap_id_int_size = sizeof (int) * num_ap_ids;
41570Sstevel@tonic-gate 	if (num_ap_ids > 0) {
41580Sstevel@tonic-gate 		var_msg_info->ap_id_sizes = (int *)malloc(sizeof (int) *
41590Sstevel@tonic-gate 		    var_msg_info->ap_id_int_size);
41600Sstevel@tonic-gate 		if (var_msg_info->ap_id_sizes == NULL) {
41610Sstevel@tonic-gate 			return (RDR_MEM_ALLOC);
41620Sstevel@tonic-gate 		}
41630Sstevel@tonic-gate 	}
41640Sstevel@tonic-gate 	for (i = 0; i < num_ap_ids; i++) {
41650Sstevel@tonic-gate 		if (ap_ids[i] != NULL) {
41660Sstevel@tonic-gate 			var_msg_info->ap_id_sizes[i] = strlen(ap_ids[i]) + 1;
41670Sstevel@tonic-gate 			var_msg_info->ap_id_char_size +=
41680Sstevel@tonic-gate 			    var_msg_info->ap_id_sizes[i];
41690Sstevel@tonic-gate 		}
41700Sstevel@tonic-gate 	}
41710Sstevel@tonic-gate 	if (var_msg_info->ap_id_char_size > 0) {
41720Sstevel@tonic-gate 		ap_id_pad_sz = RDR_ALIGN_64_BIT -
41730Sstevel@tonic-gate 		    (var_msg_info->ap_id_char_size % RDR_ALIGN_64_BIT);
41740Sstevel@tonic-gate 		var_msg_info->ap_id_char_size += ap_id_pad_sz;
41750Sstevel@tonic-gate 		var_msg_info->ap_id_chars = (char *)
41760Sstevel@tonic-gate 		    malloc(var_msg_info->ap_id_char_size);
41770Sstevel@tonic-gate 		if (var_msg_info->ap_id_chars == NULL) {
41780Sstevel@tonic-gate 			return (RDR_MEM_ALLOC);
41790Sstevel@tonic-gate 		}
41800Sstevel@tonic-gate 
41810Sstevel@tonic-gate 		bufptr = var_msg_info->ap_id_chars;
41820Sstevel@tonic-gate 		for (i = 0; i < num_ap_ids; i++) {
41830Sstevel@tonic-gate 			(void) memcpy(bufptr, ap_ids[i],
41840Sstevel@tonic-gate 			    var_msg_info->ap_id_sizes[i]);
41850Sstevel@tonic-gate 			bufptr += var_msg_info->ap_id_sizes[i];
41860Sstevel@tonic-gate 		}
41870Sstevel@tonic-gate 		for (i = 0; i < ap_id_pad_sz; i++) {
41880Sstevel@tonic-gate 			bufptr[i] = 0;
41890Sstevel@tonic-gate 		}
41900Sstevel@tonic-gate 	} else {
41910Sstevel@tonic-gate 		ap_id_pad_sz = 0;
41920Sstevel@tonic-gate 	}
41930Sstevel@tonic-gate 
41940Sstevel@tonic-gate 	return (RDR_OK);
41950Sstevel@tonic-gate }
41960Sstevel@tonic-gate 
41970Sstevel@tonic-gate 
41980Sstevel@tonic-gate /*
41990Sstevel@tonic-gate  * unpack_ap_ids:
42000Sstevel@tonic-gate  *
42010Sstevel@tonic-gate  * Unpack a buffer containing a concatenation of a list of
42020Sstevel@tonic-gate  * attachment point identifiers. The resulting list of strings
42030Sstevel@tonic-gate  * are stored in an array in the specified rdr_variable_message_info_t.
42040Sstevel@tonic-gate  */
42050Sstevel@tonic-gate static int
unpack_ap_ids(int num_ap_ids,char ** ap_ids,const char * buf,rdr_variable_message_info_t * var_msg_info)42060Sstevel@tonic-gate unpack_ap_ids(int num_ap_ids, char **ap_ids, const char *buf,
42070Sstevel@tonic-gate     rdr_variable_message_info_t *var_msg_info)
42080Sstevel@tonic-gate {
42090Sstevel@tonic-gate 	int	i;
42100Sstevel@tonic-gate 	int	ap_id_size;
42110Sstevel@tonic-gate 	int	chars_copied;
42120Sstevel@tonic-gate 	char	*bufptr;
42130Sstevel@tonic-gate 
42140Sstevel@tonic-gate 
42150Sstevel@tonic-gate 	if ((ap_ids == NULL) || (buf == NULL) || (var_msg_info == NULL)) {
42160Sstevel@tonic-gate 		return (RDR_ERROR);
42170Sstevel@tonic-gate 	}
42180Sstevel@tonic-gate 	bufptr = (char *)buf;
42190Sstevel@tonic-gate 
42200Sstevel@tonic-gate 	var_msg_info->ap_id_int_size = sizeof (int) * num_ap_ids;
42210Sstevel@tonic-gate 	if (num_ap_ids > 0) {
42220Sstevel@tonic-gate 		var_msg_info->ap_id_sizes = (int *)
42230Sstevel@tonic-gate 		malloc(sizeof (int) * var_msg_info->ap_id_int_size);
42240Sstevel@tonic-gate 		if (var_msg_info->ap_id_sizes == NULL) {
42250Sstevel@tonic-gate 			return (RDR_MEM_ALLOC);
42260Sstevel@tonic-gate 		}
42270Sstevel@tonic-gate 		(void) memcpy(var_msg_info->ap_id_sizes, bufptr,
42280Sstevel@tonic-gate 		    var_msg_info->ap_id_int_size);
42290Sstevel@tonic-gate 	}
42300Sstevel@tonic-gate 	bufptr += var_msg_info->ap_id_int_size;
42310Sstevel@tonic-gate 
42320Sstevel@tonic-gate 	chars_copied = 0;
42330Sstevel@tonic-gate 	for (i = 0; i < num_ap_ids; i++) {
42340Sstevel@tonic-gate 		ap_id_size = var_msg_info->ap_id_sizes[i];
42350Sstevel@tonic-gate 		if (ap_id_size <= 0) {
42360Sstevel@tonic-gate 			continue;
42370Sstevel@tonic-gate 		}
42380Sstevel@tonic-gate 		if ((chars_copied + ap_id_size) >
42390Sstevel@tonic-gate 			var_msg_info->ap_id_char_size) {
42400Sstevel@tonic-gate 			return (RDR_ERROR);
42410Sstevel@tonic-gate 		}
42420Sstevel@tonic-gate 		ap_ids[i] = (char *)malloc(ap_id_size);
42430Sstevel@tonic-gate 		if (ap_ids[i] == NULL) {
42440Sstevel@tonic-gate 			return (RDR_MEM_ALLOC);
42450Sstevel@tonic-gate 		}
42460Sstevel@tonic-gate 		(void) memcpy(ap_ids[i], bufptr, ap_id_size);
42470Sstevel@tonic-gate 		bufptr += ap_id_size;
42480Sstevel@tonic-gate 		chars_copied += ap_id_size;
42490Sstevel@tonic-gate 	}
42500Sstevel@tonic-gate 	return (RDR_OK);
42510Sstevel@tonic-gate }
42520Sstevel@tonic-gate 
42530Sstevel@tonic-gate 
42540Sstevel@tonic-gate /*
42550Sstevel@tonic-gate  * find_options_sizes:
42560Sstevel@tonic-gate  *
42570Sstevel@tonic-gate  * Determine the size of a specified option string. The information
42580Sstevel@tonic-gate  * is stored in the specified rdr_variable_message_info_t.
42590Sstevel@tonic-gate  */
42600Sstevel@tonic-gate static int
find_options_sizes(char * options,rdr_variable_message_info_t * var_msg_info)42610Sstevel@tonic-gate find_options_sizes(char *options, rdr_variable_message_info_t *var_msg_info)
42620Sstevel@tonic-gate {
42630Sstevel@tonic-gate 	if (var_msg_info == NULL) {
42640Sstevel@tonic-gate 		return (RDR_ERROR);
42650Sstevel@tonic-gate 	}
42660Sstevel@tonic-gate 	if (options != NULL) {
42670Sstevel@tonic-gate 		var_msg_info->options_strlen = strlen(options) + 1;
42680Sstevel@tonic-gate 		var_msg_info->options_pad_sz = RDR_ALIGN_64_BIT -
42690Sstevel@tonic-gate 		    (var_msg_info->options_strlen % RDR_ALIGN_64_BIT);
42700Sstevel@tonic-gate 	} else {
42710Sstevel@tonic-gate 		var_msg_info->options_strlen = 0;
42720Sstevel@tonic-gate 		var_msg_info->options_pad_sz = 0;
42730Sstevel@tonic-gate 	}
42740Sstevel@tonic-gate 	return (RDR_OK);
42750Sstevel@tonic-gate }
42760Sstevel@tonic-gate 
42770Sstevel@tonic-gate 
42780Sstevel@tonic-gate /*
42790Sstevel@tonic-gate  * find_listopts_sizes:
42800Sstevel@tonic-gate  *
42810Sstevel@tonic-gate  * Determine the size of a specified list option string. The information
42820Sstevel@tonic-gate  * is stored in the specified rdr_variable_message_info_t.
42830Sstevel@tonic-gate  */
42840Sstevel@tonic-gate static int
find_listopts_sizes(char * listopts,rdr_variable_message_info_t * var_msg_info)42850Sstevel@tonic-gate find_listopts_sizes(char *listopts, rdr_variable_message_info_t *var_msg_info)
42860Sstevel@tonic-gate {
42870Sstevel@tonic-gate 	if (var_msg_info == NULL) {
42880Sstevel@tonic-gate 		return (RDR_ERROR);
42890Sstevel@tonic-gate 	}
42900Sstevel@tonic-gate 	if (listopts != NULL) {
42910Sstevel@tonic-gate 		var_msg_info->listopts_strlen = strlen(listopts) + 1;
42920Sstevel@tonic-gate 		var_msg_info->listopts_pad_sz = RDR_ALIGN_64_BIT -
42930Sstevel@tonic-gate 		    (var_msg_info->listopts_strlen % RDR_ALIGN_64_BIT);
42940Sstevel@tonic-gate 	} else {
42950Sstevel@tonic-gate 		var_msg_info->listopts_strlen = 0;
42960Sstevel@tonic-gate 		var_msg_info->listopts_pad_sz = 0;
42970Sstevel@tonic-gate 	}
42980Sstevel@tonic-gate 	return (RDR_OK);
42990Sstevel@tonic-gate }
43000Sstevel@tonic-gate 
43010Sstevel@tonic-gate 
43020Sstevel@tonic-gate /*
43030Sstevel@tonic-gate  * find_function_size:
43040Sstevel@tonic-gate  *
43050Sstevel@tonic-gate  * Determine the size of a specified private function string. The
43060Sstevel@tonic-gate  * information is stored in the specified rdr_variable_message_info_t.
43070Sstevel@tonic-gate  */
43080Sstevel@tonic-gate static int
find_function_sizes(char * function,rdr_variable_message_info_t * var_msg_info)43090Sstevel@tonic-gate find_function_sizes(char *function, rdr_variable_message_info_t *var_msg_info)
43100Sstevel@tonic-gate {
43110Sstevel@tonic-gate 	if (var_msg_info == NULL) {
43120Sstevel@tonic-gate 		return (RDR_ERROR);
43130Sstevel@tonic-gate 	}
43140Sstevel@tonic-gate 	if (function != NULL) {
43150Sstevel@tonic-gate 		var_msg_info->function_strlen = strlen(function) + 1;
43160Sstevel@tonic-gate 		var_msg_info->function_pad_sz = RDR_ALIGN_64_BIT -
43170Sstevel@tonic-gate 		    (var_msg_info->function_strlen % RDR_ALIGN_64_BIT);
43180Sstevel@tonic-gate 	} else {
43190Sstevel@tonic-gate 		var_msg_info->function_strlen = 0;
43200Sstevel@tonic-gate 		var_msg_info->function_pad_sz = 0;
43210Sstevel@tonic-gate 	}
43220Sstevel@tonic-gate 	return (RDR_OK);
43230Sstevel@tonic-gate }
43240Sstevel@tonic-gate 
43250Sstevel@tonic-gate 
43260Sstevel@tonic-gate /*
43270Sstevel@tonic-gate  * find_errstring_sizes:
43280Sstevel@tonic-gate  *
43290Sstevel@tonic-gate  * Determine the size of a specified error string. The information
43300Sstevel@tonic-gate  * is stored in the specified rdr_variable_message_info_t.
43310Sstevel@tonic-gate  */
43320Sstevel@tonic-gate static int
find_errstring_sizes(char ** errstring,rdr_variable_message_info_t * var_msg_info)43330Sstevel@tonic-gate find_errstring_sizes(char **errstring,
43340Sstevel@tonic-gate     rdr_variable_message_info_t *var_msg_info)
43350Sstevel@tonic-gate {
43360Sstevel@tonic-gate 	if ((errstring != NULL) && (*errstring != NULL)) {
43370Sstevel@tonic-gate 		var_msg_info->errstring_strlen = strlen(*errstring) + 1;
43380Sstevel@tonic-gate 		var_msg_info->errstring_pad_sz = RDR_ALIGN_64_BIT -
43390Sstevel@tonic-gate 		    (var_msg_info->errstring_strlen % RDR_ALIGN_64_BIT);
43400Sstevel@tonic-gate 	} else {
43410Sstevel@tonic-gate 		var_msg_info->errstring_strlen = 0;
43420Sstevel@tonic-gate 		var_msg_info->errstring_pad_sz = 0;
43430Sstevel@tonic-gate 	}
43440Sstevel@tonic-gate 	return (RDR_OK);
43450Sstevel@tonic-gate }
43460Sstevel@tonic-gate 
43470Sstevel@tonic-gate 
43480Sstevel@tonic-gate /*
43490Sstevel@tonic-gate  * get_ap_ids_from_buf:
43500Sstevel@tonic-gate  *
43510Sstevel@tonic-gate  * Unpack a buffer containing a concatenation of a list of attachment
43520Sstevel@tonic-gate  * point identifiers. An appropriately sized buffer is allocated and
43530Sstevel@tonic-gate  * the resulting list of strings are stored in an array in the specified
43540Sstevel@tonic-gate  * rdr_variable_message_info_t.
43550Sstevel@tonic-gate  */
43560Sstevel@tonic-gate static int
get_ap_ids_from_buf(char *** ap_id_ptr,int num_ap_ids,rdr_variable_message_info_t * var_msg_info,const char * buf)43570Sstevel@tonic-gate get_ap_ids_from_buf(char ***ap_id_ptr, int num_ap_ids,
43580Sstevel@tonic-gate     rdr_variable_message_info_t *var_msg_info, const char *buf)
43590Sstevel@tonic-gate {
43600Sstevel@tonic-gate 	if ((ap_id_ptr == NULL) || (buf == NULL) || (var_msg_info == NULL)) {
43610Sstevel@tonic-gate 		return (RDR_ERROR);
43620Sstevel@tonic-gate 	}
43630Sstevel@tonic-gate 	if (num_ap_ids > 0) {
43640Sstevel@tonic-gate 		*ap_id_ptr = (char **)malloc(sizeof (char *) * num_ap_ids);
43650Sstevel@tonic-gate 		if (*ap_id_ptr == NULL) {
43660Sstevel@tonic-gate 			return (RDR_MEM_ALLOC);
43670Sstevel@tonic-gate 		}
43680Sstevel@tonic-gate 		if (unpack_ap_ids(num_ap_ids, *ap_id_ptr, buf, var_msg_info)) {
43690Sstevel@tonic-gate 			cleanup_variable_ap_id_info(var_msg_info);
43700Sstevel@tonic-gate 			return (RDR_ERROR);
43710Sstevel@tonic-gate 		}
43720Sstevel@tonic-gate 
43730Sstevel@tonic-gate 	} else if (num_ap_ids < 0) {
43740Sstevel@tonic-gate 		return (RDR_ERROR);
43750Sstevel@tonic-gate 	}
43760Sstevel@tonic-gate 
43770Sstevel@tonic-gate 	cleanup_variable_ap_id_info(var_msg_info);
43780Sstevel@tonic-gate 
43790Sstevel@tonic-gate 	return (RDR_OK);
43800Sstevel@tonic-gate }
43810Sstevel@tonic-gate 
43820Sstevel@tonic-gate 
43830Sstevel@tonic-gate /*
43840Sstevel@tonic-gate  * get_string_from_buf:
43850Sstevel@tonic-gate  *
43860Sstevel@tonic-gate  * Copy a string to a new buffer. Memory is allocated for the
43870Sstevel@tonic-gate  * new buffer and the original string is copied to the new buffer.
43880Sstevel@tonic-gate  * This is primarily used when a string is located in a packed
43890Sstevel@tonic-gate  * buffer that will eventually get deallocated.
43900Sstevel@tonic-gate  */
43910Sstevel@tonic-gate static int
get_string_from_buf(char ** stringptr,int strsize,const char * buf)43920Sstevel@tonic-gate get_string_from_buf(char **stringptr, int strsize, const char *buf)
43930Sstevel@tonic-gate {
43940Sstevel@tonic-gate 	if (buf == NULL) {
43950Sstevel@tonic-gate 		return (RDR_ERROR);
43960Sstevel@tonic-gate 	}
43970Sstevel@tonic-gate 
43980Sstevel@tonic-gate 	/*
43990Sstevel@tonic-gate 	 * A stringptr of NULL is a valid value. The errstring param
44000Sstevel@tonic-gate 	 * in an rconfig_xxx call is valid and is passed to this
44010Sstevel@tonic-gate 	 * function. For example, see errstring in the call to this
44020Sstevel@tonic-gate 	 * function in unpack_change_state_reply.
44030Sstevel@tonic-gate 	 */
44040Sstevel@tonic-gate 	if (stringptr != NULL) {
44050Sstevel@tonic-gate 		if (strsize > 0) {
44060Sstevel@tonic-gate 			*stringptr = (char *)malloc(strsize);
44070Sstevel@tonic-gate 			if (*stringptr == NULL) {
44080Sstevel@tonic-gate 				return (RDR_MEM_ALLOC);
44090Sstevel@tonic-gate 			}
44100Sstevel@tonic-gate 			(void) memcpy(*stringptr, buf, strsize);
44110Sstevel@tonic-gate 		} else if (strsize == 0) {
44120Sstevel@tonic-gate 			*stringptr = NULL;
44130Sstevel@tonic-gate 		} else if (strsize < 0) {
44140Sstevel@tonic-gate 			*stringptr = NULL;
44150Sstevel@tonic-gate 			return (RDR_ERROR);
44160Sstevel@tonic-gate 		}
44170Sstevel@tonic-gate 	}
44180Sstevel@tonic-gate 	return (RDR_OK);
44190Sstevel@tonic-gate }
44200Sstevel@tonic-gate 
44210Sstevel@tonic-gate 
44220Sstevel@tonic-gate /*
44230Sstevel@tonic-gate  * cleanup_ap_ids:
44240Sstevel@tonic-gate  *
44250Sstevel@tonic-gate  * Deallocate the specified array of attachment point identifiers.
44260Sstevel@tonic-gate  */
44270Sstevel@tonic-gate static int
cleanup_ap_ids(int num_ap_ids,char ** ap_ids)44280Sstevel@tonic-gate cleanup_ap_ids(int num_ap_ids, char ** ap_ids)
44290Sstevel@tonic-gate {
44300Sstevel@tonic-gate 	int	i;
44310Sstevel@tonic-gate 
44320Sstevel@tonic-gate 	if (ap_ids == NULL) {
44330Sstevel@tonic-gate 		return (RDR_ERROR);
44340Sstevel@tonic-gate 	}
44350Sstevel@tonic-gate 	for (i = 0; i < num_ap_ids; i++) {
44360Sstevel@tonic-gate 		if (ap_ids[i] != NULL) {
44370Sstevel@tonic-gate 			free((void *)ap_ids[i]);
44380Sstevel@tonic-gate 			ap_ids[i] = NULL;
44390Sstevel@tonic-gate 		}
44400Sstevel@tonic-gate 	}
44410Sstevel@tonic-gate 	return (RDR_OK);
44420Sstevel@tonic-gate }
44430Sstevel@tonic-gate 
44440Sstevel@tonic-gate 
44450Sstevel@tonic-gate /*
44460Sstevel@tonic-gate  * cleanup_errstring:
44470Sstevel@tonic-gate  *
44480Sstevel@tonic-gate  * Deallocate the specified error string.
44490Sstevel@tonic-gate  */
44500Sstevel@tonic-gate static int
cleanup_errstring(char ** errstring)44510Sstevel@tonic-gate cleanup_errstring(char **errstring)
44520Sstevel@tonic-gate {
44530Sstevel@tonic-gate 	if (errstring) {
44540Sstevel@tonic-gate 		if (*errstring) {
44550Sstevel@tonic-gate 			free((void *)*errstring);
44560Sstevel@tonic-gate 		}
44570Sstevel@tonic-gate 		free((void *)errstring);
44580Sstevel@tonic-gate 		errstring = NULL;
44590Sstevel@tonic-gate 	}
44600Sstevel@tonic-gate 
44610Sstevel@tonic-gate 	return (RDR_OK);
44620Sstevel@tonic-gate }
44630Sstevel@tonic-gate 
44640Sstevel@tonic-gate 
44650Sstevel@tonic-gate /*
44660Sstevel@tonic-gate  * cleanup_variable_ap_id_info:
44670Sstevel@tonic-gate  *
44680Sstevel@tonic-gate  * Deallocate the ap_id information from the specified
44690Sstevel@tonic-gate  * rdr_variable_message_info_t.
44700Sstevel@tonic-gate  */
44710Sstevel@tonic-gate static void
cleanup_variable_ap_id_info(rdr_variable_message_info_t * var_msg_info)44720Sstevel@tonic-gate cleanup_variable_ap_id_info(rdr_variable_message_info_t *var_msg_info)
44730Sstevel@tonic-gate {
44740Sstevel@tonic-gate 	if (var_msg_info != NULL) {
44750Sstevel@tonic-gate 		if (var_msg_info->ap_id_sizes != NULL) {
44760Sstevel@tonic-gate 			free((void *)var_msg_info->ap_id_sizes);
44770Sstevel@tonic-gate 			var_msg_info->ap_id_sizes = NULL;
44780Sstevel@tonic-gate 		}
44790Sstevel@tonic-gate 		if (var_msg_info->ap_id_chars != NULL) {
44800Sstevel@tonic-gate 			free((void *)var_msg_info->ap_id_chars);
44810Sstevel@tonic-gate 			var_msg_info->ap_id_chars = NULL;
44820Sstevel@tonic-gate 		}
44830Sstevel@tonic-gate 	}
44840Sstevel@tonic-gate }
4485*1772Sjl139090 
4486*1772Sjl139090 /*
4487*1772Sjl139090  * load_libdscp:
4488*1772Sjl139090  *
4489*1772Sjl139090  * Try to dynamically link with libdscp.
4490*1772Sjl139090  *
4491*1772Sjl139090  * Returns:	0 if libdscp not available,
4492*1772Sjl139090  *		1 if libdscp is available.
4493*1772Sjl139090  */
4494*1772Sjl139090 static int
load_libdscp(libdscp_t * libdscp)4495*1772Sjl139090 load_libdscp(libdscp_t *libdscp)
4496*1772Sjl139090 {
4497*1772Sjl139090 	int		len;
4498*1772Sjl139090 	void		*lib;
4499*1772Sjl139090 	static char	platform[100];
4500*1772Sjl139090 	static char	pathname[MAXPATHLEN];
4501*1772Sjl139090 
4502*1772Sjl139090 	/*
4503*1772Sjl139090 	 * Only try to load libdscp once.  Use the saved
4504*1772Sjl139090 	 * status in the libdscp interface to know the
4505*1772Sjl139090 	 * results of previous attempts.
4506*1772Sjl139090 	 */
4507*1772Sjl139090 	if (libdscp->status == LIBDSCP_AVAILABLE) {
4508*1772Sjl139090 		return (1);
4509*1772Sjl139090 	}
4510*1772Sjl139090 	if (libdscp->status == LIBDSCP_UNAVAILABLE) {
4511*1772Sjl139090 		return (0);
4512*1772Sjl139090 	}
4513*1772Sjl139090 
4514*1772Sjl139090 	/*
4515*1772Sjl139090 	 * Construct a platform specific pathname for libdscp.
4516*1772Sjl139090 	 */
4517*1772Sjl139090 	len = sysinfo(SI_PLATFORM, platform, sizeof (platform));
4518*1772Sjl139090 	if ((len < 0) || (len > sizeof (platform))) {
4519*1772Sjl139090 		return (0);
4520*1772Sjl139090 	}
4521*1772Sjl139090 	len = snprintf(pathname, MAXPATHLEN, LIBDSCP_PATH, platform);
4522*1772Sjl139090 	if (len >= MAXPATHLEN) {
4523*1772Sjl139090 		libdscp->status = LIBDSCP_UNAVAILABLE;
4524*1772Sjl139090 		return (0);
4525*1772Sjl139090 	}
4526*1772Sjl139090 
4527*1772Sjl139090 	/*
4528*1772Sjl139090 	 * Try dynamically loading libdscp.
4529*1772Sjl139090 	 */
4530*1772Sjl139090 	if ((lib = dlopen(pathname, RTLD_LAZY)) == NULL) {
4531*1772Sjl139090 		libdscp->status = LIBDSCP_UNAVAILABLE;
4532*1772Sjl139090 		return (0);
4533*1772Sjl139090 	}
4534*1772Sjl139090 
4535*1772Sjl139090 	/*
4536*1772Sjl139090 	 * Try to resolve all the symbols.
4537*1772Sjl139090 	 */
4538*1772Sjl139090 	libdscp->bind = (int (*)(int, int, int))dlsym(lib, LIBDSCP_BIND);
4539*1772Sjl139090 	libdscp->secure = (int (*)(int, int))dlsym(lib, LIBDSCP_SECURE);
4540*1772Sjl139090 	libdscp->auth = (int (*)(int, struct sockaddr *, int))dlsym(lib,
4541*1772Sjl139090 	    LIBDSCP_AUTH);
4542*1772Sjl139090 
4543*1772Sjl139090 	if ((libdscp->bind == NULL) ||
4544*1772Sjl139090 	    (libdscp->secure == NULL) ||
4545*1772Sjl139090 	    (libdscp->auth == NULL)) {
4546*1772Sjl139090 		(void) dlclose(lib);
4547*1772Sjl139090 		libdscp->status = LIBDSCP_UNAVAILABLE;
4548*1772Sjl139090 		return (0);
4549*1772Sjl139090 	}
4550*1772Sjl139090 
4551*1772Sjl139090 	/*
4552*1772Sjl139090 	 * Success.
4553*1772Sjl139090 	 * Update the status to indicate libdscp is available.
4554*1772Sjl139090 	 */
4555*1772Sjl139090 	libdscp->status = LIBDSCP_AVAILABLE;
4556*1772Sjl139090 	return (1);
4557*1772Sjl139090 }
4558