From 402302ead0690b6a3e3202a5680ea1f398cbaa61 Mon Sep 17 00:00:00 2001 From: hoelscher <jens.hoelscher@fh-muenster.de> Date: Tue, 22 Sep 2015 00:28:29 +0200 Subject: [PATCH] Add parser for getsockopt SO_LINGER with Ellipse and Integer --- gtests/net/packetdrill/parser.y | 37 ++++++++++--- gtests/net/packetdrill/run_system_call.c | 52 +++++++++++++------ gtests/net/packetdrill/script.c | 4 ++ gtests/net/packetdrill/script.h | 8 ++- .../bsd/sctp/sctp_get_socket_options.pkt | 12 ++--- 5 files changed, 83 insertions(+), 30 deletions(-) diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index a8aa4236..706395d0 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -564,7 +564,8 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %type <expression_list> expression_list function_arguments %type <expression> expression binary_expression array %type <expression> decimal_integer hex_integer -%type <expression> inaddr sockaddr msghdr iovec pollfd opt_revents linger +%type <expression> inaddr sockaddr msghdr iovec pollfd opt_revents +%type <expression> linger l_onoff l_linger %type <expression> sctp_rtoinfo sctp_initmsg sctp_assocval sctp_sackinfo %type <expression> sctp_status %type <errno_info> opt_errno @@ -2276,15 +2277,39 @@ pollfd ; opt_revents -: { $$ = new_integer_expression(0, "%ld"); } +: { $$ = new_integer_expression(0, "%ld" ); } | ',' REVENTS '=' expression { $$ = $4; } ; +l_onoff +: ONOFF '=' INTEGER { + if (!is_valid_u32($3)){ + semantic_error("linger onoff out of range"); + } else { + printf("test2\n"); + $$ = new_integer_expression( $3, "%ld" ); + } +} +| ONOFF '=' ELLIPSIS { $$ = new_expression( EXPR_ELLIPSIS ); } +; + +l_linger +: LINGER '=' INTEGER { + if (!is_valid_u32($3)){ + semantic_error("linger out of range"); + } + $$ = new_integer_expression( $3, "%ld"); + printf("test6\n"); +} +| LINGER '=' ELLIPSIS { $$ = new_expression( EXPR_ELLIPSIS ); } +; + linger -: '{' ONOFF '=' INTEGER ',' LINGER '=' INTEGER '}' { - $$ = new_expression(EXPR_LINGER); - $$->value.linger.l_onoff = $4; - $$->value.linger.l_linger = $8; +: '{' l_onoff ',' l_linger '}' { + $$ = new_expression( EXPR_LINGER ); + $$->value.linger = (struct linger_expr*) malloc(sizeof(struct linger_expr)); + $$->value.linger->l_onoff = $2; + $$->value.linger->l_linger = $4; } ; diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c index 6f5a018b..5e98c2a0 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -1582,8 +1582,9 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall, if (val_expression == NULL) { return STATUS_ERR; } else if (val_expression->type == EXPR_LINGER) { - live_optval = malloc(sizeof(val_expression->value.linger)); - live_optlen = (socklen_t)sizeof(val_expression->value.linger); + printf("3\n"); + live_optval = malloc(sizeof(struct linger)); + live_optlen = (socklen_t)sizeof(struct linger); #ifdef SCTP_RTOINFO } else if (val_expression->type == EXPR_SCTP_RTOINFO) { live_optval = malloc(sizeof(val_expression->value.sctp_rtoinfo)); @@ -1614,21 +1615,38 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall, free(live_optval); return STATUS_ERR; } - if (val_expression->type == EXPR_LINGER) { + struct expression *l_onoff = val_expression->value.linger->l_onoff; + struct expression *l_linger = val_expression->value.linger->l_linger; struct linger *ling = live_optval; - if (ling->l_onoff != val_expression->value.linger.l_onoff) { - asprintf(error, "Bad getsockopt Linger onoff: expected: %d actual: %d", - val_expression->value.linger.l_onoff, ling->l_onoff); - free(live_optval); - return STATUS_ERR; + int val_onoff = 0; + if(l_onoff->type == EXPR_INTEGER){ + if(get_s32(l_onoff, &val_onoff, error)){ + free(live_optval); + return STATUS_ERR; + } + printf("Start Auswertung Linger\n"); + if (val_onoff != ling->l_onoff) { + asprintf(error, "Bad getsockopt Linger onoff: expected: %d actual: %d", + (int) val_onoff, ling->l_onoff); + free(live_optval); + return STATUS_ERR; + } } - if (ling->l_linger != val_expression->value.linger.l_linger) { - asprintf(error, "Bad getsockopt Linger Value: expected: %d actual: %d", - val_expression->value.linger.l_linger, ling->l_linger); - free(live_optval); - return STATUS_ERR; + int val_linger = 0; + if(l_linger->type == EXPR_INTEGER){ + if(get_s32(l_linger, &val_linger, error)){ + free(live_optval); + return STATUS_ERR; + } + if (ling->l_linger != val_linger) { + asprintf(error, "Bad getsockopt Linger Value: expected: %d actual: %d", + val_linger, ling->l_linger); + free(live_optval); + return STATUS_ERR; + } } + #ifdef SCTP_RTOINFO } else if (val_expression->type == EXPR_SCTP_RTOINFO) { struct sctp_rtoinfo *rtoinfo = live_optval; @@ -1708,7 +1726,6 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall, int script_fd, live_fd, level, optname, optval_s32, optlen, result; void *optval = NULL; struct expression *val_expression; - if (check_arg_count(args, 5, error)) return STATUS_ERR; if (s32_arg(args, 0, &script_fd, error)) @@ -1726,7 +1743,11 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall, if (val_expression == NULL) return STATUS_ERR; if (val_expression->type == EXPR_LINGER) { - optval = &val_expression->value.linger; + optval = malloc( sizeof( struct linger )); + get_s32(val_expression->value.linger->l_onoff, + &(((struct linger*) optval)->l_onoff), error); + get_s32(val_expression->value.linger->l_linger, + &(((struct linger*) optval)->l_linger), error); } else if (val_expression->type == EXPR_STRING) { optval = val_expression->value.string; } else if (val_expression->type == EXPR_LIST) { @@ -1765,6 +1786,7 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall, result = setsockopt(live_fd, level, optname, optval, optlen); return end_syscall(state, syscall, CHECK_EXACT, result, error); + free(optval); } static int syscall_poll(struct state *state, struct syscall_spec *syscall, diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c index c4fdb4b2..3547414b 100644 --- a/gtests/net/packetdrill/script.c +++ b/gtests/net/packetdrill/script.c @@ -285,7 +285,11 @@ void free_expression(struct expression *expression) switch (expression->type) { case EXPR_ELLIPSIS: case EXPR_INTEGER: + break; case EXPR_LINGER: + free(expression->value.linger->l_onoff); + free(expression->value.linger->l_linger); + break; #ifdef SCTP_RTOINFO case EXPR_SCTP_RTOINFO: #endif diff --git a/gtests/net/packetdrill/script.h b/gtests/net/packetdrill/script.h index a2b2e46b..38b458dc 100644 --- a/gtests/net/packetdrill/script.h +++ b/gtests/net/packetdrill/script.h @@ -72,7 +72,7 @@ struct expression { union { s64 num; char *string; - struct linger linger; + struct linger_expr *linger; struct sockaddr_in *socket_address_ipv4; struct sockaddr_in6 *socket_address_ipv6; struct binary_expression *binary; @@ -136,6 +136,12 @@ struct pollfd_expr { struct expression *revents; /* returned events */ }; +/* Handle the values for socketoption SO_Linger with inputtypes and values*/ +struct linger_expr { + struct expression *l_onoff; + struct expression *l_linger; +}; + /* The errno-related info from strace to summarize a system call error */ struct errno_spec { const char *errno_macro; /* errno symbol (C macro name) */ 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 8799fc15..57604f83 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 @@ -10,18 +10,14 @@ +0.0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 ++0 setsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=1, linger=30}, 8) = 0 ++0 getsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=128, linger=30}, [8]) = 0 + +0 setsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=100, srto_max=200, srto_min=50}, 16) = 0 +0 getsockopt(3, IPPROTO_SCTP, SCTP_RTOINFO, {srto_initial=100, srto_max=200, srto_min=50}, [16]) = 0 +0 getsockopt(3, IPPROTO_SCTP, SCTP_STATUS, {sstat_state=8, sstat_rwnd=1500, sstat_unackdata=0, sstat_penddata=0, sstat_instrms=1, sstat_outstrms=1, - sstat_fragmentation_point=1452, sstat_primary=...}, [176])= 0 - -+0 setsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=1, linger=30}, 8) = 0 -+0 getsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=128, linger=30}, [8]) = 0 -+0 getsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=..., linger=30}, [8]) = 0 -+0 getsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=128, linger=...}, [8]) = 0 -+0 getsockopt(3, SOL_SOCKET, SO_LINGER, {onoff=..., linger=...}, [8]) = 0 - + sstat_fragmentation_point=1452, sstat_primary=...}, [176])= 0 +0 close(3) = 0 -- GitLab