From 01750660f27f7e9fbea544a00a6a30665d3bec4b Mon Sep 17 00:00:00 2001 From: hoelscher <jens.hoelscher@fh-muenster.de> Date: Sat, 31 Oct 2015 08:07:23 +0100 Subject: [PATCH] add support for cmsg sctp_nxtinfo and sctp_rcvinfo --- gtests/net/packetdrill/lexer.l | 2 + gtests/net/packetdrill/parser.y | 40 ++- gtests/net/packetdrill/run_system_call.c | 294 ++++++++++-------- gtests/net/packetdrill/script.c | 10 + gtests/net/packetdrill/script.h | 2 + gtests/net/packetdrill/symbols_freebsd.c | 3 + .../packetdrill/tests/bsd/sctp/recvmsg.pkt | 54 ++++ 7 files changed, 277 insertions(+), 128 deletions(-) create mode 100644 gtests/net/packetdrill/tests/bsd/sctp/recvmsg.pkt diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index 163f890a..c4b9e435 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -295,10 +295,12 @@ rcv_ppid return RCV_PPID; rcv_tsn return RCV_TSN; rcv_cumtsn return RCV_CUMTSN; rcv_context return RCV_CONTEXT; +rcv_assoc_id return RCV_ASSOC_ID; nxt_sid return NXT_SID; nxt_flags return NXT_FLAGS; nxt_ppid return NXT_PPID; nxt_length return NXT_LENGTH; +nxt_assoc_id return NXT_ASSOC_ID; recvv_rcvinfo return RECVV_RCVINFO; recvv_nxtinfo return RECVV_NXTINFO; sse_type return SSE_TYPE; diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index b75dd85b..03cfa9bf 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -544,8 +544,8 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %token <reserved> SINFO_TIMETOLIVE SINFO_TSN SINFO_CUMTSN %token <reserved> PR_POLICY PR_VALUE 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 -%token <reserved> NXT_SID NXT_FLAGS NXT_PPID NXT_LENGTH +%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 %token <reserved> RECVV_RCVINFO RECVV_NXTINFO %token <reserved> SSE_TYPE SSE_FLAGS SSE_LENGTH %token <reserved> SENDER_DRY_TYPE SENDER_DRY_FLAGS SENDER_DRY_LENGTH SENDER_DRY_ASSOC_ID @@ -617,8 +617,8 @@ 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 %type <expression> sctp_prinfo sctp_authinfo pr_policy sctp_sendv_spa -%type <expression> sctp_rcvinfo rcv_sid rcv_ssn rcv_flags rcv_ppid rcv_tsn rcv_cumtsn rcv_context -%type <expression> sctp_nxtinfo nxt_sid nxt_flags nxt_ppid nxt_length sctp_recvv_rn +%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 %type <expression> sctp_sender_dry_event sender_dry_type sender_dry_flags sender_dry_length sender_dry_assoc_id %type <expression> sctp_event_subscribe @@ -2681,6 +2681,8 @@ cmsg_data : CMSG_DATA '=' sctp_initmsg { $$ = $3; } | CMSG_DATA '=' sctp_sndrcvinfo { $$ = $3; } | CMSG_DATA '=' sctp_sndinfo { $$ = $3; } +| CMSG_DATA '=' sctp_rcvinfo { $$ = $3; } +| CMSG_DATA '=' sctp_nxtinfo { $$ = $3; } | CMSG_DATA '=' sctp_prinfo { $$ = $3; } | CMSG_DATA '=' sctp_authinfo { $$ = $3; } | CMSG_DATA '=' sockaddr { $$ = $3; } @@ -3529,9 +3531,19 @@ rcv_context | RCV_CONTEXT '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } ; +rcv_assoc_id +: RCV_ASSOC_ID '=' INTEGER { + if (!is_valid_u32($3)) { + semantic_error("rcv_assoc_id out of range"); + } + $$ = new_integer_expression($3, "%u"); +} +| RCV_ASSOC_ID '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + sctp_rcvinfo -: '{' rcv_sid ',' rcv_ssn ',' rcv_flags ',' rcv_ppid ',' rcv_tsn ',' rcv_cumtsn ',' rcv_context '}' { +: '{' rcv_sid ',' rcv_ssn ',' rcv_flags ',' rcv_ppid ',' rcv_tsn ',' rcv_cumtsn ',' rcv_context ',' rcv_assoc_id'}' { $$ = new_expression(EXPR_SCTP_RCVINFO); $$->value.sctp_rcvinfo = calloc(1, sizeof(struct sctp_rcvinfo_expr)); $$->value.sctp_rcvinfo->rcv_sid = $2; @@ -3541,6 +3553,7 @@ sctp_rcvinfo $$->value.sctp_rcvinfo->rcv_tsn = $10; $$->value.sctp_rcvinfo->rcv_cumtsn = $12; $$->value.sctp_rcvinfo->rcv_context = $14; + $$->value.sctp_rcvinfo->rcv_assoc_id = $16; } ; @@ -3607,6 +3620,10 @@ nxt_flags } $$ = new_integer_expression($3, "%u"); } +| NXT_FLAGS '=' WORD { + $$ = new_expression(EXPR_WORD); + $$->value.string = $3; +} | NXT_FLAGS '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } ; @@ -3630,14 +3647,25 @@ nxt_length | NXT_LENGTH '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } ; +nxt_assoc_id +: NXT_ASSOC_ID '=' INTEGER { + if (!is_valid_u32($3)) { + semantic_error("nxt_assoc_id out of range"); + } + $$ = new_integer_expression($3, "%u"); +} +| NXT_ASSOC_ID '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + sctp_nxtinfo -: '{' nxt_sid ',' nxt_flags ',' nxt_ppid ',' nxt_length '}' { +: '{' nxt_sid ',' nxt_flags ',' nxt_ppid ',' nxt_length ',' nxt_assoc_id '}' { $$ = new_expression(EXPR_SCTP_NXTINFO); $$->value.sctp_sendv_spa = calloc(1, sizeof(struct sctp_nxtinfo_expr)); $$->value.sctp_nxtinfo->nxt_sid = $2; $$->value.sctp_nxtinfo->nxt_flags = $4; $$->value.sctp_nxtinfo->nxt_ppid = $6; $$->value.sctp_nxtinfo->nxt_length = $8; + $$->value.sctp_nxtinfo->nxt_assoc_id = $10; } ; diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c index 467b5908..5c8b2b9b 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -80,8 +80,15 @@ static int check_sctp_initmsg(struct sctp_initmsg_expr *expr, struct sctp_initms char **error); #endif #if defined(Linux) || defined(__FreeBSD__) -static int check_sctp_sndrcvinfo(struct sctp_sndrcvinfo_expr *expr, - struct sctp_sndrcvinfo *sctp_sndrcvinfo, +static int check_sctp_sndrcvinfo(struct sctp_sndrcvinfo_expr *expr, struct sctp_sndrcvinfo *sctp_sndrcvinfo, + char** error); +#endif +#if defined(Linux) || defined(__FreeBSD__) +static int check_sctp_rcvinfo(struct sctp_rcvinfo_expr *expr, struct sctp_rcvinfo *sctp_rcvinfo, + char** error); +#endif +#if defined(Linux) || defined(__FreeBSD__) +static int check_sctp_nxtinfo(struct sctp_nxtinfo_expr *expr, struct sctp_nxtinfo *sctp_nxtinfo, char** error); #endif @@ -728,6 +735,16 @@ static int cmsg_new(struct expression *expression, cmsg_size += CMSG_SPACE(sizeof(struct sctp_sndinfo)); break; #endif +#if defined(SCTP_RCVINFO) + case EXPR_SCTP_RCVINFO: + cmsg_size += CMSG_SPACE(sizeof(struct sctp_rcvinfo)); + break; +#endif +#if defined(SCTP_NXTINFO) + case EXPR_SCTP_NXTINFO: + cmsg_size += CMSG_SPACE(sizeof(struct sctp_nxtinfo)); + break; +#endif #if defined(SCTP_PRINFO) case EXPR_SCTP_PRINFO: cmsg_size += CMSG_SPACE(sizeof(struct sctp_prinfo)); @@ -806,6 +823,16 @@ static int cmsg_new(struct expression *expression, break; } #endif +#if defined(SCTP_RCVINFO) + case EXPR_SCTP_RCVINFO: + cmsg = (struct cmsghdr *) ((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_rcvinfo))); + break; +#endif +#if defined(SCTP_NXTINFO) + case EXPR_SCTP_NXTINFO: + cmsg = (struct cmsghdr *) ((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_nxtinfo))); + break; +#endif #if defined(SCTP_PRINFO) case EXPR_SCTP_PRINFO: { struct sctp_prinfo info; @@ -853,6 +880,143 @@ error_out: *cmsg_len_ptr = 0; return STATUS_ERR; } +static int check_cmsghdr(struct expression *expr_list, struct msghdr *msg, char **error) { + struct expression_list *list; + struct expression *cmsg_expr; + struct cmsghdr *cmsg_ptr; + int cnt = 0; + + assert(expr_list->type == EXPR_LIST); + + list = expr_list->value.list; + for (cmsg_ptr = CMSG_FIRSTHDR(msg); cmsg_ptr != NULL; cmsg_ptr = CMSG_NXTHDR(msg, cmsg_ptr)) { + cmsg_expr = get_arg(list, cnt, error); + if (cmsg_expr->type != EXPR_ELLIPSIS) { + struct cmsghdr_expr *expr; + expr = cmsg_expr->value.cmsghdr; + if (check_u32_expr(expr->cmsg_len, cmsg_ptr->cmsg_len, + "cmsghdr.cmsg_len", error)) + return STATUS_ERR; + if (check_s32_expr(expr->cmsg_level, cmsg_ptr->cmsg_level, + "cmsghdr.cmsg_level", error)) + return STATUS_ERR; + if (check_s32_expr(expr->cmsg_type, cmsg_ptr->cmsg_type, + "cmsghdr.cmsg_type", error)) + return STATUS_ERR; + + if (expr->cmsg_data->type == EXPR_ELLIPSIS) { + continue; + } + switch(cmsg_ptr->cmsg_type) { +#ifdef SCTP_INIT + case SCTP_INIT: + if (check_sctp_initmsg(expr->cmsg_data->value.sctp_initmsg, + (struct sctp_initmsg *) CMSG_DATA(cmsg_ptr), + error)) { + return STATUS_ERR; + } + break; +#endif +#ifdef SCTP_SNDRCV + case SCTP_SNDRCV: + if (check_sctp_sndrcvinfo(expr->cmsg_data->value.sctp_sndrcvinfo, + (struct sctp_sndrcvinfo *) CMSG_DATA(cmsg_ptr), + error)) { + return STATUS_ERR; + } + break; +#endif +#ifdef SCTP_SNDINFO + case SCTP_SNDINFO: + if (check_sctp_sndinfo(expr->cmsg_data->value.sctp_sndinfo, + (struct sctp_sndinfo *) CMSG_DATA(cmsg_ptr), + error)) { + return STATUS_ERR; + } + break; +#endif +#ifdef SCTP_RCVINFO + case SCTP_RCVINFO: + if (check_sctp_rcvinfo(expr->cmsg_data->value.sctp_rcvinfo, + (struct sctp_rcvinfo *) CMSG_DATA(cmsg_ptr), + error)) { + return STATUS_ERR; + } + break; +#endif +#ifdef SCTP_NXTINFO + case SCTP_NXTINFO: + if (check_sctp_nxtinfo(expr->cmsg_data->value.sctp_nxtinfo, + (struct sctp_nxtinfo *) CMSG_DATA(cmsg_ptr), + error)) { + return STATUS_ERR; + } + break; +#endif +#ifdef SCTP_PRINFO + case SCTP_PRINFO: + if (check_u16_expr(expr->cmsg_data->value.sctp_prinfo->pr_policy, + ((struct sctp_prinfo *)CMSG_DATA(cmsg_ptr))->pr_policy, + "prinfo.pr_policy", error)) { + return STATUS_ERR; + } + if (check_u32_expr(expr->cmsg_data->value.sctp_prinfo->pr_value, + ((struct sctp_prinfo *)CMSG_DATA(cmsg_ptr))->pr_value, + "prinfo.pr_value", error)) { + return STATUS_ERR; + } + break; +#endif +#ifdef SCTP_AUTHINFO + case SCTP_AUTHINFO: + if (check_u16_expr(expr->cmsg_data->value.sctp_authinfo->auth_keynumber, + ((struct sctp_authinfo *)CMSG_DATA(cmsg_ptr))->auth_keynumber, + "authinfo.auth_keynumber", error)) { + return STATUS_ERR; + } + break; +#endif +#ifdef SCTP_DSTADDRV4 + case SCTP_DSTADDRV4: + if (expr->cmsg_data->type != EXPR_ELLIPSIS) { + struct sockaddr_in *addr = expr->cmsg_data->value.socket_address_ipv4; + struct in_addr *cmsg_addr = (struct in_addr *) CMSG_DATA(cmsg_ptr); + if (addr->sin_addr.s_addr != cmsg_addr->s_addr) { + asprintf(error, "cmsg_data for SCTP_DSTADDRV4: expected: %s actual: %s", + inet_ntoa(addr->sin_addr), + inet_ntoa(*cmsg_addr)); + return STATUS_ERR; + } + } + break; +#endif +#ifdef SCTP_DSTADDRV6 + case SCTP_DSTADDRV6: + if (expr->cmsg_data->type != EXPR_ELLIPSIS) { + struct sockaddr_in6 *addr = expr->cmsg_data->value.socket_address_ipv6; + struct in6_addr *cmsg_addr = (struct in6_addr *) CMSG_DATA(cmsg_ptr); + if (memcmp(&addr->sin6_addr, cmsg_addr, sizeof(struct in6_addr))) { + char expected_addr[INET6_ADDRSTRLEN]; + char live_addr[INET6_ADDRSTRLEN]; + inet_ntop(AF_INET6, &addr->sin6_addr, expected_addr, INET6_ADDRSTRLEN); + inet_ntop(AF_INET6, cmsg_addr, live_addr, INET6_ADDRSTRLEN); + asprintf(error, "sockaddr_in6 from.sin6_addr. expected: %s actual %s", + expected_addr, live_addr); + return STATUS_ERR; + } + } + break; +#endif + default: + asprintf(error, "can't check cmsg type"); + return STATUS_ERR; + } + } + cnt++; + } + return STATUS_OK; +} + /* Free all the space used by the given msghdr. */ static void msghdr_free(struct msghdr *msg, size_t iov_len) @@ -1796,7 +1960,7 @@ static int syscall_recvmsg(struct state *state, struct syscall_spec *syscall, goto error_out; } #endif - status = STATUS_OK; + status = check_cmsghdr(msg_expression->value.msghdr->msg_control, msg, error); error_out: msghdr_free(msg, iov_len); @@ -1948,125 +2112,6 @@ static int syscall_sendto(struct state *state, struct syscall_spec *syscall, return status; } -static int check_cmsghdr(struct expression *expr_list, struct msghdr *msg, char **error) { - struct expression_list *list; - struct expression *cmsg_expr; - struct cmsghdr *cmsg_ptr; - int cnt = 0; - - assert(expr_list->type == EXPR_LIST); - - list = expr_list->value.list; - for (cmsg_ptr = CMSG_FIRSTHDR(msg); cmsg_ptr != NULL; cmsg_ptr = CMSG_NXTHDR(msg, cmsg_ptr)) { - cmsg_expr = get_arg(list, cnt, error); - if (cmsg_expr->type != EXPR_ELLIPSIS) { - struct cmsghdr_expr *expr; - expr = cmsg_expr->value.cmsghdr; - if (check_u32_expr(expr->cmsg_len, cmsg_ptr->cmsg_len, - "cmsghdr.cmsg_len", error)) - return STATUS_ERR; - if (check_s32_expr(expr->cmsg_level, cmsg_ptr->cmsg_level, - "cmsghdr.cmsg_level", error)) - return STATUS_ERR; - if (check_s32_expr(expr->cmsg_type, cmsg_ptr->cmsg_type, - "cmsghdr.cmsg_type", error)) - return STATUS_ERR; - - if (expr->cmsg_data->type == EXPR_ELLIPSIS) { - continue; - } - switch(cmsg_ptr->cmsg_type) { -#ifdef SCTP_INIT - case SCTP_INIT: - if (check_sctp_initmsg(expr->cmsg_data->value.sctp_initmsg, - (struct sctp_initmsg *) CMSG_DATA(cmsg_ptr), - error)) { - return STATUS_ERR; - } - break; -#endif -#ifdef SCTP_SNDRCV - case SCTP_SNDRCV: - if (check_sctp_sndrcvinfo(expr->cmsg_data->value.sctp_sndrcvinfo, - (struct sctp_sndrcvinfo *) CMSG_DATA(cmsg_ptr), - error)) { - return STATUS_ERR; - } - break; -#endif -#ifdef SCTP_SNDINFO - case SCTP_SNDINFO: - if (check_sctp_sndinfo(expr->cmsg_data->value.sctp_sndinfo, - (struct sctp_sndinfo *) CMSG_DATA(cmsg_ptr), - error)) { - return STATUS_ERR; - } - break; -#endif -#ifdef SCTP_PRINFO - case SCTP_PRINFO: - if (check_u16_expr(expr->cmsg_data->value.sctp_prinfo->pr_policy, - ((struct sctp_prinfo *)CMSG_DATA(cmsg_ptr))->pr_policy, - "prinfo.pr_policy", error)) { - return STATUS_ERR; - } - if (check_u32_expr(expr->cmsg_data->value.sctp_prinfo->pr_value, - ((struct sctp_prinfo *)CMSG_DATA(cmsg_ptr))->pr_value, - "prinfo.pr_value", error)) { - return STATUS_ERR; - } - break; -#endif -#ifdef SCTP_AUTHINFO - case SCTP_AUTHINFO: - if (check_u16_expr(expr->cmsg_data->value.sctp_authinfo->auth_keynumber, - ((struct sctp_authinfo *)CMSG_DATA(cmsg_ptr))->auth_keynumber, - "authinfo.auth_keynumber", error)) { - return STATUS_ERR; - } - break; -#endif -#ifdef SCTP_DSTADDRV4 - case SCTP_DSTADDRV4: - if (expr->cmsg_data->type != EXPR_ELLIPSIS) { - struct sockaddr_in *addr = expr->cmsg_data->value.socket_address_ipv4; - struct in_addr *cmsg_addr = (struct in_addr *) CMSG_DATA(cmsg_ptr); - if (addr->sin_addr.s_addr != cmsg_addr->s_addr) { - asprintf(error, "cmsg_data for SCTP_DSTADDRV4: expected: %s actual: %s", - inet_ntoa(addr->sin_addr), - inet_ntoa(*cmsg_addr)); - return STATUS_ERR; - } - } - break; -#endif -#ifdef SCTP_DSTADDRV6 - case SCTP_DSTADDRV6: - if (expr->cmsg_data->type != EXPR_ELLIPSIS) { - struct sockaddr_in6 *addr = expr->cmsg_data->value.socket_address_ipv6; - struct in6_addr *cmsg_addr = (struct in6_addr *) CMSG_DATA(cmsg_ptr); - if (memcmp(&addr->sin6_addr, cmsg_addr, sizeof(struct in6_addr))) { - char expected_addr[INET6_ADDRSTRLEN]; - char live_addr[INET6_ADDRSTRLEN]; - inet_ntop(AF_INET6, &addr->sin6_addr, expected_addr, INET6_ADDRSTRLEN); - inet_ntop(AF_INET6, cmsg_addr, live_addr, INET6_ADDRSTRLEN); - asprintf(error, "sockaddr_in6 from.sin6_addr. expected: %s actual %s", - expected_addr, live_addr); - return STATUS_ERR; - } - } - break; -#endif - default: - asprintf(error, "can't check cmsg type"); - return STATUS_ERR; - } - } - cnt++; - } - return STATUS_OK; -} - static int syscall_sendmsg(struct state *state, struct syscall_spec *syscall, struct expression_list *args, char **error) { @@ -3749,6 +3794,9 @@ static int check_sctp_rcvinfo(struct sctp_rcvinfo_expr *expr, if (check_u32_expr(expr->rcv_context, sctp_rcvinfo->rcv_context, "sctp_rcvinfo.rcv_context", error)) return STATUS_ERR; + if (check_u32_expr(expr->rcv_assoc_id, sctp_rcvinfo->rcv_assoc_id, + "sctp_rcvinfo.rcv_assoc_id", error)) + return STATUS_ERR; return STATUS_OK; } @@ -3777,6 +3825,8 @@ static int check_sctp_nxtinfo(struct sctp_nxtinfo_expr *expr, } if (check_u32_expr(expr->nxt_length, sctp_nxtinfo->nxt_length, "sctp_nxtinfo.nxt_length", error)) return STATUS_ERR; + if (check_u32_expr(expr->nxt_assoc_id, sctp_nxtinfo->nxt_assoc_id, "sctp_nxtinfo.nxt_assoc_id", error)) + return STATUS_ERR; return STATUS_OK; } diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c index 4508038f..2073a5ed 100644 --- a/gtests/net/packetdrill/script.c +++ b/gtests/net/packetdrill/script.c @@ -432,12 +432,14 @@ void free_expression(struct expression *expression) free_expression(expression->value.sctp_rcvinfo->rcv_tsn); free_expression(expression->value.sctp_rcvinfo->rcv_cumtsn); free_expression(expression->value.sctp_rcvinfo->rcv_context); + free_expression(expression->value.sctp_rcvinfo->rcv_assoc_id); break; case EXPR_SCTP_NXTINFO: free_expression(expression->value.sctp_nxtinfo->nxt_sid); free_expression(expression->value.sctp_nxtinfo->nxt_flags); free_expression(expression->value.sctp_nxtinfo->nxt_ppid); free_expression(expression->value.sctp_nxtinfo->nxt_length); + free_expression(expression->value.sctp_nxtinfo->nxt_assoc_id); break; case EXPR_SCTP_RECVV_RN: free_expression(expression->value.sctp_recvv_rn->recvv_rcvinfo); @@ -1420,6 +1422,10 @@ static int evaluate_sctp_rcvinfo_expression(struct expression *in, &out_info->rcv_context, error)) return STATUS_ERR; + if (evaluate(in_info->rcv_assoc_id, + &out_info->rcv_assoc_id, + error)) + return STATUS_ERR; return STATUS_OK; } @@ -1456,6 +1462,10 @@ static int evaluate_sctp_nxtinfo_expression(struct expression *in, &out_info->nxt_length, error)) return STATUS_ERR; + if (evaluate(in_info->nxt_assoc_id, + &out_info->nxt_assoc_id, + error)) + return STATUS_ERR; return STATUS_OK; } diff --git a/gtests/net/packetdrill/script.h b/gtests/net/packetdrill/script.h index 3a9942d5..f14ce435 100644 --- a/gtests/net/packetdrill/script.h +++ b/gtests/net/packetdrill/script.h @@ -335,6 +335,7 @@ struct sctp_rcvinfo_expr { struct expression *rcv_tsn; struct expression *rcv_cumtsn; struct expression *rcv_context; + struct expression *rcv_assoc_id; }; /* Parse tree for sctp_nxtinfo in sctp_recvv syscall. */ @@ -343,6 +344,7 @@ struct sctp_nxtinfo_expr { struct expression *nxt_flags; struct expression *nxt_ppid; struct expression *nxt_length; + struct expression *nxt_assoc_id; }; /* Parse tree for sctp_recvv_rn in sctp_recvv syscall. */ diff --git a/gtests/net/packetdrill/symbols_freebsd.c b/gtests/net/packetdrill/symbols_freebsd.c index 135d9e19..d4907b7f 100644 --- a/gtests/net/packetdrill/symbols_freebsd.c +++ b/gtests/net/packetdrill/symbols_freebsd.c @@ -182,6 +182,7 @@ struct int_symbol platform_symbols_table[] = { { SCTP_STREAM_CHANGE_EVENT, "SCTP_STREAM_CHANGE_EVENT" }, { SCTP_SEND_FAILED_EVENT, "SCTP_SEND_FAILED_EVENT" }, { SCTP_UNORDERED, "SCTP_UNORDERED" }, + { SCTP_COMPLETE, "SCTP_COMPLETE" }, { SCTP_ADDR_OVER, "SCTP_ADDR_OVER" }, { SCTP_ABORT, "SCTP_ABORT" }, { SCTP_EOF, "SCTP_EOF" }, @@ -224,6 +225,8 @@ struct int_symbol platform_symbols_table[] = { { SCTP_ADDR_MADE_PRIM, "SCTP_ADDR_MADE_PRIM" }, { SCTP_SNDRCV, "SCTP_SNDRCV" }, { SCTP_SNDINFO, "SCTP_SNDINFO" }, + { SCTP_RCVINFO, "SCTP_RCVINFO" }, + { SCTP_NXTINFO, "SCTP_NXTINFO" }, { SCTP_PRINFO, "SCTP_PRINFO" }, { SCTP_AUTHINFO, "SCTP_AUTHINFO" }, { SCTP_DSTADDRV4, "SCTP_DSTADDRV4" }, diff --git a/gtests/net/packetdrill/tests/bsd/sctp/recvmsg.pkt b/gtests/net/packetdrill/tests/bsd/sctp/recvmsg.pkt new file mode 100644 index 00000000..a991b0b3 --- /dev/null +++ b/gtests/net/packetdrill/tests/bsd/sctp/recvmsg.pkt @@ -0,0 +1,54 @@ +--tolerance_usecs=100000 + + 0.0 socket(..., SOCK_STREAM, IPPROTO_SCTP) = 3 ++0.0 fcntl(3, F_GETFL) = 0x2 (flags O_RDWR) ++0.0 fcntl(3, F_SETFL, O_RDWR|O_NONBLOCK) = 0 ++0.0 bind(3, ..., ...) = 0 +// Check the handshake with an empty(!) cookie ++0.1 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress) ++0.0 > sctp: INIT[flgs=0, tag=1, a_rwnd=..., os=..., is=..., tsn=1, ...] ++0.1 < sctp: INIT_ACK[flgs=0, tag=2, a_rwnd=1500, os=16, is=16, tsn=1, STATE_COOKIE[len=4, val=...]] ++0.0 > sctp: COOKIE_ECHO[flgs=0, len=4, val=...] ++0.1 < sctp: COOKIE_ACK[flgs=0] ++0.0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 +//recvmsg(sd, msghdr, flags) + ++0.0 setsockopt(3, IPPROTO_SCTP, SCTP_PEER_ADDR_PARAMS, {spp_address={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")}, +spp_hbinterval=0, spp_pathmaxrxt=8, spp_pathmtu=1468, spp_flags=SPP_HB_DISABLE, spp_ipv6_flowlabel=0, spp_dscp=0}, 152) = 0 + +//base test ++0.0 < sctp: DATA[flgs=BE, len=1016, tsn=1, sid=0, ssn=0, ppid=0] +* > sctp: SACK[flgs=0, cum_tsn=1, a_rwnd=..., gaps=[], dups=[]] ++1.0 recvmsg(3, {msg_name(...)=..., msg_iov(1)=[{iov_base=..., iov_len=1000}], msg_control(0)=[], msg_flags=MSG_EOR}, 0) = 1000 + ++0.0 setsockopt(3, IPPROTO_SCTP, SCTP_RECVRCVINFO, [1], 4) = 0 ++0.0 setsockopt(3, IPPROTO_SCTP, SCTP_RECVNXTINFO, [0], 4) = 0 ++0.0 < sctp: DATA[flgs=BE, len=1016, tsn=2, sid=0, ssn=1, ppid=0] +* > sctp: SACK[flgs=0, cum_tsn=2, a_rwnd=..., gaps=[], dups=[]] ++0.0 recvmsg(3, {msg_name(...)=..., msg_iov(1)=[{iov_base=..., iov_len=1000}], msg_control(40)= + [{cmsg_len=40, cmsg_level=IPPROTO_SCTP, cmsg_type=SCTP_RCVINFO, cmsg_data= + {rcv_sid=0, rcv_ssn=1, rcv_flags=0, rcv_ppid=htonl(0), rcv_tsn=2, rcv_cumtsn=2, rcv_context=0, rcv_assoc_id=...} + }], + msg_flags=MSG_EOR}, 0) = 1000 + ++0.0 setsockopt(3, IPPROTO_SCTP, SCTP_RECVRCVINFO, [0], 4) = 0 ++0.0 setsockopt(3, IPPROTO_SCTP, SCTP_RECVNXTINFO, [1], 4) = 0 ++0.0 < sctp: DATA[flgs=BE, len=1016, tsn=3, sid=0, ssn=2, ppid=0] +* > sctp: SACK[flgs=0, cum_tsn=3, a_rwnd=..., gaps=[], dups=[]] ++0.0 < sctp: DATA[flgs=BE, len=1016, tsn=4, sid=0, ssn=3, ppid=1234] +* > sctp: SACK[flgs=0, cum_tsn=4, a_rwnd=..., gaps=[], dups=[]] ++0.0 recvmsg(3, {msg_name(...)=..., msg_iov(1)=[{iov_base=..., iov_len=1000}],msg_control(28)= + [{cmsg_len=28, cmsg_level=IPPROTO_SCTP, cmsg_type=SCTP_NXTINFO, cmsg_data= + {nxt_sid=0, nxt_flags=SCTP_COMPLETE, nxt_ppid=htonl(1234), nxt_length=1000, nxt_assoc_id=3} + }] ,msg_flags=MSG_EOR}, 0) = 1000 + ++0.0 setsockopt(3, IPPROTO_SCTP, SCTP_RECVRCVINFO, [1], 4) = 0 ++0.0 setsockopt(3, IPPROTO_SCTP, SCTP_RECVNXTINFO, [1], 4) = 0 ++0.0 < sctp: DATA[flgs=BE, len=1016, tsn=5, sid=0, ssn=4, ppid=9876] +* > sctp: SACK[flgs=0, cum_tsn=5, a_rwnd=..., gaps=[], dups=[]] ++0.0 recvmsg(3, {msg_name(...)=..., msg_iov(1)=[{iov_base=..., iov_len=1000}],msg_control(68)= + [{cmsg_len=40, cmsg_level=IPPROTO_SCTP, cmsg_type=SCTP_RCVINFO, cmsg_data= + {rcv_sid=0, rcv_ssn=3, rcv_flags=0, rcv_ppid=htonl(1234), rcv_tsn=4, rcv_cumtsn=5, rcv_context=0, rcv_assoc_id=...}}, + {cmsg_len=28, cmsg_level=IPPROTO_SCTP, cmsg_type=SCTP_NXTINFO, cmsg_data= + {nxt_sid=0, nxt_flags=SCTP_COMPLETE, nxt_ppid=htonl(9876), nxt_length=1000, nxt_assoc_id=3} + }] ,msg_flags=MSG_EOR}, 0) = 1000 -- GitLab