xref: /titanic_50/usr/src/cmd/dcs/sparc/sun4u/rdr_messages.c (revision 25cf1a301a396c38e8adf52c15f537b80d2483f7)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*25cf1a30Sjl139090  * Common Development and Distribution License (the "License").
6*25cf1a30Sjl139090  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
22*25cf1a30Sjl139090  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
267c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate /*
297c478bd9Sstevel@tonic-gate  * WARNING: The contents of this file are shared by all projects
307c478bd9Sstevel@tonic-gate  * that  wish to  perform  remote  Dynamic Reconfiguration  (DR)
317c478bd9Sstevel@tonic-gate  * operations. Copies of this file can be found in the following
327c478bd9Sstevel@tonic-gate  * locations:
337c478bd9Sstevel@tonic-gate  *
347c478bd9Sstevel@tonic-gate  *	Project	    Location
357c478bd9Sstevel@tonic-gate  *	-------	    --------
367c478bd9Sstevel@tonic-gate  *	Solaris	    usr/src/cmd/dcs/sparc/sun4u/%M%
377c478bd9Sstevel@tonic-gate  *	SMS	    src/sms/lib/librdr/%M%
387c478bd9Sstevel@tonic-gate  *
397c478bd9Sstevel@tonic-gate  * In order for proper communication to occur,  the files in the
407c478bd9Sstevel@tonic-gate  * above locations must match exactly. Any changes that are made
417c478bd9Sstevel@tonic-gate  * to this file should  be made to all of the files in the list.
427c478bd9Sstevel@tonic-gate  */
437c478bd9Sstevel@tonic-gate 
447c478bd9Sstevel@tonic-gate /*
457c478bd9Sstevel@tonic-gate  * This file is a module that contains an interface for performing
467c478bd9Sstevel@tonic-gate  * remote Dynamic Reconfiguration (DR) operations. It hides all
477c478bd9Sstevel@tonic-gate  * network operations such as establishing a connection, sending
487c478bd9Sstevel@tonic-gate  * and receiving messages, and closing a connection. It also handles
497c478bd9Sstevel@tonic-gate  * the packing and unpacking of messages for network transport.
507c478bd9Sstevel@tonic-gate  */
517c478bd9Sstevel@tonic-gate 
527c478bd9Sstevel@tonic-gate #include <stdio.h>
537c478bd9Sstevel@tonic-gate #include <stdlib.h>
547c478bd9Sstevel@tonic-gate #include <unistd.h>
557c478bd9Sstevel@tonic-gate #include <string.h>
567c478bd9Sstevel@tonic-gate #include <fcntl.h>
577c478bd9Sstevel@tonic-gate #include <errno.h>
58*25cf1a30Sjl139090 #include <dlfcn.h>
597c478bd9Sstevel@tonic-gate #include <netdb.h>
60*25cf1a30Sjl139090 #include <libdscp.h>
617c478bd9Sstevel@tonic-gate #include <sys/socket.h>
62*25cf1a30Sjl139090 #include <sys/systeminfo.h>
637c478bd9Sstevel@tonic-gate #include <netinet/tcp.h>
647c478bd9Sstevel@tonic-gate 
65*25cf1a30Sjl139090 #include "dcs.h"
667c478bd9Sstevel@tonic-gate #include "remote_cfg.h"
677c478bd9Sstevel@tonic-gate #include "rdr_param_types.h"
687c478bd9Sstevel@tonic-gate #include "rdr_messages.h"
697c478bd9Sstevel@tonic-gate 
707c478bd9Sstevel@tonic-gate 
717c478bd9Sstevel@tonic-gate /*
727c478bd9Sstevel@tonic-gate  * Structure holding information about
737c478bd9Sstevel@tonic-gate  * all possible variable length fields
747c478bd9Sstevel@tonic-gate  * that can be present in an RDR message.
757c478bd9Sstevel@tonic-gate  */
767c478bd9Sstevel@tonic-gate typedef struct {
777c478bd9Sstevel@tonic-gate 	int	ap_id_int_size;
787c478bd9Sstevel@tonic-gate 	int	ap_id_char_size;
797c478bd9Sstevel@tonic-gate 	int	*ap_id_sizes;
807c478bd9Sstevel@tonic-gate 	char	*ap_id_chars;
817c478bd9Sstevel@tonic-gate 	int	errstring_strlen;
827c478bd9Sstevel@tonic-gate 	int	errstring_pad_sz;
837c478bd9Sstevel@tonic-gate 	int	options_strlen;
847c478bd9Sstevel@tonic-gate 	int	options_pad_sz;
857c478bd9Sstevel@tonic-gate 	int	listopts_strlen;
867c478bd9Sstevel@tonic-gate 	int	listopts_pad_sz;
877c478bd9Sstevel@tonic-gate 	int	function_strlen;
887c478bd9Sstevel@tonic-gate 	int	function_pad_sz;
897c478bd9Sstevel@tonic-gate } rdr_variable_message_info_t;
907c478bd9Sstevel@tonic-gate 
917c478bd9Sstevel@tonic-gate /*
927c478bd9Sstevel@tonic-gate  * A table of maximum sizes for each message type. Message size is
937c478bd9Sstevel@tonic-gate  * validated when the message header is first received. This prevents
947c478bd9Sstevel@tonic-gate  * a situation where a corrupted or bad header can cause too much
957c478bd9Sstevel@tonic-gate  * memory to be allocated.
967c478bd9Sstevel@tonic-gate  *
977c478bd9Sstevel@tonic-gate  * The message size limits were chosen to be a very generous upper bound
987c478bd9Sstevel@tonic-gate  * on the amount of data each message can send. They are not intended to
997c478bd9Sstevel@tonic-gate  * be a precise measurement of the data size.
1007c478bd9Sstevel@tonic-gate  */
1017c478bd9Sstevel@tonic-gate #define	NOMSG		0
1027c478bd9Sstevel@tonic-gate #define	SHORTMSG	(150 * 1024)		/* 150 KB */
1037c478bd9Sstevel@tonic-gate #define	LONGMSG		(3 * 1024 * 1024)	/* 3 MB */
1047c478bd9Sstevel@tonic-gate 
1057c478bd9Sstevel@tonic-gate struct {
1067c478bd9Sstevel@tonic-gate 	ulong_t	req_max;
1077c478bd9Sstevel@tonic-gate 	ulong_t	reply_max;
1087c478bd9Sstevel@tonic-gate } msg_sizes[] = {
1097c478bd9Sstevel@tonic-gate 	/*
1107c478bd9Sstevel@tonic-gate 	 * request	reply
1117c478bd9Sstevel@tonic-gate 	 * -------	-----
1127c478bd9Sstevel@tonic-gate 	 */
1137c478bd9Sstevel@tonic-gate 	{  NOMSG,	NOMSG	  },	/*  Invalid Opcode		*/
1147c478bd9Sstevel@tonic-gate 	{  SHORTMSG,	SHORTMSG  },	/*  RDR_SES_REQ			*/
1157c478bd9Sstevel@tonic-gate 	{  NOMSG,	NOMSG	  },	/*  RDR_SES_ESTBL		*/
1167c478bd9Sstevel@tonic-gate 	{  NOMSG,	NOMSG	  },	/*  RDR_SES_END			*/
1177c478bd9Sstevel@tonic-gate 	{  SHORTMSG,	SHORTMSG  },	/*  RDR_CONF_CHANGE_STATE	*/
1187c478bd9Sstevel@tonic-gate 	{  SHORTMSG,	SHORTMSG  },	/*  RDR_CONF_PRIVATE_FUNC	*/
1197c478bd9Sstevel@tonic-gate 	{  SHORTMSG,	SHORTMSG  },	/*  RDR_CONF_TEST		*/
1207c478bd9Sstevel@tonic-gate 	{  SHORTMSG,	LONGMSG	  },	/*  RDR_CONF_LIST_EXT		*/
1217c478bd9Sstevel@tonic-gate 	{  SHORTMSG,	NOMSG	  },	/*  RDR_CONF_HELP		*/
1227c478bd9Sstevel@tonic-gate 	{  SHORTMSG,	NOMSG	  },	/*  RDR_CONF_AP_ID_CMP		*/
1237c478bd9Sstevel@tonic-gate 	{  SHORTMSG,	NOMSG	  },	/*  RDR_CONF_ABORT_CMD		*/
1247c478bd9Sstevel@tonic-gate 	{  SHORTMSG,	SHORTMSG  },	/*  RDR_CONF_CONFIRM_CALLBACK 	*/
1257c478bd9Sstevel@tonic-gate 	{  SHORTMSG,	NOMSG	  },	/*  RDR_CONF_MSG_CALLBACK	*/
1267c478bd9Sstevel@tonic-gate 	{  SHORTMSG,	LONGMSG	  }	/*  RDR_RSRC_INFO		*/
1277c478bd9Sstevel@tonic-gate };
1287c478bd9Sstevel@tonic-gate 
1297c478bd9Sstevel@tonic-gate 
1307c478bd9Sstevel@tonic-gate #define	RDR_BAD_FD		(-1)
1317c478bd9Sstevel@tonic-gate 
1327c478bd9Sstevel@tonic-gate #define	RDR_MSG_HDR_SIZE 	sizeof (rdr_msg_hdr_t)
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate static const int RDR_ALIGN_64_BIT = 8;   /* 8 bytes */
1357c478bd9Sstevel@tonic-gate 
136*25cf1a30Sjl139090 /*
137*25cf1a30Sjl139090  * Interfaces for dynamic use of libdscp.
138*25cf1a30Sjl139090  */
139*25cf1a30Sjl139090 
140*25cf1a30Sjl139090 #define	LIBDSCP_PATH	"/usr/platform/%s/lib/libdscp.so.1"
141*25cf1a30Sjl139090 
142*25cf1a30Sjl139090 #define	LIBDSCP_BIND	"dscpBind"
143*25cf1a30Sjl139090 #define	LIBDSCP_SECURE	"dscpSecure"
144*25cf1a30Sjl139090 #define	LIBDSCP_AUTH	"dscpAuth"
145*25cf1a30Sjl139090 
146*25cf1a30Sjl139090 typedef enum {
147*25cf1a30Sjl139090 	LIBDSCP_UNKNOWN = 0,
148*25cf1a30Sjl139090 	LIBDSCP_AVAILABLE,
149*25cf1a30Sjl139090 	LIBDSCP_UNAVAILABLE
150*25cf1a30Sjl139090 } dscp_status_t;
151*25cf1a30Sjl139090 
152*25cf1a30Sjl139090 typedef struct {
153*25cf1a30Sjl139090 	dscp_status_t	status;
154*25cf1a30Sjl139090 	int		(*bind)(int, int, int);
155*25cf1a30Sjl139090 	int		(*secure)(int, int);
156*25cf1a30Sjl139090 	int		(*auth)(int, struct sockaddr *, int);
157*25cf1a30Sjl139090 } libdscp_t;
158*25cf1a30Sjl139090 
159*25cf1a30Sjl139090 static libdscp_t libdscp;
1607c478bd9Sstevel@tonic-gate 
1617c478bd9Sstevel@tonic-gate /*
1627c478bd9Sstevel@tonic-gate  * Static Function Declarations
1637c478bd9Sstevel@tonic-gate  */
1647c478bd9Sstevel@tonic-gate 
1657c478bd9Sstevel@tonic-gate /*
1667c478bd9Sstevel@tonic-gate  * Socket Related Routines
1677c478bd9Sstevel@tonic-gate  */
1687c478bd9Sstevel@tonic-gate static int rdr_setopt(int fd, int name, int level);
1697c478bd9Sstevel@tonic-gate 
1707c478bd9Sstevel@tonic-gate static int rdr_bind(int fd, struct sockaddr *addr);
1717c478bd9Sstevel@tonic-gate 
172*25cf1a30Sjl139090 static int rdr_secure(int fd, struct sockaddr *addr);
173*25cf1a30Sjl139090 
174*25cf1a30Sjl139090 static int rdr_auth(struct sockaddr *addr, int len);
175*25cf1a30Sjl139090 
1767c478bd9Sstevel@tonic-gate static int rdr_snd(int fd, rdr_msg_hdr_t *hdr, char *data, int data_sz,
1777c478bd9Sstevel@tonic-gate 			int timeout);
1787c478bd9Sstevel@tonic-gate static int rdr_snd_raw(int fd, char *msg, int data_sz, int timeout);
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate static int rdr_rcv(int fd, rdr_msg_hdr_t *hdr, char **data, int timeout);
1817c478bd9Sstevel@tonic-gate 
1827c478bd9Sstevel@tonic-gate static int rdr_rcv_raw(int fd, char *msg, int data_size, int timeout);
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate /*
1857c478bd9Sstevel@tonic-gate  * Data Validation Routines
1867c478bd9Sstevel@tonic-gate  */
1877c478bd9Sstevel@tonic-gate static int validate_header(rdr_msg_hdr_t *hdr);
1887c478bd9Sstevel@tonic-gate 
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate /*
1917c478bd9Sstevel@tonic-gate  * Session Request Routines
1927c478bd9Sstevel@tonic-gate  */
1937c478bd9Sstevel@tonic-gate static int pack_ses_req_request(ses_req_params_t *params, char **buf,
1947c478bd9Sstevel@tonic-gate 			int *buf_size);
1957c478bd9Sstevel@tonic-gate static int unpack_ses_req_request(ses_req_params_t *params, const char *buf);
1967c478bd9Sstevel@tonic-gate 
1977c478bd9Sstevel@tonic-gate static int pack_ses_req_reply(ses_req_params_t *params, char **buf,
1987c478bd9Sstevel@tonic-gate 			int *buf_size);
1997c478bd9Sstevel@tonic-gate static int unpack_ses_req_reply(ses_req_params_t *params, const char *buf);
2007c478bd9Sstevel@tonic-gate 
2017c478bd9Sstevel@tonic-gate 
2027c478bd9Sstevel@tonic-gate /*
2037c478bd9Sstevel@tonic-gate  * Change State Routines
2047c478bd9Sstevel@tonic-gate  */
2057c478bd9Sstevel@tonic-gate static int pack_change_state_request(change_state_params_t *params,
2067c478bd9Sstevel@tonic-gate 			char **buf, int *buf_size);
2077c478bd9Sstevel@tonic-gate static int unpack_change_state_request(change_state_params_t *params,
2087c478bd9Sstevel@tonic-gate 			const char *buf);
2097c478bd9Sstevel@tonic-gate static int pack_change_state_reply(change_state_params_t *params,
2107c478bd9Sstevel@tonic-gate 			char **buf, int *buf_size);
2117c478bd9Sstevel@tonic-gate static int unpack_change_state_reply(change_state_params_t *params,
2127c478bd9Sstevel@tonic-gate 			const char *buf);
2137c478bd9Sstevel@tonic-gate 
2147c478bd9Sstevel@tonic-gate /*
2157c478bd9Sstevel@tonic-gate  * Private Func Routines
2167c478bd9Sstevel@tonic-gate  */
2177c478bd9Sstevel@tonic-gate static int pack_private_func_request(private_func_params_t *params,
2187c478bd9Sstevel@tonic-gate 			char **buf, int *buf_size);
2197c478bd9Sstevel@tonic-gate static int unpack_private_func_request(private_func_params_t *params,
2207c478bd9Sstevel@tonic-gate 			const char *buf);
2217c478bd9Sstevel@tonic-gate static int pack_private_func_reply(private_func_params_t *params,
2227c478bd9Sstevel@tonic-gate 			char **buf, int *buf_size);
2237c478bd9Sstevel@tonic-gate static int unpack_private_func_reply(private_func_params_t *params,
2247c478bd9Sstevel@tonic-gate 			const char *buf);
2257c478bd9Sstevel@tonic-gate 
2267c478bd9Sstevel@tonic-gate /*
2277c478bd9Sstevel@tonic-gate  * Test Routines
2287c478bd9Sstevel@tonic-gate  */
2297c478bd9Sstevel@tonic-gate static int pack_test_request(test_params_t *params, char **buf, int *buf_size);
2307c478bd9Sstevel@tonic-gate 
2317c478bd9Sstevel@tonic-gate static int unpack_test_request(test_params_t *params, const char *buf);
2327c478bd9Sstevel@tonic-gate 
2337c478bd9Sstevel@tonic-gate static int pack_test_reply(test_params_t *params, char **buf, int *buf_size);
2347c478bd9Sstevel@tonic-gate 
2357c478bd9Sstevel@tonic-gate static int unpack_test_reply(test_params_t *params, const char *buf);
2367c478bd9Sstevel@tonic-gate 
2377c478bd9Sstevel@tonic-gate 
2387c478bd9Sstevel@tonic-gate /*
2397c478bd9Sstevel@tonic-gate  * List Ext Routines
2407c478bd9Sstevel@tonic-gate  */
2417c478bd9Sstevel@tonic-gate static int pack_list_ext_request(list_ext_params_t *params, char **buf,
2427c478bd9Sstevel@tonic-gate 			int *buf_size);
2437c478bd9Sstevel@tonic-gate static int unpack_list_ext_request(list_ext_params_t *params, const char *buf);
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate static int pack_list_ext_reply(list_ext_params_t *params, char **buf,
2467c478bd9Sstevel@tonic-gate 			int *buf_size);
2477c478bd9Sstevel@tonic-gate static int unpack_list_ext_reply(list_ext_params_t *params, const char *buf);
2487c478bd9Sstevel@tonic-gate 
2497c478bd9Sstevel@tonic-gate 
2507c478bd9Sstevel@tonic-gate /*
2517c478bd9Sstevel@tonic-gate  * Help Routines
2527c478bd9Sstevel@tonic-gate  */
2537c478bd9Sstevel@tonic-gate static int pack_help_request(help_params_t *params, char **buf, int *buf_size);
2547c478bd9Sstevel@tonic-gate 
2557c478bd9Sstevel@tonic-gate static int unpack_help_request(help_params_t *params, const char *buf);
2567c478bd9Sstevel@tonic-gate 
2577c478bd9Sstevel@tonic-gate 
2587c478bd9Sstevel@tonic-gate /*
2597c478bd9Sstevel@tonic-gate  * Ap Id Cmp Routines
2607c478bd9Sstevel@tonic-gate  */
2617c478bd9Sstevel@tonic-gate static int pack_ap_id_cmp_request(ap_id_cmp_params_t *params, char **buf,
2627c478bd9Sstevel@tonic-gate 			int *buf_size);
2637c478bd9Sstevel@tonic-gate static int unpack_ap_id_cmp_request(ap_id_cmp_params_t *params,
2647c478bd9Sstevel@tonic-gate 			const char *buf);
2657c478bd9Sstevel@tonic-gate 
2667c478bd9Sstevel@tonic-gate /*
2677c478bd9Sstevel@tonic-gate  * Abort Routines
2687c478bd9Sstevel@tonic-gate  */
2697c478bd9Sstevel@tonic-gate static int pack_abort_cmd_request(abort_cmd_params_t *params, char **buf,
2707c478bd9Sstevel@tonic-gate 			int *buf_size);
2717c478bd9Sstevel@tonic-gate static int unpack_abort_cmd_request(abort_cmd_params_t *params,
2727c478bd9Sstevel@tonic-gate 			const char *buf);
2737c478bd9Sstevel@tonic-gate 
2747c478bd9Sstevel@tonic-gate /*
2757c478bd9Sstevel@tonic-gate  * Confirm Callback Routines
2767c478bd9Sstevel@tonic-gate  */
2777c478bd9Sstevel@tonic-gate static int pack_confirm_request(confirm_callback_params_t *params, char **buf,
2787c478bd9Sstevel@tonic-gate 			int *buf_size);
2797c478bd9Sstevel@tonic-gate static int unpack_confirm_request(confirm_callback_params_t *params,
2807c478bd9Sstevel@tonic-gate 			const char *buf);
2817c478bd9Sstevel@tonic-gate static int pack_confirm_reply(confirm_callback_params_t *params,
2827c478bd9Sstevel@tonic-gate 			char **buf, int *buf_size);
2837c478bd9Sstevel@tonic-gate static int unpack_confirm_reply(confirm_callback_params_t *params,
2847c478bd9Sstevel@tonic-gate 			const char *buf);
2857c478bd9Sstevel@tonic-gate 
2867c478bd9Sstevel@tonic-gate /*
2877c478bd9Sstevel@tonic-gate  * Message Callback Routines
2887c478bd9Sstevel@tonic-gate  */
2897c478bd9Sstevel@tonic-gate static int pack_message_request(msg_callback_params_t *params, char **buf,
2907c478bd9Sstevel@tonic-gate 			int *buf_size);
2917c478bd9Sstevel@tonic-gate static int unpack_message_request(msg_callback_params_t *params,
2927c478bd9Sstevel@tonic-gate 			const char *buf);
2937c478bd9Sstevel@tonic-gate 
2947c478bd9Sstevel@tonic-gate /*
2957c478bd9Sstevel@tonic-gate  * Resource Info Routines
2967c478bd9Sstevel@tonic-gate  */
2977c478bd9Sstevel@tonic-gate static int pack_rsrc_info_request(rsrc_info_params_t *params, char **buf,
2987c478bd9Sstevel@tonic-gate 			int *buf_size);
2997c478bd9Sstevel@tonic-gate static int unpack_rsrc_info_request(rsrc_info_params_t *params,
3007c478bd9Sstevel@tonic-gate 			const char *buf);
3017c478bd9Sstevel@tonic-gate static int pack_rsrc_info_reply(rsrc_info_params_t *params, char **buf,
302*25cf1a30Sjl139090 			int *buf_size, int encoding);
3037c478bd9Sstevel@tonic-gate static int unpack_rsrc_info_reply(rsrc_info_params_t *params, const char *buf);
3047c478bd9Sstevel@tonic-gate 
3057c478bd9Sstevel@tonic-gate /*
3067c478bd9Sstevel@tonic-gate  * General Pack/Unpack Routines
3077c478bd9Sstevel@tonic-gate  */
3087c478bd9Sstevel@tonic-gate static int pack_ap_ids(int num_ap_ids, char *const *ap_ids,
3097c478bd9Sstevel@tonic-gate 			rdr_variable_message_info_t *var_msg_info);
3107c478bd9Sstevel@tonic-gate static int unpack_ap_ids(int num_ap_ids, char **ap_ids, const char *buf,
3117c478bd9Sstevel@tonic-gate 			rdr_variable_message_info_t *var_msg_info);
3127c478bd9Sstevel@tonic-gate 
3137c478bd9Sstevel@tonic-gate /*
3147c478bd9Sstevel@tonic-gate  * Find Variable Info Sizes
3157c478bd9Sstevel@tonic-gate  */
3167c478bd9Sstevel@tonic-gate static int find_options_sizes(char *options,
3177c478bd9Sstevel@tonic-gate 			rdr_variable_message_info_t *var_msg_info);
3187c478bd9Sstevel@tonic-gate static int find_listopts_sizes(char *listopts,
3197c478bd9Sstevel@tonic-gate 			rdr_variable_message_info_t *var_msg_info);
3207c478bd9Sstevel@tonic-gate static int find_function_sizes(char *function,
3217c478bd9Sstevel@tonic-gate 			rdr_variable_message_info_t *var_msg_info);
3227c478bd9Sstevel@tonic-gate static int find_errstring_sizes(char **errstring,
3237c478bd9Sstevel@tonic-gate 			rdr_variable_message_info_t *var_msg_info);
3247c478bd9Sstevel@tonic-gate 
3257c478bd9Sstevel@tonic-gate /*
3267c478bd9Sstevel@tonic-gate  * Extract Info From Buffers
3277c478bd9Sstevel@tonic-gate  */
3287c478bd9Sstevel@tonic-gate static int get_ap_ids_from_buf(char ***ap_id_ptr, int num_ap_ids,
3297c478bd9Sstevel@tonic-gate 			rdr_variable_message_info_t *var_msg_info,
3307c478bd9Sstevel@tonic-gate 			const char *buf);
3317c478bd9Sstevel@tonic-gate static int get_string_from_buf(char **stringptr, int strsize, const char *buf);
3327c478bd9Sstevel@tonic-gate 
3337c478bd9Sstevel@tonic-gate 
3347c478bd9Sstevel@tonic-gate /*
3357c478bd9Sstevel@tonic-gate  * Cleanup Routines
3367c478bd9Sstevel@tonic-gate  */
3377c478bd9Sstevel@tonic-gate static int cleanup_ap_ids(int num_ap_ids, char **ap_ids);
3387c478bd9Sstevel@tonic-gate 
3397c478bd9Sstevel@tonic-gate static int cleanup_errstring(char **errstring);
3407c478bd9Sstevel@tonic-gate 
3417c478bd9Sstevel@tonic-gate static void cleanup_variable_ap_id_info(
3427c478bd9Sstevel@tonic-gate 			rdr_variable_message_info_t *var_msg_info);
3437c478bd9Sstevel@tonic-gate 
3447c478bd9Sstevel@tonic-gate /*
345*25cf1a30Sjl139090  * Functions for loading libdscp.
346*25cf1a30Sjl139090  */
347*25cf1a30Sjl139090 static int load_libdscp(libdscp_t *libdscp);
348*25cf1a30Sjl139090 
349*25cf1a30Sjl139090 /*
3507c478bd9Sstevel@tonic-gate  * Public Functions
3517c478bd9Sstevel@tonic-gate  */
3527c478bd9Sstevel@tonic-gate 
3537c478bd9Sstevel@tonic-gate 
3547c478bd9Sstevel@tonic-gate /*
3557c478bd9Sstevel@tonic-gate  * rdr_open:
3567c478bd9Sstevel@tonic-gate  *
3577c478bd9Sstevel@tonic-gate  * Establish a transport endpoint to prepare for a new
3587c478bd9Sstevel@tonic-gate  * connection. Returns a file descriptor representing the
3597c478bd9Sstevel@tonic-gate  * new transport if successful or RDR_BAD_FD upon failure.
3607c478bd9Sstevel@tonic-gate  */
3617c478bd9Sstevel@tonic-gate int
rdr_open(int family)3627c478bd9Sstevel@tonic-gate rdr_open(int family)
3637c478bd9Sstevel@tonic-gate {
3647c478bd9Sstevel@tonic-gate 	int	newfd;
3657c478bd9Sstevel@tonic-gate 
3667c478bd9Sstevel@tonic-gate 
3677c478bd9Sstevel@tonic-gate 	if ((newfd = socket(family, SOCK_STREAM, 0)) == NULL) {
3687c478bd9Sstevel@tonic-gate 		return (RDR_BAD_FD);
3697c478bd9Sstevel@tonic-gate 	}
3707c478bd9Sstevel@tonic-gate 
3717c478bd9Sstevel@tonic-gate 	return (newfd);
3727c478bd9Sstevel@tonic-gate }
3737c478bd9Sstevel@tonic-gate 
3747c478bd9Sstevel@tonic-gate 
3757c478bd9Sstevel@tonic-gate /*
3767c478bd9Sstevel@tonic-gate  * rdr_init:
3777c478bd9Sstevel@tonic-gate  *
3787c478bd9Sstevel@tonic-gate  * Initialize a transport endpoint. This involves binding to
3797c478bd9Sstevel@tonic-gate  * a particular port and setting any user specified socket
3807c478bd9Sstevel@tonic-gate  * options.
3817c478bd9Sstevel@tonic-gate  */
3827c478bd9Sstevel@tonic-gate int
rdr_init(int fd,struct sockaddr * addr,int * opts,int num_opts,int blog)3837c478bd9Sstevel@tonic-gate rdr_init(int fd, struct sockaddr *addr, int *opts, int num_opts, int blog)
3847c478bd9Sstevel@tonic-gate {
3857c478bd9Sstevel@tonic-gate 	int	i;
3867c478bd9Sstevel@tonic-gate 
3877c478bd9Sstevel@tonic-gate 
3887c478bd9Sstevel@tonic-gate 	/* sanity checks */
3897c478bd9Sstevel@tonic-gate 	if ((fd < 0) || (addr == NULL)) {
3907c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
3917c478bd9Sstevel@tonic-gate 	}
3927c478bd9Sstevel@tonic-gate 
3937c478bd9Sstevel@tonic-gate 	if ((opts == NULL) || (num_opts < 0)) {
3947c478bd9Sstevel@tonic-gate 		num_opts = 0;
3957c478bd9Sstevel@tonic-gate 	}
3967c478bd9Sstevel@tonic-gate 
397*25cf1a30Sjl139090 	/* turn on security features */
398*25cf1a30Sjl139090 	if (rdr_secure(fd, addr) != RDR_OK) {
399*25cf1a30Sjl139090 		return (RDR_NET_ERR);
400*25cf1a30Sjl139090 	}
401*25cf1a30Sjl139090 
4027c478bd9Sstevel@tonic-gate 	/* bind the address, if is not already bound */
4037c478bd9Sstevel@tonic-gate 	if (rdr_bind(fd, addr) != RDR_OK) {
4047c478bd9Sstevel@tonic-gate 		return (RDR_NET_ERR);
4057c478bd9Sstevel@tonic-gate 	}
4067c478bd9Sstevel@tonic-gate 
4077c478bd9Sstevel@tonic-gate 	/*
4087c478bd9Sstevel@tonic-gate 	 * Set TCP_NODELAY for this endpoint. This disables Nagle's
4097c478bd9Sstevel@tonic-gate 	 * algorithm that can cause a delay in sending small sized
4107c478bd9Sstevel@tonic-gate 	 * messages. Since most of the RDR messages are small, this
4117c478bd9Sstevel@tonic-gate 	 * is a restriction that negatively impacts performance.
4127c478bd9Sstevel@tonic-gate 	 */
4137c478bd9Sstevel@tonic-gate 	if (rdr_setopt(fd, TCP_NODELAY, IPPROTO_TCP) != RDR_OK) {
4147c478bd9Sstevel@tonic-gate 		return (RDR_NET_ERR);
4157c478bd9Sstevel@tonic-gate 	}
4167c478bd9Sstevel@tonic-gate 
4177c478bd9Sstevel@tonic-gate 	/* set the user specified socket options */
4187c478bd9Sstevel@tonic-gate 	for (i = 0; i < num_opts; i++) {
4197c478bd9Sstevel@tonic-gate 		if (rdr_setopt(fd, opts[i], SOL_SOCKET) != RDR_OK) {
4207c478bd9Sstevel@tonic-gate 			return (RDR_NET_ERR);
4217c478bd9Sstevel@tonic-gate 		}
4227c478bd9Sstevel@tonic-gate 	}
4237c478bd9Sstevel@tonic-gate 
4247c478bd9Sstevel@tonic-gate 	/*
4257c478bd9Sstevel@tonic-gate 	 * If blog is not zero, it is a server that is being
4267c478bd9Sstevel@tonic-gate 	 * initialized. In order for it to be able to accept
4277c478bd9Sstevel@tonic-gate 	 * connections, we have to set the size of the incoming
4287c478bd9Sstevel@tonic-gate 	 * connection queue.
4297c478bd9Sstevel@tonic-gate 	 */
4307c478bd9Sstevel@tonic-gate 	if (blog != 0) {
4317c478bd9Sstevel@tonic-gate 		if (listen(fd, blog) == -1) {
4327c478bd9Sstevel@tonic-gate 			return (RDR_NET_ERR);
4337c478bd9Sstevel@tonic-gate 		}
4347c478bd9Sstevel@tonic-gate 	}
4357c478bd9Sstevel@tonic-gate 
4367c478bd9Sstevel@tonic-gate 	return (RDR_OK);
4377c478bd9Sstevel@tonic-gate }
4387c478bd9Sstevel@tonic-gate 
4397c478bd9Sstevel@tonic-gate 
4407c478bd9Sstevel@tonic-gate /*
4417c478bd9Sstevel@tonic-gate  * rdr_connect_clnt:
4427c478bd9Sstevel@tonic-gate  *
4437c478bd9Sstevel@tonic-gate  * Perform the necessary steps for a client to connect to
4447c478bd9Sstevel@tonic-gate  * a server process. The required information is the file
4457c478bd9Sstevel@tonic-gate  * descriptor for the transport endpoint, and the remote
4467c478bd9Sstevel@tonic-gate  * address.
4477c478bd9Sstevel@tonic-gate  */
4487c478bd9Sstevel@tonic-gate int
rdr_connect_clnt(int fd,struct sockaddr * addr)4497c478bd9Sstevel@tonic-gate rdr_connect_clnt(int fd, struct sockaddr *addr)
4507c478bd9Sstevel@tonic-gate {
4517c478bd9Sstevel@tonic-gate 	unsigned int	addr_len;
4527c478bd9Sstevel@tonic-gate 
4537c478bd9Sstevel@tonic-gate 
4547c478bd9Sstevel@tonic-gate 	/* sanity check */
4557c478bd9Sstevel@tonic-gate 	if (addr == NULL) {
4567c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
4577c478bd9Sstevel@tonic-gate 	}
4587c478bd9Sstevel@tonic-gate 
4597c478bd9Sstevel@tonic-gate 	/* initialize the address length */
4607c478bd9Sstevel@tonic-gate 	switch (addr->sa_family) {
4617c478bd9Sstevel@tonic-gate 
4627c478bd9Sstevel@tonic-gate 	case AF_INET:
4637c478bd9Sstevel@tonic-gate 		addr_len = sizeof (struct sockaddr_in);
4647c478bd9Sstevel@tonic-gate 		break;
4657c478bd9Sstevel@tonic-gate 
4667c478bd9Sstevel@tonic-gate 	case AF_INET6:
4677c478bd9Sstevel@tonic-gate 		addr_len = sizeof (struct sockaddr_in6);
4687c478bd9Sstevel@tonic-gate 		break;
4697c478bd9Sstevel@tonic-gate 
4707c478bd9Sstevel@tonic-gate 	default:
4717c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
4727c478bd9Sstevel@tonic-gate 	}
4737c478bd9Sstevel@tonic-gate 
4747c478bd9Sstevel@tonic-gate 	/* attempt the connection */
4757c478bd9Sstevel@tonic-gate 	if (connect(fd, addr, addr_len) == -1) {
4767c478bd9Sstevel@tonic-gate 		return (RDR_NET_ERR);
4777c478bd9Sstevel@tonic-gate 	}
4787c478bd9Sstevel@tonic-gate 
4797c478bd9Sstevel@tonic-gate 	return (RDR_OK);
4807c478bd9Sstevel@tonic-gate }
4817c478bd9Sstevel@tonic-gate 
4827c478bd9Sstevel@tonic-gate 
4837c478bd9Sstevel@tonic-gate /*
4847c478bd9Sstevel@tonic-gate  * rdr_connect_srv:
4857c478bd9Sstevel@tonic-gate  *
4867c478bd9Sstevel@tonic-gate  * Perform the necessary steps for a server to connect to a
4877c478bd9Sstevel@tonic-gate  * pending client request. The new connection is allocated a
4887c478bd9Sstevel@tonic-gate  * new file descriptor, separate from the one used to accept
4897c478bd9Sstevel@tonic-gate  * the connection.
4907c478bd9Sstevel@tonic-gate  */
4917c478bd9Sstevel@tonic-gate int
rdr_connect_srv(int fd)4927c478bd9Sstevel@tonic-gate rdr_connect_srv(int fd)
4937c478bd9Sstevel@tonic-gate {
4947c478bd9Sstevel@tonic-gate 	int			newfd;
4957c478bd9Sstevel@tonic-gate 	unsigned int		faddr_len;
4967c478bd9Sstevel@tonic-gate 	struct sockaddr_storage	faddr;
4977c478bd9Sstevel@tonic-gate 
4987c478bd9Sstevel@tonic-gate 
499*25cf1a30Sjl139090 	/* accept the connection */
5007c478bd9Sstevel@tonic-gate 	faddr_len = sizeof (faddr);
5017c478bd9Sstevel@tonic-gate 	if ((newfd = accept(fd, (struct sockaddr *)&faddr, &faddr_len)) == -1) {
5027c478bd9Sstevel@tonic-gate 		return (RDR_BAD_FD);
5037c478bd9Sstevel@tonic-gate 	}
5047c478bd9Sstevel@tonic-gate 
505*25cf1a30Sjl139090 	/* if the peer doesn't authenticate properly, reject */
506*25cf1a30Sjl139090 	if (rdr_auth((struct sockaddr *)&faddr, faddr_len) != RDR_OK) {
507*25cf1a30Sjl139090 		(void) close(newfd);
508*25cf1a30Sjl139090 		return (RDR_BAD_FD);
509*25cf1a30Sjl139090 	}
510*25cf1a30Sjl139090 
5117c478bd9Sstevel@tonic-gate 	return (newfd);
5127c478bd9Sstevel@tonic-gate }
5137c478bd9Sstevel@tonic-gate 
5147c478bd9Sstevel@tonic-gate 
5157c478bd9Sstevel@tonic-gate /*
5167c478bd9Sstevel@tonic-gate  * rdr_reject:
5177c478bd9Sstevel@tonic-gate  *
5187c478bd9Sstevel@tonic-gate  * Reject an incoming connection attempt. This requires
5197c478bd9Sstevel@tonic-gate  * that the connection be accepted first.
5207c478bd9Sstevel@tonic-gate  */
5217c478bd9Sstevel@tonic-gate int
rdr_reject(int fd)5227c478bd9Sstevel@tonic-gate rdr_reject(int fd)
5237c478bd9Sstevel@tonic-gate {
5247c478bd9Sstevel@tonic-gate 	unsigned int		faddr_len;
5257c478bd9Sstevel@tonic-gate 	struct sockaddr_storage	faddr;
5267c478bd9Sstevel@tonic-gate 
5277c478bd9Sstevel@tonic-gate 
5287c478bd9Sstevel@tonic-gate 	/* first accept the connection */
5297c478bd9Sstevel@tonic-gate 	faddr_len = sizeof (faddr);
5307c478bd9Sstevel@tonic-gate 	if (accept(fd, (struct sockaddr *)&faddr, &faddr_len) == -1) {
5317c478bd9Sstevel@tonic-gate 		return (RDR_NET_ERR);
5327c478bd9Sstevel@tonic-gate 	}
5337c478bd9Sstevel@tonic-gate 
5347c478bd9Sstevel@tonic-gate 	/* then close it */
535*25cf1a30Sjl139090 	(void) close(fd);
5367c478bd9Sstevel@tonic-gate 
5377c478bd9Sstevel@tonic-gate 	return (RDR_OK);
5387c478bd9Sstevel@tonic-gate }
5397c478bd9Sstevel@tonic-gate 
5407c478bd9Sstevel@tonic-gate 
5417c478bd9Sstevel@tonic-gate /*
5427c478bd9Sstevel@tonic-gate  * rdr_close:
5437c478bd9Sstevel@tonic-gate  *
5447c478bd9Sstevel@tonic-gate  * Close down an given connection.
5457c478bd9Sstevel@tonic-gate  */
5467c478bd9Sstevel@tonic-gate int
rdr_close(int fd)5477c478bd9Sstevel@tonic-gate rdr_close(int fd)
5487c478bd9Sstevel@tonic-gate {
549*25cf1a30Sjl139090 	(void) close(fd);
5507c478bd9Sstevel@tonic-gate 
5517c478bd9Sstevel@tonic-gate 	return (RDR_OK);
5527c478bd9Sstevel@tonic-gate }
5537c478bd9Sstevel@tonic-gate 
5547c478bd9Sstevel@tonic-gate 
5557c478bd9Sstevel@tonic-gate /*
5567c478bd9Sstevel@tonic-gate  * rdr_snd_msg:
5577c478bd9Sstevel@tonic-gate  *
5587c478bd9Sstevel@tonic-gate  * Public interface for sending an RDR message. The data
5597c478bd9Sstevel@tonic-gate  * passed in through hdr and param are packed for network
5607c478bd9Sstevel@tonic-gate  * transport and sent.
5617c478bd9Sstevel@tonic-gate  */
5627c478bd9Sstevel@tonic-gate int
rdr_snd_msg(int fd,rdr_msg_hdr_t * hdr,cfga_params_t * param,int timeout)5637c478bd9Sstevel@tonic-gate rdr_snd_msg(int fd, rdr_msg_hdr_t *hdr, cfga_params_t *param, int timeout)
5647c478bd9Sstevel@tonic-gate {
5657c478bd9Sstevel@tonic-gate 	int	err;
5667c478bd9Sstevel@tonic-gate 	char	*pack_buf = NULL;
5677c478bd9Sstevel@tonic-gate 	int	pack_buf_sz = 0;
5687c478bd9Sstevel@tonic-gate 
5697c478bd9Sstevel@tonic-gate 
5707c478bd9Sstevel@tonic-gate 	/* sanity checks */
5717c478bd9Sstevel@tonic-gate 	if ((hdr == NULL) || (param == NULL)) {
5727c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
5737c478bd9Sstevel@tonic-gate 	}
5747c478bd9Sstevel@tonic-gate 
5757c478bd9Sstevel@tonic-gate 	/*
5767c478bd9Sstevel@tonic-gate 	 * Pack the message for transport
5777c478bd9Sstevel@tonic-gate 	 */
5787c478bd9Sstevel@tonic-gate 	switch (hdr->message_opcode) {
5797c478bd9Sstevel@tonic-gate 
5807c478bd9Sstevel@tonic-gate 		case RDR_SES_REQ: {
5817c478bd9Sstevel@tonic-gate 
5827c478bd9Sstevel@tonic-gate 			ses_req_params_t *rparam;
5837c478bd9Sstevel@tonic-gate 			rparam = (ses_req_params_t *)param;
5847c478bd9Sstevel@tonic-gate 
5857c478bd9Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
5867c478bd9Sstevel@tonic-gate 				err = pack_ses_req_request(rparam,
5877c478bd9Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
5887c478bd9Sstevel@tonic-gate 			} else {
5897c478bd9Sstevel@tonic-gate 				err = pack_ses_req_reply(rparam,
5907c478bd9Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
5917c478bd9Sstevel@tonic-gate 			}
5927c478bd9Sstevel@tonic-gate 
5937c478bd9Sstevel@tonic-gate 			break;
5947c478bd9Sstevel@tonic-gate 		}
5957c478bd9Sstevel@tonic-gate 
5967c478bd9Sstevel@tonic-gate 		case RDR_SES_ESTBL:
5977c478bd9Sstevel@tonic-gate 		case RDR_SES_END:
5987c478bd9Sstevel@tonic-gate 
5997c478bd9Sstevel@tonic-gate 			/*
6007c478bd9Sstevel@tonic-gate 			 * This is not an error condition because
6017c478bd9Sstevel@tonic-gate 			 * there is no extra information to pack.
6027c478bd9Sstevel@tonic-gate 			 */
6037c478bd9Sstevel@tonic-gate 			err = RDR_OK;
6047c478bd9Sstevel@tonic-gate 			break;
6057c478bd9Sstevel@tonic-gate 
6067c478bd9Sstevel@tonic-gate 		case RDR_CONF_CHANGE_STATE: {
6077c478bd9Sstevel@tonic-gate 
6087c478bd9Sstevel@tonic-gate 			change_state_params_t *cparam;
6097c478bd9Sstevel@tonic-gate 			cparam = (change_state_params_t *)param;
6107c478bd9Sstevel@tonic-gate 
6117c478bd9Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
6127c478bd9Sstevel@tonic-gate 				err = pack_change_state_request(cparam,
6137c478bd9Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
6147c478bd9Sstevel@tonic-gate 			} else {
6157c478bd9Sstevel@tonic-gate 				err = pack_change_state_reply(cparam,
6167c478bd9Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
6177c478bd9Sstevel@tonic-gate 			}
6187c478bd9Sstevel@tonic-gate 			break;
6197c478bd9Sstevel@tonic-gate 		}
6207c478bd9Sstevel@tonic-gate 
6217c478bd9Sstevel@tonic-gate 		case RDR_CONF_PRIVATE_FUNC: {
6227c478bd9Sstevel@tonic-gate 
6237c478bd9Sstevel@tonic-gate 			private_func_params_t *pparam;
6247c478bd9Sstevel@tonic-gate 			pparam = (private_func_params_t *)param;
6257c478bd9Sstevel@tonic-gate 
6267c478bd9Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
6277c478bd9Sstevel@tonic-gate 				err = pack_private_func_request(pparam,
6287c478bd9Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
6297c478bd9Sstevel@tonic-gate 			} else {
6307c478bd9Sstevel@tonic-gate 				err = pack_private_func_reply(pparam,
6317c478bd9Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
6327c478bd9Sstevel@tonic-gate 			}
6337c478bd9Sstevel@tonic-gate 			break;
6347c478bd9Sstevel@tonic-gate 		}
6357c478bd9Sstevel@tonic-gate 
6367c478bd9Sstevel@tonic-gate 		case RDR_CONF_TEST: {
6377c478bd9Sstevel@tonic-gate 
6387c478bd9Sstevel@tonic-gate 			test_params_t *tparam;
6397c478bd9Sstevel@tonic-gate 			tparam = (test_params_t *)param;
6407c478bd9Sstevel@tonic-gate 
6417c478bd9Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
6427c478bd9Sstevel@tonic-gate 				err = pack_test_request(tparam,
6437c478bd9Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
6447c478bd9Sstevel@tonic-gate 			} else {
6457c478bd9Sstevel@tonic-gate 				err = pack_test_reply(tparam,
6467c478bd9Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
6477c478bd9Sstevel@tonic-gate 			}
6487c478bd9Sstevel@tonic-gate 			break;
6497c478bd9Sstevel@tonic-gate 		}
6507c478bd9Sstevel@tonic-gate 
6517c478bd9Sstevel@tonic-gate 		case RDR_CONF_LIST_EXT: {
6527c478bd9Sstevel@tonic-gate 
6537c478bd9Sstevel@tonic-gate 			list_ext_params_t *lparam;
6547c478bd9Sstevel@tonic-gate 			lparam = (list_ext_params_t *)param;
6557c478bd9Sstevel@tonic-gate 
6567c478bd9Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
6577c478bd9Sstevel@tonic-gate 				err = pack_list_ext_request(lparam, &pack_buf,
6587c478bd9Sstevel@tonic-gate 				    &pack_buf_sz);
6597c478bd9Sstevel@tonic-gate 			} else {
6607c478bd9Sstevel@tonic-gate 				err = pack_list_ext_reply(lparam, &pack_buf,
6617c478bd9Sstevel@tonic-gate 				    &pack_buf_sz);
6627c478bd9Sstevel@tonic-gate 			}
6637c478bd9Sstevel@tonic-gate 			break;
6647c478bd9Sstevel@tonic-gate 		}
6657c478bd9Sstevel@tonic-gate 
6667c478bd9Sstevel@tonic-gate 		case RDR_CONF_HELP: {
6677c478bd9Sstevel@tonic-gate 
6687c478bd9Sstevel@tonic-gate 			help_params_t *hparam;
6697c478bd9Sstevel@tonic-gate 			hparam = (help_params_t *)param;
6707c478bd9Sstevel@tonic-gate 
6717c478bd9Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
6727c478bd9Sstevel@tonic-gate 				err = pack_help_request(hparam,
6737c478bd9Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
6747c478bd9Sstevel@tonic-gate 			} else {
6757c478bd9Sstevel@tonic-gate 
6767c478bd9Sstevel@tonic-gate 				/*
6777c478bd9Sstevel@tonic-gate 				 * This is not an error because help
6787c478bd9Sstevel@tonic-gate 				 * reply does not have any extra information
6797c478bd9Sstevel@tonic-gate 				 * to pack.
6807c478bd9Sstevel@tonic-gate 				 */
6817c478bd9Sstevel@tonic-gate 				err = RDR_OK;
6827c478bd9Sstevel@tonic-gate 			}
6837c478bd9Sstevel@tonic-gate 			break;
6847c478bd9Sstevel@tonic-gate 		}
6857c478bd9Sstevel@tonic-gate 
6867c478bd9Sstevel@tonic-gate 		case RDR_CONF_AP_ID_CMP: {
6877c478bd9Sstevel@tonic-gate 
6887c478bd9Sstevel@tonic-gate 			ap_id_cmp_params_t *aparam;
6897c478bd9Sstevel@tonic-gate 			aparam = (ap_id_cmp_params_t *)param;
6907c478bd9Sstevel@tonic-gate 
6917c478bd9Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
6927c478bd9Sstevel@tonic-gate 				err = pack_ap_id_cmp_request(aparam,
6937c478bd9Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
6947c478bd9Sstevel@tonic-gate 			} else {
6957c478bd9Sstevel@tonic-gate 
6967c478bd9Sstevel@tonic-gate 				/*
6977c478bd9Sstevel@tonic-gate 				 * This is not an error because ap_id_cmp
6987c478bd9Sstevel@tonic-gate 				 * reply does not have any extra information
6997c478bd9Sstevel@tonic-gate 				 * to pack.
7007c478bd9Sstevel@tonic-gate 				 */
7017c478bd9Sstevel@tonic-gate 				err = RDR_OK;
7027c478bd9Sstevel@tonic-gate 			}
7037c478bd9Sstevel@tonic-gate 			break;
7047c478bd9Sstevel@tonic-gate 		}
7057c478bd9Sstevel@tonic-gate 
7067c478bd9Sstevel@tonic-gate 		case RDR_CONF_ABORT_CMD: {
7077c478bd9Sstevel@tonic-gate 
7087c478bd9Sstevel@tonic-gate 			abort_cmd_params_t *aparam;
7097c478bd9Sstevel@tonic-gate 			aparam = (abort_cmd_params_t *)param;
7107c478bd9Sstevel@tonic-gate 
7117c478bd9Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
7127c478bd9Sstevel@tonic-gate 				err = pack_abort_cmd_request(aparam,
7137c478bd9Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
7147c478bd9Sstevel@tonic-gate 			} else {
7157c478bd9Sstevel@tonic-gate 				/*
7167c478bd9Sstevel@tonic-gate 				 * This is not an error because session
7177c478bd9Sstevel@tonic-gate 				 * abort reply does not have any extra
7187c478bd9Sstevel@tonic-gate 				 * information to pack.
7197c478bd9Sstevel@tonic-gate 				 */
7207c478bd9Sstevel@tonic-gate 				err = RDR_OK;
7217c478bd9Sstevel@tonic-gate 			}
7227c478bd9Sstevel@tonic-gate 			break;
7237c478bd9Sstevel@tonic-gate 		}
7247c478bd9Sstevel@tonic-gate 
7257c478bd9Sstevel@tonic-gate 		case RDR_CONF_CONFIRM_CALLBACK: {
7267c478bd9Sstevel@tonic-gate 
7277c478bd9Sstevel@tonic-gate 			confirm_callback_params_t *cparam;
7287c478bd9Sstevel@tonic-gate 			cparam = (confirm_callback_params_t *)param;
7297c478bd9Sstevel@tonic-gate 
7307c478bd9Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
7317c478bd9Sstevel@tonic-gate 				err = pack_confirm_request(cparam,
7327c478bd9Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
7337c478bd9Sstevel@tonic-gate 			} else {
7347c478bd9Sstevel@tonic-gate 				err = pack_confirm_reply(cparam, &pack_buf,
7357c478bd9Sstevel@tonic-gate 				    &pack_buf_sz);
7367c478bd9Sstevel@tonic-gate 			}
7377c478bd9Sstevel@tonic-gate 			break;
7387c478bd9Sstevel@tonic-gate 		}
7397c478bd9Sstevel@tonic-gate 
7407c478bd9Sstevel@tonic-gate 		case RDR_CONF_MSG_CALLBACK: {
7417c478bd9Sstevel@tonic-gate 
7427c478bd9Sstevel@tonic-gate 			msg_callback_params_t *mparam;
7437c478bd9Sstevel@tonic-gate 			mparam = (msg_callback_params_t *)param;
7447c478bd9Sstevel@tonic-gate 
7457c478bd9Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
7467c478bd9Sstevel@tonic-gate 				err = pack_message_request(mparam,
7477c478bd9Sstevel@tonic-gate 				    &pack_buf, &pack_buf_sz);
7487c478bd9Sstevel@tonic-gate 			} else {
7497c478bd9Sstevel@tonic-gate 				/*
7507c478bd9Sstevel@tonic-gate 				 * It is an error to send a reply
7517c478bd9Sstevel@tonic-gate 				 * to a message callback.
7527c478bd9Sstevel@tonic-gate 				 */
7537c478bd9Sstevel@tonic-gate 				err = RDR_MSG_INVAL;
7547c478bd9Sstevel@tonic-gate 			}
7557c478bd9Sstevel@tonic-gate 			break;
7567c478bd9Sstevel@tonic-gate 		}
7577c478bd9Sstevel@tonic-gate 
7587c478bd9Sstevel@tonic-gate 		case RDR_RSRC_INFO: {
7597c478bd9Sstevel@tonic-gate 
7607c478bd9Sstevel@tonic-gate 			rsrc_info_params_t *rparam;
7617c478bd9Sstevel@tonic-gate 			rparam = (rsrc_info_params_t *)param;
7627c478bd9Sstevel@tonic-gate 
7637c478bd9Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
7647c478bd9Sstevel@tonic-gate 				err = pack_rsrc_info_request(rparam, &pack_buf,
7657c478bd9Sstevel@tonic-gate 				    &pack_buf_sz);
7667c478bd9Sstevel@tonic-gate 			} else {
767*25cf1a30Sjl139090 				if ((hdr->major_version == 1) &&
768*25cf1a30Sjl139090 				    (hdr->minor_version == 0)) {
769*25cf1a30Sjl139090 					err = pack_rsrc_info_reply(rparam,
770*25cf1a30Sjl139090 					    &pack_buf, &pack_buf_sz,
771*25cf1a30Sjl139090 					    NV_ENCODE_NATIVE);
772*25cf1a30Sjl139090 				} else {
773*25cf1a30Sjl139090 					err = pack_rsrc_info_reply(rparam,
774*25cf1a30Sjl139090 					    &pack_buf, &pack_buf_sz,
775*25cf1a30Sjl139090 					    NV_ENCODE_XDR);
776*25cf1a30Sjl139090 				}
7777c478bd9Sstevel@tonic-gate 			}
7787c478bd9Sstevel@tonic-gate 			break;
7797c478bd9Sstevel@tonic-gate 		}
7807c478bd9Sstevel@tonic-gate 
7817c478bd9Sstevel@tonic-gate 		default:
7827c478bd9Sstevel@tonic-gate 			err = RDR_MSG_INVAL;
7837c478bd9Sstevel@tonic-gate 			break;
7847c478bd9Sstevel@tonic-gate 	}
7857c478bd9Sstevel@tonic-gate 
7867c478bd9Sstevel@tonic-gate 	/* check if packed correctly */
7877c478bd9Sstevel@tonic-gate 	if (err != RDR_OK) {
7887c478bd9Sstevel@tonic-gate 		return (err);
7897c478bd9Sstevel@tonic-gate 	}
7907c478bd9Sstevel@tonic-gate 
7917c478bd9Sstevel@tonic-gate 	/* send the message */
7927c478bd9Sstevel@tonic-gate 	err = rdr_snd(fd, hdr, pack_buf, pack_buf_sz, timeout);
7937c478bd9Sstevel@tonic-gate 
7947c478bd9Sstevel@tonic-gate 	free((void *)pack_buf);
7957c478bd9Sstevel@tonic-gate 
7967c478bd9Sstevel@tonic-gate 	return (err);
7977c478bd9Sstevel@tonic-gate }
7987c478bd9Sstevel@tonic-gate 
7997c478bd9Sstevel@tonic-gate 
8007c478bd9Sstevel@tonic-gate /*
8017c478bd9Sstevel@tonic-gate  * rdr_rcv_msg:
8027c478bd9Sstevel@tonic-gate  *
8037c478bd9Sstevel@tonic-gate  * Public interface for receiving an RDR message. Data is
8047c478bd9Sstevel@tonic-gate  * unpacked into the hdr and param paramters.
8057c478bd9Sstevel@tonic-gate  */
8067c478bd9Sstevel@tonic-gate int
rdr_rcv_msg(int fd,rdr_msg_hdr_t * hdr,cfga_params_t * param,int timeout)8077c478bd9Sstevel@tonic-gate rdr_rcv_msg(int fd, rdr_msg_hdr_t *hdr, cfga_params_t *param, int timeout)
8087c478bd9Sstevel@tonic-gate {
8097c478bd9Sstevel@tonic-gate 	int	err;
8107c478bd9Sstevel@tonic-gate 	char	*unpack_buf = NULL;
8117c478bd9Sstevel@tonic-gate 
8127c478bd9Sstevel@tonic-gate 
8137c478bd9Sstevel@tonic-gate 	/* sanity checks */
8147c478bd9Sstevel@tonic-gate 	if ((hdr == NULL) || (param == NULL)) {
8157c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
8167c478bd9Sstevel@tonic-gate 	}
8177c478bd9Sstevel@tonic-gate 
8187c478bd9Sstevel@tonic-gate 	(void) memset(param, 0, sizeof (cfga_params_t));
8197c478bd9Sstevel@tonic-gate 
8207c478bd9Sstevel@tonic-gate 	/* receive the message */
8217c478bd9Sstevel@tonic-gate 	if ((err = rdr_rcv(fd, hdr, &unpack_buf, timeout)) != RDR_OK) {
8227c478bd9Sstevel@tonic-gate 		return (err);
8237c478bd9Sstevel@tonic-gate 	}
8247c478bd9Sstevel@tonic-gate 
8257c478bd9Sstevel@tonic-gate 	/*
8267c478bd9Sstevel@tonic-gate 	 * Unpack the message
8277c478bd9Sstevel@tonic-gate 	 */
8287c478bd9Sstevel@tonic-gate 	switch (hdr->message_opcode) {
8297c478bd9Sstevel@tonic-gate 
8307c478bd9Sstevel@tonic-gate 		case RDR_SES_REQ: {
8317c478bd9Sstevel@tonic-gate 
8327c478bd9Sstevel@tonic-gate 			ses_req_params_t *rparam;
8337c478bd9Sstevel@tonic-gate 			rparam = (ses_req_params_t *)param;
8347c478bd9Sstevel@tonic-gate 
8357c478bd9Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
8367c478bd9Sstevel@tonic-gate 				err = unpack_ses_req_request(rparam,
8377c478bd9Sstevel@tonic-gate 				    unpack_buf);
8387c478bd9Sstevel@tonic-gate 			} else {
8397c478bd9Sstevel@tonic-gate 				err = unpack_ses_req_reply(rparam, unpack_buf);
8407c478bd9Sstevel@tonic-gate 			}
8417c478bd9Sstevel@tonic-gate 			break;
8427c478bd9Sstevel@tonic-gate 		}
8437c478bd9Sstevel@tonic-gate 
8447c478bd9Sstevel@tonic-gate 		case RDR_SES_ESTBL:
8457c478bd9Sstevel@tonic-gate 		case RDR_SES_END:
8467c478bd9Sstevel@tonic-gate 
8477c478bd9Sstevel@tonic-gate 			/* no information to unpack */
8487c478bd9Sstevel@tonic-gate 			(void) memset(param, 0, sizeof (cfga_params_t));
8497c478bd9Sstevel@tonic-gate 			err = RDR_OK;
8507c478bd9Sstevel@tonic-gate 			break;
8517c478bd9Sstevel@tonic-gate 
8527c478bd9Sstevel@tonic-gate 		case RDR_CONF_CHANGE_STATE: {
8537c478bd9Sstevel@tonic-gate 
8547c478bd9Sstevel@tonic-gate 			change_state_params_t *cparam;
8557c478bd9Sstevel@tonic-gate 			cparam = (change_state_params_t *)param;
8567c478bd9Sstevel@tonic-gate 
8577c478bd9Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
8587c478bd9Sstevel@tonic-gate 				err = unpack_change_state_request(cparam,
8597c478bd9Sstevel@tonic-gate 				    unpack_buf);
8607c478bd9Sstevel@tonic-gate 			} else {
8617c478bd9Sstevel@tonic-gate 				err = unpack_change_state_reply(cparam,
8627c478bd9Sstevel@tonic-gate 				    unpack_buf);
8637c478bd9Sstevel@tonic-gate 			}
8647c478bd9Sstevel@tonic-gate 			break;
8657c478bd9Sstevel@tonic-gate 		}
8667c478bd9Sstevel@tonic-gate 
8677c478bd9Sstevel@tonic-gate 		case RDR_CONF_PRIVATE_FUNC: {
8687c478bd9Sstevel@tonic-gate 
8697c478bd9Sstevel@tonic-gate 			private_func_params_t *pparam;
8707c478bd9Sstevel@tonic-gate 			pparam = (private_func_params_t *)param;
8717c478bd9Sstevel@tonic-gate 
8727c478bd9Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
8737c478bd9Sstevel@tonic-gate 				err = unpack_private_func_request(pparam,
8747c478bd9Sstevel@tonic-gate 				    unpack_buf);
8757c478bd9Sstevel@tonic-gate 			} else {
8767c478bd9Sstevel@tonic-gate 				err = unpack_private_func_reply(pparam,
8777c478bd9Sstevel@tonic-gate 				    unpack_buf);
8787c478bd9Sstevel@tonic-gate 			}
8797c478bd9Sstevel@tonic-gate 			break;
8807c478bd9Sstevel@tonic-gate 		}
8817c478bd9Sstevel@tonic-gate 
8827c478bd9Sstevel@tonic-gate 		case RDR_CONF_TEST: {
8837c478bd9Sstevel@tonic-gate 
8847c478bd9Sstevel@tonic-gate 			test_params_t *tparam;
8857c478bd9Sstevel@tonic-gate 			tparam = (test_params_t *)param;
8867c478bd9Sstevel@tonic-gate 
8877c478bd9Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
8887c478bd9Sstevel@tonic-gate 				err = unpack_test_request(tparam, unpack_buf);
8897c478bd9Sstevel@tonic-gate 			} else {
8907c478bd9Sstevel@tonic-gate 				err = unpack_test_reply(tparam, unpack_buf);
8917c478bd9Sstevel@tonic-gate 			}
8927c478bd9Sstevel@tonic-gate 			break;
8937c478bd9Sstevel@tonic-gate 		}
8947c478bd9Sstevel@tonic-gate 
8957c478bd9Sstevel@tonic-gate 		case RDR_CONF_LIST_EXT: {
8967c478bd9Sstevel@tonic-gate 
8977c478bd9Sstevel@tonic-gate 			list_ext_params_t *lparam;
8987c478bd9Sstevel@tonic-gate 			lparam = (list_ext_params_t *)param;
8997c478bd9Sstevel@tonic-gate 
9007c478bd9Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
9017c478bd9Sstevel@tonic-gate 				err = unpack_list_ext_request(lparam,
9027c478bd9Sstevel@tonic-gate 				    unpack_buf);
9037c478bd9Sstevel@tonic-gate 			} else {
9047c478bd9Sstevel@tonic-gate 				err = unpack_list_ext_reply(lparam, unpack_buf);
9057c478bd9Sstevel@tonic-gate 			}
9067c478bd9Sstevel@tonic-gate 			break;
9077c478bd9Sstevel@tonic-gate 		}
9087c478bd9Sstevel@tonic-gate 
9097c478bd9Sstevel@tonic-gate 		case RDR_CONF_HELP: {
9107c478bd9Sstevel@tonic-gate 
9117c478bd9Sstevel@tonic-gate 			help_params_t *hparam;
9127c478bd9Sstevel@tonic-gate 			hparam = (help_params_t *)param;
9137c478bd9Sstevel@tonic-gate 
9147c478bd9Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
9157c478bd9Sstevel@tonic-gate 				err = unpack_help_request(hparam,
9167c478bd9Sstevel@tonic-gate 				    unpack_buf);
9177c478bd9Sstevel@tonic-gate 			} else {
9187c478bd9Sstevel@tonic-gate 				/*
9197c478bd9Sstevel@tonic-gate 				 * This is not an error because help
9207c478bd9Sstevel@tonic-gate 				 * reply does not have any extra information
9217c478bd9Sstevel@tonic-gate 				 * to unpack.
9227c478bd9Sstevel@tonic-gate 				 */
9237c478bd9Sstevel@tonic-gate 				err = RDR_OK;
9247c478bd9Sstevel@tonic-gate 			}
9257c478bd9Sstevel@tonic-gate 			break;
9267c478bd9Sstevel@tonic-gate 		}
9277c478bd9Sstevel@tonic-gate 
9287c478bd9Sstevel@tonic-gate 		case RDR_CONF_AP_ID_CMP: {
9297c478bd9Sstevel@tonic-gate 
9307c478bd9Sstevel@tonic-gate 			ap_id_cmp_params_t *aparam;
9317c478bd9Sstevel@tonic-gate 			aparam = (ap_id_cmp_params_t *)param;
9327c478bd9Sstevel@tonic-gate 
9337c478bd9Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
9347c478bd9Sstevel@tonic-gate 				err = unpack_ap_id_cmp_request(aparam,
9357c478bd9Sstevel@tonic-gate 				    unpack_buf);
9367c478bd9Sstevel@tonic-gate 			} else {
9377c478bd9Sstevel@tonic-gate 				/*
9387c478bd9Sstevel@tonic-gate 				 * This is not an error because ap_id_cmp
9397c478bd9Sstevel@tonic-gate 				 * reply does not have any extra information
9407c478bd9Sstevel@tonic-gate 				 * to pack.
9417c478bd9Sstevel@tonic-gate 				 */
9427c478bd9Sstevel@tonic-gate 				err = RDR_OK;
9437c478bd9Sstevel@tonic-gate 			}
9447c478bd9Sstevel@tonic-gate 			break;
9457c478bd9Sstevel@tonic-gate 		}
9467c478bd9Sstevel@tonic-gate 
9477c478bd9Sstevel@tonic-gate 		case RDR_CONF_ABORT_CMD: {
9487c478bd9Sstevel@tonic-gate 
9497c478bd9Sstevel@tonic-gate 			abort_cmd_params_t *aparam;
9507c478bd9Sstevel@tonic-gate 			aparam = (abort_cmd_params_t *)param;
9517c478bd9Sstevel@tonic-gate 
9527c478bd9Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
9537c478bd9Sstevel@tonic-gate 				err = unpack_abort_cmd_request(aparam,
9547c478bd9Sstevel@tonic-gate 				    unpack_buf);
9557c478bd9Sstevel@tonic-gate 			} else {
9567c478bd9Sstevel@tonic-gate 				/* no information to unpack */
9577c478bd9Sstevel@tonic-gate 				(void) memset(param, 0, sizeof (cfga_params_t));
9587c478bd9Sstevel@tonic-gate 				err = RDR_OK;
9597c478bd9Sstevel@tonic-gate 			}
9607c478bd9Sstevel@tonic-gate 
9617c478bd9Sstevel@tonic-gate 			break;
9627c478bd9Sstevel@tonic-gate 		}
9637c478bd9Sstevel@tonic-gate 
9647c478bd9Sstevel@tonic-gate 		case RDR_CONF_CONFIRM_CALLBACK: {
9657c478bd9Sstevel@tonic-gate 
9667c478bd9Sstevel@tonic-gate 			confirm_callback_params_t *cparam;
9677c478bd9Sstevel@tonic-gate 			cparam = (confirm_callback_params_t *)param;
9687c478bd9Sstevel@tonic-gate 
9697c478bd9Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
9707c478bd9Sstevel@tonic-gate 				err = unpack_confirm_request(cparam,
9717c478bd9Sstevel@tonic-gate 				    unpack_buf);
9727c478bd9Sstevel@tonic-gate 			} else {
9737c478bd9Sstevel@tonic-gate 				err = unpack_confirm_reply(cparam, unpack_buf);
9747c478bd9Sstevel@tonic-gate 			}
9757c478bd9Sstevel@tonic-gate 			break;
9767c478bd9Sstevel@tonic-gate 		}
9777c478bd9Sstevel@tonic-gate 
9787c478bd9Sstevel@tonic-gate 		case RDR_CONF_MSG_CALLBACK: {
9797c478bd9Sstevel@tonic-gate 
9807c478bd9Sstevel@tonic-gate 			msg_callback_params_t *mparam;
9817c478bd9Sstevel@tonic-gate 			mparam = (msg_callback_params_t *)param;
9827c478bd9Sstevel@tonic-gate 
9837c478bd9Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
9847c478bd9Sstevel@tonic-gate 				err = unpack_message_request(mparam,
9857c478bd9Sstevel@tonic-gate 				    unpack_buf);
9867c478bd9Sstevel@tonic-gate 			} else {
9877c478bd9Sstevel@tonic-gate 				/*
9887c478bd9Sstevel@tonic-gate 				 * It is an error to send a reply
9897c478bd9Sstevel@tonic-gate 				 * to a message callback.
9907c478bd9Sstevel@tonic-gate 				 */
9917c478bd9Sstevel@tonic-gate 				(void) memset(param, 0, sizeof (cfga_params_t));
9927c478bd9Sstevel@tonic-gate 				err = RDR_MSG_INVAL;
9937c478bd9Sstevel@tonic-gate 			}
9947c478bd9Sstevel@tonic-gate 			break;
9957c478bd9Sstevel@tonic-gate 		}
9967c478bd9Sstevel@tonic-gate 
9977c478bd9Sstevel@tonic-gate 		case RDR_RSRC_INFO: {
9987c478bd9Sstevel@tonic-gate 
9997c478bd9Sstevel@tonic-gate 			rsrc_info_params_t *rparam;
10007c478bd9Sstevel@tonic-gate 			rparam = (rsrc_info_params_t *)param;
10017c478bd9Sstevel@tonic-gate 
10027c478bd9Sstevel@tonic-gate 			if (hdr->data_type == RDR_REQUEST) {
10037c478bd9Sstevel@tonic-gate 				err = unpack_rsrc_info_request(rparam,
10047c478bd9Sstevel@tonic-gate 				    unpack_buf);
10057c478bd9Sstevel@tonic-gate 			} else {
10067c478bd9Sstevel@tonic-gate 				err = unpack_rsrc_info_reply(rparam,
10077c478bd9Sstevel@tonic-gate 				    unpack_buf);
10087c478bd9Sstevel@tonic-gate 			}
10097c478bd9Sstevel@tonic-gate 			break;
10107c478bd9Sstevel@tonic-gate 		}
10117c478bd9Sstevel@tonic-gate 
10127c478bd9Sstevel@tonic-gate 		default:
10137c478bd9Sstevel@tonic-gate 			err = RDR_MSG_INVAL;
10147c478bd9Sstevel@tonic-gate 			break;
10157c478bd9Sstevel@tonic-gate 	}
10167c478bd9Sstevel@tonic-gate 
10177c478bd9Sstevel@tonic-gate 	free(unpack_buf);
10187c478bd9Sstevel@tonic-gate 
10197c478bd9Sstevel@tonic-gate 	/* check if unpacked correctly */
10207c478bd9Sstevel@tonic-gate 	if (err != RDR_OK) {
10217c478bd9Sstevel@tonic-gate 		return (err);
10227c478bd9Sstevel@tonic-gate 	}
10237c478bd9Sstevel@tonic-gate 
10247c478bd9Sstevel@tonic-gate 	return (RDR_OK);
10257c478bd9Sstevel@tonic-gate }
10267c478bd9Sstevel@tonic-gate 
10277c478bd9Sstevel@tonic-gate 
10287c478bd9Sstevel@tonic-gate /*
10297c478bd9Sstevel@tonic-gate  * rdr_cleanup_params:
10307c478bd9Sstevel@tonic-gate  *
10317c478bd9Sstevel@tonic-gate  * Deallocate any memory that was allocated in unpacking a
10327c478bd9Sstevel@tonic-gate  * message.
10337c478bd9Sstevel@tonic-gate  */
10347c478bd9Sstevel@tonic-gate int
rdr_cleanup_params(rdr_msg_opcode_t message_opcode,cfga_params_t * param)10357c478bd9Sstevel@tonic-gate rdr_cleanup_params(rdr_msg_opcode_t message_opcode, cfga_params_t *param)
10367c478bd9Sstevel@tonic-gate {
10377c478bd9Sstevel@tonic-gate 	/* sanity check */
10387c478bd9Sstevel@tonic-gate 	if ((param == NULL)) {
10397c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
10407c478bd9Sstevel@tonic-gate 	}
10417c478bd9Sstevel@tonic-gate 
10427c478bd9Sstevel@tonic-gate 	/*
10437c478bd9Sstevel@tonic-gate 	 * Deallocate memory depending on
10447c478bd9Sstevel@tonic-gate 	 * the operation.
10457c478bd9Sstevel@tonic-gate 	 */
10467c478bd9Sstevel@tonic-gate 	switch (message_opcode) {
10477c478bd9Sstevel@tonic-gate 
10487c478bd9Sstevel@tonic-gate 	case RDR_SES_REQ: {
10497c478bd9Sstevel@tonic-gate 
10507c478bd9Sstevel@tonic-gate 		ses_req_params_t *sparam;
10517c478bd9Sstevel@tonic-gate 		sparam = (ses_req_params_t *)param;
10527c478bd9Sstevel@tonic-gate 
10537c478bd9Sstevel@tonic-gate 		if (sparam->locale_str != NULL) {
10547c478bd9Sstevel@tonic-gate 			free((void *)sparam->locale_str);
10557c478bd9Sstevel@tonic-gate 			sparam->locale_str = NULL;
10567c478bd9Sstevel@tonic-gate 		}
10577c478bd9Sstevel@tonic-gate 		break;
10587c478bd9Sstevel@tonic-gate 	}
10597c478bd9Sstevel@tonic-gate 
10607c478bd9Sstevel@tonic-gate 	case RDR_SES_ESTBL:
10617c478bd9Sstevel@tonic-gate 	case RDR_SES_END:
10627c478bd9Sstevel@tonic-gate 
10637c478bd9Sstevel@tonic-gate 		/* nothing to deallocate */
10647c478bd9Sstevel@tonic-gate 		break;
10657c478bd9Sstevel@tonic-gate 
10667c478bd9Sstevel@tonic-gate 	case RDR_CONF_CHANGE_STATE: {
10677c478bd9Sstevel@tonic-gate 
10687c478bd9Sstevel@tonic-gate 		change_state_params_t *cparam;
10697c478bd9Sstevel@tonic-gate 		cparam = (change_state_params_t *)param;
10707c478bd9Sstevel@tonic-gate 
10717c478bd9Sstevel@tonic-gate 		cleanup_ap_ids(cparam->num_ap_ids, (char **)cparam->ap_ids);
10727c478bd9Sstevel@tonic-gate 		cparam->ap_ids = NULL;
10737c478bd9Sstevel@tonic-gate 		if (cparam->options != NULL) {
10747c478bd9Sstevel@tonic-gate 			free((void *)cparam->options);
10757c478bd9Sstevel@tonic-gate 			cparam->options = NULL;
10767c478bd9Sstevel@tonic-gate 		}
10777c478bd9Sstevel@tonic-gate 		if (cparam->confp != NULL) {
10787c478bd9Sstevel@tonic-gate 			free((void *)cparam->confp);
10797c478bd9Sstevel@tonic-gate 			cparam->confp = NULL;
10807c478bd9Sstevel@tonic-gate 		}
10817c478bd9Sstevel@tonic-gate 		if (cparam->msgp != NULL) {
10827c478bd9Sstevel@tonic-gate 			free((void *)cparam->msgp);
10837c478bd9Sstevel@tonic-gate 			cparam->msgp = NULL;
10847c478bd9Sstevel@tonic-gate 		}
10857c478bd9Sstevel@tonic-gate 		cleanup_errstring(cparam->errstring);
10867c478bd9Sstevel@tonic-gate 		break;
10877c478bd9Sstevel@tonic-gate 	}
10887c478bd9Sstevel@tonic-gate 
10897c478bd9Sstevel@tonic-gate 	case RDR_CONF_PRIVATE_FUNC: {
10907c478bd9Sstevel@tonic-gate 
10917c478bd9Sstevel@tonic-gate 		private_func_params_t *pparam;
10927c478bd9Sstevel@tonic-gate 		pparam = (private_func_params_t *)param;
10937c478bd9Sstevel@tonic-gate 
10947c478bd9Sstevel@tonic-gate 		cleanup_ap_ids(pparam->num_ap_ids, (char **)pparam->ap_ids);
10957c478bd9Sstevel@tonic-gate 		pparam->ap_ids = NULL;
10967c478bd9Sstevel@tonic-gate 		if (pparam->options != NULL) {
10977c478bd9Sstevel@tonic-gate 			free((void *)pparam->options);
10987c478bd9Sstevel@tonic-gate 			pparam->options = NULL;
10997c478bd9Sstevel@tonic-gate 		}
11007c478bd9Sstevel@tonic-gate 		if (pparam->confp != NULL) {
11017c478bd9Sstevel@tonic-gate 			free((void *)pparam->confp);
11027c478bd9Sstevel@tonic-gate 			pparam->confp = NULL;
11037c478bd9Sstevel@tonic-gate 		}
11047c478bd9Sstevel@tonic-gate 		if (pparam->msgp != NULL) {
11057c478bd9Sstevel@tonic-gate 			free((void *)pparam->msgp);
11067c478bd9Sstevel@tonic-gate 			pparam->msgp = NULL;
11077c478bd9Sstevel@tonic-gate 		}
11087c478bd9Sstevel@tonic-gate 		cleanup_errstring(pparam->errstring);
11097c478bd9Sstevel@tonic-gate 		break;
11107c478bd9Sstevel@tonic-gate 	}
11117c478bd9Sstevel@tonic-gate 
11127c478bd9Sstevel@tonic-gate 	case RDR_CONF_TEST: {
11137c478bd9Sstevel@tonic-gate 
11147c478bd9Sstevel@tonic-gate 		test_params_t *tparam;
11157c478bd9Sstevel@tonic-gate 		tparam = (test_params_t *)param;
11167c478bd9Sstevel@tonic-gate 
11177c478bd9Sstevel@tonic-gate 		cleanup_ap_ids(tparam->num_ap_ids, (char **)tparam->ap_ids);
11187c478bd9Sstevel@tonic-gate 		tparam->ap_ids = NULL;
11197c478bd9Sstevel@tonic-gate 		if (tparam->options != NULL) {
11207c478bd9Sstevel@tonic-gate 			free((void *)tparam->options);
11217c478bd9Sstevel@tonic-gate 			tparam->options = NULL;
11227c478bd9Sstevel@tonic-gate 		}
11237c478bd9Sstevel@tonic-gate 		if (tparam->msgp != NULL) {
11247c478bd9Sstevel@tonic-gate 			free((void *)tparam->msgp);
11257c478bd9Sstevel@tonic-gate 			tparam->msgp = NULL;
11267c478bd9Sstevel@tonic-gate 		}
11277c478bd9Sstevel@tonic-gate 		cleanup_errstring(tparam->errstring);
11287c478bd9Sstevel@tonic-gate 		break;
11297c478bd9Sstevel@tonic-gate 	}
11307c478bd9Sstevel@tonic-gate 
11317c478bd9Sstevel@tonic-gate 	case RDR_CONF_LIST_EXT: {
11327c478bd9Sstevel@tonic-gate 
11337c478bd9Sstevel@tonic-gate 		list_ext_params_t *lparam;
11347c478bd9Sstevel@tonic-gate 		lparam = (list_ext_params_t *)param;
11357c478bd9Sstevel@tonic-gate 
11367c478bd9Sstevel@tonic-gate 		cleanup_ap_ids(lparam->num_ap_ids, (char **)lparam->ap_ids);
11377c478bd9Sstevel@tonic-gate 		lparam->ap_ids = NULL;
11387c478bd9Sstevel@tonic-gate 
11397c478bd9Sstevel@tonic-gate 		if (lparam->nlist != NULL) {
11407c478bd9Sstevel@tonic-gate 			free((void *)lparam->nlist);
11417c478bd9Sstevel@tonic-gate 			lparam->nlist = NULL;
11427c478bd9Sstevel@tonic-gate 		}
11437c478bd9Sstevel@tonic-gate 		if (lparam->ap_id_list != NULL) {
11447c478bd9Sstevel@tonic-gate 			if (*lparam->ap_id_list != NULL) {
11457c478bd9Sstevel@tonic-gate 				free((void *)*lparam->ap_id_list);
11467c478bd9Sstevel@tonic-gate 			}
11477c478bd9Sstevel@tonic-gate 			free((void *)lparam->ap_id_list);
11487c478bd9Sstevel@tonic-gate 			lparam->ap_id_list = NULL;
11497c478bd9Sstevel@tonic-gate 		}
11507c478bd9Sstevel@tonic-gate 		if (lparam->ap_id_list != NULL) {
11517c478bd9Sstevel@tonic-gate 			free((void *)lparam->ap_id_list);
11527c478bd9Sstevel@tonic-gate 			lparam->ap_id_list = NULL;
11537c478bd9Sstevel@tonic-gate 		}
11547c478bd9Sstevel@tonic-gate 
11557c478bd9Sstevel@tonic-gate 		if (lparam->options != NULL) {
11567c478bd9Sstevel@tonic-gate 			free((void *)lparam->options);
11577c478bd9Sstevel@tonic-gate 			lparam->options = NULL;
11587c478bd9Sstevel@tonic-gate 		}
11597c478bd9Sstevel@tonic-gate 		if (lparam->listopts != NULL) {
11607c478bd9Sstevel@tonic-gate 			free((void *)lparam->listopts);
11617c478bd9Sstevel@tonic-gate 			lparam->listopts = NULL;
11627c478bd9Sstevel@tonic-gate 		}
11637c478bd9Sstevel@tonic-gate 		cleanup_errstring(lparam->errstring);
11647c478bd9Sstevel@tonic-gate 		break;
11657c478bd9Sstevel@tonic-gate 	}
11667c478bd9Sstevel@tonic-gate 
11677c478bd9Sstevel@tonic-gate 	case RDR_CONF_HELP: {
11687c478bd9Sstevel@tonic-gate 
11697c478bd9Sstevel@tonic-gate 		help_params_t *hparam;
11707c478bd9Sstevel@tonic-gate 		hparam = (help_params_t *)param;
11717c478bd9Sstevel@tonic-gate 
11727c478bd9Sstevel@tonic-gate 		cleanup_ap_ids(hparam->num_ap_ids, (char **)hparam->ap_ids);
11737c478bd9Sstevel@tonic-gate 		hparam->ap_ids = NULL;
11747c478bd9Sstevel@tonic-gate 		if (hparam->msgp != NULL) {
11757c478bd9Sstevel@tonic-gate 			free((void *)hparam->msgp);
11767c478bd9Sstevel@tonic-gate 			hparam->msgp = NULL;
11777c478bd9Sstevel@tonic-gate 		}
11787c478bd9Sstevel@tonic-gate 		if (hparam->options != NULL) {
11797c478bd9Sstevel@tonic-gate 			free((void *)hparam->options);
11807c478bd9Sstevel@tonic-gate 			hparam->options = NULL;
11817c478bd9Sstevel@tonic-gate 		}
11827c478bd9Sstevel@tonic-gate 		break;
11837c478bd9Sstevel@tonic-gate 	}
11847c478bd9Sstevel@tonic-gate 
11857c478bd9Sstevel@tonic-gate 	case RDR_CONF_AP_ID_CMP: {
11867c478bd9Sstevel@tonic-gate 
11877c478bd9Sstevel@tonic-gate 		ap_id_cmp_params_t *aparam;
11887c478bd9Sstevel@tonic-gate 		aparam = (ap_id_cmp_params_t *)param;
11897c478bd9Sstevel@tonic-gate 
11907c478bd9Sstevel@tonic-gate 		if (aparam->ap_log_id1 != NULL) {
11917c478bd9Sstevel@tonic-gate 			free((void *)aparam->ap_log_id1);
11927c478bd9Sstevel@tonic-gate 			aparam->ap_log_id1 = NULL;
11937c478bd9Sstevel@tonic-gate 		}
11947c478bd9Sstevel@tonic-gate 		if (aparam->ap_log_id2 != NULL) {
11957c478bd9Sstevel@tonic-gate 			free((void *)aparam->ap_log_id2);
11967c478bd9Sstevel@tonic-gate 			aparam->ap_log_id2 = NULL;
11977c478bd9Sstevel@tonic-gate 		}
11987c478bd9Sstevel@tonic-gate 		break;
11997c478bd9Sstevel@tonic-gate 	}
12007c478bd9Sstevel@tonic-gate 
12017c478bd9Sstevel@tonic-gate 	case RDR_CONF_ABORT_CMD:
12027c478bd9Sstevel@tonic-gate 
12037c478bd9Sstevel@tonic-gate 		/* nothing to deallocate */
12047c478bd9Sstevel@tonic-gate 		break;
12057c478bd9Sstevel@tonic-gate 
12067c478bd9Sstevel@tonic-gate 	case RDR_CONF_CONFIRM_CALLBACK: {
12077c478bd9Sstevel@tonic-gate 
12087c478bd9Sstevel@tonic-gate 		confirm_callback_params_t *cparam;
12097c478bd9Sstevel@tonic-gate 		cparam = (confirm_callback_params_t *)param;
12107c478bd9Sstevel@tonic-gate 
12117c478bd9Sstevel@tonic-gate 		if (cparam->confp != NULL) {
12127c478bd9Sstevel@tonic-gate 			free((void *)cparam->confp);
12137c478bd9Sstevel@tonic-gate 			cparam->confp = NULL;
12147c478bd9Sstevel@tonic-gate 		}
12157c478bd9Sstevel@tonic-gate 		if (cparam->message != NULL) {
12167c478bd9Sstevel@tonic-gate 			free((void *)cparam->message);
12177c478bd9Sstevel@tonic-gate 			cparam->message = NULL;
12187c478bd9Sstevel@tonic-gate 		}
12197c478bd9Sstevel@tonic-gate 		break;
12207c478bd9Sstevel@tonic-gate 	}
12217c478bd9Sstevel@tonic-gate 
12227c478bd9Sstevel@tonic-gate 	case RDR_CONF_MSG_CALLBACK: {
12237c478bd9Sstevel@tonic-gate 
12247c478bd9Sstevel@tonic-gate 		msg_callback_params_t *mparam;
12257c478bd9Sstevel@tonic-gate 		mparam = (msg_callback_params_t *)param;
12267c478bd9Sstevel@tonic-gate 
12277c478bd9Sstevel@tonic-gate 		if (mparam->msgp != NULL) {
12287c478bd9Sstevel@tonic-gate 			free((void *)mparam->msgp);
12297c478bd9Sstevel@tonic-gate 			mparam->msgp = NULL;
12307c478bd9Sstevel@tonic-gate 		}
12317c478bd9Sstevel@tonic-gate 		if (mparam->message != NULL) {
12327c478bd9Sstevel@tonic-gate 			free((void *)mparam->message);
12337c478bd9Sstevel@tonic-gate 			mparam->message = NULL;
12347c478bd9Sstevel@tonic-gate 		}
12357c478bd9Sstevel@tonic-gate 		break;
12367c478bd9Sstevel@tonic-gate 	}
12377c478bd9Sstevel@tonic-gate 
12387c478bd9Sstevel@tonic-gate 	default:
12397c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
12407c478bd9Sstevel@tonic-gate 		/* NOTREACHED */
12417c478bd9Sstevel@tonic-gate 		break;
12427c478bd9Sstevel@tonic-gate 
12437c478bd9Sstevel@tonic-gate 	}
12447c478bd9Sstevel@tonic-gate 
12457c478bd9Sstevel@tonic-gate 	return (RDR_OK);
12467c478bd9Sstevel@tonic-gate }
12477c478bd9Sstevel@tonic-gate 
12482eaee53eSmb158278 /*
12492eaee53eSmb158278  * rdr_setsockopt:
12502eaee53eSmb158278  *
12512eaee53eSmb158278  * Wrapper of the setsockopt(3SOCKET) library function.
12522eaee53eSmb158278  */
12532eaee53eSmb158278 int
rdr_setsockopt(int fd,int level,int optname,const void * optval,int optlen)12542eaee53eSmb158278 rdr_setsockopt(int fd, int level, int optname, const void *optval, int optlen)
12552eaee53eSmb158278 {
12562eaee53eSmb158278 	if (setsockopt(fd, level, optname, optval, optlen) == -1)
12572eaee53eSmb158278 		return (RDR_NET_ERR);
12582eaee53eSmb158278 	else
12592eaee53eSmb158278 		return (RDR_OK);
12602eaee53eSmb158278 }
12612eaee53eSmb158278 
12627c478bd9Sstevel@tonic-gate 
12637c478bd9Sstevel@tonic-gate /*
12647c478bd9Sstevel@tonic-gate  * Private (static) Functions
12657c478bd9Sstevel@tonic-gate  */
12667c478bd9Sstevel@tonic-gate 
12677c478bd9Sstevel@tonic-gate 
12687c478bd9Sstevel@tonic-gate /*
12697c478bd9Sstevel@tonic-gate  * rdr_setopt:
12707c478bd9Sstevel@tonic-gate  *
12717c478bd9Sstevel@tonic-gate  * Set the specified option for a given transport endpoint.
12727c478bd9Sstevel@tonic-gate  * This function only sets boolean options. It does not
12737c478bd9Sstevel@tonic-gate  * provide the ability to unset an option, or set a non-
12747c478bd9Sstevel@tonic-gate  * boolean option.
12757c478bd9Sstevel@tonic-gate  */
12767c478bd9Sstevel@tonic-gate static int
rdr_setopt(int fd,int name,int level)12777c478bd9Sstevel@tonic-gate rdr_setopt(int fd, int name, int level)
12787c478bd9Sstevel@tonic-gate {
12797c478bd9Sstevel@tonic-gate 	int	on = 1;
12807c478bd9Sstevel@tonic-gate 
12817c478bd9Sstevel@tonic-gate 
12827c478bd9Sstevel@tonic-gate 	if (setsockopt(fd, level, name, &on, sizeof (on)) == -1) {
12837c478bd9Sstevel@tonic-gate 		return (RDR_NET_ERR);
12847c478bd9Sstevel@tonic-gate 	}
12857c478bd9Sstevel@tonic-gate 
12867c478bd9Sstevel@tonic-gate 	return (RDR_OK);
12877c478bd9Sstevel@tonic-gate }
12887c478bd9Sstevel@tonic-gate 
12897c478bd9Sstevel@tonic-gate 
12907c478bd9Sstevel@tonic-gate /*
12917c478bd9Sstevel@tonic-gate  * rdr_bind:
12927c478bd9Sstevel@tonic-gate  *
12937c478bd9Sstevel@tonic-gate  * Bind the specified file descriptor to a specified
12947c478bd9Sstevel@tonic-gate  * address. If the address is already bound, no error is
12957c478bd9Sstevel@tonic-gate  * returned. This is the expected behavior if a server
12967c478bd9Sstevel@tonic-gate  * has been started by inetd (1M).
12977c478bd9Sstevel@tonic-gate  */
12987c478bd9Sstevel@tonic-gate static int
rdr_bind(int fd,struct sockaddr * addr)12997c478bd9Sstevel@tonic-gate rdr_bind(int fd, struct sockaddr *addr)
13007c478bd9Sstevel@tonic-gate {
13017c478bd9Sstevel@tonic-gate 	unsigned int		addr_len;
13027c478bd9Sstevel@tonic-gate 	int			rc;
13037c478bd9Sstevel@tonic-gate 
13047c478bd9Sstevel@tonic-gate 
13057c478bd9Sstevel@tonic-gate 	/* initialize the address */
13067c478bd9Sstevel@tonic-gate 	switch (addr->sa_family) {
13077c478bd9Sstevel@tonic-gate 
13087c478bd9Sstevel@tonic-gate 	case AF_INET:
13097c478bd9Sstevel@tonic-gate 		addr_len = sizeof (struct sockaddr_in);
13107c478bd9Sstevel@tonic-gate 		break;
13117c478bd9Sstevel@tonic-gate 
13127c478bd9Sstevel@tonic-gate 	case AF_INET6:
13137c478bd9Sstevel@tonic-gate 		addr_len = sizeof (struct sockaddr_in6);
13147c478bd9Sstevel@tonic-gate 		break;
13157c478bd9Sstevel@tonic-gate 
13167c478bd9Sstevel@tonic-gate 	default:
13177c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
13187c478bd9Sstevel@tonic-gate 	}
13197c478bd9Sstevel@tonic-gate 
13207c478bd9Sstevel@tonic-gate 	/* attempt to bind the address */
13217c478bd9Sstevel@tonic-gate 	rc = bind(fd, addr, addr_len);
13227c478bd9Sstevel@tonic-gate 
13237c478bd9Sstevel@tonic-gate 	/*
13247c478bd9Sstevel@tonic-gate 	 * Ignore the error if EINVAL is returned. In
13257c478bd9Sstevel@tonic-gate 	 * this case, we assume that this means that
13267c478bd9Sstevel@tonic-gate 	 * the address was already bound. This is not
13277c478bd9Sstevel@tonic-gate 	 * an error for servers started by inetd (1M).
13287c478bd9Sstevel@tonic-gate 	 */
13297c478bd9Sstevel@tonic-gate 	if ((rc == -1) && (errno != EINVAL)) {
13307c478bd9Sstevel@tonic-gate 		return (RDR_NET_ERR);
13317c478bd9Sstevel@tonic-gate 	}
13327c478bd9Sstevel@tonic-gate 
13337c478bd9Sstevel@tonic-gate 	/*
13347c478bd9Sstevel@tonic-gate 	 * Retreive the address information of the
13357c478bd9Sstevel@tonic-gate 	 * address that was actually bound.
13367c478bd9Sstevel@tonic-gate 	 */
13377c478bd9Sstevel@tonic-gate 	addr_len = sizeof (*addr);
13387c478bd9Sstevel@tonic-gate 	if (getsockname(fd, addr, &addr_len) == -1) {
13397c478bd9Sstevel@tonic-gate 		(void) memset(addr, 0, sizeof (*addr));
13407c478bd9Sstevel@tonic-gate 		return (RDR_NET_ERR);
13417c478bd9Sstevel@tonic-gate 	}
13427c478bd9Sstevel@tonic-gate 
13437c478bd9Sstevel@tonic-gate 	return (RDR_OK);
13447c478bd9Sstevel@tonic-gate }
13457c478bd9Sstevel@tonic-gate 
13467c478bd9Sstevel@tonic-gate 
13477c478bd9Sstevel@tonic-gate /*
1348*25cf1a30Sjl139090  * rdr_secure:
1349*25cf1a30Sjl139090  *
1350*25cf1a30Sjl139090  * Activate security features for a socket.
1351*25cf1a30Sjl139090  *
1352*25cf1a30Sjl139090  * Some platforms have libdscp, which provides additional
1353*25cf1a30Sjl139090  * security features.  An attempt is made to load libdscp
1354*25cf1a30Sjl139090  * and use these features.
1355*25cf1a30Sjl139090  *
1356*25cf1a30Sjl139090  * Nothing is done if libdscp is not available.
1357*25cf1a30Sjl139090  */
1358*25cf1a30Sjl139090 static int
rdr_secure(int fd,struct sockaddr * addr)1359*25cf1a30Sjl139090 rdr_secure(int fd, struct sockaddr *addr)
1360*25cf1a30Sjl139090 {
1361*25cf1a30Sjl139090 	struct sockaddr_in	*sin;
1362*25cf1a30Sjl139090 	int			port;
1363*25cf1a30Sjl139090 	int			error;
1364*25cf1a30Sjl139090 
1365*25cf1a30Sjl139090 	if (use_libdscp == 0) {
1366*25cf1a30Sjl139090 		return (RDR_OK);
1367*25cf1a30Sjl139090 	}
1368*25cf1a30Sjl139090 
1369*25cf1a30Sjl139090 	if (load_libdscp(&libdscp) != 1) {
1370*25cf1a30Sjl139090 		return (RDR_ERROR);
1371*25cf1a30Sjl139090 	}
1372*25cf1a30Sjl139090 
1373*25cf1a30Sjl139090 	/* LINTED E_BAD_PTR_CAST_ALIGN */
1374*25cf1a30Sjl139090 	sin = (struct sockaddr_in *)addr;
1375*25cf1a30Sjl139090 	port = ntohs(sin->sin_port);
1376*25cf1a30Sjl139090 	error = libdscp.bind(0, fd, port);
1377*25cf1a30Sjl139090 
1378*25cf1a30Sjl139090 	if ((error != DSCP_OK) && (error != DSCP_ERROR_ALREADY)) {
1379*25cf1a30Sjl139090 		return (RDR_ERROR);
1380*25cf1a30Sjl139090 	}
1381*25cf1a30Sjl139090 
1382*25cf1a30Sjl139090 	if (libdscp.secure(0, fd) != DSCP_OK) {
1383*25cf1a30Sjl139090 		return (RDR_ERROR);
1384*25cf1a30Sjl139090 	}
1385*25cf1a30Sjl139090 	return (RDR_OK);
1386*25cf1a30Sjl139090 }
1387*25cf1a30Sjl139090 
1388*25cf1a30Sjl139090 /*
1389*25cf1a30Sjl139090  * rdr_auth:
1390*25cf1a30Sjl139090  *
1391*25cf1a30Sjl139090  * Authenticate if a connection is really from the service
1392*25cf1a30Sjl139090  * processor.  This is dependent upon functionality from
1393*25cf1a30Sjl139090  * libdscp, so an attempt to load and use libdscp is made.
1394*25cf1a30Sjl139090  *
1395*25cf1a30Sjl139090  * Without libdscp, this function does nothing.
1396*25cf1a30Sjl139090  */
1397*25cf1a30Sjl139090 static int
rdr_auth(struct sockaddr * addr,int len)1398*25cf1a30Sjl139090 rdr_auth(struct sockaddr *addr, int len)
1399*25cf1a30Sjl139090 {
1400*25cf1a30Sjl139090 	if (use_libdscp != 0) {
1401*25cf1a30Sjl139090 		if ((load_libdscp(&libdscp) == 0) ||
1402*25cf1a30Sjl139090 		    (libdscp.auth(0, addr, len) != DSCP_OK)) {
1403*25cf1a30Sjl139090 			return (RDR_ERROR);
1404*25cf1a30Sjl139090 		}
1405*25cf1a30Sjl139090 	}
1406*25cf1a30Sjl139090 
1407*25cf1a30Sjl139090 	return (RDR_OK);
1408*25cf1a30Sjl139090 }
1409*25cf1a30Sjl139090 
1410*25cf1a30Sjl139090 /*
14117c478bd9Sstevel@tonic-gate  * rdr_snd:
14127c478bd9Sstevel@tonic-gate  *
14137c478bd9Sstevel@tonic-gate  * Send a message in two stages. First the header is sent,
14147c478bd9Sstevel@tonic-gate  * followed by the packed buffer containing the message
14157c478bd9Sstevel@tonic-gate  * contents.
14167c478bd9Sstevel@tonic-gate  */
14177c478bd9Sstevel@tonic-gate static int
rdr_snd(int fd,rdr_msg_hdr_t * hdr,char * data,int data_sz,int timeout)14187c478bd9Sstevel@tonic-gate rdr_snd(int fd, rdr_msg_hdr_t *hdr, char *data, int data_sz, int timeout)
14197c478bd9Sstevel@tonic-gate {
14207c478bd9Sstevel@tonic-gate 	int	err;
14217c478bd9Sstevel@tonic-gate 
14227c478bd9Sstevel@tonic-gate 
14237c478bd9Sstevel@tonic-gate 	/* sanity check */
14247c478bd9Sstevel@tonic-gate 	if (hdr == NULL) {
14257c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
14267c478bd9Sstevel@tonic-gate 	}
14277c478bd9Sstevel@tonic-gate 
14287c478bd9Sstevel@tonic-gate 	/* ensure null pad bytes */
14297c478bd9Sstevel@tonic-gate 	hdr->pad_byte1 = 0;
14307c478bd9Sstevel@tonic-gate 	hdr->pad_byte2 = 0;
14317c478bd9Sstevel@tonic-gate 
14327c478bd9Sstevel@tonic-gate 	/* initialize size information */
14337c478bd9Sstevel@tonic-gate 	hdr->data_length = data_sz;
14347c478bd9Sstevel@tonic-gate 
14357c478bd9Sstevel@tonic-gate 	/* send message header */
14367c478bd9Sstevel@tonic-gate 	err = rdr_snd_raw(fd, (char *)hdr, RDR_MSG_HDR_SIZE, timeout);
14377c478bd9Sstevel@tonic-gate 	if (err != RDR_OK) {
14387c478bd9Sstevel@tonic-gate 		return (err);
14397c478bd9Sstevel@tonic-gate 	}
14407c478bd9Sstevel@tonic-gate 
14417c478bd9Sstevel@tonic-gate 	/* check if more to send */
14427c478bd9Sstevel@tonic-gate 	if (data_sz == 0) {
14437c478bd9Sstevel@tonic-gate 		return (RDR_OK);
14447c478bd9Sstevel@tonic-gate 	}
14457c478bd9Sstevel@tonic-gate 
14467c478bd9Sstevel@tonic-gate 	/* send message data */
14477c478bd9Sstevel@tonic-gate 	err = rdr_snd_raw(fd, data, data_sz, timeout);
14487c478bd9Sstevel@tonic-gate 	if (err != RDR_OK) {
14497c478bd9Sstevel@tonic-gate 		return (err);
14507c478bd9Sstevel@tonic-gate 	}
14517c478bd9Sstevel@tonic-gate 
14527c478bd9Sstevel@tonic-gate 	return (RDR_OK);
14537c478bd9Sstevel@tonic-gate }
14547c478bd9Sstevel@tonic-gate 
14557c478bd9Sstevel@tonic-gate 
14567c478bd9Sstevel@tonic-gate /*
14577c478bd9Sstevel@tonic-gate  * rdr_snd_raw:
14587c478bd9Sstevel@tonic-gate  *
14597c478bd9Sstevel@tonic-gate  * Send a raw buffer of information. This function handles
14607c478bd9Sstevel@tonic-gate  * the low level details of the send operation.
14617c478bd9Sstevel@tonic-gate  */
14627c478bd9Sstevel@tonic-gate static int
rdr_snd_raw(int fd,char * msg,int data_sz,int timeout)14637c478bd9Sstevel@tonic-gate rdr_snd_raw(int fd, char *msg, int data_sz, int timeout)
14647c478bd9Sstevel@tonic-gate {
14657c478bd9Sstevel@tonic-gate 	int		err;
14667c478bd9Sstevel@tonic-gate 	int		num_bytes;
14677c478bd9Sstevel@tonic-gate 	int		bytes_left;
14687c478bd9Sstevel@tonic-gate 	char		*bufp;
14697c478bd9Sstevel@tonic-gate 	struct pollfd	pfd;
14707c478bd9Sstevel@tonic-gate 
14717c478bd9Sstevel@tonic-gate 
14727c478bd9Sstevel@tonic-gate 	bufp = (char *)msg;
14737c478bd9Sstevel@tonic-gate 
14747c478bd9Sstevel@tonic-gate 	bytes_left = data_sz;
14757c478bd9Sstevel@tonic-gate 
14767c478bd9Sstevel@tonic-gate 	pfd.fd = fd;
14777c478bd9Sstevel@tonic-gate 	pfd.events = POLLOUT;
14787c478bd9Sstevel@tonic-gate 
14797c478bd9Sstevel@tonic-gate 	while (bytes_left > 0) {
14807c478bd9Sstevel@tonic-gate 
14817c478bd9Sstevel@tonic-gate 		pfd.revents = 0;
14827c478bd9Sstevel@tonic-gate 
14837c478bd9Sstevel@tonic-gate 		/* wait until we can send the data */
14847c478bd9Sstevel@tonic-gate 		if ((err = poll(&pfd, 1, timeout)) == -1) {
14857c478bd9Sstevel@tonic-gate 
14867c478bd9Sstevel@tonic-gate 			/* poll was interrupted */
14877c478bd9Sstevel@tonic-gate 			if (errno == EINTR) {
14887c478bd9Sstevel@tonic-gate 				return (RDR_ABORTED);
14897c478bd9Sstevel@tonic-gate 			}
14907c478bd9Sstevel@tonic-gate 
14917c478bd9Sstevel@tonic-gate 			return (RDR_ERROR);
14927c478bd9Sstevel@tonic-gate 
14937c478bd9Sstevel@tonic-gate 		} else if (err == 0) {
14947c478bd9Sstevel@tonic-gate 			return (RDR_TIMEOUT);
14957c478bd9Sstevel@tonic-gate 		}
14967c478bd9Sstevel@tonic-gate 
14977c478bd9Sstevel@tonic-gate 		/* ready to send data */
14987c478bd9Sstevel@tonic-gate 		if (pfd.revents & POLLOUT) {
14997c478bd9Sstevel@tonic-gate 
15007c478bd9Sstevel@tonic-gate 			num_bytes = write(fd, bufp, bytes_left);
15017c478bd9Sstevel@tonic-gate 
15027c478bd9Sstevel@tonic-gate 			if (num_bytes == -1) {
15037c478bd9Sstevel@tonic-gate 
15047c478bd9Sstevel@tonic-gate 				/*
15057c478bd9Sstevel@tonic-gate 				 * Distinguish between an aborted
15067c478bd9Sstevel@tonic-gate 				 * session and other network errors.
15077c478bd9Sstevel@tonic-gate 				 */
15087c478bd9Sstevel@tonic-gate 				if (errno == EPIPE) {
15097c478bd9Sstevel@tonic-gate 					return (RDR_ABORTED);
15107c478bd9Sstevel@tonic-gate 				} else {
15117c478bd9Sstevel@tonic-gate 					return (RDR_NET_ERR);
15127c478bd9Sstevel@tonic-gate 				}
15137c478bd9Sstevel@tonic-gate 			}
15147c478bd9Sstevel@tonic-gate 
15157c478bd9Sstevel@tonic-gate 			/* wrote 0 bytes, so operation was aborted */
15167c478bd9Sstevel@tonic-gate 			if (num_bytes == 0) {
15177c478bd9Sstevel@tonic-gate 				return (RDR_ABORTED);
15187c478bd9Sstevel@tonic-gate 			}
15197c478bd9Sstevel@tonic-gate 
15207c478bd9Sstevel@tonic-gate 		} else {
15217c478bd9Sstevel@tonic-gate 			return (RDR_NET_ERR);
15227c478bd9Sstevel@tonic-gate 		}
15237c478bd9Sstevel@tonic-gate 
15247c478bd9Sstevel@tonic-gate 		bytes_left -= num_bytes;
15257c478bd9Sstevel@tonic-gate 		bufp += num_bytes;
15267c478bd9Sstevel@tonic-gate 	}
15277c478bd9Sstevel@tonic-gate 
15287c478bd9Sstevel@tonic-gate 	return (RDR_OK);
15297c478bd9Sstevel@tonic-gate }
15307c478bd9Sstevel@tonic-gate 
15317c478bd9Sstevel@tonic-gate 
15327c478bd9Sstevel@tonic-gate /*
15337c478bd9Sstevel@tonic-gate  * rdr_rcv:
15347c478bd9Sstevel@tonic-gate  *
15357c478bd9Sstevel@tonic-gate  * Receive a message in two stages. First the header is
15367c478bd9Sstevel@tonic-gate  * received, followed by the packed buffer containing the
15377c478bd9Sstevel@tonic-gate  * message contents.
15387c478bd9Sstevel@tonic-gate  */
15397c478bd9Sstevel@tonic-gate static int
rdr_rcv(int fd,rdr_msg_hdr_t * hdr,char ** data,int timeout)15407c478bd9Sstevel@tonic-gate rdr_rcv(int fd, rdr_msg_hdr_t *hdr, char **data, int timeout)
15417c478bd9Sstevel@tonic-gate {
15427c478bd9Sstevel@tonic-gate 	int	err;
15437c478bd9Sstevel@tonic-gate 	int	data_sz;
15447c478bd9Sstevel@tonic-gate 	char	hdr_buf[RDR_MSG_HDR_SIZE];
15457c478bd9Sstevel@tonic-gate 	char	*buf = NULL;
15467c478bd9Sstevel@tonic-gate 
15477c478bd9Sstevel@tonic-gate 
15487c478bd9Sstevel@tonic-gate 	/* sanity check */
15497c478bd9Sstevel@tonic-gate 	if (hdr == NULL) {
15507c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
15517c478bd9Sstevel@tonic-gate 	}
15527c478bd9Sstevel@tonic-gate 
15537c478bd9Sstevel@tonic-gate 	/* receive the header */
15547c478bd9Sstevel@tonic-gate 	err = rdr_rcv_raw(fd, hdr_buf, RDR_MSG_HDR_SIZE, timeout);
15557c478bd9Sstevel@tonic-gate 	if (err != RDR_OK) {
15567c478bd9Sstevel@tonic-gate 		return (err);
15577c478bd9Sstevel@tonic-gate 	}
15587c478bd9Sstevel@tonic-gate 
15597c478bd9Sstevel@tonic-gate 	/* verify that the data is good */
15607c478bd9Sstevel@tonic-gate 	/* LINTED Pointer Cast Alignment Warning */
15617c478bd9Sstevel@tonic-gate 	if (validate_header((rdr_msg_hdr_t *)hdr_buf) != RDR_OK) {
15627c478bd9Sstevel@tonic-gate 		return (RDR_MSG_INVAL);
15637c478bd9Sstevel@tonic-gate 	}
15647c478bd9Sstevel@tonic-gate 
15657c478bd9Sstevel@tonic-gate 	/* LINTED Pointer Cast Alignment Warning */
15667c478bd9Sstevel@tonic-gate 	data_sz = ((rdr_msg_hdr_t *)hdr_buf)->data_length;
15677c478bd9Sstevel@tonic-gate 
15687c478bd9Sstevel@tonic-gate 	buf = (char *)malloc(data_sz);
15697c478bd9Sstevel@tonic-gate 	if (!buf) {
15707c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
15717c478bd9Sstevel@tonic-gate 	}
15727c478bd9Sstevel@tonic-gate 
15737c478bd9Sstevel@tonic-gate 	if (data_sz != 0) {
15747c478bd9Sstevel@tonic-gate 
15757c478bd9Sstevel@tonic-gate 		/* receive the rest of the message */
15767c478bd9Sstevel@tonic-gate 		err = rdr_rcv_raw(fd, buf, data_sz, timeout);
15777c478bd9Sstevel@tonic-gate 		if (err != RDR_OK) {
15787c478bd9Sstevel@tonic-gate 			free((void *)buf);
15797c478bd9Sstevel@tonic-gate 			return (err);
15807c478bd9Sstevel@tonic-gate 		}
15817c478bd9Sstevel@tonic-gate 	}
15827c478bd9Sstevel@tonic-gate 
15837c478bd9Sstevel@tonic-gate 	/* copy out data */
15847c478bd9Sstevel@tonic-gate 	*data = buf;
15857c478bd9Sstevel@tonic-gate 	(void) memcpy(hdr, hdr_buf, RDR_MSG_HDR_SIZE);
15867c478bd9Sstevel@tonic-gate 
15877c478bd9Sstevel@tonic-gate 	return (RDR_OK);
15887c478bd9Sstevel@tonic-gate }
15897c478bd9Sstevel@tonic-gate 
15907c478bd9Sstevel@tonic-gate 
15917c478bd9Sstevel@tonic-gate /*
15927c478bd9Sstevel@tonic-gate  * rdr_rcv_raw:
15937c478bd9Sstevel@tonic-gate  *
15947c478bd9Sstevel@tonic-gate  * Receive a raw buffer of information. This function handles
15957c478bd9Sstevel@tonic-gate  * the low level details of the receive operation.
15967c478bd9Sstevel@tonic-gate  */
15977c478bd9Sstevel@tonic-gate static int
rdr_rcv_raw(int fd,char * msg,int data_size,int timeout)15987c478bd9Sstevel@tonic-gate rdr_rcv_raw(int fd, char *msg, int data_size, int timeout)
15997c478bd9Sstevel@tonic-gate {
16007c478bd9Sstevel@tonic-gate 	int		num_bytes;
16017c478bd9Sstevel@tonic-gate 	int		err;
16027c478bd9Sstevel@tonic-gate 	int		bytes_left;
16037c478bd9Sstevel@tonic-gate 	char		*bufp;
16047c478bd9Sstevel@tonic-gate 	struct pollfd	pollfd;
16057c478bd9Sstevel@tonic-gate 
16067c478bd9Sstevel@tonic-gate 
16077c478bd9Sstevel@tonic-gate 	bufp = (char *)msg;
16087c478bd9Sstevel@tonic-gate 	bytes_left = data_size;
16097c478bd9Sstevel@tonic-gate 
16107c478bd9Sstevel@tonic-gate 	pollfd.fd = fd;
16117c478bd9Sstevel@tonic-gate 	pollfd.events = POLLIN;
16127c478bd9Sstevel@tonic-gate 
16137c478bd9Sstevel@tonic-gate 	while (bytes_left > 0) {
16147c478bd9Sstevel@tonic-gate 
16157c478bd9Sstevel@tonic-gate 		errno = 0;
16167c478bd9Sstevel@tonic-gate 		pollfd.revents = 0;
16177c478bd9Sstevel@tonic-gate 
16187c478bd9Sstevel@tonic-gate 		if ((err = poll(&pollfd, 1, timeout)) == -1) {
16197c478bd9Sstevel@tonic-gate 
16207c478bd9Sstevel@tonic-gate 			/*
16217c478bd9Sstevel@tonic-gate 			 * In the DCA, if a session is aborted, SIGINT
16227c478bd9Sstevel@tonic-gate 			 * is delivered to all active sessions. This
16237c478bd9Sstevel@tonic-gate 			 * mistakenly causes all sessions waiting in
16247c478bd9Sstevel@tonic-gate 			 * the poll to be interrupted. So, if EINTR
16257c478bd9Sstevel@tonic-gate 			 * is returned, it is ignored. If another error
16267c478bd9Sstevel@tonic-gate 			 * occurs right away, the current session really
16277c478bd9Sstevel@tonic-gate 			 * was aborted. All other sessions won't encounter
16287c478bd9Sstevel@tonic-gate 			 * an error and will proceed normally.
16297c478bd9Sstevel@tonic-gate 			 */
16307c478bd9Sstevel@tonic-gate 			if ((errno == 0) || (errno == EINTR)) {
16317c478bd9Sstevel@tonic-gate 				continue;
16327c478bd9Sstevel@tonic-gate 			}
16337c478bd9Sstevel@tonic-gate 
16347c478bd9Sstevel@tonic-gate 			return (RDR_ABORTED);
16357c478bd9Sstevel@tonic-gate 
16367c478bd9Sstevel@tonic-gate 		} else if (err == 0) {
16377c478bd9Sstevel@tonic-gate 			return (RDR_TIMEOUT);
16387c478bd9Sstevel@tonic-gate 		}
16397c478bd9Sstevel@tonic-gate 
16407c478bd9Sstevel@tonic-gate 		/* ready to receive data */
16417c478bd9Sstevel@tonic-gate 		if (pollfd.revents & POLLIN) {
16427c478bd9Sstevel@tonic-gate 
16437c478bd9Sstevel@tonic-gate 			num_bytes = read(fd, bufp, bytes_left);
16447c478bd9Sstevel@tonic-gate 
16457c478bd9Sstevel@tonic-gate 			if (num_bytes == -1) {
16467c478bd9Sstevel@tonic-gate 
16477c478bd9Sstevel@tonic-gate 				/*
16487c478bd9Sstevel@tonic-gate 				 * Distinguish between an aborted
16497c478bd9Sstevel@tonic-gate 				 * session and other network errors.
16507c478bd9Sstevel@tonic-gate 				 */
16517c478bd9Sstevel@tonic-gate 				if (errno == ECONNRESET) {
16527c478bd9Sstevel@tonic-gate 					return (RDR_ABORTED);
16537c478bd9Sstevel@tonic-gate 				} else {
16547c478bd9Sstevel@tonic-gate 					return (RDR_NET_ERR);
16557c478bd9Sstevel@tonic-gate 				}
16567c478bd9Sstevel@tonic-gate 			}
16577c478bd9Sstevel@tonic-gate 
16587c478bd9Sstevel@tonic-gate 			/* read 0 bytes, so operation was aborted */
16597c478bd9Sstevel@tonic-gate 			if (num_bytes == 0) {
16607c478bd9Sstevel@tonic-gate 				return (RDR_ABORTED);
16617c478bd9Sstevel@tonic-gate 			}
16627c478bd9Sstevel@tonic-gate 
16637c478bd9Sstevel@tonic-gate 		} else {
16647c478bd9Sstevel@tonic-gate 			return (RDR_NET_ERR);
16657c478bd9Sstevel@tonic-gate 		}
16667c478bd9Sstevel@tonic-gate 
16677c478bd9Sstevel@tonic-gate 		bytes_left -= num_bytes;
16687c478bd9Sstevel@tonic-gate 		bufp += num_bytes;
16697c478bd9Sstevel@tonic-gate 	}
16707c478bd9Sstevel@tonic-gate 
16717c478bd9Sstevel@tonic-gate 	return (RDR_OK);
16727c478bd9Sstevel@tonic-gate }
16737c478bd9Sstevel@tonic-gate 
16747c478bd9Sstevel@tonic-gate 
16757c478bd9Sstevel@tonic-gate /*
16767c478bd9Sstevel@tonic-gate  * validate_header:
16777c478bd9Sstevel@tonic-gate  *
16787c478bd9Sstevel@tonic-gate  * Perform a series of sanity checks on the header data that is
16797c478bd9Sstevel@tonic-gate  * received. This gets called before the variable length data is
16807c478bd9Sstevel@tonic-gate  * read in to make sure that the information in the header can
16817c478bd9Sstevel@tonic-gate  * be trusted.
16827c478bd9Sstevel@tonic-gate  */
16837c478bd9Sstevel@tonic-gate static int
validate_header(rdr_msg_hdr_t * hdr)16847c478bd9Sstevel@tonic-gate validate_header(rdr_msg_hdr_t *hdr)
16857c478bd9Sstevel@tonic-gate {
16867c478bd9Sstevel@tonic-gate 	unsigned char	op;
16877c478bd9Sstevel@tonic-gate 
16887c478bd9Sstevel@tonic-gate 
16897c478bd9Sstevel@tonic-gate 	if (hdr == NULL) {
16907c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
16917c478bd9Sstevel@tonic-gate 	}
16927c478bd9Sstevel@tonic-gate 
16937c478bd9Sstevel@tonic-gate 	op = hdr->message_opcode;
16947c478bd9Sstevel@tonic-gate 
16957c478bd9Sstevel@tonic-gate 	/* validate opcode */
16967c478bd9Sstevel@tonic-gate 	if ((op < RDR_SES_REQ) || (op >= RDR_NUM_OPS)) {
16977c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
16987c478bd9Sstevel@tonic-gate 	}
16997c478bd9Sstevel@tonic-gate 
17007c478bd9Sstevel@tonic-gate 	/* validate message size (and type) for op */
17017c478bd9Sstevel@tonic-gate 	switch (hdr->data_type) {
17027c478bd9Sstevel@tonic-gate 
17037c478bd9Sstevel@tonic-gate 	case RDR_REQUEST:
17047c478bd9Sstevel@tonic-gate 		if (hdr->data_length > msg_sizes[op].req_max) {
17057c478bd9Sstevel@tonic-gate 			return (RDR_ERROR);
17067c478bd9Sstevel@tonic-gate 		}
17077c478bd9Sstevel@tonic-gate 		break;
17087c478bd9Sstevel@tonic-gate 
17097c478bd9Sstevel@tonic-gate 	case RDR_REPLY:
17107c478bd9Sstevel@tonic-gate 		if (hdr->data_length > msg_sizes[op].reply_max) {
17117c478bd9Sstevel@tonic-gate 			return (RDR_ERROR);
17127c478bd9Sstevel@tonic-gate 		}
17137c478bd9Sstevel@tonic-gate 		break;
17147c478bd9Sstevel@tonic-gate 
17157c478bd9Sstevel@tonic-gate 	default:
17167c478bd9Sstevel@tonic-gate 		/* invalid data type */
17177c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
17187c478bd9Sstevel@tonic-gate 	}
17197c478bd9Sstevel@tonic-gate 
17207c478bd9Sstevel@tonic-gate 	/* all checks passed */
17217c478bd9Sstevel@tonic-gate 	return (RDR_OK);
17227c478bd9Sstevel@tonic-gate }
17237c478bd9Sstevel@tonic-gate 
17247c478bd9Sstevel@tonic-gate 
17257c478bd9Sstevel@tonic-gate /*
17267c478bd9Sstevel@tonic-gate  * pack_ses_req_request:
17277c478bd9Sstevel@tonic-gate  *
17287c478bd9Sstevel@tonic-gate  * Handle packing a session request request message.
17297c478bd9Sstevel@tonic-gate  */
17307c478bd9Sstevel@tonic-gate static int
pack_ses_req_request(ses_req_params_t * params,char ** buf,int * buf_size)17317c478bd9Sstevel@tonic-gate pack_ses_req_request(ses_req_params_t *params, char **buf, int *buf_size)
17327c478bd9Sstevel@tonic-gate {
17337c478bd9Sstevel@tonic-gate 	char		*bufptr;
17347c478bd9Sstevel@tonic-gate 	int		locale_str_len;
17357c478bd9Sstevel@tonic-gate 	rdr_ses_req_t	ses_req;
17367c478bd9Sstevel@tonic-gate 
17377c478bd9Sstevel@tonic-gate 
17387c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
17397c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
17407c478bd9Sstevel@tonic-gate 	}
17417c478bd9Sstevel@tonic-gate 
17427c478bd9Sstevel@tonic-gate 	/*
17437c478bd9Sstevel@tonic-gate 	 * Determine the size of the locale string
17447c478bd9Sstevel@tonic-gate 	 */
17457c478bd9Sstevel@tonic-gate 	if (params->locale_str != NULL) {
17467c478bd9Sstevel@tonic-gate 		locale_str_len = strlen(params->locale_str) + 1;
17477c478bd9Sstevel@tonic-gate 	} else {
17487c478bd9Sstevel@tonic-gate 		locale_str_len = 0;
17497c478bd9Sstevel@tonic-gate 	}
17507c478bd9Sstevel@tonic-gate 
17517c478bd9Sstevel@tonic-gate 	/*
17527c478bd9Sstevel@tonic-gate 	 * Collect size info specific to the ses_req request message
17537c478bd9Sstevel@tonic-gate 	 * and allocate a buffer
17547c478bd9Sstevel@tonic-gate 	 */
17557c478bd9Sstevel@tonic-gate 	*buf_size = sizeof (rdr_ses_req_t);
17567c478bd9Sstevel@tonic-gate 	*buf_size += locale_str_len;
17577c478bd9Sstevel@tonic-gate 
17587c478bd9Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
17597c478bd9Sstevel@tonic-gate 	if (*buf == NULL) {
17607c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
17617c478bd9Sstevel@tonic-gate 	}
17627c478bd9Sstevel@tonic-gate 
17637c478bd9Sstevel@tonic-gate 	/*
17647c478bd9Sstevel@tonic-gate 	 * Set fixed locale size label by name
17657c478bd9Sstevel@tonic-gate 	 */
17667c478bd9Sstevel@tonic-gate 	ses_req.locale_size = locale_str_len;
17677c478bd9Sstevel@tonic-gate 
17687c478bd9Sstevel@tonic-gate 	/*
17697c478bd9Sstevel@tonic-gate 	 * Set variable information using memcpy
17707c478bd9Sstevel@tonic-gate 	 */
17717c478bd9Sstevel@tonic-gate 	bufptr = *buf;
17727c478bd9Sstevel@tonic-gate 
17737c478bd9Sstevel@tonic-gate 	(void) memcpy(bufptr, &ses_req, sizeof (rdr_ses_req_t));
17747c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_ses_req_t);
17757c478bd9Sstevel@tonic-gate 
17767c478bd9Sstevel@tonic-gate 	if (params->locale_str != NULL) {
17777c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, params->locale_str, locale_str_len);
17787c478bd9Sstevel@tonic-gate 		bufptr += locale_str_len;
17797c478bd9Sstevel@tonic-gate 	}
17807c478bd9Sstevel@tonic-gate 
17817c478bd9Sstevel@tonic-gate 	return (RDR_OK);
17827c478bd9Sstevel@tonic-gate }
17837c478bd9Sstevel@tonic-gate 
17847c478bd9Sstevel@tonic-gate 
17857c478bd9Sstevel@tonic-gate /*
17867c478bd9Sstevel@tonic-gate  * unpack_ses_req_request:
17877c478bd9Sstevel@tonic-gate  *
17887c478bd9Sstevel@tonic-gate  * Handle unpacking a session request request message.
17897c478bd9Sstevel@tonic-gate  */
17907c478bd9Sstevel@tonic-gate static int
unpack_ses_req_request(ses_req_params_t * params,const char * buf)17917c478bd9Sstevel@tonic-gate unpack_ses_req_request(ses_req_params_t *params, const char *buf)
17927c478bd9Sstevel@tonic-gate {
17937c478bd9Sstevel@tonic-gate 	char		*bufptr;
17947c478bd9Sstevel@tonic-gate 	rdr_ses_req_t	ses_req_data;
17957c478bd9Sstevel@tonic-gate 
17967c478bd9Sstevel@tonic-gate 
17977c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
17987c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
17997c478bd9Sstevel@tonic-gate 	}
18007c478bd9Sstevel@tonic-gate 
18017c478bd9Sstevel@tonic-gate 	bufptr = (char *)buf;
18027c478bd9Sstevel@tonic-gate 	(void) memcpy(&ses_req_data, bufptr, sizeof (rdr_ses_req_t));
18037c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_ses_req_t);
18047c478bd9Sstevel@tonic-gate 
18057c478bd9Sstevel@tonic-gate 	/*
18067c478bd9Sstevel@tonic-gate 	 * handle getting the locale string
18077c478bd9Sstevel@tonic-gate 	 */
18087c478bd9Sstevel@tonic-gate 	if (get_string_from_buf(&(params->locale_str),
18097c478bd9Sstevel@tonic-gate 	    ses_req_data.locale_size, bufptr)) {
18107c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
18117c478bd9Sstevel@tonic-gate 	}
18127c478bd9Sstevel@tonic-gate 
18137c478bd9Sstevel@tonic-gate 	return (RDR_OK);
18147c478bd9Sstevel@tonic-gate }
18157c478bd9Sstevel@tonic-gate 
18167c478bd9Sstevel@tonic-gate 
18177c478bd9Sstevel@tonic-gate /*
18187c478bd9Sstevel@tonic-gate  * pack_ses_req_reply:
18197c478bd9Sstevel@tonic-gate  *
18207c478bd9Sstevel@tonic-gate  * Handle packing a session request reply message.
18217c478bd9Sstevel@tonic-gate  */
18227c478bd9Sstevel@tonic-gate static int
pack_ses_req_reply(ses_req_params_t * params,char ** buf,int * buf_size)18237c478bd9Sstevel@tonic-gate pack_ses_req_reply(ses_req_params_t *params, char **buf, int *buf_size)
18247c478bd9Sstevel@tonic-gate {
18257c478bd9Sstevel@tonic-gate 	rdr_ses_req_reply_t	ses_req_reply_data;
18267c478bd9Sstevel@tonic-gate 
18277c478bd9Sstevel@tonic-gate 
18287c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
18297c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
18307c478bd9Sstevel@tonic-gate 	}
18317c478bd9Sstevel@tonic-gate 
18327c478bd9Sstevel@tonic-gate 	/*
18337c478bd9Sstevel@tonic-gate 	 * Collect size info specific to the session request reply
18347c478bd9Sstevel@tonic-gate 	 * message and allocate a buffer
18357c478bd9Sstevel@tonic-gate 	 */
18367c478bd9Sstevel@tonic-gate 	*buf_size = sizeof (rdr_ses_req_reply_t);
18377c478bd9Sstevel@tonic-gate 
18387c478bd9Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
18397c478bd9Sstevel@tonic-gate 	if (*buf == NULL) {
18407c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
18417c478bd9Sstevel@tonic-gate 	}
18427c478bd9Sstevel@tonic-gate 
18437c478bd9Sstevel@tonic-gate 	/*
18447c478bd9Sstevel@tonic-gate 	 * Set fixed session identifier
18457c478bd9Sstevel@tonic-gate 	 */
18467c478bd9Sstevel@tonic-gate 	ses_req_reply_data.session_id = params->session_id;
18477c478bd9Sstevel@tonic-gate 
18487c478bd9Sstevel@tonic-gate 	/*
18497c478bd9Sstevel@tonic-gate 	 * Copy information using memcpy
18507c478bd9Sstevel@tonic-gate 	 */
18517c478bd9Sstevel@tonic-gate 	(void) memcpy(*buf, &ses_req_reply_data, sizeof (rdr_ses_req_reply_t));
18527c478bd9Sstevel@tonic-gate 
18537c478bd9Sstevel@tonic-gate 	return (RDR_OK);
18547c478bd9Sstevel@tonic-gate }
18557c478bd9Sstevel@tonic-gate 
18567c478bd9Sstevel@tonic-gate 
18577c478bd9Sstevel@tonic-gate /*
18587c478bd9Sstevel@tonic-gate  * unpack_ses_req_request:
18597c478bd9Sstevel@tonic-gate  *
18607c478bd9Sstevel@tonic-gate  * Handle unpacking a session request reply message.
18617c478bd9Sstevel@tonic-gate  */
18627c478bd9Sstevel@tonic-gate static int
unpack_ses_req_reply(ses_req_params_t * params,const char * buf)18637c478bd9Sstevel@tonic-gate unpack_ses_req_reply(ses_req_params_t *params, const char *buf)
18647c478bd9Sstevel@tonic-gate {
18657c478bd9Sstevel@tonic-gate 	rdr_ses_req_reply_t	*ses_req_reply_datap;
18667c478bd9Sstevel@tonic-gate 
18677c478bd9Sstevel@tonic-gate 
18687c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
18697c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
18707c478bd9Sstevel@tonic-gate 	}
18717c478bd9Sstevel@tonic-gate 
18727c478bd9Sstevel@tonic-gate 	/* LINTED Pointer Cast Alignment Warning */
18737c478bd9Sstevel@tonic-gate 	ses_req_reply_datap = (rdr_ses_req_reply_t *)buf;
18747c478bd9Sstevel@tonic-gate 
18757c478bd9Sstevel@tonic-gate 	/*
18767c478bd9Sstevel@tonic-gate 	 * copy out the session information
18777c478bd9Sstevel@tonic-gate 	 */
18787c478bd9Sstevel@tonic-gate 	params->session_id = ses_req_reply_datap->session_id;
18797c478bd9Sstevel@tonic-gate 
18807c478bd9Sstevel@tonic-gate 	return (RDR_OK);
18817c478bd9Sstevel@tonic-gate }
18827c478bd9Sstevel@tonic-gate 
18837c478bd9Sstevel@tonic-gate 
18847c478bd9Sstevel@tonic-gate /*
18857c478bd9Sstevel@tonic-gate  * pack_change_state_request:
18867c478bd9Sstevel@tonic-gate  *
18877c478bd9Sstevel@tonic-gate  * Handle packing a change state request message.
18887c478bd9Sstevel@tonic-gate  */
18897c478bd9Sstevel@tonic-gate static int
pack_change_state_request(change_state_params_t * params,char ** buf,int * buf_size)18907c478bd9Sstevel@tonic-gate pack_change_state_request(change_state_params_t *params, char **buf,
18917c478bd9Sstevel@tonic-gate     int *buf_size)
18927c478bd9Sstevel@tonic-gate {
18937c478bd9Sstevel@tonic-gate 	int				i;
18947c478bd9Sstevel@tonic-gate 	char				*bufptr;
18957c478bd9Sstevel@tonic-gate 	rdr_change_state_t		change_state_data;
18967c478bd9Sstevel@tonic-gate 	rdr_variable_message_info_t	var_msg_info;
18977c478bd9Sstevel@tonic-gate 
18987c478bd9Sstevel@tonic-gate 
18997c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
19007c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
19017c478bd9Sstevel@tonic-gate 	}
19027c478bd9Sstevel@tonic-gate 
19037c478bd9Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
19047c478bd9Sstevel@tonic-gate 
19057c478bd9Sstevel@tonic-gate 	/*
19067c478bd9Sstevel@tonic-gate 	 * Set variable length fields and make a call to partially
19077c478bd9Sstevel@tonic-gate 	 * pack it.
19087c478bd9Sstevel@tonic-gate 	 */
19097c478bd9Sstevel@tonic-gate 	if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) {
19107c478bd9Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
19117c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
19127c478bd9Sstevel@tonic-gate 	}
19137c478bd9Sstevel@tonic-gate 	if (find_options_sizes(params->options, &var_msg_info)) {
19147c478bd9Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
19157c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
19167c478bd9Sstevel@tonic-gate 	}
19177c478bd9Sstevel@tonic-gate 
19187c478bd9Sstevel@tonic-gate 	/*
19197c478bd9Sstevel@tonic-gate 	 * Collect size info specific to the change_state request
19207c478bd9Sstevel@tonic-gate 	 * message and allocate a buffer
19217c478bd9Sstevel@tonic-gate 	 */
19227c478bd9Sstevel@tonic-gate 	*buf_size = sizeof (rdr_change_state_t);
19237c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.ap_id_int_size;
19247c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.ap_id_char_size;
19257c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.options_strlen;
19267c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.options_pad_sz;
19277c478bd9Sstevel@tonic-gate 
19287c478bd9Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
19297c478bd9Sstevel@tonic-gate 	if (*buf == NULL) {
19307c478bd9Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
19317c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
19327c478bd9Sstevel@tonic-gate 	}
19337c478bd9Sstevel@tonic-gate 
19347c478bd9Sstevel@tonic-gate 	/*
19357c478bd9Sstevel@tonic-gate 	 * Set fixed address labels by name
19367c478bd9Sstevel@tonic-gate 	 */
19377c478bd9Sstevel@tonic-gate 	change_state_data.num_ap_ids = params->num_ap_ids;
19387c478bd9Sstevel@tonic-gate 	change_state_data.ap_id_char_size = var_msg_info.ap_id_char_size;
19397c478bd9Sstevel@tonic-gate 	change_state_data.options_size = var_msg_info.options_strlen +
19407c478bd9Sstevel@tonic-gate 	    var_msg_info.options_pad_sz;
19417c478bd9Sstevel@tonic-gate 
19427c478bd9Sstevel@tonic-gate 	if (params->confp != NULL) {
19437c478bd9Sstevel@tonic-gate 		change_state_data.confirm_callback_id =
19447c478bd9Sstevel@tonic-gate 		    (unsigned long)params->confp->confirm;
19457c478bd9Sstevel@tonic-gate 		change_state_data.confirm_appdata_ptr =
19467c478bd9Sstevel@tonic-gate 		    (unsigned long)params->confp->appdata_ptr;
19477c478bd9Sstevel@tonic-gate 	} else {
19487c478bd9Sstevel@tonic-gate 		change_state_data.confirm_callback_id = 0;
19497c478bd9Sstevel@tonic-gate 		change_state_data.confirm_appdata_ptr = 0;
19507c478bd9Sstevel@tonic-gate 	}
19517c478bd9Sstevel@tonic-gate 	if (params->msgp != NULL) {
19527c478bd9Sstevel@tonic-gate 		change_state_data.msg_callback_id =
19537c478bd9Sstevel@tonic-gate 		    (unsigned long)params->msgp->message_routine;
19547c478bd9Sstevel@tonic-gate 		change_state_data.msg_appdata_ptr =
19557c478bd9Sstevel@tonic-gate 		    (unsigned long)params->msgp->appdata_ptr;
19567c478bd9Sstevel@tonic-gate 	} else {
19577c478bd9Sstevel@tonic-gate 		change_state_data.msg_callback_id = 0;
19587c478bd9Sstevel@tonic-gate 		change_state_data.msg_appdata_ptr = 0;
19597c478bd9Sstevel@tonic-gate 	}
19607c478bd9Sstevel@tonic-gate 
19617c478bd9Sstevel@tonic-gate 	change_state_data.flags = params->flags;
19627c478bd9Sstevel@tonic-gate 	change_state_data.timeval = params->timeval;
19637c478bd9Sstevel@tonic-gate 	change_state_data.state_change_cmd = params->state_change;
19647c478bd9Sstevel@tonic-gate 	if (params->errstring != NULL) {
19657c478bd9Sstevel@tonic-gate 		change_state_data.error_msg_ctl = RDR_GENERATE_ERR_MSGS;
19667c478bd9Sstevel@tonic-gate 	} else {
19677c478bd9Sstevel@tonic-gate 		change_state_data.error_msg_ctl = RDR_DONT_GENERATE_ERR_MSGS;
19687c478bd9Sstevel@tonic-gate 	}
19697c478bd9Sstevel@tonic-gate 	change_state_data.retries = params->retries;
19707c478bd9Sstevel@tonic-gate 
19717c478bd9Sstevel@tonic-gate 	/*
19727c478bd9Sstevel@tonic-gate 	 * Set variable information using memcpy
19737c478bd9Sstevel@tonic-gate 	 */
19747c478bd9Sstevel@tonic-gate 	bufptr = *buf;
19757c478bd9Sstevel@tonic-gate 
19767c478bd9Sstevel@tonic-gate 	(void) memcpy(bufptr, &change_state_data, sizeof (rdr_change_state_t));
19777c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_change_state_t);
19787c478bd9Sstevel@tonic-gate 
19797c478bd9Sstevel@tonic-gate 	if (var_msg_info.ap_id_sizes != NULL) {
19807c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, var_msg_info.ap_id_sizes,
19817c478bd9Sstevel@tonic-gate 		    var_msg_info.ap_id_int_size);
19827c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.ap_id_int_size;
19837c478bd9Sstevel@tonic-gate 	}
19847c478bd9Sstevel@tonic-gate 
19857c478bd9Sstevel@tonic-gate 	if (var_msg_info.ap_id_chars != NULL) {
19867c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, var_msg_info.ap_id_chars,
19877c478bd9Sstevel@tonic-gate 		    var_msg_info.ap_id_char_size);
19887c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.ap_id_char_size;
19897c478bd9Sstevel@tonic-gate 	}
19907c478bd9Sstevel@tonic-gate 
19917c478bd9Sstevel@tonic-gate 	if (params->options != NULL) {
19927c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, params->options,
19937c478bd9Sstevel@tonic-gate 		    var_msg_info.options_strlen);
19947c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.options_strlen;
19957c478bd9Sstevel@tonic-gate 		for (i = 0; i < var_msg_info.options_pad_sz; i++) {
19967c478bd9Sstevel@tonic-gate 			bufptr[i] = 0;
19977c478bd9Sstevel@tonic-gate 		}
19987c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.options_pad_sz;
19997c478bd9Sstevel@tonic-gate 	}
20007c478bd9Sstevel@tonic-gate 
20017c478bd9Sstevel@tonic-gate 	cleanup_variable_ap_id_info(&var_msg_info);
20027c478bd9Sstevel@tonic-gate 
20037c478bd9Sstevel@tonic-gate 	return (RDR_OK);
20047c478bd9Sstevel@tonic-gate }
20057c478bd9Sstevel@tonic-gate 
20067c478bd9Sstevel@tonic-gate 
20077c478bd9Sstevel@tonic-gate /*
20087c478bd9Sstevel@tonic-gate  * unpack_change_state_request:
20097c478bd9Sstevel@tonic-gate  *
20107c478bd9Sstevel@tonic-gate  * Handle unpacking a change state request message.
20117c478bd9Sstevel@tonic-gate  */
20127c478bd9Sstevel@tonic-gate static int
unpack_change_state_request(change_state_params_t * params,const char * buf)20137c478bd9Sstevel@tonic-gate unpack_change_state_request(change_state_params_t *params, const char *buf)
20147c478bd9Sstevel@tonic-gate {
20157c478bd9Sstevel@tonic-gate 	char				*bufptr;
20167c478bd9Sstevel@tonic-gate 	rdr_variable_message_info_t 	var_msg_info;
20177c478bd9Sstevel@tonic-gate 	rdr_change_state_t		change_state_data;
20187c478bd9Sstevel@tonic-gate 
20197c478bd9Sstevel@tonic-gate 
20207c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
20217c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
20227c478bd9Sstevel@tonic-gate 	}
20237c478bd9Sstevel@tonic-gate 
20247c478bd9Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
20257c478bd9Sstevel@tonic-gate 
20267c478bd9Sstevel@tonic-gate 	bufptr = (char *)buf;
20277c478bd9Sstevel@tonic-gate 	(void) memcpy(&change_state_data, bufptr, sizeof (rdr_change_state_t));
20287c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_change_state_t);
20297c478bd9Sstevel@tonic-gate 
20307c478bd9Sstevel@tonic-gate 	/*
20317c478bd9Sstevel@tonic-gate 	 * handle getting the ap_ids
20327c478bd9Sstevel@tonic-gate 	 */
20337c478bd9Sstevel@tonic-gate 	var_msg_info.ap_id_char_size = change_state_data.ap_id_char_size;
20347c478bd9Sstevel@tonic-gate 	if (get_ap_ids_from_buf((char ***)&(params->ap_ids),
20357c478bd9Sstevel@tonic-gate 	    change_state_data.num_ap_ids, &var_msg_info, bufptr)) {
20367c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
20377c478bd9Sstevel@tonic-gate 	}
20387c478bd9Sstevel@tonic-gate 	bufptr += var_msg_info.ap_id_int_size;
20397c478bd9Sstevel@tonic-gate 	bufptr += var_msg_info.ap_id_char_size;
20407c478bd9Sstevel@tonic-gate 
20417c478bd9Sstevel@tonic-gate 	/*
20427c478bd9Sstevel@tonic-gate 	 * handle getting the options
20437c478bd9Sstevel@tonic-gate 	 */
20447c478bd9Sstevel@tonic-gate 	if (get_string_from_buf(&(params->options),
20457c478bd9Sstevel@tonic-gate 	    change_state_data.options_size, bufptr)) {
20467c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
20477c478bd9Sstevel@tonic-gate 	}
20487c478bd9Sstevel@tonic-gate 	bufptr += change_state_data.options_size;
20497c478bd9Sstevel@tonic-gate 
20507c478bd9Sstevel@tonic-gate 	/*
20517c478bd9Sstevel@tonic-gate 	 * Set fixed address labels by name
20527c478bd9Sstevel@tonic-gate 	 */
20537c478bd9Sstevel@tonic-gate 	params->state_change = (cfga_cmd_t)change_state_data.state_change_cmd;
20547c478bd9Sstevel@tonic-gate 	params->num_ap_ids = change_state_data.num_ap_ids;
20557c478bd9Sstevel@tonic-gate 
20567c478bd9Sstevel@tonic-gate 	params->confp = (struct cfga_confirm *)
20577c478bd9Sstevel@tonic-gate 	    malloc(sizeof (struct cfga_confirm));
20587c478bd9Sstevel@tonic-gate 	if (params->confp == NULL) {
20597c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
20607c478bd9Sstevel@tonic-gate 	}
20617c478bd9Sstevel@tonic-gate 
20627c478bd9Sstevel@tonic-gate 	/* set params->confp->confirm using memcpy */
20637c478bd9Sstevel@tonic-gate 	(void) memcpy((void*)params->confp,
20647c478bd9Sstevel@tonic-gate 	    &(change_state_data.confirm_callback_id), sizeof (unsigned long));
20657c478bd9Sstevel@tonic-gate 	params->confp->appdata_ptr =
20667c478bd9Sstevel@tonic-gate 	    (void*)change_state_data.confirm_appdata_ptr;
20677c478bd9Sstevel@tonic-gate 
20687c478bd9Sstevel@tonic-gate 	params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg));
20697c478bd9Sstevel@tonic-gate 	if (params->msgp == NULL) {
20707c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
20717c478bd9Sstevel@tonic-gate 	}
20727c478bd9Sstevel@tonic-gate 
20737c478bd9Sstevel@tonic-gate 	/* set params->msgp->message_routine using memcpy */
20747c478bd9Sstevel@tonic-gate 	(void) memcpy((void*)params->msgp,
20757c478bd9Sstevel@tonic-gate 	    &(change_state_data.msg_callback_id), sizeof (unsigned long));
20767c478bd9Sstevel@tonic-gate 	params->msgp->appdata_ptr =
20777c478bd9Sstevel@tonic-gate 	    (void*)change_state_data.msg_appdata_ptr;
20787c478bd9Sstevel@tonic-gate 
20797c478bd9Sstevel@tonic-gate 	if (change_state_data.error_msg_ctl == RDR_GENERATE_ERR_MSGS) {
20807c478bd9Sstevel@tonic-gate 		params->errstring = (char **)malloc(sizeof (char *));
20817c478bd9Sstevel@tonic-gate 		if (params->errstring == NULL) {
20827c478bd9Sstevel@tonic-gate 			return (RDR_MEM_ALLOC);
20837c478bd9Sstevel@tonic-gate 		}
20847c478bd9Sstevel@tonic-gate 		*(params->errstring) = NULL;
20857c478bd9Sstevel@tonic-gate 	} else {	/* error_msg_ctl == RDR_DONT_GENERATE_ERR_MSGS */
20867c478bd9Sstevel@tonic-gate 		params->errstring = NULL;
20877c478bd9Sstevel@tonic-gate 	}
20887c478bd9Sstevel@tonic-gate 	params->flags = change_state_data.flags;
20897c478bd9Sstevel@tonic-gate 	params->timeval = change_state_data.timeval;
20907c478bd9Sstevel@tonic-gate 	params->retries = change_state_data.retries;
20917c478bd9Sstevel@tonic-gate 
20927c478bd9Sstevel@tonic-gate 	return (RDR_OK);
20937c478bd9Sstevel@tonic-gate }
20947c478bd9Sstevel@tonic-gate 
20957c478bd9Sstevel@tonic-gate 
20967c478bd9Sstevel@tonic-gate /*
20977c478bd9Sstevel@tonic-gate  * pack_change_state_reply:
20987c478bd9Sstevel@tonic-gate  *
20997c478bd9Sstevel@tonic-gate  * Handle packing a change state reply message.
21007c478bd9Sstevel@tonic-gate  */
21017c478bd9Sstevel@tonic-gate static int
pack_change_state_reply(change_state_params_t * params,char ** buf,int * buf_size)21027c478bd9Sstevel@tonic-gate pack_change_state_reply(change_state_params_t *params, char **buf,
21037c478bd9Sstevel@tonic-gate     int *buf_size)
21047c478bd9Sstevel@tonic-gate {
21057c478bd9Sstevel@tonic-gate 	int				i;
21067c478bd9Sstevel@tonic-gate 	char				*bufptr;
21077c478bd9Sstevel@tonic-gate 	rdr_change_state_reply_t	change_state_data;
21087c478bd9Sstevel@tonic-gate 	rdr_variable_message_info_t 	var_msg_info;
21097c478bd9Sstevel@tonic-gate 
21107c478bd9Sstevel@tonic-gate 
21117c478bd9Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
21127c478bd9Sstevel@tonic-gate 
21137c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
21147c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
21157c478bd9Sstevel@tonic-gate 	}
21167c478bd9Sstevel@tonic-gate 
21177c478bd9Sstevel@tonic-gate 	/*
21187c478bd9Sstevel@tonic-gate 	 * Set variable length fields (size info)
21197c478bd9Sstevel@tonic-gate 	 */
21207c478bd9Sstevel@tonic-gate 	if (find_errstring_sizes(params->errstring, &var_msg_info)) {
21217c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
21227c478bd9Sstevel@tonic-gate 	}
21237c478bd9Sstevel@tonic-gate 
21247c478bd9Sstevel@tonic-gate 	/*
21257c478bd9Sstevel@tonic-gate 	 * Collect size info specific to the change_state reply
21267c478bd9Sstevel@tonic-gate 	 * message and allocate a buffer
21277c478bd9Sstevel@tonic-gate 	 */
21287c478bd9Sstevel@tonic-gate 	*buf_size = sizeof (rdr_change_state_reply_t);
21297c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.errstring_strlen;
21307c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.errstring_pad_sz;
21317c478bd9Sstevel@tonic-gate 
21327c478bd9Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
21337c478bd9Sstevel@tonic-gate 	if (*buf == NULL) {
21347c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
21357c478bd9Sstevel@tonic-gate 	}
21367c478bd9Sstevel@tonic-gate 
21377c478bd9Sstevel@tonic-gate 	/*
21387c478bd9Sstevel@tonic-gate 	 * Set fixed address labels by name
21397c478bd9Sstevel@tonic-gate 	 */
21407c478bd9Sstevel@tonic-gate 	change_state_data.errstring_size = var_msg_info.errstring_strlen +
21417c478bd9Sstevel@tonic-gate 	    var_msg_info.errstring_pad_sz;
21427c478bd9Sstevel@tonic-gate 
21437c478bd9Sstevel@tonic-gate 	/*
21447c478bd9Sstevel@tonic-gate 	 * Set variable information using memcpy
21457c478bd9Sstevel@tonic-gate 	 */
21467c478bd9Sstevel@tonic-gate 	bufptr = *buf;
21477c478bd9Sstevel@tonic-gate 
21487c478bd9Sstevel@tonic-gate 	(void) memcpy(bufptr, &change_state_data,
21497c478bd9Sstevel@tonic-gate 	    sizeof (rdr_change_state_reply_t));
21507c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_change_state_reply_t);
21517c478bd9Sstevel@tonic-gate 
21527c478bd9Sstevel@tonic-gate 	if ((params->errstring != NULL) && (*(params->errstring) != NULL)) {
21537c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, *(params->errstring),
21547c478bd9Sstevel@tonic-gate 		    var_msg_info.errstring_strlen);
21557c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.errstring_strlen;
21567c478bd9Sstevel@tonic-gate 		for (i = 0; i < var_msg_info.errstring_pad_sz; i++) {
21577c478bd9Sstevel@tonic-gate 			bufptr[i] = 0;
21587c478bd9Sstevel@tonic-gate 		}
21597c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.errstring_pad_sz;
21607c478bd9Sstevel@tonic-gate 	}
21617c478bd9Sstevel@tonic-gate 
21627c478bd9Sstevel@tonic-gate 	return (RDR_OK);
21637c478bd9Sstevel@tonic-gate }
21647c478bd9Sstevel@tonic-gate 
21657c478bd9Sstevel@tonic-gate 
21667c478bd9Sstevel@tonic-gate /*
21677c478bd9Sstevel@tonic-gate  * unpack_change_state_reply:
21687c478bd9Sstevel@tonic-gate  *
21697c478bd9Sstevel@tonic-gate  * Handle unpacking a change state reply message.
21707c478bd9Sstevel@tonic-gate  */
21717c478bd9Sstevel@tonic-gate static int
unpack_change_state_reply(change_state_params_t * params,const char * buf)21727c478bd9Sstevel@tonic-gate unpack_change_state_reply(change_state_params_t *params, const char *buf)
21737c478bd9Sstevel@tonic-gate {
21747c478bd9Sstevel@tonic-gate 	char				*bufptr;
21757c478bd9Sstevel@tonic-gate 	rdr_change_state_reply_t	change_state_data;
21767c478bd9Sstevel@tonic-gate 
21777c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
21787c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
21797c478bd9Sstevel@tonic-gate 	}
21807c478bd9Sstevel@tonic-gate 
21817c478bd9Sstevel@tonic-gate 	bufptr = (char *)buf;
21827c478bd9Sstevel@tonic-gate 	(void) memcpy(&change_state_data, bufptr,
21837c478bd9Sstevel@tonic-gate 	    sizeof (rdr_change_state_reply_t));
21847c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_change_state_reply_t);
21857c478bd9Sstevel@tonic-gate 
21867c478bd9Sstevel@tonic-gate 	/*
21877c478bd9Sstevel@tonic-gate 	 * handle getting the errstring
21887c478bd9Sstevel@tonic-gate 	 */
21897c478bd9Sstevel@tonic-gate 	params->errstring = (char **)malloc(sizeof (char *));
21907c478bd9Sstevel@tonic-gate 	if (params->errstring == NULL) {
21917c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
21927c478bd9Sstevel@tonic-gate 	}
21937c478bd9Sstevel@tonic-gate 	if (get_string_from_buf(params->errstring,
21947c478bd9Sstevel@tonic-gate 	    change_state_data.errstring_size, bufptr)) {
21957c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
21967c478bd9Sstevel@tonic-gate 	}
21977c478bd9Sstevel@tonic-gate 	bufptr += change_state_data.errstring_size;
21987c478bd9Sstevel@tonic-gate 
21997c478bd9Sstevel@tonic-gate 	return (RDR_OK);
22007c478bd9Sstevel@tonic-gate }
22017c478bd9Sstevel@tonic-gate 
22027c478bd9Sstevel@tonic-gate 
22037c478bd9Sstevel@tonic-gate /*
22047c478bd9Sstevel@tonic-gate  * pack_private_func_request:
22057c478bd9Sstevel@tonic-gate  *
22067c478bd9Sstevel@tonic-gate  * Handle packing a private function request message.
22077c478bd9Sstevel@tonic-gate  */
22087c478bd9Sstevel@tonic-gate static int
pack_private_func_request(private_func_params_t * params,char ** buf,int * buf_size)22097c478bd9Sstevel@tonic-gate pack_private_func_request(private_func_params_t *params, char **buf,
22107c478bd9Sstevel@tonic-gate     int *buf_size)
22117c478bd9Sstevel@tonic-gate {
22127c478bd9Sstevel@tonic-gate 	int				i;
22137c478bd9Sstevel@tonic-gate 	char				*bufptr;
22147c478bd9Sstevel@tonic-gate 	rdr_private_func_t		private_func_data;
22157c478bd9Sstevel@tonic-gate 	rdr_variable_message_info_t	var_msg_info;
22167c478bd9Sstevel@tonic-gate 
22177c478bd9Sstevel@tonic-gate 
22187c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
22197c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
22207c478bd9Sstevel@tonic-gate 	}
22217c478bd9Sstevel@tonic-gate 
22227c478bd9Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
22237c478bd9Sstevel@tonic-gate 
22247c478bd9Sstevel@tonic-gate 	/*
22257c478bd9Sstevel@tonic-gate 	 * Set variable length fields and make a call to partially
22267c478bd9Sstevel@tonic-gate 	 * pack it.
22277c478bd9Sstevel@tonic-gate 	 */
22287c478bd9Sstevel@tonic-gate 	if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) {
22297c478bd9Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
22307c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
22317c478bd9Sstevel@tonic-gate 	}
22327c478bd9Sstevel@tonic-gate 	if (find_options_sizes(params->options, &var_msg_info)) {
22337c478bd9Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
22347c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
22357c478bd9Sstevel@tonic-gate 	}
22367c478bd9Sstevel@tonic-gate 	if (find_function_sizes(params->function, &var_msg_info)) {
22377c478bd9Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
22387c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
22397c478bd9Sstevel@tonic-gate 	}
22407c478bd9Sstevel@tonic-gate 
22417c478bd9Sstevel@tonic-gate 	/*
22427c478bd9Sstevel@tonic-gate 	 * Collect size info specific to the private_func request
22437c478bd9Sstevel@tonic-gate 	 * message and allocate a buffer
22447c478bd9Sstevel@tonic-gate 	 */
22457c478bd9Sstevel@tonic-gate 	*buf_size = sizeof (rdr_private_func_t);
22467c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.ap_id_int_size;
22477c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.ap_id_char_size;
22487c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.options_strlen;
22497c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.options_pad_sz;
22507c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.function_strlen;
22517c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.function_pad_sz;
22527c478bd9Sstevel@tonic-gate 
22537c478bd9Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
22547c478bd9Sstevel@tonic-gate 	if (*buf == NULL) {
22557c478bd9Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
22567c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
22577c478bd9Sstevel@tonic-gate 	}
22587c478bd9Sstevel@tonic-gate 
22597c478bd9Sstevel@tonic-gate 	/*
22607c478bd9Sstevel@tonic-gate 	 * Set fixed address labels by name
22617c478bd9Sstevel@tonic-gate 	 */
22627c478bd9Sstevel@tonic-gate 	private_func_data.num_ap_ids = params->num_ap_ids;
22637c478bd9Sstevel@tonic-gate 	private_func_data.ap_id_char_size = var_msg_info.ap_id_char_size;
22647c478bd9Sstevel@tonic-gate 	private_func_data.options_size = var_msg_info.options_strlen +
22657c478bd9Sstevel@tonic-gate 	    var_msg_info.options_pad_sz;
22667c478bd9Sstevel@tonic-gate 	private_func_data.function_size = var_msg_info.function_strlen +
22677c478bd9Sstevel@tonic-gate 	    var_msg_info.function_pad_sz;
22687c478bd9Sstevel@tonic-gate 
22697c478bd9Sstevel@tonic-gate 	if (params->confp != NULL) {
22707c478bd9Sstevel@tonic-gate 		private_func_data.confirm_callback_id =
22717c478bd9Sstevel@tonic-gate 		    (unsigned long)params->confp->confirm;
22727c478bd9Sstevel@tonic-gate 		private_func_data.confirm_appdata_ptr =
22737c478bd9Sstevel@tonic-gate 		    (unsigned long)params->confp->appdata_ptr;
22747c478bd9Sstevel@tonic-gate 	} else {
22757c478bd9Sstevel@tonic-gate 		private_func_data.confirm_callback_id = 0;
22767c478bd9Sstevel@tonic-gate 		private_func_data.confirm_appdata_ptr = 0;
22777c478bd9Sstevel@tonic-gate 	}
22787c478bd9Sstevel@tonic-gate 	if (params->msgp != NULL) {
22797c478bd9Sstevel@tonic-gate 		private_func_data.msg_callback_id =
22807c478bd9Sstevel@tonic-gate 		    (unsigned long)params->msgp->message_routine;
22817c478bd9Sstevel@tonic-gate 		private_func_data.msg_appdata_ptr =
22827c478bd9Sstevel@tonic-gate 		    (unsigned long)params->msgp->appdata_ptr;
22837c478bd9Sstevel@tonic-gate 	} else {
22847c478bd9Sstevel@tonic-gate 		private_func_data.msg_callback_id = 0;
22857c478bd9Sstevel@tonic-gate 		private_func_data.msg_appdata_ptr = 0;
22867c478bd9Sstevel@tonic-gate 	}
22877c478bd9Sstevel@tonic-gate 
22887c478bd9Sstevel@tonic-gate 	private_func_data.flags = params->flags;
22897c478bd9Sstevel@tonic-gate 
22907c478bd9Sstevel@tonic-gate 	if (params->errstring != NULL) {
22917c478bd9Sstevel@tonic-gate 		private_func_data.error_msg_ctl = RDR_GENERATE_ERR_MSGS;
22927c478bd9Sstevel@tonic-gate 	} else {
22937c478bd9Sstevel@tonic-gate 		private_func_data.error_msg_ctl = RDR_DONT_GENERATE_ERR_MSGS;
22947c478bd9Sstevel@tonic-gate 	}
22957c478bd9Sstevel@tonic-gate 
22967c478bd9Sstevel@tonic-gate 	/*
22977c478bd9Sstevel@tonic-gate 	 * Set variable information using memcpy
22987c478bd9Sstevel@tonic-gate 	 */
22997c478bd9Sstevel@tonic-gate 	bufptr = *buf;
23007c478bd9Sstevel@tonic-gate 
23017c478bd9Sstevel@tonic-gate 	(void) memcpy(bufptr, &private_func_data, sizeof (rdr_private_func_t));
23027c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_private_func_t);
23037c478bd9Sstevel@tonic-gate 
23047c478bd9Sstevel@tonic-gate 	if (var_msg_info.ap_id_sizes != NULL) {
23057c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, var_msg_info.ap_id_sizes,
23067c478bd9Sstevel@tonic-gate 		    var_msg_info.ap_id_int_size);
23077c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.ap_id_int_size;
23087c478bd9Sstevel@tonic-gate 	}
23097c478bd9Sstevel@tonic-gate 
23107c478bd9Sstevel@tonic-gate 	if (var_msg_info.ap_id_chars != NULL) {
23117c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, var_msg_info.ap_id_chars,
23127c478bd9Sstevel@tonic-gate 		    var_msg_info.ap_id_char_size);
23137c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.ap_id_char_size;
23147c478bd9Sstevel@tonic-gate 	}
23157c478bd9Sstevel@tonic-gate 
23167c478bd9Sstevel@tonic-gate 	if (params->options != NULL) {
23177c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, params->options,
23187c478bd9Sstevel@tonic-gate 		    var_msg_info.options_strlen);
23197c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.options_strlen;
23207c478bd9Sstevel@tonic-gate 		for (i = 0; i < var_msg_info.options_pad_sz; i++) {
23217c478bd9Sstevel@tonic-gate 			bufptr[i] = 0;
23227c478bd9Sstevel@tonic-gate 		}
23237c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.options_pad_sz;
23247c478bd9Sstevel@tonic-gate 	}
23257c478bd9Sstevel@tonic-gate 
23267c478bd9Sstevel@tonic-gate 	if (params->function != NULL) {
23277c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, params->function,
23287c478bd9Sstevel@tonic-gate 		    var_msg_info.function_strlen);
23297c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.function_strlen;
23307c478bd9Sstevel@tonic-gate 		for (i = 0; i < var_msg_info.function_pad_sz; i++) {
23317c478bd9Sstevel@tonic-gate 			bufptr[i] = 0;
23327c478bd9Sstevel@tonic-gate 		}
23337c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.function_pad_sz;
23347c478bd9Sstevel@tonic-gate 	}
23357c478bd9Sstevel@tonic-gate 
23367c478bd9Sstevel@tonic-gate 	cleanup_variable_ap_id_info(&var_msg_info);
23377c478bd9Sstevel@tonic-gate 
23387c478bd9Sstevel@tonic-gate 	return (RDR_OK);
23397c478bd9Sstevel@tonic-gate }
23407c478bd9Sstevel@tonic-gate 
23417c478bd9Sstevel@tonic-gate 
23427c478bd9Sstevel@tonic-gate /*
23437c478bd9Sstevel@tonic-gate  * unpack_private_func_request:
23447c478bd9Sstevel@tonic-gate  *
23457c478bd9Sstevel@tonic-gate  * Handle unpacking a private function request message.
23467c478bd9Sstevel@tonic-gate  */
23477c478bd9Sstevel@tonic-gate static int
unpack_private_func_request(private_func_params_t * params,const char * buf)23487c478bd9Sstevel@tonic-gate unpack_private_func_request(private_func_params_t *params, const char *buf)
23497c478bd9Sstevel@tonic-gate {
23507c478bd9Sstevel@tonic-gate 	char				*bufptr;
23517c478bd9Sstevel@tonic-gate 	rdr_variable_message_info_t 	var_msg_info;
23527c478bd9Sstevel@tonic-gate 	rdr_private_func_t		private_func_data;
23537c478bd9Sstevel@tonic-gate 
23547c478bd9Sstevel@tonic-gate 
23557c478bd9Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
23567c478bd9Sstevel@tonic-gate 
23577c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
23587c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
23597c478bd9Sstevel@tonic-gate 	}
23607c478bd9Sstevel@tonic-gate 
23617c478bd9Sstevel@tonic-gate 	bufptr = (char *)buf;
23627c478bd9Sstevel@tonic-gate 	(void) memcpy(&private_func_data, bufptr, sizeof (rdr_private_func_t));
23637c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_private_func_t);
23647c478bd9Sstevel@tonic-gate 
23657c478bd9Sstevel@tonic-gate 	/*
23667c478bd9Sstevel@tonic-gate 	 * handle getting the ap_ids
23677c478bd9Sstevel@tonic-gate 	 */
23687c478bd9Sstevel@tonic-gate 	var_msg_info.ap_id_char_size = private_func_data.ap_id_char_size;
23697c478bd9Sstevel@tonic-gate 	if (get_ap_ids_from_buf((char ***)&(params->ap_ids),
23707c478bd9Sstevel@tonic-gate 	    private_func_data.num_ap_ids, &var_msg_info, bufptr)) {
23717c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
23727c478bd9Sstevel@tonic-gate 	}
23737c478bd9Sstevel@tonic-gate 	bufptr += var_msg_info.ap_id_int_size;
23747c478bd9Sstevel@tonic-gate 	bufptr += var_msg_info.ap_id_char_size;
23757c478bd9Sstevel@tonic-gate 
23767c478bd9Sstevel@tonic-gate 	/*
23777c478bd9Sstevel@tonic-gate 	 * handle getting the options and function
23787c478bd9Sstevel@tonic-gate 	 */
23797c478bd9Sstevel@tonic-gate 	if (get_string_from_buf(&(params->options),
23807c478bd9Sstevel@tonic-gate 	    private_func_data.options_size, bufptr)) {
23817c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
23827c478bd9Sstevel@tonic-gate 	}
23837c478bd9Sstevel@tonic-gate 	bufptr += private_func_data.options_size;
23847c478bd9Sstevel@tonic-gate 
23857c478bd9Sstevel@tonic-gate 	if (get_string_from_buf(&(params->function),
23867c478bd9Sstevel@tonic-gate 	    private_func_data.function_size, bufptr)) {
23877c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
23887c478bd9Sstevel@tonic-gate 	}
23897c478bd9Sstevel@tonic-gate 	bufptr += private_func_data.function_size;
23907c478bd9Sstevel@tonic-gate 
23917c478bd9Sstevel@tonic-gate 	/*
23927c478bd9Sstevel@tonic-gate 	 * Set fixed address labels by name
23937c478bd9Sstevel@tonic-gate 	 */
23947c478bd9Sstevel@tonic-gate 	params->num_ap_ids = private_func_data.num_ap_ids;
23957c478bd9Sstevel@tonic-gate 
23967c478bd9Sstevel@tonic-gate 	params->confp = (struct cfga_confirm *)
23977c478bd9Sstevel@tonic-gate 	    malloc(sizeof (struct cfga_confirm));
23987c478bd9Sstevel@tonic-gate 	if (params->confp == NULL) {
23997c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
24007c478bd9Sstevel@tonic-gate 	}
24017c478bd9Sstevel@tonic-gate 
24027c478bd9Sstevel@tonic-gate 	/* set params->confp->confirm using memcpy */
24037c478bd9Sstevel@tonic-gate 	(void) memcpy((void*)params->confp,
24047c478bd9Sstevel@tonic-gate 	    &(private_func_data.confirm_callback_id), sizeof (unsigned long));
24057c478bd9Sstevel@tonic-gate 	params->confp->appdata_ptr =
24067c478bd9Sstevel@tonic-gate 	    (void*)private_func_data.confirm_appdata_ptr;
24077c478bd9Sstevel@tonic-gate 
24087c478bd9Sstevel@tonic-gate 	params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg));
24097c478bd9Sstevel@tonic-gate 	if (params->msgp == NULL) {
24107c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
24117c478bd9Sstevel@tonic-gate 	}
24127c478bd9Sstevel@tonic-gate 
24137c478bd9Sstevel@tonic-gate 	/* set params->msgp->message_routine using memcpy */
24147c478bd9Sstevel@tonic-gate 	(void) memcpy((void*)params->msgp,
24157c478bd9Sstevel@tonic-gate 	    &(private_func_data.msg_callback_id), sizeof (unsigned long));
24167c478bd9Sstevel@tonic-gate 	params->msgp->appdata_ptr =
24177c478bd9Sstevel@tonic-gate 	    (void*)private_func_data.msg_appdata_ptr;
24187c478bd9Sstevel@tonic-gate 
24197c478bd9Sstevel@tonic-gate 	if (private_func_data.error_msg_ctl == RDR_GENERATE_ERR_MSGS) {
24207c478bd9Sstevel@tonic-gate 		params->errstring = (char **)malloc(sizeof (char *));
24217c478bd9Sstevel@tonic-gate 		if (params->errstring == NULL) {
24227c478bd9Sstevel@tonic-gate 			return (RDR_MEM_ALLOC);
24237c478bd9Sstevel@tonic-gate 		}
24247c478bd9Sstevel@tonic-gate 		*(params->errstring) = NULL;
24257c478bd9Sstevel@tonic-gate 	} else {	/* error_msg_ctl == RDR_DONT_GENERATE_ERR_MSGS */
24267c478bd9Sstevel@tonic-gate 		params->errstring = NULL;
24277c478bd9Sstevel@tonic-gate 	}
24287c478bd9Sstevel@tonic-gate 	params->flags = private_func_data.flags;
24297c478bd9Sstevel@tonic-gate 
24307c478bd9Sstevel@tonic-gate 	return (RDR_OK);
24317c478bd9Sstevel@tonic-gate }
24327c478bd9Sstevel@tonic-gate 
24337c478bd9Sstevel@tonic-gate 
24347c478bd9Sstevel@tonic-gate /*
24357c478bd9Sstevel@tonic-gate  * pack_private_func_reply:
24367c478bd9Sstevel@tonic-gate  *
24377c478bd9Sstevel@tonic-gate  * Handle packing a private function reply message.
24387c478bd9Sstevel@tonic-gate  */
24397c478bd9Sstevel@tonic-gate static int
pack_private_func_reply(private_func_params_t * params,char ** buf,int * buf_size)24407c478bd9Sstevel@tonic-gate pack_private_func_reply(private_func_params_t *params, char **buf,
24417c478bd9Sstevel@tonic-gate     int *buf_size)
24427c478bd9Sstevel@tonic-gate {
24437c478bd9Sstevel@tonic-gate 	int				i;
24447c478bd9Sstevel@tonic-gate 	char				*bufptr;
24457c478bd9Sstevel@tonic-gate 	rdr_private_func_reply_t	private_func_data;
24467c478bd9Sstevel@tonic-gate 	rdr_variable_message_info_t 	var_msg_info;
24477c478bd9Sstevel@tonic-gate 
24487c478bd9Sstevel@tonic-gate 
24497c478bd9Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
24507c478bd9Sstevel@tonic-gate 
24517c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
24527c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
24537c478bd9Sstevel@tonic-gate 	}
24547c478bd9Sstevel@tonic-gate 
24557c478bd9Sstevel@tonic-gate 	/*
24567c478bd9Sstevel@tonic-gate 	 * Set variable length fields (size info)
24577c478bd9Sstevel@tonic-gate 	 */
24587c478bd9Sstevel@tonic-gate 	if (find_errstring_sizes(params->errstring, &var_msg_info)) {
24597c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
24607c478bd9Sstevel@tonic-gate 	}
24617c478bd9Sstevel@tonic-gate 
24627c478bd9Sstevel@tonic-gate 	/*
24637c478bd9Sstevel@tonic-gate 	 * Collect size info specific to the private_func reply
24647c478bd9Sstevel@tonic-gate 	 * message and allocate a buffer
24657c478bd9Sstevel@tonic-gate 	 */
24667c478bd9Sstevel@tonic-gate 	*buf_size = sizeof (rdr_private_func_reply_t);
24677c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.errstring_strlen;
24687c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.errstring_pad_sz;
24697c478bd9Sstevel@tonic-gate 
24707c478bd9Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
24717c478bd9Sstevel@tonic-gate 	if (*buf == NULL) {
24727c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
24737c478bd9Sstevel@tonic-gate 	}
24747c478bd9Sstevel@tonic-gate 
24757c478bd9Sstevel@tonic-gate 	/*
24767c478bd9Sstevel@tonic-gate 	 * Set fixed address labels by name
24777c478bd9Sstevel@tonic-gate 	 */
24787c478bd9Sstevel@tonic-gate 	private_func_data.errstring_size = var_msg_info.errstring_strlen +
24797c478bd9Sstevel@tonic-gate 	    var_msg_info.errstring_pad_sz;
24807c478bd9Sstevel@tonic-gate 
24817c478bd9Sstevel@tonic-gate 	/*
24827c478bd9Sstevel@tonic-gate 	 * Set variable information using memcpy
24837c478bd9Sstevel@tonic-gate 	 */
24847c478bd9Sstevel@tonic-gate 	bufptr = *buf;
24857c478bd9Sstevel@tonic-gate 
24867c478bd9Sstevel@tonic-gate 	(void) memcpy(bufptr, &private_func_data,
24877c478bd9Sstevel@tonic-gate 	    sizeof (rdr_private_func_reply_t));
24887c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_private_func_reply_t);
24897c478bd9Sstevel@tonic-gate 	if ((params->errstring != NULL) && (*(params->errstring) != NULL)) {
24907c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, *(params->errstring),
24917c478bd9Sstevel@tonic-gate 		    var_msg_info.errstring_strlen);
24927c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.errstring_strlen;
24937c478bd9Sstevel@tonic-gate 		for (i = 0; i < var_msg_info.errstring_pad_sz; i++) {
24947c478bd9Sstevel@tonic-gate 			bufptr[i] = 0;
24957c478bd9Sstevel@tonic-gate 		}
24967c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.errstring_pad_sz;
24977c478bd9Sstevel@tonic-gate 	}
24987c478bd9Sstevel@tonic-gate 
24997c478bd9Sstevel@tonic-gate 	return (RDR_OK);
25007c478bd9Sstevel@tonic-gate }
25017c478bd9Sstevel@tonic-gate 
25027c478bd9Sstevel@tonic-gate 
25037c478bd9Sstevel@tonic-gate /*
25047c478bd9Sstevel@tonic-gate  * unpack_private_func_reply:
25057c478bd9Sstevel@tonic-gate  *
25067c478bd9Sstevel@tonic-gate  * Handle unpacking a private function reply message.
25077c478bd9Sstevel@tonic-gate  */
25087c478bd9Sstevel@tonic-gate static int
unpack_private_func_reply(private_func_params_t * params,const char * buf)25097c478bd9Sstevel@tonic-gate unpack_private_func_reply(private_func_params_t *params, const char *buf)
25107c478bd9Sstevel@tonic-gate {
25117c478bd9Sstevel@tonic-gate 	char				*bufptr;
25127c478bd9Sstevel@tonic-gate 	rdr_private_func_reply_t	private_func_data;
25137c478bd9Sstevel@tonic-gate 
25147c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
25157c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
25167c478bd9Sstevel@tonic-gate 	}
25177c478bd9Sstevel@tonic-gate 
25187c478bd9Sstevel@tonic-gate 	bufptr = (char *)buf;
25197c478bd9Sstevel@tonic-gate 	(void) memcpy(&private_func_data, bufptr,
25207c478bd9Sstevel@tonic-gate 	    sizeof (rdr_private_func_reply_t));
25217c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_private_func_reply_t);
25227c478bd9Sstevel@tonic-gate 
25237c478bd9Sstevel@tonic-gate 	/*
25247c478bd9Sstevel@tonic-gate 	 * handle getting the errstring
25257c478bd9Sstevel@tonic-gate 	 */
25267c478bd9Sstevel@tonic-gate 	params->errstring = (char **)malloc(sizeof (char *));
25277c478bd9Sstevel@tonic-gate 	if (params->errstring == NULL) {
25287c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
25297c478bd9Sstevel@tonic-gate 	}
25307c478bd9Sstevel@tonic-gate 	if (get_string_from_buf(params->errstring,
25317c478bd9Sstevel@tonic-gate 	    private_func_data.errstring_size, bufptr)) {
25327c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
25337c478bd9Sstevel@tonic-gate 	}
25347c478bd9Sstevel@tonic-gate 	bufptr += private_func_data.errstring_size;
25357c478bd9Sstevel@tonic-gate 
25367c478bd9Sstevel@tonic-gate 	return (RDR_OK);
25377c478bd9Sstevel@tonic-gate }
25387c478bd9Sstevel@tonic-gate 
25397c478bd9Sstevel@tonic-gate 
25407c478bd9Sstevel@tonic-gate /*
25417c478bd9Sstevel@tonic-gate  * pack_test_request:
25427c478bd9Sstevel@tonic-gate  *
25437c478bd9Sstevel@tonic-gate  * Handle packing a test request message.
25447c478bd9Sstevel@tonic-gate  */
25457c478bd9Sstevel@tonic-gate static int
pack_test_request(test_params_t * params,char ** buf,int * buf_size)25467c478bd9Sstevel@tonic-gate pack_test_request(test_params_t *params, char **buf, int *buf_size)
25477c478bd9Sstevel@tonic-gate {
25487c478bd9Sstevel@tonic-gate 	int				i;
25497c478bd9Sstevel@tonic-gate 	char				*bufptr;
25507c478bd9Sstevel@tonic-gate 	rdr_test_t			test_data;
25517c478bd9Sstevel@tonic-gate 	rdr_variable_message_info_t	var_msg_info;
25527c478bd9Sstevel@tonic-gate 
25537c478bd9Sstevel@tonic-gate 
25547c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
25557c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
25567c478bd9Sstevel@tonic-gate 	}
25577c478bd9Sstevel@tonic-gate 
25587c478bd9Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
25597c478bd9Sstevel@tonic-gate 
25607c478bd9Sstevel@tonic-gate 	/*
25617c478bd9Sstevel@tonic-gate 	 * Set variable length fields and make a call to partially
25627c478bd9Sstevel@tonic-gate 	 * pack it.
25637c478bd9Sstevel@tonic-gate 	 */
25647c478bd9Sstevel@tonic-gate 	if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) {
25657c478bd9Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
25667c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
25677c478bd9Sstevel@tonic-gate 	}
25687c478bd9Sstevel@tonic-gate 	if (find_options_sizes(params->options, &var_msg_info)) {
25697c478bd9Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
25707c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
25717c478bd9Sstevel@tonic-gate 	}
25727c478bd9Sstevel@tonic-gate 
25737c478bd9Sstevel@tonic-gate 	/*
25747c478bd9Sstevel@tonic-gate 	 * Collect size info specific to the test request
25757c478bd9Sstevel@tonic-gate 	 * message and allocate a buffer
25767c478bd9Sstevel@tonic-gate 	 */
25777c478bd9Sstevel@tonic-gate 	*buf_size = sizeof (rdr_test_t);
25787c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.ap_id_int_size;
25797c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.ap_id_char_size;
25807c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.options_strlen;
25817c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.options_pad_sz;
25827c478bd9Sstevel@tonic-gate 
25837c478bd9Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
25847c478bd9Sstevel@tonic-gate 	if (*buf == NULL) {
25857c478bd9Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
25867c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
25877c478bd9Sstevel@tonic-gate 	}
25887c478bd9Sstevel@tonic-gate 
25897c478bd9Sstevel@tonic-gate 	/*
25907c478bd9Sstevel@tonic-gate 	 * Set fixed address labels by name
25917c478bd9Sstevel@tonic-gate 	 */
25927c478bd9Sstevel@tonic-gate 	test_data.num_ap_ids = params->num_ap_ids;
25937c478bd9Sstevel@tonic-gate 	test_data.ap_id_char_size = var_msg_info.ap_id_char_size;
25947c478bd9Sstevel@tonic-gate 	test_data.options_size = var_msg_info.options_strlen +
25957c478bd9Sstevel@tonic-gate 	    var_msg_info.options_pad_sz;
25967c478bd9Sstevel@tonic-gate 
25977c478bd9Sstevel@tonic-gate 	if (params->msgp != NULL) {
25987c478bd9Sstevel@tonic-gate 		test_data.msg_callback_id =
25997c478bd9Sstevel@tonic-gate 		    (unsigned long)params->msgp->message_routine;
26007c478bd9Sstevel@tonic-gate 		test_data.msg_appdata_ptr =
26017c478bd9Sstevel@tonic-gate 		    (unsigned long)params->msgp->appdata_ptr;
26027c478bd9Sstevel@tonic-gate 	} else {
26037c478bd9Sstevel@tonic-gate 		test_data.msg_callback_id = 0;
26047c478bd9Sstevel@tonic-gate 		test_data.msg_appdata_ptr = 0;
26057c478bd9Sstevel@tonic-gate 	}
26067c478bd9Sstevel@tonic-gate 
26077c478bd9Sstevel@tonic-gate 	test_data.flags = params->flags;
26087c478bd9Sstevel@tonic-gate 
26097c478bd9Sstevel@tonic-gate 	if (params->errstring != NULL) {
26107c478bd9Sstevel@tonic-gate 		test_data.error_msg_ctl = RDR_GENERATE_ERR_MSGS;
26117c478bd9Sstevel@tonic-gate 	} else {
26127c478bd9Sstevel@tonic-gate 		test_data.error_msg_ctl = RDR_DONT_GENERATE_ERR_MSGS;
26137c478bd9Sstevel@tonic-gate 	}
26147c478bd9Sstevel@tonic-gate 
26157c478bd9Sstevel@tonic-gate 	/*
26167c478bd9Sstevel@tonic-gate 	 * Set variable information using memcpy
26177c478bd9Sstevel@tonic-gate 	 */
26187c478bd9Sstevel@tonic-gate 	bufptr = *buf;
26197c478bd9Sstevel@tonic-gate 
26207c478bd9Sstevel@tonic-gate 	(void) memcpy(bufptr, &test_data, sizeof (rdr_test_t));
26217c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_test_t);
26227c478bd9Sstevel@tonic-gate 
26237c478bd9Sstevel@tonic-gate 	if (var_msg_info.ap_id_sizes != NULL) {
26247c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, var_msg_info.ap_id_sizes,
26257c478bd9Sstevel@tonic-gate 		    var_msg_info.ap_id_int_size);
26267c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.ap_id_int_size;
26277c478bd9Sstevel@tonic-gate 	}
26287c478bd9Sstevel@tonic-gate 
26297c478bd9Sstevel@tonic-gate 	if (var_msg_info.ap_id_chars != NULL) {
26307c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, var_msg_info.ap_id_chars,
26317c478bd9Sstevel@tonic-gate 		    var_msg_info.ap_id_char_size);
26327c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.ap_id_char_size;
26337c478bd9Sstevel@tonic-gate 	}
26347c478bd9Sstevel@tonic-gate 
26357c478bd9Sstevel@tonic-gate 	if (params->options != NULL) {
26367c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, params->options,
26377c478bd9Sstevel@tonic-gate 		    var_msg_info.options_strlen);
26387c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.options_strlen;
26397c478bd9Sstevel@tonic-gate 		for (i = 0; i < var_msg_info.options_pad_sz; i++) {
26407c478bd9Sstevel@tonic-gate 			bufptr[i] = 0;
26417c478bd9Sstevel@tonic-gate 		}
26427c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.options_pad_sz;
26437c478bd9Sstevel@tonic-gate 	}
26447c478bd9Sstevel@tonic-gate 
26457c478bd9Sstevel@tonic-gate 	cleanup_variable_ap_id_info(&var_msg_info);
26467c478bd9Sstevel@tonic-gate 
26477c478bd9Sstevel@tonic-gate 	return (RDR_OK);
26487c478bd9Sstevel@tonic-gate }
26497c478bd9Sstevel@tonic-gate 
26507c478bd9Sstevel@tonic-gate 
26517c478bd9Sstevel@tonic-gate /*
26527c478bd9Sstevel@tonic-gate  * unpack_test_request:
26537c478bd9Sstevel@tonic-gate  *
26547c478bd9Sstevel@tonic-gate  * Handle unpacking a test request message.
26557c478bd9Sstevel@tonic-gate  */
26567c478bd9Sstevel@tonic-gate static int
unpack_test_request(test_params_t * params,const char * buf)26577c478bd9Sstevel@tonic-gate unpack_test_request(test_params_t *params, const char *buf)
26587c478bd9Sstevel@tonic-gate {
26597c478bd9Sstevel@tonic-gate 	char				*bufptr;
26607c478bd9Sstevel@tonic-gate 	rdr_variable_message_info_t 	var_msg_info;
26617c478bd9Sstevel@tonic-gate 	rdr_test_t			test_data;
26627c478bd9Sstevel@tonic-gate 
26637c478bd9Sstevel@tonic-gate 
26647c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
26657c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
26667c478bd9Sstevel@tonic-gate 	}
26677c478bd9Sstevel@tonic-gate 
26687c478bd9Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
26697c478bd9Sstevel@tonic-gate 
26707c478bd9Sstevel@tonic-gate 	bufptr = (char *)buf;
26717c478bd9Sstevel@tonic-gate 	(void) memcpy(&test_data, bufptr, sizeof (rdr_test_t));
26727c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_test_t);
26737c478bd9Sstevel@tonic-gate 
26747c478bd9Sstevel@tonic-gate 	/*
26757c478bd9Sstevel@tonic-gate 	 * handle getting the ap_ids
26767c478bd9Sstevel@tonic-gate 	 */
26777c478bd9Sstevel@tonic-gate 	var_msg_info.ap_id_char_size = test_data.ap_id_char_size;
26787c478bd9Sstevel@tonic-gate 	if (get_ap_ids_from_buf((char ***)&(params->ap_ids),
26797c478bd9Sstevel@tonic-gate 	    test_data.num_ap_ids, &var_msg_info, bufptr)) {
26807c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
26817c478bd9Sstevel@tonic-gate 	}
26827c478bd9Sstevel@tonic-gate 	bufptr += var_msg_info.ap_id_int_size;
26837c478bd9Sstevel@tonic-gate 	bufptr += var_msg_info.ap_id_char_size;
26847c478bd9Sstevel@tonic-gate 
26857c478bd9Sstevel@tonic-gate 	/*
26867c478bd9Sstevel@tonic-gate 	 * handle getting the options
26877c478bd9Sstevel@tonic-gate 	 */
26887c478bd9Sstevel@tonic-gate 	if (get_string_from_buf(&(params->options),
26897c478bd9Sstevel@tonic-gate 	    test_data.options_size, bufptr)) {
26907c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
26917c478bd9Sstevel@tonic-gate 	}
26927c478bd9Sstevel@tonic-gate 	bufptr += test_data.options_size;
26937c478bd9Sstevel@tonic-gate 
26947c478bd9Sstevel@tonic-gate 	/*
26957c478bd9Sstevel@tonic-gate 	 * Set fixed address labels by name
26967c478bd9Sstevel@tonic-gate 	 */
26977c478bd9Sstevel@tonic-gate 	params->num_ap_ids = test_data.num_ap_ids;
26987c478bd9Sstevel@tonic-gate 
26997c478bd9Sstevel@tonic-gate 	params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg));
27007c478bd9Sstevel@tonic-gate 	if (params->msgp == NULL) {
27017c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
27027c478bd9Sstevel@tonic-gate 	}
27037c478bd9Sstevel@tonic-gate 
27047c478bd9Sstevel@tonic-gate 	/* set params->msgp->message_routine using memcpy */
27057c478bd9Sstevel@tonic-gate 	(void) memcpy((void*)params->msgp,
27067c478bd9Sstevel@tonic-gate 	    &(test_data.msg_callback_id), sizeof (unsigned long));
27077c478bd9Sstevel@tonic-gate 	params->msgp->appdata_ptr =
27087c478bd9Sstevel@tonic-gate 	    (void*)test_data.msg_appdata_ptr;
27097c478bd9Sstevel@tonic-gate 
27107c478bd9Sstevel@tonic-gate 	if (test_data.error_msg_ctl == RDR_GENERATE_ERR_MSGS) {
27117c478bd9Sstevel@tonic-gate 		params->errstring = (char **)malloc(sizeof (char *));
27127c478bd9Sstevel@tonic-gate 		if (params->errstring == NULL) {
27137c478bd9Sstevel@tonic-gate 			return (RDR_MEM_ALLOC);
27147c478bd9Sstevel@tonic-gate 		}
27157c478bd9Sstevel@tonic-gate 		*(params->errstring) = NULL;
27167c478bd9Sstevel@tonic-gate 	} else {	/* error_msg_ctl == RDR_DONT_GENERATE_ERR_MSGS */
27177c478bd9Sstevel@tonic-gate 		params->errstring = NULL;
27187c478bd9Sstevel@tonic-gate 	}
27197c478bd9Sstevel@tonic-gate 	params->flags = test_data.flags;
27207c478bd9Sstevel@tonic-gate 
27217c478bd9Sstevel@tonic-gate 	return (RDR_OK);
27227c478bd9Sstevel@tonic-gate }
27237c478bd9Sstevel@tonic-gate 
27247c478bd9Sstevel@tonic-gate 
27257c478bd9Sstevel@tonic-gate /*
27267c478bd9Sstevel@tonic-gate  * pack_test_reply:
27277c478bd9Sstevel@tonic-gate  *
27287c478bd9Sstevel@tonic-gate  * Handle packing a test reply message.
27297c478bd9Sstevel@tonic-gate  */
27307c478bd9Sstevel@tonic-gate static int
pack_test_reply(test_params_t * params,char ** buf,int * buf_size)27317c478bd9Sstevel@tonic-gate pack_test_reply(test_params_t *params, char **buf, int *buf_size)
27327c478bd9Sstevel@tonic-gate {
27337c478bd9Sstevel@tonic-gate 	int				i;
27347c478bd9Sstevel@tonic-gate 	char				*bufptr;
27357c478bd9Sstevel@tonic-gate 	rdr_test_reply_t		test_data;
27367c478bd9Sstevel@tonic-gate 	rdr_variable_message_info_t 	var_msg_info;
27377c478bd9Sstevel@tonic-gate 
27387c478bd9Sstevel@tonic-gate 
27397c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
27407c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
27417c478bd9Sstevel@tonic-gate 	}
27427c478bd9Sstevel@tonic-gate 
27437c478bd9Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
27447c478bd9Sstevel@tonic-gate 
27457c478bd9Sstevel@tonic-gate 	/*
27467c478bd9Sstevel@tonic-gate 	 * Set variable length fields (size info)
27477c478bd9Sstevel@tonic-gate 	 */
27487c478bd9Sstevel@tonic-gate 	if (find_errstring_sizes(params->errstring, &var_msg_info)) {
27497c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
27507c478bd9Sstevel@tonic-gate 	}
27517c478bd9Sstevel@tonic-gate 
27527c478bd9Sstevel@tonic-gate 	/*
27537c478bd9Sstevel@tonic-gate 	 * Collect size info specific to the test reply
27547c478bd9Sstevel@tonic-gate 	 * message and allocate a buffer
27557c478bd9Sstevel@tonic-gate 	 */
27567c478bd9Sstevel@tonic-gate 	*buf_size = sizeof (rdr_test_reply_t);
27577c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.errstring_strlen;
27587c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.errstring_pad_sz;
27597c478bd9Sstevel@tonic-gate 
27607c478bd9Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
27617c478bd9Sstevel@tonic-gate 	if (*buf == NULL) {
27627c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
27637c478bd9Sstevel@tonic-gate 	}
27647c478bd9Sstevel@tonic-gate 
27657c478bd9Sstevel@tonic-gate 	/*
27667c478bd9Sstevel@tonic-gate 	 * Set fixed address labels by name
27677c478bd9Sstevel@tonic-gate 	 */
27687c478bd9Sstevel@tonic-gate 	test_data.errstring_size = var_msg_info.errstring_strlen +
27697c478bd9Sstevel@tonic-gate 	    var_msg_info.errstring_pad_sz;
27707c478bd9Sstevel@tonic-gate 
27717c478bd9Sstevel@tonic-gate 	/*
27727c478bd9Sstevel@tonic-gate 	 * Set variable information using memcpy
27737c478bd9Sstevel@tonic-gate 	 */
27747c478bd9Sstevel@tonic-gate 	bufptr = *buf;
27757c478bd9Sstevel@tonic-gate 
27767c478bd9Sstevel@tonic-gate 	(void) memcpy(bufptr, &test_data, sizeof (rdr_test_reply_t));
27777c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_test_reply_t);
27787c478bd9Sstevel@tonic-gate 	if ((params->errstring != NULL) && (*(params->errstring) != NULL)) {
27797c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, *(params->errstring),
27807c478bd9Sstevel@tonic-gate 		    var_msg_info.errstring_strlen);
27817c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.errstring_strlen;
27827c478bd9Sstevel@tonic-gate 		for (i = 0; i < var_msg_info.errstring_pad_sz; i++) {
27837c478bd9Sstevel@tonic-gate 			bufptr[i] = 0;
27847c478bd9Sstevel@tonic-gate 		}
27857c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.errstring_pad_sz;
27867c478bd9Sstevel@tonic-gate 	}
27877c478bd9Sstevel@tonic-gate 
27887c478bd9Sstevel@tonic-gate 	return (RDR_OK);
27897c478bd9Sstevel@tonic-gate }
27907c478bd9Sstevel@tonic-gate 
27917c478bd9Sstevel@tonic-gate 
27927c478bd9Sstevel@tonic-gate /*
27937c478bd9Sstevel@tonic-gate  * unpack_test_reply:
27947c478bd9Sstevel@tonic-gate  *
27957c478bd9Sstevel@tonic-gate  * Handle unpacking a test reply message.
27967c478bd9Sstevel@tonic-gate  */
27977c478bd9Sstevel@tonic-gate static int
unpack_test_reply(test_params_t * params,const char * buf)27987c478bd9Sstevel@tonic-gate unpack_test_reply(test_params_t *params, const char *buf)
27997c478bd9Sstevel@tonic-gate {
28007c478bd9Sstevel@tonic-gate 	char			*bufptr;
28017c478bd9Sstevel@tonic-gate 	rdr_test_reply_t	test_data;
28027c478bd9Sstevel@tonic-gate 
28037c478bd9Sstevel@tonic-gate 
28047c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
28057c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
28067c478bd9Sstevel@tonic-gate 	}
28077c478bd9Sstevel@tonic-gate 
28087c478bd9Sstevel@tonic-gate 	bufptr = (char *)buf;
28097c478bd9Sstevel@tonic-gate 	(void) memcpy(&test_data, bufptr, sizeof (rdr_test_reply_t));
28107c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_test_reply_t);
28117c478bd9Sstevel@tonic-gate 
28127c478bd9Sstevel@tonic-gate 	/*
28137c478bd9Sstevel@tonic-gate 	 * handle getting the errstring
28147c478bd9Sstevel@tonic-gate 	 */
28157c478bd9Sstevel@tonic-gate 	params->errstring = (char **)malloc(sizeof (char *));
28167c478bd9Sstevel@tonic-gate 	if (params->errstring == NULL) {
28177c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
28187c478bd9Sstevel@tonic-gate 	}
28197c478bd9Sstevel@tonic-gate 	if (get_string_from_buf(params->errstring,
28207c478bd9Sstevel@tonic-gate 	    test_data.errstring_size, bufptr)) {
28217c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
28227c478bd9Sstevel@tonic-gate 	}
28237c478bd9Sstevel@tonic-gate 	bufptr += test_data.errstring_size;
28247c478bd9Sstevel@tonic-gate 
28257c478bd9Sstevel@tonic-gate 	return (RDR_OK);
28267c478bd9Sstevel@tonic-gate }
28277c478bd9Sstevel@tonic-gate 
28287c478bd9Sstevel@tonic-gate 
28297c478bd9Sstevel@tonic-gate /*
28307c478bd9Sstevel@tonic-gate  * pack_list_ext_request:
28317c478bd9Sstevel@tonic-gate  *
28327c478bd9Sstevel@tonic-gate  * Handle packing a list request message.
28337c478bd9Sstevel@tonic-gate  */
28347c478bd9Sstevel@tonic-gate static int
pack_list_ext_request(list_ext_params_t * params,char ** buf,int * buf_size)28357c478bd9Sstevel@tonic-gate pack_list_ext_request(list_ext_params_t *params, char **buf, int *buf_size)
28367c478bd9Sstevel@tonic-gate {
28377c478bd9Sstevel@tonic-gate 	int				i;
28387c478bd9Sstevel@tonic-gate 	char				*bufptr;
28397c478bd9Sstevel@tonic-gate 	rdr_list_ext_t 			list_ext_data;
28407c478bd9Sstevel@tonic-gate 	rdr_variable_message_info_t 	var_msg_info;
28417c478bd9Sstevel@tonic-gate 
28427c478bd9Sstevel@tonic-gate 
28437c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
28447c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
28457c478bd9Sstevel@tonic-gate 	}
28467c478bd9Sstevel@tonic-gate 
28477c478bd9Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
28487c478bd9Sstevel@tonic-gate 
28497c478bd9Sstevel@tonic-gate 	/*
28507c478bd9Sstevel@tonic-gate 	 * Set variable length fields and make a call to partially
28517c478bd9Sstevel@tonic-gate 	 * pack it.
28527c478bd9Sstevel@tonic-gate 	 */
28537c478bd9Sstevel@tonic-gate 	if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) {
28547c478bd9Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
28557c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
28567c478bd9Sstevel@tonic-gate 	}
28577c478bd9Sstevel@tonic-gate 	if (find_options_sizes(params->options, &var_msg_info)) {
28587c478bd9Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
28597c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
28607c478bd9Sstevel@tonic-gate 	}
28617c478bd9Sstevel@tonic-gate 	if (find_listopts_sizes(params->listopts, &var_msg_info)) {
28627c478bd9Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
28637c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
28647c478bd9Sstevel@tonic-gate 	}
28657c478bd9Sstevel@tonic-gate 
28667c478bd9Sstevel@tonic-gate 
28677c478bd9Sstevel@tonic-gate 	/*
28687c478bd9Sstevel@tonic-gate 	 * Collect size info specific to the list_ext request
28697c478bd9Sstevel@tonic-gate 	 * message and allocate a buffer
28707c478bd9Sstevel@tonic-gate 	 */
28717c478bd9Sstevel@tonic-gate 	*buf_size = sizeof (rdr_list_ext_t);
28727c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.ap_id_int_size;
28737c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.ap_id_char_size;
28747c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.options_strlen;
28757c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.options_pad_sz;
28767c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.listopts_strlen;
28777c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.listopts_pad_sz;
28787c478bd9Sstevel@tonic-gate 
28797c478bd9Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
28807c478bd9Sstevel@tonic-gate 	if (*buf == NULL) {
28817c478bd9Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
28827c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
28837c478bd9Sstevel@tonic-gate 	}
28847c478bd9Sstevel@tonic-gate 
28857c478bd9Sstevel@tonic-gate 	/*
28867c478bd9Sstevel@tonic-gate 	 * Set fixed address labels by name
28877c478bd9Sstevel@tonic-gate 	 */
28887c478bd9Sstevel@tonic-gate 	list_ext_data.num_ap_ids = params->num_ap_ids;
28897c478bd9Sstevel@tonic-gate 	list_ext_data.ap_id_char_size = var_msg_info.ap_id_char_size;
28907c478bd9Sstevel@tonic-gate 	list_ext_data.options_size = var_msg_info.options_strlen +
28917c478bd9Sstevel@tonic-gate 	    var_msg_info.options_pad_sz;
28927c478bd9Sstevel@tonic-gate 	list_ext_data.listopts_size = var_msg_info.listopts_strlen +
28937c478bd9Sstevel@tonic-gate 	    var_msg_info.listopts_pad_sz;
28947c478bd9Sstevel@tonic-gate 	if (params->errstring != NULL) {
28957c478bd9Sstevel@tonic-gate 		list_ext_data.error_msg_ctl = RDR_GENERATE_ERR_MSGS;
28967c478bd9Sstevel@tonic-gate 	} else {
28977c478bd9Sstevel@tonic-gate 		list_ext_data.error_msg_ctl = RDR_DONT_GENERATE_ERR_MSGS;
28987c478bd9Sstevel@tonic-gate 	}
28997c478bd9Sstevel@tonic-gate 	if ((params->num_ap_ids != 0) || (params->ap_ids != NULL)) {
29007c478bd9Sstevel@tonic-gate 		list_ext_data.list_msg_ctl = RDR_LIST_ONLY_PARAM_APS;
29017c478bd9Sstevel@tonic-gate 	} else {
29027c478bd9Sstevel@tonic-gate 		list_ext_data.list_msg_ctl = RDR_LIST_ALL_APS;
29037c478bd9Sstevel@tonic-gate 	}
29047c478bd9Sstevel@tonic-gate 	list_ext_data.flags = params->flags;
29057c478bd9Sstevel@tonic-gate 	list_ext_data.permissions = params->permissions;
29067c478bd9Sstevel@tonic-gate 
29077c478bd9Sstevel@tonic-gate 	/*
29087c478bd9Sstevel@tonic-gate 	 * Set variable information using memcpy
29097c478bd9Sstevel@tonic-gate 	 */
29107c478bd9Sstevel@tonic-gate 	bufptr = *buf;
29117c478bd9Sstevel@tonic-gate 
29127c478bd9Sstevel@tonic-gate 	(void) memcpy(bufptr, &list_ext_data, sizeof (rdr_list_ext_t));
29137c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_list_ext_t);
29147c478bd9Sstevel@tonic-gate 
29157c478bd9Sstevel@tonic-gate 	if (var_msg_info.ap_id_sizes != NULL) {
29167c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, var_msg_info.ap_id_sizes,
29177c478bd9Sstevel@tonic-gate 		    var_msg_info.ap_id_int_size);
29187c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.ap_id_int_size;
29197c478bd9Sstevel@tonic-gate 	}
29207c478bd9Sstevel@tonic-gate 
29217c478bd9Sstevel@tonic-gate 	if (var_msg_info.ap_id_chars != NULL) {
29227c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, var_msg_info.ap_id_chars,
29237c478bd9Sstevel@tonic-gate 		    var_msg_info.ap_id_char_size);
29247c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.ap_id_char_size;
29257c478bd9Sstevel@tonic-gate 	}
29267c478bd9Sstevel@tonic-gate 
29277c478bd9Sstevel@tonic-gate 	if (params->options != NULL) {
29287c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, params->options,
29297c478bd9Sstevel@tonic-gate 		    var_msg_info.options_strlen);
29307c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.options_strlen;
29317c478bd9Sstevel@tonic-gate 		for (i = 0; i < var_msg_info.options_pad_sz; i++) {
29327c478bd9Sstevel@tonic-gate 			bufptr[i] = 0;
29337c478bd9Sstevel@tonic-gate 		}
29347c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.options_pad_sz;
29357c478bd9Sstevel@tonic-gate 	}
29367c478bd9Sstevel@tonic-gate 
29377c478bd9Sstevel@tonic-gate 	if (params->listopts != NULL) {
29387c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, params->listopts,
29397c478bd9Sstevel@tonic-gate 		    var_msg_info.listopts_strlen);
29407c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.listopts_strlen;
29417c478bd9Sstevel@tonic-gate 		for (i = 0; i < var_msg_info.listopts_pad_sz; i++) {
29427c478bd9Sstevel@tonic-gate 			bufptr[i] = 0;
29437c478bd9Sstevel@tonic-gate 		}
29447c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.listopts_pad_sz;
29457c478bd9Sstevel@tonic-gate 	}
29467c478bd9Sstevel@tonic-gate 
29477c478bd9Sstevel@tonic-gate 	cleanup_variable_ap_id_info(&var_msg_info);
29487c478bd9Sstevel@tonic-gate 
29497c478bd9Sstevel@tonic-gate 	return (RDR_OK);
29507c478bd9Sstevel@tonic-gate }
29517c478bd9Sstevel@tonic-gate 
29527c478bd9Sstevel@tonic-gate 
29537c478bd9Sstevel@tonic-gate /*
29547c478bd9Sstevel@tonic-gate  * unpack_list_ext_request:
29557c478bd9Sstevel@tonic-gate  *
29567c478bd9Sstevel@tonic-gate  * Handle unpacking a list request message.
29577c478bd9Sstevel@tonic-gate  */
29587c478bd9Sstevel@tonic-gate static int
unpack_list_ext_request(list_ext_params_t * params,const char * buf)29597c478bd9Sstevel@tonic-gate unpack_list_ext_request(list_ext_params_t *params, const char *buf)
29607c478bd9Sstevel@tonic-gate {
29617c478bd9Sstevel@tonic-gate 	char				*bufptr;
29627c478bd9Sstevel@tonic-gate 	rdr_variable_message_info_t 	var_msg_info;
29637c478bd9Sstevel@tonic-gate 	rdr_list_ext_t			list_ext_data;
29647c478bd9Sstevel@tonic-gate 
29657c478bd9Sstevel@tonic-gate 
29667c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
29677c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
29687c478bd9Sstevel@tonic-gate 	}
29697c478bd9Sstevel@tonic-gate 
29707c478bd9Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
29717c478bd9Sstevel@tonic-gate 
29727c478bd9Sstevel@tonic-gate 	bufptr = (char *)buf;
29737c478bd9Sstevel@tonic-gate 	(void) memcpy(&list_ext_data, bufptr, sizeof (rdr_list_ext_t));
29747c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_list_ext_t);
29757c478bd9Sstevel@tonic-gate 
29767c478bd9Sstevel@tonic-gate 	/*
29777c478bd9Sstevel@tonic-gate 	 * handle getting the ap_ids
29787c478bd9Sstevel@tonic-gate 	 */
29797c478bd9Sstevel@tonic-gate 	var_msg_info.ap_id_char_size = list_ext_data.ap_id_char_size;
29807c478bd9Sstevel@tonic-gate 	if (get_ap_ids_from_buf(&(params->ap_ids), list_ext_data.num_ap_ids,
29817c478bd9Sstevel@tonic-gate 	    &var_msg_info, bufptr)) {
29827c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
29837c478bd9Sstevel@tonic-gate 	}
29847c478bd9Sstevel@tonic-gate 	bufptr += var_msg_info.ap_id_int_size;
29857c478bd9Sstevel@tonic-gate 	bufptr += var_msg_info.ap_id_char_size;
29867c478bd9Sstevel@tonic-gate 
29877c478bd9Sstevel@tonic-gate 	/*
29887c478bd9Sstevel@tonic-gate 	 * handle getting the options
29897c478bd9Sstevel@tonic-gate 	 */
29907c478bd9Sstevel@tonic-gate 	if (get_string_from_buf(&(params->options),
29917c478bd9Sstevel@tonic-gate 	    list_ext_data.options_size, bufptr)) {
29927c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
29937c478bd9Sstevel@tonic-gate 	}
29947c478bd9Sstevel@tonic-gate 	bufptr += list_ext_data.options_size;
29957c478bd9Sstevel@tonic-gate 
29967c478bd9Sstevel@tonic-gate 	/*
29977c478bd9Sstevel@tonic-gate 	 * handle getting the listopts
29987c478bd9Sstevel@tonic-gate 	 */
29997c478bd9Sstevel@tonic-gate 	if (get_string_from_buf(&(params->listopts),
30007c478bd9Sstevel@tonic-gate 	    list_ext_data.listopts_size, bufptr)) {
30017c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
30027c478bd9Sstevel@tonic-gate 	}
30037c478bd9Sstevel@tonic-gate 	bufptr += list_ext_data.listopts_size;
30047c478bd9Sstevel@tonic-gate 
30057c478bd9Sstevel@tonic-gate 	/*
30067c478bd9Sstevel@tonic-gate 	 * Set fixed address labels by name
30077c478bd9Sstevel@tonic-gate 	 */
30087c478bd9Sstevel@tonic-gate 	params->num_ap_ids = list_ext_data.num_ap_ids;
30097c478bd9Sstevel@tonic-gate 
30107c478bd9Sstevel@tonic-gate 	params->ap_id_list = (rdr_list_t **)malloc(sizeof (rdr_list_t *));
30117c478bd9Sstevel@tonic-gate 	if (params->ap_id_list == NULL) {
30127c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
30137c478bd9Sstevel@tonic-gate 	}
30147c478bd9Sstevel@tonic-gate 	*(params->ap_id_list) = NULL;
30157c478bd9Sstevel@tonic-gate 
30167c478bd9Sstevel@tonic-gate 	params->nlist = (int *)malloc(sizeof (int));
30177c478bd9Sstevel@tonic-gate 	if (params->nlist == NULL) {
30187c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
30197c478bd9Sstevel@tonic-gate 	}
30207c478bd9Sstevel@tonic-gate 	if (list_ext_data.error_msg_ctl == RDR_GENERATE_ERR_MSGS) {
30217c478bd9Sstevel@tonic-gate 		params->errstring = (char **)malloc(sizeof (char *));
30227c478bd9Sstevel@tonic-gate 		if (params->errstring == NULL) {
30237c478bd9Sstevel@tonic-gate 			return (RDR_MEM_ALLOC);
30247c478bd9Sstevel@tonic-gate 		}
30257c478bd9Sstevel@tonic-gate 		*(params->errstring) = NULL;
30267c478bd9Sstevel@tonic-gate 	} else {	/* error_msg_ctl == RDR_DONT_GENERATE_ERR_MSGS */
30277c478bd9Sstevel@tonic-gate 	    params->errstring = NULL;
30287c478bd9Sstevel@tonic-gate 	}
30297c478bd9Sstevel@tonic-gate 	params->flags = list_ext_data.flags;
30307c478bd9Sstevel@tonic-gate 	params->permissions = list_ext_data.permissions;
30317c478bd9Sstevel@tonic-gate 
30327c478bd9Sstevel@tonic-gate 	return (RDR_OK);
30337c478bd9Sstevel@tonic-gate }
30347c478bd9Sstevel@tonic-gate 
30357c478bd9Sstevel@tonic-gate 
30367c478bd9Sstevel@tonic-gate /*
30377c478bd9Sstevel@tonic-gate  * pack_list_ext_reply:
30387c478bd9Sstevel@tonic-gate  *
30397c478bd9Sstevel@tonic-gate  * Handle packing a list reply message.
30407c478bd9Sstevel@tonic-gate  */
30417c478bd9Sstevel@tonic-gate static int
pack_list_ext_reply(list_ext_params_t * params,char ** buf,int * buf_size)30427c478bd9Sstevel@tonic-gate pack_list_ext_reply(list_ext_params_t *params, char **buf, int *buf_size)
30437c478bd9Sstevel@tonic-gate {
30447c478bd9Sstevel@tonic-gate 	int				i;
30457c478bd9Sstevel@tonic-gate 	char				*bufptr;
30467c478bd9Sstevel@tonic-gate 	rdr_list_ext_reply_t		list_ext_data;
30477c478bd9Sstevel@tonic-gate 	rdr_variable_message_info_t 	var_msg_info;
30487c478bd9Sstevel@tonic-gate 	int 				list_data_size;
30497c478bd9Sstevel@tonic-gate 
30507c478bd9Sstevel@tonic-gate 
30517c478bd9Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
30527c478bd9Sstevel@tonic-gate 
30537c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
30547c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
30557c478bd9Sstevel@tonic-gate 	}
30567c478bd9Sstevel@tonic-gate 
30577c478bd9Sstevel@tonic-gate 	/*
30587c478bd9Sstevel@tonic-gate 	 * Set variable length fields (size info)
30597c478bd9Sstevel@tonic-gate 	 */
30607c478bd9Sstevel@tonic-gate 	if (find_errstring_sizes(params->errstring, &var_msg_info)) {
30617c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
30627c478bd9Sstevel@tonic-gate 	}
30637c478bd9Sstevel@tonic-gate 
30647c478bd9Sstevel@tonic-gate 	if (params->nlist == NULL) {
30657c478bd9Sstevel@tonic-gate 		list_data_size = 0;
30667c478bd9Sstevel@tonic-gate 	} else {
30677c478bd9Sstevel@tonic-gate 		list_data_size = *(params->nlist) * sizeof (rdr_list_t);
30687c478bd9Sstevel@tonic-gate 	}
30697c478bd9Sstevel@tonic-gate 
30707c478bd9Sstevel@tonic-gate 	/*
30717c478bd9Sstevel@tonic-gate 	 * Collect size info specific to the list_ext reply
30727c478bd9Sstevel@tonic-gate 	 * message and allocate a buffer
30737c478bd9Sstevel@tonic-gate 	 */
30747c478bd9Sstevel@tonic-gate 	*buf_size = sizeof (rdr_list_ext_reply_t);
30757c478bd9Sstevel@tonic-gate 	*buf_size += list_data_size;
30767c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.errstring_strlen;
30777c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.errstring_pad_sz;
30787c478bd9Sstevel@tonic-gate 
30797c478bd9Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
30807c478bd9Sstevel@tonic-gate 	if (*buf == NULL) {
30817c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
30827c478bd9Sstevel@tonic-gate 	}
30837c478bd9Sstevel@tonic-gate 
30847c478bd9Sstevel@tonic-gate 	/*
30857c478bd9Sstevel@tonic-gate 	 * Set fixed address labels by name
30867c478bd9Sstevel@tonic-gate 	 */
30877c478bd9Sstevel@tonic-gate 	list_ext_data.num_ap_ids = (params->nlist) ? *(params->nlist) : 0;
30887c478bd9Sstevel@tonic-gate 	list_ext_data.errstring_size = var_msg_info.errstring_strlen +
30897c478bd9Sstevel@tonic-gate 	    var_msg_info.errstring_pad_sz;
30907c478bd9Sstevel@tonic-gate 
30917c478bd9Sstevel@tonic-gate 	/*
30927c478bd9Sstevel@tonic-gate 	 * Set variable information using memcpy
30937c478bd9Sstevel@tonic-gate 	 */
30947c478bd9Sstevel@tonic-gate 	bufptr = *buf;
30957c478bd9Sstevel@tonic-gate 
30967c478bd9Sstevel@tonic-gate 	(void) memcpy(bufptr, &list_ext_data, sizeof (rdr_list_ext_reply_t));
30977c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_list_ext_reply_t);
30987c478bd9Sstevel@tonic-gate 
30997c478bd9Sstevel@tonic-gate 	if ((params->ap_id_list != NULL) && (*(params->ap_id_list) != NULL)) {
31007c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, *(params->ap_id_list), list_data_size);
31017c478bd9Sstevel@tonic-gate 		bufptr += list_data_size;
31027c478bd9Sstevel@tonic-gate 	} else if (list_data_size) {
31037c478bd9Sstevel@tonic-gate 		/*
31047c478bd9Sstevel@tonic-gate 		 * Something is out of sync. We were expecting
31057c478bd9Sstevel@tonic-gate 		 * some data to copy, but instead we found a
31067c478bd9Sstevel@tonic-gate 		 * NULL pointer.
31077c478bd9Sstevel@tonic-gate 		 */
31087c478bd9Sstevel@tonic-gate 		(void) free((void *)*buf);
31097c478bd9Sstevel@tonic-gate 		*buf = NULL;
31107c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
31117c478bd9Sstevel@tonic-gate 	}
31127c478bd9Sstevel@tonic-gate 
31137c478bd9Sstevel@tonic-gate 	if ((params->errstring != NULL) && (*(params->errstring) != NULL)) {
31147c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, *(params->errstring),
31157c478bd9Sstevel@tonic-gate 		    var_msg_info.errstring_strlen);
31167c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.errstring_strlen;
31177c478bd9Sstevel@tonic-gate 		for (i = 0; i < var_msg_info.errstring_pad_sz; i++) {
31187c478bd9Sstevel@tonic-gate 			bufptr[i] = 0;
31197c478bd9Sstevel@tonic-gate 		}
31207c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.errstring_pad_sz;
31217c478bd9Sstevel@tonic-gate 	}
31227c478bd9Sstevel@tonic-gate 
31237c478bd9Sstevel@tonic-gate 	return (RDR_OK);
31247c478bd9Sstevel@tonic-gate }
31257c478bd9Sstevel@tonic-gate 
31267c478bd9Sstevel@tonic-gate 
31277c478bd9Sstevel@tonic-gate /*
31287c478bd9Sstevel@tonic-gate  * unpack_list_ext_reply:
31297c478bd9Sstevel@tonic-gate  *
31307c478bd9Sstevel@tonic-gate  * Handle unpacking a list reply message.
31317c478bd9Sstevel@tonic-gate  */
31327c478bd9Sstevel@tonic-gate static int
unpack_list_ext_reply(list_ext_params_t * params,const char * buf)31337c478bd9Sstevel@tonic-gate unpack_list_ext_reply(list_ext_params_t *params, const char *buf)
31347c478bd9Sstevel@tonic-gate {
31357c478bd9Sstevel@tonic-gate 	int 			list_data_size;
31367c478bd9Sstevel@tonic-gate 	char 			*bufptr;
31377c478bd9Sstevel@tonic-gate 	rdr_list_ext_reply_t	list_ext_data;
31387c478bd9Sstevel@tonic-gate 
31397c478bd9Sstevel@tonic-gate 
31407c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
31417c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
31427c478bd9Sstevel@tonic-gate 	}
31437c478bd9Sstevel@tonic-gate 
31447c478bd9Sstevel@tonic-gate 	bufptr = (char *)buf;
31457c478bd9Sstevel@tonic-gate 	(void) memcpy(&list_ext_data, bufptr, sizeof (rdr_list_ext_reply_t));
31467c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_list_ext_reply_t);
31477c478bd9Sstevel@tonic-gate 
31487c478bd9Sstevel@tonic-gate 	/*
31497c478bd9Sstevel@tonic-gate 	 * handle getting the ap_id rcfga_list_data_t's.
31507c478bd9Sstevel@tonic-gate 	 */
31517c478bd9Sstevel@tonic-gate 	if (list_ext_data.num_ap_ids > 0) {
31527c478bd9Sstevel@tonic-gate 		params->nlist = (int *)malloc(sizeof (int));
31537c478bd9Sstevel@tonic-gate 		if (params->nlist == NULL) {
31547c478bd9Sstevel@tonic-gate 			return (RDR_MEM_ALLOC);
31557c478bd9Sstevel@tonic-gate 		}
31567c478bd9Sstevel@tonic-gate 		*(params->nlist) = list_ext_data.num_ap_ids;
31577c478bd9Sstevel@tonic-gate 		params->ap_id_list = (rdr_list_t **)
31587c478bd9Sstevel@tonic-gate 		    malloc(sizeof (rdr_list_t *));
31597c478bd9Sstevel@tonic-gate 		if (params->ap_id_list == NULL) {
31607c478bd9Sstevel@tonic-gate 			return (RDR_MEM_ALLOC);
31617c478bd9Sstevel@tonic-gate 		}
31627c478bd9Sstevel@tonic-gate 		*(params->ap_id_list) = (rdr_list_t *)
31637c478bd9Sstevel@tonic-gate 		malloc(sizeof (rdr_list_t) * list_ext_data.num_ap_ids);
31647c478bd9Sstevel@tonic-gate 		if (*(params->ap_id_list) == NULL) {
31657c478bd9Sstevel@tonic-gate 			return (RDR_MEM_ALLOC);
31667c478bd9Sstevel@tonic-gate 		}
31677c478bd9Sstevel@tonic-gate 		list_data_size = list_ext_data.num_ap_ids * sizeof (rdr_list_t);
31687c478bd9Sstevel@tonic-gate 		(void) memcpy(*(params->ap_id_list), bufptr, list_data_size);
31697c478bd9Sstevel@tonic-gate 		bufptr += list_data_size;
31707c478bd9Sstevel@tonic-gate 	}
31717c478bd9Sstevel@tonic-gate 
31727c478bd9Sstevel@tonic-gate 	/*
31737c478bd9Sstevel@tonic-gate 	 * handle getting the errstring
31747c478bd9Sstevel@tonic-gate 	 */
31757c478bd9Sstevel@tonic-gate 	params->errstring = (char **)malloc(sizeof (char *));
31767c478bd9Sstevel@tonic-gate 	if (params->errstring == NULL) {
31777c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
31787c478bd9Sstevel@tonic-gate 	}
31797c478bd9Sstevel@tonic-gate 	if (get_string_from_buf(params->errstring,
31807c478bd9Sstevel@tonic-gate 			list_ext_data.errstring_size, bufptr)) {
31817c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
31827c478bd9Sstevel@tonic-gate 	}
31837c478bd9Sstevel@tonic-gate 	bufptr += list_ext_data.errstring_size;
31847c478bd9Sstevel@tonic-gate 
31857c478bd9Sstevel@tonic-gate 	return (RDR_OK);
31867c478bd9Sstevel@tonic-gate }
31877c478bd9Sstevel@tonic-gate 
31887c478bd9Sstevel@tonic-gate 
31897c478bd9Sstevel@tonic-gate /*
31907c478bd9Sstevel@tonic-gate  * pack_help_request:
31917c478bd9Sstevel@tonic-gate  *
31927c478bd9Sstevel@tonic-gate  * Handle packing a help request message.
31937c478bd9Sstevel@tonic-gate  */
31947c478bd9Sstevel@tonic-gate static int
pack_help_request(help_params_t * params,char ** buf,int * buf_size)31957c478bd9Sstevel@tonic-gate pack_help_request(help_params_t *params, char **buf, int *buf_size)
31967c478bd9Sstevel@tonic-gate {
31977c478bd9Sstevel@tonic-gate 	int				i;
31987c478bd9Sstevel@tonic-gate 	char				*bufptr;
31997c478bd9Sstevel@tonic-gate 	rdr_help_t			help_data;
32007c478bd9Sstevel@tonic-gate 	rdr_variable_message_info_t	var_msg_info;
32017c478bd9Sstevel@tonic-gate 
32027c478bd9Sstevel@tonic-gate 
32037c478bd9Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
32047c478bd9Sstevel@tonic-gate 
32057c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
32067c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
32077c478bd9Sstevel@tonic-gate 	}
32087c478bd9Sstevel@tonic-gate 
32097c478bd9Sstevel@tonic-gate 	/*
32107c478bd9Sstevel@tonic-gate 	 * Set variable length fields and make a call to partially
32117c478bd9Sstevel@tonic-gate 	 * pack it.
32127c478bd9Sstevel@tonic-gate 	 */
32137c478bd9Sstevel@tonic-gate 	if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) {
32147c478bd9Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
32157c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
32167c478bd9Sstevel@tonic-gate 	}
32177c478bd9Sstevel@tonic-gate 	if (find_options_sizes(params->options, &var_msg_info)) {
32187c478bd9Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
32197c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
32207c478bd9Sstevel@tonic-gate 	}
32217c478bd9Sstevel@tonic-gate 
32227c478bd9Sstevel@tonic-gate 	/*
32237c478bd9Sstevel@tonic-gate 	 * Collect size info specific to the help request message and
32247c478bd9Sstevel@tonic-gate 	 * and allocate a buffer
32257c478bd9Sstevel@tonic-gate 	 */
32267c478bd9Sstevel@tonic-gate 	*buf_size = sizeof (rdr_help_t);
32277c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.ap_id_int_size;
32287c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.ap_id_char_size;
32297c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.options_strlen;
32307c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.options_pad_sz;
32317c478bd9Sstevel@tonic-gate 
32327c478bd9Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
32337c478bd9Sstevel@tonic-gate 	if (*buf == NULL) {
32347c478bd9Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
32357c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
32367c478bd9Sstevel@tonic-gate 	}
32377c478bd9Sstevel@tonic-gate 
32387c478bd9Sstevel@tonic-gate 	/*
32397c478bd9Sstevel@tonic-gate 	 * Set fixed address labels by name
32407c478bd9Sstevel@tonic-gate 	 */
32417c478bd9Sstevel@tonic-gate 	help_data.num_ap_ids = params->num_ap_ids;
32427c478bd9Sstevel@tonic-gate 	help_data.ap_id_char_size = var_msg_info.ap_id_char_size;
32437c478bd9Sstevel@tonic-gate 	help_data.options_size = var_msg_info.options_strlen +
32447c478bd9Sstevel@tonic-gate 	    var_msg_info.options_pad_sz;
32457c478bd9Sstevel@tonic-gate 
32467c478bd9Sstevel@tonic-gate 	if (params->msgp != NULL) {
32477c478bd9Sstevel@tonic-gate 		help_data.msg_callback_id =
32487c478bd9Sstevel@tonic-gate 		    (unsigned long)params->msgp->message_routine;
32497c478bd9Sstevel@tonic-gate 		help_data.msg_appdata_ptr =
32507c478bd9Sstevel@tonic-gate 		    (unsigned long)params->msgp->appdata_ptr;
32517c478bd9Sstevel@tonic-gate 	} else {
32527c478bd9Sstevel@tonic-gate 		help_data.msg_callback_id = 0;
32537c478bd9Sstevel@tonic-gate 		help_data.msg_appdata_ptr = 0;
32547c478bd9Sstevel@tonic-gate 	}
32557c478bd9Sstevel@tonic-gate 
32567c478bd9Sstevel@tonic-gate 	help_data.flags = params->flags;
32577c478bd9Sstevel@tonic-gate 
32587c478bd9Sstevel@tonic-gate 	/*
32597c478bd9Sstevel@tonic-gate 	 * Set variable information using memcpy
32607c478bd9Sstevel@tonic-gate 	 */
32617c478bd9Sstevel@tonic-gate 	bufptr = *buf;
32627c478bd9Sstevel@tonic-gate 
32637c478bd9Sstevel@tonic-gate 	(void) memcpy(bufptr, &help_data, sizeof (rdr_help_t));
32647c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_help_t);
32657c478bd9Sstevel@tonic-gate 
32667c478bd9Sstevel@tonic-gate 	if (var_msg_info.ap_id_sizes != NULL) {
32677c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, var_msg_info.ap_id_sizes,
32687c478bd9Sstevel@tonic-gate 		    var_msg_info.ap_id_int_size);
32697c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.ap_id_int_size;
32707c478bd9Sstevel@tonic-gate 	}
32717c478bd9Sstevel@tonic-gate 
32727c478bd9Sstevel@tonic-gate 	if (var_msg_info.ap_id_chars != NULL) {
32737c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, var_msg_info.ap_id_chars,
32747c478bd9Sstevel@tonic-gate 		    var_msg_info.ap_id_char_size);
32757c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.ap_id_char_size;
32767c478bd9Sstevel@tonic-gate 	}
32777c478bd9Sstevel@tonic-gate 
32787c478bd9Sstevel@tonic-gate 	if (params->options != NULL) {
32797c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, params->options,
32807c478bd9Sstevel@tonic-gate 		    var_msg_info.options_strlen);
32817c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.options_strlen;
32827c478bd9Sstevel@tonic-gate 		for (i = 0; i < var_msg_info.options_pad_sz; i++) {
32837c478bd9Sstevel@tonic-gate 			bufptr[i] = 0;
32847c478bd9Sstevel@tonic-gate 		}
32857c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.options_pad_sz;
32867c478bd9Sstevel@tonic-gate 	}
32877c478bd9Sstevel@tonic-gate 
32887c478bd9Sstevel@tonic-gate 	cleanup_variable_ap_id_info(&var_msg_info);
32897c478bd9Sstevel@tonic-gate 
32907c478bd9Sstevel@tonic-gate 	return (RDR_OK);
32917c478bd9Sstevel@tonic-gate }
32927c478bd9Sstevel@tonic-gate 
32937c478bd9Sstevel@tonic-gate 
32947c478bd9Sstevel@tonic-gate /*
32957c478bd9Sstevel@tonic-gate  * unpack_help_request:
32967c478bd9Sstevel@tonic-gate  *
32977c478bd9Sstevel@tonic-gate  * Handle unpacking a help request message.
32987c478bd9Sstevel@tonic-gate  */
32997c478bd9Sstevel@tonic-gate static int
unpack_help_request(help_params_t * params,const char * buf)33007c478bd9Sstevel@tonic-gate unpack_help_request(help_params_t *params, const char *buf)
33017c478bd9Sstevel@tonic-gate {
33027c478bd9Sstevel@tonic-gate 	char				*bufptr;
33037c478bd9Sstevel@tonic-gate 	rdr_variable_message_info_t 	var_msg_info;
33047c478bd9Sstevel@tonic-gate 	rdr_help_t			help_data;
33057c478bd9Sstevel@tonic-gate 
33067c478bd9Sstevel@tonic-gate 
33077c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
33087c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
33097c478bd9Sstevel@tonic-gate 	}
33107c478bd9Sstevel@tonic-gate 
33117c478bd9Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
33127c478bd9Sstevel@tonic-gate 
33137c478bd9Sstevel@tonic-gate 	bufptr = (char *)buf;
33147c478bd9Sstevel@tonic-gate 	(void) memcpy(&help_data, bufptr, sizeof (rdr_help_t));
33157c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_help_t);
33167c478bd9Sstevel@tonic-gate 
33177c478bd9Sstevel@tonic-gate 	/*
33187c478bd9Sstevel@tonic-gate 	 * handle getting the ap_ids
33197c478bd9Sstevel@tonic-gate 	 */
33207c478bd9Sstevel@tonic-gate 	var_msg_info.ap_id_char_size = help_data.ap_id_char_size;
33217c478bd9Sstevel@tonic-gate 	if (get_ap_ids_from_buf((char ***)&(params->ap_ids),
33227c478bd9Sstevel@tonic-gate 	    help_data.num_ap_ids, &var_msg_info, bufptr)) {
33237c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
33247c478bd9Sstevel@tonic-gate 	}
33257c478bd9Sstevel@tonic-gate 	bufptr += var_msg_info.ap_id_int_size;
33267c478bd9Sstevel@tonic-gate 	bufptr += var_msg_info.ap_id_char_size;
33277c478bd9Sstevel@tonic-gate 
33287c478bd9Sstevel@tonic-gate 	/*
33297c478bd9Sstevel@tonic-gate 	 * handle getting the options
33307c478bd9Sstevel@tonic-gate 	 */
33317c478bd9Sstevel@tonic-gate 	if (get_string_from_buf(&(params->options),
33327c478bd9Sstevel@tonic-gate 	    help_data.options_size, bufptr)) {
33337c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
33347c478bd9Sstevel@tonic-gate 	}
33357c478bd9Sstevel@tonic-gate 	bufptr += help_data.options_size;
33367c478bd9Sstevel@tonic-gate 
33377c478bd9Sstevel@tonic-gate 	/*
33387c478bd9Sstevel@tonic-gate 	 * Set fixed address labels by name
33397c478bd9Sstevel@tonic-gate 	 */
33407c478bd9Sstevel@tonic-gate 	params->num_ap_ids = help_data.num_ap_ids;
33417c478bd9Sstevel@tonic-gate 
33427c478bd9Sstevel@tonic-gate 	params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg));
33437c478bd9Sstevel@tonic-gate 	if (params->msgp == NULL) {
33447c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
33457c478bd9Sstevel@tonic-gate 	}
33467c478bd9Sstevel@tonic-gate 
33477c478bd9Sstevel@tonic-gate 	/* set params->msgp->message_routine using memcpy */
33487c478bd9Sstevel@tonic-gate 	(void) memcpy((void*)params->msgp, &(help_data.msg_callback_id),
33497c478bd9Sstevel@tonic-gate 	    sizeof (unsigned long));
33507c478bd9Sstevel@tonic-gate 
33517c478bd9Sstevel@tonic-gate 	params->msgp->appdata_ptr = (void*)help_data.msg_appdata_ptr;
33527c478bd9Sstevel@tonic-gate 	params->flags = help_data.flags;
33537c478bd9Sstevel@tonic-gate 
33547c478bd9Sstevel@tonic-gate 	return (RDR_OK);
33557c478bd9Sstevel@tonic-gate }
33567c478bd9Sstevel@tonic-gate 
33577c478bd9Sstevel@tonic-gate 
33587c478bd9Sstevel@tonic-gate /*
33597c478bd9Sstevel@tonic-gate  * pack_ap_id_cmp_request:
33607c478bd9Sstevel@tonic-gate  *
33617c478bd9Sstevel@tonic-gate  * Handle packing an attachment point comparison request message.
33627c478bd9Sstevel@tonic-gate  */
33637c478bd9Sstevel@tonic-gate static int
pack_ap_id_cmp_request(ap_id_cmp_params_t * params,char ** buf,int * buf_size)33647c478bd9Sstevel@tonic-gate pack_ap_id_cmp_request(ap_id_cmp_params_t *params, char **buf, int *buf_size)
33657c478bd9Sstevel@tonic-gate {
33667c478bd9Sstevel@tonic-gate 	int			i;
33677c478bd9Sstevel@tonic-gate 	char			*bufptr;
33687c478bd9Sstevel@tonic-gate 	rdr_ap_id_cmp_t		ap_id_cmp_data;
33697c478bd9Sstevel@tonic-gate 	int			ap_id1_strlen;
33707c478bd9Sstevel@tonic-gate 	int			ap_id1_pad_sz;
33717c478bd9Sstevel@tonic-gate 	int			ap_id2_strlen;
33727c478bd9Sstevel@tonic-gate 	int			ap_id2_pad_sz;
33737c478bd9Sstevel@tonic-gate 
33747c478bd9Sstevel@tonic-gate 
33757c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
33767c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
33777c478bd9Sstevel@tonic-gate 	}
33787c478bd9Sstevel@tonic-gate 
33797c478bd9Sstevel@tonic-gate 	/*
33807c478bd9Sstevel@tonic-gate 	 * Set variable length fields and make a call to partially
33817c478bd9Sstevel@tonic-gate 	 * pack it.
33827c478bd9Sstevel@tonic-gate 	 */
33837c478bd9Sstevel@tonic-gate 	if (params->ap_log_id1 != NULL) {
33847c478bd9Sstevel@tonic-gate 		ap_id1_strlen = strlen(params->ap_log_id1) + 1;
33857c478bd9Sstevel@tonic-gate 		ap_id1_pad_sz = RDR_ALIGN_64_BIT -
33867c478bd9Sstevel@tonic-gate 		    (ap_id1_strlen % RDR_ALIGN_64_BIT);
33877c478bd9Sstevel@tonic-gate 	} else {
33887c478bd9Sstevel@tonic-gate 		ap_id1_strlen = 0;
33897c478bd9Sstevel@tonic-gate 		ap_id1_pad_sz = 0;
33907c478bd9Sstevel@tonic-gate 	}
33917c478bd9Sstevel@tonic-gate 
33927c478bd9Sstevel@tonic-gate 	if (params->ap_log_id2 != NULL) {
33937c478bd9Sstevel@tonic-gate 		ap_id2_strlen = strlen(params->ap_log_id2) + 1;
33947c478bd9Sstevel@tonic-gate 		ap_id2_pad_sz = RDR_ALIGN_64_BIT -
33957c478bd9Sstevel@tonic-gate 		    (ap_id2_strlen % RDR_ALIGN_64_BIT);
33967c478bd9Sstevel@tonic-gate 	} else {
33977c478bd9Sstevel@tonic-gate 		ap_id2_strlen = 0;
33987c478bd9Sstevel@tonic-gate 		ap_id2_pad_sz = 0;
33997c478bd9Sstevel@tonic-gate 	}
34007c478bd9Sstevel@tonic-gate 
34017c478bd9Sstevel@tonic-gate 	/*
34027c478bd9Sstevel@tonic-gate 	 * Collect size info specific to the ap id compare request
34037c478bd9Sstevel@tonic-gate 	 * message and allocate a buffer
34047c478bd9Sstevel@tonic-gate 	 */
34057c478bd9Sstevel@tonic-gate 	*buf_size = sizeof (rdr_ap_id_cmp_t);
34067c478bd9Sstevel@tonic-gate 	*buf_size += ap_id1_strlen;
34077c478bd9Sstevel@tonic-gate 	*buf_size += ap_id1_pad_sz;
34087c478bd9Sstevel@tonic-gate 	*buf_size += ap_id2_strlen;
34097c478bd9Sstevel@tonic-gate 	*buf_size += ap_id2_pad_sz;
34107c478bd9Sstevel@tonic-gate 
34117c478bd9Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
34127c478bd9Sstevel@tonic-gate 	if (*buf == NULL) {
34137c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
34147c478bd9Sstevel@tonic-gate 	}
34157c478bd9Sstevel@tonic-gate 
34167c478bd9Sstevel@tonic-gate 	/*
34177c478bd9Sstevel@tonic-gate 	 * Set fixed address labels by name
34187c478bd9Sstevel@tonic-gate 	 */
34197c478bd9Sstevel@tonic-gate 	ap_id_cmp_data.ap_id1_size = ap_id1_strlen + ap_id1_pad_sz;
34207c478bd9Sstevel@tonic-gate 	ap_id_cmp_data.ap_id2_size = ap_id2_strlen + ap_id2_pad_sz;
34217c478bd9Sstevel@tonic-gate 
34227c478bd9Sstevel@tonic-gate 
34237c478bd9Sstevel@tonic-gate 	/*
34247c478bd9Sstevel@tonic-gate 	 * Set variable information using memcpy
34257c478bd9Sstevel@tonic-gate 	 */
34267c478bd9Sstevel@tonic-gate 	bufptr = *buf;
34277c478bd9Sstevel@tonic-gate 
34287c478bd9Sstevel@tonic-gate 	(void) memcpy(bufptr, &ap_id_cmp_data, sizeof (rdr_ap_id_cmp_t));
34297c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_ap_id_cmp_t);
34307c478bd9Sstevel@tonic-gate 
34317c478bd9Sstevel@tonic-gate 	if (params->ap_log_id1 != NULL) {
34327c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, params->ap_log_id1, ap_id1_strlen);
34337c478bd9Sstevel@tonic-gate 		bufptr += ap_id1_strlen;
34347c478bd9Sstevel@tonic-gate 		for (i = 0; i < ap_id1_pad_sz; i++) {
34357c478bd9Sstevel@tonic-gate 			bufptr[i] = 0;
34367c478bd9Sstevel@tonic-gate 		}
34377c478bd9Sstevel@tonic-gate 		bufptr += ap_id1_pad_sz;
34387c478bd9Sstevel@tonic-gate 	}
34397c478bd9Sstevel@tonic-gate 
34407c478bd9Sstevel@tonic-gate 	if (params->ap_log_id2 != NULL) {
34417c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, params->ap_log_id2, ap_id2_strlen);
34427c478bd9Sstevel@tonic-gate 		bufptr += ap_id2_strlen;
34437c478bd9Sstevel@tonic-gate 		for (i = 0; i < ap_id2_pad_sz; i++) {
34447c478bd9Sstevel@tonic-gate 			bufptr[i] = 0;
34457c478bd9Sstevel@tonic-gate 		}
34467c478bd9Sstevel@tonic-gate 		bufptr += ap_id2_pad_sz;
34477c478bd9Sstevel@tonic-gate 	}
34487c478bd9Sstevel@tonic-gate 
34497c478bd9Sstevel@tonic-gate 	return (RDR_OK);
34507c478bd9Sstevel@tonic-gate }
34517c478bd9Sstevel@tonic-gate 
34527c478bd9Sstevel@tonic-gate 
34537c478bd9Sstevel@tonic-gate /*
34547c478bd9Sstevel@tonic-gate  * unpack_ap_id_cmp_request:
34557c478bd9Sstevel@tonic-gate  *
34567c478bd9Sstevel@tonic-gate  * Handle unpacking an attachment point comparison request message.
34577c478bd9Sstevel@tonic-gate  */
34587c478bd9Sstevel@tonic-gate static int
unpack_ap_id_cmp_request(ap_id_cmp_params_t * params,const char * buf)34597c478bd9Sstevel@tonic-gate unpack_ap_id_cmp_request(ap_id_cmp_params_t *params, const char *buf)
34607c478bd9Sstevel@tonic-gate {
34617c478bd9Sstevel@tonic-gate 	char			*bufptr;
34627c478bd9Sstevel@tonic-gate 	rdr_ap_id_cmp_t		ap_id_cmp_data;
34637c478bd9Sstevel@tonic-gate 
34647c478bd9Sstevel@tonic-gate 
34657c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
34667c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
34677c478bd9Sstevel@tonic-gate 	}
34687c478bd9Sstevel@tonic-gate 
34697c478bd9Sstevel@tonic-gate 	bufptr = (char *)buf;
34707c478bd9Sstevel@tonic-gate 	(void) memcpy(&ap_id_cmp_data, bufptr, sizeof (rdr_ap_id_cmp_t));
34717c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_ap_id_cmp_t);
34727c478bd9Sstevel@tonic-gate 
34737c478bd9Sstevel@tonic-gate 	/*
34747c478bd9Sstevel@tonic-gate 	 * handle getting the cmp ap ids
34757c478bd9Sstevel@tonic-gate 	 */
34767c478bd9Sstevel@tonic-gate 	if (get_string_from_buf(&(params->ap_log_id1),
34777c478bd9Sstevel@tonic-gate 	    ap_id_cmp_data.ap_id1_size, bufptr)) {
34787c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
34797c478bd9Sstevel@tonic-gate 	}
34807c478bd9Sstevel@tonic-gate 	bufptr += ap_id_cmp_data.ap_id1_size;
34817c478bd9Sstevel@tonic-gate 
34827c478bd9Sstevel@tonic-gate 	if (get_string_from_buf(&(params->ap_log_id2),
34837c478bd9Sstevel@tonic-gate 	    ap_id_cmp_data.ap_id2_size, bufptr)) {
34847c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
34857c478bd9Sstevel@tonic-gate 	}
34867c478bd9Sstevel@tonic-gate 	bufptr += ap_id_cmp_data.ap_id2_size;
34877c478bd9Sstevel@tonic-gate 
34887c478bd9Sstevel@tonic-gate 	return (RDR_OK);
34897c478bd9Sstevel@tonic-gate }
34907c478bd9Sstevel@tonic-gate 
34917c478bd9Sstevel@tonic-gate 
34927c478bd9Sstevel@tonic-gate /*
34937c478bd9Sstevel@tonic-gate  * pack_abort_cmd_request:
34947c478bd9Sstevel@tonic-gate  *
34957c478bd9Sstevel@tonic-gate  * Handle packing an abort request message.
34967c478bd9Sstevel@tonic-gate  */
34977c478bd9Sstevel@tonic-gate static int
pack_abort_cmd_request(abort_cmd_params_t * params,char ** buf,int * buf_size)34987c478bd9Sstevel@tonic-gate pack_abort_cmd_request(abort_cmd_params_t *params, char **buf, int *buf_size)
34997c478bd9Sstevel@tonic-gate {
35007c478bd9Sstevel@tonic-gate 	rdr_abort_cmd_t		abort_cmd_data;
35017c478bd9Sstevel@tonic-gate 
35027c478bd9Sstevel@tonic-gate 
35037c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
35047c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
35057c478bd9Sstevel@tonic-gate 	}
35067c478bd9Sstevel@tonic-gate 
35077c478bd9Sstevel@tonic-gate 	/*
35087c478bd9Sstevel@tonic-gate 	 * Collect size info specific to the abort cmd request
35097c478bd9Sstevel@tonic-gate 	 * message and allocate a buffer
35107c478bd9Sstevel@tonic-gate 	 */
35117c478bd9Sstevel@tonic-gate 	*buf_size = sizeof (rdr_abort_cmd_t);
35127c478bd9Sstevel@tonic-gate 
35137c478bd9Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
35147c478bd9Sstevel@tonic-gate 	if (*buf == NULL) {
35157c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
35167c478bd9Sstevel@tonic-gate 	}
35177c478bd9Sstevel@tonic-gate 
35187c478bd9Sstevel@tonic-gate 	/*
35197c478bd9Sstevel@tonic-gate 	 * Set fixed session identifier
35207c478bd9Sstevel@tonic-gate 	 */
35217c478bd9Sstevel@tonic-gate 	abort_cmd_data.session_id = params->session_id;
35227c478bd9Sstevel@tonic-gate 
35237c478bd9Sstevel@tonic-gate 	/*
35247c478bd9Sstevel@tonic-gate 	 * Copy information using memcpy
35257c478bd9Sstevel@tonic-gate 	 */
35267c478bd9Sstevel@tonic-gate 	(void) memcpy(*buf, &abort_cmd_data, sizeof (rdr_abort_cmd_t));
35277c478bd9Sstevel@tonic-gate 
35287c478bd9Sstevel@tonic-gate 	return (RDR_OK);
35297c478bd9Sstevel@tonic-gate }
35307c478bd9Sstevel@tonic-gate 
35317c478bd9Sstevel@tonic-gate 
35327c478bd9Sstevel@tonic-gate /*
35337c478bd9Sstevel@tonic-gate  * unpack_abort_cmd_request:
35347c478bd9Sstevel@tonic-gate  *
35357c478bd9Sstevel@tonic-gate  * Handle unpacking an abort request message.
35367c478bd9Sstevel@tonic-gate  */
35377c478bd9Sstevel@tonic-gate static int
unpack_abort_cmd_request(abort_cmd_params_t * params,const char * buf)35387c478bd9Sstevel@tonic-gate unpack_abort_cmd_request(abort_cmd_params_t *params, const char *buf)
35397c478bd9Sstevel@tonic-gate {
35407c478bd9Sstevel@tonic-gate 	rdr_abort_cmd_t		*abort_cmd_datap;
35417c478bd9Sstevel@tonic-gate 
35427c478bd9Sstevel@tonic-gate 
35437c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
35447c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
35457c478bd9Sstevel@tonic-gate 	}
35467c478bd9Sstevel@tonic-gate 
35477c478bd9Sstevel@tonic-gate 	/* LINTED Pointer Cast Alignment Warning */
35487c478bd9Sstevel@tonic-gate 	abort_cmd_datap = (rdr_abort_cmd_t *)buf;
35497c478bd9Sstevel@tonic-gate 
35507c478bd9Sstevel@tonic-gate 	/*
35517c478bd9Sstevel@tonic-gate 	 * copy out the session information
35527c478bd9Sstevel@tonic-gate 	 */
35537c478bd9Sstevel@tonic-gate 
35547c478bd9Sstevel@tonic-gate 	params->session_id = abort_cmd_datap->session_id;
35557c478bd9Sstevel@tonic-gate 
35567c478bd9Sstevel@tonic-gate 	return (RDR_OK);
35577c478bd9Sstevel@tonic-gate }
35587c478bd9Sstevel@tonic-gate 
35597c478bd9Sstevel@tonic-gate 
35607c478bd9Sstevel@tonic-gate /*
35617c478bd9Sstevel@tonic-gate  * pack_confirm_request:
35627c478bd9Sstevel@tonic-gate  *
35637c478bd9Sstevel@tonic-gate  * Handle packing a confirm callback request.
35647c478bd9Sstevel@tonic-gate  */
35657c478bd9Sstevel@tonic-gate static int
pack_confirm_request(confirm_callback_params_t * params,char ** buf,int * buf_size)35667c478bd9Sstevel@tonic-gate pack_confirm_request(confirm_callback_params_t *params, char **buf,
35677c478bd9Sstevel@tonic-gate     int *buf_size)
35687c478bd9Sstevel@tonic-gate {
35697c478bd9Sstevel@tonic-gate 	int				i;
35707c478bd9Sstevel@tonic-gate 	char				*bufptr;
35717c478bd9Sstevel@tonic-gate 	rdr_confirm_callback_t		confirm_callback_data;
35727c478bd9Sstevel@tonic-gate 	int 				message_strlen;
35737c478bd9Sstevel@tonic-gate 	int 				message_pad_sz;
35747c478bd9Sstevel@tonic-gate 
35757c478bd9Sstevel@tonic-gate 
35767c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
35777c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
35787c478bd9Sstevel@tonic-gate 	}
35797c478bd9Sstevel@tonic-gate 
35807c478bd9Sstevel@tonic-gate 	/*
35817c478bd9Sstevel@tonic-gate 	 * Set variable length fields and make a call to partially
35827c478bd9Sstevel@tonic-gate 	 * pack it.
35837c478bd9Sstevel@tonic-gate 	 */
35847c478bd9Sstevel@tonic-gate 	if (params->message != NULL) {
35857c478bd9Sstevel@tonic-gate 		message_strlen = strlen(params->message) + 1;
35867c478bd9Sstevel@tonic-gate 		message_pad_sz = RDR_ALIGN_64_BIT -
35877c478bd9Sstevel@tonic-gate 		    (message_strlen % RDR_ALIGN_64_BIT);
35887c478bd9Sstevel@tonic-gate 	} else {
35897c478bd9Sstevel@tonic-gate 		message_strlen = 0;
35907c478bd9Sstevel@tonic-gate 		message_pad_sz = 0;
35917c478bd9Sstevel@tonic-gate 	}
35927c478bd9Sstevel@tonic-gate 
35937c478bd9Sstevel@tonic-gate 
35947c478bd9Sstevel@tonic-gate 	/*
35957c478bd9Sstevel@tonic-gate 	 * Collect size info specific to the confirm callback request
35967c478bd9Sstevel@tonic-gate 	 * message and allocate a buffer
35977c478bd9Sstevel@tonic-gate 	 */
35987c478bd9Sstevel@tonic-gate 	*buf_size = sizeof (rdr_confirm_callback_t);
35997c478bd9Sstevel@tonic-gate 	*buf_size += message_strlen;
36007c478bd9Sstevel@tonic-gate 	*buf_size += message_pad_sz;
36017c478bd9Sstevel@tonic-gate 
36027c478bd9Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
36037c478bd9Sstevel@tonic-gate 	if (*buf == NULL) {
36047c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
36057c478bd9Sstevel@tonic-gate 	}
36067c478bd9Sstevel@tonic-gate 
36077c478bd9Sstevel@tonic-gate 	/*
36087c478bd9Sstevel@tonic-gate 	 * Set fixed address labels by name
36097c478bd9Sstevel@tonic-gate 	 */
36107c478bd9Sstevel@tonic-gate 	if (params->confp != NULL) {
36117c478bd9Sstevel@tonic-gate 		confirm_callback_data.confirm_callback_id =
36127c478bd9Sstevel@tonic-gate 		    (unsigned long)params->confp->confirm;
36137c478bd9Sstevel@tonic-gate 		confirm_callback_data.appdata_ptr =
36147c478bd9Sstevel@tonic-gate 		    (unsigned long)params->confp->appdata_ptr;
36157c478bd9Sstevel@tonic-gate 	} else {
36167c478bd9Sstevel@tonic-gate 		confirm_callback_data.confirm_callback_id = 0;
36177c478bd9Sstevel@tonic-gate 		confirm_callback_data.appdata_ptr = 0;
36187c478bd9Sstevel@tonic-gate 	}
36197c478bd9Sstevel@tonic-gate 	confirm_callback_data.message_size = message_strlen + message_pad_sz;
36207c478bd9Sstevel@tonic-gate 
36217c478bd9Sstevel@tonic-gate 	/*
36227c478bd9Sstevel@tonic-gate 	 * Set variable information using memcpy
36237c478bd9Sstevel@tonic-gate 	 */
36247c478bd9Sstevel@tonic-gate 	bufptr = *buf;
36257c478bd9Sstevel@tonic-gate 	(void) memcpy(bufptr, &confirm_callback_data,
36267c478bd9Sstevel@tonic-gate 	    sizeof (rdr_confirm_callback_t));
36277c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_confirm_callback_t);
36287c478bd9Sstevel@tonic-gate 
36297c478bd9Sstevel@tonic-gate 	if (params->message != NULL) {
36307c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, params->message, message_strlen);
36317c478bd9Sstevel@tonic-gate 		bufptr += message_strlen;
36327c478bd9Sstevel@tonic-gate 		for (i = 0; i < message_pad_sz; i++) {
36337c478bd9Sstevel@tonic-gate 			bufptr[i] = 0;
36347c478bd9Sstevel@tonic-gate 		}
36357c478bd9Sstevel@tonic-gate 		bufptr += message_pad_sz;
36367c478bd9Sstevel@tonic-gate 	}
36377c478bd9Sstevel@tonic-gate 
36387c478bd9Sstevel@tonic-gate 	return (RDR_OK);
36397c478bd9Sstevel@tonic-gate }
36407c478bd9Sstevel@tonic-gate 
36417c478bd9Sstevel@tonic-gate 
36427c478bd9Sstevel@tonic-gate /*
36437c478bd9Sstevel@tonic-gate  * unpack_confirm_request:
36447c478bd9Sstevel@tonic-gate  *
36457c478bd9Sstevel@tonic-gate  * Handle unpacking a confirm callback request.
36467c478bd9Sstevel@tonic-gate  */
36477c478bd9Sstevel@tonic-gate static int
unpack_confirm_request(confirm_callback_params_t * params,const char * buf)36487c478bd9Sstevel@tonic-gate unpack_confirm_request(confirm_callback_params_t *params, const char *buf)
36497c478bd9Sstevel@tonic-gate {
36507c478bd9Sstevel@tonic-gate 	char				*bufptr;
36517c478bd9Sstevel@tonic-gate 	rdr_confirm_callback_t		confirm_callback_data;
36527c478bd9Sstevel@tonic-gate 
36537c478bd9Sstevel@tonic-gate 
36547c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
36557c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
36567c478bd9Sstevel@tonic-gate 	}
36577c478bd9Sstevel@tonic-gate 
36587c478bd9Sstevel@tonic-gate 	bufptr = (char *)buf;
36597c478bd9Sstevel@tonic-gate 	(void) memcpy(&confirm_callback_data, bufptr,
36607c478bd9Sstevel@tonic-gate 	    sizeof (rdr_confirm_callback_t));
36617c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_confirm_callback_t);
36627c478bd9Sstevel@tonic-gate 
36637c478bd9Sstevel@tonic-gate 	/*
36647c478bd9Sstevel@tonic-gate 	 * handle getting the message text
36657c478bd9Sstevel@tonic-gate 	 */
36667c478bd9Sstevel@tonic-gate 	if (get_string_from_buf(&(params->message),
36677c478bd9Sstevel@tonic-gate 	    confirm_callback_data.message_size, bufptr)) {
36687c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
36697c478bd9Sstevel@tonic-gate 	}
36707c478bd9Sstevel@tonic-gate 	bufptr += confirm_callback_data.message_size;
36717c478bd9Sstevel@tonic-gate 
36727c478bd9Sstevel@tonic-gate 	/*
36737c478bd9Sstevel@tonic-gate 	 * Set fixed address labels by name
36747c478bd9Sstevel@tonic-gate 	 */
36757c478bd9Sstevel@tonic-gate 	params->confp = (struct cfga_confirm *)
36767c478bd9Sstevel@tonic-gate 	    malloc(sizeof (struct cfga_confirm));
36777c478bd9Sstevel@tonic-gate 	if (params->confp == NULL) {
36787c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
36797c478bd9Sstevel@tonic-gate 	}
36807c478bd9Sstevel@tonic-gate 
36817c478bd9Sstevel@tonic-gate 	/* set params->confp->confirm using memcpy */
36827c478bd9Sstevel@tonic-gate 	(void) memcpy((void*)params->confp,
36837c478bd9Sstevel@tonic-gate 	    &(confirm_callback_data.confirm_callback_id),
36847c478bd9Sstevel@tonic-gate 	    sizeof (unsigned long));
36857c478bd9Sstevel@tonic-gate 
36867c478bd9Sstevel@tonic-gate 	params->confp->appdata_ptr =
36877c478bd9Sstevel@tonic-gate 	    (void*)confirm_callback_data.appdata_ptr;
36887c478bd9Sstevel@tonic-gate 
36897c478bd9Sstevel@tonic-gate 	return (RDR_OK);
36907c478bd9Sstevel@tonic-gate }
36917c478bd9Sstevel@tonic-gate 
36927c478bd9Sstevel@tonic-gate 
36937c478bd9Sstevel@tonic-gate /*
36947c478bd9Sstevel@tonic-gate  * pack_confirm_reply:
36957c478bd9Sstevel@tonic-gate  *
36967c478bd9Sstevel@tonic-gate  * Handle packing a confirm callback reply.
36977c478bd9Sstevel@tonic-gate  */
36987c478bd9Sstevel@tonic-gate static int
pack_confirm_reply(confirm_callback_params_t * params,char ** buf,int * buf_size)36997c478bd9Sstevel@tonic-gate pack_confirm_reply(confirm_callback_params_t *params, char **buf, int *buf_size)
37007c478bd9Sstevel@tonic-gate {
37017c478bd9Sstevel@tonic-gate 	char				*bufptr;
37027c478bd9Sstevel@tonic-gate 	rdr_confirm_callback_reply_t	confirm_callback_data;
37037c478bd9Sstevel@tonic-gate 
37047c478bd9Sstevel@tonic-gate 
37057c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
37067c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
37077c478bd9Sstevel@tonic-gate 	}
37087c478bd9Sstevel@tonic-gate 
37097c478bd9Sstevel@tonic-gate 	/*
37107c478bd9Sstevel@tonic-gate 	 * Collect size info specific to the confirm callback reply
37117c478bd9Sstevel@tonic-gate 	 * message and allocate a buffer
37127c478bd9Sstevel@tonic-gate 	 */
37137c478bd9Sstevel@tonic-gate 	*buf_size = sizeof (confirm_callback_params_t);
37147c478bd9Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
37157c478bd9Sstevel@tonic-gate 	if (*buf == NULL) {
37167c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
37177c478bd9Sstevel@tonic-gate 	}
37187c478bd9Sstevel@tonic-gate 
37197c478bd9Sstevel@tonic-gate 	/*
37207c478bd9Sstevel@tonic-gate 	 * Set fixed address labels by name
37217c478bd9Sstevel@tonic-gate 	 */
37227c478bd9Sstevel@tonic-gate 	if (params->confp != NULL) {
37237c478bd9Sstevel@tonic-gate 		confirm_callback_data.confirm_callback_id =
37247c478bd9Sstevel@tonic-gate 		    (unsigned long)params->confp->confirm;
37257c478bd9Sstevel@tonic-gate 		confirm_callback_data.appdata_ptr =
37267c478bd9Sstevel@tonic-gate 		    (unsigned long)params->confp->appdata_ptr;
37277c478bd9Sstevel@tonic-gate 	} else {
37287c478bd9Sstevel@tonic-gate 		confirm_callback_data.confirm_callback_id = 0;
37297c478bd9Sstevel@tonic-gate 		confirm_callback_data.appdata_ptr = 0;
37307c478bd9Sstevel@tonic-gate 	}
37317c478bd9Sstevel@tonic-gate 	confirm_callback_data.response = params->response;
37327c478bd9Sstevel@tonic-gate 
37337c478bd9Sstevel@tonic-gate 	/*
37347c478bd9Sstevel@tonic-gate 	 * Set variable information using memcpy
37357c478bd9Sstevel@tonic-gate 	 */
37367c478bd9Sstevel@tonic-gate 	bufptr = *buf;
37377c478bd9Sstevel@tonic-gate 
37387c478bd9Sstevel@tonic-gate 	(void) memcpy(bufptr, &confirm_callback_data,
37397c478bd9Sstevel@tonic-gate 	    sizeof (rdr_confirm_callback_reply_t));
37407c478bd9Sstevel@tonic-gate 
37417c478bd9Sstevel@tonic-gate 	return (RDR_OK);
37427c478bd9Sstevel@tonic-gate }
37437c478bd9Sstevel@tonic-gate 
37447c478bd9Sstevel@tonic-gate 
37457c478bd9Sstevel@tonic-gate /*
37467c478bd9Sstevel@tonic-gate  * unpack_confirm_reply:
37477c478bd9Sstevel@tonic-gate  *
37487c478bd9Sstevel@tonic-gate  * Handle unpacking a confirm callback reply.
37497c478bd9Sstevel@tonic-gate  */
37507c478bd9Sstevel@tonic-gate static int
unpack_confirm_reply(confirm_callback_params_t * params,const char * buf)37517c478bd9Sstevel@tonic-gate unpack_confirm_reply(confirm_callback_params_t *params, const char *buf)
37527c478bd9Sstevel@tonic-gate {
37537c478bd9Sstevel@tonic-gate 	char				*bufptr;
37547c478bd9Sstevel@tonic-gate 	rdr_confirm_callback_reply_t	confirm_callback_data;
37557c478bd9Sstevel@tonic-gate 
37567c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
37577c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
37587c478bd9Sstevel@tonic-gate 	}
37597c478bd9Sstevel@tonic-gate 
37607c478bd9Sstevel@tonic-gate 	bufptr = (char *)buf;
37617c478bd9Sstevel@tonic-gate 	(void) memcpy(&confirm_callback_data, bufptr,
37627c478bd9Sstevel@tonic-gate 	    sizeof (rdr_confirm_callback_reply_t));
37637c478bd9Sstevel@tonic-gate 	bufptr += sizeof (confirm_callback_params_t);
37647c478bd9Sstevel@tonic-gate 
37657c478bd9Sstevel@tonic-gate 	/*
37667c478bd9Sstevel@tonic-gate 	 * Set fixed address labels by name
37677c478bd9Sstevel@tonic-gate 	 */
37687c478bd9Sstevel@tonic-gate 	params->confp = (struct cfga_confirm *)
37697c478bd9Sstevel@tonic-gate 	    malloc(sizeof (struct cfga_confirm));
37707c478bd9Sstevel@tonic-gate 	if (params->confp == NULL) {
37717c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
37727c478bd9Sstevel@tonic-gate 	}
37737c478bd9Sstevel@tonic-gate 
37747c478bd9Sstevel@tonic-gate 	/* set params->confp->confirm using memcpy */
37757c478bd9Sstevel@tonic-gate 	(void) memcpy((void*)params->confp,
37767c478bd9Sstevel@tonic-gate 	    &(confirm_callback_data.confirm_callback_id),
37777c478bd9Sstevel@tonic-gate 	    sizeof (unsigned long));
37787c478bd9Sstevel@tonic-gate 
37797c478bd9Sstevel@tonic-gate 	params->confp->appdata_ptr =
37807c478bd9Sstevel@tonic-gate 	    (void*)confirm_callback_data.appdata_ptr;
37817c478bd9Sstevel@tonic-gate 	params->response = confirm_callback_data.response;
37827c478bd9Sstevel@tonic-gate 
37837c478bd9Sstevel@tonic-gate 	return (RDR_OK);
37847c478bd9Sstevel@tonic-gate }
37857c478bd9Sstevel@tonic-gate 
37867c478bd9Sstevel@tonic-gate 
37877c478bd9Sstevel@tonic-gate /*
37887c478bd9Sstevel@tonic-gate  * pack_message_request:
37897c478bd9Sstevel@tonic-gate  *
37907c478bd9Sstevel@tonic-gate  * Handle packing a message callback request.
37917c478bd9Sstevel@tonic-gate  */
37927c478bd9Sstevel@tonic-gate static int
pack_message_request(msg_callback_params_t * params,char ** buf,int * buf_size)37937c478bd9Sstevel@tonic-gate pack_message_request(msg_callback_params_t *params, char **buf, int *buf_size)
37947c478bd9Sstevel@tonic-gate {
37957c478bd9Sstevel@tonic-gate 	int			i;
37967c478bd9Sstevel@tonic-gate 	char			*bufptr;
37977c478bd9Sstevel@tonic-gate 	rdr_msg_callback_t	msg_callback_data;
37987c478bd9Sstevel@tonic-gate 	int			message_strlen;
37997c478bd9Sstevel@tonic-gate 	int			message_pad_sz;
38007c478bd9Sstevel@tonic-gate 
38017c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
38027c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
38037c478bd9Sstevel@tonic-gate 	}
38047c478bd9Sstevel@tonic-gate 
38057c478bd9Sstevel@tonic-gate 	/*
38067c478bd9Sstevel@tonic-gate 	 * Set variable length fields and make a call to partially
38077c478bd9Sstevel@tonic-gate 	 * pack it.
38087c478bd9Sstevel@tonic-gate 	 */
38097c478bd9Sstevel@tonic-gate 	if (params->message != NULL) {
38107c478bd9Sstevel@tonic-gate 		message_strlen = strlen(params->message) + 1;
38117c478bd9Sstevel@tonic-gate 		message_pad_sz = RDR_ALIGN_64_BIT -
38127c478bd9Sstevel@tonic-gate 		    (message_strlen % RDR_ALIGN_64_BIT);
38137c478bd9Sstevel@tonic-gate 	} else {
38147c478bd9Sstevel@tonic-gate 		message_strlen = 0;
38157c478bd9Sstevel@tonic-gate 		message_pad_sz = 0;
38167c478bd9Sstevel@tonic-gate 	}
38177c478bd9Sstevel@tonic-gate 
38187c478bd9Sstevel@tonic-gate 
38197c478bd9Sstevel@tonic-gate 	/*
38207c478bd9Sstevel@tonic-gate 	 * Collect size info specific to the message callback request
38217c478bd9Sstevel@tonic-gate 	 * message and allocate a buffer
38227c478bd9Sstevel@tonic-gate 	 */
38237c478bd9Sstevel@tonic-gate 	*buf_size = sizeof (rdr_msg_callback_t);
38247c478bd9Sstevel@tonic-gate 	*buf_size += message_strlen;
38257c478bd9Sstevel@tonic-gate 	*buf_size += message_pad_sz;
38267c478bd9Sstevel@tonic-gate 
38277c478bd9Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
38287c478bd9Sstevel@tonic-gate 	if (*buf == NULL) {
38297c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
38307c478bd9Sstevel@tonic-gate 	}
38317c478bd9Sstevel@tonic-gate 
38327c478bd9Sstevel@tonic-gate 	/*
38337c478bd9Sstevel@tonic-gate 	 * Set fixed address labels by name
38347c478bd9Sstevel@tonic-gate 	 */
38357c478bd9Sstevel@tonic-gate 	if (params->msgp != NULL) {
38367c478bd9Sstevel@tonic-gate 		msg_callback_data.msg_callback_id =
38377c478bd9Sstevel@tonic-gate 		    (unsigned long)params->msgp->message_routine;
38387c478bd9Sstevel@tonic-gate 		msg_callback_data.appdata_ptr =
38397c478bd9Sstevel@tonic-gate 		    (unsigned long)params->msgp->appdata_ptr;
38407c478bd9Sstevel@tonic-gate 	} else {
38417c478bd9Sstevel@tonic-gate 		msg_callback_data.msg_callback_id = 0;
38427c478bd9Sstevel@tonic-gate 		msg_callback_data.appdata_ptr = 0;
38437c478bd9Sstevel@tonic-gate 	}
38447c478bd9Sstevel@tonic-gate 	msg_callback_data.message_size = message_strlen + message_pad_sz;
38457c478bd9Sstevel@tonic-gate 
38467c478bd9Sstevel@tonic-gate 	/*
38477c478bd9Sstevel@tonic-gate 	 * Set variable information using memcpy
38487c478bd9Sstevel@tonic-gate 	 */
38497c478bd9Sstevel@tonic-gate 	bufptr = *buf;
38507c478bd9Sstevel@tonic-gate 
38517c478bd9Sstevel@tonic-gate 	(void) memcpy(bufptr, &msg_callback_data, sizeof (rdr_msg_callback_t));
38527c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_msg_callback_t);
38537c478bd9Sstevel@tonic-gate 
38547c478bd9Sstevel@tonic-gate 	if (params->message != NULL) {
38557c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, params->message, message_strlen);
38567c478bd9Sstevel@tonic-gate 		bufptr += message_strlen;
38577c478bd9Sstevel@tonic-gate 		for (i = 0; i < message_pad_sz; i++) {
38587c478bd9Sstevel@tonic-gate 			bufptr[i] = 0;
38597c478bd9Sstevel@tonic-gate 		}
38607c478bd9Sstevel@tonic-gate 		bufptr += message_pad_sz;
38617c478bd9Sstevel@tonic-gate 	}
38627c478bd9Sstevel@tonic-gate 
38637c478bd9Sstevel@tonic-gate 	return (RDR_OK);
38647c478bd9Sstevel@tonic-gate }
38657c478bd9Sstevel@tonic-gate 
38667c478bd9Sstevel@tonic-gate 
38677c478bd9Sstevel@tonic-gate /*
38687c478bd9Sstevel@tonic-gate  * unpack_message_request:
38697c478bd9Sstevel@tonic-gate  *
38707c478bd9Sstevel@tonic-gate  * Handle unpacking a message callback request.
38717c478bd9Sstevel@tonic-gate  */
38727c478bd9Sstevel@tonic-gate static int
unpack_message_request(msg_callback_params_t * params,const char * buf)38737c478bd9Sstevel@tonic-gate unpack_message_request(msg_callback_params_t *params, const char *buf)
38747c478bd9Sstevel@tonic-gate {
38757c478bd9Sstevel@tonic-gate 	char			*bufptr;
38767c478bd9Sstevel@tonic-gate 	rdr_msg_callback_t	msg_callback_data;
38777c478bd9Sstevel@tonic-gate 
38787c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
38797c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
38807c478bd9Sstevel@tonic-gate 	}
38817c478bd9Sstevel@tonic-gate 
38827c478bd9Sstevel@tonic-gate 	bufptr = (char *)buf;
38837c478bd9Sstevel@tonic-gate 	(void) memcpy(&msg_callback_data, bufptr, sizeof (rdr_msg_callback_t));
38847c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_msg_callback_t);
38857c478bd9Sstevel@tonic-gate 
38867c478bd9Sstevel@tonic-gate 	/*
38877c478bd9Sstevel@tonic-gate 	 * handle getting the message text
38887c478bd9Sstevel@tonic-gate 	 */
38897c478bd9Sstevel@tonic-gate 	if (get_string_from_buf(&(params->message),
38907c478bd9Sstevel@tonic-gate 	    msg_callback_data.message_size, bufptr)) {
38917c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
38927c478bd9Sstevel@tonic-gate 	}
38937c478bd9Sstevel@tonic-gate 	bufptr += msg_callback_data.message_size;
38947c478bd9Sstevel@tonic-gate 
38957c478bd9Sstevel@tonic-gate 	/*
38967c478bd9Sstevel@tonic-gate 	 * Set fixed address labels by name
38977c478bd9Sstevel@tonic-gate 	 */
38987c478bd9Sstevel@tonic-gate 	params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg));
38997c478bd9Sstevel@tonic-gate 	if (params->msgp == NULL) {
39007c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
39017c478bd9Sstevel@tonic-gate 	}
39027c478bd9Sstevel@tonic-gate 
39037c478bd9Sstevel@tonic-gate 	/* set params->msgp->message_routine using memcpy */
39047c478bd9Sstevel@tonic-gate 	(void) memcpy((void*)params->msgp, &(msg_callback_data.msg_callback_id),
39057c478bd9Sstevel@tonic-gate 	    sizeof (unsigned long));
39067c478bd9Sstevel@tonic-gate 
39077c478bd9Sstevel@tonic-gate 	params->msgp->appdata_ptr = (void*)msg_callback_data.appdata_ptr;
39087c478bd9Sstevel@tonic-gate 
39097c478bd9Sstevel@tonic-gate 	return (RDR_OK);
39107c478bd9Sstevel@tonic-gate }
39117c478bd9Sstevel@tonic-gate 
39127c478bd9Sstevel@tonic-gate /*
39137c478bd9Sstevel@tonic-gate  * pack_rsrc_info_request:
39147c478bd9Sstevel@tonic-gate  *
39157c478bd9Sstevel@tonic-gate  * Handle packing a resource info request.
39167c478bd9Sstevel@tonic-gate  */
39177c478bd9Sstevel@tonic-gate static int
pack_rsrc_info_request(rsrc_info_params_t * params,char ** buf,int * buf_size)39187c478bd9Sstevel@tonic-gate pack_rsrc_info_request(rsrc_info_params_t *params, char **buf, int *buf_size)
39197c478bd9Sstevel@tonic-gate {
39207c478bd9Sstevel@tonic-gate 	char				*bufptr;
39217c478bd9Sstevel@tonic-gate 	rdr_rsrc_info_t			rsrc_info_data;
39227c478bd9Sstevel@tonic-gate 	rdr_variable_message_info_t 	var_msg_info;
39237c478bd9Sstevel@tonic-gate 
39247c478bd9Sstevel@tonic-gate 
39257c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
39267c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
39277c478bd9Sstevel@tonic-gate 	}
39287c478bd9Sstevel@tonic-gate 
39297c478bd9Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
39307c478bd9Sstevel@tonic-gate 
39317c478bd9Sstevel@tonic-gate 	/*
39327c478bd9Sstevel@tonic-gate 	 * Set variable length fields and make a call to partially
39337c478bd9Sstevel@tonic-gate 	 * pack it.
39347c478bd9Sstevel@tonic-gate 	 */
39357c478bd9Sstevel@tonic-gate 	if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) {
39367c478bd9Sstevel@tonic-gate 		cleanup_variable_ap_id_info(&var_msg_info);
39377c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
39387c478bd9Sstevel@tonic-gate 	}
39397c478bd9Sstevel@tonic-gate 
39407c478bd9Sstevel@tonic-gate 	/*
39417c478bd9Sstevel@tonic-gate 	 * Collect size info specific to the resource info request
39427c478bd9Sstevel@tonic-gate 	 * message and allocate a buffer.
39437c478bd9Sstevel@tonic-gate 	 */
39447c478bd9Sstevel@tonic-gate 	*buf_size = sizeof (rdr_rsrc_info_t);
39457c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.ap_id_int_size;
39467c478bd9Sstevel@tonic-gate 	*buf_size += var_msg_info.ap_id_char_size;
39477c478bd9Sstevel@tonic-gate 
39487c478bd9Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
39497c478bd9Sstevel@tonic-gate 	if (*buf == NULL) {
39507c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
39517c478bd9Sstevel@tonic-gate 	}
39527c478bd9Sstevel@tonic-gate 
39537c478bd9Sstevel@tonic-gate 	/*
39547c478bd9Sstevel@tonic-gate 	 * Set fixed address labels by name.
39557c478bd9Sstevel@tonic-gate 	 */
39567c478bd9Sstevel@tonic-gate 	rsrc_info_data.num_ap_ids = params->num_ap_ids;
39577c478bd9Sstevel@tonic-gate 	rsrc_info_data.ap_id_char_size = var_msg_info.ap_id_char_size;
39587c478bd9Sstevel@tonic-gate 	rsrc_info_data.flags = params->flags;
39597c478bd9Sstevel@tonic-gate 
39607c478bd9Sstevel@tonic-gate 	/*
39617c478bd9Sstevel@tonic-gate 	 * Set variable information using memcpy.
39627c478bd9Sstevel@tonic-gate 	 */
39637c478bd9Sstevel@tonic-gate 	bufptr = *buf;
39647c478bd9Sstevel@tonic-gate 
39657c478bd9Sstevel@tonic-gate 	(void) memcpy(bufptr, &rsrc_info_data, sizeof (rdr_rsrc_info_t));
39667c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_rsrc_info_t);
39677c478bd9Sstevel@tonic-gate 
39687c478bd9Sstevel@tonic-gate 	if (var_msg_info.ap_id_sizes != NULL) {
39697c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, var_msg_info.ap_id_sizes,
39707c478bd9Sstevel@tonic-gate 		    var_msg_info.ap_id_int_size);
39717c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.ap_id_int_size;
39727c478bd9Sstevel@tonic-gate 	}
39737c478bd9Sstevel@tonic-gate 
39747c478bd9Sstevel@tonic-gate 	if (var_msg_info.ap_id_chars != NULL) {
39757c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, var_msg_info.ap_id_chars,
39767c478bd9Sstevel@tonic-gate 		    var_msg_info.ap_id_char_size);
39777c478bd9Sstevel@tonic-gate 		bufptr += var_msg_info.ap_id_char_size;
39787c478bd9Sstevel@tonic-gate 	}
39797c478bd9Sstevel@tonic-gate 
39807c478bd9Sstevel@tonic-gate 	cleanup_variable_ap_id_info(&var_msg_info);
39817c478bd9Sstevel@tonic-gate 
39827c478bd9Sstevel@tonic-gate 	return (RDR_OK);
39837c478bd9Sstevel@tonic-gate }
39847c478bd9Sstevel@tonic-gate 
39857c478bd9Sstevel@tonic-gate 
39867c478bd9Sstevel@tonic-gate /*
39877c478bd9Sstevel@tonic-gate  * unpack_rsrc_info_request:
39887c478bd9Sstevel@tonic-gate  *
39897c478bd9Sstevel@tonic-gate  * Handle unpacking a resource info request message.
39907c478bd9Sstevel@tonic-gate  */
39917c478bd9Sstevel@tonic-gate static int
unpack_rsrc_info_request(rsrc_info_params_t * params,const char * buf)39927c478bd9Sstevel@tonic-gate unpack_rsrc_info_request(rsrc_info_params_t *params, const char *buf)
39937c478bd9Sstevel@tonic-gate {
39947c478bd9Sstevel@tonic-gate 	char				*bufptr;
39957c478bd9Sstevel@tonic-gate 	rdr_variable_message_info_t 	var_msg_info;
39967c478bd9Sstevel@tonic-gate 	rdr_rsrc_info_t			rsrc_info_data;
39977c478bd9Sstevel@tonic-gate 
39987c478bd9Sstevel@tonic-gate 
39997c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
40007c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
40017c478bd9Sstevel@tonic-gate 	}
40027c478bd9Sstevel@tonic-gate 
40037c478bd9Sstevel@tonic-gate 	(void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
40047c478bd9Sstevel@tonic-gate 
40057c478bd9Sstevel@tonic-gate 	bufptr = (char *)buf;
40067c478bd9Sstevel@tonic-gate 	(void) memcpy(&rsrc_info_data, bufptr, sizeof (rdr_rsrc_info_t));
40077c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_rsrc_info_t);
40087c478bd9Sstevel@tonic-gate 
40097c478bd9Sstevel@tonic-gate 	/*
40107c478bd9Sstevel@tonic-gate 	 * Handle getting the ap_ids.
40117c478bd9Sstevel@tonic-gate 	 */
40127c478bd9Sstevel@tonic-gate 	var_msg_info.ap_id_char_size = rsrc_info_data.ap_id_char_size;
40137c478bd9Sstevel@tonic-gate 	if (get_ap_ids_from_buf(&(params->ap_ids), rsrc_info_data.num_ap_ids,
40147c478bd9Sstevel@tonic-gate 	    &var_msg_info, bufptr)) {
40157c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
40167c478bd9Sstevel@tonic-gate 	}
40177c478bd9Sstevel@tonic-gate 	bufptr += var_msg_info.ap_id_int_size;
40187c478bd9Sstevel@tonic-gate 	bufptr += var_msg_info.ap_id_char_size;
40197c478bd9Sstevel@tonic-gate 
40207c478bd9Sstevel@tonic-gate 	/*
40217c478bd9Sstevel@tonic-gate 	 * Set fixed address labels by name.
40227c478bd9Sstevel@tonic-gate 	 */
40237c478bd9Sstevel@tonic-gate 	params->num_ap_ids = rsrc_info_data.num_ap_ids;
40247c478bd9Sstevel@tonic-gate 	params->flags = rsrc_info_data.flags;
40257c478bd9Sstevel@tonic-gate 
40267c478bd9Sstevel@tonic-gate 	return (RDR_OK);
40277c478bd9Sstevel@tonic-gate }
40287c478bd9Sstevel@tonic-gate 
40297c478bd9Sstevel@tonic-gate 
40307c478bd9Sstevel@tonic-gate /*
40317c478bd9Sstevel@tonic-gate  * pack_rsrc_info_reply:
40327c478bd9Sstevel@tonic-gate  *
40337c478bd9Sstevel@tonic-gate  * Handle packing a resource info reply message.
40347c478bd9Sstevel@tonic-gate  */
40357c478bd9Sstevel@tonic-gate static int
pack_rsrc_info_reply(rsrc_info_params_t * params,char ** buf,int * buf_size,int encoding)4036*25cf1a30Sjl139090 pack_rsrc_info_reply(rsrc_info_params_t *params, char **buf, int *buf_size,
4037*25cf1a30Sjl139090     int encoding)
40387c478bd9Sstevel@tonic-gate {
40397c478bd9Sstevel@tonic-gate 	char				*bufptr;
40407c478bd9Sstevel@tonic-gate 	rdr_rsrc_info_reply_t		rsrc_info_data;
40417c478bd9Sstevel@tonic-gate 	int				pack_status;
40427c478bd9Sstevel@tonic-gate 	caddr_t				rsrc_info_bufp = NULL;
40437c478bd9Sstevel@tonic-gate 	size_t 				rsrc_info_size;
40447c478bd9Sstevel@tonic-gate 
40457c478bd9Sstevel@tonic-gate 
40467c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
40477c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
40487c478bd9Sstevel@tonic-gate 	}
40497c478bd9Sstevel@tonic-gate 
40507c478bd9Sstevel@tonic-gate 	/*
40517c478bd9Sstevel@tonic-gate 	 * Pack snapshot handle data.
40527c478bd9Sstevel@tonic-gate 	 */
4053*25cf1a30Sjl139090 	pack_status = ri_pack(params->hdl, &rsrc_info_bufp, &rsrc_info_size,
4054*25cf1a30Sjl139090 	    encoding);
40557c478bd9Sstevel@tonic-gate 	if (pack_status != 0) {
40567c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
40577c478bd9Sstevel@tonic-gate 	}
40587c478bd9Sstevel@tonic-gate 
40597c478bd9Sstevel@tonic-gate 	/*
40607c478bd9Sstevel@tonic-gate 	 * Collect size info specific to the rsrc_info reply message
40617c478bd9Sstevel@tonic-gate 	 * and allocate a buffer.
40627c478bd9Sstevel@tonic-gate 	 */
40637c478bd9Sstevel@tonic-gate 	*buf_size = sizeof (rdr_rsrc_info_reply_t);
40647c478bd9Sstevel@tonic-gate 	*buf_size += rsrc_info_size;
40657c478bd9Sstevel@tonic-gate 
40667c478bd9Sstevel@tonic-gate 	*buf = (char *)malloc(*buf_size);
40677c478bd9Sstevel@tonic-gate 	if (*buf == NULL) {
40687c478bd9Sstevel@tonic-gate 		free(rsrc_info_bufp);
40697c478bd9Sstevel@tonic-gate 		return (RDR_MEM_ALLOC);
40707c478bd9Sstevel@tonic-gate 	}
40717c478bd9Sstevel@tonic-gate 
40727c478bd9Sstevel@tonic-gate 	/*
40737c478bd9Sstevel@tonic-gate 	 * Set fixed address labels by name.
40747c478bd9Sstevel@tonic-gate 	 */
40757c478bd9Sstevel@tonic-gate 	rsrc_info_data.packed_hdl_size = rsrc_info_size;
40767c478bd9Sstevel@tonic-gate 
40777c478bd9Sstevel@tonic-gate 	/*
40787c478bd9Sstevel@tonic-gate 	 * Set variable information using memcpy.
40797c478bd9Sstevel@tonic-gate 	 */
40807c478bd9Sstevel@tonic-gate 	bufptr = *buf;
40817c478bd9Sstevel@tonic-gate 
40827c478bd9Sstevel@tonic-gate 	(void) memcpy(bufptr, &rsrc_info_data, sizeof (rdr_rsrc_info_reply_t));
40837c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_rsrc_info_reply_t);
40847c478bd9Sstevel@tonic-gate 
40857c478bd9Sstevel@tonic-gate 	if (rsrc_info_bufp) {
40867c478bd9Sstevel@tonic-gate 		(void) memcpy(bufptr, rsrc_info_bufp, rsrc_info_size);
40877c478bd9Sstevel@tonic-gate 		free(rsrc_info_bufp);
40887c478bd9Sstevel@tonic-gate 	}
40897c478bd9Sstevel@tonic-gate 
40907c478bd9Sstevel@tonic-gate 	return (RDR_OK);
40917c478bd9Sstevel@tonic-gate }
40927c478bd9Sstevel@tonic-gate 
40937c478bd9Sstevel@tonic-gate 
40947c478bd9Sstevel@tonic-gate /*
40957c478bd9Sstevel@tonic-gate  * unpack_rsrc_info_reply:
40967c478bd9Sstevel@tonic-gate  *
40977c478bd9Sstevel@tonic-gate  * Handle unpacking a resource info reply message.
40987c478bd9Sstevel@tonic-gate  */
40997c478bd9Sstevel@tonic-gate static int
unpack_rsrc_info_reply(rsrc_info_params_t * params,const char * buf)41007c478bd9Sstevel@tonic-gate unpack_rsrc_info_reply(rsrc_info_params_t *params, const char *buf)
41017c478bd9Sstevel@tonic-gate {
41027c478bd9Sstevel@tonic-gate 	int			unpack_status;
41037c478bd9Sstevel@tonic-gate 	char 			*bufptr;
41047c478bd9Sstevel@tonic-gate 	rdr_rsrc_info_reply_t	rsrc_info_data;
41057c478bd9Sstevel@tonic-gate 
41067c478bd9Sstevel@tonic-gate 
41077c478bd9Sstevel@tonic-gate 	if ((params == NULL) || (buf == NULL)) {
41087c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
41097c478bd9Sstevel@tonic-gate 	}
41107c478bd9Sstevel@tonic-gate 
41117c478bd9Sstevel@tonic-gate 	bufptr = (char *)buf;
41127c478bd9Sstevel@tonic-gate 	(void) memcpy(&rsrc_info_data, bufptr, sizeof (rdr_rsrc_info_reply_t));
41137c478bd9Sstevel@tonic-gate 	bufptr += sizeof (rdr_rsrc_info_reply_t);
41147c478bd9Sstevel@tonic-gate 
41157c478bd9Sstevel@tonic-gate 	/*
41167c478bd9Sstevel@tonic-gate 	 * Unpack buf into resource info handle.
41177c478bd9Sstevel@tonic-gate 	 */
41187c478bd9Sstevel@tonic-gate 	unpack_status = ri_unpack(bufptr, rsrc_info_data.packed_hdl_size,
41197c478bd9Sstevel@tonic-gate 	    &params->hdl);
41207c478bd9Sstevel@tonic-gate 
41217c478bd9Sstevel@tonic-gate 	return ((unpack_status == 0) ? RDR_OK : RDR_ERROR);
41227c478bd9Sstevel@tonic-gate }
41237c478bd9Sstevel@tonic-gate 
41247c478bd9Sstevel@tonic-gate 
41257c478bd9Sstevel@tonic-gate /*
41267c478bd9Sstevel@tonic-gate  * pack_ap_ids:
41277c478bd9Sstevel@tonic-gate  *
41287c478bd9Sstevel@tonic-gate  * Pack a list of attachment point identifiers into a single buffer.
41297c478bd9Sstevel@tonic-gate  * This buffer is stored in the specified rdr_variable_message_info_t
41307c478bd9Sstevel@tonic-gate  * and is padded to be 64-bit aligned.
41317c478bd9Sstevel@tonic-gate  */
41327c478bd9Sstevel@tonic-gate static int
pack_ap_ids(int num_ap_ids,char * const * ap_ids,rdr_variable_message_info_t * var_msg_info)41337c478bd9Sstevel@tonic-gate pack_ap_ids(int num_ap_ids, char *const *ap_ids,
41347c478bd9Sstevel@tonic-gate     rdr_variable_message_info_t *var_msg_info)
41357c478bd9Sstevel@tonic-gate {
41367c478bd9Sstevel@tonic-gate 	int	i;
41377c478bd9Sstevel@tonic-gate 	int	ap_id_pad_sz;
41387c478bd9Sstevel@tonic-gate 	char	*bufptr;
41397c478bd9Sstevel@tonic-gate 
41407c478bd9Sstevel@tonic-gate 
41417c478bd9Sstevel@tonic-gate 	if (var_msg_info == NULL) {
41427c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
41437c478bd9Sstevel@tonic-gate 	}
41447c478bd9Sstevel@tonic-gate 
41457c478bd9Sstevel@tonic-gate 	/*
41467c478bd9Sstevel@tonic-gate 	 * NULL is a valid value for ap_ids in the list_ext
41477c478bd9Sstevel@tonic-gate 	 * case. For list_ext, no specified attachment points
41487c478bd9Sstevel@tonic-gate 	 * indicates that _all_ attachment points should be
41497c478bd9Sstevel@tonic-gate 	 * displayed. However, if ap_ids is NULL, num_ap_ids
41507c478bd9Sstevel@tonic-gate 	 * should be 0.
41517c478bd9Sstevel@tonic-gate 	 */
41527c478bd9Sstevel@tonic-gate 	if ((ap_ids == NULL) && (num_ap_ids != 0)) {
41537c478bd9Sstevel@tonic-gate 		num_ap_ids = 0;
41547c478bd9Sstevel@tonic-gate 	}
41557c478bd9Sstevel@tonic-gate 
41567c478bd9Sstevel@tonic-gate 	var_msg_info->ap_id_int_size = sizeof (int) * num_ap_ids;
41577c478bd9Sstevel@tonic-gate 	if (num_ap_ids > 0) {
41587c478bd9Sstevel@tonic-gate 		var_msg_info->ap_id_sizes = (int *)malloc(sizeof (int) *
41597c478bd9Sstevel@tonic-gate 		    var_msg_info->ap_id_int_size);
41607c478bd9Sstevel@tonic-gate 		if (var_msg_info->ap_id_sizes == NULL) {
41617c478bd9Sstevel@tonic-gate 			return (RDR_MEM_ALLOC);
41627c478bd9Sstevel@tonic-gate 		}
41637c478bd9Sstevel@tonic-gate 	}
41647c478bd9Sstevel@tonic-gate 	for (i = 0; i < num_ap_ids; i++) {
41657c478bd9Sstevel@tonic-gate 		if (ap_ids[i] != NULL) {
41667c478bd9Sstevel@tonic-gate 			var_msg_info->ap_id_sizes[i] = strlen(ap_ids[i]) + 1;
41677c478bd9Sstevel@tonic-gate 			var_msg_info->ap_id_char_size +=
41687c478bd9Sstevel@tonic-gate 			    var_msg_info->ap_id_sizes[i];
41697c478bd9Sstevel@tonic-gate 		}
41707c478bd9Sstevel@tonic-gate 	}
41717c478bd9Sstevel@tonic-gate 	if (var_msg_info->ap_id_char_size > 0) {
41727c478bd9Sstevel@tonic-gate 		ap_id_pad_sz = RDR_ALIGN_64_BIT -
41737c478bd9Sstevel@tonic-gate 		    (var_msg_info->ap_id_char_size % RDR_ALIGN_64_BIT);
41747c478bd9Sstevel@tonic-gate 		var_msg_info->ap_id_char_size += ap_id_pad_sz;
41757c478bd9Sstevel@tonic-gate 		var_msg_info->ap_id_chars = (char *)
41767c478bd9Sstevel@tonic-gate 		    malloc(var_msg_info->ap_id_char_size);
41777c478bd9Sstevel@tonic-gate 		if (var_msg_info->ap_id_chars == NULL) {
41787c478bd9Sstevel@tonic-gate 			return (RDR_MEM_ALLOC);
41797c478bd9Sstevel@tonic-gate 		}
41807c478bd9Sstevel@tonic-gate 
41817c478bd9Sstevel@tonic-gate 		bufptr = var_msg_info->ap_id_chars;
41827c478bd9Sstevel@tonic-gate 		for (i = 0; i < num_ap_ids; i++) {
41837c478bd9Sstevel@tonic-gate 			(void) memcpy(bufptr, ap_ids[i],
41847c478bd9Sstevel@tonic-gate 			    var_msg_info->ap_id_sizes[i]);
41857c478bd9Sstevel@tonic-gate 			bufptr += var_msg_info->ap_id_sizes[i];
41867c478bd9Sstevel@tonic-gate 		}
41877c478bd9Sstevel@tonic-gate 		for (i = 0; i < ap_id_pad_sz; i++) {
41887c478bd9Sstevel@tonic-gate 			bufptr[i] = 0;
41897c478bd9Sstevel@tonic-gate 		}
41907c478bd9Sstevel@tonic-gate 	} else {
41917c478bd9Sstevel@tonic-gate 		ap_id_pad_sz = 0;
41927c478bd9Sstevel@tonic-gate 	}
41937c478bd9Sstevel@tonic-gate 
41947c478bd9Sstevel@tonic-gate 	return (RDR_OK);
41957c478bd9Sstevel@tonic-gate }
41967c478bd9Sstevel@tonic-gate 
41977c478bd9Sstevel@tonic-gate 
41987c478bd9Sstevel@tonic-gate /*
41997c478bd9Sstevel@tonic-gate  * unpack_ap_ids:
42007c478bd9Sstevel@tonic-gate  *
42017c478bd9Sstevel@tonic-gate  * Unpack a buffer containing a concatenation of a list of
42027c478bd9Sstevel@tonic-gate  * attachment point identifiers. The resulting list of strings
42037c478bd9Sstevel@tonic-gate  * are stored in an array in the specified rdr_variable_message_info_t.
42047c478bd9Sstevel@tonic-gate  */
42057c478bd9Sstevel@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)42067c478bd9Sstevel@tonic-gate unpack_ap_ids(int num_ap_ids, char **ap_ids, const char *buf,
42077c478bd9Sstevel@tonic-gate     rdr_variable_message_info_t *var_msg_info)
42087c478bd9Sstevel@tonic-gate {
42097c478bd9Sstevel@tonic-gate 	int	i;
42107c478bd9Sstevel@tonic-gate 	int	ap_id_size;
42117c478bd9Sstevel@tonic-gate 	int	chars_copied;
42127c478bd9Sstevel@tonic-gate 	char	*bufptr;
42137c478bd9Sstevel@tonic-gate 
42147c478bd9Sstevel@tonic-gate 
42157c478bd9Sstevel@tonic-gate 	if ((ap_ids == NULL) || (buf == NULL) || (var_msg_info == NULL)) {
42167c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
42177c478bd9Sstevel@tonic-gate 	}
42187c478bd9Sstevel@tonic-gate 	bufptr = (char *)buf;
42197c478bd9Sstevel@tonic-gate 
42207c478bd9Sstevel@tonic-gate 	var_msg_info->ap_id_int_size = sizeof (int) * num_ap_ids;
42217c478bd9Sstevel@tonic-gate 	if (num_ap_ids > 0) {
42227c478bd9Sstevel@tonic-gate 		var_msg_info->ap_id_sizes = (int *)
42237c478bd9Sstevel@tonic-gate 		malloc(sizeof (int) * var_msg_info->ap_id_int_size);
42247c478bd9Sstevel@tonic-gate 		if (var_msg_info->ap_id_sizes == NULL) {
42257c478bd9Sstevel@tonic-gate 			return (RDR_MEM_ALLOC);
42267c478bd9Sstevel@tonic-gate 		}
42277c478bd9Sstevel@tonic-gate 		(void) memcpy(var_msg_info->ap_id_sizes, bufptr,
42287c478bd9Sstevel@tonic-gate 		    var_msg_info->ap_id_int_size);
42297c478bd9Sstevel@tonic-gate 	}
42307c478bd9Sstevel@tonic-gate 	bufptr += var_msg_info->ap_id_int_size;
42317c478bd9Sstevel@tonic-gate 
42327c478bd9Sstevel@tonic-gate 	chars_copied = 0;
42337c478bd9Sstevel@tonic-gate 	for (i = 0; i < num_ap_ids; i++) {
42347c478bd9Sstevel@tonic-gate 		ap_id_size = var_msg_info->ap_id_sizes[i];
42357c478bd9Sstevel@tonic-gate 		if (ap_id_size <= 0) {
42367c478bd9Sstevel@tonic-gate 			continue;
42377c478bd9Sstevel@tonic-gate 		}
42387c478bd9Sstevel@tonic-gate 		if ((chars_copied + ap_id_size) >
42397c478bd9Sstevel@tonic-gate 			var_msg_info->ap_id_char_size) {
42407c478bd9Sstevel@tonic-gate 			return (RDR_ERROR);
42417c478bd9Sstevel@tonic-gate 		}
42427c478bd9Sstevel@tonic-gate 		ap_ids[i] = (char *)malloc(ap_id_size);
42437c478bd9Sstevel@tonic-gate 		if (ap_ids[i] == NULL) {
42447c478bd9Sstevel@tonic-gate 			return (RDR_MEM_ALLOC);
42457c478bd9Sstevel@tonic-gate 		}
42467c478bd9Sstevel@tonic-gate 		(void) memcpy(ap_ids[i], bufptr, ap_id_size);
42477c478bd9Sstevel@tonic-gate 		bufptr += ap_id_size;
42487c478bd9Sstevel@tonic-gate 		chars_copied += ap_id_size;
42497c478bd9Sstevel@tonic-gate 	}
42507c478bd9Sstevel@tonic-gate 	return (RDR_OK);
42517c478bd9Sstevel@tonic-gate }
42527c478bd9Sstevel@tonic-gate 
42537c478bd9Sstevel@tonic-gate 
42547c478bd9Sstevel@tonic-gate /*
42557c478bd9Sstevel@tonic-gate  * find_options_sizes:
42567c478bd9Sstevel@tonic-gate  *
42577c478bd9Sstevel@tonic-gate  * Determine the size of a specified option string. The information
42587c478bd9Sstevel@tonic-gate  * is stored in the specified rdr_variable_message_info_t.
42597c478bd9Sstevel@tonic-gate  */
42607c478bd9Sstevel@tonic-gate static int
find_options_sizes(char * options,rdr_variable_message_info_t * var_msg_info)42617c478bd9Sstevel@tonic-gate find_options_sizes(char *options, rdr_variable_message_info_t *var_msg_info)
42627c478bd9Sstevel@tonic-gate {
42637c478bd9Sstevel@tonic-gate 	if (var_msg_info == NULL) {
42647c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
42657c478bd9Sstevel@tonic-gate 	}
42667c478bd9Sstevel@tonic-gate 	if (options != NULL) {
42677c478bd9Sstevel@tonic-gate 		var_msg_info->options_strlen = strlen(options) + 1;
42687c478bd9Sstevel@tonic-gate 		var_msg_info->options_pad_sz = RDR_ALIGN_64_BIT -
42697c478bd9Sstevel@tonic-gate 		    (var_msg_info->options_strlen % RDR_ALIGN_64_BIT);
42707c478bd9Sstevel@tonic-gate 	} else {
42717c478bd9Sstevel@tonic-gate 		var_msg_info->options_strlen = 0;
42727c478bd9Sstevel@tonic-gate 		var_msg_info->options_pad_sz = 0;
42737c478bd9Sstevel@tonic-gate 	}
42747c478bd9Sstevel@tonic-gate 	return (RDR_OK);
42757c478bd9Sstevel@tonic-gate }
42767c478bd9Sstevel@tonic-gate 
42777c478bd9Sstevel@tonic-gate 
42787c478bd9Sstevel@tonic-gate /*
42797c478bd9Sstevel@tonic-gate  * find_listopts_sizes:
42807c478bd9Sstevel@tonic-gate  *
42817c478bd9Sstevel@tonic-gate  * Determine the size of a specified list option string. The information
42827c478bd9Sstevel@tonic-gate  * is stored in the specified rdr_variable_message_info_t.
42837c478bd9Sstevel@tonic-gate  */
42847c478bd9Sstevel@tonic-gate static int
find_listopts_sizes(char * listopts,rdr_variable_message_info_t * var_msg_info)42857c478bd9Sstevel@tonic-gate find_listopts_sizes(char *listopts, rdr_variable_message_info_t *var_msg_info)
42867c478bd9Sstevel@tonic-gate {
42877c478bd9Sstevel@tonic-gate 	if (var_msg_info == NULL) {
42887c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
42897c478bd9Sstevel@tonic-gate 	}
42907c478bd9Sstevel@tonic-gate 	if (listopts != NULL) {
42917c478bd9Sstevel@tonic-gate 		var_msg_info->listopts_strlen = strlen(listopts) + 1;
42927c478bd9Sstevel@tonic-gate 		var_msg_info->listopts_pad_sz = RDR_ALIGN_64_BIT -
42937c478bd9Sstevel@tonic-gate 		    (var_msg_info->listopts_strlen % RDR_ALIGN_64_BIT);
42947c478bd9Sstevel@tonic-gate 	} else {
42957c478bd9Sstevel@tonic-gate 		var_msg_info->listopts_strlen = 0;
42967c478bd9Sstevel@tonic-gate 		var_msg_info->listopts_pad_sz = 0;
42977c478bd9Sstevel@tonic-gate 	}
42987c478bd9Sstevel@tonic-gate 	return (RDR_OK);
42997c478bd9Sstevel@tonic-gate }
43007c478bd9Sstevel@tonic-gate 
43017c478bd9Sstevel@tonic-gate 
43027c478bd9Sstevel@tonic-gate /*
43037c478bd9Sstevel@tonic-gate  * find_function_size:
43047c478bd9Sstevel@tonic-gate  *
43057c478bd9Sstevel@tonic-gate  * Determine the size of a specified private function string. The
43067c478bd9Sstevel@tonic-gate  * information is stored in the specified rdr_variable_message_info_t.
43077c478bd9Sstevel@tonic-gate  */
43087c478bd9Sstevel@tonic-gate static int
find_function_sizes(char * function,rdr_variable_message_info_t * var_msg_info)43097c478bd9Sstevel@tonic-gate find_function_sizes(char *function, rdr_variable_message_info_t *var_msg_info)
43107c478bd9Sstevel@tonic-gate {
43117c478bd9Sstevel@tonic-gate 	if (var_msg_info == NULL) {
43127c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
43137c478bd9Sstevel@tonic-gate 	}
43147c478bd9Sstevel@tonic-gate 	if (function != NULL) {
43157c478bd9Sstevel@tonic-gate 		var_msg_info->function_strlen = strlen(function) + 1;
43167c478bd9Sstevel@tonic-gate 		var_msg_info->function_pad_sz = RDR_ALIGN_64_BIT -
43177c478bd9Sstevel@tonic-gate 		    (var_msg_info->function_strlen % RDR_ALIGN_64_BIT);
43187c478bd9Sstevel@tonic-gate 	} else {
43197c478bd9Sstevel@tonic-gate 		var_msg_info->function_strlen = 0;
43207c478bd9Sstevel@tonic-gate 		var_msg_info->function_pad_sz = 0;
43217c478bd9Sstevel@tonic-gate 	}
43227c478bd9Sstevel@tonic-gate 	return (RDR_OK);
43237c478bd9Sstevel@tonic-gate }
43247c478bd9Sstevel@tonic-gate 
43257c478bd9Sstevel@tonic-gate 
43267c478bd9Sstevel@tonic-gate /*
43277c478bd9Sstevel@tonic-gate  * find_errstring_sizes:
43287c478bd9Sstevel@tonic-gate  *
43297c478bd9Sstevel@tonic-gate  * Determine the size of a specified error string. The information
43307c478bd9Sstevel@tonic-gate  * is stored in the specified rdr_variable_message_info_t.
43317c478bd9Sstevel@tonic-gate  */
43327c478bd9Sstevel@tonic-gate static int
find_errstring_sizes(char ** errstring,rdr_variable_message_info_t * var_msg_info)43337c478bd9Sstevel@tonic-gate find_errstring_sizes(char **errstring,
43347c478bd9Sstevel@tonic-gate     rdr_variable_message_info_t *var_msg_info)
43357c478bd9Sstevel@tonic-gate {
43367c478bd9Sstevel@tonic-gate 	if ((errstring != NULL) && (*errstring != NULL)) {
43377c478bd9Sstevel@tonic-gate 		var_msg_info->errstring_strlen = strlen(*errstring) + 1;
43387c478bd9Sstevel@tonic-gate 		var_msg_info->errstring_pad_sz = RDR_ALIGN_64_BIT -
43397c478bd9Sstevel@tonic-gate 		    (var_msg_info->errstring_strlen % RDR_ALIGN_64_BIT);
43407c478bd9Sstevel@tonic-gate 	} else {
43417c478bd9Sstevel@tonic-gate 		var_msg_info->errstring_strlen = 0;
43427c478bd9Sstevel@tonic-gate 		var_msg_info->errstring_pad_sz = 0;
43437c478bd9Sstevel@tonic-gate 	}
43447c478bd9Sstevel@tonic-gate 	return (RDR_OK);
43457c478bd9Sstevel@tonic-gate }
43467c478bd9Sstevel@tonic-gate 
43477c478bd9Sstevel@tonic-gate 
43487c478bd9Sstevel@tonic-gate /*
43497c478bd9Sstevel@tonic-gate  * get_ap_ids_from_buf:
43507c478bd9Sstevel@tonic-gate  *
43517c478bd9Sstevel@tonic-gate  * Unpack a buffer containing a concatenation of a list of attachment
43527c478bd9Sstevel@tonic-gate  * point identifiers. An appropriately sized buffer is allocated and
43537c478bd9Sstevel@tonic-gate  * the resulting list of strings are stored in an array in the specified
43547c478bd9Sstevel@tonic-gate  * rdr_variable_message_info_t.
43557c478bd9Sstevel@tonic-gate  */
43567c478bd9Sstevel@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)43577c478bd9Sstevel@tonic-gate get_ap_ids_from_buf(char ***ap_id_ptr, int num_ap_ids,
43587c478bd9Sstevel@tonic-gate     rdr_variable_message_info_t *var_msg_info, const char *buf)
43597c478bd9Sstevel@tonic-gate {
43607c478bd9Sstevel@tonic-gate 	if ((ap_id_ptr == NULL) || (buf == NULL) || (var_msg_info == NULL)) {
43617c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
43627c478bd9Sstevel@tonic-gate 	}
43637c478bd9Sstevel@tonic-gate 	if (num_ap_ids > 0) {
43647c478bd9Sstevel@tonic-gate 		*ap_id_ptr = (char **)malloc(sizeof (char *) * num_ap_ids);
43657c478bd9Sstevel@tonic-gate 		if (*ap_id_ptr == NULL) {
43667c478bd9Sstevel@tonic-gate 			return (RDR_MEM_ALLOC);
43677c478bd9Sstevel@tonic-gate 		}
43687c478bd9Sstevel@tonic-gate 		if (unpack_ap_ids(num_ap_ids, *ap_id_ptr, buf, var_msg_info)) {
43697c478bd9Sstevel@tonic-gate 			cleanup_variable_ap_id_info(var_msg_info);
43707c478bd9Sstevel@tonic-gate 			return (RDR_ERROR);
43717c478bd9Sstevel@tonic-gate 		}
43727c478bd9Sstevel@tonic-gate 
43737c478bd9Sstevel@tonic-gate 	} else if (num_ap_ids < 0) {
43747c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
43757c478bd9Sstevel@tonic-gate 	}
43767c478bd9Sstevel@tonic-gate 
43777c478bd9Sstevel@tonic-gate 	cleanup_variable_ap_id_info(var_msg_info);
43787c478bd9Sstevel@tonic-gate 
43797c478bd9Sstevel@tonic-gate 	return (RDR_OK);
43807c478bd9Sstevel@tonic-gate }
43817c478bd9Sstevel@tonic-gate 
43827c478bd9Sstevel@tonic-gate 
43837c478bd9Sstevel@tonic-gate /*
43847c478bd9Sstevel@tonic-gate  * get_string_from_buf:
43857c478bd9Sstevel@tonic-gate  *
43867c478bd9Sstevel@tonic-gate  * Copy a string to a new buffer. Memory is allocated for the
43877c478bd9Sstevel@tonic-gate  * new buffer and the original string is copied to the new buffer.
43887c478bd9Sstevel@tonic-gate  * This is primarily used when a string is located in a packed
43897c478bd9Sstevel@tonic-gate  * buffer that will eventually get deallocated.
43907c478bd9Sstevel@tonic-gate  */
43917c478bd9Sstevel@tonic-gate static int
get_string_from_buf(char ** stringptr,int strsize,const char * buf)43927c478bd9Sstevel@tonic-gate get_string_from_buf(char **stringptr, int strsize, const char *buf)
43937c478bd9Sstevel@tonic-gate {
43947c478bd9Sstevel@tonic-gate 	if (buf == NULL) {
43957c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
43967c478bd9Sstevel@tonic-gate 	}
43977c478bd9Sstevel@tonic-gate 
43987c478bd9Sstevel@tonic-gate 	/*
43997c478bd9Sstevel@tonic-gate 	 * A stringptr of NULL is a valid value. The errstring param
44007c478bd9Sstevel@tonic-gate 	 * in an rconfig_xxx call is valid and is passed to this
44017c478bd9Sstevel@tonic-gate 	 * function. For example, see errstring in the call to this
44027c478bd9Sstevel@tonic-gate 	 * function in unpack_change_state_reply.
44037c478bd9Sstevel@tonic-gate 	 */
44047c478bd9Sstevel@tonic-gate 	if (stringptr != NULL) {
44057c478bd9Sstevel@tonic-gate 		if (strsize > 0) {
44067c478bd9Sstevel@tonic-gate 			*stringptr = (char *)malloc(strsize);
44077c478bd9Sstevel@tonic-gate 			if (*stringptr == NULL) {
44087c478bd9Sstevel@tonic-gate 				return (RDR_MEM_ALLOC);
44097c478bd9Sstevel@tonic-gate 			}
44107c478bd9Sstevel@tonic-gate 			(void) memcpy(*stringptr, buf, strsize);
44117c478bd9Sstevel@tonic-gate 		} else if (strsize == 0) {
44127c478bd9Sstevel@tonic-gate 			*stringptr = NULL;
44137c478bd9Sstevel@tonic-gate 		} else if (strsize < 0) {
44147c478bd9Sstevel@tonic-gate 			*stringptr = NULL;
44157c478bd9Sstevel@tonic-gate 			return (RDR_ERROR);
44167c478bd9Sstevel@tonic-gate 		}
44177c478bd9Sstevel@tonic-gate 	}
44187c478bd9Sstevel@tonic-gate 	return (RDR_OK);
44197c478bd9Sstevel@tonic-gate }
44207c478bd9Sstevel@tonic-gate 
44217c478bd9Sstevel@tonic-gate 
44227c478bd9Sstevel@tonic-gate /*
44237c478bd9Sstevel@tonic-gate  * cleanup_ap_ids:
44247c478bd9Sstevel@tonic-gate  *
44257c478bd9Sstevel@tonic-gate  * Deallocate the specified array of attachment point identifiers.
44267c478bd9Sstevel@tonic-gate  */
44277c478bd9Sstevel@tonic-gate static int
cleanup_ap_ids(int num_ap_ids,char ** ap_ids)44287c478bd9Sstevel@tonic-gate cleanup_ap_ids(int num_ap_ids, char ** ap_ids)
44297c478bd9Sstevel@tonic-gate {
44307c478bd9Sstevel@tonic-gate 	int	i;
44317c478bd9Sstevel@tonic-gate 
44327c478bd9Sstevel@tonic-gate 	if (ap_ids == NULL) {
44337c478bd9Sstevel@tonic-gate 		return (RDR_ERROR);
44347c478bd9Sstevel@tonic-gate 	}
44357c478bd9Sstevel@tonic-gate 	for (i = 0; i < num_ap_ids; i++) {
44367c478bd9Sstevel@tonic-gate 		if (ap_ids[i] != NULL) {
44377c478bd9Sstevel@tonic-gate 			free((void *)ap_ids[i]);
44387c478bd9Sstevel@tonic-gate 			ap_ids[i] = NULL;
44397c478bd9Sstevel@tonic-gate 		}
44407c478bd9Sstevel@tonic-gate 	}
44417c478bd9Sstevel@tonic-gate 	return (RDR_OK);
44427c478bd9Sstevel@tonic-gate }
44437c478bd9Sstevel@tonic-gate 
44447c478bd9Sstevel@tonic-gate 
44457c478bd9Sstevel@tonic-gate /*
44467c478bd9Sstevel@tonic-gate  * cleanup_errstring:
44477c478bd9Sstevel@tonic-gate  *
44487c478bd9Sstevel@tonic-gate  * Deallocate the specified error string.
44497c478bd9Sstevel@tonic-gate  */
44507c478bd9Sstevel@tonic-gate static int
cleanup_errstring(char ** errstring)44517c478bd9Sstevel@tonic-gate cleanup_errstring(char **errstring)
44527c478bd9Sstevel@tonic-gate {
44537c478bd9Sstevel@tonic-gate 	if (errstring) {
44547c478bd9Sstevel@tonic-gate 		if (*errstring) {
44557c478bd9Sstevel@tonic-gate 			free((void *)*errstring);
44567c478bd9Sstevel@tonic-gate 		}
44577c478bd9Sstevel@tonic-gate 		free((void *)errstring);
44587c478bd9Sstevel@tonic-gate 		errstring = NULL;
44597c478bd9Sstevel@tonic-gate 	}
44607c478bd9Sstevel@tonic-gate 
44617c478bd9Sstevel@tonic-gate 	return (RDR_OK);
44627c478bd9Sstevel@tonic-gate }
44637c478bd9Sstevel@tonic-gate 
44647c478bd9Sstevel@tonic-gate 
44657c478bd9Sstevel@tonic-gate /*
44667c478bd9Sstevel@tonic-gate  * cleanup_variable_ap_id_info:
44677c478bd9Sstevel@tonic-gate  *
44687c478bd9Sstevel@tonic-gate  * Deallocate the ap_id information from the specified
44697c478bd9Sstevel@tonic-gate  * rdr_variable_message_info_t.
44707c478bd9Sstevel@tonic-gate  */
44717c478bd9Sstevel@tonic-gate static void
cleanup_variable_ap_id_info(rdr_variable_message_info_t * var_msg_info)44727c478bd9Sstevel@tonic-gate cleanup_variable_ap_id_info(rdr_variable_message_info_t *var_msg_info)
44737c478bd9Sstevel@tonic-gate {
44747c478bd9Sstevel@tonic-gate 	if (var_msg_info != NULL) {
44757c478bd9Sstevel@tonic-gate 		if (var_msg_info->ap_id_sizes != NULL) {
44767c478bd9Sstevel@tonic-gate 			free((void *)var_msg_info->ap_id_sizes);
44777c478bd9Sstevel@tonic-gate 			var_msg_info->ap_id_sizes = NULL;
44787c478bd9Sstevel@tonic-gate 		}
44797c478bd9Sstevel@tonic-gate 		if (var_msg_info->ap_id_chars != NULL) {
44807c478bd9Sstevel@tonic-gate 			free((void *)var_msg_info->ap_id_chars);
44817c478bd9Sstevel@tonic-gate 			var_msg_info->ap_id_chars = NULL;
44827c478bd9Sstevel@tonic-gate 		}
44837c478bd9Sstevel@tonic-gate 	}
44847c478bd9Sstevel@tonic-gate }
4485*25cf1a30Sjl139090 
4486*25cf1a30Sjl139090 /*
4487*25cf1a30Sjl139090  * load_libdscp:
4488*25cf1a30Sjl139090  *
4489*25cf1a30Sjl139090  * Try to dynamically link with libdscp.
4490*25cf1a30Sjl139090  *
4491*25cf1a30Sjl139090  * Returns:	0 if libdscp not available,
4492*25cf1a30Sjl139090  *		1 if libdscp is available.
4493*25cf1a30Sjl139090  */
4494*25cf1a30Sjl139090 static int
load_libdscp(libdscp_t * libdscp)4495*25cf1a30Sjl139090 load_libdscp(libdscp_t *libdscp)
4496*25cf1a30Sjl139090 {
4497*25cf1a30Sjl139090 	int		len;
4498*25cf1a30Sjl139090 	void		*lib;
4499*25cf1a30Sjl139090 	static char	platform[100];
4500*25cf1a30Sjl139090 	static char	pathname[MAXPATHLEN];
4501*25cf1a30Sjl139090 
4502*25cf1a30Sjl139090 	/*
4503*25cf1a30Sjl139090 	 * Only try to load libdscp once.  Use the saved
4504*25cf1a30Sjl139090 	 * status in the libdscp interface to know the
4505*25cf1a30Sjl139090 	 * results of previous attempts.
4506*25cf1a30Sjl139090 	 */
4507*25cf1a30Sjl139090 	if (libdscp->status == LIBDSCP_AVAILABLE) {
4508*25cf1a30Sjl139090 		return (1);
4509*25cf1a30Sjl139090 	}
4510*25cf1a30Sjl139090 	if (libdscp->status == LIBDSCP_UNAVAILABLE) {
4511*25cf1a30Sjl139090 		return (0);
4512*25cf1a30Sjl139090 	}
4513*25cf1a30Sjl139090 
4514*25cf1a30Sjl139090 	/*
4515*25cf1a30Sjl139090 	 * Construct a platform specific pathname for libdscp.
4516*25cf1a30Sjl139090 	 */
4517*25cf1a30Sjl139090 	len = sysinfo(SI_PLATFORM, platform, sizeof (platform));
4518*25cf1a30Sjl139090 	if ((len < 0) || (len > sizeof (platform))) {
4519*25cf1a30Sjl139090 		return (0);
4520*25cf1a30Sjl139090 	}
4521*25cf1a30Sjl139090 	len = snprintf(pathname, MAXPATHLEN, LIBDSCP_PATH, platform);
4522*25cf1a30Sjl139090 	if (len >= MAXPATHLEN) {
4523*25cf1a30Sjl139090 		libdscp->status = LIBDSCP_UNAVAILABLE;
4524*25cf1a30Sjl139090 		return (0);
4525*25cf1a30Sjl139090 	}
4526*25cf1a30Sjl139090 
4527*25cf1a30Sjl139090 	/*
4528*25cf1a30Sjl139090 	 * Try dynamically loading libdscp.
4529*25cf1a30Sjl139090 	 */
4530*25cf1a30Sjl139090 	if ((lib = dlopen(pathname, RTLD_LAZY)) == NULL) {
4531*25cf1a30Sjl139090 		libdscp->status = LIBDSCP_UNAVAILABLE;
4532*25cf1a30Sjl139090 		return (0);
4533*25cf1a30Sjl139090 	}
4534*25cf1a30Sjl139090 
4535*25cf1a30Sjl139090 	/*
4536*25cf1a30Sjl139090 	 * Try to resolve all the symbols.
4537*25cf1a30Sjl139090 	 */
4538*25cf1a30Sjl139090 	libdscp->bind = (int (*)(int, int, int))dlsym(lib, LIBDSCP_BIND);
4539*25cf1a30Sjl139090 	libdscp->secure = (int (*)(int, int))dlsym(lib, LIBDSCP_SECURE);
4540*25cf1a30Sjl139090 	libdscp->auth = (int (*)(int, struct sockaddr *, int))dlsym(lib,
4541*25cf1a30Sjl139090 	    LIBDSCP_AUTH);
4542*25cf1a30Sjl139090 
4543*25cf1a30Sjl139090 	if ((libdscp->bind == NULL) ||
4544*25cf1a30Sjl139090 	    (libdscp->secure == NULL) ||
4545*25cf1a30Sjl139090 	    (libdscp->auth == NULL)) {
4546*25cf1a30Sjl139090 		(void) dlclose(lib);
4547*25cf1a30Sjl139090 		libdscp->status = LIBDSCP_UNAVAILABLE;
4548*25cf1a30Sjl139090 		return (0);
4549*25cf1a30Sjl139090 	}
4550*25cf1a30Sjl139090 
4551*25cf1a30Sjl139090 	/*
4552*25cf1a30Sjl139090 	 * Success.
4553*25cf1a30Sjl139090 	 * Update the status to indicate libdscp is available.
4554*25cf1a30Sjl139090 	 */
4555*25cf1a30Sjl139090 	libdscp->status = LIBDSCP_AVAILABLE;
4556*25cf1a30Sjl139090 	return (1);
4557*25cf1a30Sjl139090 }
4558