diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index 5cebb2f7756b4b2a022ceaa3201d2958e1ef38b6..bca3df3b2360ed450acebdffd7ed10c5a8436cfd 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -171,6 +171,7 @@ revents return REVENTS; onoff return ONOFF; linger return LINGER; htons return _HTONS_; +htonl return _HTONL_; ipv4 return IPV4; ipv6 return IPV6; icmp return ICMP; diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index 8bee0f81aa97f7bd91244558eb7cb9525bf28a02..d6ce691cc26dd4925893a8914185cbff69baa88e 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -493,7 +493,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, * have ALL_CAPS names, and nonterminal symbols have lower_case names. */ %token ELLIPSIS -%token <reserved> SA_FAMILY SIN_PORT SIN_ADDR _HTONS_ INET_ADDR +%token <reserved> SA_FAMILY SIN_PORT SIN_ADDR _HTONS_ _HTONL_ INET_ADDR %token <reserved> MSG_NAME MSG_IOV MSG_FLAGS %token <reserved> FD EVENTS REVENTS ONOFF LINGER %token <reserved> ACK ECR EOL MSS NOP SACK SACKOK TIMESTAMP VAL WIN WSCALE PRO @@ -591,7 +591,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %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 null -%type <expression> sctp_sndrcvinfo sinfo_stream sinfo_ssn sinfo_flags sinfo_ppid sinfo_context +%type <expression> sctp_sndrcvinfo sinfo_stream sinfo_ssn sinfo_flags sinfo_ppid sinfo_context %type <expression> sinfo_timetolive sinfo_tsn sinfo_cumtsn %type <errno_info> opt_errno %type <chunk_list> sctp_chunk_list_spec @@ -1328,6 +1328,12 @@ opt_ppid } $$ = $3; } +| PPID '=' HEX_INTEGER { + if (!is_valid_u32($3)) { + semantic_error("ppid value out of range"); + } + $$ = $3; +} ; opt_fsn @@ -2364,6 +2370,18 @@ expression } | decimal_integer { $$ = $1; } | hex_integer { $$ = $1; } +| _HTONL_ '(' INTEGER ')' { + if (!is_valid_u32($3)) { + semantic_error("number out of range"); + } + $$ = new_integer_expression(htonl((u32)$3), "%lu"); +} +| _HTONL_ '(' HEX_INTEGER ')' { + if (!is_valid_u32($3)) { + semantic_error("number out of range"); + } + $$ = new_integer_expression(htonl((u32)$3), "%#lx"); +} | WORD { $$ = new_expression(EXPR_WORD); $$->value.string = $1; @@ -2685,26 +2703,18 @@ sctp_initmsg sctp_stream_value : '{' STREAM_ID '=' expression ',' STREAM_VALUE '=' expression '}' { -#if defined(SCTP_SS_VALUE) $$ = new_expression(EXPR_SCTP_STREAM_VALUE); $$->value.sctp_stream_value = calloc(1, sizeof(struct sctp_stream_value_expr)); $$->value.sctp_stream_value->stream_id = $4; $$->value.sctp_stream_value->stream_value = $8; -#else - $$ = NULL; -#endif } ; sctp_assoc_value : '{' ASSOC_VALUE '=' expression '}' { -#if defined(SCTP_MAXSEG) || defined(SCTP_MAX_BURST) || defined(SCTP_INTERLEAVING_SUPPORTED) $$ = new_expression(EXPR_SCTP_ASSOC_VALUE); $$->value.sctp_assoc_value = calloc(1, sizeof(struct sctp_assoc_value_expr)); $$->value.sctp_assoc_value->assoc_value = $4; -#else - $$ = NULL; -#endif } ; @@ -3084,11 +3094,11 @@ snd_flags ; snd_ppid -: SND_PPID '=' INTEGER { - if (!is_valid_u32($3)) { +: SND_PPID '=' _HTONL_ '(' INTEGER ')'{ + if (!is_valid_u32($5)) { semantic_error("snd_ppid out of range"); } - $$ = new_integer_expression($3, "%u"); + $$ = new_integer_expression(htonl((u32)$5), "%u"); } | SND_PPID '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } ; @@ -3156,11 +3166,11 @@ sinfo_flags ; sinfo_ppid -: SINFO_PPID '=' INTEGER { - if (!is_valid_u32($3)) { +: SINFO_PPID '=' _HTONL_ '(' INTEGER ')' { + if (!is_valid_u32($5)) { semantic_error("sinfo_ppid out of range"); } - $$ = new_integer_expression($3, "%u"); + $$ = new_integer_expression(htonl((u32)$5), "%u"); } | SINFO_PPID '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } ; @@ -3208,7 +3218,7 @@ sinfo_cumtsn sctp_sndrcvinfo : '{' sinfo_stream ',' sinfo_ssn ',' sinfo_flags ',' sinfo_ppid ',' sinfo_context ',' sinfo_timetolive ',' sinfo_tsn ',' sinfo_cumtsn '}' { $$ = new_expression(EXPR_SCTP_SNDRCVINFO); - $$->value.sctp_sndrcvinfo = calloc(1, sizeof(struct sctp_sndrcvinfo)); + $$->value.sctp_sndrcvinfo = calloc(1, sizeof(struct sctp_sndrcvinfo_expr)); $$->value.sctp_sndrcvinfo->sinfo_stream = $2; $$->value.sctp_sndrcvinfo->sinfo_ssn = $4; $$->value.sctp_sndrcvinfo->sinfo_flags = $6; diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c index cf947c92d4d96da00c157ed536a9dd9558937c07..10db6470af2447668cfbcbe73ba209b211ebb128 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -2974,7 +2974,7 @@ error_out: static int syscall_sctp_sendmsg(struct state *state, struct syscall_spec *syscall, struct expression_list *args, char **error) { -#if defined(__FreeBSD__) || defined(__Linux__) || defined(__NetBSD__) || defined(__OpenBSD__) +#if defined(__FreeBSD__) || defined(__Linux__) int result, script_fd, live_fd, len; void *msg = NULL; struct sockaddr_storage to; @@ -2983,7 +2983,7 @@ static int syscall_sctp_sendmsg(struct state *state, struct syscall_spec *syscal 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; - + if (check_arg_count(args, 10, error)) return STATUS_ERR; if (s32_arg(args, 0, &script_fd, error)) @@ -3012,11 +3012,11 @@ static int syscall_sctp_sendmsg(struct state *state, struct syscall_spec *syscal 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"); + asprintf(error, "Bad input for receiver in sctp_sendmsg"); return STATUS_ERR; } } - tolen_expr = get_arg(args, 4, error); + tolen_expr = get_arg(args, 4, error); if (tolen_expr->type != EXPR_ELLIPSIS) if (get_u32(tolen_expr, &tolen, error)) return STATUS_ERR; @@ -3037,10 +3037,10 @@ static int syscall_sctp_sendmsg(struct state *state, struct syscall_spec *syscal return STATUS_ERR; msg = calloc(len, 1); - assert(msg != NULL); + assert(msg != NULL); begin_syscall(state, syscall); - result = sctp_sendmsg(live_fd, msg, (size_t)len, (struct sockaddr*) to_ptr, + 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)) { @@ -3055,9 +3055,9 @@ static int syscall_sctp_sendmsg(struct state *state, struct syscall_spec *syscal #endif } -#if defined(__FreeBSD__) || defined(__Linux__) || defined(__NetBSD__) || defined(__OpenBSD__) +#if defined(__FreeBSD__) || defined(__Linux__) static int check_sctp_sndrcvinfo(struct sctp_sndrcvinfo_expr *expr, - struct sctp_sndrcvinfo *sctp_sndrcvinfo, + struct sctp_sndrcvinfo *sctp_sndrcvinfo, char** error) { if (expr->sinfo_stream->type != EXPR_ELLIPSIS) { u16 sinfo_stream; @@ -3101,9 +3101,9 @@ static int check_sctp_sndrcvinfo(struct sctp_sndrcvinfo_expr *expr, if (get_u32(expr->sinfo_ppid, &sinfo_ppid, error)) { return STATUS_ERR; } - if (sctp_sndrcvinfo->sinfo_ppid != sinfo_ppid) { + if (ntohl(sctp_sndrcvinfo->sinfo_ppid) != ntohl(sinfo_ppid)) { asprintf(error, "sctp_sndrcvinfo.sinfo_ppid: expected: %u actual: %u", - sinfo_ppid, sctp_sndrcvinfo->sinfo_ppid); + ntohl(sinfo_ppid), ntohl(sctp_sndrcvinfo->sinfo_ppid)); return STATUS_ERR; } } @@ -3163,7 +3163,7 @@ static int syscall_sctp_recvmsg(struct state *state, struct syscall_spec *syscal struct expression_list *args, char **error) { -#if defined(__FreeBSD__) || defined(__Linux__) || defined(__NetBSD__) || defined(__OpenBSD__) +#if defined(__FreeBSD__) || defined(__Linux__) int script_fd, live_fd, live_msg_flags, result; void *msg; u32 len; @@ -3192,7 +3192,7 @@ static int syscall_sctp_recvmsg(struct state *state, struct syscall_spec *syscal result = sctp_recvmsg(live_fd, msg, len, (struct sockaddr*) &live_from, &live_fromlen, &live_sinfo, &live_msg_flags); free(msg); - + if (end_syscall(state, syscall, CHECK_EXACT, result, error)) { return STATUS_ERR; } @@ -3206,7 +3206,7 @@ static int syscall_sctp_recvmsg(struct state *state, struct syscall_spec *syscal script_addr = (struct sockaddr*)script_from_expr->value.socket_address_ipv6; } else { asprintf(error, "sctp_recvmsg fromlen: can't check sctp_recvmsg from"); - return STATUS_ERR; + return STATUS_ERR; } if (script_addr->sa_family != live_from.sa_family) { asprintf(error, "sctp_recvmsg from.sa_family: expected: %d actual: %d", @@ -3214,7 +3214,7 @@ static int syscall_sctp_recvmsg(struct state *state, struct syscall_spec *syscal return STATUS_ERR; } switch(script_addr->sa_family) { - case AF_INET: + case AF_INET: { struct sockaddr_in *script_sockaddr = (struct sockaddr_in*)script_addr; struct sockaddr_in *live_sockaddr = (struct sockaddr_in*)&live_from; @@ -3234,7 +3234,7 @@ static int syscall_sctp_recvmsg(struct state *state, struct syscall_spec *syscal } } break; - case AF_INET6: + case AF_INET6: { struct sockaddr_in6 *script_sockaddr = (struct sockaddr_in6*)script_addr; struct sockaddr_in6 *live_sockaddr = (struct sockaddr_in6*)&live_from; diff --git a/gtests/net/packetdrill/tests/bsd/sctp/sctp_recvmsg.pkt b/gtests/net/packetdrill/tests/bsd/sctp/sctp_recvmsg.pkt index c4df402369587dea4affade5c2f9b9af31b14d48..c972405b33548d46192ae443bcff7d2f8007cbda 100644 --- a/gtests/net/packetdrill/tests/bsd/sctp/sctp_recvmsg.pkt +++ b/gtests/net/packetdrill/tests/bsd/sctp/sctp_recvmsg.pkt @@ -1,6 +1,7 @@ +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, ...] @@ -14,15 +15,14 @@ * > sctp: SACK[flgs=0, cum_tsn=1, a_rwnd=..., gaps=[], dups=[]] +0.0 sctp_recvmsg(3, ..., 1000, ..., ..., ..., 8) = 1000 -+0.0 < sctp: DATA[flgs=BE, len=1016, tsn=2, sid=0, ssn=1, ppid=0] ++0.0 < sctp: DATA[flgs=BE, len=1016, tsn=2, sid=0, ssn=1, ppid=1234] * > sctp: SACK[flgs=0, cum_tsn=2, a_rwnd=..., gaps=[], dups=[]] -+0.0 sctp_recvmsg(3, ..., 1000, ..., ..., {sinfo_stream=0, sinfo_ssn=1, sinfo_flags=0, -sinfo_ppid=0, sinfo_context=0, sinfo_timetolive=0, sinfo_tsn=2, sinfo_cumtsn=2}, 8) = 1000 ++0.0 sctp_recvmsg(3, ..., 1000, ..., ..., {sinfo_stream=0, sinfo_ssn=1, sinfo_flags=0, sinfo_ppid=htonl(1234), sinfo_context=0, sinfo_timetolive=0, sinfo_tsn=2, sinfo_cumtsn=2}, 8) = 1000 +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_recvmsg(3, ..., 1000, {sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")}, 16, -{sinfo_stream=0, sinfo_ssn=2, sinfo_flags=0, sinfo_ppid=0, sinfo_context=0, sinfo_timetolive=0, sinfo_tsn=3, sinfo_cumtsn=3}, 8) = 1000 +{sinfo_stream=0, sinfo_ssn=2, sinfo_flags=0, sinfo_ppid=htonl(0), sinfo_context=0, sinfo_timetolive=0, sinfo_tsn=3, sinfo_cumtsn=3}, 8) = 1000 +0.0 close(3) = 0 +0.0 > sctp: SHUTDOWN[flgs=0, cum_tsn=3] diff --git a/gtests/net/packetdrill/tests/bsd/sctp/sctp_sendmsg.pkt b/gtests/net/packetdrill/tests/bsd/sctp/sctp_sendmsg.pkt index e9d6ec47dddfe82400ecb61c1122c941fe843ec9..a4cee70186ebb2b42af587c94d53f58f3f9bd655 100644 --- a/gtests/net/packetdrill/tests/bsd/sctp/sctp_sendmsg.pkt +++ b/gtests/net/packetdrill/tests/bsd/sctp/sctp_sendmsg.pkt @@ -1,23 +1,24 @@ +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=1, is=1, tsn=1, STATE_COOKIE[len=4, val=...]] ++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 -//sctp_sendmsg(int sd, const void * msg, size_t len, struct sockaddr *to, socklen_t tolen, +//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 -+0.0 > sctp: DATA[flgs=BE, len=1016, tsn=1, sid=0, ssn=0, ppid=0] ++0.0 sctp_sendmsg(3, ..., 1000, ..., ..., htonl(1234), SCTP_UNORDERED, 1, 0, 0) = 1000 ++0.0 > sctp: DATA[flgs=UBE, len=1016, tsn=1, sid=1, ssn=0, ppid=1234] +0.0 < sctp: SACK[flgs=0, cum_tsn=1, a_rwnd=1500, gaps=[], dups=[]] -+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_sendmsg(3, ..., 1000, {sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")}, 16, htonl(0x1234), 0, 0, 0, 0) = 1000 ++0.0 > sctp: DATA[flgs=BE, len=1016, tsn=2, sid=0, ssn=0, ppid=0x1234] +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: DATA[flgs=BE, len=1016, tsn=3, sid=0, ssn=1, 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]