/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* WARNING: The contents of this file are shared by all projects
* that wish to perform remote Dynamic Reconfiguration (DR)
* operations. Copies of this file can be found in the following
* locations:
*
* Project Location
* ------- --------
*
* In order for proper communication to occur, the files in the
* above locations must match exactly. Any changes that are made
* to this file should be made to all of the files in the list.
*/
/*
* This file is a module that contains an interface for performing
* remote Dynamic Reconfiguration (DR) operations. It hides all
* network operations such as establishing a connection, sending
* and receiving messages, and closing a connection. It also handles
* the packing and unpacking of messages for network transport.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
#include <dlfcn.h>
#include <netdb.h>
#include <libdscp.h>
#include <sys/systeminfo.h>
#include "dcs.h"
#include "remote_cfg.h"
#include "rdr_param_types.h"
#include "rdr_messages.h"
/*
* Structure holding information about
* all possible variable length fields
* that can be present in an RDR message.
*/
typedef struct {
int ap_id_int_size;
int ap_id_char_size;
int *ap_id_sizes;
char *ap_id_chars;
int errstring_strlen;
int errstring_pad_sz;
int options_strlen;
int options_pad_sz;
int listopts_strlen;
int listopts_pad_sz;
int function_strlen;
int function_pad_sz;
/*
* A table of maximum sizes for each message type. Message size is
* validated when the message header is first received. This prevents
* a situation where a corrupted or bad header can cause too much
* memory to be allocated.
*
* The message size limits were chosen to be a very generous upper bound
* on the amount of data each message can send. They are not intended to
* be a precise measurement of the data size.
*/
#define NOMSG 0
struct {
} msg_sizes[] = {
/*
* request reply
* ------- -----
*/
};
/*
* Interfaces for dynamic use of libdscp.
*/
typedef enum {
LIBDSCP_UNKNOWN = 0,
typedef struct {
int (*bind)(int, int, int);
int (*secure)(int, int);
} libdscp_t;
/*
* Static Function Declarations
*/
/*
* Socket Related Routines
*/
int timeout);
/*
* Data Validation Routines
*/
/*
* Session Request Routines
*/
int *buf_size);
int *buf_size);
/*
* Change State Routines
*/
const char *buf);
const char *buf);
/*
* Private Func Routines
*/
const char *buf);
const char *buf);
/*
* Test Routines
*/
/*
* List Ext Routines
*/
int *buf_size);
int *buf_size);
/*
* Help Routines
*/
/*
* Ap Id Cmp Routines
*/
int *buf_size);
const char *buf);
/*
* Abort Routines
*/
int *buf_size);
const char *buf);
/*
* Confirm Callback Routines
*/
int *buf_size);
const char *buf);
const char *buf);
/*
* Message Callback Routines
*/
int *buf_size);
const char *buf);
/*
* Resource Info Routines
*/
int *buf_size);
const char *buf);
/*
*/
/*
* Find Variable Info Sizes
*/
static int find_options_sizes(char *options,
static int find_listopts_sizes(char *listopts,
static int find_function_sizes(char *function,
static int find_errstring_sizes(char **errstring,
/*
* Extract Info From Buffers
*/
const char *buf);
/*
* Cleanup Routines
*/
static int cleanup_errstring(char **errstring);
static void cleanup_variable_ap_id_info(
/*
* Functions for loading libdscp.
*/
/*
* Public Functions
*/
/*
* rdr_open:
*
* Establish a transport endpoint to prepare for a new
* connection. Returns a file descriptor representing the
* new transport if successful or RDR_BAD_FD upon failure.
*/
int
{
int newfd;
return (RDR_BAD_FD);
}
return (newfd);
}
/*
* rdr_init:
*
* Initialize a transport endpoint. This involves binding to
* a particular port and setting any user specified socket
* options.
*/
int
{
int i;
/* sanity checks */
return (RDR_ERROR);
}
num_opts = 0;
}
/* turn on security features */
return (RDR_NET_ERR);
}
/* bind the address, if is not already bound */
return (RDR_NET_ERR);
}
/*
* Set TCP_NODELAY for this endpoint. This disables Nagle's
* algorithm that can cause a delay in sending small sized
* messages. Since most of the RDR messages are small, this
* is a restriction that negatively impacts performance.
*/
return (RDR_NET_ERR);
}
/* set the user specified socket options */
for (i = 0; i < num_opts; i++) {
return (RDR_NET_ERR);
}
}
/*
* If blog is not zero, it is a server that is being
* initialized. In order for it to be able to accept
* connections, we have to set the size of the incoming
* connection queue.
*/
if (blog != 0) {
return (RDR_NET_ERR);
}
}
return (RDR_OK);
}
/*
* rdr_connect_clnt:
*
* Perform the necessary steps for a client to connect to
* a server process. The required information is the file
* descriptor for the transport endpoint, and the remote
* address.
*/
int
{
unsigned int addr_len;
/* sanity check */
return (RDR_ERROR);
}
/* initialize the address length */
case AF_INET:
addr_len = sizeof (struct sockaddr_in);
break;
case AF_INET6:
addr_len = sizeof (struct sockaddr_in6);
break;
default:
return (RDR_ERROR);
}
/* attempt the connection */
return (RDR_NET_ERR);
}
return (RDR_OK);
}
/*
* rdr_connect_srv:
*
* Perform the necessary steps for a server to connect to a
* pending client request. The new connection is allocated a
* new file descriptor, separate from the one used to accept
* the connection.
*/
int
{
int newfd;
unsigned int faddr_len;
/* accept the connection */
return (RDR_BAD_FD);
}
/* if the peer doesn't authenticate properly, reject */
return (RDR_BAD_FD);
}
return (newfd);
}
/*
* rdr_reject:
*
* Reject an incoming connection attempt. This requires
* that the connection be accepted first.
*/
int
{
unsigned int faddr_len;
/* first accept the connection */
return (RDR_NET_ERR);
}
/* then close it */
return (RDR_OK);
}
/*
* rdr_close:
*
* Close down an given connection.
*/
int
{
return (RDR_OK);
}
/*
* rdr_snd_msg:
*
* Public interface for sending an RDR message. The data
* passed in through hdr and param are packed for network
* transport and sent.
*/
int
{
int err;
int pack_buf_sz = 0;
/* sanity checks */
return (RDR_ERROR);
}
/*
* Pack the message for transport
*/
switch (hdr->message_opcode) {
case RDR_SES_REQ: {
&pack_buf, &pack_buf_sz);
} else {
&pack_buf, &pack_buf_sz);
}
break;
}
case RDR_SES_ESTBL:
case RDR_SES_END:
/*
* This is not an error condition because
* there is no extra information to pack.
*/
break;
case RDR_CONF_CHANGE_STATE: {
&pack_buf, &pack_buf_sz);
} else {
&pack_buf, &pack_buf_sz);
}
break;
}
case RDR_CONF_PRIVATE_FUNC: {
&pack_buf, &pack_buf_sz);
} else {
&pack_buf, &pack_buf_sz);
}
break;
}
case RDR_CONF_TEST: {
&pack_buf, &pack_buf_sz);
} else {
&pack_buf, &pack_buf_sz);
}
break;
}
case RDR_CONF_LIST_EXT: {
&pack_buf_sz);
} else {
&pack_buf_sz);
}
break;
}
case RDR_CONF_HELP: {
&pack_buf, &pack_buf_sz);
} else {
/*
* This is not an error because help
* reply does not have any extra information
* to pack.
*/
}
break;
}
case RDR_CONF_AP_ID_CMP: {
&pack_buf, &pack_buf_sz);
} else {
/*
* This is not an error because ap_id_cmp
* reply does not have any extra information
* to pack.
*/
}
break;
}
case RDR_CONF_ABORT_CMD: {
&pack_buf, &pack_buf_sz);
} else {
/*
* This is not an error because session
* abort reply does not have any extra
* information to pack.
*/
}
break;
}
case RDR_CONF_CONFIRM_CALLBACK: {
&pack_buf, &pack_buf_sz);
} else {
&pack_buf_sz);
}
break;
}
case RDR_CONF_MSG_CALLBACK: {
&pack_buf, &pack_buf_sz);
} else {
/*
* It is an error to send a reply
* to a message callback.
*/
err = RDR_MSG_INVAL;
}
break;
}
case RDR_RSRC_INFO: {
&pack_buf_sz);
} else {
(hdr->minor_version == 0)) {
&pack_buf, &pack_buf_sz,
} else {
&pack_buf, &pack_buf_sz,
}
}
break;
}
default:
err = RDR_MSG_INVAL;
break;
}
/* check if packed correctly */
return (err);
}
/* send the message */
return (err);
}
/*
* rdr_rcv_msg:
*
* Public interface for receiving an RDR message. Data is
* unpacked into the hdr and param paramters.
*/
int
{
int err;
/* sanity checks */
return (RDR_ERROR);
}
/* receive the message */
return (err);
}
/*
* Unpack the message
*/
switch (hdr->message_opcode) {
case RDR_SES_REQ: {
} else {
}
break;
}
case RDR_SES_ESTBL:
case RDR_SES_END:
/* no information to unpack */
break;
case RDR_CONF_CHANGE_STATE: {
} else {
}
break;
}
case RDR_CONF_PRIVATE_FUNC: {
} else {
}
break;
}
case RDR_CONF_TEST: {
} else {
}
break;
}
case RDR_CONF_LIST_EXT: {
} else {
}
break;
}
case RDR_CONF_HELP: {
} else {
/*
* This is not an error because help
* reply does not have any extra information
* to unpack.
*/
}
break;
}
case RDR_CONF_AP_ID_CMP: {
} else {
/*
* This is not an error because ap_id_cmp
* reply does not have any extra information
* to pack.
*/
}
break;
}
case RDR_CONF_ABORT_CMD: {
} else {
/* no information to unpack */
}
break;
}
case RDR_CONF_CONFIRM_CALLBACK: {
} else {
}
break;
}
case RDR_CONF_MSG_CALLBACK: {
} else {
/*
* It is an error to send a reply
* to a message callback.
*/
err = RDR_MSG_INVAL;
}
break;
}
case RDR_RSRC_INFO: {
} else {
}
break;
}
default:
err = RDR_MSG_INVAL;
break;
}
/* check if unpacked correctly */
return (err);
}
return (RDR_OK);
}
/*
* rdr_cleanup_params:
*
* Deallocate any memory that was allocated in unpacking a
* message.
*/
int
{
/* sanity check */
return (RDR_ERROR);
}
/*
* Deallocate memory depending on
* the operation.
*/
switch (message_opcode) {
case RDR_SES_REQ: {
}
break;
}
case RDR_SES_ESTBL:
case RDR_SES_END:
/* nothing to deallocate */
break;
case RDR_CONF_CHANGE_STATE: {
}
}
}
break;
}
case RDR_CONF_PRIVATE_FUNC: {
}
}
}
break;
}
case RDR_CONF_TEST: {
}
}
break;
}
case RDR_CONF_LIST_EXT: {
}
}
}
}
}
}
break;
}
case RDR_CONF_HELP: {
}
}
break;
}
case RDR_CONF_AP_ID_CMP: {
}
}
break;
}
case RDR_CONF_ABORT_CMD:
/* nothing to deallocate */
break;
case RDR_CONF_CONFIRM_CALLBACK: {
}
}
break;
}
case RDR_CONF_MSG_CALLBACK: {
}
}
break;
}
default:
return (RDR_ERROR);
/* NOTREACHED */
break;
}
return (RDR_OK);
}
/*
* rdr_setsockopt:
*
* Wrapper of the setsockopt(3SOCKET) library function.
*/
int
{
return (RDR_NET_ERR);
else
return (RDR_OK);
}
/*
* Private (static) Functions
*/
/*
* rdr_setopt:
*
* Set the specified option for a given transport endpoint.
* This function only sets boolean options. It does not
* provide the ability to unset an option, or set a non-
* boolean option.
*/
static int
{
return (RDR_NET_ERR);
}
return (RDR_OK);
}
/*
* rdr_bind:
*
* Bind the specified file descriptor to a specified
* address. If the address is already bound, no error is
* returned. This is the expected behavior if a server
* has been started by inetd (1M).
*/
static int
{
unsigned int addr_len;
int rc;
/* initialize the address */
case AF_INET:
addr_len = sizeof (struct sockaddr_in);
break;
case AF_INET6:
addr_len = sizeof (struct sockaddr_in6);
break;
default:
return (RDR_ERROR);
}
/* attempt to bind the address */
/*
* Ignore the error if EINVAL is returned. In
* this case, we assume that this means that
* the address was already bound. This is not
* an error for servers started by inetd (1M).
*/
return (RDR_NET_ERR);
}
/*
* Retreive the address information of the
* address that was actually bound.
*/
return (RDR_NET_ERR);
}
return (RDR_OK);
}
/*
* rdr_secure:
*
* Activate security features for a socket.
*
* Some platforms have libdscp, which provides additional
* security features. An attempt is made to load libdscp
* and use these features.
*
* Nothing is done if libdscp is not available.
*/
static int
{
int port;
int error;
if (use_libdscp == 0) {
return (RDR_OK);
}
return (RDR_ERROR);
}
/* LINTED E_BAD_PTR_CAST_ALIGN */
return (RDR_ERROR);
}
return (RDR_ERROR);
}
return (RDR_OK);
}
/*
* rdr_auth:
*
* Authenticate if a connection is really from the service
* processor. This is dependent upon functionality from
* libdscp, so an attempt to load and use libdscp is made.
*
* Without libdscp, this function does nothing.
*/
static int
{
if (use_libdscp != 0) {
if ((load_libdscp(&libdscp) == 0) ||
return (RDR_ERROR);
}
}
return (RDR_OK);
}
/*
* rdr_snd:
*
* Send a message in two stages. First the header is sent,
* followed by the packed buffer containing the message
* contents.
*/
static int
{
int err;
/* sanity check */
return (RDR_ERROR);
}
/* ensure null pad bytes */
/* initialize size information */
/* send message header */
return (err);
}
/* check if more to send */
if (data_sz == 0) {
return (RDR_OK);
}
/* send message data */
return (err);
}
return (RDR_OK);
}
/*
* rdr_snd_raw:
*
* Send a raw buffer of information. This function handles
* the low level details of the send operation.
*/
static int
{
int err;
int num_bytes;
int bytes_left;
char *bufp;
while (bytes_left > 0) {
/* wait until we can send the data */
/* poll was interrupted */
return (RDR_ABORTED);
}
return (RDR_ERROR);
} else if (err == 0) {
return (RDR_TIMEOUT);
}
/* ready to send data */
if (num_bytes == -1) {
/*
* Distinguish between an aborted
* session and other network errors.
*/
return (RDR_ABORTED);
} else {
return (RDR_NET_ERR);
}
}
/* wrote 0 bytes, so operation was aborted */
if (num_bytes == 0) {
return (RDR_ABORTED);
}
} else {
return (RDR_NET_ERR);
}
bytes_left -= num_bytes;
}
return (RDR_OK);
}
/*
* rdr_rcv:
*
* Receive a message in two stages. First the header is
* received, followed by the packed buffer containing the
* message contents.
*/
static int
{
int err;
int data_sz;
/* sanity check */
return (RDR_ERROR);
}
/* receive the header */
return (err);
}
/* verify that the data is good */
/* LINTED Pointer Cast Alignment Warning */
return (RDR_MSG_INVAL);
}
/* LINTED Pointer Cast Alignment Warning */
if (!buf) {
return (RDR_MEM_ALLOC);
}
if (data_sz != 0) {
/* receive the rest of the message */
return (err);
}
}
/* copy out data */
return (RDR_OK);
}
/*
* rdr_rcv_raw:
*
* Receive a raw buffer of information. This function handles
* the low level details of the receive operation.
*/
static int
{
int num_bytes;
int err;
int bytes_left;
char *bufp;
while (bytes_left > 0) {
errno = 0;
/*
* In the DCA, if a session is aborted, SIGINT
* is delivered to all active sessions. This
* mistakenly causes all sessions waiting in
* the poll to be interrupted. So, if EINTR
* is returned, it is ignored. If another error
* occurs right away, the current session really
* was aborted. All other sessions won't encounter
* an error and will proceed normally.
*/
continue;
}
return (RDR_ABORTED);
} else if (err == 0) {
return (RDR_TIMEOUT);
}
/* ready to receive data */
if (num_bytes == -1) {
/*
* Distinguish between an aborted
* session and other network errors.
*/
if (errno == ECONNRESET) {
return (RDR_ABORTED);
} else {
return (RDR_NET_ERR);
}
}
/* read 0 bytes, so operation was aborted */
if (num_bytes == 0) {
return (RDR_ABORTED);
}
} else {
return (RDR_NET_ERR);
}
bytes_left -= num_bytes;
}
return (RDR_OK);
}
/*
* validate_header:
*
* Perform a series of sanity checks on the header data that is
* received. This gets called before the variable length data is
* read in to make sure that the information in the header can
* be trusted.
*/
static int
{
unsigned char op;
return (RDR_ERROR);
}
/* validate opcode */
return (RDR_ERROR);
}
/* validate message size (and type) for op */
case RDR_REQUEST:
return (RDR_ERROR);
}
break;
case RDR_REPLY:
return (RDR_ERROR);
}
break;
default:
/* invalid data type */
return (RDR_ERROR);
}
/* all checks passed */
return (RDR_OK);
}
/*
* pack_ses_req_request:
*
* Handle packing a session request request message.
*/
static int
{
char *bufptr;
int locale_str_len;
return (RDR_ERROR);
}
/*
* Determine the size of the locale string
*/
} else {
locale_str_len = 0;
}
/*
* Collect size info specific to the ses_req request message
* and allocate a buffer
*/
*buf_size = sizeof (rdr_ses_req_t);
*buf_size += locale_str_len;
return (RDR_MEM_ALLOC);
}
/*
* Set fixed locale size label by name
*/
/*
* Set variable information using memcpy
*/
bufptr += sizeof (rdr_ses_req_t);
bufptr += locale_str_len;
}
return (RDR_OK);
}
/*
* unpack_ses_req_request:
*
* Handle unpacking a session request request message.
*/
static int
{
char *bufptr;
return (RDR_ERROR);
}
bufptr += sizeof (rdr_ses_req_t);
/*
* handle getting the locale string
*/
return (RDR_ERROR);
}
return (RDR_OK);
}
/*
* pack_ses_req_reply:
*
* Handle packing a session request reply message.
*/
static int
{
return (RDR_ERROR);
}
/*
* Collect size info specific to the session request reply
* message and allocate a buffer
*/
*buf_size = sizeof (rdr_ses_req_reply_t);
return (RDR_MEM_ALLOC);
}
/*
* Set fixed session identifier
*/
/*
* Copy information using memcpy
*/
return (RDR_OK);
}
/*
* unpack_ses_req_request:
*
* Handle unpacking a session request reply message.
*/
static int
{
return (RDR_ERROR);
}
/* LINTED Pointer Cast Alignment Warning */
/*
* copy out the session information
*/
return (RDR_OK);
}
/*
* pack_change_state_request:
*
* Handle packing a change state request message.
*/
static int
int *buf_size)
{
int i;
char *bufptr;
return (RDR_ERROR);
}
/*
* Set variable length fields and make a call to partially
* pack it.
*/
return (RDR_ERROR);
}
return (RDR_ERROR);
}
/*
* Collect size info specific to the change_state request
* message and allocate a buffer
*/
*buf_size = sizeof (rdr_change_state_t);
return (RDR_MEM_ALLOC);
}
/*
* Set fixed address labels by name
*/
} else {
}
} else {
}
} else {
}
/*
* Set variable information using memcpy
*/
bufptr += sizeof (rdr_change_state_t);
}
}
for (i = 0; i < var_msg_info.options_pad_sz; i++) {
bufptr[i] = 0;
}
}
return (RDR_OK);
}
/*
* unpack_change_state_request:
*
* Handle unpacking a change state request message.
*/
static int
{
char *bufptr;
return (RDR_ERROR);
}
bufptr += sizeof (rdr_change_state_t);
/*
* handle getting the ap_ids
*/
return (RDR_ERROR);
}
/*
* handle getting the options
*/
return (RDR_ERROR);
}
/*
* Set fixed address labels by name
*/
malloc(sizeof (struct cfga_confirm));
return (RDR_MEM_ALLOC);
}
/* set params->confp->confirm using memcpy */
&(change_state_data.confirm_callback_id), sizeof (unsigned long));
(void*)change_state_data.confirm_appdata_ptr;
return (RDR_MEM_ALLOC);
}
/* set params->msgp->message_routine using memcpy */
&(change_state_data.msg_callback_id), sizeof (unsigned long));
(void*)change_state_data.msg_appdata_ptr;
return (RDR_MEM_ALLOC);
}
} else { /* error_msg_ctl == RDR_DONT_GENERATE_ERR_MSGS */
}
return (RDR_OK);
}
/*
* pack_change_state_reply:
*
* Handle packing a change state reply message.
*/
static int
int *buf_size)
{
int i;
char *bufptr;
return (RDR_ERROR);
}
/*
* Set variable length fields (size info)
*/
return (RDR_ERROR);
}
/*
* Collect size info specific to the change_state reply
* message and allocate a buffer
*/
*buf_size = sizeof (rdr_change_state_reply_t);
return (RDR_MEM_ALLOC);
}
/*
* Set fixed address labels by name
*/
/*
* Set variable information using memcpy
*/
sizeof (rdr_change_state_reply_t));
bufptr += sizeof (rdr_change_state_reply_t);
for (i = 0; i < var_msg_info.errstring_pad_sz; i++) {
bufptr[i] = 0;
}
}
return (RDR_OK);
}
/*
* unpack_change_state_reply:
*
* Handle unpacking a change state reply message.
*/
static int
{
char *bufptr;
return (RDR_ERROR);
}
sizeof (rdr_change_state_reply_t));
bufptr += sizeof (rdr_change_state_reply_t);
/*
* handle getting the errstring
*/
return (RDR_MEM_ALLOC);
}
return (RDR_ERROR);
}
return (RDR_OK);
}
/*
* pack_private_func_request:
*
* Handle packing a private function request message.
*/
static int
int *buf_size)
{
int i;
char *bufptr;
return (RDR_ERROR);
}
/*
* Set variable length fields and make a call to partially
* pack it.
*/
return (RDR_ERROR);
}
return (RDR_ERROR);
}
return (RDR_ERROR);
}
/*
* Collect size info specific to the private_func request
* message and allocate a buffer
*/
*buf_size = sizeof (rdr_private_func_t);
return (RDR_MEM_ALLOC);
}
/*
* Set fixed address labels by name
*/
} else {
}
} else {
}
} else {
}
/*
* Set variable information using memcpy
*/
bufptr += sizeof (rdr_private_func_t);
}
}
for (i = 0; i < var_msg_info.options_pad_sz; i++) {
bufptr[i] = 0;
}
}
for (i = 0; i < var_msg_info.function_pad_sz; i++) {
bufptr[i] = 0;
}
}
return (RDR_OK);
}
/*
* unpack_private_func_request:
*
* Handle unpacking a private function request message.
*/
static int
{
char *bufptr;
return (RDR_ERROR);
}
bufptr += sizeof (rdr_private_func_t);
/*
* handle getting the ap_ids
*/
return (RDR_ERROR);
}
/*
* handle getting the options and function
*/
return (RDR_ERROR);
}
return (RDR_ERROR);
}
/*
* Set fixed address labels by name
*/
malloc(sizeof (struct cfga_confirm));
return (RDR_MEM_ALLOC);
}
/* set params->confp->confirm using memcpy */
&(private_func_data.confirm_callback_id), sizeof (unsigned long));
(void*)private_func_data.confirm_appdata_ptr;
return (RDR_MEM_ALLOC);
}
/* set params->msgp->message_routine using memcpy */
&(private_func_data.msg_callback_id), sizeof (unsigned long));
(void*)private_func_data.msg_appdata_ptr;
return (RDR_MEM_ALLOC);
}
} else { /* error_msg_ctl == RDR_DONT_GENERATE_ERR_MSGS */
}
return (RDR_OK);
}
/*
* pack_private_func_reply:
*
* Handle packing a private function reply message.
*/
static int
int *buf_size)
{
int i;
char *bufptr;
return (RDR_ERROR);
}
/*
* Set variable length fields (size info)
*/
return (RDR_ERROR);
}
/*
* Collect size info specific to the private_func reply
* message and allocate a buffer
*/
*buf_size = sizeof (rdr_private_func_reply_t);
return (RDR_MEM_ALLOC);
}
/*
* Set fixed address labels by name
*/
/*
* Set variable information using memcpy
*/
sizeof (rdr_private_func_reply_t));
bufptr += sizeof (rdr_private_func_reply_t);
for (i = 0; i < var_msg_info.errstring_pad_sz; i++) {
bufptr[i] = 0;
}
}
return (RDR_OK);
}
/*
* unpack_private_func_reply:
*
* Handle unpacking a private function reply message.
*/
static int
{
char *bufptr;
return (RDR_ERROR);
}
sizeof (rdr_private_func_reply_t));
bufptr += sizeof (rdr_private_func_reply_t);
/*
* handle getting the errstring
*/
return (RDR_MEM_ALLOC);
}
return (RDR_ERROR);
}
return (RDR_OK);
}
/*
* pack_test_request:
*
* Handle packing a test request message.
*/
static int
{
int i;
char *bufptr;
return (RDR_ERROR);
}
/*
* Set variable length fields and make a call to partially
* pack it.
*/
return (RDR_ERROR);
}
return (RDR_ERROR);
}
/*
* Collect size info specific to the test request
* message and allocate a buffer
*/
*buf_size = sizeof (rdr_test_t);
return (RDR_MEM_ALLOC);
}
/*
* Set fixed address labels by name
*/
} else {
test_data.msg_callback_id = 0;
test_data.msg_appdata_ptr = 0;
}
} else {
}
/*
* Set variable information using memcpy
*/
bufptr += sizeof (rdr_test_t);
}
}
for (i = 0; i < var_msg_info.options_pad_sz; i++) {
bufptr[i] = 0;
}
}
return (RDR_OK);
}
/*
* unpack_test_request:
*
* Handle unpacking a test request message.
*/
static int
{
char *bufptr;
return (RDR_ERROR);
}
bufptr += sizeof (rdr_test_t);
/*
* handle getting the ap_ids
*/
return (RDR_ERROR);
}
/*
* handle getting the options
*/
return (RDR_ERROR);
}
/*
* Set fixed address labels by name
*/
return (RDR_MEM_ALLOC);
}
/* set params->msgp->message_routine using memcpy */
&(test_data.msg_callback_id), sizeof (unsigned long));
(void*)test_data.msg_appdata_ptr;
return (RDR_MEM_ALLOC);
}
} else { /* error_msg_ctl == RDR_DONT_GENERATE_ERR_MSGS */
}
return (RDR_OK);
}
/*
* pack_test_reply:
*
* Handle packing a test reply message.
*/
static int
{
int i;
char *bufptr;
return (RDR_ERROR);
}
/*
* Set variable length fields (size info)
*/
return (RDR_ERROR);
}
/*
* Collect size info specific to the test reply
* message and allocate a buffer
*/
*buf_size = sizeof (rdr_test_reply_t);
return (RDR_MEM_ALLOC);
}
/*
* Set fixed address labels by name
*/
/*
* Set variable information using memcpy
*/
bufptr += sizeof (rdr_test_reply_t);
for (i = 0; i < var_msg_info.errstring_pad_sz; i++) {
bufptr[i] = 0;
}
}
return (RDR_OK);
}
/*
* unpack_test_reply:
*
* Handle unpacking a test reply message.
*/
static int
{
char *bufptr;
return (RDR_ERROR);
}
bufptr += sizeof (rdr_test_reply_t);
/*
* handle getting the errstring
*/
return (RDR_MEM_ALLOC);
}
return (RDR_ERROR);
}
return (RDR_OK);
}
/*
* pack_list_ext_request:
*
* Handle packing a list request message.
*/
static int
{
int i;
char *bufptr;
return (RDR_ERROR);
}
/*
* Set variable length fields and make a call to partially
* pack it.
*/
return (RDR_ERROR);
}
return (RDR_ERROR);
}
return (RDR_ERROR);
}
/*
* Collect size info specific to the list_ext request
* message and allocate a buffer
*/
*buf_size = sizeof (rdr_list_ext_t);
return (RDR_MEM_ALLOC);
}
/*
* Set fixed address labels by name
*/
} else {
}
} else {
}
/*
* Set variable information using memcpy
*/
bufptr += sizeof (rdr_list_ext_t);
}
}
for (i = 0; i < var_msg_info.options_pad_sz; i++) {
bufptr[i] = 0;
}
}
for (i = 0; i < var_msg_info.listopts_pad_sz; i++) {
bufptr[i] = 0;
}
}
return (RDR_OK);
}
/*
* unpack_list_ext_request:
*
* Handle unpacking a list request message.
*/
static int
{
char *bufptr;
return (RDR_ERROR);
}
bufptr += sizeof (rdr_list_ext_t);
/*
* handle getting the ap_ids
*/
&var_msg_info, bufptr)) {
return (RDR_ERROR);
}
/*
* handle getting the options
*/
return (RDR_ERROR);
}
/*
* handle getting the listopts
*/
return (RDR_ERROR);
}
/*
* Set fixed address labels by name
*/
return (RDR_MEM_ALLOC);
}
return (RDR_MEM_ALLOC);
}
return (RDR_MEM_ALLOC);
}
} else { /* error_msg_ctl == RDR_DONT_GENERATE_ERR_MSGS */
}
return (RDR_OK);
}
/*
* pack_list_ext_reply:
*
* Handle packing a list reply message.
*/
static int
{
int i;
char *bufptr;
int list_data_size;
return (RDR_ERROR);
}
/*
* Set variable length fields (size info)
*/
return (RDR_ERROR);
}
list_data_size = 0;
} else {
}
/*
* Collect size info specific to the list_ext reply
* message and allocate a buffer
*/
*buf_size = sizeof (rdr_list_ext_reply_t);
*buf_size += list_data_size;
return (RDR_MEM_ALLOC);
}
/*
* Set fixed address labels by name
*/
/*
* Set variable information using memcpy
*/
bufptr += sizeof (rdr_list_ext_reply_t);
bufptr += list_data_size;
} else if (list_data_size) {
/*
* Something is out of sync. We were expecting
* some data to copy, but instead we found a
* NULL pointer.
*/
return (RDR_ERROR);
}
for (i = 0; i < var_msg_info.errstring_pad_sz; i++) {
bufptr[i] = 0;
}
}
return (RDR_OK);
}
/*
* unpack_list_ext_reply:
*
* Handle unpacking a list reply message.
*/
static int
{
int list_data_size;
char *bufptr;
return (RDR_ERROR);
}
bufptr += sizeof (rdr_list_ext_reply_t);
/*
* handle getting the ap_id rcfga_list_data_t's.
*/
if (list_ext_data.num_ap_ids > 0) {
return (RDR_MEM_ALLOC);
}
malloc(sizeof (rdr_list_t *));
return (RDR_MEM_ALLOC);
}
return (RDR_MEM_ALLOC);
}
bufptr += list_data_size;
}
/*
* handle getting the errstring
*/
return (RDR_MEM_ALLOC);
}
return (RDR_ERROR);
}
return (RDR_OK);
}
/*
* pack_help_request:
*
* Handle packing a help request message.
*/
static int
{
int i;
char *bufptr;
return (RDR_ERROR);
}
/*
* Set variable length fields and make a call to partially
* pack it.
*/
return (RDR_ERROR);
}
return (RDR_ERROR);
}
/*
* Collect size info specific to the help request message and
* and allocate a buffer
*/
*buf_size = sizeof (rdr_help_t);
return (RDR_MEM_ALLOC);
}
/*
* Set fixed address labels by name
*/
} else {
help_data.msg_callback_id = 0;
help_data.msg_appdata_ptr = 0;
}
/*
* Set variable information using memcpy
*/
bufptr += sizeof (rdr_help_t);
}
}
for (i = 0; i < var_msg_info.options_pad_sz; i++) {
bufptr[i] = 0;
}
}
return (RDR_OK);
}
/*
* unpack_help_request:
*
* Handle unpacking a help request message.
*/
static int
{
char *bufptr;
return (RDR_ERROR);
}
bufptr += sizeof (rdr_help_t);
/*
* handle getting the ap_ids
*/
return (RDR_ERROR);
}
/*
* handle getting the options
*/
return (RDR_ERROR);
}
/*
* Set fixed address labels by name
*/
return (RDR_MEM_ALLOC);
}
/* set params->msgp->message_routine using memcpy */
sizeof (unsigned long));
return (RDR_OK);
}
/*
* pack_ap_id_cmp_request:
*
* Handle packing an attachment point comparison request message.
*/
static int
{
int i;
char *bufptr;
int ap_id1_strlen;
int ap_id1_pad_sz;
int ap_id2_strlen;
int ap_id2_pad_sz;
return (RDR_ERROR);
}
/*
* Set variable length fields and make a call to partially
* pack it.
*/
} else {
ap_id1_strlen = 0;
ap_id1_pad_sz = 0;
}
} else {
ap_id2_strlen = 0;
ap_id2_pad_sz = 0;
}
/*
* Collect size info specific to the ap id compare request
* message and allocate a buffer
*/
*buf_size = sizeof (rdr_ap_id_cmp_t);
*buf_size += ap_id1_strlen;
*buf_size += ap_id1_pad_sz;
*buf_size += ap_id2_strlen;
*buf_size += ap_id2_pad_sz;
return (RDR_MEM_ALLOC);
}
/*
* Set fixed address labels by name
*/
/*
* Set variable information using memcpy
*/
bufptr += sizeof (rdr_ap_id_cmp_t);
bufptr += ap_id1_strlen;
for (i = 0; i < ap_id1_pad_sz; i++) {
bufptr[i] = 0;
}
bufptr += ap_id1_pad_sz;
}
bufptr += ap_id2_strlen;
for (i = 0; i < ap_id2_pad_sz; i++) {
bufptr[i] = 0;
}
bufptr += ap_id2_pad_sz;
}
return (RDR_OK);
}
/*
* unpack_ap_id_cmp_request:
*
* Handle unpacking an attachment point comparison request message.
*/
static int
{
char *bufptr;
return (RDR_ERROR);
}
bufptr += sizeof (rdr_ap_id_cmp_t);
/*
* handle getting the cmp ap ids
*/
return (RDR_ERROR);
}
return (RDR_ERROR);
}
return (RDR_OK);
}
/*
* pack_abort_cmd_request:
*
* Handle packing an abort request message.
*/
static int
{
return (RDR_ERROR);
}
/*
* Collect size info specific to the abort cmd request
* message and allocate a buffer
*/
*buf_size = sizeof (rdr_abort_cmd_t);
return (RDR_MEM_ALLOC);
}
/*
* Set fixed session identifier
*/
/*
* Copy information using memcpy
*/
return (RDR_OK);
}
/*
* unpack_abort_cmd_request:
*
* Handle unpacking an abort request message.
*/
static int
{
return (RDR_ERROR);
}
/* LINTED Pointer Cast Alignment Warning */
/*
* copy out the session information
*/
return (RDR_OK);
}
/*
* pack_confirm_request:
*
* Handle packing a confirm callback request.
*/
static int
int *buf_size)
{
int i;
char *bufptr;
int message_strlen;
int message_pad_sz;
return (RDR_ERROR);
}
/*
* Set variable length fields and make a call to partially
* pack it.
*/
} else {
message_strlen = 0;
message_pad_sz = 0;
}
/*
* Collect size info specific to the confirm callback request
* message and allocate a buffer
*/
*buf_size = sizeof (rdr_confirm_callback_t);
*buf_size += message_strlen;
*buf_size += message_pad_sz;
return (RDR_MEM_ALLOC);
}
/*
* Set fixed address labels by name
*/
} else {
}
/*
* Set variable information using memcpy
*/
sizeof (rdr_confirm_callback_t));
bufptr += sizeof (rdr_confirm_callback_t);
bufptr += message_strlen;
for (i = 0; i < message_pad_sz; i++) {
bufptr[i] = 0;
}
bufptr += message_pad_sz;
}
return (RDR_OK);
}
/*
* unpack_confirm_request:
*
* Handle unpacking a confirm callback request.
*/
static int
{
char *bufptr;
return (RDR_ERROR);
}
sizeof (rdr_confirm_callback_t));
bufptr += sizeof (rdr_confirm_callback_t);
/*
* handle getting the message text
*/
return (RDR_ERROR);
}
/*
* Set fixed address labels by name
*/
malloc(sizeof (struct cfga_confirm));
return (RDR_MEM_ALLOC);
}
/* set params->confp->confirm using memcpy */
sizeof (unsigned long));
(void*)confirm_callback_data.appdata_ptr;
return (RDR_OK);
}
/*
* pack_confirm_reply:
*
* Handle packing a confirm callback reply.
*/
static int
{
char *bufptr;
return (RDR_ERROR);
}
/*
* Collect size info specific to the confirm callback reply
* message and allocate a buffer
*/
*buf_size = sizeof (confirm_callback_params_t);
return (RDR_MEM_ALLOC);
}
/*
* Set fixed address labels by name
*/
} else {
}
/*
* Set variable information using memcpy
*/
sizeof (rdr_confirm_callback_reply_t));
return (RDR_OK);
}
/*
* unpack_confirm_reply:
*
* Handle unpacking a confirm callback reply.
*/
static int
{
char *bufptr;
return (RDR_ERROR);
}
sizeof (rdr_confirm_callback_reply_t));
bufptr += sizeof (confirm_callback_params_t);
/*
* Set fixed address labels by name
*/
malloc(sizeof (struct cfga_confirm));
return (RDR_MEM_ALLOC);
}
/* set params->confp->confirm using memcpy */
sizeof (unsigned long));
(void*)confirm_callback_data.appdata_ptr;
return (RDR_OK);
}
/*
* pack_message_request:
*
* Handle packing a message callback request.
*/
static int
{
int i;
char *bufptr;
int message_strlen;
int message_pad_sz;
return (RDR_ERROR);
}
/*
* Set variable length fields and make a call to partially
* pack it.
*/
} else {
message_strlen = 0;
message_pad_sz = 0;
}
/*
* Collect size info specific to the message callback request
* message and allocate a buffer
*/
*buf_size = sizeof (rdr_msg_callback_t);
*buf_size += message_strlen;
*buf_size += message_pad_sz;
return (RDR_MEM_ALLOC);
}
/*
* Set fixed address labels by name
*/
} else {
}
/*
* Set variable information using memcpy
*/
bufptr += sizeof (rdr_msg_callback_t);
bufptr += message_strlen;
for (i = 0; i < message_pad_sz; i++) {
bufptr[i] = 0;
}
bufptr += message_pad_sz;
}
return (RDR_OK);
}
/*
* unpack_message_request:
*
* Handle unpacking a message callback request.
*/
static int
{
char *bufptr;
return (RDR_ERROR);
}
bufptr += sizeof (rdr_msg_callback_t);
/*
* handle getting the message text
*/
return (RDR_ERROR);
}
/*
* Set fixed address labels by name
*/
return (RDR_MEM_ALLOC);
}
/* set params->msgp->message_routine using memcpy */
sizeof (unsigned long));
return (RDR_OK);
}
/*
* pack_rsrc_info_request:
*
* Handle packing a resource info request.
*/
static int
{
char *bufptr;
return (RDR_ERROR);
}
/*
* Set variable length fields and make a call to partially
* pack it.
*/
return (RDR_ERROR);
}
/*
* Collect size info specific to the resource info request
* message and allocate a buffer.
*/
*buf_size = sizeof (rdr_rsrc_info_t);
return (RDR_MEM_ALLOC);
}
/*
* Set fixed address labels by name.
*/
/*
* Set variable information using memcpy.
*/
bufptr += sizeof (rdr_rsrc_info_t);
}
}
return (RDR_OK);
}
/*
* unpack_rsrc_info_request:
*
* Handle unpacking a resource info request message.
*/
static int
{
char *bufptr;
return (RDR_ERROR);
}
bufptr += sizeof (rdr_rsrc_info_t);
/*
* Handle getting the ap_ids.
*/
&var_msg_info, bufptr)) {
return (RDR_ERROR);
}
/*
* Set fixed address labels by name.
*/
return (RDR_OK);
}
/*
* pack_rsrc_info_reply:
*
* Handle packing a resource info reply message.
*/
static int
int encoding)
{
char *bufptr;
int pack_status;
return (RDR_ERROR);
}
/*
* Pack snapshot handle data.
*/
encoding);
if (pack_status != 0) {
return (RDR_ERROR);
}
/*
* Collect size info specific to the rsrc_info reply message
* and allocate a buffer.
*/
*buf_size = sizeof (rdr_rsrc_info_reply_t);
*buf_size += rsrc_info_size;
return (RDR_MEM_ALLOC);
}
/*
* Set fixed address labels by name.
*/
/*
* Set variable information using memcpy.
*/
bufptr += sizeof (rdr_rsrc_info_reply_t);
if (rsrc_info_bufp) {
}
return (RDR_OK);
}
/*
* unpack_rsrc_info_reply:
*
* Handle unpacking a resource info reply message.
*/
static int
{
int unpack_status;
char *bufptr;
return (RDR_ERROR);
}
bufptr += sizeof (rdr_rsrc_info_reply_t);
/*
* Unpack buf into resource info handle.
*/
}
/*
* pack_ap_ids:
*
* Pack a list of attachment point identifiers into a single buffer.
* This buffer is stored in the specified rdr_variable_message_info_t
* and is padded to be 64-bit aligned.
*/
static int
{
int i;
int ap_id_pad_sz;
char *bufptr;
if (var_msg_info == NULL) {
return (RDR_ERROR);
}
/*
* NULL is a valid value for ap_ids in the list_ext
* case. For list_ext, no specified attachment points
* indicates that _all_ attachment points should be
* displayed. However, if ap_ids is NULL, num_ap_ids
* should be 0.
*/
num_ap_ids = 0;
}
if (num_ap_ids > 0) {
return (RDR_MEM_ALLOC);
}
}
for (i = 0; i < num_ap_ids; i++) {
var_msg_info->ap_id_sizes[i];
}
}
if (var_msg_info->ap_id_char_size > 0) {
var_msg_info->ap_id_chars = (char *)
return (RDR_MEM_ALLOC);
}
for (i = 0; i < num_ap_ids; i++) {
var_msg_info->ap_id_sizes[i]);
}
for (i = 0; i < ap_id_pad_sz; i++) {
bufptr[i] = 0;
}
} else {
ap_id_pad_sz = 0;
}
return (RDR_OK);
}
/*
* unpack_ap_ids:
*
* Unpack a buffer containing a concatenation of a list of
* attachment point identifiers. The resulting list of strings
* are stored in an array in the specified rdr_variable_message_info_t.
*/
static int
{
int i;
int ap_id_size;
int chars_copied;
char *bufptr;
return (RDR_ERROR);
}
if (num_ap_ids > 0) {
var_msg_info->ap_id_sizes = (int *)
return (RDR_MEM_ALLOC);
}
}
chars_copied = 0;
for (i = 0; i < num_ap_ids; i++) {
if (ap_id_size <= 0) {
continue;
}
if ((chars_copied + ap_id_size) >
return (RDR_ERROR);
}
return (RDR_MEM_ALLOC);
}
bufptr += ap_id_size;
}
return (RDR_OK);
}
/*
* find_options_sizes:
*
* Determine the size of a specified option string. The information
* is stored in the specified rdr_variable_message_info_t.
*/
static int
{
if (var_msg_info == NULL) {
return (RDR_ERROR);
}
} else {
var_msg_info->options_strlen = 0;
var_msg_info->options_pad_sz = 0;
}
return (RDR_OK);
}
/*
* find_listopts_sizes:
*
* Determine the size of a specified list option string. The information
* is stored in the specified rdr_variable_message_info_t.
*/
static int
{
if (var_msg_info == NULL) {
return (RDR_ERROR);
}
} else {
var_msg_info->listopts_strlen = 0;
var_msg_info->listopts_pad_sz = 0;
}
return (RDR_OK);
}
/*
* find_function_size:
*
* Determine the size of a specified private function string. The
* information is stored in the specified rdr_variable_message_info_t.
*/
static int
{
if (var_msg_info == NULL) {
return (RDR_ERROR);
}
} else {
var_msg_info->function_strlen = 0;
var_msg_info->function_pad_sz = 0;
}
return (RDR_OK);
}
/*
* find_errstring_sizes:
*
* Determine the size of a specified error string. The information
* is stored in the specified rdr_variable_message_info_t.
*/
static int
{
} else {
var_msg_info->errstring_strlen = 0;
var_msg_info->errstring_pad_sz = 0;
}
return (RDR_OK);
}
/*
* get_ap_ids_from_buf:
*
* Unpack a buffer containing a concatenation of a list of attachment
* point identifiers. An appropriately sized buffer is allocated and
* the resulting list of strings are stored in an array in the specified
* rdr_variable_message_info_t.
*/
static int
{
return (RDR_ERROR);
}
if (num_ap_ids > 0) {
return (RDR_MEM_ALLOC);
}
return (RDR_ERROR);
}
} else if (num_ap_ids < 0) {
return (RDR_ERROR);
}
return (RDR_OK);
}
/*
* get_string_from_buf:
*
* Copy a string to a new buffer. Memory is allocated for the
* new buffer and the original string is copied to the new buffer.
* This is primarily used when a string is located in a packed
* buffer that will eventually get deallocated.
*/
static int
{
return (RDR_ERROR);
}
/*
* A stringptr of NULL is a valid value. The errstring param
* in an rconfig_xxx call is valid and is passed to this
* function. For example, see errstring in the call to this
* function in unpack_change_state_reply.
*/
if (strsize > 0) {
return (RDR_MEM_ALLOC);
}
} else if (strsize == 0) {
} else if (strsize < 0) {
return (RDR_ERROR);
}
}
return (RDR_OK);
}
/*
* cleanup_ap_ids:
*
* Deallocate the specified array of attachment point identifiers.
*/
static int
{
int i;
return (RDR_ERROR);
}
for (i = 0; i < num_ap_ids; i++) {
}
}
return (RDR_OK);
}
/*
* cleanup_errstring:
*
* Deallocate the specified error string.
*/
static int
{
if (errstring) {
if (*errstring) {
}
}
return (RDR_OK);
}
/*
* cleanup_variable_ap_id_info:
*
* Deallocate the ap_id information from the specified
* rdr_variable_message_info_t.
*/
static void
{
if (var_msg_info != NULL) {
}
}
}
}
/*
* load_libdscp:
*
* Try to dynamically link with libdscp.
*
* Returns: 0 if libdscp not available,
* 1 if libdscp is available.
*/
static int
{
int len;
void *lib;
/*
* Only try to load libdscp once. Use the saved
* status in the libdscp interface to know the
* results of previous attempts.
*/
return (1);
}
return (0);
}
/*
* Construct a platform specific pathname for libdscp.
*/
return (0);
}
if (len >= MAXPATHLEN) {
return (0);
}
/*
* Try dynamically loading libdscp.
*/
return (0);
}
/*
* Try to resolve all the symbols.
*/
return (0);
}
/*
* Success.
* Update the status to indicate libdscp is available.
*/
return (1);
}