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

add support for sctp_sendv

parent d9f02651
No related branches found
No related tags found
No related merge requests found
...@@ -202,6 +202,8 @@ ect0 return ECT0; ...@@ -202,6 +202,8 @@ ect0 return ECT0;
ect1 return ECT1; ect1 return ECT1;
noecn return NO_ECN; noecn return NO_ECN;
ce return CE; ce return CE;
iov_base return IOV_BASE;
iov_len return IOV_LEN;
[.][.][.] return ELLIPSIS; [.][.][.] return ELLIPSIS;
assoc_value return ASSOC_VALUE; assoc_value return ASSOC_VALUE;
stream_id return STREAM_ID; stream_id return STREAM_ID;
...@@ -256,6 +258,13 @@ sinfo_context return SINFO_CONTEXT; ...@@ -256,6 +258,13 @@ sinfo_context return SINFO_CONTEXT;
sinfo_timetolive return SINFO_TIMETOLIVE; sinfo_timetolive return SINFO_TIMETOLIVE;
sinfo_tsn return SINFO_TSN; sinfo_tsn return SINFO_TSN;
sinfo_cumtsn return SINFO_CUMTSN; sinfo_cumtsn return SINFO_CUMTSN;
pr_policy return PR_POLICY;
pr_value return PR_VALUE;
auth_keynumber return AUTH_KEYNUMBER;
sendv_flags return SENDV_FLAGS;
sendv_sndinfo return SENDV_SNDINFO;
sendv_prinfo return SENDV_PRINFO;
sendv_authinfo return SENDV_AUTHINFO;
CHUNK return CHUNK; CHUNK return CHUNK;
DATA return DATA; DATA return DATA;
INIT return INIT; INIT return INIT;
......
...@@ -498,6 +498,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, ...@@ -498,6 +498,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
%token <reserved> FD EVENTS REVENTS ONOFF LINGER %token <reserved> FD EVENTS REVENTS ONOFF LINGER
%token <reserved> ACK ECR EOL MSS NOP SACK SACKOK TIMESTAMP VAL WIN WSCALE PRO %token <reserved> ACK ECR EOL MSS NOP SACK SACKOK TIMESTAMP VAL WIN WSCALE PRO
%token <reserved> FAST_OPEN %token <reserved> FAST_OPEN
%token <reserved> IOV_BASE IOV_LEN
%token <reserved> ECT0 ECT1 CE ECT01 NO_ECN %token <reserved> ECT0 ECT1 CE ECT01 NO_ECN
%token <reserved> IPV4 IPV6 ICMP SCTP UDP UDPLITE GRE MTU %token <reserved> IPV4 IPV6 ICMP SCTP UDP UDPLITE GRE MTU
%token <reserved> MPLS LABEL TC TTL %token <reserved> MPLS LABEL TC TTL
...@@ -541,6 +542,8 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, ...@@ -541,6 +542,8 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
%token <reserved> BAD_CRC32C NULL_ %token <reserved> BAD_CRC32C NULL_
%token <reserved> SINFO_STREAM SINFO_SSN SINFO_FLAGS SINFO_PPID SINFO_CONTEXT %token <reserved> SINFO_STREAM SINFO_SSN SINFO_FLAGS SINFO_PPID SINFO_CONTEXT
%token <reserved> SINFO_TIMETOLIVE SINFO_TSN SINFO_CUMTSN %token <reserved> SINFO_TIMETOLIVE SINFO_TSN SINFO_CUMTSN
%token <reserved> PR_POLICY PR_VALUE AUTH_KEYNUMBER SENDV_FLAGS SENDV_SNDINFO
%token <reserved> SENDV_PRINFO SENDV_AUTHINFO
%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
...@@ -593,6 +596,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, ...@@ -593,6 +596,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string,
%type <expression> sctp_event se_type se_on sctp_setadaptation null %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 <expression> sinfo_timetolive sinfo_tsn sinfo_cumtsn
%type <expression> sctp_prinfo sctp_authinfo pr_policy sctp_sendv_spa
%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
...@@ -2456,10 +2460,19 @@ expression ...@@ -2456,10 +2460,19 @@ expression
| sctp_setadaptation{ | sctp_setadaptation{
$$ = $1; $$ = $1;
} }
| null { | sctp_sndrcvinfo {
$$ = $1; $$ = $1;
} }
| sctp_sndrcvinfo { | sctp_prinfo {
$$ = $1;
}
| sctp_authinfo {
$$ = $1;
}
| sctp_sendv_spa {
$$ = $1;
}
| null {
$$ = $1; $$ = $1;
} }
; ;
...@@ -2562,6 +2575,13 @@ iovec ...@@ -2562,6 +2575,13 @@ iovec
iov_expr->iov_base = new_expression(EXPR_ELLIPSIS); iov_expr->iov_base = new_expression(EXPR_ELLIPSIS);
iov_expr->iov_len = $4; iov_expr->iov_len = $4;
} }
| '{' IOV_BASE '=' ELLIPSIS ',' IOV_LEN '=' decimal_integer '}' {
struct iovec_expr *iov_expr = calloc(1, sizeof(struct iovec_expr));
$$ = new_expression(EXPR_IOVEC);
$$->value.iovec = iov_expr;
iov_expr->iov_base = new_expression(EXPR_ELLIPSIS);
iov_expr->iov_len = $8;
}
; ;
pollfd pollfd
...@@ -3228,6 +3248,53 @@ sctp_sndrcvinfo ...@@ -3228,6 +3248,53 @@ sctp_sndrcvinfo
$$->value.sctp_sndrcvinfo->sinfo_tsn = $14; $$->value.sctp_sndrcvinfo->sinfo_tsn = $14;
$$->value.sctp_sndrcvinfo->sinfo_cumtsn = $16; $$->value.sctp_sndrcvinfo->sinfo_cumtsn = $16;
}; };
pr_policy
: PR_POLICY '=' WORD {
$$ = new_expression(EXPR_WORD);
$$->value.string = $3;
}
| PR_POLICY '=' INTEGER {
if (!is_valid_u16($3)) {
semantic_error("pr_policy out of range");
}
$$ = new_integer_expression($3, "%hu");
};
sctp_prinfo
: '{' pr_policy ',' PR_VALUE '=' INTEGER'}' {
$$ = new_expression(EXPR_SCTP_PRINFO);
$$->value.sctp_prinfo = calloc(1, sizeof(struct sctp_prinfo_expr));
$$->value.sctp_prinfo->pr_policy = $2;
if (!is_valid_u32($6)) {
semantic_error("pr_value out of range");
}
$$->value.sctp_prinfo->pr_value = new_integer_expression($6, "%u");
}
;
sctp_authinfo
: '{' AUTH_KEYNUMBER '=' INTEGER '}' {
$$ = new_expression(EXPR_SCTP_AUTHINFO);
$$->value.sctp_authinfo = calloc(1, sizeof(struct sctp_authinfo_expr));
if (!is_valid_u16($4)) {
semantic_error("auth_keynumber out of range");
}
$$->value.sctp_authinfo->auth_keynumber = new_integer_expression($4, "%hu");
}
;
sctp_sendv_spa
: '{' SENDV_FLAGS '=' expression ',' SENDV_SNDINFO '=' expression ',' SENDV_PRINFO '=' expression ',' SENDV_AUTHINFO '=' expression '}' {
$$ = new_expression(EXPR_SCTP_SENDV_SPA);
$$->value.sctp_sendv_spa = calloc(1, sizeof(struct sctp_sendv_spa_expr));
$$->value.sctp_sendv_spa->sendv_flags = $4;
$$->value.sctp_sendv_spa->sendv_sndinfo = $8;
$$->value.sctp_sendv_spa->sendv_prinfo = $12;
$$->value.sctp_sendv_spa->sendv_authinfo = $16;
}
;
opt_errno opt_errno
: { $$ = NULL; } : { $$ = NULL; }
| WORD note { | WORD note {
......
...@@ -122,7 +122,44 @@ static int get_arg_count(struct expression_list *args) ...@@ -122,7 +122,44 @@ static int get_arg_count(struct expression_list *args)
{ {
return expression_list_length(args); return expression_list_length(args);
} }
/* This table maps expression types to human-readable strings */
struct expression_type_entry {
enum expression_t type;
const char *name;
};
struct expression_type_entry expression_type_table2[] = {
{ EXPR_NONE, "none" },
{ EXPR_NULL, "null" },
{ EXPR_ELLIPSIS, "ellipsis" },
{ EXPR_INTEGER, "integer" },
{ EXPR_WORD, "word" },
{ EXPR_STRING, "string" },
{ EXPR_SOCKET_ADDRESS_IPV4, "sockaddr_in" },
{ EXPR_SOCKET_ADDRESS_IPV6, "sockaddr_in6" },
{ EXPR_LINGER, "linger" },
{ EXPR_BINARY, "binary_expression" },
{ EXPR_LIST, "list" },
{ EXPR_IOVEC, "iovec" },
{ EXPR_MSGHDR, "msghdr" },
{ EXPR_POLLFD, "pollfd" },
{ EXPR_SCTP_RTOINFO, "sctp_rtoinfo"},
{ EXPR_SCTP_INITMSG, "sctp_initmsg"},
{ EXPR_SCTP_ASSOC_VALUE, "sctp_assoc_value"},
{ EXPR_SCTP_SACKINFO, "sctp_sackinfo"},
{ EXPR_SCTP_STATUS, "sctp_status"},
{ EXPR_SCTP_PADDRINFO, "sctp_paddrinfo"},
{ EXPR_SCTP_PEER_ADDR_PARAMS,"sctp_peer_addr_params"},
{ EXPR_SCTP_STREAM_VALUE, "sctp_stream_value"},
{ EXPR_SCTP_ASSOCPARAMS, "sctp_assocparams"},
{ EXPR_SCTP_EVENT, "sctp_event" },
{ EXPR_SCTP_SNDINFO, "sctp_sndinfo" },
{ EXPR_SCTP_SETADAPTATION, "sctp_setadaptation"},
{ EXPR_SCTP_SNDRCVINFO, "sctp_sndrcvinfo" },
{ EXPR_SCTP_PRINFO, "sctp_prinfo" },
{ EXPR_SCTP_AUTHINFO, "sctp_authinfo" },
{ EXPR_SCTP_SENDV_SPA, "sctp_sendv_spa" },
{ NUM_EXPR_TYPES, NULL}
};
/* Verify that the expression list has the expected number of /* Verify that the expression list has the expected number of
* expressions. Returns STATUS_OK on success; on failure returns * expressions. Returns STATUS_OK on success; on failure returns
* STATUS_ERR and sets error message. * STATUS_ERR and sets error message.
...@@ -3043,11 +3080,10 @@ static int syscall_sctp_sendmsg(struct state *state, struct syscall_spec *syscal ...@@ -3043,11 +3080,10 @@ static int syscall_sctp_sendmsg(struct state *state, struct syscall_spec *syscal
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); tolen, ppid, flags, stream_no, timetolive, context);
free(msg);
if (end_syscall(state, syscall, CHECK_EXACT, result, error)) { if (end_syscall(state, syscall, CHECK_EXACT, result, error)) {
free(msg);
return STATUS_ERR; return STATUS_ERR;
} }
free(msg);
return STATUS_OK; return STATUS_OK;
#else #else
asprintf(error, "sctp_sendmsg is not supported"); asprintf(error, "sctp_sendmsg is not supported");
...@@ -3294,6 +3330,207 @@ static int syscall_sctp_recvmsg(struct state *state, struct syscall_spec *syscal ...@@ -3294,6 +3330,207 @@ static int syscall_sctp_recvmsg(struct state *state, struct syscall_spec *syscal
#endif #endif
} }
int parse_expression_to_sctp_sndinfo(struct expression *expr, struct sctp_sndinfo *info, char **error) {
if (expr->type == EXPR_SCTP_SNDINFO) {
struct sctp_sndinfo_expr *sndinfo_expr = expr->value.sctp_sndinfo;
info->snd_assoc_id = 0;
if (get_u16(sndinfo_expr->snd_sid, &info->snd_sid, error)) {
return STATUS_ERR;
}
if (get_u16(sndinfo_expr->snd_flags, &info->snd_flags, error)) {
return STATUS_ERR;
}
if (get_u32(sndinfo_expr->snd_ppid, &info->snd_ppid, error)) {
return STATUS_ERR;
}
if (get_u32(sndinfo_expr->snd_context, &info->snd_context, error)) {
return STATUS_ERR;
}
} else {
return STATUS_ERR;
}
return STATUS_OK;
}
int parse_expression_to_sctp_authinfo(struct expression *expr, struct sctp_authinfo *info, char **error) {
if (expr->type == EXPR_SCTP_AUTHINFO) {
struct sctp_authinfo_expr *auth_expr = expr->value.sctp_authinfo;
if (get_u16(auth_expr->auth_keynumber, &info->auth_keynumber, error)) {
return STATUS_ERR;
}
} else {
return STATUS_ERR;
}
return STATUS_OK;
}
int parse_expression_to_sctp_prinfo(struct expression *expr, struct sctp_prinfo *info, char **error) {
if (expr->type == EXPR_SCTP_PRINFO) {
struct sctp_prinfo_expr *prinfo_expr = expr->value.sctp_prinfo;
if (get_u16(prinfo_expr->pr_policy, &info->pr_policy, error)) {
return STATUS_ERR;
}
if (get_u32(prinfo_expr->pr_value, &info->pr_value, error)) {
return STATUS_ERR;
}
} else {
return STATUS_ERR;
}
return STATUS_OK;
}
int parse_expression_to_sctp_sendv_spa(struct expression *expr, struct sctp_sendv_spa *info, char **error) {
if (expr->type == EXPR_SCTP_SENDV_SPA) {
struct sctp_sendv_spa_expr *spa_expr = expr->value.sctp_sendv_spa;
if (get_u32(spa_expr->sendv_flags, &info->sendv_flags, error)) {
return STATUS_ERR;
}
if (spa_expr->sendv_sndinfo->type != EXPR_ELLIPSIS) {
if (parse_expression_to_sctp_sndinfo(spa_expr->sendv_sndinfo, &info->sendv_sndinfo, error))
return STATUS_ERR;
}
if (spa_expr->sendv_sndinfo->type != EXPR_ELLIPSIS) {
if (parse_expression_to_sctp_prinfo(spa_expr->sendv_prinfo, &info->sendv_prinfo, error))
return STATUS_ERR;
}
if (spa_expr->sendv_sndinfo->type != EXPR_ELLIPSIS) {
if (parse_expression_to_sctp_authinfo(spa_expr->sendv_authinfo, &info->sendv_authinfo, error))
return STATUS_ERR;
}
} else {
return STATUS_ERR;
}
return STATUS_OK;
}
static int syscall_sctp_sendv(struct state *state, struct syscall_spec *syscall,
struct expression_list *args,
char **error)
{
#if defined(__FreeBSD__)
int script_fd, live_fd, iovcnt, addrcnt, result, flags;
u32 infotype, script_iovec_list_len = 0;
socklen_t infolen;
struct sockaddr *addrs;
void *info;
struct iovec *iov;
struct expression *iovec_expr_list, *iovcnt_expr, *addrs_expr, *addrcnt_expr;
struct expression *info_expr, *infolen_expr, *infotype_expr, *flags_expr;
struct sctp_sndinfo sndinfo;
struct sctp_prinfo prinfo;
struct sctp_authinfo authinfo;
struct sctp_sendv_spa spa;
if (check_arg_count(args, 9, error))
return STATUS_ERR;
if (s32_arg(args, 0, &script_fd, error))
return STATUS_ERR;
if (to_live_fd(state, script_fd, &live_fd, error))
return STATUS_ERR;
iovec_expr_list = get_arg(args, 1, error);
iovec_new(iovec_expr_list, &iov, &script_iovec_list_len, error);
iovcnt_expr = get_arg(args, 2, error);
if (get_s32(iovcnt_expr, &iovcnt, error))
return STATUS_ERR;
addrs_expr = get_arg(args, 3, error);
if (addrs_expr->type == EXPR_NULL) {
addrs = NULL;
} else if (addrs_expr->type == EXPR_SOCKET_ADDRESS_IPV4 ||
addrs_expr->type == EXPR_SOCKET_ADDRESS_IPV6 ||
addrs_expr->type == EXPR_ELLIPSIS) {
addrs = malloc(sizeof(struct sockaddr_storage));
get_sockstorage_arg(addrs_expr, (struct sockaddr_storage *)addrs, live_fd);
} else if (addrs_expr->type == EXPR_LIST) {
struct expression_list *addrs_expr_list = (struct expression_list *)addrs_expr->value.list;
struct expression *expr;
int addrlen = expression_list_length(addrs_expr_list);
int i = 0;
size_t size = 0;
struct sockaddr *addr_ptr;
for (i = 0; i < addrlen; i++) {
expr = get_arg(addrs_expr_list, i, error);
if (expr->type == EXPR_SOCKET_ADDRESS_IPV4) {
size += sizeof(struct sockaddr_in);
} else if (expr->type == EXPR_SOCKET_ADDRESS_IPV6) {
size += sizeof(struct sockaddr_in);
} else {
return STATUS_ERR;
}
}
addrs = malloc(size);
addr_ptr = (struct sockaddr *)addrs;
for(i = 0; i < addrlen; i++) {
expr = get_arg(addrs_expr_list, i, error);
if (expr->type == EXPR_SOCKET_ADDRESS_IPV4) {
size = sizeof(struct sockaddr_in);
memcpy(expr->value.socket_address_ipv4, addr_ptr, size);
addr_ptr = addr_ptr + sizeof(struct sockaddr_in);
} else if (expr->type == EXPR_SOCKET_ADDRESS_IPV6) {
size = sizeof(struct sockaddr_in);
memcpy(expr->value.socket_address_ipv6, addr_ptr, size);
addr_ptr = addr_ptr + sizeof(struct sockaddr_in6);
}
}
} else {
return STATUS_ERR;
}
addrcnt_expr = get_arg(args, 4, error);
if (get_s32(addrcnt_expr, &addrcnt, error))
return STATUS_ERR;
info_expr = get_arg(args, 5, error);
if (info_expr->type == EXPR_SCTP_SNDINFO) {
if (parse_expression_to_sctp_sndinfo(info_expr, &sndinfo, error))
return STATUS_ERR;
info = &sndinfo;
} else if (info_expr->type == EXPR_SCTP_PRINFO) {
info = malloc(sizeof(struct sctp_prinfo));
if (parse_expression_to_sctp_prinfo(info_expr, &prinfo, error))
return STATUS_ERR;
info = &prinfo;
} else if (info_expr->type == EXPR_SCTP_AUTHINFO) {
if (parse_expression_to_sctp_authinfo(info_expr, &authinfo, error))
return STATUS_ERR;
info = &authinfo;
} else if (info_expr->type == EXPR_SCTP_SENDV_SPA) {
if (parse_expression_to_sctp_sendv_spa(info_expr, &spa, error))
return STATUS_ERR;
info = &spa;
} else if (info_expr->type == EXPR_NULL) {
info = NULL;
} else {
asprintf(error, "Bad input for info");
return STATUS_ERR;
}
infolen_expr = get_arg(args, 6, error);
if (get_u32(infolen_expr, &infolen, error))
return STATUS_ERR;
infotype_expr = get_arg(args, 7, error);
if (get_u32(infotype_expr, &infotype, error))
return STATUS_ERR;
flags_expr = get_arg(args, 8, error);
if (get_s32(flags_expr, &flags, error))
return STATUS_ERR;
begin_syscall(state, syscall);
result = sctp_sendv(live_fd, iov, iovcnt, addrs, addrcnt, info, infolen, infotype, flags);
if (end_syscall(state, syscall, CHECK_EXACT, result, error)) {
free(addrs);
iovec_free(iov, script_iovec_list_len);
return STATUS_ERR;
}
free(addrs);
iovec_free(iov, script_iovec_list_len);
return STATUS_OK;
#else
asprintf(error, "sctp_sendv is not supported");
return STATUS_ERR;
#endif
}
/* A dispatch table with all the system calls that we support... */ /* A dispatch table with all the system calls that we support... */
struct system_call_entry { struct system_call_entry {
const char *name; const char *name;
...@@ -3327,6 +3564,7 @@ struct system_call_entry system_call_table[] = { ...@@ -3327,6 +3564,7 @@ struct system_call_entry system_call_table[] = {
{"poll", syscall_poll}, {"poll", syscall_poll},
{"sctp_sendmsg", syscall_sctp_sendmsg}, {"sctp_sendmsg", syscall_sctp_sendmsg},
{"sctp_recvmsg", syscall_sctp_recvmsg}, {"sctp_recvmsg", syscall_sctp_recvmsg},
{"sctp_sendv", syscall_sctp_sendv},
}; };
/* Evaluate the system call arguments and invoke the system call. */ /* Evaluate the system call arguments and invoke the system call. */
......
...@@ -79,6 +79,9 @@ struct expression_type_entry expression_type_table[] = { ...@@ -79,6 +79,9 @@ struct expression_type_entry expression_type_table[] = {
{ EXPR_SCTP_SNDINFO, "sctp_sndinfo" }, { EXPR_SCTP_SNDINFO, "sctp_sndinfo" },
{ EXPR_SCTP_SETADAPTATION, "sctp_setadaptation"}, { EXPR_SCTP_SETADAPTATION, "sctp_setadaptation"},
{ EXPR_SCTP_SNDRCVINFO, "sctp_sndrcvinfo" }, { EXPR_SCTP_SNDRCVINFO, "sctp_sndrcvinfo" },
{ EXPR_SCTP_PRINFO, "sctp_prinfo" },
{ EXPR_SCTP_AUTHINFO, "sctp_authinfo" },
{ EXPR_SCTP_SENDV_SPA, "sctp_sendv_spa" },
{ NUM_EXPR_TYPES, NULL} { NUM_EXPR_TYPES, NULL}
}; };
...@@ -378,6 +381,19 @@ void free_expression(struct expression *expression) ...@@ -378,6 +381,19 @@ void free_expression(struct expression *expression)
free_expression(expression->value.sctp_sndrcvinfo->sinfo_tsn); free_expression(expression->value.sctp_sndrcvinfo->sinfo_tsn);
free_expression(expression->value.sctp_sndrcvinfo->sinfo_cumtsn); free_expression(expression->value.sctp_sndrcvinfo->sinfo_cumtsn);
break; break;
case EXPR_SCTP_PRINFO:
free_expression(expression->value.sctp_prinfo->pr_policy);
free_expression(expression->value.sctp_prinfo->pr_value);
break;
case EXPR_SCTP_AUTHINFO:
free_expression(expression->value.sctp_authinfo->auth_keynumber);
break;
case EXPR_SCTP_SENDV_SPA:
free_expression(expression->value.sctp_sendv_spa->sendv_flags);
free_expression(expression->value.sctp_sendv_spa->sendv_sndinfo);
free_expression(expression->value.sctp_sendv_spa->sendv_prinfo);
free_expression(expression->value.sctp_sendv_spa->sendv_authinfo);
break;
case EXPR_WORD: case EXPR_WORD:
assert(expression->value.string); assert(expression->value.string);
free(expression->value.string); free(expression->value.string);
...@@ -1031,6 +1047,94 @@ static int evaluate_sctp_sndrcvinfo_expression(struct expression *in, ...@@ -1031,6 +1047,94 @@ static int evaluate_sctp_sndrcvinfo_expression(struct expression *in,
return STATUS_OK; return STATUS_OK;
} }
static int evaluate_sctp_prinfo_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_prinfo_expr *in_info;
struct sctp_prinfo_expr *out_info;
assert(in->type == EXPR_SCTP_PRINFO);
assert(in->value.sctp_prinfo);
assert(out->type == EXPR_SCTP_PRINFO);
out->value.sctp_prinfo = calloc(1, sizeof(struct sctp_prinfo_expr));
in_info = in->value.sctp_prinfo;
out_info = out->value.sctp_prinfo;
if (evaluate(in_info->pr_policy,
&out_info->pr_policy,
error))
return STATUS_ERR;
if (evaluate(in_info->pr_value,
&out_info->pr_value,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_authinfo_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_authinfo_expr *in_info;
struct sctp_authinfo_expr *out_info;
assert(in->type == EXPR_SCTP_AUTHINFO);
assert(in->value.sctp_authinfo);
assert(out->type == EXPR_SCTP_AUTHINFO);
out->value.sctp_authinfo = calloc(1, sizeof(struct sctp_authinfo_expr));
in_info = in->value.sctp_authinfo;
out_info = out->value.sctp_authinfo;
if (evaluate(in_info->auth_keynumber,
&out_info->auth_keynumber,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate_sctp_sendv_spa_expression(struct expression *in,
struct expression *out,
char **error)
{
struct sctp_sendv_spa_expr *in_spa;
struct sctp_sendv_spa_expr *out_spa;
assert(in->type == EXPR_SCTP_SENDV_SPA);
assert(in->value.sctp_sendv_spa);
assert(out->type == EXPR_SCTP_SENDV_SPA);
out->value.sctp_sendv_spa = calloc(1, sizeof(struct sctp_sendv_spa_expr));
in_spa = in->value.sctp_sendv_spa;
out_spa = out->value.sctp_sendv_spa;
if (evaluate(in_spa->sendv_flags,
&out_spa->sendv_flags,
error))
return STATUS_ERR;
if (evaluate(in_spa->sendv_sndinfo,
&out_spa->sendv_sndinfo,
error))
return STATUS_ERR;
if (evaluate(in_spa->sendv_prinfo,
&out_spa->sendv_prinfo,
error))
return STATUS_ERR;
if (evaluate(in_spa->sendv_authinfo,
&out_spa->sendv_authinfo,
error))
return STATUS_ERR;
return STATUS_OK;
}
static int evaluate(struct expression *in, static int evaluate(struct expression *in,
struct expression **out_ptr, char **error) struct expression **out_ptr, char **error)
{ {
...@@ -1095,6 +1199,15 @@ static int evaluate(struct expression *in, ...@@ -1095,6 +1199,15 @@ static int evaluate(struct expression *in,
case EXPR_SCTP_SNDRCVINFO: case EXPR_SCTP_SNDRCVINFO:
result = evaluate_sctp_sndrcvinfo_expression(in, out, error); result = evaluate_sctp_sndrcvinfo_expression(in, out, error);
break; break;
case EXPR_SCTP_PRINFO:
result = evaluate_sctp_prinfo_expression(in, out, error);
break;
case EXPR_SCTP_AUTHINFO:
result = evaluate_sctp_authinfo_expression(in, out, error);
break;
case EXPR_SCTP_SENDV_SPA:
result = evaluate_sctp_sendv_spa_expression(in, out, error);
break;
case EXPR_WORD: case EXPR_WORD:
out->type = EXPR_INTEGER; out->type = EXPR_INTEGER;
if (symbol_to_int(in->value.string, if (symbol_to_int(in->value.string,
......
...@@ -59,6 +59,9 @@ enum expression_t { ...@@ -59,6 +59,9 @@ enum expression_t {
EXPR_SCTP_SNDINFO, /* struct sctp_sndinfo for SCTP_DEFAULT_SNDINFO */ EXPR_SCTP_SNDINFO, /* struct sctp_sndinfo for SCTP_DEFAULT_SNDINFO */
EXPR_SCTP_SETADAPTATION, /* struct sctp_setadaptation for SCTP_ADATTATION_LAYER */ EXPR_SCTP_SETADAPTATION, /* struct sctp_setadaptation for SCTP_ADATTATION_LAYER */
EXPR_SCTP_SNDRCVINFO, /* struct sctp_sndrcvinfo for syscall sctp_recvmsg */ EXPR_SCTP_SNDRCVINFO, /* struct sctp_sndrcvinfo for syscall sctp_recvmsg */
EXPR_SCTP_PRINFO, /* struct sctp_prinfo for syscall sctp_sendv */
EXPR_SCTP_AUTHINFO, /* struct sctp_authinfo for syscall sctp_sendv */
EXPR_SCTP_SENDV_SPA, /* struct sctp_sendv_spa for syscall sctp_sendv */
NUM_EXPR_TYPES, NUM_EXPR_TYPES,
}; };
/* Convert an expression type to a human-readable string */ /* Convert an expression type to a human-readable string */
...@@ -91,6 +94,9 @@ struct expression { ...@@ -91,6 +94,9 @@ struct expression {
struct sctp_sndinfo_expr *sctp_sndinfo; struct sctp_sndinfo_expr *sctp_sndinfo;
struct sctp_setadaptation_expr *sctp_setadaptation; struct sctp_setadaptation_expr *sctp_setadaptation;
struct sctp_sndrcvinfo_expr *sctp_sndrcvinfo; struct sctp_sndrcvinfo_expr *sctp_sndrcvinfo;
struct sctp_prinfo_expr *sctp_prinfo;
struct sctp_authinfo_expr *sctp_authinfo;
struct sctp_sendv_spa_expr *sctp_sendv_spa;
} value; } value;
const char *format; /* the printf format for printing the value */ const char *format; /* the printf format for printing the value */
}; };
...@@ -137,6 +143,7 @@ struct linger_expr { ...@@ -137,6 +143,7 @@ struct linger_expr {
struct expression *l_onoff; struct expression *l_onoff;
struct expression *l_linger; struct expression *l_linger;
}; };
/* Parse tree for a sctp_rtoinfo struct in a [gs]etsockopt syscall. */ /* Parse tree for a sctp_rtoinfo struct in a [gs]etsockopt syscall. */
struct sctp_rtoinfo_expr { struct sctp_rtoinfo_expr {
struct expression *srto_initial; struct expression *srto_initial;
...@@ -242,6 +249,25 @@ struct sctp_sndrcvinfo_expr { ...@@ -242,6 +249,25 @@ struct sctp_sndrcvinfo_expr {
struct expression *sinfo_cumtsn; struct expression *sinfo_cumtsn;
}; };
/* Parse tree for sctp_prinfo in sctp_sendv syscall. */
struct sctp_prinfo_expr {
struct expression *pr_policy;
struct expression *pr_value;
};
/* Parse tree for sctp_authinfo in sctp_sendv syscall. */
struct sctp_authinfo_expr {
struct expression *auth_keynumber;
};
/* Parse tree for sctp_sendv_spa in sctp_sendv syscall. */
struct sctp_sendv_spa_expr {
struct expression *sendv_flags;
struct expression *sendv_sndinfo;
struct expression *sendv_prinfo;
struct expression *sendv_authinfo;
};
/* 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) */
......
...@@ -185,6 +185,16 @@ struct int_symbol platform_symbols_table[] = { ...@@ -185,6 +185,16 @@ struct int_symbol platform_symbols_table[] = {
{ SCTP_SENDALL, "SCTP_SENDALL" }, { SCTP_SENDALL, "SCTP_SENDALL" },
{ SCTP_EOR, "SCTP_EOR" }, { SCTP_EOR, "SCTP_EOR" },
{ SCTP_SACK_IMMEDIATELY, "SCTP_SACK_IMMEDIATELY" }, { SCTP_SACK_IMMEDIATELY, "SCTP_SACK_IMMEDIATELY" },
{ SCTP_PR_SCTP_NONE, "SCTP_PR_SCTP_NONE" },
{ SCTP_PR_SCTP_TTL, "SCTP_PR_SCTP_TTL" },
{ SCTP_SENDV_NOINFO, "SCTP_SENDV_NOINFO" },
{ SCTP_SENDV_SNDINFO, "SCTP_SENDV_SNDINFO" },
{ SCTP_SENDV_PRINFO, "SCTP_SENDV_PRINFO" },
{ SCTP_SENDV_AUTHINFO, "SCTP_SENDV_AUTHINFO" },
{ SCTP_SENDV_SPA, "SCTP_SENDV_SPA" },
{ SCTP_SEND_SNDINFO_VALID, "SCTP_SEND_SNDINFO_VALID" },
{ SCTP_SEND_PRINFO_VALID, "SCTP_SEND_PRINFO_VALID" },
{ SCTP_SEND_AUTHINFO_VALID, "SCTP_SEND_AUTHINFO_VALID" },
/* /usr/include/netinet/tcp.h */ /* /usr/include/netinet/tcp.h */
{ TCP_NODELAY, "TCP_NODELAY" }, { TCP_NODELAY, "TCP_NODELAY" },
......
+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=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_sendv(int sd, const struct iovec *iov, int iovcnt, struct sockaddr *addrs, int addrcnt, void *info, socklen_t infolen, unsigned int infotype, int flags);
//test with sctp_sendv_sndinfo
//+0.0 sctp_sendv(3, [{iov_base=..., iov_len=1000}], 1, ..., 1, {snd_sid=1, snd_flags=0, snd_ppid=htonl(1234), snd_context=0}, 16, SCTP_SENDV_SNDINFO, 0) = 1000
//+0.0 > sctp: DATA[flgs=BE, len=1016, tsn=1, sid=1, ssn=0, ppid=1234]
//+0.0 < sctp: SACK[flgs=0, cum_tsn=1, a_rwnd=1500, gaps=[], dups=[]]
//test with sctp_sendv_authinfo
+1.0 sctp_sendv(3, [{iov_base=..., iov_len=500}, {iov_base=..., iov_len=500}], 2, ..., 1, {auth_keynumber=123}, 2, SCTP_SENDV_AUTHINFO, 0) = 1000
* > sctp: DATA[flgs=BE, len=1016, tsn=1, sid=0, ssn=0, ppid=0]
+0.0 < sctp: SACK[flgs=0, cum_tsn=1, a_rwnd=1500, gaps=[], dups=[]]
//base test
+1.0 sctp_sendv(3, [{iov_base=..., iov_len=1000}], 1, ..., 1, NULL, 0, SCTP_SENDV_NOINFO, 0) = 1000
* > sctp: DATA[flgs=BE, len=1016, tsn=2, sid=0, ssn=1, ppid=0]
+0.0 < sctp: SACK[flgs=0, cum_tsn=2, a_rwnd=1500, gaps=[], dups=[]]
//base test
+1.0 sctp_sendv(3, [{iov_base=..., iov_len=1000}], 1, ..., 1, NULL, 0, SCTP_SENDV_NOINFO, 0) = 1000
* > sctp: DATA[flgs=BE, len=1016, tsn=3, sid=0, ssn=2, ppid=0]
+0.0 < sctp: SACK[flgs=0, cum_tsn=3, a_rwnd=1500, gaps=[], dups=[]]
//base test
+5.0 sctp_sendv(3, [{iov_base=..., iov_len=1000}], 1, ..., 1, NULL, 0, SCTP_SENDV_NOINFO, 0) = 1000
* > sctp: DATA[flgs=BE, len=1016, tsn=4, sid=0, ssn=3, ppid=0]
+0.0 < sctp: SACK[flgs=0, cum_tsn=4, a_rwnd=1500, gaps=[], dups=[]]
//TEST NULL as sockaddr
+5.0 sctp_sendv(3, [{iov_base=..., iov_len=500}], 1, NULL, 0, NULL, 0, SCTP_SENDV_NOINFO, 0) = 500
* > sctp: DATA[flgs=BE, len=516, tsn=5, sid=0, ssn=4, ppid=0]
+0.0 < sctp: SACK[flgs=0, cum_tsn=5, a_rwnd=1500, gaps=[], dups=[]]
//TEST with two structs iov
+5.0 sctp_sendv(3, [{iov_base=..., iov_len=500},{iov_base=..., iov_len=500}], 2, ..., 1, NULL, 0, SCTP_SENDV_NOINFO, 0) = 1000
* > sctp: DATA[flgs=BE, len=1016, tsn=6, sid=0, ssn=5, ppid=0]
+0.0 < sctp: SACK[flgs=0, cum_tsn=6, a_rwnd=1500, gaps=[], dups=[]]
//test with sctp_sendv_prinfo
+5.0 sctp_sendv(3, [{iov_base=..., iov_len=500}, {iov_base=..., iov_len=500}], 2, ..., 1, {pr_policy=0, pr_value=0}, 8, SCTP_SENDV_PRINFO, 0) = 1000
* > sctp: DATA[flgs=BE, len=1016, tsn=7, sid=0, ssn=6, ppid=0]
+0.0 < sctp: SACK[flgs=0, cum_tsn=7, a_rwnd=1500, gaps=[], dups=[]]
//test with all sctp_sendv_spainfo
+5.0 sctp_sendv(3, [{..., 500}, {..., 500}], 2, ..., 1, {sendv_flags=SCTP_SEND_SNDINFO_VALID,
sendv_sndinfo={snd_sid=2, snd_flags=0, snd_ppid=htonl(0), snd_context=0},
sendv_prinfo={pr_policy=SCTP_PR_SCTP_TTL, pr_value=10},
sendv_authinfo={auth_keynumber=123}}, 32, SCTP_SENDV_SPA, 0) = 1000
* > sctp: DATA[flgs=BE, len=1016, tsn=8, sid=2, ssn=0, ppid=0]
+0.0 < sctp: SACK[flgs=0, cum_tsn=8, a_rwnd=1500, gaps=[], dups=[]]
//test with struct sockaddr
+4.0 sctp_sendv(3, [{..., 1000}], 1, [{sa_family=AF_INET, sin_port=htons(8080), sin_addr=inet_addr("192.0.2.1")}], 1, NULL, 0, SCTP_SENDV_NOINFO, 0) = 1000
* > sctp: DATA[flgs=BE, len=1016, tsn=9, sid=5, ssn=0, ppid=1234]
+0.0 < sctp: SACK[flgs=0, cum_tsn=9, a_rwnd=1500, gaps=[], dups=[]]
+0.0 close(3) = 0
+0.0 > sctp: SHUTDOWN[flgs=0, cum_tsn=0]
+0.1 < sctp: SHUTDOWN_ACK[flgs=0]
+0.0 > sctp: SHUTDOWN_COMPLETE[flgs=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