Skip to content
Snippets Groups Projects
Commit 6a361a6d authored by hoelscher's avatar hoelscher
Browse files

add [gs]etsockopt SCTP_PRIMARY_ADDR

parent 61a57e42
No related branches found
No related tags found
No related merge requests found
......@@ -268,6 +268,8 @@ snd_flags return SND_FLAGS;
snd_ppid return SND_PPID;
snd_context return SND_CONTEXT;
snd_assoc_id return SND_ASSOC_ID;
ssp_assoc_id return SSP_ASSOC_ID;
ssp_addr return SSP_ADDR;
ssb_adaptation_ind return SSB_ADAPTATION_IND;
sinfo_stream return SINFO_STREAM;
sinfo_ssn return SINFO_SSN;
......
......@@ -538,6 +538,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
%token <reserved> SPP_FLAGS SPP_IPV6_FLOWLABEL_ SPP_DSCP_
%token <reserved> SASOC_ASOCMAXRXT SASOC_ASSOC_ID SASOC_NUMBER_PEER_DESTINATIONS SASOC_PEER_RWND
%token <reserved> SASOC_LOCAL_RWND SASOC_COOKIE_LIFE SE_ASSOC_ID SE_TYPE SE_ON
%token <reserved> SSP_ASSOC_ID SSP_ADDR
%token <reserved> SND_SID SND_FLAGS SND_PPID SND_CONTEXT SND_ASSOC_ID SSB_ADAPTATION_IND
%token <reserved> BAD_CRC32C NULL_
%token <reserved> SINFO_STREAM SINFO_SSN SINFO_FLAGS SINFO_PPID SINFO_CONTEXT SINFO_ASSOC_ID
......@@ -614,7 +615,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
%type <expression> sasoc_assoc_id 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_assoc_id snd_context
%type <expression> sctp_event se_assoc_id se_type se_on sctp_setadaptation null
%type <expression> sctp_event se_assoc_id se_type se_on sctp_setadaptation sctp_setprim ssp_assoc_id null
%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 sinfo_pr_value serinfo_next_flags
%type <expression> serinfo_next_stream serinfo_next_aid serinfo_next_length serinfo_next_ppid sctp_extrcvinfo
......@@ -2509,6 +2510,9 @@ expression
| sctp_sndinfo {
$$ = $1;
}
| sctp_setprim {
$$ = $1;
}
| sctp_setadaptation{
$$ = $1;
}
......@@ -3371,7 +3375,28 @@ sctp_sndinfo
$$->value.sctp_sndinfo->snd_assoc_id = $10;
}
;
ssp_assoc_id
: SSP_ASSOC_ID '=' INTEGER {
if (!is_valid_u32($3)) {
semantic_error("ssp_assoc_id out of range");
}
$$ = new_integer_expression($3, "%u");
}
| SSP_ASSOC_ID '=' WORD {
$$ = new_expression(EXPR_WORD);
$$->value.string = $3;
}
| SSP_ASSOC_ID '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
;
sctp_setprim
: '{' ssp_assoc_id ',' SSP_ADDR '=' sockaddr'}' {
$$ = new_expression(EXPR_SCTP_SETPRIM);
$$->value.sctp_setprim = calloc(1, sizeof(struct sctp_setprim_expr));
$$->value.sctp_setprim->ssp_assoc_id = $2;
$$->value.sctp_setprim->ssp_addr = $6;
}
;
sctp_setadaptation
: '{' SSB_ADAPTATION_IND '=' INTEGER '}' {
$$ = new_expression(EXPR_SCTP_SETADAPTATION);
......
......@@ -269,6 +269,27 @@ static int get_size_t(struct expression *expression,
}
#endif
#if defined(linux) || defined(__FreeBSD__)
/* Sets the value from the expression argument, checking that it is a
* valid sctp_assoc_t, and matches the expected type. Returns STATUS_OK on
* success; on failure returns STATUS_ERR and sets error message.
*/
static int get_sctp_assoc_t(struct expression *expression,
sctp_assoc_t *value, char **error)
{
if (check_type(expression, EXPR_INTEGER, error))
return STATUS_ERR;
if (expression->value.num < 0) {
asprintf(error,
"Value out of range for sctp_assoc_t: %lld",
expression->value.num);
return STATUS_ERR;
}
*value = expression->value.num;
return STATUS_OK;
}
#endif
/* Sets the value from the expression argument, checking that it is a
* valid u32, and matches the expected type. Returns STATUS_OK on
* success; on failure returns STATUS_ERR and sets error message.
......@@ -2795,6 +2816,21 @@ static int check_sctp_sndinfo(struct sctp_sndinfo_expr *expr,
}
#endif
#ifdef SCTP_PRIMARY_ADDR
static int check_sctp_setprim(struct sctp_setprim_expr *expr,
struct sctp_setprim *sctp_setprim,
char **error)
{
if (check_u32_expr(expr->ssp_assoc_id, sctp_setprim->ssp_assoc_id,
"sctp_setprim.ssp_assoc_id", error))
return STATUS_ERR;
if (check_sockaddr(expr->ssp_addr, (struct sockaddr *)&sctp_setprim->ssp_addr, error))
return STATUS_ERR;
return STATUS_OK;
}
#endif
#ifdef SCTP_ADAPTATION_LAYER
static int check_sctp_setadaptation(struct sctp_setadaptation_expr *expr,
struct sctp_setadaptation *sctp_setadaptation,
......@@ -2844,15 +2880,11 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
case EXPR_SCTP_RTOINFO:
live_optval = malloc(sizeof(struct sctp_rtoinfo));
live_optlen = (socklen_t)sizeof(struct sctp_rtoinfo);
if (val_expression->value.sctp_rtoinfo->srto_assoc_id->type != EXPR_ELLIPSIS) {
if (get_u32(val_expression->value.sctp_rtoinfo->srto_assoc_id,
&((struct sctp_rtoinfo*)live_optval)->srto_assoc_id,
error)) {
free(live_optval);
return STATUS_ERR;
}
} else {
((struct sctp_rtoinfo*)live_optval)->srto_assoc_id = 0;
if (get_sctp_assoc_t(val_expression->value.sctp_rtoinfo->srto_assoc_id,
&((struct sctp_rtoinfo*)live_optval)->srto_assoc_id,
error)) {
free(live_optval);
return STATUS_ERR;
}
break;
#endif
......@@ -2860,15 +2892,11 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
case EXPR_SCTP_ASSOCPARAMS:
live_optval = malloc(sizeof(struct sctp_assocparams));
live_optlen = (socklen_t)sizeof(struct sctp_assocparams);
if (val_expression->value.sctp_rtoinfo->srto_assoc_id->type != EXPR_ELLIPSIS) {
if (get_u32(val_expression->value.sctp_assocparams->sasoc_assoc_id,
if (get_sctp_assoc_t(val_expression->value.sctp_assocparams->sasoc_assoc_id,
&((struct sctp_assocparams*) live_optval)->sasoc_assoc_id,
error)) {
free(live_optval);
return STATUS_ERR;
}
} else {
((struct sctp_assocparams*) live_optval)->sasoc_assoc_id = 0;
free(live_optval);
return STATUS_ERR;
}
break;
#endif
......@@ -2888,7 +2916,7 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
#ifdef SCTP_STATUS
case EXPR_SCTP_STATUS:
live_optval = malloc(sizeof(struct sctp_status));
live_optlen = (socklen_t)sizeof(struct sctp_status);
live_optlen = (socklen_t) sizeof(struct sctp_status);
((struct sctp_status*) live_optval)->sstat_assoc_id = 0;
break;
#endif
......@@ -2896,7 +2924,7 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
case EXPR_SCTP_PADDRINFO: {
struct sctp_paddrinfo_expr *expr_paddrinfo = val_expression->value.sctp_paddrinfo;
struct sctp_paddrinfo *live_paddrinfo = malloc(sizeof(struct sctp_paddrinfo));
live_optlen = (socklen_t)sizeof(struct sctp_paddrinfo);
live_optlen = (socklen_t) sizeof(struct sctp_paddrinfo);
memset(live_paddrinfo, 0, sizeof(struct sctp_paddrinfo));
live_paddrinfo->spinfo_assoc_id = 0;
if (get_sockstorage_arg(expr_paddrinfo->spinfo_address,
......@@ -2950,15 +2978,11 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
case EXPR_SCTP_EVENT:
live_optval = malloc(sizeof(struct sctp_event));
live_optlen = sizeof(struct sctp_event);
if (val_expression->value.sctp_event->se_assoc_id->type != EXPR_ELLIPSIS) {
if (get_u32(val_expression->value.sctp_event->se_assoc_id,
&((struct sctp_event *)live_optval)->se_assoc_id,
error)) {
free(live_optval);
return STATUS_ERR;
}
} else {
((struct sctp_event *)live_optval)->se_assoc_id = 0;
if (get_sctp_assoc_t(val_expression->value.sctp_event->se_assoc_id,
&((struct sctp_event *)live_optval)->se_assoc_id,
error)) {
free(live_optval);
return STATUS_ERR;
}
if (get_u16(val_expression->value.sctp_event->se_type,
&((struct sctp_event *)live_optval)->se_type,
......@@ -2978,9 +3002,21 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
case EXPR_SCTP_SNDINFO:
live_optval = malloc(sizeof(struct sctp_sndinfo));
live_optlen = sizeof(struct sctp_sndinfo);
if (get_u32(val_expression->value.sctp_sndinfo->snd_assoc_id,
&((struct sctp_sndinfo *)live_optval)->snd_assoc_id,
error)) {
if (get_sctp_assoc_t(val_expression->value.sctp_sndinfo->snd_assoc_id,
&((struct sctp_sndinfo *)live_optval)->snd_assoc_id,
error)) {
free(live_optval);
return STATUS_ERR;
}
break;
#endif
#ifdef SCTP_PRIMARY_ADDR
case EXPR_SCTP_SETPRIM:
live_optval = malloc(sizeof(struct sctp_setprim));
live_optlen = sizeof(struct sctp_setprim);
if (get_sctp_assoc_t(val_expression->value.sctp_setprim->ssp_assoc_id,
&((struct sctp_setprim *)live_optval)->ssp_assoc_id,
error)) {
free(live_optval);
return STATUS_ERR;
}
......@@ -3083,6 +3119,11 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
result = check_sctp_sndinfo(val_expression->value.sctp_sndinfo, live_optval, error);
break;
#endif
#ifdef SCTP_PRIMARY_ADDR
case EXPR_SCTP_SETPRIM:
result = check_sctp_setprim(val_expression->value.sctp_setprim, live_optval, error);
break;
#endif
#ifdef SCTP_ADAPTATION_LAYER
case EXPR_SCTP_SETADAPTATION:
result = check_sctp_setadaptation(val_expression->value.sctp_setadaptation, live_optval, error);
......@@ -3144,6 +3185,9 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
#ifdef SCTP_DEFAULT_SNDINFO
struct sctp_sndinfo sndinfo;
#endif
#ifdef SCTP_PRIMARY_ADDR
struct sctp_setprim setprim;
#endif
#ifdef SCTP_ADAPTATION_LAYER
struct sctp_setadaptation setadaptation;
#endif
......@@ -3189,8 +3233,8 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
#ifdef SCTP_RTOINFO
case EXPR_SCTP_RTOINFO:
if (val_expression->value.sctp_rtoinfo->srto_assoc_id->type != EXPR_ELLIPSIS) {
if (get_u32(val_expression->value.sctp_rtoinfo->srto_assoc_id,
&rtoinfo.srto_assoc_id, error)) {
if (get_sctp_assoc_t(val_expression->value.sctp_rtoinfo->srto_assoc_id,
&rtoinfo.srto_assoc_id, error)) {
return STATUS_ERR;
}
} else {
......@@ -3213,8 +3257,8 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
#endif
#ifdef SCTP_ASSOCINFO
case EXPR_SCTP_ASSOCPARAMS:
if (get_u32(val_expression->value.sctp_assocparams->sasoc_assoc_id,
&assocparams.sasoc_assoc_id, error)) {
if (get_sctp_assoc_t(val_expression->value.sctp_assocparams->sasoc_assoc_id,
&assocparams.sasoc_assoc_id, error)) {
return STATUS_ERR;
}
if (get_u16(val_expression->value.sctp_assocparams->sasoc_asocmaxrxt,
......@@ -3306,8 +3350,8 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
#ifdef SCTP_EVENT
case EXPR_SCTP_EVENT:
if (val_expression->value.sctp_event->se_assoc_id->type != EXPR_ELLIPSIS) {
if (get_u16(val_expression->value.sctp_event->se_assoc_id,
&event.se_type, error)) {
if (get_sctp_assoc_t(val_expression->value.sctp_event->se_assoc_id,
&event.se_assoc_id, error)) {
return STATUS_ERR;
}
} else {
......@@ -3387,13 +3431,26 @@ static int syscall_setsockopt(struct state *state, struct syscall_spec *syscall,
&sndinfo.snd_context, error)) {
return STATUS_ERR;
}
if (get_u32(val_expression->value.sctp_sndinfo->snd_assoc_id,
&sndinfo.snd_assoc_id, error)) {
if (get_sctp_assoc_t(val_expression->value.sctp_sndinfo->snd_assoc_id,
&sndinfo.snd_assoc_id, error)) {
return STATUS_ERR;
}
optval = &sndinfo;
break;
#endif
#ifdef SCTP_PRIMARY_ADDR
case EXPR_SCTP_SETPRIM:
if (get_sctp_assoc_t(val_expression->value.sctp_setprim->ssp_assoc_id,
&setprim.ssp_assoc_id, error)) {
return STATUS_ERR;
}
if (get_sockstorage_arg(val_expression->value.sctp_setprim->ssp_addr,
&setprim.ssp_addr, live_fd)) {
return STATUS_ERR;
}
optval = &setprim;
break;
#endif
#ifdef SCTP_ADAPTATION_LAYER
case EXPR_SCTP_SETADAPTATION:
if (get_u32(val_expression->value.sctp_setadaptation->ssb_adaptation_ind,
......@@ -3915,7 +3972,7 @@ static int parse_expression_to_sctp_sndrcvinfo(struct expression *expr,
info->sinfo_assoc_id = 0;
}
} else {
if (get_u32(sndrcvinfo_expr->sinfo_assoc_id, (u32 *)&info->sinfo_assoc_id, error)) {
if (get_sctp_assoc_t(sndrcvinfo_expr->sinfo_assoc_id, &info->sinfo_assoc_id, error)) {
return STATUS_ERR;
}
}
......@@ -3942,7 +3999,7 @@ static int parse_expression_to_sctp_sndinfo(struct expression *expr, struct sctp
if (get_u32(sndinfo_expr->snd_context, &info->snd_context, error)) {
return STATUS_ERR;
}
if (get_u32(sndinfo_expr->snd_assoc_id, &info->snd_assoc_id, error)) {
if (get_sctp_assoc_t(sndinfo_expr->snd_assoc_id, &info->snd_assoc_id, error)) {
return STATUS_ERR;
}
} else {
......@@ -5047,7 +5104,7 @@ static int syscall_sctp_peeloff(struct state *state, struct syscall_spec *syscal
if (to_live_fd(state, script_fd, &live_fd, error))
return STATUS_ERR;
expr_assoc = get_arg(args, 1, error);
if (get_u32(expr_assoc, (u32 *)&assoc_id, error))
if (get_sctp_assoc_t(expr_assoc, &assoc_id, error))
return STATUS_ERR;
//check connection Type and set assoc_id if one-to-many style socket
......@@ -5094,7 +5151,7 @@ static int syscall_sctp_getpaddrs(struct state *state, struct syscall_spec *sysc
if (to_live_fd(state, script_fd, &live_fd, error))
return STATUS_ERR;
assoc_expr = get_arg(args, 1, error);
if (get_u32(assoc_expr, (u32 *)&assoc_id, error))
if (get_sctp_assoc_t(assoc_expr, (u32 *)&assoc_id, error))
return STATUS_ERR;
begin_syscall(state, syscall);
......@@ -5179,7 +5236,7 @@ static int syscall_sctp_getladdrs(struct state *state, struct syscall_spec *sysc
if (to_live_fd(state, script_fd, &live_fd, error))
return STATUS_ERR;
assoc_expr = get_arg(args, 1, error);
if (get_u32(assoc_expr, (u32 *)&assoc_id, error))
if (get_sctp_assoc_t(assoc_expr, &assoc_id, error))
return STATUS_ERR;
begin_syscall(state, syscall);
......
......@@ -79,6 +79,7 @@ struct expression_type_entry expression_type_table[] = {
{ EXPR_SCTP_EVENT, "sctp_event" },
{ EXPR_SCTP_EVENT_SUBSCRIBE, "sctp_event_subscribe"},
{ EXPR_SCTP_SNDINFO, "sctp_sndinfo" },
{ EXPR_SCTP_SETPRIM, "sctp_setprim" },
{ EXPR_SCTP_SETADAPTATION, "sctp_setadaptation"},
{ EXPR_SCTP_SNDRCVINFO, "sctp_sndrcvinfo" },
{ EXPR_SCTP_PRINFO, "sctp_prinfo" },
......@@ -400,6 +401,10 @@ void free_expression(struct expression *expression)
free_expression(expression->value.sctp_sndinfo->snd_ppid);
free_expression(expression->value.sctp_sndinfo->snd_context);
free_expression(expression->value.sctp_sndinfo->snd_assoc_id);
break;
case EXPR_SCTP_SETPRIM:
free_expression(expression->value.sctp_setprim->ssp_assoc_id);
free_expression(expression->value.sctp_setprim->ssp_addr);
break;
case EXPR_SCTP_SETADAPTATION:
free_expression(expression->value.sctp_setadaptation->ssb_adaptation_ind);
......@@ -1243,6 +1248,34 @@ static int evaluate_sctp_sndinfo_expression(struct expression *in,
return STATUS_OK;
}
static int evaluate_sctp_setprim_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_setprim_expr *in_prim;
struct sctp_setprim_expr *out_prim;
assert(in->type == EXPR_SCTP_SETPRIM);
assert(in->value.sctp_setprim);
assert(out->type == EXPR_SCTP_SETPRIM);
out->value.sctp_setprim = calloc(1, sizeof(struct sctp_setprim_expr));
in_prim = in->value.sctp_setprim;
out_prim = out->value.sctp_setprim;
if (evaluate(in_prim->ssp_assoc_id,
&out_prim->ssp_assoc_id,
error))
return STATUS_ERR;
if (evaluate(in_prim->ssp_addr,
&out_prim->ssp_addr,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_setadaptation_expression(struct expression *in,
struct expression *out,
char **error)
......@@ -2145,6 +2178,9 @@ static int evaluate(struct expression *in,
case EXPR_SCTP_SNDINFO:
result = evaluate_sctp_sndinfo_expression(in, out, error);
break;
case EXPR_SCTP_SETPRIM:
result = evaluate_sctp_setprim_expression(in, out, error);
break;
case EXPR_SCTP_SETADAPTATION:
result = evaluate_sctp_setadaptation_expression(in, out, error);
break;
......
......@@ -59,6 +59,7 @@ enum expression_t {
EXPR_SCTP_EVENT, /* struct sctp_event for SCTP_EVENT */
EXPR_SCTP_EVENT_SUBSCRIBE,/* struct sctp_event_subscribe for SCTP_EVENTS */
EXPR_SCTP_SNDINFO, /* struct sctp_sndinfo for SCTP_DEFAULT_SNDINFO */
EXPR_SCTP_SETPRIM, /* expression tree for sctp_setprim SCTP_PRIMARY_ADDR */
EXPR_SCTP_SETADAPTATION, /* struct sctp_setadaptation for SCTP_ADATTATION_LAYER */
EXPR_SCTP_SNDRCVINFO, /* struct sctp_sndrcvinfo for syscall sctp_recvmsg */
EXPR_SCTP_PRINFO, /* struct sctp_prinfo for syscall sctp_sendv */
......@@ -111,6 +112,7 @@ struct expression {
struct sctp_event_expr *sctp_event;
struct sctp_event_subscribe_expr *sctp_event_subscribe;
struct sctp_sndinfo_expr *sctp_sndinfo;
struct sctp_setprim_expr *sctp_setprim;
struct sctp_setadaptation_expr *sctp_setadaptation;
struct sctp_sndrcvinfo_expr *sctp_sndrcvinfo;
struct sctp_prinfo_expr *sctp_prinfo;
......@@ -294,6 +296,12 @@ struct sctp_sndinfo_expr {
struct expression *snd_assoc_id;
};
/* Parse tree for sctp_setadaptation struct in [gs]etsockopt syscall. */
struct sctp_setprim_expr {
struct expression *ssp_assoc_id;
struct expression *ssp_addr;
};
/* Parse tree for sctp_setadaptation struct in [gs]etsockopt syscall. */
struct sctp_setadaptation_expr {
struct expression *ssb_adaptation_ind;
......
......@@ -84,6 +84,7 @@ struct int_symbol platform_symbols_table[] = {
{ SCTP_INITMSG, "SCTP_INITMSG" },
{ SCTP_INIT, "SCTP_INIT" },
{ SCTP_NODELAY, "SCTP_NODELAY" },
{ SCTP_PRIMARY_ADDR, "SCTP_PRIMARY_ADDR" },
{ SCTP_ADAPTATION_LAYER, "SCTP_ADAPTATION_LAYER" },
{ SCTP_MAXSEG, "SCTP_MAXSEG" },
{ SCTP_DELAYED_SACK, "SCTP_DELAYED_SACK" },
......
......@@ -8,7 +8,10 @@
+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
+0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
+0 setsockopt(3, IPPROTO_SCTP, SCTP_PRIMARY_ADDR, {ssp_assoc_id=0, ssp_addr={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")}}, 136) = 0
+0 getsockopt(3, IPPROTO_SCTP, SCTP_PRIMARY_ADDR, {ssp_assoc_id=0, ssp_addr={sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")}}, [136]) = 0
+0 setsockopt(3, IPPROTO_SCTP, SCTP_STATUS, {sstat_state=..., sstat_rwnd=..., sstat_unackdata=..., sstat_penddata=...,
sstat_instrms=..., sstat_outstrms=..., sstat_fragmentation_point=..., sstat_primary=...}, 176) = -1
......
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