Code owners
Assign users and groups as approvers for specific file changes. Learn more.
script.c 72.88 KiB
/*
* Copyright 2013 Google Inc.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
/*
* Author: ncardwell@google.com (Neal Cardwell)
*
* Implementation of functions to help interpret a test script.
*/
#include "script.h"
#include <assert.h>
#include <poll.h>
#include <stdlib.h>
#include "symbols.h"
/* Fill in a value representing the given expression in
* fully-evaluated form (e.g. symbols resolved to ints). On success,
* returns STATUS_OK. On error return STATUS_ERR and fill in *error.
*/
static int evaluate(struct expression *in,
struct expression **out_ptr, char **error);
/* Initialize script object */
void init_script(struct script *script)
{
memset(script, 0, sizeof(*script));
script->option_list = NULL;
script->init_command = NULL;
script->event_list = NULL;
}
/* This table maps expression types to human-readable strings */
struct expression_type_entry {
enum expression_t type;
const char *name;
};
struct expression_type_entry expression_type_table[] = {
{ EXPR_NONE, "none" },
{ EXPR_NULL, "null" },
{ EXPR_ELLIPSIS, "ellipsis" },
{ EXPR_INTEGER, "integer" },
{ EXPR_WORD, "word" },
{ EXPR_STRING, "string" },
{ EXPR_SOCKET_ADDRESS_IPV4, "sockaddr_in" },
{ EXPR_SOCKET_ADDRESS_IPV6, "sockaddr_in6" },
{ EXPR_LINGER, "linger" },
{ EXPR_BINARY, "binary_expression" },
{ EXPR_LIST, "list" },
{ EXPR_IOVEC, "iovec" },
{ EXPR_MSGHDR, "msghdr" },
{ EXPR_CMSGHDR, "cmsghdr"},
{ EXPR_POLLFD, "pollfd" },
{ EXPR_SCTP_RTOINFO, "sctp_rtoinfo"},
{ EXPR_SCTP_INITMSG, "sctp_initmsg"},
{ EXPR_SCTP_ASSOC_VALUE, "sctp_assoc_value"},
{ EXPR_SCTP_SACKINFO, "sctp_sackinfo"},
{ EXPR_SCTP_STATUS, "sctp_status"},
{ EXPR_SCTP_PADDRINFO, "sctp_paddrinfo"},
{ EXPR_SCTP_PEER_ADDR_PARAMS,"sctp_peer_addr_params"},
{ EXPR_SCTP_STREAM_VALUE, "sctp_stream_value"},
{ EXPR_SCTP_ASSOCPARAMS, "sctp_assocparams"},
{ EXPR_SCTP_EVENT, "sctp_event" },
{ EXPR_SCTP_EVENT_SUBSCRIBE, "sctp_event_subscribe"},
{ EXPR_SCTP_SNDINFO, "sctp_sndinfo" },
{ EXPR_SCTP_SETPRIM, "sctp_setprim" },
{ EXPR_SCTP_SETADAPTATION, "sctp_setadaptation"},
{ EXPR_SCTP_SNDRCVINFO, "sctp_sndrcvinfo" },
{ EXPR_SCTP_PRINFO, "sctp_prinfo" },
{ EXPR_SCTP_DEFAULT_PRINFO, "sctp_default_prinfo"},
{ EXPR_SCTP_AUTHINFO, "sctp_authinfo" },
{ EXPR_SCTP_SENDV_SPA, "sctp_sendv_spa" },
{ EXPR_SCTP_RCVINFO, "sctp_rcvinfo" },
{ EXPR_SCTP_NXTINFO, "sctp_nxtinfo" },
{ EXPR_SCTP_RECVV_RN, "sctp_recvv_rn " },
{ EXPR_SCTP_ASSOC_CHANGE, "sctp_assoc_change"},
{ EXPR_SCTP_PADDR_CHANGE, "sctp_paddr_change"},
{ EXPR_SCTP_REMOTE_ERROR, "sctp_remote_error"},
{ EXPR_SCTP_SEND_FAILED, "sctp_send_failed"},
{ EXPR_SCTP_SHUTDOWN_EVENT, "sctp_shutdown_event"},
{ EXPR_SCTP_ADAPTATION_EVENT,"sctp_adaptation_event"},
{ EXPR_SCTP_PDAPI_EVENT, "sctp_pdapi_event"},
{ EXPR_SCTP_AUTHKEY_EVENT, "sctp_authkey_event"},
{ EXPR_SCTP_SENDER_DRY_EVENT,"sctp_sender_dry_event"},
{ EXPR_SCTP_SEND_FAILED_EVENT,"sctp_send_failed_event"},
{ EXPR_SCTP_TLV, "sctp_tlv" },
{ EXPR_SCTP_EXTRCVINFO, "sctp_extrcvinfo" },
{ NUM_EXPR_TYPES, NULL}
};
const char *expression_type_to_string(enum expression_t type)
{
int i = 0;
assert(ARRAY_SIZE(expression_type_table) == NUM_EXPR_TYPES + 1);
for (i = 0; expression_type_table[i].name != NULL; ++i)
if (expression_type_table[i].type == type)
return expression_type_table[i].name;
return "UNKNOWN_TYPE";
}
/* Cross-platform symbols. */
struct int_symbol cross_platform_symbols[] = {
{ AF_INET, "AF_INET" },
{ AF_INET6, "AF_INET6" },
{ PF_INET, "PF_INET" },
{ PF_INET6, "PF_INET6" },
{ SOCK_STREAM, "SOCK_STREAM" },
{ SOCK_DGRAM, "SOCK_DGRAM" },
{ IPPROTO_IP, "IPPROTO_IP" },
{ IPPROTO_IPV6, "IPPROTO_IPV6" },
{ IPPROTO_ICMP, "IPPROTO_ICMP" },
{ IPPROTO_SCTP, "IPPROTO_SCTP" },
{ IPPROTO_TCP, "IPPROTO_TCP" },
{ IPPROTO_UDP, "IPPROTO_UDP" },
{ IPPROTO_UDPLITE, "IPPROTO_UDPLITE" },
{ SHUT_RD, "SHUT_RD" },
{ SHUT_WR, "SHUT_WR" },
{ SHUT_RDWR, "SHUT_RDWR" },
{ SOL_SOCKET, "SOL_SOCKET" },
/* Sentinel marking the end of the table. */
{ 0, NULL },
};
/* Do a symbol->int lookup, and return true iff we found the symbol. */
static bool lookup_int_symbol(const char *input_symbol, s64 *output_integer,
struct int_symbol *symbols)
{
int i;
for (i = 0; symbols[i].name != NULL ; ++i) {
if (strcmp(input_symbol, symbols[i].name) == 0) {
*output_integer = symbols[i].value;
return true;
}
}
return false;
}
int symbol_to_int(const char *input_symbol, s64 *output_integer,
char **error)
{
if (lookup_int_symbol(input_symbol, output_integer,
cross_platform_symbols))
return STATUS_OK;
if (lookup_int_symbol(input_symbol, output_integer,
platform_symbols()))
return STATUS_OK;
asprintf(error, "unknown symbol: '%s'", input_symbol);
return STATUS_ERR;
}
/* Names for the events and revents bit mask flags for poll() system call */
struct flag_name poll_flags[] = {
{ POLLIN, "POLLIN" },
{ POLLPRI, "POLLPRI" },
{ POLLOUT, "POLLOUT" },
#ifdef POLLRDNORM
{ POLLRDNORM, "POLLRDNORM" },
#endif
#ifdef POLLRDBAND
{ POLLRDBAND, "POLLRDBAND" },
#endif
#ifdef POLLWRNORM
{ POLLWRNORM, "POLLWRNORM" },
#endif
#ifdef POLLWRBAND
{ POLLWRBAND, "POLLWRBAND" },
#endif
#ifdef POLLMSG
{ POLLMSG, "POLLMSG" },
#endif
#ifdef POLLREMOVE
{ POLLREMOVE, "POLLREMOVE" },
#endif
#ifdef POLLRDHUP
{ POLLRDHUP, "POLLRDHUP" },
#endif
#ifdef POLLINIGNEOF
{ POLLINIGNEOF, "POLLINIGNEOF" },
#endif
{ POLLERR, "POLLERR" },
{ POLLHUP, "POLLHUP" },
{ POLLNVAL, "POLLNVAL" },
{ 0, "" },
};
/* Return the human-readable ASCII string corresponding to a given
* flag value, or "???" if none matches.
*/
static const char *flag_name(struct flag_name *flags_array, u64 flag)
{
while (flags_array->name && flags_array->flag != flag)
flags_array++;
if (flags_array->flag == flag)
return flags_array->name;
else
return "???";
}
char *flags_to_string(struct flag_name *flags_array, u64 flags)
{
u64 bit_mask = 1;
int i = 0;
char *out = strdup("");
for (i = 0; i < 64; ++i) {
if (flags & bit_mask) {
char *tmp = NULL;
asprintf(&tmp, "%s%s%s",
out,
out[0] ? "|" : "",
flag_name(flags_array, bit_mask));
free(out);
out = tmp;
}
bit_mask <<= 1;
}
return out;
}
/* Fill in 'out' with an unescaped version of the input string. On
* success, return STATUS_OK; on error, return STATUS_ERR and store
* an error message in *error.
*/
static int unescape_cstring_expression(const char *input_string,
struct expression *out, char **error)
{
int bytes = strlen(input_string);
out->type = EXPR_STRING;
out->value.string = (char *)malloc(bytes);
const char *c_in = input_string;
char *c_out = out->value.string;
while (*c_in != '\0') {
if (*c_in == '\\') {
++c_in;
switch (*c_in) {
case '\\':
*c_out = '\\';
case '"':
*c_out = '"';
case 'f':
*c_out = '\f';
break;
case 'n':
*c_out = '\n';
break;
case 'r':
*c_out = '\r';
break;
case 't':
*c_out = '\t';
break;
case 'v':
*c_out = '\v';
break;
default:
asprintf(error, "unsupported escape code: '%c'",
*c_in);
return STATUS_ERR;
}
} else {
*c_out = *c_in;
}
++c_in;
++c_out;
}
return STATUS_OK;
}
void free_expression(struct expression *expression)
{
if (expression == NULL)
return;
if ((expression->type <= EXPR_NONE) ||
(expression->type >= NUM_EXPR_TYPES))
assert(!"bad expression type");
switch (expression->type) {
case EXPR_NULL:
case EXPR_ELLIPSIS:
case EXPR_INTEGER:
break;
case EXPR_LINGER:
assert(expression->value.linger);
free_expression(expression->value.linger->l_onoff);
free_expression(expression->value.linger->l_linger);
break;
case EXPR_SCTP_RTOINFO:
assert(expression->value.sctp_rtoinfo);
free_expression(expression->value.sctp_rtoinfo->srto_assoc_id);
free_expression(expression->value.sctp_rtoinfo->srto_initial);
free_expression(expression->value.sctp_rtoinfo->srto_max);
free_expression(expression->value.sctp_rtoinfo->srto_min);
break;
case EXPR_SCTP_ASSOC_VALUE:
assert(expression->value.sctp_assoc_value);
free_expression(expression->value.sctp_assoc_value->assoc_id);
free_expression(expression->value.sctp_assoc_value->assoc_value);
break;
case EXPR_SCTP_INITMSG:
assert(expression->value.sctp_initmsg);
free_expression(expression->value.sctp_initmsg->sinit_num_ostreams);
free_expression(expression->value.sctp_initmsg->sinit_max_instreams);
free_expression(expression->value.sctp_initmsg->sinit_max_attempts);
free_expression(expression->value.sctp_initmsg->sinit_max_init_timeo);
break;
case EXPR_SCTP_SACKINFO:
assert(expression->value.sctp_sack_info);
free_expression(expression->value.sctp_sack_info->sack_assoc_id);
free_expression(expression->value.sctp_sack_info->sack_delay);
free_expression(expression->value.sctp_sack_info->sack_freq);
break;
case EXPR_SCTP_PADDRINFO:
assert(expression->value.sctp_paddrinfo);
free_expression(expression->value.sctp_paddrinfo->spinfo_address);
free_expression(expression->value.sctp_paddrinfo->spinfo_state);
free_expression(expression->value.sctp_paddrinfo->spinfo_cwnd);
free_expression(expression->value.sctp_paddrinfo->spinfo_srtt);
free_expression(expression->value.sctp_paddrinfo->spinfo_rto);
free_expression(expression->value.sctp_paddrinfo->spinfo_mtu);
break;
case EXPR_SCTP_STATUS:
assert(expression->value.sctp_status);
free_expression(expression->value.sctp_status->sstat_assoc_id);
free_expression(expression->value.sctp_status->sstat_state);
free_expression(expression->value.sctp_status->sstat_rwnd);
free_expression(expression->value.sctp_status->sstat_unackdata);
free_expression(expression->value.sctp_status->sstat_penddata);
free_expression(expression->value.sctp_status->sstat_instrms);
free_expression(expression->value.sctp_status->sstat_outstrms);
free_expression(expression->value.sctp_status->sstat_fragmentation_point);
free_expression(expression->value.sctp_status->sstat_primary);
break;
case EXPR_SCTP_PEER_ADDR_PARAMS:
assert(expression->value.sctp_paddrparams);
free_expression(expression->value.sctp_paddrparams->spp_assoc_id);
free_expression(expression->value.sctp_paddrparams->spp_address);
free_expression(expression->value.sctp_paddrparams->spp_hbinterval);
free_expression(expression->value.sctp_paddrparams->spp_pathmaxrxt);
free_expression(expression->value.sctp_paddrparams->spp_pathmtu);
free_expression(expression->value.sctp_paddrparams->spp_flags);
free_expression(expression->value.sctp_paddrparams->spp_ipv6_flowlabel);
free_expression(expression->value.sctp_paddrparams->spp_dscp);
break;
case EXPR_SCTP_STREAM_VALUE:
assert(expression->value.sctp_stream_value);
free_expression(expression->value.sctp_stream_value->stream_id);
free_expression(expression->value.sctp_stream_value->stream_value);
break;
case EXPR_SCTP_ASSOCPARAMS:
free_expression(expression->value.sctp_assocparams->sasoc_assoc_id);
free_expression(expression->value.sctp_assocparams->sasoc_asocmaxrxt);
free_expression(expression->value.sctp_assocparams->sasoc_number_peer_destinations);
free_expression(expression->value.sctp_assocparams->sasoc_peer_rwnd);
free_expression(expression->value.sctp_assocparams->sasoc_local_rwnd);
free_expression(expression->value.sctp_assocparams->sasoc_cookie_life);
break;
case EXPR_SCTP_EVENT:
free_expression(expression->value.sctp_event->se_assoc_id);
free_expression(expression->value.sctp_event->se_type);
free_expression(expression->value.sctp_event->se_on);
break;
case EXPR_SCTP_EVENT_SUBSCRIBE:
free_expression(expression->value.sctp_event_subscribe->sctp_data_io_event);
free_expression(expression->value.sctp_event_subscribe->sctp_association_event);
free_expression(expression->value.sctp_event_subscribe->sctp_address_event);
free_expression(expression->value.sctp_event_subscribe->sctp_send_failure_event);
free_expression(expression->value.sctp_event_subscribe->sctp_peer_error_event);
free_expression(expression->value.sctp_event_subscribe->sctp_shutdown_event);
free_expression(expression->value.sctp_event_subscribe->sctp_partial_delivery_event);
free_expression(expression->value.sctp_event_subscribe->sctp_adaptation_layer_event);
free_expression(expression->value.sctp_event_subscribe->sctp_authentication_event);
free_expression(expression->value.sctp_event_subscribe->sctp_sender_dry_event);
break;
case EXPR_SCTP_SNDINFO:
free_expression(expression->value.sctp_sndinfo->snd_sid);
free_expression(expression->value.sctp_sndinfo->snd_flags);
free_expression(expression->value.sctp_sndinfo->snd_ppid);
free_expression(expression->value.sctp_sndinfo->snd_context);
free_expression(expression->value.sctp_sndinfo->snd_assoc_id);
break;
case EXPR_SCTP_SETPRIM:
free_expression(expression->value.sctp_setprim->ssp_assoc_id);
free_expression(expression->value.sctp_setprim->ssp_addr);
break;
case EXPR_SCTP_SETADAPTATION:
free_expression(expression->value.sctp_setadaptation->ssb_adaptation_ind);
break;
case EXPR_SCTP_SNDRCVINFO:
free_expression(expression->value.sctp_sndrcvinfo->sinfo_stream);
free_expression(expression->value.sctp_sndrcvinfo->sinfo_ssn);
free_expression(expression->value.sctp_sndrcvinfo->sinfo_flags);
free_expression(expression->value.sctp_sndrcvinfo->sinfo_ppid);
free_expression(expression->value.sctp_sndrcvinfo->sinfo_context);
free_expression(expression->value.sctp_sndrcvinfo->sinfo_timetolive);
free_expression(expression->value.sctp_sndrcvinfo->sinfo_tsn);
free_expression(expression->value.sctp_sndrcvinfo->sinfo_cumtsn);
free_expression(expression->value.sctp_sndrcvinfo->sinfo_assoc_id);
break;
case EXPR_SCTP_PRINFO:
free_expression(expression->value.sctp_prinfo->pr_policy);
free_expression(expression->value.sctp_prinfo->pr_value);
break;
case EXPR_SCTP_DEFAULT_PRINFO:
free_expression(expression->value.sctp_default_prinfo->pr_policy);
free_expression(expression->value.sctp_default_prinfo->pr_value);
free_expression(expression->value.sctp_default_prinfo->pr_assoc_id);
break;
case EXPR_SCTP_AUTHINFO:
free_expression(expression->value.sctp_authinfo->auth_keynumber);
break;
case EXPR_SCTP_SENDV_SPA:
free_expression(expression->value.sctp_sendv_spa->sendv_flags);
free_expression(expression->value.sctp_sendv_spa->sendv_sndinfo);
free_expression(expression->value.sctp_sendv_spa->sendv_prinfo);
free_expression(expression->value.sctp_sendv_spa->sendv_authinfo);
break;
case EXPR_SCTP_RCVINFO:
free_expression(expression->value.sctp_rcvinfo->rcv_sid);
free_expression(expression->value.sctp_rcvinfo->rcv_ssn);
free_expression(expression->value.sctp_rcvinfo->rcv_flags);
free_expression(expression->value.sctp_rcvinfo->rcv_ppid);
free_expression(expression->value.sctp_rcvinfo->rcv_tsn);
free_expression(expression->value.sctp_rcvinfo->rcv_cumtsn);
free_expression(expression->value.sctp_rcvinfo->rcv_context);
free_expression(expression->value.sctp_rcvinfo->rcv_assoc_id);
break;
case EXPR_SCTP_NXTINFO:
free_expression(expression->value.sctp_nxtinfo->nxt_sid);
free_expression(expression->value.sctp_nxtinfo->nxt_flags);
free_expression(expression->value.sctp_nxtinfo->nxt_ppid);
free_expression(expression->value.sctp_nxtinfo->nxt_length);
free_expression(expression->value.sctp_nxtinfo->nxt_assoc_id);
break;
case EXPR_SCTP_RECVV_RN:
free_expression(expression->value.sctp_recvv_rn->recvv_rcvinfo);
free_expression(expression->value.sctp_recvv_rn->recvv_nxtinfo);
break;
case EXPR_SCTP_ASSOC_CHANGE:
free_expression(expression->value.sctp_assoc_change->sac_type);
free_expression(expression->value.sctp_assoc_change->sac_flags);
free_expression(expression->value.sctp_assoc_change->sac_length);
free_expression(expression->value.sctp_assoc_change->sac_state);
free_expression(expression->value.sctp_assoc_change->sac_error);
free_expression(expression->value.sctp_assoc_change->sac_outbound_streams);
free_expression(expression->value.sctp_assoc_change->sac_inbound_streams);
free_expression(expression->value.sctp_assoc_change->sac_assoc_id);
free_expression(expression->value.sctp_assoc_change->sac_info);
break;
case EXPR_SCTP_PADDR_CHANGE:
free_expression(expression->value.sctp_paddr_change->spc_type);
free_expression(expression->value.sctp_paddr_change->spc_flags);
free_expression(expression->value.sctp_paddr_change->spc_length);
free_expression(expression->value.sctp_paddr_change->spc_aaddr);
free_expression(expression->value.sctp_paddr_change->spc_state);
free_expression(expression->value.sctp_paddr_change->spc_error);
free_expression(expression->value.sctp_paddr_change->spc_assoc_id);
break;
case EXPR_SCTP_REMOTE_ERROR:
free_expression(expression->value.sctp_remote_error->sre_type);
free_expression(expression->value.sctp_remote_error->sre_flags);
free_expression(expression->value.sctp_remote_error->sre_length);
free_expression(expression->value.sctp_remote_error->sre_error);
free_expression(expression->value.sctp_remote_error->sre_assoc_id);
free_expression(expression->value.sctp_remote_error->sre_data);
break;
case EXPR_SCTP_SEND_FAILED:
free_expression(expression->value.sctp_send_failed->ssf_type);
free_expression(expression->value.sctp_send_failed->ssf_flags);
free_expression(expression->value.sctp_send_failed->ssf_length);
free_expression(expression->value.sctp_send_failed->ssf_error);
free_expression(expression->value.sctp_send_failed->ssf_info);
free_expression(expression->value.sctp_send_failed->ssf_assoc_id);
free_expression(expression->value.sctp_send_failed->ssf_data);
break;
case EXPR_SCTP_SHUTDOWN_EVENT:
free_expression(expression->value.sctp_shutdown_event->sse_type);
free_expression(expression->value.sctp_shutdown_event->sse_flags);
free_expression(expression->value.sctp_shutdown_event->sse_length);
free_expression(expression->value.sctp_shutdown_event->sse_assoc_id);
break;
case EXPR_SCTP_ADAPTATION_EVENT:
free_expression(expression->value.sctp_adaptation_event->sai_type);
free_expression(expression->value.sctp_adaptation_event->sai_flags);
free_expression(expression->value.sctp_adaptation_event->sai_length);
free_expression(expression->value.sctp_adaptation_event->sai_adaptation_ind);
free_expression(expression->value.sctp_adaptation_event->sai_assoc_id);
break;
case EXPR_SCTP_PDAPI_EVENT:
free_expression(expression->value.sctp_pdapi_event->pdapi_type);
free_expression(expression->value.sctp_pdapi_event->pdapi_flags);
free_expression(expression->value.sctp_pdapi_event->pdapi_length);
free_expression(expression->value.sctp_pdapi_event->pdapi_indication);
free_expression(expression->value.sctp_pdapi_event->pdapi_stream);
free_expression(expression->value.sctp_pdapi_event->pdapi_seq);
free_expression(expression->value.sctp_pdapi_event->pdapi_assoc_id);
break;
case EXPR_SCTP_AUTHKEY_EVENT:
free_expression(expression->value.sctp_authkey_event->auth_type);
free_expression(expression->value.sctp_authkey_event->auth_flags);
free_expression(expression->value.sctp_authkey_event->auth_length);
free_expression(expression->value.sctp_authkey_event->auth_keynumber);
free_expression(expression->value.sctp_authkey_event->auth_indication);
free_expression(expression->value.sctp_authkey_event->auth_assoc_id);
break;
case EXPR_SCTP_SENDER_DRY_EVENT:
free_expression(expression->value.sctp_sender_dry_event->sender_dry_type);
free_expression(expression->value.sctp_sender_dry_event->sender_dry_flags);
free_expression(expression->value.sctp_sender_dry_event->sender_dry_length);
free_expression(expression->value.sctp_sender_dry_event->sender_dry_assoc_id);
break;
case EXPR_SCTP_SEND_FAILED_EVENT:
free_expression(expression->value.sctp_send_failed_event->ssfe_type);
free_expression(expression->value.sctp_send_failed_event->ssfe_flags);
free_expression(expression->value.sctp_send_failed_event->ssfe_length);
free_expression(expression->value.sctp_send_failed_event->ssfe_error);
free_expression(expression->value.sctp_send_failed_event->ssfe_info);
free_expression(expression->value.sctp_send_failed_event->ssfe_assoc_id);
free_expression(expression->value.sctp_send_failed_event->ssfe_data);
break;
case EXPR_SCTP_TLV:
free_expression(expression->value.sctp_tlv->sn_type);
free_expression(expression->value.sctp_tlv->sn_flags);
free_expression(expression->value.sctp_tlv->sn_length);
break;
case EXPR_SCTP_EXTRCVINFO:
free_expression(expression->value.sctp_extrcvinfo->sinfo_stream);
free_expression(expression->value.sctp_extrcvinfo->sinfo_ssn);
free_expression(expression->value.sctp_extrcvinfo->sinfo_flags);
free_expression(expression->value.sctp_extrcvinfo->sinfo_ppid);
free_expression(expression->value.sctp_extrcvinfo->sinfo_context);
free_expression(expression->value.sctp_extrcvinfo->sinfo_pr_value);
free_expression(expression->value.sctp_extrcvinfo->sinfo_tsn);
free_expression(expression->value.sctp_extrcvinfo->sinfo_cumtsn);
free_expression(expression->value.sctp_extrcvinfo->serinfo_next_flags);
free_expression(expression->value.sctp_extrcvinfo->serinfo_next_stream);
free_expression(expression->value.sctp_extrcvinfo->serinfo_next_aid);
free_expression(expression->value.sctp_extrcvinfo->serinfo_next_length);
free_expression(expression->value.sctp_extrcvinfo->serinfo_next_ppid);
free_expression(expression->value.sctp_extrcvinfo->sinfo_assoc_id);
break;
case EXPR_WORD:
assert(expression->value.string);
free(expression->value.string);
break;
case EXPR_STRING:
assert(expression->value.string);
free(expression->value.string);
break;
case EXPR_SOCKET_ADDRESS_IPV4:
assert(expression->value.socket_address_ipv4);
free(expression->value.socket_address_ipv4);
break;
case EXPR_SOCKET_ADDRESS_IPV6:
assert(expression->value.socket_address_ipv6);
free(expression->value.socket_address_ipv6);
break;
case EXPR_BINARY:
assert(expression->value.binary);
free(expression->value.binary->op);
free_expression(expression->value.binary->lhs);
free_expression(expression->value.binary->rhs);
free(expression->value.binary);
break;
case EXPR_LIST:
free_expression_list(expression->value.list);
break;
case EXPR_IOVEC:
assert(expression->value.iovec);
free_expression(expression->value.iovec->iov_base);
free_expression(expression->value.iovec->iov_len);
break;
case EXPR_MSGHDR:
assert(expression->value.msghdr);
free_expression(expression->value.msghdr->msg_name);
free_expression(expression->value.msghdr->msg_namelen);
free_expression(expression->value.msghdr->msg_iov);
free_expression(expression->value.msghdr->msg_iovlen);
free_expression(expression->value.msghdr->msg_control);
free_expression(expression->value.msghdr->msg_controllen);
free_expression(expression->value.msghdr->msg_flags);
break;
case EXPR_CMSGHDR:
free_expression(expression->value.cmsghdr->cmsg_len);
free_expression(expression->value.cmsghdr->cmsg_level);
free_expression(expression->value.cmsghdr->cmsg_type);
free_expression(expression->value.cmsghdr->cmsg_data);
break;
case EXPR_POLLFD:
assert(expression->value.pollfd);
free_expression(expression->value.pollfd->fd);
free_expression(expression->value.pollfd->events);
free_expression(expression->value.pollfd->revents);
break;
case EXPR_NONE:
case NUM_EXPR_TYPES:
break;
/* missing default case so compiler catches missing cases */
}
memset(expression, 0, sizeof(*expression)); /* paranoia */
free(expression);
}
void free_expression_list(struct expression_list *list)
{
while (list != NULL) {
free_expression(list->expression);
struct expression_list *dead = list;
list = list->next;
free(dead);
}
}
static int evaluate_binary_expression(struct expression *in,
struct expression *out, char **error)
{
int result = STATUS_ERR;
assert(in->type == EXPR_BINARY);
assert(in->value.binary);
out->type = EXPR_INTEGER;
struct expression *lhs = NULL;
struct expression *rhs = NULL;
if (evaluate(in->value.binary->lhs, &lhs, error))
goto error_out;
if (evaluate(in->value.binary->rhs, &rhs, error))
goto error_out;
if (strcmp("|", in->value.binary->op) == 0) {
if (lhs->type != EXPR_INTEGER) {
asprintf(error, "left hand side of | not an integer");
} else if (rhs->type != EXPR_INTEGER) {
asprintf(error, "right hand side of | not an integer");
} else {
out->value.num = lhs->value.num | rhs->value.num;
result = STATUS_OK;
}
} else {
asprintf(error, "bad binary operator '%s'",
in->value.binary->op);
}
error_out:
free_expression(rhs);
free_expression(lhs);
return result;
}
static int evaluate_list_expression(struct expression *in,
struct expression *out, char **error)
{
assert(in->type == EXPR_LIST);
assert(out->type == EXPR_LIST);
out->value.list = NULL;
return evaluate_expression_list(in->value.list,
&out->value.list, error);
}
static int evaluate_iovec_expression(struct expression *in,
struct expression *out, char **error)
{
struct iovec_expr *in_iov;
struct iovec_expr *out_iov;
assert(in->type == EXPR_IOVEC);
assert(in->value.iovec);
assert(out->type == EXPR_IOVEC);
out->value.iovec = calloc(1, sizeof(struct iovec_expr));
in_iov = in->value.iovec;
out_iov = out->value.iovec;
if (evaluate(in_iov->iov_base, &out_iov->iov_base, error))
return STATUS_ERR;
if (evaluate(in_iov->iov_len, &out_iov->iov_len, error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_cmsghdr_expression(struct expression *in,
struct expression *out, char **error)
{
struct cmsghdr_expr *in_cmsg;
struct cmsghdr_expr *out_cmsg;
assert(in->type == EXPR_CMSGHDR);
assert(in->value.msghdr);
assert(out->type == EXPR_CMSGHDR);
out->value.cmsghdr = calloc(1, sizeof(struct cmsghdr_expr));
in_cmsg = in->value.cmsghdr;
out_cmsg = out->value.cmsghdr;
if (evaluate(in_cmsg->cmsg_len, &out_cmsg->cmsg_len, error))
return STATUS_ERR;
if (evaluate(in_cmsg->cmsg_level, &out_cmsg->cmsg_level, error))
return STATUS_ERR;
if (evaluate(in_cmsg->cmsg_type, &out_cmsg->cmsg_type, error))
return STATUS_ERR;
if (evaluate(in_cmsg->cmsg_data, &out_cmsg->cmsg_data, error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_msghdr_expression(struct expression *in,
struct expression *out, char **error)
{
struct msghdr_expr *in_msg;
struct msghdr_expr *out_msg;
assert(in->type == EXPR_MSGHDR);
assert(in->value.msghdr);
assert(out->type == EXPR_MSGHDR);
out->value.msghdr = calloc(1, sizeof(struct msghdr_expr));
in_msg = in->value.msghdr;
out_msg = out->value.msghdr;
if (evaluate(in_msg->msg_name, &out_msg->msg_name, error))
return STATUS_ERR;
if (evaluate(in_msg->msg_namelen, &out_msg->msg_namelen, error))
return STATUS_ERR;
if (evaluate(in_msg->msg_iov, &out_msg->msg_iov, error))
return STATUS_ERR;
if (evaluate(in_msg->msg_iovlen, &out_msg->msg_iovlen, error))
return STATUS_ERR;
if (evaluate(in_msg->msg_control, &out_msg->msg_control, error))
return STATUS_ERR;
if (evaluate(in_msg->msg_controllen, &out_msg->msg_controllen,error))
return STATUS_ERR;
if (evaluate(in_msg->msg_flags, &out_msg->msg_flags, error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_pollfd_expression(struct expression *in,
struct expression *out, char **error)
{
struct pollfd_expr *in_pollfd;
struct pollfd_expr *out_pollfd;
assert(in->type == EXPR_POLLFD);
assert(in->value.pollfd);
assert(out->type == EXPR_POLLFD);
out->value.pollfd = calloc(1, sizeof(struct pollfd_expr));
in_pollfd = in->value.pollfd;
out_pollfd = out->value.pollfd;
if (evaluate(in_pollfd->fd, &out_pollfd->fd, error))
return STATUS_ERR;
if (evaluate(in_pollfd->events, &out_pollfd->events, error))
return STATUS_ERR;
if (evaluate(in_pollfd->revents, &out_pollfd->revents, error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_rtoinfo_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_rtoinfo_expr *in_rtoinfo;
struct sctp_rtoinfo_expr *out_rtoinfo;
assert(in->type == EXPR_SCTP_RTOINFO);
assert(in->value.sctp_rtoinfo);
assert(out->type == EXPR_SCTP_RTOINFO);
out->value.sctp_rtoinfo = calloc(1, sizeof(struct sctp_rtoinfo_expr));
in_rtoinfo = in->value.sctp_rtoinfo;
out_rtoinfo = out->value.sctp_rtoinfo;
if (evaluate(in_rtoinfo->srto_assoc_id,
&out_rtoinfo->srto_assoc_id,
error))
return STATUS_ERR;
if (evaluate(in_rtoinfo->srto_initial,
&out_rtoinfo->srto_initial,
error))
return STATUS_ERR;
if (evaluate(in_rtoinfo->srto_max,
&out_rtoinfo->srto_max,
error))
return STATUS_ERR;
if (evaluate(in_rtoinfo->srto_min,
&out_rtoinfo->srto_min,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_initmsg_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_initmsg_expr *in_initmsg;
struct sctp_initmsg_expr *out_initmsg;
assert(in->type == EXPR_SCTP_INITMSG);
assert(in->value.sctp_initmsg);
assert(out->type == EXPR_SCTP_INITMSG);
out->value.sctp_initmsg = calloc(1, sizeof(struct sctp_initmsg_expr));
in_initmsg = in->value.sctp_initmsg;
out_initmsg = out->value.sctp_initmsg;
if (evaluate(in_initmsg->sinit_num_ostreams,
&out_initmsg->sinit_num_ostreams,
error))
return STATUS_ERR;
if (evaluate(in_initmsg->sinit_max_instreams,
&out_initmsg->sinit_max_instreams,
error))
return STATUS_ERR;
if (evaluate(in_initmsg->sinit_max_attempts,
&out_initmsg->sinit_max_attempts,
error))
return STATUS_ERR;
if (evaluate(in_initmsg->sinit_max_init_timeo,
&out_initmsg->sinit_max_init_timeo,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_assoc_value_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_assoc_value_expr *in_value;
struct sctp_assoc_value_expr *out_value;
assert(in->type == EXPR_SCTP_ASSOC_VALUE);
assert(in->value.sctp_assoc_value);
assert(out->type == EXPR_SCTP_ASSOC_VALUE);
out->value.sctp_assoc_value = calloc(1, sizeof(struct sctp_assoc_value_expr));
in_value = in->value.sctp_assoc_value;
out_value = out->value.sctp_assoc_value;
if (evaluate(in_value->assoc_id,
&out_value->assoc_id,
error))
return STATUS_ERR;
if (evaluate(in_value->assoc_value,
&out_value->assoc_value,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_sack_info_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_sack_info_expr *in_sack_info;
struct sctp_sack_info_expr *out_sack_info;
assert(in->type == EXPR_SCTP_SACKINFO);
assert(in->value.sctp_sack_info);
assert(out->type == EXPR_SCTP_SACKINFO);
out->value.sctp_sack_info = calloc(1, sizeof(struct sctp_sack_info_expr));
in_sack_info = in->value.sctp_sack_info;
out_sack_info = out->value.sctp_sack_info;
if (evaluate(in_sack_info->sack_assoc_id,
&out_sack_info->sack_assoc_id,
error))
return STATUS_ERR;
if (evaluate(in_sack_info->sack_delay,
&out_sack_info->sack_delay,
error))
return STATUS_ERR;
if (evaluate(in_sack_info->sack_freq,
&out_sack_info->sack_freq,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_paddrinfo_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_paddrinfo_expr *in_paddrinfo;
struct sctp_paddrinfo_expr *out_paddrinfo;
assert(in->type == EXPR_SCTP_PADDRINFO);
assert(in->value.sctp_paddrinfo);
assert(out->type == EXPR_SCTP_PADDRINFO);
out->value.sctp_paddrinfo = calloc(1, sizeof(struct sctp_paddrinfo_expr));
in_paddrinfo = in->value.sctp_paddrinfo;
out_paddrinfo = out->value.sctp_paddrinfo;
if (evaluate(in_paddrinfo->spinfo_address,
&out_paddrinfo->spinfo_address,
error))
return STATUS_ERR;
if (evaluate(in_paddrinfo->spinfo_state,
&out_paddrinfo->spinfo_state,
error))
return STATUS_ERR;
if (evaluate(in_paddrinfo->spinfo_cwnd,
&out_paddrinfo->spinfo_cwnd,
error))
return STATUS_ERR;
if (evaluate(in_paddrinfo->spinfo_srtt,
&out_paddrinfo->spinfo_srtt,
error))
return STATUS_ERR;
if (evaluate(in_paddrinfo->spinfo_rto,
&out_paddrinfo->spinfo_rto,
error))
return STATUS_ERR;
if (evaluate(in_paddrinfo->spinfo_mtu,
&out_paddrinfo->spinfo_mtu,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_status_expression(struct expression *in,
struct expression *out, char **error)
{
struct sctp_status_expr *in_status;
struct sctp_status_expr *out_status;
assert(in->type == EXPR_SCTP_STATUS);
assert(in->value.sctp_status);
assert(out->type == EXPR_SCTP_STATUS);
out->value.sctp_status = calloc(1, sizeof(struct sctp_status_expr));
in_status = in->value.sctp_status;
out_status = out->value.sctp_status;
if (evaluate(in_status->sstat_assoc_id,
&out_status->sstat_assoc_id,
error))
return STATUS_ERR;
if (evaluate(in_status->sstat_state,
&out_status->sstat_state,
error))
return STATUS_ERR;
if (evaluate(in_status->sstat_rwnd,
&out_status->sstat_rwnd,
error))
return STATUS_ERR;
if (evaluate(in_status->sstat_unackdata,
&out_status->sstat_unackdata,
error))
return STATUS_ERR;
if (evaluate(in_status->sstat_penddata,
&out_status->sstat_penddata,
error))
return STATUS_ERR;
if (evaluate(in_status->sstat_instrms,
&out_status->sstat_instrms,
error))
return STATUS_ERR;
if (evaluate(in_status->sstat_outstrms,
&out_status->sstat_outstrms,
error))
return STATUS_ERR;
if (evaluate(in_status->sstat_fragmentation_point,
&out_status->sstat_fragmentation_point,
error))
return STATUS_ERR;
if (evaluate(in_status->sstat_primary,
&out_status->sstat_primary,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_peer_addr_param_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_paddrparams_expr *in_paddrparams;
struct sctp_paddrparams_expr *out_paddrparams;
assert(in->type == EXPR_SCTP_PEER_ADDR_PARAMS);
assert(in->value.sctp_paddrparams);
assert(out->type == EXPR_SCTP_PEER_ADDR_PARAMS);
out->value.sctp_paddrparams = calloc(1, sizeof(struct sctp_paddrparams_expr));
in_paddrparams = in->value.sctp_paddrparams;
out_paddrparams = out->value.sctp_paddrparams;
if (evaluate(in_paddrparams->spp_assoc_id,
&out_paddrparams->spp_assoc_id,
error))
return STATUS_ERR;
if (evaluate(in_paddrparams->spp_address,
&out_paddrparams->spp_address,
error))
return STATUS_ERR;
if (evaluate(in_paddrparams->spp_hbinterval,
&out_paddrparams->spp_hbinterval,
error))
return STATUS_ERR;
if (evaluate(in_paddrparams->spp_pathmaxrxt,
&out_paddrparams->spp_pathmaxrxt,
error))
return STATUS_ERR;
if (evaluate(in_paddrparams->spp_pathmtu,
&out_paddrparams->spp_pathmtu,
error))
return STATUS_ERR;
if (evaluate(in_paddrparams->spp_flags,
&out_paddrparams->spp_flags,
error))
return STATUS_ERR;
if (evaluate(in_paddrparams->spp_ipv6_flowlabel,
&out_paddrparams->spp_ipv6_flowlabel,
error))
return STATUS_ERR;
if (evaluate(in_paddrparams->spp_dscp,
&out_paddrparams->spp_dscp,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_stream_value_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_stream_value_expr *in_value;
struct sctp_stream_value_expr *out_value;
assert(in->type == EXPR_SCTP_STREAM_VALUE);
assert(in->value.sctp_stream_value);
assert(out->type == EXPR_SCTP_STREAM_VALUE);
out->value.sctp_stream_value = calloc(1, sizeof(struct sctp_stream_value_expr));
in_value = in->value.sctp_stream_value;
out_value = out->value.sctp_stream_value;
if (evaluate(in_value->stream_id,
&out_value->stream_id,
error))
return STATUS_ERR;
if (evaluate(in_value->stream_value,
&out_value->stream_value,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_event_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_event_expr *in_event;
struct sctp_event_expr *out_event;
assert(in->type == EXPR_SCTP_EVENT);
assert(in->value.sctp_event);
assert(out->type == EXPR_SCTP_EVENT);
out->value.sctp_event = calloc(1, sizeof(struct sctp_event_expr));
in_event = in->value.sctp_event;
out_event = out->value.sctp_event;
if (evaluate(in_event->se_assoc_id,
&out_event->se_assoc_id,
error))
return STATUS_ERR;
if (evaluate(in_event->se_type,
&out_event->se_type,
error))
return STATUS_ERR;
if (evaluate(in_event->se_on,
&out_event->se_on,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_event_subscribe_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_event_subscribe_expr *in_event;
struct sctp_event_subscribe_expr *out_event;
assert(in->type == EXPR_SCTP_EVENT_SUBSCRIBE);
assert(in->value.sctp_event_subscribe);
assert(out->type == EXPR_SCTP_EVENT_SUBSCRIBE);
out->value.sctp_event_subscribe = calloc(1, sizeof(struct sctp_event_subscribe_expr));
in_event = in->value.sctp_event_subscribe;
out_event = out->value.sctp_event_subscribe;
if (evaluate(in_event->sctp_data_io_event,
&out_event->sctp_data_io_event,
error))
return STATUS_ERR;
if (evaluate(in_event->sctp_association_event,
&out_event->sctp_association_event,
error))
return STATUS_ERR;
if (evaluate(in_event->sctp_address_event,
&out_event->sctp_address_event,
error))
return STATUS_ERR;
if (evaluate(in_event->sctp_send_failure_event,
&out_event->sctp_send_failure_event,
error))
return STATUS_ERR;
if (evaluate(in_event->sctp_peer_error_event,
&out_event->sctp_peer_error_event,
error))
return STATUS_ERR;
if (evaluate(in_event->sctp_shutdown_event,
&out_event->sctp_shutdown_event,
error))
return STATUS_ERR;
if (evaluate(in_event->sctp_partial_delivery_event,
&out_event->sctp_partial_delivery_event,
error))
return STATUS_ERR;
if (evaluate(in_event->sctp_adaptation_layer_event,
&out_event->sctp_adaptation_layer_event,
error))
return STATUS_ERR;
if (evaluate(in_event->sctp_authentication_event,
&out_event->sctp_authentication_event,
error))
return STATUS_ERR;
if (evaluate(in_event->sctp_sender_dry_event,
&out_event->sctp_sender_dry_event,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_accocparams_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_assocparams_expr *in_params;
struct sctp_assocparams_expr *out_params;
assert(in->type == EXPR_SCTP_ASSOCPARAMS);
assert(in->value.sctp_assocparams);
assert(out->type == EXPR_SCTP_ASSOCPARAMS);
out->value.sctp_assocparams = calloc(1, sizeof(struct sctp_assocparams_expr));
in_params = in->value.sctp_assocparams;
out_params = out->value.sctp_assocparams;
if (evaluate(in_params->sasoc_assoc_id,
&out_params->sasoc_assoc_id,
error))
return STATUS_ERR;
if (evaluate(in_params->sasoc_asocmaxrxt,
&out_params->sasoc_asocmaxrxt,
error))
return STATUS_ERR;
if (evaluate(in_params->sasoc_number_peer_destinations,
&out_params->sasoc_number_peer_destinations,
error))
return STATUS_ERR;
if (evaluate(in_params->sasoc_peer_rwnd,
&out_params->sasoc_peer_rwnd,
error))
return STATUS_ERR;
if (evaluate(in_params->sasoc_local_rwnd,
&out_params->sasoc_local_rwnd,
error))
return STATUS_ERR;
if (evaluate(in_params->sasoc_cookie_life,
&out_params->sasoc_cookie_life,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_sndinfo_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_sndinfo_expr *in_sndinfo;
struct sctp_sndinfo_expr *out_sndinfo;
assert(in->type == EXPR_SCTP_SNDINFO);
assert(in->value.sctp_sndinfo);
assert(out->type == EXPR_SCTP_SNDINFO);
out->value.sctp_sndinfo = calloc(1, sizeof(struct sctp_sndinfo_expr));
in_sndinfo = in->value.sctp_sndinfo;
out_sndinfo = out->value.sctp_sndinfo;
if (evaluate(in_sndinfo->snd_sid,
&out_sndinfo->snd_sid,
error))
return STATUS_ERR;
if (evaluate(in_sndinfo->snd_flags,
&out_sndinfo->snd_flags,
error))
return STATUS_ERR;
if (evaluate(in_sndinfo->snd_ppid,
&out_sndinfo->snd_ppid,
error))
return STATUS_ERR;
if (evaluate(in_sndinfo->snd_context,
&out_sndinfo->snd_context,
error))
return STATUS_ERR;
if (evaluate(in_sndinfo->snd_assoc_id,
&out_sndinfo->snd_assoc_id,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_setprim_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_setprim_expr *in_prim;
struct sctp_setprim_expr *out_prim;
assert(in->type == EXPR_SCTP_SETPRIM);
assert(in->value.sctp_setprim);
assert(out->type == EXPR_SCTP_SETPRIM);
out->value.sctp_setprim = calloc(1, sizeof(struct sctp_setprim_expr));
in_prim = in->value.sctp_setprim;
out_prim = out->value.sctp_setprim;
if (evaluate(in_prim->ssp_assoc_id,
&out_prim->ssp_assoc_id,
error))
return STATUS_ERR;
if (evaluate(in_prim->ssp_addr,
&out_prim->ssp_addr,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_setadaptation_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_setadaptation_expr *in_adaptation;
struct sctp_setadaptation_expr *out_adaptation;
assert(in->type == EXPR_SCTP_SETADAPTATION);
assert(in->value.sctp_setadaptation);
assert(out->type == EXPR_SCTP_SETADAPTATION);
out->value.sctp_setadaptation = calloc(1, sizeof(struct sctp_setadaptation_expr));
in_adaptation = in->value.sctp_setadaptation;
out_adaptation = out->value.sctp_setadaptation;
if (evaluate(in_adaptation->ssb_adaptation_ind,
&out_adaptation->ssb_adaptation_ind,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_sndrcvinfo_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_sndrcvinfo_expr *in_info;
struct sctp_sndrcvinfo_expr *out_info;
assert(in->type == EXPR_SCTP_SNDRCVINFO);
assert(in->value.sctp_sndrcvinfo);
assert(out->type == EXPR_SCTP_SNDRCVINFO);
out->value.sctp_sndrcvinfo = calloc(1, sizeof(struct sctp_sndrcvinfo_expr));
in_info = in->value.sctp_sndrcvinfo;
out_info = out->value.sctp_sndrcvinfo;
if (evaluate(in_info->sinfo_stream,
&out_info->sinfo_stream,
error))
return STATUS_ERR;
if (evaluate(in_info->sinfo_ssn,
&out_info->sinfo_ssn,
error))
return STATUS_ERR;
if (evaluate(in_info->sinfo_flags,
&out_info->sinfo_flags,
error))
return STATUS_ERR;
if (evaluate(in_info->sinfo_ppid,
&out_info->sinfo_ppid,
error))
return STATUS_ERR;
if (evaluate(in_info->sinfo_context,
&out_info->sinfo_context,
error))
return STATUS_ERR;
if (evaluate(in_info->sinfo_timetolive,
&out_info->sinfo_timetolive,
error))
return STATUS_ERR;
if (evaluate(in_info->sinfo_tsn,
&out_info->sinfo_tsn,
error))
return STATUS_ERR;
if (evaluate(in_info->sinfo_cumtsn,
&out_info->sinfo_cumtsn,
error))
return STATUS_ERR;
if (evaluate(in_info->sinfo_assoc_id,
&out_info->sinfo_assoc_id,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_prinfo_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_prinfo_expr *in_info;
struct sctp_prinfo_expr *out_info;
assert(in->type == EXPR_SCTP_PRINFO);
assert(in->value.sctp_prinfo);
assert(out->type == EXPR_SCTP_PRINFO);
out->value.sctp_prinfo = calloc(1, sizeof(struct sctp_prinfo_expr));
in_info = in->value.sctp_prinfo;
out_info = out->value.sctp_prinfo;
if (evaluate(in_info->pr_policy,
&out_info->pr_policy,
error))
return STATUS_ERR;
if (evaluate(in_info->pr_value,
&out_info->pr_value,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_default_prinfo_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_default_prinfo_expr *in_info;
struct sctp_default_prinfo_expr *out_info;
assert(in->type == EXPR_SCTP_DEFAULT_PRINFO);
assert(in->value.sctp_default_prinfo);
assert(out->type == EXPR_SCTP_DEFAULT_PRINFO);
out->value.sctp_default_prinfo = calloc(1, sizeof(struct sctp_default_prinfo_expr));
in_info = in->value.sctp_default_prinfo;
out_info = out->value.sctp_default_prinfo;
if (evaluate(in_info->pr_policy,
&out_info->pr_policy,
error))
return STATUS_ERR;
if (evaluate(in_info->pr_value,
&out_info->pr_value,
error))
return STATUS_ERR;
if (evaluate(in_info->pr_assoc_id,
&out_info->pr_assoc_id,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_authinfo_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_authinfo_expr *in_info;
struct sctp_authinfo_expr *out_info;
assert(in->type == EXPR_SCTP_AUTHINFO);
assert(in->value.sctp_authinfo);
assert(out->type == EXPR_SCTP_AUTHINFO);
out->value.sctp_authinfo = calloc(1, sizeof(struct sctp_authinfo_expr));
in_info = in->value.sctp_authinfo;
out_info = out->value.sctp_authinfo;
if (evaluate(in_info->auth_keynumber,
&out_info->auth_keynumber,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_sendv_spa_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_sendv_spa_expr *in_spa;
struct sctp_sendv_spa_expr *out_spa;
assert(in->type == EXPR_SCTP_SENDV_SPA);
assert(in->value.sctp_sendv_spa);
assert(out->type == EXPR_SCTP_SENDV_SPA);
out->value.sctp_sendv_spa = calloc(1, sizeof(struct sctp_sendv_spa_expr));
in_spa = in->value.sctp_sendv_spa;
out_spa = out->value.sctp_sendv_spa;
if (evaluate(in_spa->sendv_flags,
&out_spa->sendv_flags,
error))
return STATUS_ERR;
if (evaluate(in_spa->sendv_sndinfo,
&out_spa->sendv_sndinfo,
error))
return STATUS_ERR;
if (evaluate(in_spa->sendv_prinfo,
&out_spa->sendv_prinfo,
error))
return STATUS_ERR;
if (evaluate(in_spa->sendv_authinfo,
&out_spa->sendv_authinfo,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_rcvinfo_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_rcvinfo_expr *in_info;
struct sctp_rcvinfo_expr *out_info;
assert(in->type == EXPR_SCTP_RCVINFO);
assert(in->value.sctp_rcvinfo);
assert(out->type == EXPR_SCTP_RCVINFO);
out->value.sctp_rcvinfo = calloc(1, sizeof(struct sctp_rcvinfo_expr));
in_info = in->value.sctp_rcvinfo;
out_info = out->value.sctp_rcvinfo;
if (evaluate(in_info->rcv_sid,
&out_info->rcv_sid,
error))
return STATUS_ERR;
if (evaluate(in_info->rcv_ssn,
&out_info->rcv_ssn,
error))
return STATUS_ERR;
if (evaluate(in_info->rcv_flags,
&out_info->rcv_flags,
error))
return STATUS_ERR;
if (evaluate(in_info->rcv_ppid,
&out_info->rcv_ppid,
error))
return STATUS_ERR;
if (evaluate(in_info->rcv_tsn,
&out_info->rcv_tsn,
error))
return STATUS_ERR;
if (evaluate(in_info->rcv_cumtsn,
&out_info->rcv_cumtsn,
error))
return STATUS_ERR;
if (evaluate(in_info->rcv_context,
&out_info->rcv_context,
error))
return STATUS_ERR;
if (evaluate(in_info->rcv_assoc_id,
&out_info->rcv_assoc_id,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_nxtinfo_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_nxtinfo_expr *in_info;
struct sctp_nxtinfo_expr *out_info;
assert(in->type == EXPR_SCTP_NXTINFO);
assert(in->value.sctp_nxtinfo);
assert(out->type == EXPR_SCTP_NXTINFO);
out->value.sctp_nxtinfo = calloc(1, sizeof(struct sctp_nxtinfo_expr));
in_info = in->value.sctp_nxtinfo;
out_info = out->value.sctp_nxtinfo;
if (evaluate(in_info->nxt_sid,
&out_info->nxt_sid,
error))
return STATUS_ERR;
if (evaluate(in_info->nxt_flags,
&out_info->nxt_flags,
error))
return STATUS_ERR;
if (evaluate(in_info->nxt_ppid,
&out_info->nxt_ppid,
error))
return STATUS_ERR;
if (evaluate(in_info->nxt_length,
&out_info->nxt_length,
error))
return STATUS_ERR;
if (evaluate(in_info->nxt_assoc_id,
&out_info->nxt_assoc_id,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_recvv_rn_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_recvv_rn_expr *in_rn;
struct sctp_recvv_rn_expr *out_rn;
assert(in->type == EXPR_SCTP_RECVV_RN);
assert(in->value.sctp_recvv_rn);
assert(out->type == EXPR_SCTP_RECVV_RN);
out->value.sctp_recvv_rn = calloc(1, sizeof(struct sctp_recvv_rn_expr));
in_rn = in->value.sctp_recvv_rn;
out_rn = out->value.sctp_recvv_rn;
if (evaluate(in_rn->recvv_rcvinfo,
&out_rn->recvv_rcvinfo,
error))
return STATUS_ERR;
if (evaluate(in_rn->recvv_nxtinfo,
&out_rn->recvv_nxtinfo,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_assoc_change_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_assoc_change_expr *in_event;
struct sctp_assoc_change_expr *out_event;
assert(in->type == EXPR_SCTP_ASSOC_CHANGE);
assert(in->value.sctp_assoc_change);
assert(out->type == EXPR_SCTP_ASSOC_CHANGE);
out->value.sctp_assoc_change = calloc(1, sizeof(struct sctp_assoc_change_expr));
in_event = in->value.sctp_assoc_change;
out_event = out->value.sctp_assoc_change;
if (evaluate(in_event->sac_type,
&out_event->sac_type,
error))
return STATUS_ERR;
if (evaluate(in_event->sac_flags,
&out_event->sac_flags,
error))
return STATUS_ERR;
if (evaluate(in_event->sac_length,
&out_event->sac_length,
error))
return STATUS_ERR;
if (evaluate(in_event->sac_state,
&out_event->sac_state,
error))
return STATUS_ERR;
if (evaluate(in_event->sac_error,
&out_event->sac_error,
error))
return STATUS_ERR;
if (evaluate(in_event->sac_outbound_streams,
&out_event->sac_outbound_streams,
error))
return STATUS_ERR;
if (evaluate(in_event->sac_inbound_streams,
&out_event->sac_inbound_streams,
error))
return STATUS_ERR;
if (evaluate(in_event->sac_assoc_id,
&out_event->sac_assoc_id,
error))
return STATUS_ERR;
if (evaluate(in_event->sac_info,
&out_event->sac_info,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_paddr_change_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_paddr_change_expr *in_event;
struct sctp_paddr_change_expr *out_event;
assert(in->type == EXPR_SCTP_PADDR_CHANGE);
assert(in->value.sctp_paddr_change);
assert(out->type == EXPR_SCTP_PADDR_CHANGE);
out->value.sctp_paddr_change = calloc(1, sizeof(struct sctp_paddr_change_expr));
in_event = in->value.sctp_paddr_change;
out_event = out->value.sctp_paddr_change;
if (evaluate(in_event->spc_type,
&out_event->spc_type,
error))
return STATUS_ERR;
if (evaluate(in_event->spc_flags,
&out_event->spc_flags,
error))
return STATUS_ERR;
if (evaluate(in_event->spc_length,
&out_event->spc_length,
error))
return STATUS_ERR;
if (evaluate(in_event->spc_aaddr,
&out_event->spc_aaddr,
error))
return STATUS_ERR;
if (evaluate(in_event->spc_state,
&out_event->spc_state,
error))
return STATUS_ERR;
if (evaluate(in_event->spc_error,
&out_event->spc_error,
error))
return STATUS_ERR;
if (evaluate(in_event->spc_assoc_id,
&out_event->spc_assoc_id,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_remote_error_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_remote_error_expr *in_event;
struct sctp_remote_error_expr *out_event;
assert(in->type == EXPR_SCTP_REMOTE_ERROR);
assert(in->value.sctp_remote_error);
assert(out->type == EXPR_SCTP_REMOTE_ERROR);
out->value.sctp_remote_error = calloc(1, sizeof(struct sctp_remote_error_expr));
in_event = in->value.sctp_remote_error;
out_event = out->value.sctp_remote_error;
if (evaluate(in_event->sre_type,
&out_event->sre_type,
error))
return STATUS_ERR;
if (evaluate(in_event->sre_flags,
&out_event->sre_flags,
error))
return STATUS_ERR;
if (evaluate(in_event->sre_length,
&out_event->sre_length,
error))
return STATUS_ERR;
if (evaluate(in_event->sre_error,
&out_event->sre_error,
error))
return STATUS_ERR;
if (evaluate(in_event->sre_assoc_id,
&out_event->sre_assoc_id,
error))
return STATUS_ERR;
if (evaluate(in_event->sre_data,
&out_event->sre_data,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_send_failed_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_send_failed_expr *in_event;
struct sctp_send_failed_expr *out_event;
assert(in->type == EXPR_SCTP_SEND_FAILED);
assert(in->value.sctp_send_failed);
assert(out->type == EXPR_SCTP_SEND_FAILED);
out->value.sctp_send_failed = calloc(1, sizeof(struct sctp_send_failed_expr));
in_event = in->value.sctp_send_failed;
out_event = out->value.sctp_send_failed;
if (evaluate(in_event->ssf_type,
&out_event->ssf_type,
error))
return STATUS_ERR;
if (evaluate(in_event->ssf_flags,
&out_event->ssf_flags,
error))
return STATUS_ERR;
if (evaluate(in_event->ssf_length,
&out_event->ssf_length,
error))
return STATUS_ERR;
if (evaluate(in_event->ssf_error,
&out_event->ssf_error,
error))
return STATUS_ERR;
if (evaluate(in_event->ssf_info,
&out_event->ssf_info,
error))
return STATUS_ERR;
if (evaluate(in_event->ssf_assoc_id,
&out_event->ssf_assoc_id,
error))
return STATUS_ERR;
if (evaluate(in_event->ssf_data,
&out_event->ssf_data,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_shutdown_event_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_shutdown_event_expr *in_event;
struct sctp_shutdown_event_expr *out_event;
assert(in->type == EXPR_SCTP_SHUTDOWN_EVENT);
assert(in->value.sctp_shutdown_event);
assert(out->type == EXPR_SCTP_SHUTDOWN_EVENT);
out->value.sctp_shutdown_event = calloc(1, sizeof(struct sctp_shutdown_event_expr));
in_event = in->value.sctp_shutdown_event;
out_event = out->value.sctp_shutdown_event;
if (evaluate(in_event->sse_type,
&out_event->sse_type,
error))
return STATUS_ERR;
if (evaluate(in_event->sse_flags,
&out_event->sse_flags,
error))
return STATUS_ERR;
if (evaluate(in_event->sse_length,
&out_event->sse_length,
error))
return STATUS_ERR;
if (evaluate(in_event->sse_assoc_id,
&out_event->sse_assoc_id,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_adaptation_event_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_adaptation_event_expr *in_event;
struct sctp_adaptation_event_expr *out_event;
assert(in->type == EXPR_SCTP_ADAPTATION_EVENT);
assert(in->value.sctp_adaptation_event);
assert(out->type == EXPR_SCTP_ADAPTATION_EVENT);
out->value.sctp_adaptation_event = calloc(1, sizeof(struct sctp_adaptation_event_expr));
in_event = in->value.sctp_adaptation_event;
out_event = out->value.sctp_adaptation_event;
if (evaluate(in_event->sai_type,
&out_event->sai_type,
error))
return STATUS_ERR;
if (evaluate(in_event->sai_flags,
&out_event->sai_flags,
error))
return STATUS_ERR;
if (evaluate(in_event->sai_length,
&out_event->sai_length,
error))
return STATUS_ERR;
if (evaluate(in_event->sai_adaptation_ind,
&out_event->sai_adaptation_ind,
error))
return STATUS_ERR;
if (evaluate(in_event->sai_assoc_id,
&out_event->sai_assoc_id,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_pdapi_event_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_pdapi_event_expr *in_event;
struct sctp_pdapi_event_expr *out_event;
assert(in->type == EXPR_SCTP_PDAPI_EVENT);
assert(in->value.sctp_pdapi_event);
assert(out->type == EXPR_SCTP_PDAPI_EVENT);
out->value.sctp_pdapi_event = calloc(1, sizeof(struct sctp_pdapi_event_expr));
in_event = in->value.sctp_pdapi_event;
out_event = out->value.sctp_pdapi_event;
if (evaluate(in_event->pdapi_type,
&out_event->pdapi_type,
error))
return STATUS_ERR;
if (evaluate(in_event->pdapi_flags,
&out_event->pdapi_flags,
error))
return STATUS_ERR;
if (evaluate(in_event->pdapi_length,
&out_event->pdapi_length,
error))
return STATUS_ERR;
if (evaluate(in_event->pdapi_indication,
&out_event->pdapi_indication,
error))
return STATUS_ERR;
if (evaluate(in_event->pdapi_stream,
&out_event->pdapi_stream,
error))
return STATUS_ERR;
if (evaluate(in_event->pdapi_seq,
&out_event->pdapi_seq,
error))
return STATUS_ERR;
if (evaluate(in_event->pdapi_assoc_id,
&out_event->pdapi_assoc_id,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_authkey_event_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_authkey_event_expr *in_event;
struct sctp_authkey_event_expr *out_event;
assert(in->type == EXPR_SCTP_AUTHKEY_EVENT);
assert(in->value.sctp_authkey_event);
assert(out->type == EXPR_SCTP_AUTHKEY_EVENT);
out->value.sctp_authkey_event = calloc(1, sizeof(struct sctp_authkey_event_expr));
in_event = in->value.sctp_authkey_event;
out_event = out->value.sctp_authkey_event;
if (evaluate(in_event->auth_type,
&out_event->auth_type,
error))
return STATUS_ERR;
if (evaluate(in_event->auth_flags,
&out_event->auth_flags,
error))
return STATUS_ERR;
if (evaluate(in_event->auth_length,
&out_event->auth_length,
error))
return STATUS_ERR;
if (evaluate(in_event->auth_keynumber,
&out_event->auth_keynumber,
error))
return STATUS_ERR;
if (evaluate(in_event->auth_indication,
&out_event->auth_indication,
error))
return STATUS_ERR;
if (evaluate(in_event->auth_assoc_id,
&out_event->auth_assoc_id,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_sender_dry_event_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_sender_dry_event_expr *in_event;
struct sctp_sender_dry_event_expr *out_event;
assert(in->type == EXPR_SCTP_SENDER_DRY_EVENT);
assert(in->value.sctp_sender_dry_event);
assert(out->type == EXPR_SCTP_SENDER_DRY_EVENT);
out->value.sctp_sender_dry_event = calloc(1, sizeof(struct sctp_sender_dry_event_expr));
in_event = in->value.sctp_sender_dry_event;
out_event = out->value.sctp_sender_dry_event;
if (evaluate(in_event->sender_dry_type,
&out_event->sender_dry_type,
error))
return STATUS_ERR;
if (evaluate(in_event->sender_dry_flags,
&out_event->sender_dry_flags,
error))
return STATUS_ERR;
if (evaluate(in_event->sender_dry_length,
&out_event->sender_dry_length,
error))
return STATUS_ERR;
if (evaluate(in_event->sender_dry_assoc_id,
&out_event->sender_dry_assoc_id,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_send_failed_event_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_send_failed_event_expr *in_event;
struct sctp_send_failed_event_expr *out_event;
assert(in->type == EXPR_SCTP_SEND_FAILED_EVENT);
assert(in->value.sctp_send_failed_event);
assert(out->type == EXPR_SCTP_SEND_FAILED_EVENT);
out->value.sctp_send_failed_event = calloc(1, sizeof(struct sctp_send_failed_event_expr));
in_event = in->value.sctp_send_failed_event;
out_event = out->value.sctp_send_failed_event;
if (evaluate(in_event->ssfe_type,
&out_event->ssfe_type,
error))
return STATUS_ERR;
if (evaluate(in_event->ssfe_flags,
&out_event->ssfe_flags,
error))
return STATUS_ERR;
if (evaluate(in_event->ssfe_length,
&out_event->ssfe_length,
error))
return STATUS_ERR;
if (evaluate(in_event->ssfe_error,
&out_event->ssfe_error,
error))
return STATUS_ERR;
if (evaluate(in_event->ssfe_info,
&out_event->ssfe_info,
error))
return STATUS_ERR;
if (evaluate(in_event->ssfe_assoc_id,
&out_event->ssfe_assoc_id,
error))
return STATUS_ERR;
if (evaluate(in_event->ssfe_data,
&out_event->ssfe_data,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_tlv_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_tlv_expr *in_tlv;
struct sctp_tlv_expr *out_tlv;
assert(in->type == EXPR_SCTP_TLV);
assert(in->value.sctp_tlv);
assert(out->type == EXPR_SCTP_TLV);
out->value.sctp_tlv = calloc(1, sizeof(struct sctp_tlv_expr));
in_tlv = in->value.sctp_tlv;
out_tlv = out->value.sctp_tlv;
if (evaluate(in_tlv->sn_type,
&out_tlv->sn_type,
error))
return STATUS_ERR;
if (evaluate(in_tlv->sn_flags,
&out_tlv->sn_flags,
error))
return STATUS_ERR;
if (evaluate(in_tlv->sn_length,
&out_tlv->sn_length,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_extrcvinfo_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_extrcvinfo_expr *in_info;
struct sctp_extrcvinfo_expr *out_info;
assert(in->type == EXPR_SCTP_EXTRCVINFO);
assert(in->value.sctp_extrcvinfo);
assert(out->type == EXPR_SCTP_EXTRCVINFO);
out->value.sctp_extrcvinfo = calloc(1, sizeof(struct sctp_extrcvinfo_expr));
in_info = in->value.sctp_extrcvinfo;
out_info = out->value.sctp_extrcvinfo;
if (evaluate(in_info->sinfo_stream,
&out_info->sinfo_stream,
error))
return STATUS_ERR;
if (evaluate(in_info->sinfo_ssn,
&out_info->sinfo_ssn,
error))
return STATUS_ERR;
if (evaluate(in_info->sinfo_flags,
&out_info->sinfo_flags,
error))
return STATUS_ERR;
if (evaluate(in_info->sinfo_ppid,
&out_info->sinfo_ppid,
error))
return STATUS_ERR;
if (evaluate(in_info->sinfo_context,
&out_info->sinfo_context,
error))
return STATUS_ERR;
if (evaluate(in_info->sinfo_pr_value,
&out_info->sinfo_pr_value,
error))
return STATUS_ERR;
if (evaluate(in_info->sinfo_tsn,
&out_info->sinfo_tsn,
error))
return STATUS_ERR;
if (evaluate(in_info->sinfo_cumtsn,
&out_info->sinfo_cumtsn,
error))
return STATUS_ERR;
if (evaluate(in_info->serinfo_next_flags,
&out_info->serinfo_next_flags,
error))
return STATUS_ERR;
if (evaluate(in_info->serinfo_next_stream,
&out_info->serinfo_next_stream,
error))
return STATUS_ERR;
if (evaluate(in_info->serinfo_next_aid,
&out_info->serinfo_next_aid,
error))
return STATUS_ERR;
if (evaluate(in_info->serinfo_next_length,
&out_info->serinfo_next_length,
error))
return STATUS_ERR;
if (evaluate(in_info->serinfo_next_ppid,
&out_info->serinfo_next_ppid,
error))
return STATUS_ERR;
if (evaluate(in_info->sinfo_assoc_id,
&out_info->sinfo_assoc_id,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate(struct expression *in,
struct expression **out_ptr, char **error)
{
int result = STATUS_OK;
struct expression *out = calloc(1, sizeof(struct expression));
*out_ptr = out;
out->type = in->type; /* most types of expression stay the same */
if ((in->type <= EXPR_NONE) ||
(in->type >= NUM_EXPR_TYPES)) {
asprintf(error, "bad expression type: %d", in->type);
return STATUS_ERR;
}
switch (in->type) {
case EXPR_NULL:
break;
case EXPR_ELLIPSIS:
break;
case EXPR_INTEGER: /* copy as-is */
out->value.num = in->value.num;
break;
case EXPR_LINGER: /* copy as-is */
memcpy(&out->value.linger, &in->value.linger,
sizeof(in->value.linger));
break;
case EXPR_SCTP_RTOINFO:
result = evaluate_sctp_rtoinfo_expression(in, out, error);
break;
case EXPR_SCTP_ASSOCPARAMS:
result = evaluate_sctp_accocparams_expression(in, out, error);
break;
case EXPR_SCTP_INITMSG:
result = evaluate_sctp_initmsg_expression(in, out, error);
break;
case EXPR_SCTP_ASSOC_VALUE:
result = evaluate_sctp_assoc_value_expression(in, out, error);
break;
case EXPR_SCTP_SACKINFO:
result = evaluate_sctp_sack_info_expression(in, out, error);
break;
case EXPR_SCTP_PADDRINFO:
result = evaluate_sctp_paddrinfo_expression(in, out, error);
break;
case EXPR_SCTP_STATUS:
result = evaluate_sctp_status_expression(in, out, error);
break;
case EXPR_SCTP_PEER_ADDR_PARAMS:
result = evaluate_sctp_peer_addr_param_expression(in, out, error);
break;
case EXPR_SCTP_STREAM_VALUE:
result = evaluate_sctp_stream_value_expression(in, out, error);
break;
case EXPR_SCTP_EVENT:
result = evaluate_sctp_event_expression(in, out, error);
break;
case EXPR_SCTP_EVENT_SUBSCRIBE:
result = evaluate_sctp_event_subscribe_expression(in, out, error);
break;
case EXPR_SCTP_SNDINFO:
result = evaluate_sctp_sndinfo_expression(in, out, error);
break;
case EXPR_SCTP_SETPRIM:
result = evaluate_sctp_setprim_expression(in, out, error);
break;
case EXPR_SCTP_SETADAPTATION:
result = evaluate_sctp_setadaptation_expression(in, out, error);
break;
case EXPR_SCTP_SNDRCVINFO:
result = evaluate_sctp_sndrcvinfo_expression(in, out, error);
break;
case EXPR_SCTP_PRINFO:
result = evaluate_sctp_prinfo_expression(in, out, error);
break;
case EXPR_SCTP_DEFAULT_PRINFO:
result = evaluate_sctp_default_prinfo_expression(in, out, error);
break;
case EXPR_SCTP_AUTHINFO:
result = evaluate_sctp_authinfo_expression(in, out, error);
break;
case EXPR_SCTP_SENDV_SPA:
result = evaluate_sctp_sendv_spa_expression(in, out, error);
break;
case EXPR_SCTP_RCVINFO:
result = evaluate_sctp_rcvinfo_expression(in, out, error);
break;
case EXPR_SCTP_NXTINFO:
result = evaluate_sctp_nxtinfo_expression(in, out, error);
break;
case EXPR_SCTP_RECVV_RN:
result = evaluate_sctp_recvv_rn_expression(in, out, error);
break;
case EXPR_SCTP_ASSOC_CHANGE:
result = evaluate_sctp_assoc_change_expression(in, out, error);
break;
case EXPR_SCTP_PADDR_CHANGE:
result = evaluate_sctp_paddr_change_expression(in, out, error);
break;
case EXPR_SCTP_REMOTE_ERROR:
result = evaluate_sctp_remote_error_expression(in, out, error);
break;
case EXPR_SCTP_SEND_FAILED:
result = evaluate_sctp_send_failed_expression(in, out, error);
break;
case EXPR_SCTP_SHUTDOWN_EVENT:
result = evaluate_sctp_shutdown_event_expression(in, out, error);
break;
case EXPR_SCTP_ADAPTATION_EVENT:
result = evaluate_sctp_adaptation_event_expression(in, out, error);
break;
case EXPR_SCTP_PDAPI_EVENT:
result = evaluate_sctp_pdapi_event_expression(in, out, error);
break;
case EXPR_SCTP_AUTHKEY_EVENT:
result = evaluate_sctp_authkey_event_expression(in, out, error);
break;
case EXPR_SCTP_SENDER_DRY_EVENT:
result = evaluate_sctp_sender_dry_event_expression(in, out, error);
break;
case EXPR_SCTP_SEND_FAILED_EVENT:
result = evaluate_sctp_send_failed_event_expression(in, out, error);
break;
case EXPR_SCTP_TLV:
result = evaluate_sctp_tlv_expression(in, out, error);
break;
case EXPR_SCTP_EXTRCVINFO:
result = evaluate_sctp_extrcvinfo_expression(in, out, error);
break;
case EXPR_WORD:
out->type = EXPR_INTEGER;
if (symbol_to_int(in->value.string,
&out->value.num, error))
return STATUS_ERR;
break;
case EXPR_STRING:
if (unescape_cstring_expression(in->value.string, out, error))
return STATUS_ERR;
break;
case EXPR_SOCKET_ADDRESS_IPV4: /* copy as-is */
out->value.socket_address_ipv4 =
malloc(sizeof(struct sockaddr_in));
memcpy(out->value.socket_address_ipv4,
in->value.socket_address_ipv4,
sizeof(*(out->value.socket_address_ipv4)));
break;
case EXPR_SOCKET_ADDRESS_IPV6: /* copy as-is */
out->value.socket_address_ipv6 =
malloc(sizeof(struct sockaddr_in6));
memcpy(out->value.socket_address_ipv6,
in->value.socket_address_ipv6,
sizeof(*(out->value.socket_address_ipv6)));
break;
case EXPR_BINARY:
result = evaluate_binary_expression(in, out, error);
break;
case EXPR_LIST:
result = evaluate_list_expression(in, out, error);
break;
case EXPR_IOVEC:
result = evaluate_iovec_expression(in, out, error);
break;
case EXPR_MSGHDR:
result = evaluate_msghdr_expression(in, out, error);
break;
case EXPR_CMSGHDR:
result = evaluate_cmsghdr_expression(in, out, error);
break;
case EXPR_POLLFD:
result = evaluate_pollfd_expression(in, out, error);
break;
case EXPR_NONE:
case NUM_EXPR_TYPES:
break;
/* missing default case so compiler catches missing cases */
}
return result;
}
/* Return a copy of the given expression list with each expression
* evaluated (e.g. symbols resolved to ints). On failure, return NULL
* and fill in *error.
*/
int evaluate_expression_list(struct expression_list *in_list,
struct expression_list **out_list,
char **error)
{
struct expression_list **node_ptr = out_list;
while (in_list != NULL) {
struct expression_list *node =
calloc(1, sizeof(struct expression_list));
*node_ptr = node;
if (evaluate(in_list->expression,
&node->expression, error)) {
free_expression_list(*out_list);
*out_list = NULL;
return STATUS_ERR;
}
node_ptr = &(node->next);
in_list = in_list->next;
}
return STATUS_OK;
}