Skip to content
Snippets Groups Projects
Commit 2d4511a1 authored by hoelscher's avatar hoelscher
Browse files

Add support for [gs]etsocketoption SCTP_EVENT

parent 9080a23f
No related branches found
No related tags found
No related merge requests found
...@@ -240,6 +240,8 @@ spp_pathmtu return SPP_PATHMTU; ...@@ -240,6 +240,8 @@ spp_pathmtu return SPP_PATHMTU;
spp_flags return SPP_FLAGS; spp_flags return SPP_FLAGS;
spp_ipv6_flowlabel return SPP_IPV6_FLOWLABEL_; /* avoid name clash */ spp_ipv6_flowlabel return SPP_IPV6_FLOWLABEL_; /* avoid name clash */
spp_dscp return SPP_DSCP_; /* avoid name clash */ spp_dscp return SPP_DSCP_; /* avoid name clash */
se_type return SE_TYPE;
se_on return SE_ON;
CHUNK return CHUNK; CHUNK return CHUNK;
DATA return DATA; DATA return DATA;
INIT return INIT; INIT return INIT;
......
...@@ -536,7 +536,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, ...@@ -536,7 +536,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
%token <reserved> SPP_ADDRESS SPP_HBINTERVAL SPP_PATHMAXRXT SPP_PATHMTU %token <reserved> SPP_ADDRESS SPP_HBINTERVAL SPP_PATHMAXRXT SPP_PATHMTU
%token <reserved> SPP_FLAGS SPP_IPV6_FLOWLABEL_ SPP_DSCP_ %token <reserved> SPP_FLAGS SPP_IPV6_FLOWLABEL_ SPP_DSCP_
%token <reserved> SASOC_ASOCMAXRXT SASOC_NUMBER_PEER_DESTINATIONS SASOC_PEER_RWND %token <reserved> SASOC_ASOCMAXRXT SASOC_NUMBER_PEER_DESTINATIONS SASOC_PEER_RWND
%token <reserved> SASOC_LOCAL_RWND SASOC_COOKIE_LIFE %token <reserved> SASOC_LOCAL_RWND SASOC_COOKIE_LIFE SE_TYPE SE_ON
%token <floating> FLOAT %token <floating> FLOAT
%token <integer> INTEGER HEX_INTEGER %token <integer> INTEGER HEX_INTEGER
%token <string> WORD STRING BACK_QUOTED CODE IPV4_ADDR IPV6_ADDR %token <string> WORD STRING BACK_QUOTED CODE IPV4_ADDR IPV6_ADDR
...@@ -584,7 +584,8 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, ...@@ -584,7 +584,8 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
%type <expression> spp_flags spp_ipv6_flowlabel spp_dscp %type <expression> spp_flags spp_ipv6_flowlabel spp_dscp
%type <expression> spinfo_address spinfo_state spinfo_cwnd spinfo_srtt spinfo_rto spinfo_mtu %type <expression> spinfo_address spinfo_state spinfo_cwnd spinfo_srtt spinfo_rto spinfo_mtu
%type <expression> sasoc_asocmaxrxt sasoc_number_peer_destinations sasoc_peer_rwnd %type <expression> sasoc_asocmaxrxt sasoc_number_peer_destinations sasoc_peer_rwnd
%type <expression> sasoc_local_rwnd sasoc_cookie_life sctp_assocparams %type <expression> sasoc_local_rwnd sasoc_cookie_life sctp_assocparams
%type <expression> sctp_event se_type se_on
%type <errno_info> opt_errno %type <errno_info> opt_errno
%type <chunk_list> sctp_chunk_list_spec %type <chunk_list> sctp_chunk_list_spec
%type <chunk_list_item> sctp_chunk_spec %type <chunk_list_item> sctp_chunk_spec
...@@ -2367,7 +2368,10 @@ expression ...@@ -2367,7 +2368,10 @@ expression
| sctp_paddrparams { | sctp_paddrparams {
$$ = $1; $$ = $1;
} }
| sctp_assocparams { | sctp_assocparams {
$$ = $1;
}
| sctp_event {
$$ = $1; $$ = $1;
} }
; ;
...@@ -2965,6 +2969,42 @@ sctp_assocparams ...@@ -2965,6 +2969,42 @@ sctp_assocparams
} }
; ;
se_type
: SE_TYPE '=' INTEGER {
if (!is_valid_u16($3)) {
semantic_error("se_type out of range");
}
$$ = new_integer_expression($3, "%hu");
}
| SE_TYPE '=' WORD {
$$ = new_expression(EXPR_WORD);
$$->value.string = $3;
}
;
se_on
: SE_ON '=' INTEGER {
if (!is_valid_u8($3)) {
semantic_error("se_on out of range");
}
$$ = new_integer_expression($3, "%hhu");
}
| SE_ON '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
;
sctp_event
: '{' se_type ',' se_on '}' {
#ifdef SCTP_EVENT
$$ = new_expression(EXPR_SCTP_EVENT);
$$->value.sctp_event = calloc(1, sizeof(struct sctp_event_expr));
$$->value.sctp_event->se_type = $2;
$$->value.sctp_event->se_on = $4;
#elif
$$ = NULL;
#endif
}
;
opt_errno opt_errno
: { $$ = NULL; } : { $$ = NULL; }
| WORD note { | WORD note {
......
...@@ -2224,6 +2224,39 @@ static int check_sctp_assocparams(struct sctp_assocparams_expr *expr, ...@@ -2224,6 +2224,39 @@ static int check_sctp_assocparams(struct sctp_assocparams_expr *expr,
} }
#endif #endif
#ifdef SCTP_EVENT
static int check_sctp_event(struct sctp_event_expr *expr,
struct sctp_event *sctp_event,
char **error)
{
if (expr->se_type->type != EXPR_ELLIPSIS) {
u16 se_type;
if (get_u16(expr->se_type, &se_type, error)) {
return STATUS_ERR;
}
if (sctp_event->se_type != se_type) {
asprintf(error, "Bad getsockopt sctp_event.se_type: expected: %hu actual: %hu",
se_type, sctp_event->se_type);
return STATUS_ERR;
}
}
if (expr->se_on->type != EXPR_ELLIPSIS) {
u8 se_on;
if (get_u8(expr->se_on, &se_on, error)) {
return STATUS_ERR;
}
if (sctp_event->se_on != se_on) {
asprintf(error, "Bad getsockopt sctp_event.se_on: expected: %hhu actual: %hhu",
se_on, sctp_event->se_on);
return STATUS_ERR;
}
}
return STATUS_OK;
}
#endif
static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall, static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
struct expression_list *args, char **error) struct expression_list *args, char **error)
{ {
...@@ -2349,6 +2382,18 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall, ...@@ -2349,6 +2382,18 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
free(live_optval); free(live_optval);
return STATUS_ERR; return STATUS_ERR;
} }
#endif
#ifdef SCTP_EVENT
} else if (val_expression->type == EXPR_SCTP_EVENT) {
live_optval = malloc(sizeof(struct sctp_event));
live_optlen = sizeof(struct sctp_event);
((struct sctp_event *)live_optval)->se_assoc_id = 0;
if (get_u16(val_expression->value.sctp_event->se_type,
&((struct sctp_event *)live_optval)->se_type,
error)) {
free(live_optval);
return STATUS_ERR;
}
#endif #endif
} else { } else {
s32_bracketed_arg(args, 3, &script_optval, error); s32_bracketed_arg(args, 3, &script_optval, error);
...@@ -2437,6 +2482,13 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall, ...@@ -2437,6 +2482,13 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
free(live_optval); free(live_optval);
return STATUS_ERR; return STATUS_ERR;
} }
#endif
#ifdef SCTP_EVENT
} else if (val_expression->type == EXPR_SCTP_EVENT) {
if (check_sctp_event(val_expression->value.sctp_event, live_optval, error)) {
free(live_optval);
return STATUS_ERR;
}
#endif #endif
} else { } else {
if (*(int*)live_optval != script_optval) { if (*(int*)live_optval != script_optval) {
...@@ -2481,6 +2533,9 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall, ...@@ -2481,6 +2533,9 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
#if defined(SCTP_SS_VALUE) #if defined(SCTP_SS_VALUE)
struct sctp_stream_value stream_value; struct sctp_stream_value stream_value;
#endif #endif
#ifdef SCTP_EVENT
struct sctp_event event;
#endif
#ifdef SCTP_PEER_ADDR_PARAMS #ifdef SCTP_PEER_ADDR_PARAMS
struct sctp_paddrparams paddrparams; struct sctp_paddrparams paddrparams;
#ifdef linux #ifdef linux
...@@ -2656,6 +2711,20 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall, ...@@ -2656,6 +2711,20 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
optval = &paddrinfo; optval = &paddrinfo;
break; break;
#endif #endif
#ifdef SCTP_EVENT
case EXPR_SCTP_EVENT:
event.se_assoc_id = 0;
if (get_u16(val_expression->value.sctp_event->se_type,
&event.se_type, error)) {
return STATUS_ERR;
}
if (get_u8(val_expression->value.sctp_event->se_on,
&event.se_on, error)) {
return STATUS_ERR;
}
optval = &event;
break;
#endif
#ifdef SCTP_PEER_ADDR_PARAMS #ifdef SCTP_PEER_ADDR_PARAMS
case EXPR_SCTP_PEER_ADDR_PARAMS: case EXPR_SCTP_PEER_ADDR_PARAMS:
paddrparams.spp_assoc_id = 0; paddrparams.spp_assoc_id = 0;
......
...@@ -89,6 +89,9 @@ struct expression_type_entry expression_type_table[] = { ...@@ -89,6 +89,9 @@ struct expression_type_entry expression_type_table[] = {
#endif #endif
#ifdef SCTP_ASSOCINFO #ifdef SCTP_ASSOCINFO
{ EXPR_SCTP_ASSOCPARAMS, "sctp_assocparams"}, { EXPR_SCTP_ASSOCPARAMS, "sctp_assocparams"},
#endif
#ifdef SCTP_EVENT
{ EXPR_SCTP_EVENT, "sctp_event" },
#endif #endif
{ NUM_EXPR_TYPES, NULL} { NUM_EXPR_TYPES, NULL}
}; };
...@@ -380,6 +383,12 @@ void free_expression(struct expression *expression) ...@@ -380,6 +383,12 @@ void free_expression(struct expression *expression)
free_expression(expression->value.sctp_assocparams->sasoc_local_rwnd); free_expression(expression->value.sctp_assocparams->sasoc_local_rwnd);
free_expression(expression->value.sctp_assocparams->sasoc_cookie_life); free_expression(expression->value.sctp_assocparams->sasoc_cookie_life);
break; break;
#endif
#ifdef SCTP_EVENT
case EXPR_SCTP_EVENT:
free_expression(expression->value.sctp_event->se_type);
free_expression(expression->value.sctp_event->se_on);
break;
#endif #endif
case EXPR_WORD: case EXPR_WORD:
assert(expression->value.string); assert(expression->value.string);
...@@ -869,6 +878,36 @@ static int evaluate_sctp_stream_value_expression(struct expression *in, ...@@ -869,6 +878,36 @@ static int evaluate_sctp_stream_value_expression(struct expression *in,
} }
#endif #endif
#ifdef SCTP_EVENT
static int evaluate_sctp_event_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_event_expr *in_event;
struct sctp_event_expr *out_event;
assert(in->type == EXPR_SCTP_EVENT);
assert(in->value.sctp_event);
assert(out->type == EXPR_SCTP_EVENT);
out->value.sctp_event = calloc(1, sizeof(struct sctp_event_expr));
in_event = in->value.sctp_event;
out_event = out->value.sctp_event;
if (evaluate(in_event->se_type,
&out_event->se_type,
error))
return STATUS_ERR;
if (evaluate(in_event->se_on,
&out_event->se_on,
error))
return STATUS_ERR;
return STATUS_OK;
}
#endif
#ifdef SCTP_ASSOCINFO #ifdef SCTP_ASSOCINFO
static int evaluate_sctp_accocparams_expression(struct expression *in, static int evaluate_sctp_accocparams_expression(struct expression *in,
struct expression *out, struct expression *out,
...@@ -976,6 +1015,11 @@ static int evaluate(struct expression *in, ...@@ -976,6 +1015,11 @@ static int evaluate(struct expression *in,
case EXPR_SCTP_STREAM_VALUE: case EXPR_SCTP_STREAM_VALUE:
evaluate_sctp_stream_value_expression(in, out, error); evaluate_sctp_stream_value_expression(in, out, error);
break; break;
#endif
#ifdef SCTP_EVENT
case EXPR_SCTP_EVENT:
result = evaluate_sctp_event_expression(in, out, error);
break;
#endif #endif
case EXPR_WORD: case EXPR_WORD:
out->type = EXPR_INTEGER; out->type = EXPR_INTEGER;
......
...@@ -66,10 +66,13 @@ enum expression_t { ...@@ -66,10 +66,13 @@ enum expression_t {
EXPR_SCTP_STREAM_VALUE, /* struct sctp_stream_value for SCTP_SS_VALUE */ EXPR_SCTP_STREAM_VALUE, /* struct sctp_stream_value for SCTP_SS_VALUE */
#endif #endif
#ifdef SCTP_PEER_ADDR_PARAMS #ifdef SCTP_PEER_ADDR_PARAMS
EXPR_SCTP_PEER_ADDR_PARAMS, /* struct for sctp_paddrparams for SCTP_PEER_ADDR_PARAMS*/ EXPR_SCTP_PEER_ADDR_PARAMS, /* struct for sctp_paddrparams for SCTP_PEER_ADDR_PARAMS */
#endif #endif
#ifdef SCTP_ASSOCINFO #ifdef SCTP_ASSOCINFO
EXPR_SCTP_ASSOCPARAMS, /* struct sctp_assocparams for SCTP_ASSOCINFO */ EXPR_SCTP_ASSOCPARAMS, /* struct sctp_assocparams for SCTP_ASSOCINFO */
#endif
#ifdef SCTP_EVENT
EXPR_SCTP_EVENT, /* struct sctp_event to for SCTP_EVENT */
#endif #endif
NUM_EXPR_TYPES, NUM_EXPR_TYPES,
}; };
...@@ -114,6 +117,9 @@ struct expression { ...@@ -114,6 +117,9 @@ struct expression {
#endif #endif
#ifdef SCTP_ASSOCINFO #ifdef SCTP_ASSOCINFO
struct sctp_assocparams_expr *sctp_assocparams; struct sctp_assocparams_expr *sctp_assocparams;
#endif
#ifdef SCTP_EVENT
struct sctp_event_expr *sctp_event;
#endif #endif
} value; } value;
const char *format; /* the printf format for printing the value */ const char *format; /* the printf format for printing the value */
...@@ -248,6 +254,14 @@ struct sctp_assocparams_expr { ...@@ -248,6 +254,14 @@ struct sctp_assocparams_expr {
}; };
#endif #endif
#ifdef SCTP_EVENT
/* Parse tree for sctp_enevt struct in [gs]etsockopt syscall. */
struct sctp_event_expr {
struct expression *se_type;
struct expression *se_on;
};
#endif
/* The errno-related info from strace to summarize a system call error */ /* The errno-related info from strace to summarize a system call error */
struct errno_spec { struct errno_spec {
const char *errno_macro; /* errno symbol (C macro name) */ const char *errno_macro; /* errno symbol (C macro name) */
......
...@@ -87,6 +87,7 @@ struct int_symbol platform_symbols_table[] = { ...@@ -87,6 +87,7 @@ struct int_symbol platform_symbols_table[] = {
{ SCTP_DELAYED_SACK, "SCTP_DELAYED_SACK" }, { SCTP_DELAYED_SACK, "SCTP_DELAYED_SACK" },
{ SCTP_MAX_BURST, "SCTP_MAX_BURST" }, { SCTP_MAX_BURST, "SCTP_MAX_BURST" },
{ SCTP_PEER_ADDR_PARAMS, "SCTP_PEER_ADDR_PARAMS" }, { SCTP_PEER_ADDR_PARAMS, "SCTP_PEER_ADDR_PARAMS" },
{ SCTP_EVENT, "SCTP_EVENT" },
{ SCTP_STATUS, "SCTP_STATUS" }, { SCTP_STATUS, "SCTP_STATUS" },
{ SCTP_GET_PEER_ADDR_INFO, "SCTP_GET_PEER_ADDR_INFO" }, { SCTP_GET_PEER_ADDR_INFO, "SCTP_GET_PEER_ADDR_INFO" },
{ SCTP_FRAGMENT_INTERLEAVE, "SCTP_FRAGMENT_INTERLEAVE" }, { SCTP_FRAGMENT_INTERLEAVE, "SCTP_FRAGMENT_INTERLEAVE" },
...@@ -160,7 +161,21 @@ struct int_symbol platform_symbols_table[] = { ...@@ -160,7 +161,21 @@ struct int_symbol platform_symbols_table[] = {
{ SPP_PMTUD_DISABLE, "SPP_PMTUD_DISABLE" }, { SPP_PMTUD_DISABLE, "SPP_PMTUD_DISABLE" },
{ SPP_IPV6_FLOWLABEL, "SPP_IPV6_FLOWLABEL" }, { SPP_IPV6_FLOWLABEL, "SPP_IPV6_FLOWLABEL" },
{ SPP_DSCP, "SPP_DSCP" }, { SPP_DSCP, "SPP_DSCP" },
{ SCTP_ASSOC_CHANGE, "SCTP_ASSOC_CHANGE" },
{ SCTP_PEER_ADDR_CHANGE, "SCTP_PEER_ADDR_CHANGE" },
{ SCTP_REMOTE_ERROR, "SCTP_REMOTE_ERROR" },
{ SCTP_SEND_FAILED, "SCTP_SEND_FAILED" },
{ SCTP_SHUTDOWN_EVENT, "SCTP_SHUTDOWN_EVENT" },
{ SCTP_ADAPTATION_INDICATION, "SCTP_ADAPTATION_INDICATION" },
{ SCTP_ADAPTION_INDICATION, "SCTP_ADAPTION_INDICATION" },
{ SCTP_PARTIAL_DELIVERY_EVENT, "SCTP_PARTIAL_DELIVERY_EVENT" },
{ SCTP_AUTHENTICATION_EVENT, "SCTP_AUTHENTICATION_EVENT" },
{ SCTP_STREAM_RESET_EVENT, "SCTP_STREAM_RESET_EVENT" },
{ SCTP_SENDER_DRY_EVENT, "SCTP_SENDER_DRY_EVENT" },
{ SCTP_NOTIFICATIONS_STOPPED_EVENT, "SCTP_NOTIFICATIONS_STOPPED_EVENT"},
{ SCTP_ASSOC_RESET_EVENT, "SCTP_ASSOC_RESET_EVENT" },
{ SCTP_STREAM_CHANGE_EVENT, "SCTP_STREAM_CHANGE_EVENT" },
{ SCTP_SEND_FAILED_EVENT, "SCTP_SEND_FAILED_EVENT" },
/* /usr/include/netinet/tcp.h */ /* /usr/include/netinet/tcp.h */
{ TCP_NODELAY, "TCP_NODELAY" }, { TCP_NODELAY, "TCP_NODELAY" },
{ TCP_MAXSEG, "TCP_MAXSEG" }, { TCP_MAXSEG, "TCP_MAXSEG" },
......
...@@ -107,4 +107,7 @@ spp_hbinterval=300, spp_pathmaxrxt=..., spp_pathmtu=1468, spp_flags=521, spp_ipv ...@@ -107,4 +107,7 @@ spp_hbinterval=300, spp_pathmaxrxt=..., spp_pathmtu=1468, spp_flags=521, spp_ipv
+0 getsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_delay=..., sack_freq=1}, [12]) = 0 +0 getsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_delay=..., sack_freq=1}, [12]) = 0
+0 getsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_delay=250, sack_freq=...}, [12]) = 0 +0 getsockopt(3, IPPROTO_SCTP, SCTP_DELAYED_SACK, {sack_delay=250, sack_freq=...}, [12]) = 0
+0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SHUTDOWN_EVENT, se_on=1}, 8) = 0
+0 getsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_SHUTDOWN_EVENT, se_on=1}, [8]) = 0
+0 close(3) = 0 +0 close(3) = 0
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment