/* * 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; }