diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index 63e848bfac7d7dead1c784f4b6e41dd734b96c91..668f5e436029149e072dd71ecc9ff9be0980bdd0 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -212,6 +212,8 @@ iov_len return IOV_LEN; [.][.][.] return ELLIPSIS; assoc_id return ASSOC_ID; assoc_value return ASSOC_VALUE; +shmac_number_of_idents return SHMAC_NUMBER_OF_IDENTS; +shmac_idents return SHMAC_IDENTS; stream_id return STREAM_ID; stream_value return STREAM_VALUE; scact_assoc_id return SCACT_ASSOC_ID; diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index 932fbf701206f9f93c481bf107dcb93fd2250c84..b3be7ede15920de46c5a0e1fe0beae2d4ac43633 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -506,7 +506,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %token <reserved> SRTO_ASSOC_ID SRTO_INITIAL SRTO_MAX SRTO_MIN %token <reserved> SINIT_NUM_OSTREAMS SINIT_MAX_INSTREAMS SINIT_MAX_ATTEMPTS %token <reserved> SINIT_MAX_INIT_TIMEO -%token <reserved> ASSOC_ID ASSOC_VALUE +%token <reserved> ASSOC_ID ASSOC_VALUE SHMAC_NUMBER_OF_IDENTS SHMAC_IDENTS %token <reserved> STREAM_ID STREAM_VALUE %token <reserved> SCACT_ASSOC_ID SCACT_KEYNUMBER SACK_ASSOC_ID SACK_DELAY SACK_FREQ %token <reserved> SSTAT_ASSOC_ID SSTAT_STATE SSTAT_RWND SSTAT_UNACKDATA SSTAT_PENDDATA @@ -606,7 +606,8 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %type <expression> sctp_status sstat_state sstat_rwnd sstat_unackdata sstat_penddata %type <expression> sstat_instrms sstat_outstrms sstat_fragmentation_point sstat_primary %type <expression> sctp_initmsg sinit_num_ostreams sinit_max_instreams sinit_max_attempts -%type <expression> sinit_max_init_timeo sctp_assoc_value sctp_stream_value +%type <expression> sinit_max_init_timeo sctp_assoc_value sctp_stream_value sctp_hmacalgo +%type <expression> shmac_number_of_idents %type <expression> sctp_authkeyid scact_keynumber sctp_sackinfo sack_delay sack_freq %type <expression> sctp_rtoinfo srto_initial srto_max srto_min sctp_paddrinfo %type <expression> sctp_paddrparams spp_address spp_hbinterval spp_pathmtu spp_pathmaxrxt @@ -2483,7 +2484,10 @@ expression | sctp_assoc_value { $$ = $1; } -| sctp_stream_value { +| sctp_hmacalgo { + $$ = $1; +} +| sctp_stream_value { $$ = $1; } | sctp_authkeyid { @@ -2914,6 +2918,25 @@ sctp_assoc_value $$->value.sctp_assoc_value->assoc_value = $4; } ; + +shmac_number_of_idents +: SHMAC_NUMBER_OF_IDENTS '=' INTEGER { + if (!is_valid_u32($3)) { + semantic_error("shmac_number_of_idents out of range"); + } + $$ = new_integer_expression($3, "%u"); +} +| SHMAC_NUMBER_OF_IDENTS '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +sctp_hmacalgo +: '{' shmac_number_of_idents ',' SHMAC_IDENTS '=' array '}' { + $$ = new_expression(EXPR_SCTP_HMACALGO); + $$->value.sctp_hmacalgo = calloc(1, sizeof(struct sctp_assoc_value_expr)); + $$->value.sctp_hmacalgo->shmac_number_of_idents = $2; + $$->value.sctp_hmacalgo->shmac_idents = $6; +} + scact_keynumber : SCACT_KEYNUMBER '=' INTEGER { if (!is_valid_u16($3)) { diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c index cc4e958914abed2a86b0306f98a152abab1e0f3f..330258a2d8b2093c7d4e8786a97084493f61d805 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -755,6 +755,48 @@ static int check_u8array_expr(struct expression *expr_list, u8 *data, size_t dat } #endif +#if defined(__FreeBSD__) || defined(linux) +static int check_u16array_expr(struct expression *expr_list, u16 *data, int data_len, char *val_name, char **error) { + if ( expr_list->type != EXPR_ELLIPSIS) { + struct expression *expr = NULL; + unsigned int i; + + switch(expr_list->type) { + case EXPR_LIST: + if (data_len != expression_list_length(expr_list->value.list)) { + asprintf(error, "%s length: expected: %u actual %zu", + val_name, expression_list_length(expr_list->value.list), data_len); + return STATUS_ERR; + } + for (i = 0; i < data_len; i++) { + expr = get_arg(expr_list->value.list, i, error); + if (expr->type != EXPR_ELLIPSIS) { + u16 script_val; + + if (get_u16(expr, &script_val, error)) { + return STATUS_ERR; + } + if (script_val != data[i]) { + asprintf(error, "%s[%d]: expected: %hu actual: %hu", + val_name, i, script_val, data[i]); + return STATUS_ERR; + } + } + } + break; + case EXPR_NULL: + if (data != NULL) + return STATUS_ERR; + break; + default: asprintf(error, "Bad expressiontype for %s", val_name); + return STATUS_ERR; + break; + } + } + return STATUS_OK; +} +#endif + /* Free all the space used by the given iovec. */ static void iovec_free(struct iovec *iov, size_t iov_len) { @@ -2923,6 +2965,23 @@ static int check_sctp_setadaptation(struct sctp_setadaptation_expr *expr, } #endif +static int check_sctp_hamcalgo(struct sctp_hmacalgo_expr *expr, + struct sctp_hmacalgo *sctp_hmacalgo, + char **error) { + if (check_u32_expr(expr->shmac_number_of_idents, sctp_hmacalgo->shmac_number_of_idents, + "sctp_hmacalgo.shmac_number_of_idents", error)) + return STATUS_ERR; + if (check_type(expr->shmac_idents, EXPR_LIST, error)) { + return STATUS_ERR; + } + if (check_u16array_expr(expr->shmac_idents, sctp_hmacalgo->shmac_idents, + sctp_hmacalgo->shmac_number_of_idents, + "sctp_hmacalgo.shmac_idents", error)) + return STATUS_ERR; + + return STATUS_OK; +} + static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall, struct expression_list *args, char **error) { @@ -3072,6 +3131,12 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall, } break; #endif +#ifdef SCTP_HMAC_IDENT + case EXPR_SCTP_HMACALGO: + live_optval = malloc(sizeof(struct sctp_hmacalgo)); + live_optlen = sizeof(struct sctp_hmacalgo); + break; +#endif #ifdef SCTP_SS_VALUE case EXPR_SCTP_STREAM_VALUE: live_optval = malloc(sizeof(struct sctp_stream_value)); @@ -3238,6 +3303,11 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall, result = check_sctp_assoc_value(val_expression->value.sctp_assoc_value, live_optval, error); break; #endif +#ifdef SCTP_HMAC_IDENT + case EXPR_SCTP_HMACALGO: + result = check_sctp_hamcalgo(val_expression->value.sctp_hmacalgo, live_optval, error); + break; +#endif #ifdef SCTP_SS_VALUE case EXPR_SCTP_STREAM_VALUE: result = check_sctp_stream_value(val_expression->value.sctp_stream_value, live_optval, error); @@ -3459,6 +3529,33 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall, optval = &assoc_value; break; #endif +#ifdef SCTP_HMAC_IDENT + case EXPR_SCTP_HMACALGO: { + int len, i; + struct sctp_hmacalgo *hmacalgo; + struct expression_list *list; + + if (check_type(val_expression->value.sctp_hmacalgo->shmac_idents, EXPR_LIST, error)) { + return STATUS_ERR; + } + list = val_expression->value.sctp_hmacalgo->shmac_idents->value.list; + len = expression_list_length(list); + hmacalgo = malloc(sizeof(u32) + (sizeof(u16) * len)); + + if (get_u32(val_expression->value.sctp_hmacalgo->shmac_number_of_idents, + &hmacalgo->shmac_number_of_idents, error)) { + free(hmacalgo); + return STATUS_ERR; + } + for (i = 0; i < len; i++) { + struct expression *expr; + expr = get_arg(list, i, error); + get_u16(expr, &(hmacalgo->shmac_idents[i]), error); + } + optval = &hmacalgo; + break; + } +#endif #ifdef SCTP_SS_VALUE case EXPR_SCTP_STREAM_VALUE: stream_value.assoc_id = 0; @@ -3740,6 +3837,9 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall, result = setsockopt(live_fd, level, optname, optval, optlen); return end_syscall(state, syscall, CHECK_EXACT, result, error); +#ifdef SCTP_HMAC_IDENT + free(optval); +#endif } static int syscall_poll(struct state *state, struct syscall_spec *syscall, diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c index 30a5d678588da0ffbbeadc1971047c90b1b1d2e6..4da1ea3abfb0c31690eada029203d0231a0eb359 100644 --- a/gtests/net/packetdrill/script.c +++ b/gtests/net/packetdrill/script.c @@ -70,6 +70,7 @@ struct expression_type_entry expression_type_table[] = { { EXPR_SCTP_RTOINFO, "sctp_rtoinfo"}, { EXPR_SCTP_INITMSG, "sctp_initmsg"}, { EXPR_SCTP_ASSOC_VALUE, "sctp_assoc_value"}, + { EXPR_SCTP_HMACALGO, "sctp_hmacalgo"}, { EXPR_SCTP_AUTHKEYID, "sctp_authkeyid"}, { EXPR_SCTP_SACKINFO, "sctp_sackinfo"}, { EXPR_SCTP_STATUS, "sctp_status"}, @@ -321,6 +322,11 @@ void free_expression(struct expression *expression) free_expression(expression->value.sctp_rtoinfo->srto_max); free_expression(expression->value.sctp_rtoinfo->srto_min); break; + case EXPR_SCTP_HMACALGO: + assert(expression->value.sctp_hmacalgo); + free_expression(expression->value.sctp_hmacalgo->shmac_number_of_idents); + free_expression(expression->value.sctp_hmacalgo->shmac_idents); + break; case EXPR_SCTP_ASSOC_VALUE: assert(expression->value.sctp_assoc_value); free_expression(expression->value.sctp_assoc_value->assoc_id); @@ -868,6 +874,34 @@ static int evaluate_sctp_initmsg_expression(struct expression *in, return STATUS_OK; } +static int evaluate_sctp_hmacalgo_expression(struct expression *in, + struct expression *out, + char **error) +{ + struct sctp_hmacalgo_expr *in_hmac; + struct sctp_hmacalgo_expr *out_hmac; + + assert(in->type == EXPR_SCTP_HMACALGO); + assert(in->value.sctp_hmacalgo); + assert(out->type == EXPR_SCTP_HMACALGO); + + out->value.sctp_hmacalgo = calloc(1, sizeof(struct sctp_hmacalgo_expr)); + + in_hmac = in->value.sctp_hmacalgo; + out_hmac = out->value.sctp_hmacalgo; + + if (evaluate(in_hmac->shmac_number_of_idents, + &out_hmac->shmac_number_of_idents, + error)) + return STATUS_ERR; + if (evaluate(in_hmac->shmac_idents, + &out_hmac->shmac_idents, + error)) + return STATUS_ERR; + + return STATUS_OK; +} + static int evaluate_sctp_assoc_value_expression(struct expression *in, struct expression *out, char **error) @@ -2244,6 +2278,9 @@ static int evaluate(struct expression *in, case EXPR_SCTP_ASSOCPARAMS: result = evaluate_sctp_accocparams_expression(in, out, error); break; + case EXPR_SCTP_HMACALGO: + result = evaluate_sctp_hmacalgo_expression(in, out, error); + break; case EXPR_SCTP_INITMSG: result = evaluate_sctp_initmsg_expression(in, out, error); break; diff --git a/gtests/net/packetdrill/script.h b/gtests/net/packetdrill/script.h index c38efbeb2b35b593138c0443b1727f7b0ed668d3..e4358679a23793358233efb108f6c954b188764d 100644 --- a/gtests/net/packetdrill/script.h +++ b/gtests/net/packetdrill/script.h @@ -50,6 +50,7 @@ enum expression_t { EXPR_SCTP_RTOINFO, /* struct sctp_rtoinfo for SCTP_RTOINFO */ EXPR_SCTP_INITMSG, /* struct sctp_initmsg for SCTP_INITMSG */ EXPR_SCTP_ASSOC_VALUE, /* struct sctp_assoc_value */ + EXPR_SCTP_HMACALGO, /* expression tree for sctp_hmacalgo struct for [gs]etsockopt */ EXPR_SCTP_AUTHKEYID, /* expression tree for sctp_authkeyid struct for [gs]etsockopt */ EXPR_SCTP_SACKINFO, /* struct sctp_sack_info_expr for */ EXPR_SCTP_STATUS, /* struct sctp_status for SCTP_STATUS */ @@ -104,6 +105,7 @@ struct expression { struct pollfd_expr *pollfd; struct sctp_rtoinfo_expr *sctp_rtoinfo; struct sctp_initmsg_expr *sctp_initmsg; + struct sctp_hmacalgo_expr *sctp_hmacalgo; struct sctp_assoc_value_expr *sctp_assoc_value; struct sctp_authkeyid_expr *sctp_authkeyid; struct sctp_sack_info_expr *sctp_sack_info; @@ -210,6 +212,12 @@ struct sctp_initmsg_expr { struct expression *sinit_max_init_timeo; }; +/* Parse tree for a sctp_hmacalgo struct in a [gs]etsockopt syscall. */ +struct sctp_hmacalgo_expr { + struct expression *shmac_number_of_idents; + struct expression *shmac_idents; +}; + /* Parse tree for a sctp_assoc_value struct in a [gs]etsockopt syscall. */ struct sctp_assoc_value_expr { struct expression *assoc_id; diff --git a/gtests/net/packetdrill/symbols_freebsd.c b/gtests/net/packetdrill/symbols_freebsd.c index a13803ce19e984e98ebeedd7aaea14aec9c02916..7cbc44b8022daf0629290436d3b71464fb7c6f6f 100644 --- a/gtests/net/packetdrill/symbols_freebsd.c +++ b/gtests/net/packetdrill/symbols_freebsd.c @@ -91,6 +91,7 @@ struct int_symbol platform_symbols_table[] = { { SCTP_DEFAULT_SEND_PARAM, "SCTP_DEFAULT_SEND_PARAM" }, { SCTP_I_WANT_MAPPED_V4_ADDR, "SCTP_I_WANT_MAPPED_V4_ADDR" }, { SCTP_MAXSEG, "SCTP_MAXSEG" }, + { SCTP_HMAC_IDENT, "SCTP_HMAC_IDENT" }, { SCTP_AUTH_ACTIVE_KEY, "SCTP_AUTH_ACTIVE_KEY" }, { SCTP_DELAYED_SACK, "SCTP_DELAYED_SACK" }, { SCTP_MAX_BURST, "SCTP_MAX_BURST" }, @@ -246,6 +247,8 @@ struct int_symbol platform_symbols_table[] = { { SCTP_DSTADDRV6, "SCTP_DSTADDRV6" }, { SCTP_EXTRCV, "SCTP_EXTRCV" }, { SCTP_USE_EXT_RCVINFO, "SCTP_USE_EXT_RCVINFO" }, + { SCTP_AUTH_HMAC_ID_SHA1, "SCTP_AUTH_HMAC_ID_SHA1" }, + { SCTP_AUTH_HMAC_ID_SHA256, "SCTP_AUTH_HMAC_ID_SHA256" }, /* /usr/include/netinet/tcp.h */ { TCP_NODELAY, "TCP_NODELAY" }, { TCP_MAXSEG, "TCP_MAXSEG" }, diff --git a/gtests/net/packetdrill/tests/bsd/sctp/api_tests/getsockopt/sctp_hmac_ident.pkt b/gtests/net/packetdrill/tests/bsd/sctp/api_tests/getsockopt/sctp_hmac_ident.pkt index 5b531a63db96162e7a32cbf6d65f2e30d633936d..2388a9c2ccc873ae78914deac891e092a7fbd1bf 100644 --- a/gtests/net/packetdrill/tests/bsd/sctp/api_tests/getsockopt/sctp_hmac_ident.pkt +++ b/gtests/net/packetdrill/tests/bsd/sctp/api_tests/getsockopt/sctp_hmac_ident.pkt @@ -10,7 +10,7 @@ +0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 -+0 setsockopt(3, IPPROTO_SCTP, SCTP_HMAC_IDENT, {shmac_number_of_idents=2, shmac_idents=[SCTP_AUTH_HMAC_ID_SHA1, SCTP_AUTH_HMAC_ID_SHA256]}, 8) = 0 +0 getsockopt(3, IPPROTO_SCTP, SCTP_HMAC_IDENT, {shmac_number_of_idents=2, shmac_idents=[SCTP_AUTH_HMAC_ID_SHA1, SCTP_AUTH_HMAC_ID_SHA256]}, [8]) = 0 ++0 setsockopt(3, IPPROTO_SCTP, SCTP_HMAC_IDENT, {shmac_number_of_idents=2, shmac_idents=[SCTP_AUTH_HMAC_ID_SHA1, SCTP_AUTH_HMAC_ID_SHA256]}, 8) = 0 +0 close(3) = 0