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

add support for sctp_get_assoc_id_lists for [gs]etsockopt, shoult end in an...

add support for sctp_get_assoc_id_lists for [gs]etsockopt, shoult end in an error but didn't do taht for one-to-one socket
parent f8ed864e
No related branches found
No related tags found
No related merge requests found
......@@ -382,6 +382,8 @@ sai_assoc_id return SAI_ASSOC_ID;
sn_type return SN_TYPE;
sn_length return SN_LENGTH;
sn_flags return SN_FLAGS;
gaids_number_of_ids return GAIDS_NUMBER_OF_IDS;
gaids_assoc_id return GAIDS_ASSOC_ID;
CHUNK return CHUNK;
DATA return DATA;
INIT return INIT;
......
......@@ -564,6 +564,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
%token <reserved> SPC_TYPE SPC_FLAGS SPC_LENGTH SPC_AADDR SPC_STATE SPC_ERROR SPC_ASSOC_ID
%token <reserved> SSF_TYPE SSF_LENGTH SSF_FLAGS SSF_ERROR SSF_INFO SSF_ASSOC_ID SSF_DATA
%token <reserved> SAI_TYPE SAI_FLAGS SAI_LENGTH SAI_ADAPTATION_IND SAI_ASSOC_ID
%token <reserved> GAIDS_NUMBER_OF_IDS GAIDS_ASSOC_ID
%token <reserved> SN_TYPE SN_FLAGS SN_LENGTH
%token <floating> FLOAT
%token <integer> INTEGER HEX_INTEGER
......@@ -635,7 +636,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
%type <expression> sctp_paddr_change spc_type spc_flags spc_length spc_aaddr spc_error spc_state
%type <expression> sctp_send_failed ssf_type ssf_length ssf_flags ssf_error ssf_info ssf_data
%type <expression> sctp_adaptation_event sai_type sai_flags sai_length sai_adaptation_ind
%type <expression> sctp_tlv sn_type sn_flags sn_length
%type <expression> sctp_tlv sn_type sn_flags sn_length sctp_assoc_ids gaids_number_of_ids
%type <errno_info> opt_errno
%type <chunk_list> sctp_chunk_list_spec
%type <chunk_list_item> sctp_chunk_spec
......@@ -2547,6 +2548,9 @@ expression
| sctp_recvv_rn {
$$ = $1;
}
| sctp_assoc_ids {
$$ = $1;
}
| null {
$$ = $1;
}
......@@ -4763,6 +4767,24 @@ sctp_tlv
}
;
gaids_number_of_ids
: GAIDS_NUMBER_OF_IDS '=' INTEGER {
if (!is_valid_u32($3)) {
semantic_error("gaids_number_of_ids out of range");
}
$$ = new_integer_expression($3, "%u");
}
| GAIDS_NUMBER_OF_IDS '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); }
;
sctp_assoc_ids
: '{' gaids_number_of_ids ',' GAIDS_ASSOC_ID '=' array '}' {
$$ = new_expression(EXPR_SCTP_ASSOC_IDS);
$$->value.sctp_assoc_ids = calloc(1, sizeof(struct sctp_assoc_ids_expr));
$$->value.sctp_assoc_ids->gaids_number_of_ids = $2;
$$->value.sctp_assoc_ids->gaids_assoc_id = $6;
};
opt_errno
: { $$ = NULL; }
| WORD note {
......
......@@ -2982,6 +2982,45 @@ static int check_sctp_hamcalgo(struct sctp_hmacalgo_expr *expr,
return STATUS_OK;
}
static int check_sctp_assoc_ids(struct sctp_assoc_ids_expr *expr,
struct sctp_assoc_ids *sctp_assoc_ids,
char **error) {
int list_len = 0, i = 0;
struct expression *assoc_id;
struct expression_list *ids;
if (check_u32_expr(expr->gaids_number_of_ids, sctp_assoc_ids->gaids_number_of_ids,
"sctp_assoc_ids.gaids_number_of_ids", error)) {
return STATUS_ERR;
}
ids = expr->gaids_assoc_id->value.list;
list_len = expression_list_length(ids);
if (list_len != sctp_assoc_ids->gaids_number_of_ids) {
asprintf(error, "live gaids_number_if_ids unequal to length if expected gaids_assoc_id. actual %u, expected %d",
sctp_assoc_ids->gaids_number_of_ids, list_len);
return STATUS_ERR;
}
if (list_len == 1) {
assoc_id = get_arg(ids, 0, error);
if (assoc_id->type == EXPR_ELLIPSIS) {
return STATUS_OK;
}
}
for (i = 0; i < list_len; i++) {
assoc_id = get_arg(ids, i, error);
sctp_assoc_t script_id;
if (get_sctp_assoc_t(assoc_id, &script_id, error)) {
return STATUS_ERR;
}
if (script_id != sctp_assoc_ids->gaids_assoc_id[i]) {
asprintf(error, "sctp_assoc_ids.gaids_assoc_id[%d]. expected %u, actual %u",
i, script_id, sctp_assoc_ids->gaids_assoc_id[i]);
return STATUS_ERR;
}
}
return STATUS_OK;
}
static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
struct expression_list *args, char **error)
{
......@@ -3226,6 +3265,14 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
live_optval = malloc(sizeof(struct sctp_setadaptation));
live_optlen = sizeof(struct sctp_setadaptation);
break;
#endif
#ifdef SCTP_GET_ASSOC_ID_LIST
case EXPR_SCTP_ASSOC_IDS: {
s32 len = expression_list_length(val_expression->value.sctp_assoc_ids->gaids_assoc_id->value.list);
live_optval = malloc(sizeof(u32) + (sizeof(sctp_assoc_t) * len));
live_optlen = sizeof(u32) + (sizeof(sctp_assoc_t) * len);
break;
}
#endif
case EXPR_LIST:
s32_bracketed_arg(args, 3, &script_optval, error);
......@@ -3347,6 +3394,12 @@ static int syscall_getsockopt(struct state *state, struct syscall_spec *syscall,
case EXPR_SCTP_SETADAPTATION:
result = check_sctp_setadaptation(val_expression->value.sctp_setadaptation, live_optval, error);
break;
#endif
#ifdef SCTP_GET_ASSOC_ID_LIST
case EXPR_SCTP_ASSOC_IDS: {
result = check_sctp_assoc_ids(val_expression->value.sctp_assoc_ids, live_optval, error);
break;
}
#endif
case EXPR_LIST:
if (*(int*)live_optval != script_optval) {
......
......@@ -103,6 +103,7 @@ struct expression_type_entry expression_type_table[] = {
{ EXPR_SCTP_SEND_FAILED_EVENT,"sctp_send_failed_event"},
{ EXPR_SCTP_TLV, "sctp_tlv" },
{ EXPR_SCTP_EXTRCVINFO, "sctp_extrcvinfo" },
{ EXPR_SCTP_ASSOC_IDS, "sctp_assoc_ids" },
{ NUM_EXPR_TYPES, NULL}
};
......@@ -580,6 +581,10 @@ void free_expression(struct expression *expression)
free_expression(expression->value.sctp_extrcvinfo->serinfo_next_ppid);
free_expression(expression->value.sctp_extrcvinfo->sinfo_assoc_id);
break;
case EXPR_SCTP_ASSOC_IDS:
free_expression(expression->value.sctp_assoc_ids->gaids_number_of_ids);
free_expression(expression->value.sctp_assoc_ids->gaids_assoc_id);
break;
case EXPR_WORD:
assert(expression->value.string);
free(expression->value.string);
......@@ -2247,6 +2252,33 @@ static int evaluate_sctp_extrcvinfo_expression(struct expression *in,
return STATUS_OK;
}
static int evaluate_sctp_assoc_ids_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_assoc_ids_expr *in_ids;
struct sctp_assoc_ids_expr *out_ids;
assert(in->type == EXPR_SCTP_ASSOC_IDS);
assert(in->value.sctp_assoc_ids);
assert(out->type == EXPR_SCTP_ASSOC_IDS);
out->value.sctp_assoc_ids = calloc(1, sizeof(struct sctp_assoc_ids_expr));
in_ids = in->value.sctp_assoc_ids;
out_ids = out->value.sctp_assoc_ids;
if (evaluate(in_ids->gaids_number_of_ids,
&out_ids->gaids_number_of_ids,
error))
return STATUS_ERR;
if (evaluate(in_ids->gaids_assoc_id,
&out_ids->gaids_assoc_id,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate(struct expression *in,
struct expression **out_ptr, char **error)
{
......@@ -2380,6 +2412,9 @@ static int evaluate(struct expression *in,
case EXPR_SCTP_EXTRCVINFO:
result = evaluate_sctp_extrcvinfo_expression(in, out, error);
break;
case EXPR_SCTP_ASSOC_IDS:
result = evaluate_sctp_assoc_ids_expression(in, out, error);
break;
case EXPR_WORD:
out->type = EXPR_INTEGER;
if (symbol_to_int(in->value.string,
......
......@@ -83,6 +83,7 @@ enum expression_t {
EXPR_SCTP_SEND_FAILED_EVENT, /* expression tree for sctp_send_failed_event */
EXPR_SCTP_TLV, /* expression tree for sctp_notifications_stopped_event */
EXPR_SCTP_EXTRCVINFO, /* expression tree for sctp_extrcvinfo struct in cmsghdr */
EXPR_SCTP_ASSOC_IDS, /* expression tree for sctp_assoc_ids struct for [gs]etsockopt */
NUM_EXPR_TYPES,
};
/* Convert an expression type to a human-readable string */
......@@ -139,6 +140,7 @@ struct expression {
struct sctp_send_failed_event_expr *sctp_send_failed_event;
struct sctp_tlv_expr *sctp_tlv;
struct sctp_extrcvinfo_expr *sctp_extrcvinfo;
struct sctp_assoc_ids_expr *sctp_assoc_ids;
} value;
const char *format; /* the printf format for printing the value */
};
......@@ -523,6 +525,12 @@ struct sctp_extrcvinfo_expr {
struct expression *sinfo_assoc_id;
};
/* Parse tree for sctp_extrcvinfo struct for cmsg. */
struct sctp_assoc_ids_expr {
struct expression *gaids_number_of_ids;
struct expression *gaids_assoc_id;
};
/* The errno-related info from strace to summarize a system call error */
struct errno_spec {
const char *errno_macro; /* errno symbol (C macro name) */
......
......@@ -108,6 +108,7 @@ struct int_symbol platform_symbols_table[] = {
{ SCTP_STATUS, "SCTP_STATUS" },
{ SCTP_GET_PEER_ADDR_INFO, "SCTP_GET_PEER_ADDR_INFO" },
{ SCTP_GET_ASSOC_NUMBER, "SCTP_GET_ASSOC_NUMBER" },
{ SCTP_GET_ASSOC_ID_LIST, "SCTP_GET_ASSOC_ID_LIST" },
{ SCTP_FRAGMENT_INTERLEAVE, "SCTP_FRAGMENT_INTERLEAVE" },
#if defined(SCTP_INTERLEAVING_SUPPORTED)
{ SCTP_INTERLEAVING_SUPPORTED, "SCTP_INTERLEAVING_SUPPORTED" },
......
......@@ -10,6 +10,6 @@
+0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0
+0 getsockopt(3, IPPROTO_SCTP, SCTP_GET_ASSOC_ID_LIST, {gaids_number_of_ids=0, gaids_assoc_id=[...]}, [0]) = -1
+0 getsockopt(3, IPPROTO_SCTP, SCTP_GET_ASSOC_ID_LIST, {gaids_number_of_ids=1, gaids_assoc_id=[3]}, [8]) = -1
+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