diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index 5179907b893c25b9cac2f4b4614a5e57207cd101..acfd944b311b8f8aed1e7474226fa38a85438881 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -319,6 +319,7 @@ staleness return STALENESS; param return PARAM; chk return CHK; bad_crc32c return BAD_CRC32C; +NULL return NULL_; --[a-zA-Z0-9_]+ yylval.string = option(yytext); return OPTION; [-]?[0-9]*[.][0-9]+ yylval.floating = atof(yytext); return FLOAT; [-]?[0-9]+ yylval.integer = atoll(yytext); return INTEGER; diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index 606070435535d84f480475a8212363b8280da29a..3bf683e7eb81fd8900e8f22cac7409de6391a3e3 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -538,7 +538,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %token <reserved> SASOC_ASOCMAXRXT SASOC_NUMBER_PEER_DESTINATIONS SASOC_PEER_RWND %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 <reserved> BAD_CRC32C +%token <reserved> BAD_CRC32C NULL_ %token <floating> FLOAT %token <integer> INTEGER HEX_INTEGER %token <string> WORD STRING BACK_QUOTED CODE IPV4_ADDR IPV6_ADDR @@ -588,7 +588,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %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 <expression> sctp_event se_type se_on sctp_setadaptation null %type <errno_info> opt_errno %type <chunk_list> sctp_chunk_list_spec %type <chunk_list_item> sctp_chunk_spec @@ -2398,6 +2398,9 @@ expression | sctp_setadaptation{ $$ = $1; } +| null { + $$ = $1; +} ; decimal_integer @@ -3059,16 +3062,12 @@ snd_context 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_expr)); $$->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 @@ -3121,3 +3120,8 @@ code_spec } ; +null +: NULL_ { + $$ = new_expression(EXPR_NULL); +} +; diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c index 2b7ba1aa5cdd2f656e1ffbdbcc4ab00df422ca12..6162e510fbb4d806d852f5fcf36363d8a53e19f4 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -2977,7 +2977,8 @@ static int syscall_sctp_sendmsg(struct state *state, struct syscall_spec *syscal int result, script_fd, live_fd, len; void *msg = NULL; struct sockaddr_storage to; - socklen_t tolen; + struct sockaddr_storage *to_ptr = &to; + socklen_t tolen = 0; u32 ppid, flags, timetolive, context; u16 stream_no; struct expression *sockaddr_expr, *tolen_expr, *ppid_expr, *flags_expr, *ttl_expr, *stream_no_expr, *context_expr; @@ -2995,20 +2996,29 @@ static int syscall_sctp_sendmsg(struct state *state, struct syscall_spec *syscal sockaddr_expr = get_arg(args, 3, error); if (sockaddr_expr->type == EXPR_ELLIPSIS) { socklen_t len = (socklen_t)sizeof(struct sockaddr_storage); - if (getpeername(live_fd, (struct sockaddr *)&to, &len)) { + if (getpeername(live_fd, (struct sockaddr *)to_ptr, &len)) { return STATUS_ERR; } tolen = len; - } else if (sockaddr_expr->type == EXPR_SOCKET_ADDRESS_IPV4) { - memcpy(&to, sockaddr_expr->value.socket_address_ipv4, sizeof(struct sockaddr_in)); - } else if (sockaddr_expr->type == EXPR_SOCKET_ADDRESS_IPV6) { - memcpy(&to, sockaddr_expr->value.socket_address_ipv6, sizeof(struct sockaddr_in6)); + } else if (sockaddr_expr->type == EXPR_NULL) { + to_ptr = NULL; + tolen = 0; + } else { + if (sockaddr_expr->type == EXPR_SOCKET_ADDRESS_IPV4) { + memcpy(to_ptr, sockaddr_expr->value.socket_address_ipv4, sizeof(struct sockaddr_in)); + tolen = sizeof(struct sockaddr_in); + } else if (sockaddr_expr->type == EXPR_SOCKET_ADDRESS_IPV6) { + memcpy(to_ptr, sockaddr_expr->value.socket_address_ipv6, sizeof(struct sockaddr_in6)); + tolen = sizeof(struct sockaddr_in6); + } else { + asprintf(error, "Bad input for reciever in sctp_sentmsg"); + return STATUS_ERR; + } } - tolen_expr = get_arg(args, 4, error); - if (!(tolen_expr->type == EXPR_ELLIPSIS && sockaddr_expr->type == EXPR_ELLIPSIS)) { + tolen_expr = get_arg(args, 4, error); + if (tolen_expr->type != EXPR_ELLIPSIS) if (get_u32(tolen_expr, &tolen, error)) return STATUS_ERR; - } ppid_expr = get_arg(args, 5, error); if (get_u32(ppid_expr, &ppid, error)) return STATUS_ERR; @@ -3024,19 +3034,19 @@ static int syscall_sctp_sendmsg(struct state *state, struct syscall_spec *syscal context_expr = get_arg(args, 9, error); if (get_u32(context_expr, &context, error)) return STATUS_ERR; + sockaddr_expr = get_arg(args, 3, error); msg = calloc(len, 1); assert(msg != NULL); begin_syscall(state, syscall); - result = sctp_sendmsg(live_fd, msg, (size_t)len, (struct sockaddr*) &to, + result = sctp_sendmsg(live_fd, msg, (size_t)len, (struct sockaddr*) to_ptr, tolen, ppid, flags, stream_no, timetolive, context); if (end_syscall(state, syscall, CHECK_EXACT, result, error)) { free(msg); return STATUS_ERR; } - free(msg); return STATUS_OK; } diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c index 5c07f3ee5053bf66edcf3a688dba82a8c9bb82dd..3ff2b5224e52641cab0bbd266ed68f94def3ad0a 100644 --- a/gtests/net/packetdrill/script.c +++ b/gtests/net/packetdrill/script.c @@ -53,6 +53,7 @@ struct expression_type_entry { }; struct expression_type_entry expression_type_table[] = { { EXPR_NONE, "none" }, + { EXPR_NULL, "null" }, { EXPR_ELLIPSIS, "ellipsis" }, { EXPR_INTEGER, "integer" }, { EXPR_WORD, "word" }, @@ -280,6 +281,7 @@ void free_expression(struct expression *expression) (expression->type >= NUM_EXPR_TYPES)) assert(!"bad expression type"); switch (expression->type) { + case EXPR_NULL: case EXPR_ELLIPSIS: case EXPR_INTEGER: break; @@ -980,6 +982,8 @@ static int evaluate(struct expression *in, return STATUS_ERR; } switch (in->type) { + case EXPR_NULL: + break; case EXPR_ELLIPSIS: break; case EXPR_INTEGER: /* copy as-is */ diff --git a/gtests/net/packetdrill/script.h b/gtests/net/packetdrill/script.h index c614f9d7053d8e3363e8b3bbe254f2f84cc362fd..f98d43e26d3da99d2aea01a974d360c2e4a97b1b 100644 --- a/gtests/net/packetdrill/script.h +++ b/gtests/net/packetdrill/script.h @@ -33,6 +33,7 @@ /* The types of expressions in a script */ enum expression_t { EXPR_NONE, + EXPR_NULL, /* Expression to handle NULL */ EXPR_ELLIPSIS, /* ... but no value */ EXPR_INTEGER, /* integer in 'num' */ EXPR_LINGER, /* struct linger for SO_LINGER */ diff --git a/gtests/net/packetdrill/tests/bsd/sctp/sctp_sendmsg.pkt b/gtests/net/packetdrill/tests/bsd/sctp/sctp_sendmsg.pkt index ca3d8d6b0b0d691c611db901c55a51574c07097b..e9d6ec47dddfe82400ecb61c1122c941fe843ec9 100644 --- a/gtests/net/packetdrill/tests/bsd/sctp/sctp_sendmsg.pkt +++ b/gtests/net/packetdrill/tests/bsd/sctp/sctp_sendmsg.pkt @@ -8,7 +8,6 @@ +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 -// Tear down the association //sctp_sendmsg(int sd, const void * msg, size_t len, struct sockaddr *to, socklen_t tolen, // uint32_t ppid, uint32_t flags, uint16_t stream_no, uint32_t timetolive, uint32_t context); +0.0 sctp_sendmsg(3, ..., 1000, ..., ..., 0, 0, 0, 0, 0) = 1000 @@ -17,6 +16,9 @@ +0.0 sctp_sendmsg(3, ..., 1000, {sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")}, 16, 0, 0, 0, 0, 0) = 1000 +0.0 > sctp: DATA[flgs=BE, len=1016, tsn=2, sid=0, ssn=1, ppid=0] +0.0 < sctp: SACK[flgs=0, cum_tsn=2, a_rwnd=1500, gaps=[], dups=[]] ++0.0 sctp_sendmsg(3, ..., 1000, NULL, 0, 0, 0, 0, 0, 0) = 1000 ++0.0 > sctp: DATA[flgs=BE, len=1016, tsn=3, sid=0, ssn=2, ppid=0] ++0.0 < sctp: SACK[flgs=0, cum_tsn=3, a_rwnd=1500, gaps=[], dups=[]] +0.0 close(3) = 0 +0.0 > sctp: SHUTDOWN[flgs=0, cum_tsn=0] +0.1 < sctp: SHUTDOWN_ACK[flgs=0]