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