diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index 53e33af76bc44dcabe30c85ededd067c10791fc5..4980fdd81f2f576bbcdf50bc91dda24874571639 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -242,6 +242,10 @@ spp_ipv6_flowlabel return SPP_IPV6_FLOWLABEL_; /* avoid name clash */ spp_dscp return SPP_DSCP_; /* avoid name clash */ se_type return SE_TYPE; se_on return SE_ON; +snd_sid return SND_SID; +snd_flags return SND_FLAGS; +snd_ppid return SND_PPID; +snd_context return SND_CONTEXT; ssb_adaptation_ind return SSB_ADAPTATION_IND; CHUNK return CHUNK; DATA return DATA; diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index aec7dea7374d0a0586e8be10ebacf87e0223feb4..50a02d6ba38722b0644901d0d489f828dd477de1 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -536,7 +536,8 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %token <reserved> SPP_ADDRESS SPP_HBINTERVAL SPP_PATHMAXRXT SPP_PATHMTU %token <reserved> SPP_FLAGS SPP_IPV6_FLOWLABEL_ SPP_DSCP_ %token <reserved> SASOC_ASOCMAXRXT SASOC_NUMBER_PEER_DESTINATIONS SASOC_PEER_RWND -%token <reserved> SASOC_LOCAL_RWND SASOC_COOKIE_LIFE SE_TYPE SE_ON SSB_ADAPTATION_IND +%token <reserved> SASOC_LOCAL_RWND SASOC_COOKIE_LIFE SE_TYPE SE_ON +%token <reserved> SND_SID SND_FLAGS SND_PPID SND_CONTEXT SSB_ADAPTATION_IND %token <floating> FLOAT %token <integer> INTEGER HEX_INTEGER %token <string> WORD STRING BACK_QUOTED CODE IPV4_ADDR IPV6_ADDR @@ -585,6 +586,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %type <expression> spinfo_address spinfo_state spinfo_cwnd spinfo_srtt spinfo_rto spinfo_mtu %type <expression> sasoc_asocmaxrxt sasoc_number_peer_destinations sasoc_peer_rwnd %type <expression> sasoc_local_rwnd sasoc_cookie_life sctp_assocparams +%type <expression> sctp_sndinfo snd_sid snd_flags snd_ppid snd_context %type <expression> sctp_event se_type se_on sctp_setadaptation %type <errno_info> opt_errno %type <chunk_list> sctp_chunk_list_spec @@ -2374,6 +2376,9 @@ expression | sctp_event { $$ = $1; } +| sctp_sndinfo { + $$ = $1; +} | sctp_setadaptation{ $$ = $1; } @@ -2992,6 +2997,64 @@ sctp_event } ; +snd_sid +: SND_SID '=' INTEGER { + if (!is_valid_u16($3)) { + semantic_error("snd_sid out of range"); + } + $$ = new_integer_expression($3, "%hu"); +} +| SND_SID '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +snd_flags +: SND_FLAGS '=' INTEGER { + if (!is_valid_u16($3)) { + semantic_error("snd_flags out of range"); + } + $$ = new_integer_expression($3, "%hu"); +} +| SND_FLAGS '=' WORD { + $$ = new_expression(EXPR_WORD); + $$->value.string = $3; +} +| SND_FLAGS '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +snd_ppid +: SND_PPID '=' INTEGER { + if (!is_valid_u32($3)) { + semantic_error("snd_ppid out of range"); + } + $$ = new_integer_expression($3, "%u"); +} +| SND_PPID '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +snd_context +: SND_CONTEXT '=' INTEGER { + if (!is_valid_u32($3)) { + semantic_error("snd_context out of range"); + } + $$ = new_integer_expression($3, "%u"); +} +| SND_CONTEXT '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +sctp_sndinfo +: '{' snd_sid ',' snd_flags ',' snd_ppid ',' snd_context '}' { +#ifdef SCTP_DEFAULT_SNDINFO + $$ = new_expression(EXPR_SCTP_SNDINFO); + $$->value.sctp_sndinfo = calloc(1, sizeof(struct sctp_sndinfo)); + $$->value.sctp_sndinfo->snd_sid = $2; + $$->value.sctp_sndinfo->snd_flags = $4; + $$->value.sctp_sndinfo->snd_ppid = $6; + $$->value.sctp_sndinfo->snd_context = $8; +#else + $$ = NULL; +#endif +} + sctp_setadaptation : '{' SSB_ADAPTATION_IND '=' INTEGER '}' { $$ = new_expression(EXPR_SCTP_SETADAPTATION); diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c index 175e125bb444117f81a5adcda2891b476375e30d..558e77e84337e5d00fa8f56ff5a0670ad41187b8 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -2280,6 +2280,63 @@ static int check_sctp_event(struct sctp_event_expr *expr, } #endif +#ifdef SCTP_DEFAULT_SNDINFO +static int check_sctp_sndinfo(struct sctp_sndinfo_expr *expr, + struct sctp_sndinfo *sctp_sndinfo, + char **error) +{ + if (expr->snd_sid->type != EXPR_ELLIPSIS) { + u16 snd_sid; + + if (get_u16(expr->snd_sid, &snd_sid, error)) { + return STATUS_ERR; + } + if (sctp_sndinfo->snd_sid != snd_sid) { + asprintf(error, "Bad getsockopt sctp_sndinfo.snd_sid: expected: %hu actual: %hu", + snd_sid, sctp_sndinfo->snd_sid); + return STATUS_ERR; + } + } + if (expr->snd_flags->type != EXPR_ELLIPSIS) { + u16 snd_flags; + + if (get_u16(expr->snd_flags, &snd_flags, error)) { + return STATUS_ERR; + } + if (sctp_sndinfo->snd_flags != snd_flags) { + asprintf(error, "Bad getsockopt sctp_sndinfo.snd_flags: expected: %hu actual: %hu", + snd_flags, sctp_sndinfo->snd_flags); + return STATUS_ERR; + } + } + if (expr->snd_ppid->type != EXPR_ELLIPSIS) { + u32 snd_ppid; + + if (get_u32(expr->snd_ppid, &snd_ppid, error)) { + return STATUS_ERR; + } + if (sctp_sndinfo->snd_ppid != snd_ppid) { + asprintf(error, "Bad getsockopt sctp_sndinfo.snd_ppid: expected: %u actual: %u", + snd_ppid, sctp_sndinfo->snd_ppid); + return STATUS_ERR; + } + } + if (expr->snd_context->type != EXPR_ELLIPSIS) { + u32 snd_context; + + if (get_u32(expr->snd_context, &snd_context, error)) { + return STATUS_ERR; + } + if (sctp_sndinfo->snd_context != snd_context) { + asprintf(error, "Bad getsockopt sctp_sndinfo.snd_context: expected: %u actual: %u", + snd_context, sctp_sndinfo->snd_context); + return STATUS_ERR; + } + } + return STATUS_OK; +} +#endif + #ifdef SCTP_ADAPTATION_LAYER static int check_sctp_setadaptation(struct sctp_setadaptation_expr *expr, struct sctp_setadaptation *sctp_setadaptation, @@ -2329,125 +2386,132 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall, return STATUS_ERR; } switch (val_expression->type) { - case EXPR_LINGER: - live_optval = malloc(sizeof(struct linger)); - live_optlen = (socklen_t)sizeof(struct linger); - break; + case EXPR_LINGER: + live_optval = malloc(sizeof(struct linger)); + live_optlen = (socklen_t)sizeof(struct linger); + break; #ifdef SCTP_RTOINFO - case EXPR_SCTP_RTOINFO: - live_optval = malloc(sizeof(struct sctp_rtoinfo)); - live_optlen = (socklen_t)sizeof(struct sctp_rtoinfo); - ((struct sctp_rtoinfo*)live_optval)->srto_assoc_id = 0; - break; + case EXPR_SCTP_RTOINFO: + live_optval = malloc(sizeof(struct sctp_rtoinfo)); + live_optlen = (socklen_t)sizeof(struct sctp_rtoinfo); + ((struct sctp_rtoinfo*)live_optval)->srto_assoc_id = 0; + break; #endif #ifdef SCTP_ASSOCINFO - case EXPR_SCTP_ASSOCPARAMS: - live_optval = malloc(sizeof(struct sctp_assocparams)); - live_optlen = (socklen_t)sizeof(struct sctp_assocparams); - ((struct sctp_assocparams*) live_optval)->sasoc_assoc_id = 0; - break; + case EXPR_SCTP_ASSOCPARAMS: + live_optval = malloc(sizeof(struct sctp_assocparams)); + live_optlen = (socklen_t)sizeof(struct sctp_assocparams); + ((struct sctp_assocparams*) live_optval)->sasoc_assoc_id = 0; + break; #endif #ifdef SCTP_INITMSG - case EXPR_SCTP_INITMSG: - live_optval = malloc(sizeof(struct sctp_initmsg)); - live_optlen = (socklen_t)sizeof(struct sctp_initmsg); - break; + case EXPR_SCTP_INITMSG: + live_optval = malloc(sizeof(struct sctp_initmsg)); + live_optlen = (socklen_t)sizeof(struct sctp_initmsg); + break; #endif #ifdef SCTP_DELAYED_SACK - case EXPR_SCTP_SACKINFO: - live_optval = malloc(sizeof(struct sctp_sack_info)); - live_optlen = (socklen_t)sizeof(struct sctp_sack_info); - ((struct sctp_sack_info*) live_optval)->sack_assoc_id = 0; - break; + case EXPR_SCTP_SACKINFO: + live_optval = malloc(sizeof(struct sctp_sack_info)); + live_optlen = (socklen_t)sizeof(struct sctp_sack_info); + ((struct sctp_sack_info*) live_optval)->sack_assoc_id = 0; + break; #endif #ifdef SCTP_STATUS - case EXPR_SCTP_STATUS: - live_optval = malloc(sizeof(struct sctp_status)); - live_optlen = (socklen_t)sizeof(struct sctp_status); - ((struct sctp_status*) live_optval)->sstat_assoc_id = 0; - break; + case EXPR_SCTP_STATUS: + live_optval = malloc(sizeof(struct sctp_status)); + live_optlen = (socklen_t)sizeof(struct sctp_status); + ((struct sctp_status*) live_optval)->sstat_assoc_id = 0; + break; #endif #ifdef SCTP_GET_PEER_ADDR_INFO - case EXPR_SCTP_PADDRINFO: { - struct sctp_paddrinfo_expr *expr_paddrinfo = val_expression->value.sctp_paddrinfo; - struct sctp_paddrinfo *live_paddrinfo = malloc(sizeof(struct sctp_paddrinfo)); - live_optlen = (socklen_t)sizeof(struct sctp_paddrinfo); - memset(live_paddrinfo, 0, sizeof(struct sctp_paddrinfo)); - live_paddrinfo->spinfo_assoc_id = 0; - if (get_sockstorage_arg(expr_paddrinfo->spinfo_address, &(live_paddrinfo->spinfo_address), live_fd, error)){ - asprintf(error, "Bad getsockopt, bad get input for spinfo_address"); - free(live_paddrinfo); - return STATUS_ERR; - } - live_optval = live_paddrinfo; - break; + case EXPR_SCTP_PADDRINFO: { + struct sctp_paddrinfo_expr *expr_paddrinfo = val_expression->value.sctp_paddrinfo; + struct sctp_paddrinfo *live_paddrinfo = malloc(sizeof(struct sctp_paddrinfo)); + live_optlen = (socklen_t)sizeof(struct sctp_paddrinfo); + memset(live_paddrinfo, 0, sizeof(struct sctp_paddrinfo)); + live_paddrinfo->spinfo_assoc_id = 0; + if (get_sockstorage_arg(expr_paddrinfo->spinfo_address, &(live_paddrinfo->spinfo_address), live_fd, error)){ + asprintf(error, "Bad getsockopt, bad get input for spinfo_address"); + free(live_paddrinfo); + return STATUS_ERR; } + live_optval = live_paddrinfo; + break; + } #endif #ifdef SCTP_PEER_ADDR_PARAMS - case EXPR_SCTP_PEER_ADDR_PARAMS: { - struct sctp_paddrparams_expr *expr_params = val_expression->value.sctp_paddrparams; - struct sctp_paddrparams *live_params = malloc(sizeof(struct sctp_paddrparams)); - memset(live_params, 0, sizeof(struct sctp_paddrparams)); - live_optlen = sizeof(struct sctp_paddrparams); - if (get_sockstorage_arg(expr_params->spp_address, &live_params->spp_address, live_fd, error)){ - asprintf(error, "Bad getsockopt, bad get input for spp_address"); - free(live_params); - return STATUS_ERR; - } - live_params->spp_assoc_id = 0; - live_optval = live_params; - break; + case EXPR_SCTP_PEER_ADDR_PARAMS: { + struct sctp_paddrparams_expr *expr_params = val_expression->value.sctp_paddrparams; + struct sctp_paddrparams *live_params = malloc(sizeof(struct sctp_paddrparams)); + memset(live_params, 0, sizeof(struct sctp_paddrparams)); + live_optlen = sizeof(struct sctp_paddrparams); + if (get_sockstorage_arg(expr_params->spp_address, &live_params->spp_address, live_fd, error)){ + asprintf(error, "Bad getsockopt, bad get input for spp_address"); + free(live_params); + return STATUS_ERR; } + live_params->spp_assoc_id = 0; + live_optval = live_params; + break; + } #endif #if defined(SCTP_MAXSEG) || defined(SCTP_MAX_BURST) || defined(SCTP_INTERLEAVING_SUPPORTED) - case EXPR_SCTP_ASSOC_VALUE: - live_optval = malloc(sizeof(struct sctp_assoc_value)); - live_optlen = (socklen_t)sizeof(struct sctp_assoc_value); - ((struct sctp_assoc_value *) live_optval)->assoc_id = 0; - break; + case EXPR_SCTP_ASSOC_VALUE: + live_optval = malloc(sizeof(struct sctp_assoc_value)); + live_optlen = (socklen_t)sizeof(struct sctp_assoc_value); + ((struct sctp_assoc_value *) live_optval)->assoc_id = 0; + break; #endif #ifdef SCTP_SS_VALUE - case EXPR_SCTP_STREAM_VALUE: - live_optval = malloc(sizeof(struct sctp_stream_value)); - live_optlen = (socklen_t)sizeof(struct sctp_stream_value); - ((struct sctp_stream_value *) live_optval)->assoc_id = 0; - if (get_u16(val_expression->value.sctp_stream_value->stream_id, - &((struct sctp_stream_value *)live_optval)->stream_id, - error)) { - free(live_optval); - return STATUS_ERR; - } - break; + case EXPR_SCTP_STREAM_VALUE: + live_optval = malloc(sizeof(struct sctp_stream_value)); + live_optlen = (socklen_t)sizeof(struct sctp_stream_value); + ((struct sctp_stream_value *) live_optval)->assoc_id = 0; + if (get_u16(val_expression->value.sctp_stream_value->stream_id, + &((struct sctp_stream_value *)live_optval)->stream_id, + error)) { + free(live_optval); + return STATUS_ERR; + } + break; #endif #ifdef SCTP_EVENT - case EXPR_SCTP_EVENT: - live_optval = malloc(sizeof(struct sctp_event)); - live_optlen = sizeof(struct sctp_event); - ((struct sctp_event *)live_optval)->se_assoc_id = 0; - if (get_u16(val_expression->value.sctp_event->se_type, - &((struct sctp_event *)live_optval)->se_type, - error)) { - free(live_optval); - return STATUS_ERR; - } - break; + case EXPR_SCTP_EVENT: + live_optval = malloc(sizeof(struct sctp_event)); + live_optlen = sizeof(struct sctp_event); + ((struct sctp_event *)live_optval)->se_assoc_id = 0; + if (get_u16(val_expression->value.sctp_event->se_type, + &((struct sctp_event *)live_optval)->se_type, + error)) { + free(live_optval); + return STATUS_ERR; + } + break; +#endif +#ifdef SCTP_DEFAULT_SNDINFO + case EXPR_SCTP_SNDINFO: + live_optval = malloc(sizeof(struct sctp_sndinfo)); + live_optlen = sizeof(struct sctp_sndinfo); + ((struct sctp_sndinfo *)live_optval)->snd_assoc_id = 0; + break; #endif #ifdef SCTP_ADAPTATION_LAYER - case EXPR_SCTP_SETADAPTATION: - live_optval = malloc(sizeof(struct sctp_setadaptation)); - live_optlen = sizeof(struct sctp_setadaptation); - break; + case EXPR_SCTP_SETADAPTATION: + live_optval = malloc(sizeof(struct sctp_setadaptation)); + live_optlen = sizeof(struct sctp_setadaptation); + break; #endif - case EXPR_INTEGER: - s32_bracketed_arg(args, 3, &script_optval, error); - live_optval = malloc(sizeof(int)); - live_optlen = (socklen_t)sizeof(int); - break; - default: - asprintf(error, "unsupported getsockopt value type: %s", - expression_type_to_string(val_expression->type)); - return STATUS_ERR; - break; + case EXPR_INTEGER: + s32_bracketed_arg(args, 3, &script_optval, error); + live_optval = malloc(sizeof(int)); + live_optlen = (socklen_t)sizeof(int); + break; + default: + asprintf(error, "unsupported getsockopt value type: %s", + expression_type_to_string(val_expression->type)); + return STATUS_ERR; + break; } begin_syscall(state, syscall); @@ -2466,75 +2530,80 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall, } switch (val_expression->type) { - case EXPR_LINGER: - result = check_linger(val_expression->value.linger, live_optval, error); - break; + case EXPR_LINGER: + result = check_linger(val_expression->value.linger, live_optval, error); + break; #ifdef SCTP_RTOINFO - case EXPR_SCTP_RTOINFO: - result = check_sctp_rtoinfo(val_expression->value.sctp_rtoinfo, live_optval, error); - break; + case EXPR_SCTP_RTOINFO: + result = check_sctp_rtoinfo(val_expression->value.sctp_rtoinfo, live_optval, error); + break; #endif #ifdef SCTP_ASSOCINFO - case EXPR_SCTP_ASSOCPARAMS: - result = check_sctp_assocparams(val_expression->value.sctp_assocparams, live_optval, error); - break; + case EXPR_SCTP_ASSOCPARAMS: + result = check_sctp_assocparams(val_expression->value.sctp_assocparams, live_optval, error); + break; #endif #ifdef SCTP_INITMSG - case EXPR_SCTP_INITMSG: - result = check_sctp_initmsg(val_expression->value.sctp_initmsg, live_optval, error); - break; + case EXPR_SCTP_INITMSG: + result = check_sctp_initmsg(val_expression->value.sctp_initmsg, live_optval, error); + break; #endif #ifdef SCTP_DELAYED_SACK - case EXPR_SCTP_SACKINFO: - result = check_sctp_sack_info(val_expression->value.sctp_sack_info, live_optval, error); - break; + case EXPR_SCTP_SACKINFO: + result = check_sctp_sack_info(val_expression->value.sctp_sack_info, live_optval, error); + break; #endif #ifdef SCTP_STATUS - case EXPR_SCTP_STATUS: - result = check_sctp_status(val_expression->value.sctp_status, live_optval, error); - break; + case EXPR_SCTP_STATUS: + result = check_sctp_status(val_expression->value.sctp_status, live_optval, error); + break; #endif #ifdef SCTP_GET_PEER_ADDR_INFO - case EXPR_SCTP_PADDRINFO: - result = check_sctp_paddrinfo(val_expression->value.sctp_paddrinfo, live_optval, error); - break; + case EXPR_SCTP_PADDRINFO: + result = check_sctp_paddrinfo(val_expression->value.sctp_paddrinfo, live_optval, error); + break; #endif #ifdef SCTP_PEER_ADDR_PARAMS - case EXPR_SCTP_PEER_ADDR_PARAMS: - result = check_sctp_paddrparams(val_expression->value.sctp_paddrparams, live_optval, error); - break; + case EXPR_SCTP_PEER_ADDR_PARAMS: + result = check_sctp_paddrparams(val_expression->value.sctp_paddrparams, live_optval, error); + break; #endif #if defined(SCTP_MAXSEG) || defined(SCTP_MAX_BURST) || defined(SCTP_INTERLEAVING_SUPPORTED) - case EXPR_SCTP_ASSOC_VALUE: - result = check_sctp_assoc_value(val_expression->value.sctp_assoc_value, live_optval, error); - break; + case EXPR_SCTP_ASSOC_VALUE: + result = check_sctp_assoc_value(val_expression->value.sctp_assoc_value, 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); - break; + case EXPR_SCTP_STREAM_VALUE: + result = check_sctp_stream_value(val_expression->value.sctp_stream_value, live_optval, error); + break; #endif #ifdef SCTP_EVENT - case EXPR_SCTP_EVENT: - result = check_sctp_event(val_expression->value.sctp_event, live_optval, error); - break; + case EXPR_SCTP_EVENT: + result = check_sctp_event(val_expression->value.sctp_event, live_optval, error); + break; +#endif +#ifdef SCTP_DEFAULT_SNDINFO + case EXPR_SCTP_SNDINFO: + result = check_sctp_sndinfo(val_expression->value.sctp_sndinfo, live_optval, error); + break; #endif #ifdef SCTP_ADAPTATION_LAYER - case EXPR_SCTP_SETADAPTATION: - result = check_sctp_setadaptation(val_expression->value.sctp_setadaptation, live_optval, error); - break; + case EXPR_SCTP_SETADAPTATION: + result = check_sctp_setadaptation(val_expression->value.sctp_setadaptation, live_optval, error); + break; #endif - case EXPR_INTEGER: - if (*(int*)live_optval != script_optval) { - asprintf(error, "Bad getsockopt optval: expected: %d actual: %d", - (int)script_optval, *(int*)live_optval); - result = STATUS_ERR; - } - break; - default: - asprintf(error, "Cannot check getsockopt value type: %s", - expression_type_to_string(val_expression->type)); - break; + case EXPR_INTEGER: + if (*(int*)live_optval != script_optval) { + asprintf(error, "Bad getsockopt optval: expected: %d actual: %d", + (int)script_optval, *(int*)live_optval); + result = STATUS_ERR; + } + break; + default: + asprintf(error, "Cannot check getsockopt value type: %s", + expression_type_to_string(val_expression->type)); + break; } free(live_optval); return result; @@ -2574,6 +2643,9 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall, #ifdef SCTP_EVENT struct sctp_event event; #endif +#ifdef SCTP_DEFAULT_SNDINFO + struct sctp_sndinfo sndinfo; +#endif #ifdef SCTP_ADAPTATION_LAYER struct sctp_setadaptation setadaptation; #endif @@ -2751,6 +2823,28 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall, optval = &event; break; #endif +#ifdef SCTP_DEFAULT_SNDINFO + case EXPR_SCTP_SNDINFO: + sndinfo.snd_assoc_id = 0; + if (get_u16(val_expression->value.sctp_sndinfo->snd_sid, + &sndinfo.snd_sid, error)) { + return STATUS_ERR; + } + if (get_u16(val_expression->value.sctp_sndinfo->snd_flags, + &sndinfo.snd_flags, error)) { + return STATUS_ERR; + } + if (get_u32(val_expression->value.sctp_sndinfo->snd_ppid, + &sndinfo.snd_ppid, error)) { + return STATUS_ERR; + } + if (get_u32(val_expression->value.sctp_sndinfo->snd_context, + &sndinfo.snd_context, error)) { + return STATUS_ERR; + } + optval = &sndinfo; + break; +#endif #ifdef SCTP_ADAPTATION_LAYER case EXPR_SCTP_SETADAPTATION: if (get_u32(val_expression->value.sctp_setadaptation->ssb_adaptation_ind, diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c index 9b4d75e33f0eaf02255cc60c6709c3f44ca23c2e..5c07f3ee5053bf66edcf3a688dba82a8c9bb82dd 100644 --- a/gtests/net/packetdrill/script.c +++ b/gtests/net/packetdrill/script.c @@ -75,6 +75,7 @@ struct expression_type_entry expression_type_table[] = { { EXPR_SCTP_STREAM_VALUE, "sctp_stream_value"}, { EXPR_SCTP_ASSOCPARAMS, "sctp_assocparams"}, { EXPR_SCTP_EVENT, "sctp_event" }, + { EXPR_SCTP_SNDINFO, "sctp_sndinfo" }, { EXPR_SCTP_SETADAPTATION, "sctp_setadaptation"}, { NUM_EXPR_TYPES, NULL} }; @@ -355,6 +356,12 @@ void free_expression(struct expression *expression) free_expression(expression->value.sctp_event->se_type); free_expression(expression->value.sctp_event->se_on); 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); + break; case EXPR_SCTP_SETADAPTATION: free_expression(expression->value.sctp_setadaptation->ssb_adaptation_ind); break; @@ -900,6 +907,41 @@ static int evaluate_sctp_accocparams_expression(struct expression *in, 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; + return STATUS_OK; +} + static int evaluate_sctp_setadaptation_expression(struct expression *in, struct expression *out, char **error) @@ -977,6 +1019,9 @@ static int evaluate(struct expression *in, case EXPR_SCTP_EVENT: result = evaluate_sctp_event_expression(in, out, error); break; + case EXPR_SCTP_SNDINFO: + result = evaluate_sctp_sndinfo_expression(in, out, error); + break; case EXPR_SCTP_SETADAPTATION: result = evaluate_sctp_setadaptation_expression(in, out, error); break; diff --git a/gtests/net/packetdrill/script.h b/gtests/net/packetdrill/script.h index 2c9b5d69adead0d7ade2bd749e53d33e7a0a0bb5..c614f9d7053d8e3363e8b3bbe254f2f84cc362fd 100644 --- a/gtests/net/packetdrill/script.h +++ b/gtests/net/packetdrill/script.h @@ -54,7 +54,8 @@ enum expression_t { EXPR_SCTP_STREAM_VALUE, /* struct sctp_stream_value for SCTP_SS_VALUE */ EXPR_SCTP_PEER_ADDR_PARAMS, /* struct for sctp_paddrparams for SCTP_PEER_ADDR_PARAMS */ EXPR_SCTP_ASSOCPARAMS, /* struct sctp_assocparams for SCTP_ASSOCINFO */ - EXPR_SCTP_EVENT, /* struct sctp_event to for SCTP_EVENT */ + EXPR_SCTP_EVENT, /* struct sctp_event for SCTP_EVENT */ + EXPR_SCTP_SNDINFO, /* struct sctp_sndinfo for SCTP_DEFAULT_SNDINFO */ EXPR_SCTP_SETADAPTATION, /* struct sctp_setadaptation for SCTP_ADATTATION_LAYER */ NUM_EXPR_TYPES, }; @@ -85,6 +86,7 @@ struct expression { struct sctp_stream_value_expr *sctp_stream_value; struct sctp_assocparams_expr *sctp_assocparams; struct sctp_event_expr *sctp_event; + struct sctp_sndinfo_expr *sctp_sndinfo; struct sctp_setadaptation_expr *sctp_setadaptation; } value; const char *format; /* the printf format for printing the value */ @@ -212,6 +214,14 @@ struct sctp_event_expr { struct expression *se_on; }; +/* Parse tree for sctp_sndinfo struct in [gs]etsockopt syscall. */ +struct sctp_sndinfo_expr { + struct expression *snd_sid; + struct expression *snd_flags; + struct expression *snd_ppid; + struct expression *snd_context; +}; + /* Parse tree for sctp_setadaptation struct in [gs]etsockopt syscall. */ struct sctp_setadaptation_expr { struct expression *ssb_adaptation_ind; diff --git a/gtests/net/packetdrill/symbols_freebsd.c b/gtests/net/packetdrill/symbols_freebsd.c index 779c8aab75642cd6cc36e9672eeb921c8959442f..b5454bae547d452a990c933365dc2d7d5bcbc83b 100644 --- a/gtests/net/packetdrill/symbols_freebsd.c +++ b/gtests/net/packetdrill/symbols_freebsd.c @@ -89,6 +89,7 @@ struct int_symbol platform_symbols_table[] = { { SCTP_MAX_BURST, "SCTP_MAX_BURST" }, { SCTP_PEER_ADDR_PARAMS, "SCTP_PEER_ADDR_PARAMS" }, { SCTP_EVENT, "SCTP_EVENT" }, + { SCTP_DEFAULT_SNDINFO, "SCTP_DEFAULT_SNDINFO" }, { SCTP_STATUS, "SCTP_STATUS" }, { SCTP_GET_PEER_ADDR_INFO, "SCTP_GET_PEER_ADDR_INFO" }, { SCTP_FRAGMENT_INTERLEAVE, "SCTP_FRAGMENT_INTERLEAVE" }, @@ -177,6 +178,14 @@ struct int_symbol platform_symbols_table[] = { { SCTP_ASSOC_RESET_EVENT, "SCTP_ASSOC_RESET_EVENT" }, { SCTP_STREAM_CHANGE_EVENT, "SCTP_STREAM_CHANGE_EVENT" }, { SCTP_SEND_FAILED_EVENT, "SCTP_SEND_FAILED_EVENT" }, + { SCTP_UNORDERED, "SCTP_UNORDERED" }, + { SCTP_ADDR_OVER, "SCTP_ADDR_OVER" }, + { SCTP_ABORT, "SCTP_ABORT" }, + { SCTP_EOF, "SCTP_EOF" }, + { SCTP_SENDALL, "SCTP_SENDALL" }, + { SCTP_EOR, "SCTP_EOR" }, + { SCTP_SACK_IMMEDIATELY, "SCTP_SACK_IMMEDIATELY" }, + /* /usr/include/netinet/tcp.h */ { TCP_NODELAY, "TCP_NODELAY" }, { TCP_MAXSEG, "TCP_MAXSEG" }, diff --git a/gtests/net/packetdrill/symbols_linux.c b/gtests/net/packetdrill/symbols_linux.c index 386e4c34ec865ca9805ac0c57906f95ad85f5212..464f2141f87f9ed843c69d1c309d0808eb39d1cc 100644 --- a/gtests/net/packetdrill/symbols_linux.c +++ b/gtests/net/packetdrill/symbols_linux.c @@ -107,7 +107,10 @@ struct int_symbol platform_symbols_table[] = { { SCTP_MAXSEG, "SCTP_MAXSEG" }, { SCTP_DELAYED_SACK, "SCTP_DELAYED_SACK" }, { SCTP_MAX_BURST, "SCTP_MAX_BURST" }, -#ifdef SCTP_EVENT +#if 0 + { SCTP_DEFAULT_SNDINFO, "SCTP_DEFAULT_SNDINFO" }, +#endif +#if 0 { SCTP_EVENT, "SCTP_EVENT" }, #endif { SCTP_PEER_ADDR_PARAMS, "SCTP_PEER_ADDR_PARAMS" }, @@ -170,13 +173,35 @@ struct int_symbol platform_symbols_table[] = { #ifdef SCTP_SENDER_DRY_EVENT { SCTP_SENDER_DRY_EVENT, "SCTP_SENDER_DRY_EVENT" }, #endif +#ifdef SCTP_NOTIFICATIONS_STOPPED_EVENT + { SCTP_NOTIFICATIONS_STOPPED_EVENT, "SCTP_NOTIFICATIONS_STOPPED_EVENT"}, +#endif + #ifdef SCTP_ADAPTATION_LAYER { SCTP_ADAPTATION_LAYER, "SCTP_ADAPTATION_LAYER" }, #endif + #if 0 { SPP_IPV6_FLOWLABEL, "SPP_IPV6_FLOWLABEL" }, { SPP_DSCP, "SPP_DSCP" }, #endif + { SCTP_UNORDERED, "SCTP_UNORDERED" }, + { SCTP_ADDR_OVER, "SCTP_ADDR_OVER" }, + { SCTP_ABORT, "SCTP_ABORT" }, + { SCTP_EOF, "SCTP_EOF" }, + { SCTP_SACK_IMMEDIATELY, "SCTP_SACK_IMMEDIATELY" }, +#if 0 + { SCTP_SENDALL, "SCTP_SENDALL" }, +#endif + { SCTP_UNORDERED, "SCTP_UNORDERED" }, + { SCTP_ADDR_OVER, "SCTP_ADDR_OVER" }, + { SCTP_ABORT, "SCTP_ABORT" }, + { SCTP_EOF, "SCTP_EOF" }, +#if 0 + { SCTP_SENDALL, "SCTP_SENDALL" }, + { SCTP_EOR, "SCTP_EOR" }, +#endif + { SCTP_SACK_IMMEDIATELY, "SCTP_SACK_IMMEDIATELY" }, { TCP_NODELAY, "TCP_NODELAY" }, { TCP_MAXSEG, "TCP_MAXSEG" }, diff --git a/gtests/net/packetdrill/tests/bsd/sctp/sctp_get_socket_options.pkt b/gtests/net/packetdrill/tests/bsd/sctp/sctp_get_socket_options.pkt index 7671c7d28cbf64f9a3e5c352a3fb7440006ff4bd..0cd0e2782d3dac117cdea1e727f12af2c1a3b2c4 100644 --- a/gtests/net/packetdrill/tests/bsd/sctp/sctp_get_socket_options.pkt +++ b/gtests/net/packetdrill/tests/bsd/sctp/sctp_get_socket_options.pkt @@ -96,11 +96,16 @@ spp_hbinterval=300, spp_pathmaxrxt=..., spp_pathmtu=1468, spp_flags=521, spp_ipv +0 getsockopt(3, IPPROTO_SCTP, SCTP_INITMSG, {sinit_num_ostreams=2, sinit_max_instreams=..., sinit_max_attempts=2, sinit_max_init_timeo=30}, [8]) = 0 +0 getsockopt(3, IPPROTO_SCTP, SCTP_INITMSG, {sinit_num_ostreams=2, sinit_max_instreams=2, sinit_max_attempts=..., sinit_max_init_timeo=30}, [8]) = 0 -+0 setsockopt(3, IPPROTO_SCTP, SCTP_ASSOCINFO, {sasoc_asocmaxrxt=5, sasoc_number_peer_destinations=3, sasoc_peer_rwnd=1800, sasoc_local_rwnd=2000, sasoc_cookie_life=40000}, 20) = 0 -+0 getsockopt(3, IPPROTO_SCTP, SCTP_ASSOCINFO, {sasoc_asocmaxrxt=5, sasoc_number_peer_destinations=1, sasoc_peer_rwnd=1500, sasoc_local_rwnd=1864135, sasoc_cookie_life=40000}, [20]) = 0 -+0 getsockopt(3, IPPROTO_SCTP, SCTP_ASSOCINFO, {sasoc_asocmaxrxt=..., sasoc_number_peer_destinations=..., sasoc_peer_rwnd=..., sasoc_local_rwnd=..., sasoc_cookie_life=40000}, [20]) = 0 -+0 getsockopt(3, IPPROTO_SCTP, SCTP_ASSOCINFO, {sasoc_asocmaxrxt=5, sasoc_number_peer_destinations=..., sasoc_peer_rwnd=..., sasoc_local_rwnd=..., sasoc_cookie_life=40000}, [20]) = 0 -+0 getsockopt(3, IPPROTO_SCTP, SCTP_ASSOCINFO, {sasoc_asocmaxrxt=5, sasoc_number_peer_destinations=..., sasoc_peer_rwnd=..., sasoc_local_rwnd=..., sasoc_cookie_life=...}, [20]) = 0 ++0 setsockopt(3, IPPROTO_SCTP, SCTP_ASSOCINFO, {sasoc_asocmaxrxt=5, sasoc_number_peer_destinations=3, sasoc_peer_rwnd=1800, sasoc_local_rwnd=2000, +sasoc_cookie_life=40000}, 20) = 0 ++0 getsockopt(3, IPPROTO_SCTP, SCTP_ASSOCINFO, {sasoc_asocmaxrxt=5, sasoc_number_peer_destinations=1, sasoc_peer_rwnd=1500, sasoc_local_rwnd=1864135, +sasoc_cookie_life=40000}, [20]) = 0 ++0 getsockopt(3, IPPROTO_SCTP, SCTP_ASSOCINFO, {sasoc_asocmaxrxt=..., sasoc_number_peer_destinations=..., sasoc_peer_rwnd=..., sasoc_local_rwnd=..., +sasoc_cookie_life=40000}, [20]) = 0 ++0 getsockopt(3, IPPROTO_SCTP, SCTP_ASSOCINFO, {sasoc_asocmaxrxt=5, sasoc_number_peer_destinations=..., sasoc_peer_rwnd=..., sasoc_local_rwnd=..., +sasoc_cookie_life=40000}, [20]) = 0 ++0 getsockopt(3, IPPROTO_SCTP, SCTP_ASSOCINFO, {sasoc_asocmaxrxt=5, sasoc_number_peer_destinations=..., sasoc_peer_rwnd=..., sasoc_local_rwnd=..., +sasoc_cookie_life=...}, [20]) = 0 +0 setsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_delay=250, sack_freq=1}, 12) = 0 +0 getsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_delay=250, sack_freq=1}, [12]) = 0 @@ -110,6 +115,15 @@ spp_hbinterval=300, spp_pathmaxrxt=..., spp_pathmtu=1468, spp_flags=521, spp_ipv +0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SHUTDOWN_EVENT, se_on=1}, 8) = 0 +0 getsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SHUTDOWN_EVENT, se_on=1}, [8]) = 0 ++0 setsockopt(3, IPPROTO_SCTP, SCTP_DEFAULT_SNDINFO, {snd_sid=0, snd_flags=0, snd_ppid=1, snd_context=1}, 16) = 0 ++0 getsockopt(3, IPPROTO_SCTP, SCTP_DEFAULT_SNDINFO, {snd_sid=0, snd_flags=0, snd_ppid=1, snd_context=1}, [16]) = 0 ++0 setsockopt(3, IPPROTO_SCTP, SCTP_DEFAULT_SNDINFO, {snd_sid=0, snd_flags=SCTP_UNORDERED, snd_ppid=2, snd_context=2}, 16) = 0 ++0 getsockopt(3, IPPROTO_SCTP, SCTP_DEFAULT_SNDINFO, {snd_sid=0, snd_flags=SCTP_UNORDERED, snd_ppid=2, snd_context=2}, [16]) = 0 ++0 getsockopt(3, IPPROTO_SCTP, SCTP_DEFAULT_SNDINFO, {snd_sid=0, snd_flags=SCTP_UNORDERED, snd_ppid=2, snd_context=...}, [16]) = 0 ++0 getsockopt(3, IPPROTO_SCTP, SCTP_DEFAULT_SNDINFO, {snd_sid=0, snd_flags=SCTP_UNORDERED, snd_ppid=..., snd_context=2}, [16]) = 0 ++0 getsockopt(3, IPPROTO_SCTP, SCTP_DEFAULT_SNDINFO, {snd_sid=0, snd_flags=..., snd_ppid=2, snd_context=2}, [16]) = 0 ++0 getsockopt(3, IPPROTO_SCTP, SCTP_DEFAULT_SNDINFO, {snd_sid=..., snd_flags=SCTP_UNORDERED, snd_ppid=2, snd_context=2}, [16]) = 0 + +0 setsockopt(3, IPPROTO_SCTP, SCTP_ADAPTATION_LAYER, {ssb_adaptation_ind=2}, 4) = 0 +0 getsockopt(3, IPPROTO_SCTP, SCTP_ADAPTATION_LAYER, {ssb_adaptation_ind=2}, [4]) = 0