8322 nl: misleading-indentation
[unleashed/tickless.git] / usr / src / cmd / dcs / sparc / sun4u / rdr_messages.c
blob51b836a57b3a7c074876f5421af69b97b1bdd16f
1 /*
2 * CDDL HEADER START
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
19 * CDDL HEADER END
22 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 #pragma ident "%Z%%M% %I% %E% SMI"
29 * WARNING: The contents of this file are shared by all projects
30 * that wish to perform remote Dynamic Reconfiguration (DR)
31 * operations. Copies of this file can be found in the following
32 * locations:
34 * Project Location
35 * ------- --------
36 * Solaris usr/src/cmd/dcs/sparc/sun4u/%M%
37 * SMS src/sms/lib/librdr/%M%
39 * In order for proper communication to occur, the files in the
40 * above locations must match exactly. Any changes that are made
41 * to this file should be made to all of the files in the list.
45 * This file is a module that contains an interface for performing
46 * remote Dynamic Reconfiguration (DR) operations. It hides all
47 * network operations such as establishing a connection, sending
48 * and receiving messages, and closing a connection. It also handles
49 * the packing and unpacking of messages for network transport.
52 #include <stdio.h>
53 #include <stdlib.h>
54 #include <unistd.h>
55 #include <string.h>
56 #include <fcntl.h>
57 #include <errno.h>
58 #include <dlfcn.h>
59 #include <netdb.h>
60 #include <libdscp.h>
61 #include <sys/socket.h>
62 #include <sys/systeminfo.h>
63 #include <netinet/tcp.h>
65 #include "dcs.h"
66 #include "remote_cfg.h"
67 #include "rdr_param_types.h"
68 #include "rdr_messages.h"
72 * Structure holding information about
73 * all possible variable length fields
74 * that can be present in an RDR message.
76 typedef struct {
77 int ap_id_int_size;
78 int ap_id_char_size;
79 int *ap_id_sizes;
80 char *ap_id_chars;
81 int errstring_strlen;
82 int errstring_pad_sz;
83 int options_strlen;
84 int options_pad_sz;
85 int listopts_strlen;
86 int listopts_pad_sz;
87 int function_strlen;
88 int function_pad_sz;
89 } rdr_variable_message_info_t;
92 * A table of maximum sizes for each message type. Message size is
93 * validated when the message header is first received. This prevents
94 * a situation where a corrupted or bad header can cause too much
95 * memory to be allocated.
97 * The message size limits were chosen to be a very generous upper bound
98 * on the amount of data each message can send. They are not intended to
99 * be a precise measurement of the data size.
101 #define NOMSG 0
102 #define SHORTMSG (150 * 1024) /* 150 KB */
103 #define LONGMSG (3 * 1024 * 1024) /* 3 MB */
105 struct {
106 ulong_t req_max;
107 ulong_t reply_max;
108 } msg_sizes[] = {
110 * request reply
111 * ------- -----
113 { NOMSG, NOMSG }, /* Invalid Opcode */
114 { SHORTMSG, SHORTMSG }, /* RDR_SES_REQ */
115 { NOMSG, NOMSG }, /* RDR_SES_ESTBL */
116 { NOMSG, NOMSG }, /* RDR_SES_END */
117 { SHORTMSG, SHORTMSG }, /* RDR_CONF_CHANGE_STATE */
118 { SHORTMSG, SHORTMSG }, /* RDR_CONF_PRIVATE_FUNC */
119 { SHORTMSG, SHORTMSG }, /* RDR_CONF_TEST */
120 { SHORTMSG, LONGMSG }, /* RDR_CONF_LIST_EXT */
121 { SHORTMSG, NOMSG }, /* RDR_CONF_HELP */
122 { SHORTMSG, NOMSG }, /* RDR_CONF_AP_ID_CMP */
123 { SHORTMSG, NOMSG }, /* RDR_CONF_ABORT_CMD */
124 { SHORTMSG, SHORTMSG }, /* RDR_CONF_CONFIRM_CALLBACK */
125 { SHORTMSG, NOMSG }, /* RDR_CONF_MSG_CALLBACK */
126 { SHORTMSG, LONGMSG } /* RDR_RSRC_INFO */
130 #define RDR_BAD_FD (-1)
132 #define RDR_MSG_HDR_SIZE sizeof (rdr_msg_hdr_t)
134 static const int RDR_ALIGN_64_BIT = 8; /* 8 bytes */
137 * Interfaces for dynamic use of libdscp.
140 #define LIBDSCP_PATH "/usr/platform/%s/lib/libdscp.so.1"
142 #define LIBDSCP_BIND "dscpBind"
143 #define LIBDSCP_SECURE "dscpSecure"
144 #define LIBDSCP_AUTH "dscpAuth"
146 typedef enum {
147 LIBDSCP_UNKNOWN = 0,
148 LIBDSCP_AVAILABLE,
149 LIBDSCP_UNAVAILABLE
150 } dscp_status_t;
152 typedef struct {
153 dscp_status_t status;
154 int (*bind)(int, int, int);
155 int (*secure)(int, int);
156 int (*auth)(int, struct sockaddr *, int);
157 } libdscp_t;
159 static libdscp_t libdscp;
162 * Static Function Declarations
166 * Socket Related Routines
168 static int rdr_setopt(int fd, int name, int level);
170 static int rdr_bind(int fd, struct sockaddr *addr);
172 static int rdr_secure(int fd, struct sockaddr *addr);
174 static int rdr_auth(struct sockaddr *addr, int len);
176 static int rdr_snd(int fd, rdr_msg_hdr_t *hdr, char *data, int data_sz,
177 int timeout);
178 static int rdr_snd_raw(int fd, char *msg, int data_sz, int timeout);
180 static int rdr_rcv(int fd, rdr_msg_hdr_t *hdr, char **data, int timeout);
182 static int rdr_rcv_raw(int fd, char *msg, int data_size, int timeout);
185 * Data Validation Routines
187 static int validate_header(rdr_msg_hdr_t *hdr);
191 * Session Request Routines
193 static int pack_ses_req_request(ses_req_params_t *params, char **buf,
194 int *buf_size);
195 static int unpack_ses_req_request(ses_req_params_t *params, const char *buf);
197 static int pack_ses_req_reply(ses_req_params_t *params, char **buf,
198 int *buf_size);
199 static int unpack_ses_req_reply(ses_req_params_t *params, const char *buf);
203 * Change State Routines
205 static int pack_change_state_request(change_state_params_t *params,
206 char **buf, int *buf_size);
207 static int unpack_change_state_request(change_state_params_t *params,
208 const char *buf);
209 static int pack_change_state_reply(change_state_params_t *params,
210 char **buf, int *buf_size);
211 static int unpack_change_state_reply(change_state_params_t *params,
212 const char *buf);
215 * Private Func Routines
217 static int pack_private_func_request(private_func_params_t *params,
218 char **buf, int *buf_size);
219 static int unpack_private_func_request(private_func_params_t *params,
220 const char *buf);
221 static int pack_private_func_reply(private_func_params_t *params,
222 char **buf, int *buf_size);
223 static int unpack_private_func_reply(private_func_params_t *params,
224 const char *buf);
227 * Test Routines
229 static int pack_test_request(test_params_t *params, char **buf, int *buf_size);
231 static int unpack_test_request(test_params_t *params, const char *buf);
233 static int pack_test_reply(test_params_t *params, char **buf, int *buf_size);
235 static int unpack_test_reply(test_params_t *params, const char *buf);
239 * List Ext Routines
241 static int pack_list_ext_request(list_ext_params_t *params, char **buf,
242 int *buf_size);
243 static int unpack_list_ext_request(list_ext_params_t *params, const char *buf);
245 static int pack_list_ext_reply(list_ext_params_t *params, char **buf,
246 int *buf_size);
247 static int unpack_list_ext_reply(list_ext_params_t *params, const char *buf);
251 * Help Routines
253 static int pack_help_request(help_params_t *params, char **buf, int *buf_size);
255 static int unpack_help_request(help_params_t *params, const char *buf);
259 * Ap Id Cmp Routines
261 static int pack_ap_id_cmp_request(ap_id_cmp_params_t *params, char **buf,
262 int *buf_size);
263 static int unpack_ap_id_cmp_request(ap_id_cmp_params_t *params,
264 const char *buf);
267 * Abort Routines
269 static int pack_abort_cmd_request(abort_cmd_params_t *params, char **buf,
270 int *buf_size);
271 static int unpack_abort_cmd_request(abort_cmd_params_t *params,
272 const char *buf);
275 * Confirm Callback Routines
277 static int pack_confirm_request(confirm_callback_params_t *params, char **buf,
278 int *buf_size);
279 static int unpack_confirm_request(confirm_callback_params_t *params,
280 const char *buf);
281 static int pack_confirm_reply(confirm_callback_params_t *params,
282 char **buf, int *buf_size);
283 static int unpack_confirm_reply(confirm_callback_params_t *params,
284 const char *buf);
287 * Message Callback Routines
289 static int pack_message_request(msg_callback_params_t *params, char **buf,
290 int *buf_size);
291 static int unpack_message_request(msg_callback_params_t *params,
292 const char *buf);
295 * Resource Info Routines
297 static int pack_rsrc_info_request(rsrc_info_params_t *params, char **buf,
298 int *buf_size);
299 static int unpack_rsrc_info_request(rsrc_info_params_t *params,
300 const char *buf);
301 static int pack_rsrc_info_reply(rsrc_info_params_t *params, char **buf,
302 int *buf_size, int encoding);
303 static int unpack_rsrc_info_reply(rsrc_info_params_t *params, const char *buf);
306 * General Pack/Unpack Routines
308 static int pack_ap_ids(int num_ap_ids, char *const *ap_ids,
309 rdr_variable_message_info_t *var_msg_info);
310 static int unpack_ap_ids(int num_ap_ids, char **ap_ids, const char *buf,
311 rdr_variable_message_info_t *var_msg_info);
314 * Find Variable Info Sizes
316 static int find_options_sizes(char *options,
317 rdr_variable_message_info_t *var_msg_info);
318 static int find_listopts_sizes(char *listopts,
319 rdr_variable_message_info_t *var_msg_info);
320 static int find_function_sizes(char *function,
321 rdr_variable_message_info_t *var_msg_info);
322 static int find_errstring_sizes(char **errstring,
323 rdr_variable_message_info_t *var_msg_info);
326 * Extract Info From Buffers
328 static int get_ap_ids_from_buf(char ***ap_id_ptr, int num_ap_ids,
329 rdr_variable_message_info_t *var_msg_info,
330 const char *buf);
331 static int get_string_from_buf(char **stringptr, int strsize, const char *buf);
335 * Cleanup Routines
337 static int cleanup_ap_ids(int num_ap_ids, char **ap_ids);
339 static int cleanup_errstring(char **errstring);
341 static void cleanup_variable_ap_id_info(
342 rdr_variable_message_info_t *var_msg_info);
345 * Functions for loading libdscp.
347 static int load_libdscp(libdscp_t *libdscp);
350 * Public Functions
355 * rdr_open:
357 * Establish a transport endpoint to prepare for a new
358 * connection. Returns a file descriptor representing the
359 * new transport if successful or RDR_BAD_FD upon failure.
362 rdr_open(int family)
364 int newfd;
367 if ((newfd = socket(family, SOCK_STREAM, 0)) == NULL) {
368 return (RDR_BAD_FD);
371 return (newfd);
376 * rdr_init:
378 * Initialize a transport endpoint. This involves binding to
379 * a particular port and setting any user specified socket
380 * options.
383 rdr_init(int fd, struct sockaddr *addr, int *opts, int num_opts, int blog)
385 int i;
388 /* sanity checks */
389 if ((fd < 0) || (addr == NULL)) {
390 return (RDR_ERROR);
393 if ((opts == NULL) || (num_opts < 0)) {
394 num_opts = 0;
397 /* turn on security features */
398 if (rdr_secure(fd, addr) != RDR_OK) {
399 return (RDR_NET_ERR);
402 /* bind the address, if is not already bound */
403 if (rdr_bind(fd, addr) != RDR_OK) {
404 return (RDR_NET_ERR);
408 * Set TCP_NODELAY for this endpoint. This disables Nagle's
409 * algorithm that can cause a delay in sending small sized
410 * messages. Since most of the RDR messages are small, this
411 * is a restriction that negatively impacts performance.
413 if (rdr_setopt(fd, TCP_NODELAY, IPPROTO_TCP) != RDR_OK) {
414 return (RDR_NET_ERR);
417 /* set the user specified socket options */
418 for (i = 0; i < num_opts; i++) {
419 if (rdr_setopt(fd, opts[i], SOL_SOCKET) != RDR_OK) {
420 return (RDR_NET_ERR);
425 * If blog is not zero, it is a server that is being
426 * initialized. In order for it to be able to accept
427 * connections, we have to set the size of the incoming
428 * connection queue.
430 if (blog != 0) {
431 if (listen(fd, blog) == -1) {
432 return (RDR_NET_ERR);
436 return (RDR_OK);
441 * rdr_connect_clnt:
443 * Perform the necessary steps for a client to connect to
444 * a server process. The required information is the file
445 * descriptor for the transport endpoint, and the remote
446 * address.
449 rdr_connect_clnt(int fd, struct sockaddr *addr)
451 unsigned int addr_len;
454 /* sanity check */
455 if (addr == NULL) {
456 return (RDR_ERROR);
459 /* initialize the address length */
460 switch (addr->sa_family) {
462 case AF_INET:
463 addr_len = sizeof (struct sockaddr_in);
464 break;
466 case AF_INET6:
467 addr_len = sizeof (struct sockaddr_in6);
468 break;
470 default:
471 return (RDR_ERROR);
474 /* attempt the connection */
475 if (connect(fd, addr, addr_len) == -1) {
476 return (RDR_NET_ERR);
479 return (RDR_OK);
484 * rdr_connect_srv:
486 * Perform the necessary steps for a server to connect to a
487 * pending client request. The new connection is allocated a
488 * new file descriptor, separate from the one used to accept
489 * the connection.
492 rdr_connect_srv(int fd)
494 int newfd;
495 unsigned int faddr_len;
496 struct sockaddr_storage faddr;
499 /* accept the connection */
500 faddr_len = sizeof (faddr);
501 if ((newfd = accept(fd, (struct sockaddr *)&faddr, &faddr_len)) == -1) {
502 return (RDR_BAD_FD);
505 /* if the peer doesn't authenticate properly, reject */
506 if (rdr_auth((struct sockaddr *)&faddr, faddr_len) != RDR_OK) {
507 (void) close(newfd);
508 return (RDR_BAD_FD);
511 return (newfd);
516 * rdr_reject:
518 * Reject an incoming connection attempt. This requires
519 * that the connection be accepted first.
522 rdr_reject(int fd)
524 unsigned int faddr_len;
525 struct sockaddr_storage faddr;
528 /* first accept the connection */
529 faddr_len = sizeof (faddr);
530 if (accept(fd, (struct sockaddr *)&faddr, &faddr_len) == -1) {
531 return (RDR_NET_ERR);
534 /* then close it */
535 (void) close(fd);
537 return (RDR_OK);
542 * rdr_close:
544 * Close down an given connection.
547 rdr_close(int fd)
549 (void) close(fd);
551 return (RDR_OK);
556 * rdr_snd_msg:
558 * Public interface for sending an RDR message. The data
559 * passed in through hdr and param are packed for network
560 * transport and sent.
563 rdr_snd_msg(int fd, rdr_msg_hdr_t *hdr, cfga_params_t *param, int timeout)
565 int err;
566 char *pack_buf = NULL;
567 int pack_buf_sz = 0;
570 /* sanity checks */
571 if ((hdr == NULL) || (param == NULL)) {
572 return (RDR_ERROR);
576 * Pack the message for transport
578 switch (hdr->message_opcode) {
580 case RDR_SES_REQ: {
582 ses_req_params_t *rparam;
583 rparam = (ses_req_params_t *)param;
585 if (hdr->data_type == RDR_REQUEST) {
586 err = pack_ses_req_request(rparam,
587 &pack_buf, &pack_buf_sz);
588 } else {
589 err = pack_ses_req_reply(rparam,
590 &pack_buf, &pack_buf_sz);
593 break;
596 case RDR_SES_ESTBL:
597 case RDR_SES_END:
600 * This is not an error condition because
601 * there is no extra information to pack.
603 err = RDR_OK;
604 break;
606 case RDR_CONF_CHANGE_STATE: {
608 change_state_params_t *cparam;
609 cparam = (change_state_params_t *)param;
611 if (hdr->data_type == RDR_REQUEST) {
612 err = pack_change_state_request(cparam,
613 &pack_buf, &pack_buf_sz);
614 } else {
615 err = pack_change_state_reply(cparam,
616 &pack_buf, &pack_buf_sz);
618 break;
621 case RDR_CONF_PRIVATE_FUNC: {
623 private_func_params_t *pparam;
624 pparam = (private_func_params_t *)param;
626 if (hdr->data_type == RDR_REQUEST) {
627 err = pack_private_func_request(pparam,
628 &pack_buf, &pack_buf_sz);
629 } else {
630 err = pack_private_func_reply(pparam,
631 &pack_buf, &pack_buf_sz);
633 break;
636 case RDR_CONF_TEST: {
638 test_params_t *tparam;
639 tparam = (test_params_t *)param;
641 if (hdr->data_type == RDR_REQUEST) {
642 err = pack_test_request(tparam,
643 &pack_buf, &pack_buf_sz);
644 } else {
645 err = pack_test_reply(tparam,
646 &pack_buf, &pack_buf_sz);
648 break;
651 case RDR_CONF_LIST_EXT: {
653 list_ext_params_t *lparam;
654 lparam = (list_ext_params_t *)param;
656 if (hdr->data_type == RDR_REQUEST) {
657 err = pack_list_ext_request(lparam, &pack_buf,
658 &pack_buf_sz);
659 } else {
660 err = pack_list_ext_reply(lparam, &pack_buf,
661 &pack_buf_sz);
663 break;
666 case RDR_CONF_HELP: {
668 help_params_t *hparam;
669 hparam = (help_params_t *)param;
671 if (hdr->data_type == RDR_REQUEST) {
672 err = pack_help_request(hparam,
673 &pack_buf, &pack_buf_sz);
674 } else {
677 * This is not an error because help
678 * reply does not have any extra information
679 * to pack.
681 err = RDR_OK;
683 break;
686 case RDR_CONF_AP_ID_CMP: {
688 ap_id_cmp_params_t *aparam;
689 aparam = (ap_id_cmp_params_t *)param;
691 if (hdr->data_type == RDR_REQUEST) {
692 err = pack_ap_id_cmp_request(aparam,
693 &pack_buf, &pack_buf_sz);
694 } else {
697 * This is not an error because ap_id_cmp
698 * reply does not have any extra information
699 * to pack.
701 err = RDR_OK;
703 break;
706 case RDR_CONF_ABORT_CMD: {
708 abort_cmd_params_t *aparam;
709 aparam = (abort_cmd_params_t *)param;
711 if (hdr->data_type == RDR_REQUEST) {
712 err = pack_abort_cmd_request(aparam,
713 &pack_buf, &pack_buf_sz);
714 } else {
716 * This is not an error because session
717 * abort reply does not have any extra
718 * information to pack.
720 err = RDR_OK;
722 break;
725 case RDR_CONF_CONFIRM_CALLBACK: {
727 confirm_callback_params_t *cparam;
728 cparam = (confirm_callback_params_t *)param;
730 if (hdr->data_type == RDR_REQUEST) {
731 err = pack_confirm_request(cparam,
732 &pack_buf, &pack_buf_sz);
733 } else {
734 err = pack_confirm_reply(cparam, &pack_buf,
735 &pack_buf_sz);
737 break;
740 case RDR_CONF_MSG_CALLBACK: {
742 msg_callback_params_t *mparam;
743 mparam = (msg_callback_params_t *)param;
745 if (hdr->data_type == RDR_REQUEST) {
746 err = pack_message_request(mparam,
747 &pack_buf, &pack_buf_sz);
748 } else {
750 * It is an error to send a reply
751 * to a message callback.
753 err = RDR_MSG_INVAL;
755 break;
758 case RDR_RSRC_INFO: {
760 rsrc_info_params_t *rparam;
761 rparam = (rsrc_info_params_t *)param;
763 if (hdr->data_type == RDR_REQUEST) {
764 err = pack_rsrc_info_request(rparam, &pack_buf,
765 &pack_buf_sz);
766 } else {
767 if ((hdr->major_version == 1) &&
768 (hdr->minor_version == 0)) {
769 err = pack_rsrc_info_reply(rparam,
770 &pack_buf, &pack_buf_sz,
771 NV_ENCODE_NATIVE);
772 } else {
773 err = pack_rsrc_info_reply(rparam,
774 &pack_buf, &pack_buf_sz,
775 NV_ENCODE_XDR);
778 break;
781 default:
782 err = RDR_MSG_INVAL;
783 break;
786 /* check if packed correctly */
787 if (err != RDR_OK) {
788 return (err);
791 /* send the message */
792 err = rdr_snd(fd, hdr, pack_buf, pack_buf_sz, timeout);
794 free((void *)pack_buf);
796 return (err);
801 * rdr_rcv_msg:
803 * Public interface for receiving an RDR message. Data is
804 * unpacked into the hdr and param paramters.
807 rdr_rcv_msg(int fd, rdr_msg_hdr_t *hdr, cfga_params_t *param, int timeout)
809 int err;
810 char *unpack_buf = NULL;
813 /* sanity checks */
814 if ((hdr == NULL) || (param == NULL)) {
815 return (RDR_ERROR);
818 (void) memset(param, 0, sizeof (cfga_params_t));
820 /* receive the message */
821 if ((err = rdr_rcv(fd, hdr, &unpack_buf, timeout)) != RDR_OK) {
822 return (err);
826 * Unpack the message
828 switch (hdr->message_opcode) {
830 case RDR_SES_REQ: {
832 ses_req_params_t *rparam;
833 rparam = (ses_req_params_t *)param;
835 if (hdr->data_type == RDR_REQUEST) {
836 err = unpack_ses_req_request(rparam,
837 unpack_buf);
838 } else {
839 err = unpack_ses_req_reply(rparam, unpack_buf);
841 break;
844 case RDR_SES_ESTBL:
845 case RDR_SES_END:
847 /* no information to unpack */
848 (void) memset(param, 0, sizeof (cfga_params_t));
849 err = RDR_OK;
850 break;
852 case RDR_CONF_CHANGE_STATE: {
854 change_state_params_t *cparam;
855 cparam = (change_state_params_t *)param;
857 if (hdr->data_type == RDR_REQUEST) {
858 err = unpack_change_state_request(cparam,
859 unpack_buf);
860 } else {
861 err = unpack_change_state_reply(cparam,
862 unpack_buf);
864 break;
867 case RDR_CONF_PRIVATE_FUNC: {
869 private_func_params_t *pparam;
870 pparam = (private_func_params_t *)param;
872 if (hdr->data_type == RDR_REQUEST) {
873 err = unpack_private_func_request(pparam,
874 unpack_buf);
875 } else {
876 err = unpack_private_func_reply(pparam,
877 unpack_buf);
879 break;
882 case RDR_CONF_TEST: {
884 test_params_t *tparam;
885 tparam = (test_params_t *)param;
887 if (hdr->data_type == RDR_REQUEST) {
888 err = unpack_test_request(tparam, unpack_buf);
889 } else {
890 err = unpack_test_reply(tparam, unpack_buf);
892 break;
895 case RDR_CONF_LIST_EXT: {
897 list_ext_params_t *lparam;
898 lparam = (list_ext_params_t *)param;
900 if (hdr->data_type == RDR_REQUEST) {
901 err = unpack_list_ext_request(lparam,
902 unpack_buf);
903 } else {
904 err = unpack_list_ext_reply(lparam, unpack_buf);
906 break;
909 case RDR_CONF_HELP: {
911 help_params_t *hparam;
912 hparam = (help_params_t *)param;
914 if (hdr->data_type == RDR_REQUEST) {
915 err = unpack_help_request(hparam,
916 unpack_buf);
917 } else {
919 * This is not an error because help
920 * reply does not have any extra information
921 * to unpack.
923 err = RDR_OK;
925 break;
928 case RDR_CONF_AP_ID_CMP: {
930 ap_id_cmp_params_t *aparam;
931 aparam = (ap_id_cmp_params_t *)param;
933 if (hdr->data_type == RDR_REQUEST) {
934 err = unpack_ap_id_cmp_request(aparam,
935 unpack_buf);
936 } else {
938 * This is not an error because ap_id_cmp
939 * reply does not have any extra information
940 * to pack.
942 err = RDR_OK;
944 break;
947 case RDR_CONF_ABORT_CMD: {
949 abort_cmd_params_t *aparam;
950 aparam = (abort_cmd_params_t *)param;
952 if (hdr->data_type == RDR_REQUEST) {
953 err = unpack_abort_cmd_request(aparam,
954 unpack_buf);
955 } else {
956 /* no information to unpack */
957 (void) memset(param, 0, sizeof (cfga_params_t));
958 err = RDR_OK;
961 break;
964 case RDR_CONF_CONFIRM_CALLBACK: {
966 confirm_callback_params_t *cparam;
967 cparam = (confirm_callback_params_t *)param;
969 if (hdr->data_type == RDR_REQUEST) {
970 err = unpack_confirm_request(cparam,
971 unpack_buf);
972 } else {
973 err = unpack_confirm_reply(cparam, unpack_buf);
975 break;
978 case RDR_CONF_MSG_CALLBACK: {
980 msg_callback_params_t *mparam;
981 mparam = (msg_callback_params_t *)param;
983 if (hdr->data_type == RDR_REQUEST) {
984 err = unpack_message_request(mparam,
985 unpack_buf);
986 } else {
988 * It is an error to send a reply
989 * to a message callback.
991 (void) memset(param, 0, sizeof (cfga_params_t));
992 err = RDR_MSG_INVAL;
994 break;
997 case RDR_RSRC_INFO: {
999 rsrc_info_params_t *rparam;
1000 rparam = (rsrc_info_params_t *)param;
1002 if (hdr->data_type == RDR_REQUEST) {
1003 err = unpack_rsrc_info_request(rparam,
1004 unpack_buf);
1005 } else {
1006 err = unpack_rsrc_info_reply(rparam,
1007 unpack_buf);
1009 break;
1012 default:
1013 err = RDR_MSG_INVAL;
1014 break;
1017 free(unpack_buf);
1019 /* check if unpacked correctly */
1020 if (err != RDR_OK) {
1021 return (err);
1024 return (RDR_OK);
1029 * rdr_cleanup_params:
1031 * Deallocate any memory that was allocated in unpacking a
1032 * message.
1035 rdr_cleanup_params(rdr_msg_opcode_t message_opcode, cfga_params_t *param)
1037 /* sanity check */
1038 if ((param == NULL)) {
1039 return (RDR_ERROR);
1043 * Deallocate memory depending on
1044 * the operation.
1046 switch (message_opcode) {
1048 case RDR_SES_REQ: {
1050 ses_req_params_t *sparam;
1051 sparam = (ses_req_params_t *)param;
1053 if (sparam->locale_str != NULL) {
1054 free((void *)sparam->locale_str);
1055 sparam->locale_str = NULL;
1057 break;
1060 case RDR_SES_ESTBL:
1061 case RDR_SES_END:
1063 /* nothing to deallocate */
1064 break;
1066 case RDR_CONF_CHANGE_STATE: {
1068 change_state_params_t *cparam;
1069 cparam = (change_state_params_t *)param;
1071 cleanup_ap_ids(cparam->num_ap_ids, (char **)cparam->ap_ids);
1072 cparam->ap_ids = NULL;
1073 if (cparam->options != NULL) {
1074 free((void *)cparam->options);
1075 cparam->options = NULL;
1077 if (cparam->confp != NULL) {
1078 free((void *)cparam->confp);
1079 cparam->confp = NULL;
1081 if (cparam->msgp != NULL) {
1082 free((void *)cparam->msgp);
1083 cparam->msgp = NULL;
1085 cleanup_errstring(cparam->errstring);
1086 break;
1089 case RDR_CONF_PRIVATE_FUNC: {
1091 private_func_params_t *pparam;
1092 pparam = (private_func_params_t *)param;
1094 cleanup_ap_ids(pparam->num_ap_ids, (char **)pparam->ap_ids);
1095 pparam->ap_ids = NULL;
1096 if (pparam->options != NULL) {
1097 free((void *)pparam->options);
1098 pparam->options = NULL;
1100 if (pparam->confp != NULL) {
1101 free((void *)pparam->confp);
1102 pparam->confp = NULL;
1104 if (pparam->msgp != NULL) {
1105 free((void *)pparam->msgp);
1106 pparam->msgp = NULL;
1108 cleanup_errstring(pparam->errstring);
1109 break;
1112 case RDR_CONF_TEST: {
1114 test_params_t *tparam;
1115 tparam = (test_params_t *)param;
1117 cleanup_ap_ids(tparam->num_ap_ids, (char **)tparam->ap_ids);
1118 tparam->ap_ids = NULL;
1119 if (tparam->options != NULL) {
1120 free((void *)tparam->options);
1121 tparam->options = NULL;
1123 if (tparam->msgp != NULL) {
1124 free((void *)tparam->msgp);
1125 tparam->msgp = NULL;
1127 cleanup_errstring(tparam->errstring);
1128 break;
1131 case RDR_CONF_LIST_EXT: {
1133 list_ext_params_t *lparam;
1134 lparam = (list_ext_params_t *)param;
1136 cleanup_ap_ids(lparam->num_ap_ids, (char **)lparam->ap_ids);
1137 lparam->ap_ids = NULL;
1139 if (lparam->nlist != NULL) {
1140 free((void *)lparam->nlist);
1141 lparam->nlist = NULL;
1143 if (lparam->ap_id_list != NULL) {
1144 if (*lparam->ap_id_list != NULL) {
1145 free((void *)*lparam->ap_id_list);
1147 free((void *)lparam->ap_id_list);
1148 lparam->ap_id_list = NULL;
1150 if (lparam->ap_id_list != NULL) {
1151 free((void *)lparam->ap_id_list);
1152 lparam->ap_id_list = NULL;
1155 if (lparam->options != NULL) {
1156 free((void *)lparam->options);
1157 lparam->options = NULL;
1159 if (lparam->listopts != NULL) {
1160 free((void *)lparam->listopts);
1161 lparam->listopts = NULL;
1163 cleanup_errstring(lparam->errstring);
1164 break;
1167 case RDR_CONF_HELP: {
1169 help_params_t *hparam;
1170 hparam = (help_params_t *)param;
1172 cleanup_ap_ids(hparam->num_ap_ids, (char **)hparam->ap_ids);
1173 hparam->ap_ids = NULL;
1174 if (hparam->msgp != NULL) {
1175 free((void *)hparam->msgp);
1176 hparam->msgp = NULL;
1178 if (hparam->options != NULL) {
1179 free((void *)hparam->options);
1180 hparam->options = NULL;
1182 break;
1185 case RDR_CONF_AP_ID_CMP: {
1187 ap_id_cmp_params_t *aparam;
1188 aparam = (ap_id_cmp_params_t *)param;
1190 if (aparam->ap_log_id1 != NULL) {
1191 free((void *)aparam->ap_log_id1);
1192 aparam->ap_log_id1 = NULL;
1194 if (aparam->ap_log_id2 != NULL) {
1195 free((void *)aparam->ap_log_id2);
1196 aparam->ap_log_id2 = NULL;
1198 break;
1201 case RDR_CONF_ABORT_CMD:
1203 /* nothing to deallocate */
1204 break;
1206 case RDR_CONF_CONFIRM_CALLBACK: {
1208 confirm_callback_params_t *cparam;
1209 cparam = (confirm_callback_params_t *)param;
1211 if (cparam->confp != NULL) {
1212 free((void *)cparam->confp);
1213 cparam->confp = NULL;
1215 if (cparam->message != NULL) {
1216 free((void *)cparam->message);
1217 cparam->message = NULL;
1219 break;
1222 case RDR_CONF_MSG_CALLBACK: {
1224 msg_callback_params_t *mparam;
1225 mparam = (msg_callback_params_t *)param;
1227 if (mparam->msgp != NULL) {
1228 free((void *)mparam->msgp);
1229 mparam->msgp = NULL;
1231 if (mparam->message != NULL) {
1232 free((void *)mparam->message);
1233 mparam->message = NULL;
1235 break;
1238 default:
1239 return (RDR_ERROR);
1240 /* NOTREACHED */
1241 break;
1245 return (RDR_OK);
1249 * rdr_setsockopt:
1251 * Wrapper of the setsockopt(3SOCKET) library function.
1254 rdr_setsockopt(int fd, int level, int optname, const void *optval, int optlen)
1256 if (setsockopt(fd, level, optname, optval, optlen) == -1)
1257 return (RDR_NET_ERR);
1258 else
1259 return (RDR_OK);
1264 * Private (static) Functions
1269 * rdr_setopt:
1271 * Set the specified option for a given transport endpoint.
1272 * This function only sets boolean options. It does not
1273 * provide the ability to unset an option, or set a non-
1274 * boolean option.
1276 static int
1277 rdr_setopt(int fd, int name, int level)
1279 int on = 1;
1282 if (setsockopt(fd, level, name, &on, sizeof (on)) == -1) {
1283 return (RDR_NET_ERR);
1286 return (RDR_OK);
1291 * rdr_bind:
1293 * Bind the specified file descriptor to a specified
1294 * address. If the address is already bound, no error is
1295 * returned. This is the expected behavior if a server
1296 * has been started by inetd (1M).
1298 static int
1299 rdr_bind(int fd, struct sockaddr *addr)
1301 unsigned int addr_len;
1302 int rc;
1305 /* initialize the address */
1306 switch (addr->sa_family) {
1308 case AF_INET:
1309 addr_len = sizeof (struct sockaddr_in);
1310 break;
1312 case AF_INET6:
1313 addr_len = sizeof (struct sockaddr_in6);
1314 break;
1316 default:
1317 return (RDR_ERROR);
1320 /* attempt to bind the address */
1321 rc = bind(fd, addr, addr_len);
1324 * Ignore the error if EINVAL is returned. In
1325 * this case, we assume that this means that
1326 * the address was already bound. This is not
1327 * an error for servers started by inetd (1M).
1329 if ((rc == -1) && (errno != EINVAL)) {
1330 return (RDR_NET_ERR);
1334 * Retreive the address information of the
1335 * address that was actually bound.
1337 addr_len = sizeof (*addr);
1338 if (getsockname(fd, addr, &addr_len) == -1) {
1339 (void) memset(addr, 0, sizeof (*addr));
1340 return (RDR_NET_ERR);
1343 return (RDR_OK);
1348 * rdr_secure:
1350 * Activate security features for a socket.
1352 * Some platforms have libdscp, which provides additional
1353 * security features. An attempt is made to load libdscp
1354 * and use these features.
1356 * Nothing is done if libdscp is not available.
1358 static int
1359 rdr_secure(int fd, struct sockaddr *addr)
1361 struct sockaddr_in *sin;
1362 int port;
1363 int error;
1365 if (use_libdscp == 0) {
1366 return (RDR_OK);
1369 if (load_libdscp(&libdscp) != 1) {
1370 return (RDR_ERROR);
1373 /* LINTED E_BAD_PTR_CAST_ALIGN */
1374 sin = (struct sockaddr_in *)addr;
1375 port = ntohs(sin->sin_port);
1376 error = libdscp.bind(0, fd, port);
1378 if ((error != DSCP_OK) && (error != DSCP_ERROR_ALREADY)) {
1379 return (RDR_ERROR);
1382 if (libdscp.secure(0, fd) != DSCP_OK) {
1383 return (RDR_ERROR);
1385 return (RDR_OK);
1389 * rdr_auth:
1391 * Authenticate if a connection is really from the service
1392 * processor. This is dependent upon functionality from
1393 * libdscp, so an attempt to load and use libdscp is made.
1395 * Without libdscp, this function does nothing.
1397 static int
1398 rdr_auth(struct sockaddr *addr, int len)
1400 if (use_libdscp != 0) {
1401 if ((load_libdscp(&libdscp) == 0) ||
1402 (libdscp.auth(0, addr, len) != DSCP_OK)) {
1403 return (RDR_ERROR);
1407 return (RDR_OK);
1411 * rdr_snd:
1413 * Send a message in two stages. First the header is sent,
1414 * followed by the packed buffer containing the message
1415 * contents.
1417 static int
1418 rdr_snd(int fd, rdr_msg_hdr_t *hdr, char *data, int data_sz, int timeout)
1420 int err;
1423 /* sanity check */
1424 if (hdr == NULL) {
1425 return (RDR_ERROR);
1428 /* ensure null pad bytes */
1429 hdr->pad_byte1 = 0;
1430 hdr->pad_byte2 = 0;
1432 /* initialize size information */
1433 hdr->data_length = data_sz;
1435 /* send message header */
1436 err = rdr_snd_raw(fd, (char *)hdr, RDR_MSG_HDR_SIZE, timeout);
1437 if (err != RDR_OK) {
1438 return (err);
1441 /* check if more to send */
1442 if (data_sz == 0) {
1443 return (RDR_OK);
1446 /* send message data */
1447 err = rdr_snd_raw(fd, data, data_sz, timeout);
1448 if (err != RDR_OK) {
1449 return (err);
1452 return (RDR_OK);
1457 * rdr_snd_raw:
1459 * Send a raw buffer of information. This function handles
1460 * the low level details of the send operation.
1462 static int
1463 rdr_snd_raw(int fd, char *msg, int data_sz, int timeout)
1465 int err;
1466 int num_bytes;
1467 int bytes_left;
1468 char *bufp;
1469 struct pollfd pfd;
1472 bufp = (char *)msg;
1474 bytes_left = data_sz;
1476 pfd.fd = fd;
1477 pfd.events = POLLOUT;
1479 while (bytes_left > 0) {
1481 pfd.revents = 0;
1483 /* wait until we can send the data */
1484 if ((err = poll(&pfd, 1, timeout)) == -1) {
1486 /* poll was interrupted */
1487 if (errno == EINTR) {
1488 return (RDR_ABORTED);
1491 return (RDR_ERROR);
1493 } else if (err == 0) {
1494 return (RDR_TIMEOUT);
1497 /* ready to send data */
1498 if (pfd.revents & POLLOUT) {
1500 num_bytes = write(fd, bufp, bytes_left);
1502 if (num_bytes == -1) {
1505 * Distinguish between an aborted
1506 * session and other network errors.
1508 if (errno == EPIPE) {
1509 return (RDR_ABORTED);
1510 } else {
1511 return (RDR_NET_ERR);
1515 /* wrote 0 bytes, so operation was aborted */
1516 if (num_bytes == 0) {
1517 return (RDR_ABORTED);
1520 } else {
1521 return (RDR_NET_ERR);
1524 bytes_left -= num_bytes;
1525 bufp += num_bytes;
1528 return (RDR_OK);
1533 * rdr_rcv:
1535 * Receive a message in two stages. First the header is
1536 * received, followed by the packed buffer containing the
1537 * message contents.
1539 static int
1540 rdr_rcv(int fd, rdr_msg_hdr_t *hdr, char **data, int timeout)
1542 int err;
1543 int data_sz;
1544 char hdr_buf[RDR_MSG_HDR_SIZE];
1545 char *buf = NULL;
1548 /* sanity check */
1549 if (hdr == NULL) {
1550 return (RDR_ERROR);
1553 /* receive the header */
1554 err = rdr_rcv_raw(fd, hdr_buf, RDR_MSG_HDR_SIZE, timeout);
1555 if (err != RDR_OK) {
1556 return (err);
1559 /* verify that the data is good */
1560 /* LINTED Pointer Cast Alignment Warning */
1561 if (validate_header((rdr_msg_hdr_t *)hdr_buf) != RDR_OK) {
1562 return (RDR_MSG_INVAL);
1565 /* LINTED Pointer Cast Alignment Warning */
1566 data_sz = ((rdr_msg_hdr_t *)hdr_buf)->data_length;
1568 buf = (char *)malloc(data_sz);
1569 if (!buf) {
1570 return (RDR_MEM_ALLOC);
1573 if (data_sz != 0) {
1575 /* receive the rest of the message */
1576 err = rdr_rcv_raw(fd, buf, data_sz, timeout);
1577 if (err != RDR_OK) {
1578 free((void *)buf);
1579 return (err);
1583 /* copy out data */
1584 *data = buf;
1585 (void) memcpy(hdr, hdr_buf, RDR_MSG_HDR_SIZE);
1587 return (RDR_OK);
1592 * rdr_rcv_raw:
1594 * Receive a raw buffer of information. This function handles
1595 * the low level details of the receive operation.
1597 static int
1598 rdr_rcv_raw(int fd, char *msg, int data_size, int timeout)
1600 int num_bytes;
1601 int err;
1602 int bytes_left;
1603 char *bufp;
1604 struct pollfd pollfd;
1607 bufp = (char *)msg;
1608 bytes_left = data_size;
1610 pollfd.fd = fd;
1611 pollfd.events = POLLIN;
1613 while (bytes_left > 0) {
1615 errno = 0;
1616 pollfd.revents = 0;
1618 if ((err = poll(&pollfd, 1, timeout)) == -1) {
1621 * In the DCA, if a session is aborted, SIGINT
1622 * is delivered to all active sessions. This
1623 * mistakenly causes all sessions waiting in
1624 * the poll to be interrupted. So, if EINTR
1625 * is returned, it is ignored. If another error
1626 * occurs right away, the current session really
1627 * was aborted. All other sessions won't encounter
1628 * an error and will proceed normally.
1630 if ((errno == 0) || (errno == EINTR)) {
1631 continue;
1634 return (RDR_ABORTED);
1636 } else if (err == 0) {
1637 return (RDR_TIMEOUT);
1640 /* ready to receive data */
1641 if (pollfd.revents & POLLIN) {
1643 num_bytes = read(fd, bufp, bytes_left);
1645 if (num_bytes == -1) {
1648 * Distinguish between an aborted
1649 * session and other network errors.
1651 if (errno == ECONNRESET) {
1652 return (RDR_ABORTED);
1653 } else {
1654 return (RDR_NET_ERR);
1658 /* read 0 bytes, so operation was aborted */
1659 if (num_bytes == 0) {
1660 return (RDR_ABORTED);
1663 } else {
1664 return (RDR_NET_ERR);
1667 bytes_left -= num_bytes;
1668 bufp += num_bytes;
1671 return (RDR_OK);
1676 * validate_header:
1678 * Perform a series of sanity checks on the header data that is
1679 * received. This gets called before the variable length data is
1680 * read in to make sure that the information in the header can
1681 * be trusted.
1683 static int
1684 validate_header(rdr_msg_hdr_t *hdr)
1686 unsigned char op;
1689 if (hdr == NULL) {
1690 return (RDR_ERROR);
1693 op = hdr->message_opcode;
1695 /* validate opcode */
1696 if ((op < RDR_SES_REQ) || (op >= RDR_NUM_OPS)) {
1697 return (RDR_ERROR);
1700 /* validate message size (and type) for op */
1701 switch (hdr->data_type) {
1703 case RDR_REQUEST:
1704 if (hdr->data_length > msg_sizes[op].req_max) {
1705 return (RDR_ERROR);
1707 break;
1709 case RDR_REPLY:
1710 if (hdr->data_length > msg_sizes[op].reply_max) {
1711 return (RDR_ERROR);
1713 break;
1715 default:
1716 /* invalid data type */
1717 return (RDR_ERROR);
1720 /* all checks passed */
1721 return (RDR_OK);
1726 * pack_ses_req_request:
1728 * Handle packing a session request request message.
1730 static int
1731 pack_ses_req_request(ses_req_params_t *params, char **buf, int *buf_size)
1733 char *bufptr;
1734 int locale_str_len;
1735 rdr_ses_req_t ses_req;
1738 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
1739 return (RDR_ERROR);
1743 * Determine the size of the locale string
1745 if (params->locale_str != NULL) {
1746 locale_str_len = strlen(params->locale_str) + 1;
1747 } else {
1748 locale_str_len = 0;
1752 * Collect size info specific to the ses_req request message
1753 * and allocate a buffer
1755 *buf_size = sizeof (rdr_ses_req_t);
1756 *buf_size += locale_str_len;
1758 *buf = (char *)malloc(*buf_size);
1759 if (*buf == NULL) {
1760 return (RDR_MEM_ALLOC);
1764 * Set fixed locale size label by name
1766 ses_req.locale_size = locale_str_len;
1769 * Set variable information using memcpy
1771 bufptr = *buf;
1773 (void) memcpy(bufptr, &ses_req, sizeof (rdr_ses_req_t));
1774 bufptr += sizeof (rdr_ses_req_t);
1776 if (params->locale_str != NULL) {
1777 (void) memcpy(bufptr, params->locale_str, locale_str_len);
1778 bufptr += locale_str_len;
1781 return (RDR_OK);
1786 * unpack_ses_req_request:
1788 * Handle unpacking a session request request message.
1790 static int
1791 unpack_ses_req_request(ses_req_params_t *params, const char *buf)
1793 char *bufptr;
1794 rdr_ses_req_t ses_req_data;
1797 if ((params == NULL) || (buf == NULL)) {
1798 return (RDR_ERROR);
1801 bufptr = (char *)buf;
1802 (void) memcpy(&ses_req_data, bufptr, sizeof (rdr_ses_req_t));
1803 bufptr += sizeof (rdr_ses_req_t);
1806 * handle getting the locale string
1808 if (get_string_from_buf(&(params->locale_str),
1809 ses_req_data.locale_size, bufptr)) {
1810 return (RDR_ERROR);
1813 return (RDR_OK);
1818 * pack_ses_req_reply:
1820 * Handle packing a session request reply message.
1822 static int
1823 pack_ses_req_reply(ses_req_params_t *params, char **buf, int *buf_size)
1825 rdr_ses_req_reply_t ses_req_reply_data;
1828 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
1829 return (RDR_ERROR);
1833 * Collect size info specific to the session request reply
1834 * message and allocate a buffer
1836 *buf_size = sizeof (rdr_ses_req_reply_t);
1838 *buf = (char *)malloc(*buf_size);
1839 if (*buf == NULL) {
1840 return (RDR_MEM_ALLOC);
1844 * Set fixed session identifier
1846 ses_req_reply_data.session_id = params->session_id;
1849 * Copy information using memcpy
1851 (void) memcpy(*buf, &ses_req_reply_data, sizeof (rdr_ses_req_reply_t));
1853 return (RDR_OK);
1858 * unpack_ses_req_request:
1860 * Handle unpacking a session request reply message.
1862 static int
1863 unpack_ses_req_reply(ses_req_params_t *params, const char *buf)
1865 rdr_ses_req_reply_t *ses_req_reply_datap;
1868 if ((params == NULL) || (buf == NULL)) {
1869 return (RDR_ERROR);
1872 /* LINTED Pointer Cast Alignment Warning */
1873 ses_req_reply_datap = (rdr_ses_req_reply_t *)buf;
1876 * copy out the session information
1878 params->session_id = ses_req_reply_datap->session_id;
1880 return (RDR_OK);
1885 * pack_change_state_request:
1887 * Handle packing a change state request message.
1889 static int
1890 pack_change_state_request(change_state_params_t *params, char **buf,
1891 int *buf_size)
1893 int i;
1894 char *bufptr;
1895 rdr_change_state_t change_state_data;
1896 rdr_variable_message_info_t var_msg_info;
1899 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
1900 return (RDR_ERROR);
1903 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
1906 * Set variable length fields and make a call to partially
1907 * pack it.
1909 if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) {
1910 cleanup_variable_ap_id_info(&var_msg_info);
1911 return (RDR_ERROR);
1913 if (find_options_sizes(params->options, &var_msg_info)) {
1914 cleanup_variable_ap_id_info(&var_msg_info);
1915 return (RDR_ERROR);
1919 * Collect size info specific to the change_state request
1920 * message and allocate a buffer
1922 *buf_size = sizeof (rdr_change_state_t);
1923 *buf_size += var_msg_info.ap_id_int_size;
1924 *buf_size += var_msg_info.ap_id_char_size;
1925 *buf_size += var_msg_info.options_strlen;
1926 *buf_size += var_msg_info.options_pad_sz;
1928 *buf = (char *)malloc(*buf_size);
1929 if (*buf == NULL) {
1930 cleanup_variable_ap_id_info(&var_msg_info);
1931 return (RDR_MEM_ALLOC);
1935 * Set fixed address labels by name
1937 change_state_data.num_ap_ids = params->num_ap_ids;
1938 change_state_data.ap_id_char_size = var_msg_info.ap_id_char_size;
1939 change_state_data.options_size = var_msg_info.options_strlen +
1940 var_msg_info.options_pad_sz;
1942 if (params->confp != NULL) {
1943 change_state_data.confirm_callback_id =
1944 (unsigned long)params->confp->confirm;
1945 change_state_data.confirm_appdata_ptr =
1946 (unsigned long)params->confp->appdata_ptr;
1947 } else {
1948 change_state_data.confirm_callback_id = 0;
1949 change_state_data.confirm_appdata_ptr = 0;
1951 if (params->msgp != NULL) {
1952 change_state_data.msg_callback_id =
1953 (unsigned long)params->msgp->message_routine;
1954 change_state_data.msg_appdata_ptr =
1955 (unsigned long)params->msgp->appdata_ptr;
1956 } else {
1957 change_state_data.msg_callback_id = 0;
1958 change_state_data.msg_appdata_ptr = 0;
1961 change_state_data.flags = params->flags;
1962 change_state_data.timeval = params->timeval;
1963 change_state_data.state_change_cmd = params->state_change;
1964 if (params->errstring != NULL) {
1965 change_state_data.error_msg_ctl = RDR_GENERATE_ERR_MSGS;
1966 } else {
1967 change_state_data.error_msg_ctl = RDR_DONT_GENERATE_ERR_MSGS;
1969 change_state_data.retries = params->retries;
1972 * Set variable information using memcpy
1974 bufptr = *buf;
1976 (void) memcpy(bufptr, &change_state_data, sizeof (rdr_change_state_t));
1977 bufptr += sizeof (rdr_change_state_t);
1979 if (var_msg_info.ap_id_sizes != NULL) {
1980 (void) memcpy(bufptr, var_msg_info.ap_id_sizes,
1981 var_msg_info.ap_id_int_size);
1982 bufptr += var_msg_info.ap_id_int_size;
1985 if (var_msg_info.ap_id_chars != NULL) {
1986 (void) memcpy(bufptr, var_msg_info.ap_id_chars,
1987 var_msg_info.ap_id_char_size);
1988 bufptr += var_msg_info.ap_id_char_size;
1991 if (params->options != NULL) {
1992 (void) memcpy(bufptr, params->options,
1993 var_msg_info.options_strlen);
1994 bufptr += var_msg_info.options_strlen;
1995 for (i = 0; i < var_msg_info.options_pad_sz; i++) {
1996 bufptr[i] = 0;
1998 bufptr += var_msg_info.options_pad_sz;
2001 cleanup_variable_ap_id_info(&var_msg_info);
2003 return (RDR_OK);
2008 * unpack_change_state_request:
2010 * Handle unpacking a change state request message.
2012 static int
2013 unpack_change_state_request(change_state_params_t *params, const char *buf)
2015 char *bufptr;
2016 rdr_variable_message_info_t var_msg_info;
2017 rdr_change_state_t change_state_data;
2020 if ((params == NULL) || (buf == NULL)) {
2021 return (RDR_ERROR);
2024 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
2026 bufptr = (char *)buf;
2027 (void) memcpy(&change_state_data, bufptr, sizeof (rdr_change_state_t));
2028 bufptr += sizeof (rdr_change_state_t);
2031 * handle getting the ap_ids
2033 var_msg_info.ap_id_char_size = change_state_data.ap_id_char_size;
2034 if (get_ap_ids_from_buf((char ***)&(params->ap_ids),
2035 change_state_data.num_ap_ids, &var_msg_info, bufptr)) {
2036 return (RDR_ERROR);
2038 bufptr += var_msg_info.ap_id_int_size;
2039 bufptr += var_msg_info.ap_id_char_size;
2042 * handle getting the options
2044 if (get_string_from_buf(&(params->options),
2045 change_state_data.options_size, bufptr)) {
2046 return (RDR_ERROR);
2048 bufptr += change_state_data.options_size;
2051 * Set fixed address labels by name
2053 params->state_change = (cfga_cmd_t)change_state_data.state_change_cmd;
2054 params->num_ap_ids = change_state_data.num_ap_ids;
2056 params->confp = (struct cfga_confirm *)
2057 malloc(sizeof (struct cfga_confirm));
2058 if (params->confp == NULL) {
2059 return (RDR_MEM_ALLOC);
2062 /* set params->confp->confirm using memcpy */
2063 (void) memcpy((void*)params->confp,
2064 &(change_state_data.confirm_callback_id), sizeof (unsigned long));
2065 params->confp->appdata_ptr =
2066 (void*)change_state_data.confirm_appdata_ptr;
2068 params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg));
2069 if (params->msgp == NULL) {
2070 return (RDR_MEM_ALLOC);
2073 /* set params->msgp->message_routine using memcpy */
2074 (void) memcpy((void*)params->msgp,
2075 &(change_state_data.msg_callback_id), sizeof (unsigned long));
2076 params->msgp->appdata_ptr =
2077 (void*)change_state_data.msg_appdata_ptr;
2079 if (change_state_data.error_msg_ctl == RDR_GENERATE_ERR_MSGS) {
2080 params->errstring = (char **)malloc(sizeof (char *));
2081 if (params->errstring == NULL) {
2082 return (RDR_MEM_ALLOC);
2084 *(params->errstring) = NULL;
2085 } else { /* error_msg_ctl == RDR_DONT_GENERATE_ERR_MSGS */
2086 params->errstring = NULL;
2088 params->flags = change_state_data.flags;
2089 params->timeval = change_state_data.timeval;
2090 params->retries = change_state_data.retries;
2092 return (RDR_OK);
2097 * pack_change_state_reply:
2099 * Handle packing a change state reply message.
2101 static int
2102 pack_change_state_reply(change_state_params_t *params, char **buf,
2103 int *buf_size)
2105 int i;
2106 char *bufptr;
2107 rdr_change_state_reply_t change_state_data;
2108 rdr_variable_message_info_t var_msg_info;
2111 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
2113 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
2114 return (RDR_ERROR);
2118 * Set variable length fields (size info)
2120 if (find_errstring_sizes(params->errstring, &var_msg_info)) {
2121 return (RDR_ERROR);
2125 * Collect size info specific to the change_state reply
2126 * message and allocate a buffer
2128 *buf_size = sizeof (rdr_change_state_reply_t);
2129 *buf_size += var_msg_info.errstring_strlen;
2130 *buf_size += var_msg_info.errstring_pad_sz;
2132 *buf = (char *)malloc(*buf_size);
2133 if (*buf == NULL) {
2134 return (RDR_MEM_ALLOC);
2138 * Set fixed address labels by name
2140 change_state_data.errstring_size = var_msg_info.errstring_strlen +
2141 var_msg_info.errstring_pad_sz;
2144 * Set variable information using memcpy
2146 bufptr = *buf;
2148 (void) memcpy(bufptr, &change_state_data,
2149 sizeof (rdr_change_state_reply_t));
2150 bufptr += sizeof (rdr_change_state_reply_t);
2152 if ((params->errstring != NULL) && (*(params->errstring) != NULL)) {
2153 (void) memcpy(bufptr, *(params->errstring),
2154 var_msg_info.errstring_strlen);
2155 bufptr += var_msg_info.errstring_strlen;
2156 for (i = 0; i < var_msg_info.errstring_pad_sz; i++) {
2157 bufptr[i] = 0;
2159 bufptr += var_msg_info.errstring_pad_sz;
2162 return (RDR_OK);
2167 * unpack_change_state_reply:
2169 * Handle unpacking a change state reply message.
2171 static int
2172 unpack_change_state_reply(change_state_params_t *params, const char *buf)
2174 char *bufptr;
2175 rdr_change_state_reply_t change_state_data;
2177 if ((params == NULL) || (buf == NULL)) {
2178 return (RDR_ERROR);
2181 bufptr = (char *)buf;
2182 (void) memcpy(&change_state_data, bufptr,
2183 sizeof (rdr_change_state_reply_t));
2184 bufptr += sizeof (rdr_change_state_reply_t);
2187 * handle getting the errstring
2189 params->errstring = (char **)malloc(sizeof (char *));
2190 if (params->errstring == NULL) {
2191 return (RDR_MEM_ALLOC);
2193 if (get_string_from_buf(params->errstring,
2194 change_state_data.errstring_size, bufptr)) {
2195 return (RDR_ERROR);
2197 bufptr += change_state_data.errstring_size;
2199 return (RDR_OK);
2204 * pack_private_func_request:
2206 * Handle packing a private function request message.
2208 static int
2209 pack_private_func_request(private_func_params_t *params, char **buf,
2210 int *buf_size)
2212 int i;
2213 char *bufptr;
2214 rdr_private_func_t private_func_data;
2215 rdr_variable_message_info_t var_msg_info;
2218 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
2219 return (RDR_ERROR);
2222 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
2225 * Set variable length fields and make a call to partially
2226 * pack it.
2228 if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) {
2229 cleanup_variable_ap_id_info(&var_msg_info);
2230 return (RDR_ERROR);
2232 if (find_options_sizes(params->options, &var_msg_info)) {
2233 cleanup_variable_ap_id_info(&var_msg_info);
2234 return (RDR_ERROR);
2236 if (find_function_sizes(params->function, &var_msg_info)) {
2237 cleanup_variable_ap_id_info(&var_msg_info);
2238 return (RDR_ERROR);
2242 * Collect size info specific to the private_func request
2243 * message and allocate a buffer
2245 *buf_size = sizeof (rdr_private_func_t);
2246 *buf_size += var_msg_info.ap_id_int_size;
2247 *buf_size += var_msg_info.ap_id_char_size;
2248 *buf_size += var_msg_info.options_strlen;
2249 *buf_size += var_msg_info.options_pad_sz;
2250 *buf_size += var_msg_info.function_strlen;
2251 *buf_size += var_msg_info.function_pad_sz;
2253 *buf = (char *)malloc(*buf_size);
2254 if (*buf == NULL) {
2255 cleanup_variable_ap_id_info(&var_msg_info);
2256 return (RDR_MEM_ALLOC);
2260 * Set fixed address labels by name
2262 private_func_data.num_ap_ids = params->num_ap_ids;
2263 private_func_data.ap_id_char_size = var_msg_info.ap_id_char_size;
2264 private_func_data.options_size = var_msg_info.options_strlen +
2265 var_msg_info.options_pad_sz;
2266 private_func_data.function_size = var_msg_info.function_strlen +
2267 var_msg_info.function_pad_sz;
2269 if (params->confp != NULL) {
2270 private_func_data.confirm_callback_id =
2271 (unsigned long)params->confp->confirm;
2272 private_func_data.confirm_appdata_ptr =
2273 (unsigned long)params->confp->appdata_ptr;
2274 } else {
2275 private_func_data.confirm_callback_id = 0;
2276 private_func_data.confirm_appdata_ptr = 0;
2278 if (params->msgp != NULL) {
2279 private_func_data.msg_callback_id =
2280 (unsigned long)params->msgp->message_routine;
2281 private_func_data.msg_appdata_ptr =
2282 (unsigned long)params->msgp->appdata_ptr;
2283 } else {
2284 private_func_data.msg_callback_id = 0;
2285 private_func_data.msg_appdata_ptr = 0;
2288 private_func_data.flags = params->flags;
2290 if (params->errstring != NULL) {
2291 private_func_data.error_msg_ctl = RDR_GENERATE_ERR_MSGS;
2292 } else {
2293 private_func_data.error_msg_ctl = RDR_DONT_GENERATE_ERR_MSGS;
2297 * Set variable information using memcpy
2299 bufptr = *buf;
2301 (void) memcpy(bufptr, &private_func_data, sizeof (rdr_private_func_t));
2302 bufptr += sizeof (rdr_private_func_t);
2304 if (var_msg_info.ap_id_sizes != NULL) {
2305 (void) memcpy(bufptr, var_msg_info.ap_id_sizes,
2306 var_msg_info.ap_id_int_size);
2307 bufptr += var_msg_info.ap_id_int_size;
2310 if (var_msg_info.ap_id_chars != NULL) {
2311 (void) memcpy(bufptr, var_msg_info.ap_id_chars,
2312 var_msg_info.ap_id_char_size);
2313 bufptr += var_msg_info.ap_id_char_size;
2316 if (params->options != NULL) {
2317 (void) memcpy(bufptr, params->options,
2318 var_msg_info.options_strlen);
2319 bufptr += var_msg_info.options_strlen;
2320 for (i = 0; i < var_msg_info.options_pad_sz; i++) {
2321 bufptr[i] = 0;
2323 bufptr += var_msg_info.options_pad_sz;
2326 if (params->function != NULL) {
2327 (void) memcpy(bufptr, params->function,
2328 var_msg_info.function_strlen);
2329 bufptr += var_msg_info.function_strlen;
2330 for (i = 0; i < var_msg_info.function_pad_sz; i++) {
2331 bufptr[i] = 0;
2333 bufptr += var_msg_info.function_pad_sz;
2336 cleanup_variable_ap_id_info(&var_msg_info);
2338 return (RDR_OK);
2343 * unpack_private_func_request:
2345 * Handle unpacking a private function request message.
2347 static int
2348 unpack_private_func_request(private_func_params_t *params, const char *buf)
2350 char *bufptr;
2351 rdr_variable_message_info_t var_msg_info;
2352 rdr_private_func_t private_func_data;
2355 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
2357 if ((params == NULL) || (buf == NULL)) {
2358 return (RDR_ERROR);
2361 bufptr = (char *)buf;
2362 (void) memcpy(&private_func_data, bufptr, sizeof (rdr_private_func_t));
2363 bufptr += sizeof (rdr_private_func_t);
2366 * handle getting the ap_ids
2368 var_msg_info.ap_id_char_size = private_func_data.ap_id_char_size;
2369 if (get_ap_ids_from_buf((char ***)&(params->ap_ids),
2370 private_func_data.num_ap_ids, &var_msg_info, bufptr)) {
2371 return (RDR_ERROR);
2373 bufptr += var_msg_info.ap_id_int_size;
2374 bufptr += var_msg_info.ap_id_char_size;
2377 * handle getting the options and function
2379 if (get_string_from_buf(&(params->options),
2380 private_func_data.options_size, bufptr)) {
2381 return (RDR_ERROR);
2383 bufptr += private_func_data.options_size;
2385 if (get_string_from_buf(&(params->function),
2386 private_func_data.function_size, bufptr)) {
2387 return (RDR_ERROR);
2389 bufptr += private_func_data.function_size;
2392 * Set fixed address labels by name
2394 params->num_ap_ids = private_func_data.num_ap_ids;
2396 params->confp = (struct cfga_confirm *)
2397 malloc(sizeof (struct cfga_confirm));
2398 if (params->confp == NULL) {
2399 return (RDR_MEM_ALLOC);
2402 /* set params->confp->confirm using memcpy */
2403 (void) memcpy((void*)params->confp,
2404 &(private_func_data.confirm_callback_id), sizeof (unsigned long));
2405 params->confp->appdata_ptr =
2406 (void*)private_func_data.confirm_appdata_ptr;
2408 params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg));
2409 if (params->msgp == NULL) {
2410 return (RDR_MEM_ALLOC);
2413 /* set params->msgp->message_routine using memcpy */
2414 (void) memcpy((void*)params->msgp,
2415 &(private_func_data.msg_callback_id), sizeof (unsigned long));
2416 params->msgp->appdata_ptr =
2417 (void*)private_func_data.msg_appdata_ptr;
2419 if (private_func_data.error_msg_ctl == RDR_GENERATE_ERR_MSGS) {
2420 params->errstring = (char **)malloc(sizeof (char *));
2421 if (params->errstring == NULL) {
2422 return (RDR_MEM_ALLOC);
2424 *(params->errstring) = NULL;
2425 } else { /* error_msg_ctl == RDR_DONT_GENERATE_ERR_MSGS */
2426 params->errstring = NULL;
2428 params->flags = private_func_data.flags;
2430 return (RDR_OK);
2435 * pack_private_func_reply:
2437 * Handle packing a private function reply message.
2439 static int
2440 pack_private_func_reply(private_func_params_t *params, char **buf,
2441 int *buf_size)
2443 int i;
2444 char *bufptr;
2445 rdr_private_func_reply_t private_func_data;
2446 rdr_variable_message_info_t var_msg_info;
2449 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
2451 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
2452 return (RDR_ERROR);
2456 * Set variable length fields (size info)
2458 if (find_errstring_sizes(params->errstring, &var_msg_info)) {
2459 return (RDR_ERROR);
2463 * Collect size info specific to the private_func reply
2464 * message and allocate a buffer
2466 *buf_size = sizeof (rdr_private_func_reply_t);
2467 *buf_size += var_msg_info.errstring_strlen;
2468 *buf_size += var_msg_info.errstring_pad_sz;
2470 *buf = (char *)malloc(*buf_size);
2471 if (*buf == NULL) {
2472 return (RDR_MEM_ALLOC);
2476 * Set fixed address labels by name
2478 private_func_data.errstring_size = var_msg_info.errstring_strlen +
2479 var_msg_info.errstring_pad_sz;
2482 * Set variable information using memcpy
2484 bufptr = *buf;
2486 (void) memcpy(bufptr, &private_func_data,
2487 sizeof (rdr_private_func_reply_t));
2488 bufptr += sizeof (rdr_private_func_reply_t);
2489 if ((params->errstring != NULL) && (*(params->errstring) != NULL)) {
2490 (void) memcpy(bufptr, *(params->errstring),
2491 var_msg_info.errstring_strlen);
2492 bufptr += var_msg_info.errstring_strlen;
2493 for (i = 0; i < var_msg_info.errstring_pad_sz; i++) {
2494 bufptr[i] = 0;
2496 bufptr += var_msg_info.errstring_pad_sz;
2499 return (RDR_OK);
2504 * unpack_private_func_reply:
2506 * Handle unpacking a private function reply message.
2508 static int
2509 unpack_private_func_reply(private_func_params_t *params, const char *buf)
2511 char *bufptr;
2512 rdr_private_func_reply_t private_func_data;
2514 if ((params == NULL) || (buf == NULL)) {
2515 return (RDR_ERROR);
2518 bufptr = (char *)buf;
2519 (void) memcpy(&private_func_data, bufptr,
2520 sizeof (rdr_private_func_reply_t));
2521 bufptr += sizeof (rdr_private_func_reply_t);
2524 * handle getting the errstring
2526 params->errstring = (char **)malloc(sizeof (char *));
2527 if (params->errstring == NULL) {
2528 return (RDR_MEM_ALLOC);
2530 if (get_string_from_buf(params->errstring,
2531 private_func_data.errstring_size, bufptr)) {
2532 return (RDR_ERROR);
2534 bufptr += private_func_data.errstring_size;
2536 return (RDR_OK);
2541 * pack_test_request:
2543 * Handle packing a test request message.
2545 static int
2546 pack_test_request(test_params_t *params, char **buf, int *buf_size)
2548 int i;
2549 char *bufptr;
2550 rdr_test_t test_data;
2551 rdr_variable_message_info_t var_msg_info;
2554 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
2555 return (RDR_ERROR);
2558 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
2561 * Set variable length fields and make a call to partially
2562 * pack it.
2564 if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) {
2565 cleanup_variable_ap_id_info(&var_msg_info);
2566 return (RDR_ERROR);
2568 if (find_options_sizes(params->options, &var_msg_info)) {
2569 cleanup_variable_ap_id_info(&var_msg_info);
2570 return (RDR_ERROR);
2574 * Collect size info specific to the test request
2575 * message and allocate a buffer
2577 *buf_size = sizeof (rdr_test_t);
2578 *buf_size += var_msg_info.ap_id_int_size;
2579 *buf_size += var_msg_info.ap_id_char_size;
2580 *buf_size += var_msg_info.options_strlen;
2581 *buf_size += var_msg_info.options_pad_sz;
2583 *buf = (char *)malloc(*buf_size);
2584 if (*buf == NULL) {
2585 cleanup_variable_ap_id_info(&var_msg_info);
2586 return (RDR_MEM_ALLOC);
2590 * Set fixed address labels by name
2592 test_data.num_ap_ids = params->num_ap_ids;
2593 test_data.ap_id_char_size = var_msg_info.ap_id_char_size;
2594 test_data.options_size = var_msg_info.options_strlen +
2595 var_msg_info.options_pad_sz;
2597 if (params->msgp != NULL) {
2598 test_data.msg_callback_id =
2599 (unsigned long)params->msgp->message_routine;
2600 test_data.msg_appdata_ptr =
2601 (unsigned long)params->msgp->appdata_ptr;
2602 } else {
2603 test_data.msg_callback_id = 0;
2604 test_data.msg_appdata_ptr = 0;
2607 test_data.flags = params->flags;
2609 if (params->errstring != NULL) {
2610 test_data.error_msg_ctl = RDR_GENERATE_ERR_MSGS;
2611 } else {
2612 test_data.error_msg_ctl = RDR_DONT_GENERATE_ERR_MSGS;
2616 * Set variable information using memcpy
2618 bufptr = *buf;
2620 (void) memcpy(bufptr, &test_data, sizeof (rdr_test_t));
2621 bufptr += sizeof (rdr_test_t);
2623 if (var_msg_info.ap_id_sizes != NULL) {
2624 (void) memcpy(bufptr, var_msg_info.ap_id_sizes,
2625 var_msg_info.ap_id_int_size);
2626 bufptr += var_msg_info.ap_id_int_size;
2629 if (var_msg_info.ap_id_chars != NULL) {
2630 (void) memcpy(bufptr, var_msg_info.ap_id_chars,
2631 var_msg_info.ap_id_char_size);
2632 bufptr += var_msg_info.ap_id_char_size;
2635 if (params->options != NULL) {
2636 (void) memcpy(bufptr, params->options,
2637 var_msg_info.options_strlen);
2638 bufptr += var_msg_info.options_strlen;
2639 for (i = 0; i < var_msg_info.options_pad_sz; i++) {
2640 bufptr[i] = 0;
2642 bufptr += var_msg_info.options_pad_sz;
2645 cleanup_variable_ap_id_info(&var_msg_info);
2647 return (RDR_OK);
2652 * unpack_test_request:
2654 * Handle unpacking a test request message.
2656 static int
2657 unpack_test_request(test_params_t *params, const char *buf)
2659 char *bufptr;
2660 rdr_variable_message_info_t var_msg_info;
2661 rdr_test_t test_data;
2664 if ((params == NULL) || (buf == NULL)) {
2665 return (RDR_ERROR);
2668 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
2670 bufptr = (char *)buf;
2671 (void) memcpy(&test_data, bufptr, sizeof (rdr_test_t));
2672 bufptr += sizeof (rdr_test_t);
2675 * handle getting the ap_ids
2677 var_msg_info.ap_id_char_size = test_data.ap_id_char_size;
2678 if (get_ap_ids_from_buf((char ***)&(params->ap_ids),
2679 test_data.num_ap_ids, &var_msg_info, bufptr)) {
2680 return (RDR_ERROR);
2682 bufptr += var_msg_info.ap_id_int_size;
2683 bufptr += var_msg_info.ap_id_char_size;
2686 * handle getting the options
2688 if (get_string_from_buf(&(params->options),
2689 test_data.options_size, bufptr)) {
2690 return (RDR_ERROR);
2692 bufptr += test_data.options_size;
2695 * Set fixed address labels by name
2697 params->num_ap_ids = test_data.num_ap_ids;
2699 params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg));
2700 if (params->msgp == NULL) {
2701 return (RDR_MEM_ALLOC);
2704 /* set params->msgp->message_routine using memcpy */
2705 (void) memcpy((void*)params->msgp,
2706 &(test_data.msg_callback_id), sizeof (unsigned long));
2707 params->msgp->appdata_ptr =
2708 (void*)test_data.msg_appdata_ptr;
2710 if (test_data.error_msg_ctl == RDR_GENERATE_ERR_MSGS) {
2711 params->errstring = (char **)malloc(sizeof (char *));
2712 if (params->errstring == NULL) {
2713 return (RDR_MEM_ALLOC);
2715 *(params->errstring) = NULL;
2716 } else { /* error_msg_ctl == RDR_DONT_GENERATE_ERR_MSGS */
2717 params->errstring = NULL;
2719 params->flags = test_data.flags;
2721 return (RDR_OK);
2726 * pack_test_reply:
2728 * Handle packing a test reply message.
2730 static int
2731 pack_test_reply(test_params_t *params, char **buf, int *buf_size)
2733 int i;
2734 char *bufptr;
2735 rdr_test_reply_t test_data;
2736 rdr_variable_message_info_t var_msg_info;
2739 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
2740 return (RDR_ERROR);
2743 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
2746 * Set variable length fields (size info)
2748 if (find_errstring_sizes(params->errstring, &var_msg_info)) {
2749 return (RDR_ERROR);
2753 * Collect size info specific to the test reply
2754 * message and allocate a buffer
2756 *buf_size = sizeof (rdr_test_reply_t);
2757 *buf_size += var_msg_info.errstring_strlen;
2758 *buf_size += var_msg_info.errstring_pad_sz;
2760 *buf = (char *)malloc(*buf_size);
2761 if (*buf == NULL) {
2762 return (RDR_MEM_ALLOC);
2766 * Set fixed address labels by name
2768 test_data.errstring_size = var_msg_info.errstring_strlen +
2769 var_msg_info.errstring_pad_sz;
2772 * Set variable information using memcpy
2774 bufptr = *buf;
2776 (void) memcpy(bufptr, &test_data, sizeof (rdr_test_reply_t));
2777 bufptr += sizeof (rdr_test_reply_t);
2778 if ((params->errstring != NULL) && (*(params->errstring) != NULL)) {
2779 (void) memcpy(bufptr, *(params->errstring),
2780 var_msg_info.errstring_strlen);
2781 bufptr += var_msg_info.errstring_strlen;
2782 for (i = 0; i < var_msg_info.errstring_pad_sz; i++) {
2783 bufptr[i] = 0;
2785 bufptr += var_msg_info.errstring_pad_sz;
2788 return (RDR_OK);
2793 * unpack_test_reply:
2795 * Handle unpacking a test reply message.
2797 static int
2798 unpack_test_reply(test_params_t *params, const char *buf)
2800 char *bufptr;
2801 rdr_test_reply_t test_data;
2804 if ((params == NULL) || (buf == NULL)) {
2805 return (RDR_ERROR);
2808 bufptr = (char *)buf;
2809 (void) memcpy(&test_data, bufptr, sizeof (rdr_test_reply_t));
2810 bufptr += sizeof (rdr_test_reply_t);
2813 * handle getting the errstring
2815 params->errstring = (char **)malloc(sizeof (char *));
2816 if (params->errstring == NULL) {
2817 return (RDR_MEM_ALLOC);
2819 if (get_string_from_buf(params->errstring,
2820 test_data.errstring_size, bufptr)) {
2821 return (RDR_ERROR);
2823 bufptr += test_data.errstring_size;
2825 return (RDR_OK);
2830 * pack_list_ext_request:
2832 * Handle packing a list request message.
2834 static int
2835 pack_list_ext_request(list_ext_params_t *params, char **buf, int *buf_size)
2837 int i;
2838 char *bufptr;
2839 rdr_list_ext_t list_ext_data;
2840 rdr_variable_message_info_t var_msg_info;
2843 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
2844 return (RDR_ERROR);
2847 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
2850 * Set variable length fields and make a call to partially
2851 * pack it.
2853 if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) {
2854 cleanup_variable_ap_id_info(&var_msg_info);
2855 return (RDR_ERROR);
2857 if (find_options_sizes(params->options, &var_msg_info)) {
2858 cleanup_variable_ap_id_info(&var_msg_info);
2859 return (RDR_ERROR);
2861 if (find_listopts_sizes(params->listopts, &var_msg_info)) {
2862 cleanup_variable_ap_id_info(&var_msg_info);
2863 return (RDR_ERROR);
2868 * Collect size info specific to the list_ext request
2869 * message and allocate a buffer
2871 *buf_size = sizeof (rdr_list_ext_t);
2872 *buf_size += var_msg_info.ap_id_int_size;
2873 *buf_size += var_msg_info.ap_id_char_size;
2874 *buf_size += var_msg_info.options_strlen;
2875 *buf_size += var_msg_info.options_pad_sz;
2876 *buf_size += var_msg_info.listopts_strlen;
2877 *buf_size += var_msg_info.listopts_pad_sz;
2879 *buf = (char *)malloc(*buf_size);
2880 if (*buf == NULL) {
2881 cleanup_variable_ap_id_info(&var_msg_info);
2882 return (RDR_MEM_ALLOC);
2886 * Set fixed address labels by name
2888 list_ext_data.num_ap_ids = params->num_ap_ids;
2889 list_ext_data.ap_id_char_size = var_msg_info.ap_id_char_size;
2890 list_ext_data.options_size = var_msg_info.options_strlen +
2891 var_msg_info.options_pad_sz;
2892 list_ext_data.listopts_size = var_msg_info.listopts_strlen +
2893 var_msg_info.listopts_pad_sz;
2894 if (params->errstring != NULL) {
2895 list_ext_data.error_msg_ctl = RDR_GENERATE_ERR_MSGS;
2896 } else {
2897 list_ext_data.error_msg_ctl = RDR_DONT_GENERATE_ERR_MSGS;
2899 if ((params->num_ap_ids != 0) || (params->ap_ids != NULL)) {
2900 list_ext_data.list_msg_ctl = RDR_LIST_ONLY_PARAM_APS;
2901 } else {
2902 list_ext_data.list_msg_ctl = RDR_LIST_ALL_APS;
2904 list_ext_data.flags = params->flags;
2905 list_ext_data.permissions = params->permissions;
2908 * Set variable information using memcpy
2910 bufptr = *buf;
2912 (void) memcpy(bufptr, &list_ext_data, sizeof (rdr_list_ext_t));
2913 bufptr += sizeof (rdr_list_ext_t);
2915 if (var_msg_info.ap_id_sizes != NULL) {
2916 (void) memcpy(bufptr, var_msg_info.ap_id_sizes,
2917 var_msg_info.ap_id_int_size);
2918 bufptr += var_msg_info.ap_id_int_size;
2921 if (var_msg_info.ap_id_chars != NULL) {
2922 (void) memcpy(bufptr, var_msg_info.ap_id_chars,
2923 var_msg_info.ap_id_char_size);
2924 bufptr += var_msg_info.ap_id_char_size;
2927 if (params->options != NULL) {
2928 (void) memcpy(bufptr, params->options,
2929 var_msg_info.options_strlen);
2930 bufptr += var_msg_info.options_strlen;
2931 for (i = 0; i < var_msg_info.options_pad_sz; i++) {
2932 bufptr[i] = 0;
2934 bufptr += var_msg_info.options_pad_sz;
2937 if (params->listopts != NULL) {
2938 (void) memcpy(bufptr, params->listopts,
2939 var_msg_info.listopts_strlen);
2940 bufptr += var_msg_info.listopts_strlen;
2941 for (i = 0; i < var_msg_info.listopts_pad_sz; i++) {
2942 bufptr[i] = 0;
2944 bufptr += var_msg_info.listopts_pad_sz;
2947 cleanup_variable_ap_id_info(&var_msg_info);
2949 return (RDR_OK);
2954 * unpack_list_ext_request:
2956 * Handle unpacking a list request message.
2958 static int
2959 unpack_list_ext_request(list_ext_params_t *params, const char *buf)
2961 char *bufptr;
2962 rdr_variable_message_info_t var_msg_info;
2963 rdr_list_ext_t list_ext_data;
2966 if ((params == NULL) || (buf == NULL)) {
2967 return (RDR_ERROR);
2970 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
2972 bufptr = (char *)buf;
2973 (void) memcpy(&list_ext_data, bufptr, sizeof (rdr_list_ext_t));
2974 bufptr += sizeof (rdr_list_ext_t);
2977 * handle getting the ap_ids
2979 var_msg_info.ap_id_char_size = list_ext_data.ap_id_char_size;
2980 if (get_ap_ids_from_buf(&(params->ap_ids), list_ext_data.num_ap_ids,
2981 &var_msg_info, bufptr)) {
2982 return (RDR_ERROR);
2984 bufptr += var_msg_info.ap_id_int_size;
2985 bufptr += var_msg_info.ap_id_char_size;
2988 * handle getting the options
2990 if (get_string_from_buf(&(params->options),
2991 list_ext_data.options_size, bufptr)) {
2992 return (RDR_ERROR);
2994 bufptr += list_ext_data.options_size;
2997 * handle getting the listopts
2999 if (get_string_from_buf(&(params->listopts),
3000 list_ext_data.listopts_size, bufptr)) {
3001 return (RDR_ERROR);
3003 bufptr += list_ext_data.listopts_size;
3006 * Set fixed address labels by name
3008 params->num_ap_ids = list_ext_data.num_ap_ids;
3010 params->ap_id_list = (rdr_list_t **)malloc(sizeof (rdr_list_t *));
3011 if (params->ap_id_list == NULL) {
3012 return (RDR_MEM_ALLOC);
3014 *(params->ap_id_list) = NULL;
3016 params->nlist = (int *)malloc(sizeof (int));
3017 if (params->nlist == NULL) {
3018 return (RDR_MEM_ALLOC);
3020 if (list_ext_data.error_msg_ctl == RDR_GENERATE_ERR_MSGS) {
3021 params->errstring = (char **)malloc(sizeof (char *));
3022 if (params->errstring == NULL) {
3023 return (RDR_MEM_ALLOC);
3025 *(params->errstring) = NULL;
3026 } else { /* error_msg_ctl == RDR_DONT_GENERATE_ERR_MSGS */
3027 params->errstring = NULL;
3029 params->flags = list_ext_data.flags;
3030 params->permissions = list_ext_data.permissions;
3032 return (RDR_OK);
3037 * pack_list_ext_reply:
3039 * Handle packing a list reply message.
3041 static int
3042 pack_list_ext_reply(list_ext_params_t *params, char **buf, int *buf_size)
3044 int i;
3045 char *bufptr;
3046 rdr_list_ext_reply_t list_ext_data;
3047 rdr_variable_message_info_t var_msg_info;
3048 int list_data_size;
3051 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
3053 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
3054 return (RDR_ERROR);
3058 * Set variable length fields (size info)
3060 if (find_errstring_sizes(params->errstring, &var_msg_info)) {
3061 return (RDR_ERROR);
3064 if (params->nlist == NULL) {
3065 list_data_size = 0;
3066 } else {
3067 list_data_size = *(params->nlist) * sizeof (rdr_list_t);
3071 * Collect size info specific to the list_ext reply
3072 * message and allocate a buffer
3074 *buf_size = sizeof (rdr_list_ext_reply_t);
3075 *buf_size += list_data_size;
3076 *buf_size += var_msg_info.errstring_strlen;
3077 *buf_size += var_msg_info.errstring_pad_sz;
3079 *buf = (char *)malloc(*buf_size);
3080 if (*buf == NULL) {
3081 return (RDR_MEM_ALLOC);
3085 * Set fixed address labels by name
3087 list_ext_data.num_ap_ids = (params->nlist) ? *(params->nlist) : 0;
3088 list_ext_data.errstring_size = var_msg_info.errstring_strlen +
3089 var_msg_info.errstring_pad_sz;
3092 * Set variable information using memcpy
3094 bufptr = *buf;
3096 (void) memcpy(bufptr, &list_ext_data, sizeof (rdr_list_ext_reply_t));
3097 bufptr += sizeof (rdr_list_ext_reply_t);
3099 if ((params->ap_id_list != NULL) && (*(params->ap_id_list) != NULL)) {
3100 (void) memcpy(bufptr, *(params->ap_id_list), list_data_size);
3101 bufptr += list_data_size;
3102 } else if (list_data_size) {
3104 * Something is out of sync. We were expecting
3105 * some data to copy, but instead we found a
3106 * NULL pointer.
3108 (void) free((void *)*buf);
3109 *buf = NULL;
3110 return (RDR_ERROR);
3113 if ((params->errstring != NULL) && (*(params->errstring) != NULL)) {
3114 (void) memcpy(bufptr, *(params->errstring),
3115 var_msg_info.errstring_strlen);
3116 bufptr += var_msg_info.errstring_strlen;
3117 for (i = 0; i < var_msg_info.errstring_pad_sz; i++) {
3118 bufptr[i] = 0;
3120 bufptr += var_msg_info.errstring_pad_sz;
3123 return (RDR_OK);
3128 * unpack_list_ext_reply:
3130 * Handle unpacking a list reply message.
3132 static int
3133 unpack_list_ext_reply(list_ext_params_t *params, const char *buf)
3135 int list_data_size;
3136 char *bufptr;
3137 rdr_list_ext_reply_t list_ext_data;
3140 if ((params == NULL) || (buf == NULL)) {
3141 return (RDR_ERROR);
3144 bufptr = (char *)buf;
3145 (void) memcpy(&list_ext_data, bufptr, sizeof (rdr_list_ext_reply_t));
3146 bufptr += sizeof (rdr_list_ext_reply_t);
3149 * handle getting the ap_id rcfga_list_data_t's.
3151 if (list_ext_data.num_ap_ids > 0) {
3152 params->nlist = (int *)malloc(sizeof (int));
3153 if (params->nlist == NULL) {
3154 return (RDR_MEM_ALLOC);
3156 *(params->nlist) = list_ext_data.num_ap_ids;
3157 params->ap_id_list = (rdr_list_t **)
3158 malloc(sizeof (rdr_list_t *));
3159 if (params->ap_id_list == NULL) {
3160 return (RDR_MEM_ALLOC);
3162 *(params->ap_id_list) = (rdr_list_t *)
3163 malloc(sizeof (rdr_list_t) * list_ext_data.num_ap_ids);
3164 if (*(params->ap_id_list) == NULL) {
3165 return (RDR_MEM_ALLOC);
3167 list_data_size = list_ext_data.num_ap_ids * sizeof (rdr_list_t);
3168 (void) memcpy(*(params->ap_id_list), bufptr, list_data_size);
3169 bufptr += list_data_size;
3173 * handle getting the errstring
3175 params->errstring = (char **)malloc(sizeof (char *));
3176 if (params->errstring == NULL) {
3177 return (RDR_MEM_ALLOC);
3179 if (get_string_from_buf(params->errstring,
3180 list_ext_data.errstring_size, bufptr)) {
3181 return (RDR_ERROR);
3183 bufptr += list_ext_data.errstring_size;
3185 return (RDR_OK);
3190 * pack_help_request:
3192 * Handle packing a help request message.
3194 static int
3195 pack_help_request(help_params_t *params, char **buf, int *buf_size)
3197 int i;
3198 char *bufptr;
3199 rdr_help_t help_data;
3200 rdr_variable_message_info_t var_msg_info;
3203 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
3205 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
3206 return (RDR_ERROR);
3210 * Set variable length fields and make a call to partially
3211 * pack it.
3213 if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) {
3214 cleanup_variable_ap_id_info(&var_msg_info);
3215 return (RDR_ERROR);
3217 if (find_options_sizes(params->options, &var_msg_info)) {
3218 cleanup_variable_ap_id_info(&var_msg_info);
3219 return (RDR_ERROR);
3223 * Collect size info specific to the help request message and
3224 * and allocate a buffer
3226 *buf_size = sizeof (rdr_help_t);
3227 *buf_size += var_msg_info.ap_id_int_size;
3228 *buf_size += var_msg_info.ap_id_char_size;
3229 *buf_size += var_msg_info.options_strlen;
3230 *buf_size += var_msg_info.options_pad_sz;
3232 *buf = (char *)malloc(*buf_size);
3233 if (*buf == NULL) {
3234 cleanup_variable_ap_id_info(&var_msg_info);
3235 return (RDR_MEM_ALLOC);
3239 * Set fixed address labels by name
3241 help_data.num_ap_ids = params->num_ap_ids;
3242 help_data.ap_id_char_size = var_msg_info.ap_id_char_size;
3243 help_data.options_size = var_msg_info.options_strlen +
3244 var_msg_info.options_pad_sz;
3246 if (params->msgp != NULL) {
3247 help_data.msg_callback_id =
3248 (unsigned long)params->msgp->message_routine;
3249 help_data.msg_appdata_ptr =
3250 (unsigned long)params->msgp->appdata_ptr;
3251 } else {
3252 help_data.msg_callback_id = 0;
3253 help_data.msg_appdata_ptr = 0;
3256 help_data.flags = params->flags;
3259 * Set variable information using memcpy
3261 bufptr = *buf;
3263 (void) memcpy(bufptr, &help_data, sizeof (rdr_help_t));
3264 bufptr += sizeof (rdr_help_t);
3266 if (var_msg_info.ap_id_sizes != NULL) {
3267 (void) memcpy(bufptr, var_msg_info.ap_id_sizes,
3268 var_msg_info.ap_id_int_size);
3269 bufptr += var_msg_info.ap_id_int_size;
3272 if (var_msg_info.ap_id_chars != NULL) {
3273 (void) memcpy(bufptr, var_msg_info.ap_id_chars,
3274 var_msg_info.ap_id_char_size);
3275 bufptr += var_msg_info.ap_id_char_size;
3278 if (params->options != NULL) {
3279 (void) memcpy(bufptr, params->options,
3280 var_msg_info.options_strlen);
3281 bufptr += var_msg_info.options_strlen;
3282 for (i = 0; i < var_msg_info.options_pad_sz; i++) {
3283 bufptr[i] = 0;
3285 bufptr += var_msg_info.options_pad_sz;
3288 cleanup_variable_ap_id_info(&var_msg_info);
3290 return (RDR_OK);
3295 * unpack_help_request:
3297 * Handle unpacking a help request message.
3299 static int
3300 unpack_help_request(help_params_t *params, const char *buf)
3302 char *bufptr;
3303 rdr_variable_message_info_t var_msg_info;
3304 rdr_help_t help_data;
3307 if ((params == NULL) || (buf == NULL)) {
3308 return (RDR_ERROR);
3311 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
3313 bufptr = (char *)buf;
3314 (void) memcpy(&help_data, bufptr, sizeof (rdr_help_t));
3315 bufptr += sizeof (rdr_help_t);
3318 * handle getting the ap_ids
3320 var_msg_info.ap_id_char_size = help_data.ap_id_char_size;
3321 if (get_ap_ids_from_buf((char ***)&(params->ap_ids),
3322 help_data.num_ap_ids, &var_msg_info, bufptr)) {
3323 return (RDR_ERROR);
3325 bufptr += var_msg_info.ap_id_int_size;
3326 bufptr += var_msg_info.ap_id_char_size;
3329 * handle getting the options
3331 if (get_string_from_buf(&(params->options),
3332 help_data.options_size, bufptr)) {
3333 return (RDR_ERROR);
3335 bufptr += help_data.options_size;
3338 * Set fixed address labels by name
3340 params->num_ap_ids = help_data.num_ap_ids;
3342 params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg));
3343 if (params->msgp == NULL) {
3344 return (RDR_MEM_ALLOC);
3347 /* set params->msgp->message_routine using memcpy */
3348 (void) memcpy((void*)params->msgp, &(help_data.msg_callback_id),
3349 sizeof (unsigned long));
3351 params->msgp->appdata_ptr = (void*)help_data.msg_appdata_ptr;
3352 params->flags = help_data.flags;
3354 return (RDR_OK);
3359 * pack_ap_id_cmp_request:
3361 * Handle packing an attachment point comparison request message.
3363 static int
3364 pack_ap_id_cmp_request(ap_id_cmp_params_t *params, char **buf, int *buf_size)
3366 int i;
3367 char *bufptr;
3368 rdr_ap_id_cmp_t ap_id_cmp_data;
3369 int ap_id1_strlen;
3370 int ap_id1_pad_sz;
3371 int ap_id2_strlen;
3372 int ap_id2_pad_sz;
3375 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
3376 return (RDR_ERROR);
3380 * Set variable length fields and make a call to partially
3381 * pack it.
3383 if (params->ap_log_id1 != NULL) {
3384 ap_id1_strlen = strlen(params->ap_log_id1) + 1;
3385 ap_id1_pad_sz = RDR_ALIGN_64_BIT -
3386 (ap_id1_strlen % RDR_ALIGN_64_BIT);
3387 } else {
3388 ap_id1_strlen = 0;
3389 ap_id1_pad_sz = 0;
3392 if (params->ap_log_id2 != NULL) {
3393 ap_id2_strlen = strlen(params->ap_log_id2) + 1;
3394 ap_id2_pad_sz = RDR_ALIGN_64_BIT -
3395 (ap_id2_strlen % RDR_ALIGN_64_BIT);
3396 } else {
3397 ap_id2_strlen = 0;
3398 ap_id2_pad_sz = 0;
3402 * Collect size info specific to the ap id compare request
3403 * message and allocate a buffer
3405 *buf_size = sizeof (rdr_ap_id_cmp_t);
3406 *buf_size += ap_id1_strlen;
3407 *buf_size += ap_id1_pad_sz;
3408 *buf_size += ap_id2_strlen;
3409 *buf_size += ap_id2_pad_sz;
3411 *buf = (char *)malloc(*buf_size);
3412 if (*buf == NULL) {
3413 return (RDR_MEM_ALLOC);
3417 * Set fixed address labels by name
3419 ap_id_cmp_data.ap_id1_size = ap_id1_strlen + ap_id1_pad_sz;
3420 ap_id_cmp_data.ap_id2_size = ap_id2_strlen + ap_id2_pad_sz;
3424 * Set variable information using memcpy
3426 bufptr = *buf;
3428 (void) memcpy(bufptr, &ap_id_cmp_data, sizeof (rdr_ap_id_cmp_t));
3429 bufptr += sizeof (rdr_ap_id_cmp_t);
3431 if (params->ap_log_id1 != NULL) {
3432 (void) memcpy(bufptr, params->ap_log_id1, ap_id1_strlen);
3433 bufptr += ap_id1_strlen;
3434 for (i = 0; i < ap_id1_pad_sz; i++) {
3435 bufptr[i] = 0;
3437 bufptr += ap_id1_pad_sz;
3440 if (params->ap_log_id2 != NULL) {
3441 (void) memcpy(bufptr, params->ap_log_id2, ap_id2_strlen);
3442 bufptr += ap_id2_strlen;
3443 for (i = 0; i < ap_id2_pad_sz; i++) {
3444 bufptr[i] = 0;
3446 bufptr += ap_id2_pad_sz;
3449 return (RDR_OK);
3454 * unpack_ap_id_cmp_request:
3456 * Handle unpacking an attachment point comparison request message.
3458 static int
3459 unpack_ap_id_cmp_request(ap_id_cmp_params_t *params, const char *buf)
3461 char *bufptr;
3462 rdr_ap_id_cmp_t ap_id_cmp_data;
3465 if ((params == NULL) || (buf == NULL)) {
3466 return (RDR_ERROR);
3469 bufptr = (char *)buf;
3470 (void) memcpy(&ap_id_cmp_data, bufptr, sizeof (rdr_ap_id_cmp_t));
3471 bufptr += sizeof (rdr_ap_id_cmp_t);
3474 * handle getting the cmp ap ids
3476 if (get_string_from_buf(&(params->ap_log_id1),
3477 ap_id_cmp_data.ap_id1_size, bufptr)) {
3478 return (RDR_ERROR);
3480 bufptr += ap_id_cmp_data.ap_id1_size;
3482 if (get_string_from_buf(&(params->ap_log_id2),
3483 ap_id_cmp_data.ap_id2_size, bufptr)) {
3484 return (RDR_ERROR);
3486 bufptr += ap_id_cmp_data.ap_id2_size;
3488 return (RDR_OK);
3493 * pack_abort_cmd_request:
3495 * Handle packing an abort request message.
3497 static int
3498 pack_abort_cmd_request(abort_cmd_params_t *params, char **buf, int *buf_size)
3500 rdr_abort_cmd_t abort_cmd_data;
3503 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
3504 return (RDR_ERROR);
3508 * Collect size info specific to the abort cmd request
3509 * message and allocate a buffer
3511 *buf_size = sizeof (rdr_abort_cmd_t);
3513 *buf = (char *)malloc(*buf_size);
3514 if (*buf == NULL) {
3515 return (RDR_MEM_ALLOC);
3519 * Set fixed session identifier
3521 abort_cmd_data.session_id = params->session_id;
3524 * Copy information using memcpy
3526 (void) memcpy(*buf, &abort_cmd_data, sizeof (rdr_abort_cmd_t));
3528 return (RDR_OK);
3533 * unpack_abort_cmd_request:
3535 * Handle unpacking an abort request message.
3537 static int
3538 unpack_abort_cmd_request(abort_cmd_params_t *params, const char *buf)
3540 rdr_abort_cmd_t *abort_cmd_datap;
3543 if ((params == NULL) || (buf == NULL)) {
3544 return (RDR_ERROR);
3547 /* LINTED Pointer Cast Alignment Warning */
3548 abort_cmd_datap = (rdr_abort_cmd_t *)buf;
3551 * copy out the session information
3554 params->session_id = abort_cmd_datap->session_id;
3556 return (RDR_OK);
3561 * pack_confirm_request:
3563 * Handle packing a confirm callback request.
3565 static int
3566 pack_confirm_request(confirm_callback_params_t *params, char **buf,
3567 int *buf_size)
3569 int i;
3570 char *bufptr;
3571 rdr_confirm_callback_t confirm_callback_data;
3572 int message_strlen;
3573 int message_pad_sz;
3576 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
3577 return (RDR_ERROR);
3581 * Set variable length fields and make a call to partially
3582 * pack it.
3584 if (params->message != NULL) {
3585 message_strlen = strlen(params->message) + 1;
3586 message_pad_sz = RDR_ALIGN_64_BIT -
3587 (message_strlen % RDR_ALIGN_64_BIT);
3588 } else {
3589 message_strlen = 0;
3590 message_pad_sz = 0;
3595 * Collect size info specific to the confirm callback request
3596 * message and allocate a buffer
3598 *buf_size = sizeof (rdr_confirm_callback_t);
3599 *buf_size += message_strlen;
3600 *buf_size += message_pad_sz;
3602 *buf = (char *)malloc(*buf_size);
3603 if (*buf == NULL) {
3604 return (RDR_MEM_ALLOC);
3608 * Set fixed address labels by name
3610 if (params->confp != NULL) {
3611 confirm_callback_data.confirm_callback_id =
3612 (unsigned long)params->confp->confirm;
3613 confirm_callback_data.appdata_ptr =
3614 (unsigned long)params->confp->appdata_ptr;
3615 } else {
3616 confirm_callback_data.confirm_callback_id = 0;
3617 confirm_callback_data.appdata_ptr = 0;
3619 confirm_callback_data.message_size = message_strlen + message_pad_sz;
3622 * Set variable information using memcpy
3624 bufptr = *buf;
3625 (void) memcpy(bufptr, &confirm_callback_data,
3626 sizeof (rdr_confirm_callback_t));
3627 bufptr += sizeof (rdr_confirm_callback_t);
3629 if (params->message != NULL) {
3630 (void) memcpy(bufptr, params->message, message_strlen);
3631 bufptr += message_strlen;
3632 for (i = 0; i < message_pad_sz; i++) {
3633 bufptr[i] = 0;
3635 bufptr += message_pad_sz;
3638 return (RDR_OK);
3643 * unpack_confirm_request:
3645 * Handle unpacking a confirm callback request.
3647 static int
3648 unpack_confirm_request(confirm_callback_params_t *params, const char *buf)
3650 char *bufptr;
3651 rdr_confirm_callback_t confirm_callback_data;
3654 if ((params == NULL) || (buf == NULL)) {
3655 return (RDR_ERROR);
3658 bufptr = (char *)buf;
3659 (void) memcpy(&confirm_callback_data, bufptr,
3660 sizeof (rdr_confirm_callback_t));
3661 bufptr += sizeof (rdr_confirm_callback_t);
3664 * handle getting the message text
3666 if (get_string_from_buf(&(params->message),
3667 confirm_callback_data.message_size, bufptr)) {
3668 return (RDR_ERROR);
3670 bufptr += confirm_callback_data.message_size;
3673 * Set fixed address labels by name
3675 params->confp = (struct cfga_confirm *)
3676 malloc(sizeof (struct cfga_confirm));
3677 if (params->confp == NULL) {
3678 return (RDR_MEM_ALLOC);
3681 /* set params->confp->confirm using memcpy */
3682 (void) memcpy((void*)params->confp,
3683 &(confirm_callback_data.confirm_callback_id),
3684 sizeof (unsigned long));
3686 params->confp->appdata_ptr =
3687 (void*)confirm_callback_data.appdata_ptr;
3689 return (RDR_OK);
3694 * pack_confirm_reply:
3696 * Handle packing a confirm callback reply.
3698 static int
3699 pack_confirm_reply(confirm_callback_params_t *params, char **buf, int *buf_size)
3701 char *bufptr;
3702 rdr_confirm_callback_reply_t confirm_callback_data;
3705 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
3706 return (RDR_ERROR);
3710 * Collect size info specific to the confirm callback reply
3711 * message and allocate a buffer
3713 *buf_size = sizeof (confirm_callback_params_t);
3714 *buf = (char *)malloc(*buf_size);
3715 if (*buf == NULL) {
3716 return (RDR_MEM_ALLOC);
3720 * Set fixed address labels by name
3722 if (params->confp != NULL) {
3723 confirm_callback_data.confirm_callback_id =
3724 (unsigned long)params->confp->confirm;
3725 confirm_callback_data.appdata_ptr =
3726 (unsigned long)params->confp->appdata_ptr;
3727 } else {
3728 confirm_callback_data.confirm_callback_id = 0;
3729 confirm_callback_data.appdata_ptr = 0;
3731 confirm_callback_data.response = params->response;
3734 * Set variable information using memcpy
3736 bufptr = *buf;
3738 (void) memcpy(bufptr, &confirm_callback_data,
3739 sizeof (rdr_confirm_callback_reply_t));
3741 return (RDR_OK);
3746 * unpack_confirm_reply:
3748 * Handle unpacking a confirm callback reply.
3750 static int
3751 unpack_confirm_reply(confirm_callback_params_t *params, const char *buf)
3753 char *bufptr;
3754 rdr_confirm_callback_reply_t confirm_callback_data;
3756 if ((params == NULL) || (buf == NULL)) {
3757 return (RDR_ERROR);
3760 bufptr = (char *)buf;
3761 (void) memcpy(&confirm_callback_data, bufptr,
3762 sizeof (rdr_confirm_callback_reply_t));
3763 bufptr += sizeof (confirm_callback_params_t);
3766 * Set fixed address labels by name
3768 params->confp = (struct cfga_confirm *)
3769 malloc(sizeof (struct cfga_confirm));
3770 if (params->confp == NULL) {
3771 return (RDR_MEM_ALLOC);
3774 /* set params->confp->confirm using memcpy */
3775 (void) memcpy((void*)params->confp,
3776 &(confirm_callback_data.confirm_callback_id),
3777 sizeof (unsigned long));
3779 params->confp->appdata_ptr =
3780 (void*)confirm_callback_data.appdata_ptr;
3781 params->response = confirm_callback_data.response;
3783 return (RDR_OK);
3788 * pack_message_request:
3790 * Handle packing a message callback request.
3792 static int
3793 pack_message_request(msg_callback_params_t *params, char **buf, int *buf_size)
3795 int i;
3796 char *bufptr;
3797 rdr_msg_callback_t msg_callback_data;
3798 int message_strlen;
3799 int message_pad_sz;
3801 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
3802 return (RDR_ERROR);
3806 * Set variable length fields and make a call to partially
3807 * pack it.
3809 if (params->message != NULL) {
3810 message_strlen = strlen(params->message) + 1;
3811 message_pad_sz = RDR_ALIGN_64_BIT -
3812 (message_strlen % RDR_ALIGN_64_BIT);
3813 } else {
3814 message_strlen = 0;
3815 message_pad_sz = 0;
3820 * Collect size info specific to the message callback request
3821 * message and allocate a buffer
3823 *buf_size = sizeof (rdr_msg_callback_t);
3824 *buf_size += message_strlen;
3825 *buf_size += message_pad_sz;
3827 *buf = (char *)malloc(*buf_size);
3828 if (*buf == NULL) {
3829 return (RDR_MEM_ALLOC);
3833 * Set fixed address labels by name
3835 if (params->msgp != NULL) {
3836 msg_callback_data.msg_callback_id =
3837 (unsigned long)params->msgp->message_routine;
3838 msg_callback_data.appdata_ptr =
3839 (unsigned long)params->msgp->appdata_ptr;
3840 } else {
3841 msg_callback_data.msg_callback_id = 0;
3842 msg_callback_data.appdata_ptr = 0;
3844 msg_callback_data.message_size = message_strlen + message_pad_sz;
3847 * Set variable information using memcpy
3849 bufptr = *buf;
3851 (void) memcpy(bufptr, &msg_callback_data, sizeof (rdr_msg_callback_t));
3852 bufptr += sizeof (rdr_msg_callback_t);
3854 if (params->message != NULL) {
3855 (void) memcpy(bufptr, params->message, message_strlen);
3856 bufptr += message_strlen;
3857 for (i = 0; i < message_pad_sz; i++) {
3858 bufptr[i] = 0;
3860 bufptr += message_pad_sz;
3863 return (RDR_OK);
3868 * unpack_message_request:
3870 * Handle unpacking a message callback request.
3872 static int
3873 unpack_message_request(msg_callback_params_t *params, const char *buf)
3875 char *bufptr;
3876 rdr_msg_callback_t msg_callback_data;
3878 if ((params == NULL) || (buf == NULL)) {
3879 return (RDR_ERROR);
3882 bufptr = (char *)buf;
3883 (void) memcpy(&msg_callback_data, bufptr, sizeof (rdr_msg_callback_t));
3884 bufptr += sizeof (rdr_msg_callback_t);
3887 * handle getting the message text
3889 if (get_string_from_buf(&(params->message),
3890 msg_callback_data.message_size, bufptr)) {
3891 return (RDR_ERROR);
3893 bufptr += msg_callback_data.message_size;
3896 * Set fixed address labels by name
3898 params->msgp = (struct cfga_msg *)malloc(sizeof (struct cfga_msg));
3899 if (params->msgp == NULL) {
3900 return (RDR_MEM_ALLOC);
3903 /* set params->msgp->message_routine using memcpy */
3904 (void) memcpy((void*)params->msgp, &(msg_callback_data.msg_callback_id),
3905 sizeof (unsigned long));
3907 params->msgp->appdata_ptr = (void*)msg_callback_data.appdata_ptr;
3909 return (RDR_OK);
3913 * pack_rsrc_info_request:
3915 * Handle packing a resource info request.
3917 static int
3918 pack_rsrc_info_request(rsrc_info_params_t *params, char **buf, int *buf_size)
3920 char *bufptr;
3921 rdr_rsrc_info_t rsrc_info_data;
3922 rdr_variable_message_info_t var_msg_info;
3925 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
3926 return (RDR_ERROR);
3929 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
3932 * Set variable length fields and make a call to partially
3933 * pack it.
3935 if (pack_ap_ids(params->num_ap_ids, params->ap_ids, &var_msg_info)) {
3936 cleanup_variable_ap_id_info(&var_msg_info);
3937 return (RDR_ERROR);
3941 * Collect size info specific to the resource info request
3942 * message and allocate a buffer.
3944 *buf_size = sizeof (rdr_rsrc_info_t);
3945 *buf_size += var_msg_info.ap_id_int_size;
3946 *buf_size += var_msg_info.ap_id_char_size;
3948 *buf = (char *)malloc(*buf_size);
3949 if (*buf == NULL) {
3950 return (RDR_MEM_ALLOC);
3954 * Set fixed address labels by name.
3956 rsrc_info_data.num_ap_ids = params->num_ap_ids;
3957 rsrc_info_data.ap_id_char_size = var_msg_info.ap_id_char_size;
3958 rsrc_info_data.flags = params->flags;
3961 * Set variable information using memcpy.
3963 bufptr = *buf;
3965 (void) memcpy(bufptr, &rsrc_info_data, sizeof (rdr_rsrc_info_t));
3966 bufptr += sizeof (rdr_rsrc_info_t);
3968 if (var_msg_info.ap_id_sizes != NULL) {
3969 (void) memcpy(bufptr, var_msg_info.ap_id_sizes,
3970 var_msg_info.ap_id_int_size);
3971 bufptr += var_msg_info.ap_id_int_size;
3974 if (var_msg_info.ap_id_chars != NULL) {
3975 (void) memcpy(bufptr, var_msg_info.ap_id_chars,
3976 var_msg_info.ap_id_char_size);
3977 bufptr += var_msg_info.ap_id_char_size;
3980 cleanup_variable_ap_id_info(&var_msg_info);
3982 return (RDR_OK);
3987 * unpack_rsrc_info_request:
3989 * Handle unpacking a resource info request message.
3991 static int
3992 unpack_rsrc_info_request(rsrc_info_params_t *params, const char *buf)
3994 char *bufptr;
3995 rdr_variable_message_info_t var_msg_info;
3996 rdr_rsrc_info_t rsrc_info_data;
3999 if ((params == NULL) || (buf == NULL)) {
4000 return (RDR_ERROR);
4003 (void) memset(&var_msg_info, 0, sizeof (rdr_variable_message_info_t));
4005 bufptr = (char *)buf;
4006 (void) memcpy(&rsrc_info_data, bufptr, sizeof (rdr_rsrc_info_t));
4007 bufptr += sizeof (rdr_rsrc_info_t);
4010 * Handle getting the ap_ids.
4012 var_msg_info.ap_id_char_size = rsrc_info_data.ap_id_char_size;
4013 if (get_ap_ids_from_buf(&(params->ap_ids), rsrc_info_data.num_ap_ids,
4014 &var_msg_info, bufptr)) {
4015 return (RDR_ERROR);
4017 bufptr += var_msg_info.ap_id_int_size;
4018 bufptr += var_msg_info.ap_id_char_size;
4021 * Set fixed address labels by name.
4023 params->num_ap_ids = rsrc_info_data.num_ap_ids;
4024 params->flags = rsrc_info_data.flags;
4026 return (RDR_OK);
4031 * pack_rsrc_info_reply:
4033 * Handle packing a resource info reply message.
4035 static int
4036 pack_rsrc_info_reply(rsrc_info_params_t *params, char **buf, int *buf_size,
4037 int encoding)
4039 char *bufptr;
4040 rdr_rsrc_info_reply_t rsrc_info_data;
4041 int pack_status;
4042 caddr_t rsrc_info_bufp = NULL;
4043 size_t rsrc_info_size;
4046 if ((params == NULL) || (buf == NULL) || (buf_size == NULL)) {
4047 return (RDR_ERROR);
4051 * Pack snapshot handle data.
4053 pack_status = ri_pack(params->hdl, &rsrc_info_bufp, &rsrc_info_size,
4054 encoding);
4055 if (pack_status != 0) {
4056 return (RDR_ERROR);
4060 * Collect size info specific to the rsrc_info reply message
4061 * and allocate a buffer.
4063 *buf_size = sizeof (rdr_rsrc_info_reply_t);
4064 *buf_size += rsrc_info_size;
4066 *buf = (char *)malloc(*buf_size);
4067 if (*buf == NULL) {
4068 free(rsrc_info_bufp);
4069 return (RDR_MEM_ALLOC);
4073 * Set fixed address labels by name.
4075 rsrc_info_data.packed_hdl_size = rsrc_info_size;
4078 * Set variable information using memcpy.
4080 bufptr = *buf;
4082 (void) memcpy(bufptr, &rsrc_info_data, sizeof (rdr_rsrc_info_reply_t));
4083 bufptr += sizeof (rdr_rsrc_info_reply_t);
4085 if (rsrc_info_bufp) {
4086 (void) memcpy(bufptr, rsrc_info_bufp, rsrc_info_size);
4087 free(rsrc_info_bufp);
4090 return (RDR_OK);
4095 * unpack_rsrc_info_reply:
4097 * Handle unpacking a resource info reply message.
4099 static int
4100 unpack_rsrc_info_reply(rsrc_info_params_t *params, const char *buf)
4102 int unpack_status;
4103 char *bufptr;
4104 rdr_rsrc_info_reply_t rsrc_info_data;
4107 if ((params == NULL) || (buf == NULL)) {
4108 return (RDR_ERROR);
4111 bufptr = (char *)buf;
4112 (void) memcpy(&rsrc_info_data, bufptr, sizeof (rdr_rsrc_info_reply_t));
4113 bufptr += sizeof (rdr_rsrc_info_reply_t);
4116 * Unpack buf into resource info handle.
4118 unpack_status = ri_unpack(bufptr, rsrc_info_data.packed_hdl_size,
4119 &params->hdl);
4121 return ((unpack_status == 0) ? RDR_OK : RDR_ERROR);
4126 * pack_ap_ids:
4128 * Pack a list of attachment point identifiers into a single buffer.
4129 * This buffer is stored in the specified rdr_variable_message_info_t
4130 * and is padded to be 64-bit aligned.
4132 static int
4133 pack_ap_ids(int num_ap_ids, char *const *ap_ids,
4134 rdr_variable_message_info_t *var_msg_info)
4136 int i;
4137 int ap_id_pad_sz;
4138 char *bufptr;
4141 if (var_msg_info == NULL) {
4142 return (RDR_ERROR);
4146 * NULL is a valid value for ap_ids in the list_ext
4147 * case. For list_ext, no specified attachment points
4148 * indicates that _all_ attachment points should be
4149 * displayed. However, if ap_ids is NULL, num_ap_ids
4150 * should be 0.
4152 if ((ap_ids == NULL) && (num_ap_ids != 0)) {
4153 num_ap_ids = 0;
4156 var_msg_info->ap_id_int_size = sizeof (int) * num_ap_ids;
4157 if (num_ap_ids > 0) {
4158 var_msg_info->ap_id_sizes = (int *)malloc(sizeof (int) *
4159 var_msg_info->ap_id_int_size);
4160 if (var_msg_info->ap_id_sizes == NULL) {
4161 return (RDR_MEM_ALLOC);
4164 for (i = 0; i < num_ap_ids; i++) {
4165 if (ap_ids[i] != NULL) {
4166 var_msg_info->ap_id_sizes[i] = strlen(ap_ids[i]) + 1;
4167 var_msg_info->ap_id_char_size +=
4168 var_msg_info->ap_id_sizes[i];
4171 if (var_msg_info->ap_id_char_size > 0) {
4172 ap_id_pad_sz = RDR_ALIGN_64_BIT -
4173 (var_msg_info->ap_id_char_size % RDR_ALIGN_64_BIT);
4174 var_msg_info->ap_id_char_size += ap_id_pad_sz;
4175 var_msg_info->ap_id_chars = (char *)
4176 malloc(var_msg_info->ap_id_char_size);
4177 if (var_msg_info->ap_id_chars == NULL) {
4178 return (RDR_MEM_ALLOC);
4181 bufptr = var_msg_info->ap_id_chars;
4182 for (i = 0; i < num_ap_ids; i++) {
4183 (void) memcpy(bufptr, ap_ids[i],
4184 var_msg_info->ap_id_sizes[i]);
4185 bufptr += var_msg_info->ap_id_sizes[i];
4187 for (i = 0; i < ap_id_pad_sz; i++) {
4188 bufptr[i] = 0;
4190 } else {
4191 ap_id_pad_sz = 0;
4194 return (RDR_OK);
4199 * unpack_ap_ids:
4201 * Unpack a buffer containing a concatenation of a list of
4202 * attachment point identifiers. The resulting list of strings
4203 * are stored in an array in the specified rdr_variable_message_info_t.
4205 static int
4206 unpack_ap_ids(int num_ap_ids, char **ap_ids, const char *buf,
4207 rdr_variable_message_info_t *var_msg_info)
4209 int i;
4210 int ap_id_size;
4211 int chars_copied;
4212 char *bufptr;
4215 if ((ap_ids == NULL) || (buf == NULL) || (var_msg_info == NULL)) {
4216 return (RDR_ERROR);
4218 bufptr = (char *)buf;
4220 var_msg_info->ap_id_int_size = sizeof (int) * num_ap_ids;
4221 if (num_ap_ids > 0) {
4222 var_msg_info->ap_id_sizes = (int *)
4223 malloc(sizeof (int) * var_msg_info->ap_id_int_size);
4224 if (var_msg_info->ap_id_sizes == NULL) {
4225 return (RDR_MEM_ALLOC);
4227 (void) memcpy(var_msg_info->ap_id_sizes, bufptr,
4228 var_msg_info->ap_id_int_size);
4230 bufptr += var_msg_info->ap_id_int_size;
4232 chars_copied = 0;
4233 for (i = 0; i < num_ap_ids; i++) {
4234 ap_id_size = var_msg_info->ap_id_sizes[i];
4235 if (ap_id_size <= 0) {
4236 continue;
4238 if ((chars_copied + ap_id_size) >
4239 var_msg_info->ap_id_char_size) {
4240 return (RDR_ERROR);
4242 ap_ids[i] = (char *)malloc(ap_id_size);
4243 if (ap_ids[i] == NULL) {
4244 return (RDR_MEM_ALLOC);
4246 (void) memcpy(ap_ids[i], bufptr, ap_id_size);
4247 bufptr += ap_id_size;
4248 chars_copied += ap_id_size;
4250 return (RDR_OK);
4255 * find_options_sizes:
4257 * Determine the size of a specified option string. The information
4258 * is stored in the specified rdr_variable_message_info_t.
4260 static int
4261 find_options_sizes(char *options, rdr_variable_message_info_t *var_msg_info)
4263 if (var_msg_info == NULL) {
4264 return (RDR_ERROR);
4266 if (options != NULL) {
4267 var_msg_info->options_strlen = strlen(options) + 1;
4268 var_msg_info->options_pad_sz = RDR_ALIGN_64_BIT -
4269 (var_msg_info->options_strlen % RDR_ALIGN_64_BIT);
4270 } else {
4271 var_msg_info->options_strlen = 0;
4272 var_msg_info->options_pad_sz = 0;
4274 return (RDR_OK);
4279 * find_listopts_sizes:
4281 * Determine the size of a specified list option string. The information
4282 * is stored in the specified rdr_variable_message_info_t.
4284 static int
4285 find_listopts_sizes(char *listopts, rdr_variable_message_info_t *var_msg_info)
4287 if (var_msg_info == NULL) {
4288 return (RDR_ERROR);
4290 if (listopts != NULL) {
4291 var_msg_info->listopts_strlen = strlen(listopts) + 1;
4292 var_msg_info->listopts_pad_sz = RDR_ALIGN_64_BIT -
4293 (var_msg_info->listopts_strlen % RDR_ALIGN_64_BIT);
4294 } else {
4295 var_msg_info->listopts_strlen = 0;
4296 var_msg_info->listopts_pad_sz = 0;
4298 return (RDR_OK);
4303 * find_function_size:
4305 * Determine the size of a specified private function string. The
4306 * information is stored in the specified rdr_variable_message_info_t.
4308 static int
4309 find_function_sizes(char *function, rdr_variable_message_info_t *var_msg_info)
4311 if (var_msg_info == NULL) {
4312 return (RDR_ERROR);
4314 if (function != NULL) {
4315 var_msg_info->function_strlen = strlen(function) + 1;
4316 var_msg_info->function_pad_sz = RDR_ALIGN_64_BIT -
4317 (var_msg_info->function_strlen % RDR_ALIGN_64_BIT);
4318 } else {
4319 var_msg_info->function_strlen = 0;
4320 var_msg_info->function_pad_sz = 0;
4322 return (RDR_OK);
4327 * find_errstring_sizes:
4329 * Determine the size of a specified error string. The information
4330 * is stored in the specified rdr_variable_message_info_t.
4332 static int
4333 find_errstring_sizes(char **errstring,
4334 rdr_variable_message_info_t *var_msg_info)
4336 if ((errstring != NULL) && (*errstring != NULL)) {
4337 var_msg_info->errstring_strlen = strlen(*errstring) + 1;
4338 var_msg_info->errstring_pad_sz = RDR_ALIGN_64_BIT -
4339 (var_msg_info->errstring_strlen % RDR_ALIGN_64_BIT);
4340 } else {
4341 var_msg_info->errstring_strlen = 0;
4342 var_msg_info->errstring_pad_sz = 0;
4344 return (RDR_OK);
4349 * get_ap_ids_from_buf:
4351 * Unpack a buffer containing a concatenation of a list of attachment
4352 * point identifiers. An appropriately sized buffer is allocated and
4353 * the resulting list of strings are stored in an array in the specified
4354 * rdr_variable_message_info_t.
4356 static int
4357 get_ap_ids_from_buf(char ***ap_id_ptr, int num_ap_ids,
4358 rdr_variable_message_info_t *var_msg_info, const char *buf)
4360 if ((ap_id_ptr == NULL) || (buf == NULL) || (var_msg_info == NULL)) {
4361 return (RDR_ERROR);
4363 if (num_ap_ids > 0) {
4364 *ap_id_ptr = (char **)malloc(sizeof (char *) * num_ap_ids);
4365 if (*ap_id_ptr == NULL) {
4366 return (RDR_MEM_ALLOC);
4368 if (unpack_ap_ids(num_ap_ids, *ap_id_ptr, buf, var_msg_info)) {
4369 cleanup_variable_ap_id_info(var_msg_info);
4370 return (RDR_ERROR);
4373 } else if (num_ap_ids < 0) {
4374 return (RDR_ERROR);
4377 cleanup_variable_ap_id_info(var_msg_info);
4379 return (RDR_OK);
4384 * get_string_from_buf:
4386 * Copy a string to a new buffer. Memory is allocated for the
4387 * new buffer and the original string is copied to the new buffer.
4388 * This is primarily used when a string is located in a packed
4389 * buffer that will eventually get deallocated.
4391 static int
4392 get_string_from_buf(char **stringptr, int strsize, const char *buf)
4394 if (buf == NULL) {
4395 return (RDR_ERROR);
4399 * A stringptr of NULL is a valid value. The errstring param
4400 * in an rconfig_xxx call is valid and is passed to this
4401 * function. For example, see errstring in the call to this
4402 * function in unpack_change_state_reply.
4404 if (stringptr != NULL) {
4405 if (strsize > 0) {
4406 *stringptr = (char *)malloc(strsize);
4407 if (*stringptr == NULL) {
4408 return (RDR_MEM_ALLOC);
4410 (void) memcpy(*stringptr, buf, strsize);
4411 } else if (strsize == 0) {
4412 *stringptr = NULL;
4413 } else if (strsize < 0) {
4414 *stringptr = NULL;
4415 return (RDR_ERROR);
4418 return (RDR_OK);
4423 * cleanup_ap_ids:
4425 * Deallocate the specified array of attachment point identifiers.
4427 static int
4428 cleanup_ap_ids(int num_ap_ids, char ** ap_ids)
4430 int i;
4432 if (ap_ids == NULL) {
4433 return (RDR_ERROR);
4435 for (i = 0; i < num_ap_ids; i++) {
4436 if (ap_ids[i] != NULL) {
4437 free((void *)ap_ids[i]);
4438 ap_ids[i] = NULL;
4441 return (RDR_OK);
4446 * cleanup_errstring:
4448 * Deallocate the specified error string.
4450 static int
4451 cleanup_errstring(char **errstring)
4453 if (errstring) {
4454 if (*errstring) {
4455 free((void *)*errstring);
4457 free((void *)errstring);
4458 errstring = NULL;
4461 return (RDR_OK);
4466 * cleanup_variable_ap_id_info:
4468 * Deallocate the ap_id information from the specified
4469 * rdr_variable_message_info_t.
4471 static void
4472 cleanup_variable_ap_id_info(rdr_variable_message_info_t *var_msg_info)
4474 if (var_msg_info != NULL) {
4475 if (var_msg_info->ap_id_sizes != NULL) {
4476 free((void *)var_msg_info->ap_id_sizes);
4477 var_msg_info->ap_id_sizes = NULL;
4479 if (var_msg_info->ap_id_chars != NULL) {
4480 free((void *)var_msg_info->ap_id_chars);
4481 var_msg_info->ap_id_chars = NULL;
4487 * load_libdscp:
4489 * Try to dynamically link with libdscp.
4491 * Returns: 0 if libdscp not available,
4492 * 1 if libdscp is available.
4494 static int
4495 load_libdscp(libdscp_t *libdscp)
4497 int len;
4498 void *lib;
4499 static char platform[100];
4500 static char pathname[MAXPATHLEN];
4503 * Only try to load libdscp once. Use the saved
4504 * status in the libdscp interface to know the
4505 * results of previous attempts.
4507 if (libdscp->status == LIBDSCP_AVAILABLE) {
4508 return (1);
4510 if (libdscp->status == LIBDSCP_UNAVAILABLE) {
4511 return (0);
4515 * Construct a platform specific pathname for libdscp.
4517 len = sysinfo(SI_PLATFORM, platform, sizeof (platform));
4518 if ((len < 0) || (len > sizeof (platform))) {
4519 return (0);
4521 len = snprintf(pathname, MAXPATHLEN, LIBDSCP_PATH, platform);
4522 if (len >= MAXPATHLEN) {
4523 libdscp->status = LIBDSCP_UNAVAILABLE;
4524 return (0);
4528 * Try dynamically loading libdscp.
4530 if ((lib = dlopen(pathname, RTLD_LAZY)) == NULL) {
4531 libdscp->status = LIBDSCP_UNAVAILABLE;
4532 return (0);
4536 * Try to resolve all the symbols.
4538 libdscp->bind = (int (*)(int, int, int))dlsym(lib, LIBDSCP_BIND);
4539 libdscp->secure = (int (*)(int, int))dlsym(lib, LIBDSCP_SECURE);
4540 libdscp->auth = (int (*)(int, struct sockaddr *, int))dlsym(lib,
4541 LIBDSCP_AUTH);
4543 if ((libdscp->bind == NULL) ||
4544 (libdscp->secure == NULL) ||
4545 (libdscp->auth == NULL)) {
4546 (void) dlclose(lib);
4547 libdscp->status = LIBDSCP_UNAVAILABLE;
4548 return (0);
4552 * Success.
4553 * Update the status to indicate libdscp is available.
4555 libdscp->status = LIBDSCP_AVAILABLE;
4556 return (1);