From d4d6c1f6395c1f5345561a8e7d0bf0179c16c160 Mon Sep 17 00:00:00 2001 From: hoelscher <jens.hoelscher@fh-muenster.de> Date: Fri, 27 Nov 2015 22:47:08 +0100 Subject: [PATCH] add support for sctp_get_assoc_id_lists for [gs]etsockopt, shoult end in an error but didn't do taht for one-to-one socket --- gtests/net/packetdrill/lexer.l | 2 + gtests/net/packetdrill/parser.y | 24 ++++++++- gtests/net/packetdrill/run_system_call.c | 53 +++++++++++++++++++ gtests/net/packetdrill/script.c | 35 ++++++++++++ gtests/net/packetdrill/script.h | 8 +++ gtests/net/packetdrill/symbols_freebsd.c | 1 + .../getsockopt/sctp_get_assoc_id_list.pkt | 2 +- 7 files changed, 123 insertions(+), 2 deletions(-) diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index 668f5e43..b8aaa23f 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -382,6 +382,8 @@ sai_assoc_id return SAI_ASSOC_ID; sn_type return SN_TYPE; sn_length return SN_LENGTH; sn_flags return SN_FLAGS; +gaids_number_of_ids return GAIDS_NUMBER_OF_IDS; +gaids_assoc_id return GAIDS_ASSOC_ID; CHUNK return CHUNK; DATA return DATA; INIT return INIT; diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index b3be7ede..1e15b1b8 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -564,6 +564,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %token <reserved> SPC_TYPE SPC_FLAGS SPC_LENGTH SPC_AADDR SPC_STATE SPC_ERROR SPC_ASSOC_ID %token <reserved> SSF_TYPE SSF_LENGTH SSF_FLAGS SSF_ERROR SSF_INFO SSF_ASSOC_ID SSF_DATA %token <reserved> SAI_TYPE SAI_FLAGS SAI_LENGTH SAI_ADAPTATION_IND SAI_ASSOC_ID +%token <reserved> GAIDS_NUMBER_OF_IDS GAIDS_ASSOC_ID %token <reserved> SN_TYPE SN_FLAGS SN_LENGTH %token <floating> FLOAT %token <integer> INTEGER HEX_INTEGER @@ -635,7 +636,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %type <expression> sctp_paddr_change spc_type spc_flags spc_length spc_aaddr spc_error spc_state %type <expression> sctp_send_failed ssf_type ssf_length ssf_flags ssf_error ssf_info ssf_data %type <expression> sctp_adaptation_event sai_type sai_flags sai_length sai_adaptation_ind -%type <expression> sctp_tlv sn_type sn_flags sn_length +%type <expression> sctp_tlv sn_type sn_flags sn_length sctp_assoc_ids gaids_number_of_ids %type <errno_info> opt_errno %type <chunk_list> sctp_chunk_list_spec %type <chunk_list_item> sctp_chunk_spec @@ -2547,6 +2548,9 @@ expression | sctp_recvv_rn { $$ = $1; } +| sctp_assoc_ids { + $$ = $1; +} | null { $$ = $1; } @@ -4763,6 +4767,24 @@ sctp_tlv } ; +gaids_number_of_ids +: GAIDS_NUMBER_OF_IDS '=' INTEGER { + if (!is_valid_u32($3)) { + semantic_error("gaids_number_of_ids out of range"); + } + $$ = new_integer_expression($3, "%u"); +} +| GAIDS_NUMBER_OF_IDS '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +sctp_assoc_ids +: '{' gaids_number_of_ids ',' GAIDS_ASSOC_ID '=' array '}' { + $$ = new_expression(EXPR_SCTP_ASSOC_IDS); + $$->value.sctp_assoc_ids = calloc(1, sizeof(struct sctp_assoc_ids_expr)); + $$->value.sctp_assoc_ids->gaids_number_of_ids = $2; + $$->value.sctp_assoc_ids->gaids_assoc_id = $6; +}; + opt_errno : { $$ = NULL; } | WORD note { diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c index 330258a2..c1d65ded 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -2982,6 +2982,45 @@ static int check_sctp_hamcalgo(struct sctp_hmacalgo_expr *expr, return STATUS_OK; } +static int check_sctp_assoc_ids(struct sctp_assoc_ids_expr *expr, + struct sctp_assoc_ids *sctp_assoc_ids, + char **error) { + int list_len = 0, i = 0; + struct expression *assoc_id; + struct expression_list *ids; + + if (check_u32_expr(expr->gaids_number_of_ids, sctp_assoc_ids->gaids_number_of_ids, + "sctp_assoc_ids.gaids_number_of_ids", error)) { + return STATUS_ERR; + } + ids = expr->gaids_assoc_id->value.list; + list_len = expression_list_length(ids); + if (list_len != sctp_assoc_ids->gaids_number_of_ids) { + asprintf(error, "live gaids_number_if_ids unequal to length if expected gaids_assoc_id. actual %u, expected %d", + sctp_assoc_ids->gaids_number_of_ids, list_len); + return STATUS_ERR; + } + if (list_len == 1) { + assoc_id = get_arg(ids, 0, error); + if (assoc_id->type == EXPR_ELLIPSIS) { + return STATUS_OK; + } + } + for (i = 0; i < list_len; i++) { + assoc_id = get_arg(ids, i, error); + sctp_assoc_t script_id; + if (get_sctp_assoc_t(assoc_id, &script_id, error)) { + return STATUS_ERR; + } + if (script_id != sctp_assoc_ids->gaids_assoc_id[i]) { + asprintf(error, "sctp_assoc_ids.gaids_assoc_id[%d]. expected %u, actual %u", + i, script_id, sctp_assoc_ids->gaids_assoc_id[i]); + return STATUS_ERR; + } + } + return STATUS_OK; +} + static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall, struct expression_list *args, char **error) { @@ -3226,6 +3265,14 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall, live_optval = malloc(sizeof(struct sctp_setadaptation)); live_optlen = sizeof(struct sctp_setadaptation); break; +#endif +#ifdef SCTP_GET_ASSOC_ID_LIST + case EXPR_SCTP_ASSOC_IDS: { + s32 len = expression_list_length(val_expression->value.sctp_assoc_ids->gaids_assoc_id->value.list); + live_optval = malloc(sizeof(u32) + (sizeof(sctp_assoc_t) * len)); + live_optlen = sizeof(u32) + (sizeof(sctp_assoc_t) * len); + break; + } #endif case EXPR_LIST: s32_bracketed_arg(args, 3, &script_optval, error); @@ -3347,6 +3394,12 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall, case EXPR_SCTP_SETADAPTATION: result = check_sctp_setadaptation(val_expression->value.sctp_setadaptation, live_optval, error); break; +#endif +#ifdef SCTP_GET_ASSOC_ID_LIST + case EXPR_SCTP_ASSOC_IDS: { + result = check_sctp_assoc_ids(val_expression->value.sctp_assoc_ids, live_optval, error); + break; + } #endif case EXPR_LIST: if (*(int*)live_optval != script_optval) { diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c index 4da1ea3a..dc0cd46e 100644 --- a/gtests/net/packetdrill/script.c +++ b/gtests/net/packetdrill/script.c @@ -103,6 +103,7 @@ struct expression_type_entry expression_type_table[] = { { EXPR_SCTP_SEND_FAILED_EVENT,"sctp_send_failed_event"}, { EXPR_SCTP_TLV, "sctp_tlv" }, { EXPR_SCTP_EXTRCVINFO, "sctp_extrcvinfo" }, + { EXPR_SCTP_ASSOC_IDS, "sctp_assoc_ids" }, { NUM_EXPR_TYPES, NULL} }; @@ -580,6 +581,10 @@ void free_expression(struct expression *expression) free_expression(expression->value.sctp_extrcvinfo->serinfo_next_ppid); free_expression(expression->value.sctp_extrcvinfo->sinfo_assoc_id); break; + case EXPR_SCTP_ASSOC_IDS: + free_expression(expression->value.sctp_assoc_ids->gaids_number_of_ids); + free_expression(expression->value.sctp_assoc_ids->gaids_assoc_id); + break; case EXPR_WORD: assert(expression->value.string); free(expression->value.string); @@ -2247,6 +2252,33 @@ static int evaluate_sctp_extrcvinfo_expression(struct expression *in, return STATUS_OK; } +static int evaluate_sctp_assoc_ids_expression(struct expression *in, + struct expression *out, + char **error) +{ + struct sctp_assoc_ids_expr *in_ids; + struct sctp_assoc_ids_expr *out_ids; + + assert(in->type == EXPR_SCTP_ASSOC_IDS); + assert(in->value.sctp_assoc_ids); + assert(out->type == EXPR_SCTP_ASSOC_IDS); + + out->value.sctp_assoc_ids = calloc(1, sizeof(struct sctp_assoc_ids_expr)); + + in_ids = in->value.sctp_assoc_ids; + out_ids = out->value.sctp_assoc_ids; + + if (evaluate(in_ids->gaids_number_of_ids, + &out_ids->gaids_number_of_ids, + error)) + return STATUS_ERR; + if (evaluate(in_ids->gaids_assoc_id, + &out_ids->gaids_assoc_id, + error)) + return STATUS_ERR; + return STATUS_OK; +} + static int evaluate(struct expression *in, struct expression **out_ptr, char **error) { @@ -2380,6 +2412,9 @@ static int evaluate(struct expression *in, case EXPR_SCTP_EXTRCVINFO: result = evaluate_sctp_extrcvinfo_expression(in, out, error); break; + case EXPR_SCTP_ASSOC_IDS: + result = evaluate_sctp_assoc_ids_expression(in, out, error); + break; case EXPR_WORD: out->type = EXPR_INTEGER; if (symbol_to_int(in->value.string, diff --git a/gtests/net/packetdrill/script.h b/gtests/net/packetdrill/script.h index e4358679..56388a4b 100644 --- a/gtests/net/packetdrill/script.h +++ b/gtests/net/packetdrill/script.h @@ -83,6 +83,7 @@ enum expression_t { EXPR_SCTP_SEND_FAILED_EVENT, /* expression tree for sctp_send_failed_event */ EXPR_SCTP_TLV, /* expression tree for sctp_notifications_stopped_event */ EXPR_SCTP_EXTRCVINFO, /* expression tree for sctp_extrcvinfo struct in cmsghdr */ + EXPR_SCTP_ASSOC_IDS, /* expression tree for sctp_assoc_ids struct for [gs]etsockopt */ NUM_EXPR_TYPES, }; /* Convert an expression type to a human-readable string */ @@ -139,6 +140,7 @@ struct expression { struct sctp_send_failed_event_expr *sctp_send_failed_event; struct sctp_tlv_expr *sctp_tlv; struct sctp_extrcvinfo_expr *sctp_extrcvinfo; + struct sctp_assoc_ids_expr *sctp_assoc_ids; } value; const char *format; /* the printf format for printing the value */ }; @@ -523,6 +525,12 @@ struct sctp_extrcvinfo_expr { struct expression *sinfo_assoc_id; }; +/* Parse tree for sctp_extrcvinfo struct for cmsg. */ +struct sctp_assoc_ids_expr { + struct expression *gaids_number_of_ids; + struct expression *gaids_assoc_id; +}; + /* The errno-related info from strace to summarize a system call error */ struct errno_spec { const char *errno_macro; /* errno symbol (C macro name) */ diff --git a/gtests/net/packetdrill/symbols_freebsd.c b/gtests/net/packetdrill/symbols_freebsd.c index 83f436d6..15707ec6 100644 --- a/gtests/net/packetdrill/symbols_freebsd.c +++ b/gtests/net/packetdrill/symbols_freebsd.c @@ -108,6 +108,7 @@ struct int_symbol platform_symbols_table[] = { { SCTP_STATUS, "SCTP_STATUS" }, { SCTP_GET_PEER_ADDR_INFO, "SCTP_GET_PEER_ADDR_INFO" }, { SCTP_GET_ASSOC_NUMBER, "SCTP_GET_ASSOC_NUMBER" }, + { SCTP_GET_ASSOC_ID_LIST, "SCTP_GET_ASSOC_ID_LIST" }, { SCTP_FRAGMENT_INTERLEAVE, "SCTP_FRAGMENT_INTERLEAVE" }, #if defined(SCTP_INTERLEAVING_SUPPORTED) { SCTP_INTERLEAVING_SUPPORTED, "SCTP_INTERLEAVING_SUPPORTED" }, diff --git a/gtests/net/packetdrill/tests/bsd/sctp/api_tests/getsockopt/sctp_get_assoc_id_list.pkt b/gtests/net/packetdrill/tests/bsd/sctp/api_tests/getsockopt/sctp_get_assoc_id_list.pkt index 8d6b9cd8..e09f741f 100644 --- a/gtests/net/packetdrill/tests/bsd/sctp/api_tests/getsockopt/sctp_get_assoc_id_list.pkt +++ b/gtests/net/packetdrill/tests/bsd/sctp/api_tests/getsockopt/sctp_get_assoc_id_list.pkt @@ -10,6 +10,6 @@ +0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 -+0 getsockopt(3, IPPROTO_SCTP, SCTP_GET_ASSOC_ID_LIST, {gaids_number_of_ids=0, gaids_assoc_id=[...]}, [0]) = -1 ++0 getsockopt(3, IPPROTO_SCTP, SCTP_GET_ASSOC_ID_LIST, {gaids_number_of_ids=1, gaids_assoc_id=[3]}, [8]) = -1 +0 close(3) = 0 -- GitLab