From 8e39ad2daa47eb378a4907abc5e3079453bf2a22 Mon Sep 17 00:00:00 2001 From: hoelscher <jens.hoelscher@fh-muenster.de> Date: Sat, 28 Nov 2015 01:11:13 +0100 Subject: [PATCH] add support for socketoption SCTP_SET_PEER_PRIMARY_ADDR, test does not work --- gtests/net/packetdrill/lexer.l | 2 ++ gtests/net/packetdrill/parser.y | 20 ++++++++++- gtests/net/packetdrill/run_system_call.c | 18 +++++++++- gtests/net/packetdrill/script.c | 35 +++++++++++++++++++ gtests/net/packetdrill/script.h | 8 +++++ gtests/net/packetdrill/symbols_freebsd.c | 1 + .../getsockopt/sctp_set_peer_primary_addr.pkt | 9 +++-- 7 files changed, 89 insertions(+), 4 deletions(-) diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index 9f07914d..5ab6e90f 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -387,6 +387,8 @@ gaids_assoc_id return GAIDS_ASSOC_ID; gauth_assoc_id return GAUTH_ASSOC_ID; gauth_number_of_chunks return GAUTH_NUMBER_OF_CHUNKS; gauth_chunks return GAUTH_CHUNKS; +sspp_assoc_id return SSPP_ASSOC_ID; +sspp_addr return SSPP_ADDR; CHUNK return CHUNK; DATA return DATA; INIT return INIT; diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index 6a6f2deb..c4fc0704 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -564,7 +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> GAIDS_NUMBER_OF_IDS GAIDS_ASSOC_ID SSPP_ASSOC_ID SSPP_ADDR %token <reserved> SN_TYPE SN_FLAGS SN_LENGTH %token <floating> FLOAT %token <integer> INTEGER HEX_INTEGER @@ -638,6 +638,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %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 sctp_assoc_ids gaids_number_of_ids +%type <expression> sctp_setpeerprim %type <errno_info> opt_errno %type <chunk_list> sctp_chunk_list_spec %type <chunk_list_item> sctp_chunk_spec @@ -2555,6 +2556,9 @@ expression | sctp_authchunks { $$ = $1; } +| sctp_setpeerprim { + $$ = $1; +} | null { $$ = $1; } @@ -4815,6 +4819,20 @@ sctp_authchunks $$->value.sctp_authchunks->gauth_chunks = $6; }; +sctp_setpeerprim +: '{' SSPP_ASSOC_ID '=' sctp_assoc_id ',' SSPP_ADDR '=' sockaddr '}' { + $$ = new_expression(EXPR_SCTP_SETPEERPRIM); + $$->value.sctp_setpeerprim = calloc(1, sizeof(struct sctp_setpeerprim_expr)); + $$->value.sctp_setpeerprim->sspp_assoc_id = $4; + $$->value.sctp_setpeerprim->sspp_addr = $8; +} +| '{' SSPP_ADDR '=' sockaddr '}' { + $$ = new_expression(EXPR_SCTP_SETPEERPRIM); + $$->value.sctp_setpeerprim = calloc(1, sizeof(struct sctp_setpeerprim_expr)); + $$->value.sctp_setpeerprim->sspp_assoc_id = new_expression(EXPR_ELLIPSIS); + $$->value.sctp_setpeerprim->sspp_addr = $4; +}; + opt_errno : { $$ = NULL; } | WORD note { diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c index 780c4155..954b0c5b 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -495,7 +495,7 @@ static int ellipsis_arg(struct expression_list *args, int index, char **error) return STATUS_OK; } -#if defined(SCTP_GET_PEER_ADDR_INFO) || defined(SCTP_PEER_ADDR_PARAMS) +#if defined(SCTP_GET_PEER_ADDR_INFO) || defined(SCTP_PEER_ADDR_PARAMS) || defined(SCTP_SET_PEER_PRIMARY_ADDR) /* Return STATUS_OK if the argument in from type sockaddr_in or * sockaddr_in6 */ @@ -3513,6 +3513,9 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall, #ifdef SCTP_ADAPTATION_LAYER struct sctp_setadaptation setadaptation; #endif +#ifdef SCTP_SET_PEER_PRIMARY_ADDR + struct sctp_setpeerprim setpeerprim; +#endif #ifdef SCTP_PEER_ADDR_PARAMS struct sctp_paddrparams paddrparams; #ifdef linux @@ -3863,6 +3866,19 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall, optval = &setadaptation; break; #endif +#ifdef SCTP_SET_PEER_PRIMARY_ADDR + case EXPR_SCTP_SETPEERPRIM: + if (get_sctp_assoc_t(val_expression->value.sctp_setpeerprim->sspp_assoc_id, + &setpeerprim.sspp_assoc_id, error)) { + return STATUS_ERR; + } + if (get_sockstorage_arg(val_expression->value.sctp_setpeerprim->sspp_addr, + &setpeerprim.sspp_addr, live_fd)) { + return STATUS_ERR; + } + optval = &setpeerprim; + break; +#endif #ifdef SCTP_PEER_ADDR_PARAMS case EXPR_SCTP_PEER_ADDR_PARAMS: if (get_sctp_assoc_t(val_expression->value.sctp_paddrparams->spp_assoc_id, diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c index 41744e15..ee105cb9 100644 --- a/gtests/net/packetdrill/script.c +++ b/gtests/net/packetdrill/script.c @@ -105,6 +105,7 @@ struct expression_type_entry expression_type_table[] = { { EXPR_SCTP_EXTRCVINFO, "sctp_extrcvinfo" }, { EXPR_SCTP_ASSOC_IDS, "sctp_assoc_ids" }, { EXPR_SCTP_AUTHCHUNKS, "sctp_authchunks" }, + { EXPR_SCTP_SETPEERPRIM, "sctp_setpeerprim"}, { NUM_EXPR_TYPES, NULL} }; @@ -591,6 +592,10 @@ void free_expression(struct expression *expression) free_expression(expression->value.sctp_authchunks->gauth_number_of_chunks); free_expression(expression->value.sctp_authchunks->gauth_chunks); break; + case EXPR_SCTP_SETPEERPRIM: + free_expression(expression->value.sctp_setpeerprim->sspp_assoc_id); + free_expression(expression->value.sctp_setpeerprim->sspp_addr); + break; case EXPR_WORD: assert(expression->value.string); free(expression->value.string); @@ -2316,6 +2321,33 @@ static int evaluate_sctp_authchunks_expression(struct expression *in, return STATUS_OK; } +static int evaluate_sctp_setpeerprim_expression(struct expression *in, + struct expression *out, + char **error) +{ + struct sctp_setpeerprim_expr *in_sspp; + struct sctp_setpeerprim_expr *out_sspp; + + assert(in->type == EXPR_SCTP_SETPEERPRIM); + assert(in->value.sctp_setpeerprim); + assert(out->type == EXPR_SCTP_SETPEERPRIM); + + out->value.sctp_setpeerprim = calloc(1, sizeof(struct sctp_setpeerprim_expr)); + + in_sspp = in->value.sctp_setpeerprim; + out_sspp = out->value.sctp_setpeerprim; + + if (evaluate(in_sspp->sspp_assoc_id, + &out_sspp->sspp_assoc_id, + error)) + return STATUS_ERR; + if (evaluate(in_sspp->sspp_addr, + &out_sspp->sspp_addr, + error)) + return STATUS_ERR; + return STATUS_OK; +} + static int evaluate(struct expression *in, struct expression **out_ptr, char **error) { @@ -2455,6 +2487,9 @@ static int evaluate(struct expression *in, case EXPR_SCTP_AUTHCHUNKS: result = evaluate_sctp_authchunks_expression(in, out, error); break; + case EXPR_SCTP_SETPEERPRIM: + result = evaluate_sctp_setpeerprim_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 1913bef6..36a70bfd 100644 --- a/gtests/net/packetdrill/script.h +++ b/gtests/net/packetdrill/script.h @@ -85,6 +85,7 @@ enum expression_t { 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 */ EXPR_SCTP_AUTHCHUNKS, /* expression tree for sctp_authchunks struct for [gs]etsockopt */ + EXPR_SCTP_SETPEERPRIM, /* expression tree for sctp_setpeerprim struct for [gs]etsockopt */ NUM_EXPR_TYPES, }; /* Convert an expression type to a human-readable string */ @@ -143,6 +144,7 @@ struct expression { struct sctp_extrcvinfo_expr *sctp_extrcvinfo; struct sctp_assoc_ids_expr *sctp_assoc_ids; struct sctp_authchunks_expr *sctp_authchunks; + struct sctp_setpeerprim_expr *sctp_setpeerprim; } value; const char *format; /* the printf format for printing the value */ }; @@ -540,6 +542,12 @@ struct sctp_authchunks_expr { struct expression *gauth_chunks; }; +/* Parse tree for sctp_setpeerprim struct for [gs]etsockopt. */ +struct sctp_setpeerprim_expr { + struct expression *sspp_assoc_id; + struct expression *sspp_addr; +}; + /* 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 de6b5e95..367564b2 100644 --- a/gtests/net/packetdrill/symbols_freebsd.c +++ b/gtests/net/packetdrill/symbols_freebsd.c @@ -111,6 +111,7 @@ struct int_symbol platform_symbols_table[] = { { SCTP_LOCAL_AUTH_CHUNKS, "SCTP_LOCAL_AUTH_CHUNKS" }, { SCTP_GET_ASSOC_NUMBER, "SCTP_GET_ASSOC_NUMBER" }, { SCTP_GET_ASSOC_ID_LIST, "SCTP_GET_ASSOC_ID_LIST" }, + { SCTP_SET_PEER_PRIMARY_ADDR, "SCTP_SET_PEER_PRIMARY_ADDR" }, { SCTP_AUTH_CHUNK, "SCTP_AUTH_CHUNK" }, { SCTP_AUTH_KEY, "SCTP_AUTH_KEY" }, { SCTP_AUTH_DEACTIVATE_KEY, "SCTP_AUTH_DEACTIVATE_KEY" }, diff --git a/gtests/net/packetdrill/tests/bsd/sctp/api_tests/getsockopt/sctp_set_peer_primary_addr.pkt b/gtests/net/packetdrill/tests/bsd/sctp/api_tests/getsockopt/sctp_set_peer_primary_addr.pkt index 71340f99..4a3e7b88 100644 --- a/gtests/net/packetdrill/tests/bsd/sctp/api_tests/getsockopt/sctp_set_peer_primary_addr.pkt +++ b/gtests/net/packetdrill/tests/bsd/sctp/api_tests/getsockopt/sctp_set_peer_primary_addr.pkt @@ -10,7 +10,12 @@ +0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 -+0 setsockopt(3, IPPROTO_SCTP, SCTP_SET_PEER_PRIMARY_ADDR, {sspp_assoc_id=..., sspp={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},}, 20) = 0 -+0 setsockopt(3, IPPROTO_SCTP, SCTP_SET_PEER_PRIMARY_ADDR, {sspp={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")},}, 20) = 0 ++0 setsockopt(3, IPPROTO_SCTP, SCTP_SET_PEER_PRIMARY_ADDR, {sspp_addr={sa_family=AF_INET, + sin_port=htons(8080), + sin_addr=inet_addr("192.0.2.1")}}, 136) = 0 ++0 setsockopt(3, IPPROTO_SCTP, SCTP_SET_PEER_PRIMARY_ADDR, {sspp_assoc_id=..., + sspp_addr={sa_family=AF_INET, + sin_port=htons(8080), + sin_addr=inet_addr("192.0.2.1")}}, 136) = 0 +0 close(3) = 0 -- GitLab