From c4d639700c95d5048b95a37c6e9bb9c4c3f420fc Mon Sep 17 00:00:00 2001 From: hoelscher <jens.hoelscher@fh-muenster.de> Date: Thu, 26 Nov 2015 23:36:15 +0100 Subject: [PATCH] add sctp_default_prinfo for [gs]etsockopt syscall --- gtests/net/packetdrill/lexer.l | 1 + gtests/net/packetdrill/parser.y | 22 +++++- gtests/net/packetdrill/run_system_call.c | 78 ++++++++++++++++++- gtests/net/packetdrill/script.c | 41 ++++++++++ gtests/net/packetdrill/script.h | 9 +++ gtests/net/packetdrill/symbols_freebsd.c | 1 + .../bsd/sctp/sctp_get_socket_options.pkt | 3 + 7 files changed, 149 insertions(+), 6 deletions(-) diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index 2476987f..9d0f8866 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -291,6 +291,7 @@ serinfo_next_length return SERINFO_NEXT_LENGTH; serinfo_next_ppid return SERINFO_NEXT_PPID; pr_policy return PR_POLICY; pr_value return PR_VALUE; +pr_assoc_id return PR_ASSOC_ID; sendv_flags return SENDV_FLAGS; sendv_sndinfo return SENDV_SNDINFO; sendv_prinfo return SENDV_PRINFO; diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index 89cbf3c7..db0fd2cd 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -544,7 +544,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %token <reserved> SINFO_STREAM SINFO_SSN SINFO_FLAGS SINFO_PPID SINFO_CONTEXT SINFO_ASSOC_ID %token <reserved> SINFO_TIMETOLIVE SINFO_TSN SINFO_CUMTSN SINFO_PR_VALUE SERINFO_NEXT_FLAGS %token <reserved> SERINFO_NEXT_STREAM SERINFO_NEXT_AID SERINFO_NEXT_LENGTH SERINFO_NEXT_PPID -%token <reserved> PR_POLICY PR_VALUE AUTH_KEYNUMBER SENDV_FLAGS SENDV_SNDINFO +%token <reserved> PR_POLICY PR_VALUE PR_ASSOC_ID AUTH_KEYNUMBER SENDV_FLAGS SENDV_SNDINFO %token <reserved> SENDV_PRINFO SENDV_AUTHINFO %token <reserved> RCV_SID RCV_SSN RCV_FLAGS RCV_PPID RCV_TSN RCV_CUMTSN RCV_CONTEXT RCV_ASSOC_ID %token <reserved> NXT_SID NXT_FLAGS NXT_PPID NXT_LENGTH NXT_ASSOC_ID @@ -619,7 +619,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %type <expression> sctp_sndrcvinfo sinfo_stream sinfo_ssn sinfo_flags sinfo_ppid sinfo_context %type <expression> sinfo_timetolive sinfo_tsn sinfo_cumtsn sinfo_assoc_id sinfo_pr_value serinfo_next_flags %type <expression> serinfo_next_stream serinfo_next_aid serinfo_next_length serinfo_next_ppid sctp_extrcvinfo -%type <expression> sctp_prinfo sctp_authinfo pr_policy sctp_sendv_spa +%type <expression> sctp_prinfo sctp_authinfo pr_policy sctp_sendv_spa sctp_default_prinfo %type <expression> sctp_rcvinfo rcv_sid rcv_ssn rcv_flags rcv_ppid rcv_tsn rcv_cumtsn rcv_context rcv_assoc_id %type <expression> sctp_nxtinfo nxt_sid nxt_flags nxt_ppid nxt_length nxt_assoc_id sctp_recvv_rn %type <expression> sctp_shutdown_event sse_type sse_flags sse_length sse_assoc_id @@ -2522,6 +2522,9 @@ expression | sctp_prinfo { $$ = $1; } +|sctp_default_prinfo{ + $$ = $1; +} | sctp_authinfo { $$ = $1; } @@ -3697,8 +3700,21 @@ pr_policy $$ = new_integer_expression($3, "%hu"); }; +sctp_default_prinfo +: '{' pr_policy ',' PR_VALUE '=' INTEGER ',' PR_ASSOC_ID '=' expression'}' { + $$ = new_expression(EXPR_SCTP_DEFAULT_PRINFO); + $$->value.sctp_default_prinfo = calloc(1, sizeof(struct sctp_default_prinfo_expr)); + $$->value.sctp_default_prinfo->pr_policy = $2; + if (!is_valid_u32($6)) { + semantic_error("pr_value out of range"); + } + $$->value.sctp_default_prinfo->pr_value = new_integer_expression($6, "%u"); + $$->value.sctp_default_prinfo->pr_assoc_id = $10; +} +; + sctp_prinfo -: '{' pr_policy ',' PR_VALUE '=' INTEGER'}' { +: '{' pr_policy ',' PR_VALUE '=' INTEGER '}' { $$ = new_expression(EXPR_SCTP_PRINFO); $$->value.sctp_prinfo = calloc(1, sizeof(struct sctp_prinfo_expr)); $$->value.sctp_prinfo->pr_policy = $2; diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c index d5ce3c0d..40c26cb4 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -660,6 +660,23 @@ int check_u32_expr(struct expression *expr, u32 value, char *val_name, char **er return STATUS_OK; } +#if defined(__FreeBSD__) || defined(linux) +int check_sctp_assoc_t_expr(struct expression *expr, sctp_assoc_t value, char *val_name, char **error) { + if (expr->type != EXPR_ELLIPSIS) { + sctp_assoc_t script_val; + + if (get_sctp_assoc_t(expr, &script_val, error)) { + return STATUS_ERR; + } + if (script_val != value) { + asprintf(error, "%s: expected: %u actual: %u", val_name, script_val, value); + return STATUS_ERR; + } + } + return STATUS_OK; +} +#endif + int check_socklen_t_expr(struct expression *expr, socklen_t value, char *val_name, char **error) { if (expr->type != EXPR_ELLIPSIS) { socklen_t script_val; @@ -2509,8 +2526,8 @@ static int check_linger(struct linger_expr *expr, static int check_sctp_rtoinfo(struct sctp_rtoinfo_expr *expr, struct sctp_rtoinfo *sctp_rtoinfo, char **error) { - if (check_u32_expr(expr->srto_assoc_id, sctp_rtoinfo->srto_assoc_id, - "sctp_rtoinfo.srto_assoc_id", error)) + if (check_sctp_assoc_t_expr(expr->srto_assoc_id, sctp_rtoinfo->srto_assoc_id, + "sctp_rtoinfo.srto_assoc_id", error)) return STATUS_ERR; if (check_u32_expr(expr->srto_initial, sctp_rtoinfo->srto_initial, "sctp_rtoinfo.srto_initial", error)) @@ -2821,13 +2838,31 @@ static int check_sctp_sndinfo(struct sctp_sndinfo_expr *expr, return STATUS_OK; } #endif +#ifdef SCTP_DEFAULT_PRINFO +static int check_sctp_default_prinfo(struct sctp_default_prinfo_expr *expr, + struct sctp_default_prinfo *info, + char **error) +{ + if (check_sctp_assoc_t_expr(expr->pr_assoc_id, info->pr_assoc_id, + "sctp_default_prinfo.pr_assoc_id", error)) + return STATUS_ERR; + if (check_u16_expr(expr->pr_policy, info->pr_policy, + "sctp_default_prinfo.pr_policy", error)) + return STATUS_ERR; + if (check_u32_expr(expr->pr_value, info->pr_value, + "sctp_default_prinfo.pr_value", error)) + return STATUS_ERR; + + return STATUS_OK; +} +#endif #ifdef SCTP_PRIMARY_ADDR static int check_sctp_setprim(struct sctp_setprim_expr *expr, struct sctp_setprim *sctp_setprim, char **error) { - if (check_u32_expr(expr->ssp_assoc_id, sctp_setprim->ssp_assoc_id, + if (check_sctp_assoc_t_expr(expr->ssp_assoc_id, sctp_setprim->ssp_assoc_id, "sctp_setprim.ssp_assoc_id", error)) return STATUS_ERR; if (check_sockaddr(expr->ssp_addr, (struct sockaddr *)&sctp_setprim->ssp_addr, error)) @@ -3027,6 +3062,18 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall, } break; #endif +#ifdef SCTP_DEFAULT_PRINFO + case EXPR_SCTP_DEFAULT_PRINFO: + live_optval = malloc(sizeof(struct sctp_default_prinfo)); + live_optlen = sizeof(struct sctp_default_prinfo); + if (get_sctp_assoc_t(val_expression->value.sctp_default_prinfo->pr_assoc_id, + &((struct sctp_default_prinfo *)live_optval)->pr_assoc_id, + error)) { + free(live_optval); + return STATUS_ERR; + } + break; +#endif #ifdef SCTP_PRIMARY_ADDR case EXPR_SCTP_SETPRIM: live_optval = malloc(sizeof(struct sctp_setprim)); @@ -3136,6 +3183,11 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall, result = check_sctp_sndinfo(val_expression->value.sctp_sndinfo, live_optval, error); break; #endif +#ifdef SCTP_DEFAULT_PRINFO + case EXPR_SCTP_DEFAULT_PRINFO: + result = check_sctp_default_prinfo(val_expression->value.sctp_default_prinfo, live_optval, error); + break; +#endif #ifdef SCTP_PRIMARY_ADDR case EXPR_SCTP_SETPRIM: result = check_sctp_setprim(val_expression->value.sctp_setprim, live_optval, error); @@ -3202,6 +3254,9 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall, #ifdef SCTP_DEFAULT_SNDINFO struct sctp_sndinfo sndinfo; #endif +#ifdef SCTP_DEFAULT_PRINFO + struct sctp_default_prinfo default_prinfo; +#endif #ifdef SCTP_PRIMARY_ADDR struct sctp_setprim setprim; #endif @@ -3458,6 +3513,23 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall, optval = &sndinfo; break; #endif +#ifdef SCTP_DEFAULT_PRINFO + case EXPR_SCTP_DEFAULT_PRINFO: + if (get_u16(val_expression->value.sctp_default_prinfo->pr_policy, + &default_prinfo.pr_policy, error)) { + return STATUS_ERR; + } + if (get_u32(val_expression->value.sctp_default_prinfo->pr_value, + &default_prinfo.pr_value, error)) { + return STATUS_ERR; + } + if (get_sctp_assoc_t(val_expression->value.sctp_default_prinfo->pr_assoc_id, + &default_prinfo.pr_assoc_id, error)) { + return STATUS_ERR; + } + optval = &default_prinfo; + break; +#endif #ifdef SCTP_PRIMARY_ADDR case EXPR_SCTP_SETPRIM: if (get_sctp_assoc_t(val_expression->value.sctp_setprim->ssp_assoc_id, diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c index ec2f92d6..887b1a0b 100644 --- a/gtests/net/packetdrill/script.c +++ b/gtests/net/packetdrill/script.c @@ -83,6 +83,7 @@ struct expression_type_entry expression_type_table[] = { { 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" }, @@ -427,6 +428,11 @@ void free_expression(struct expression *expression) 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; @@ -1399,6 +1405,38 @@ static int evaluate_sctp_prinfo_expression(struct expression *in, 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) @@ -2205,6 +2243,9 @@ static int evaluate(struct expression *in, 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; diff --git a/gtests/net/packetdrill/script.h b/gtests/net/packetdrill/script.h index 740e7485..b2b15803 100644 --- a/gtests/net/packetdrill/script.h +++ b/gtests/net/packetdrill/script.h @@ -63,6 +63,7 @@ enum expression_t { EXPR_SCTP_SETADAPTATION, /* struct sctp_setadaptation for SCTP_ADATTATION_LAYER */ EXPR_SCTP_SNDRCVINFO, /* struct sctp_sndrcvinfo for syscall sctp_recvmsg */ EXPR_SCTP_PRINFO, /* struct sctp_prinfo for syscall sctp_sendv */ + EXPR_SCTP_DEFAULT_PRINFO, /* expression tree for struct sctp_default_prinfo for syscall [gs]etsockopt */ EXPR_SCTP_AUTHINFO, /* struct sctp_authinfo for syscall sctp_sendv */ EXPR_SCTP_SENDV_SPA, /* struct sctp_sendv_spa for syscall sctp_sendv */ EXPR_SCTP_RCVINFO, /* struct sctp_rcvinfo for syscall sctp_recvv */ @@ -116,6 +117,7 @@ struct expression { struct sctp_setadaptation_expr *sctp_setadaptation; struct sctp_sndrcvinfo_expr *sctp_sndrcvinfo; struct sctp_prinfo_expr *sctp_prinfo; + struct sctp_default_prinfo_expr *sctp_default_prinfo; struct sctp_authinfo_expr *sctp_authinfo; struct sctp_sendv_spa_expr *sctp_sendv_spa; struct sctp_rcvinfo_expr *sctp_rcvinfo; @@ -329,6 +331,13 @@ struct sctp_prinfo_expr { struct expression *pr_value; }; +/* Parse tree for sctp_default_prinfo in [gs]etsockopt syscall. */ +struct sctp_default_prinfo_expr { + struct expression *pr_policy; + struct expression *pr_value; + struct expression *pr_assoc_id; +}; + /* Parse tree for sctp_authinfo in sctp_sendv syscall. */ struct sctp_authinfo_expr { struct expression *auth_keynumber; diff --git a/gtests/net/packetdrill/symbols_freebsd.c b/gtests/net/packetdrill/symbols_freebsd.c index ae52fa39..4f4f2c17 100644 --- a/gtests/net/packetdrill/symbols_freebsd.c +++ b/gtests/net/packetdrill/symbols_freebsd.c @@ -93,6 +93,7 @@ struct int_symbol platform_symbols_table[] = { { SCTP_EVENT, "SCTP_EVENT" }, { SCTP_EVENTS, "SCTP_EVENTS" }, { SCTP_DEFAULT_SNDINFO, "SCTP_DEFAULT_SNDINFO" }, + { SCTP_DEFAULT_PRINFO, "SCTP_DEFAULT_PRINFO" }, { SCTP_STATUS, "SCTP_STATUS" }, { SCTP_GET_PEER_ADDR_INFO, "SCTP_GET_PEER_ADDR_INFO" }, { SCTP_FRAGMENT_INTERLEAVE, "SCTP_FRAGMENT_INTERLEAVE" }, 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 637209b2..d11d2c32 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 @@ -13,6 +13,9 @@ +0 setsockopt(3, IPPROTO_SCTP, SCTP_PRIMARY_ADDR, {ssp_assoc_id=0, ssp_addr={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")}}, 136) = 0 +0 getsockopt(3, IPPROTO_SCTP, SCTP_PRIMARY_ADDR, {ssp_assoc_id=0, ssp_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_DEFAULT_PRINFO, {pr_policy=SCTP_PR_SCTP_TTL, pr_value=5, pr_assoc_id=3}, 12) = 0 ++0 getsockopt(3, IPPROTO_SCTP, SCTP_DEFAULT_PRINFO, {pr_policy=SCTP_PR_SCTP_TTL, pr_value=5, pr_assoc_id=3}, [12]) = 0 + +0 setsockopt(3, IPPROTO_SCTP, SCTP_STATUS, {sstat_state=..., sstat_rwnd=..., sstat_unackdata=..., sstat_penddata=..., sstat_instrms=..., sstat_outstrms=..., sstat_fragmentation_point=..., sstat_primary=...}, 176) = -1 -- GitLab