diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c index 1bc2ee45505d6fb207ebe0c989e968cd8c56c63c..d89419fadc2646434192d3e6050936e9b2ab4d26 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -61,7 +61,7 @@ static int check_sctp_notification(struct iovec *iov, struct expression *iovec_e static int parse_expression_to_sctp_initmsg(struct expression *expr, struct sctp_initmsg *init, char **error); static int parse_expression_to_sctp_sndrcvinfo(struct expression *expr, struct sctp_sndrcvinfo *info, - char **error); + bool send, char **error); #endif #if defined(__FreeBSD__) static int parse_expression_to_sctp_sndinfo(struct expression *expr, struct sctp_sndinfo *info, @@ -714,14 +714,14 @@ error_out: return status; } -/* Allocate and fill in an -cmsghdr described by the given expression. +/* Allocate and fill in an cmsghdr described by the given expression. * Return STATUS_OK if the expression is a valid cmsghdr. Otherwise * fill in the error with a human-readable error message and return * STATUS_ERR. */ static int cmsg_new(struct expression *expression, - void **cmsg_ptr, size_t *cmsg_len_ptr, char **error) + void **cmsg_ptr, size_t *cmsg_len_ptr, + bool send, char **error) { struct expression_list *list; int list_len = 0, i = 0; @@ -830,7 +830,7 @@ static int cmsg_new(struct expression *expression, #if defined(SCTP_SNDRCV) case EXPR_SCTP_SNDRCVINFO: { struct sctp_sndrcvinfo info; - if (parse_expression_to_sctp_sndrcvinfo(cmsg_expr->cmsg_data, &info, error)) { + if (parse_expression_to_sctp_sndrcvinfo(cmsg_expr->cmsg_data, &info, send, error)) { goto error_out; } memcpy(CMSG_DATA(cmsg), &info, sizeof(struct sctp_sndrcvinfo)); @@ -1080,7 +1080,7 @@ static void msghdr_free(struct msghdr *msg, size_t iov_len) /* Allocate and fill in a msghdr described by the given expression. */ static int msghdr_new(struct expression *expression, struct msghdr **msg_ptr, size_t *iov_len_ptr, - char **error) + bool send, char **error) { int status = STATUS_ERR; s32 s32_val = 0; @@ -1126,7 +1126,7 @@ static int msghdr_new(struct expression *expression, } if (msg_expr->msg_control != NULL) { - if (cmsg_new(msg_expr->msg_control, &msg->msg_control, &cmsg_len, error)) + if (cmsg_new(msg_expr->msg_control, &msg->msg_control, &cmsg_len, send, error)) goto error_out; } @@ -1982,7 +1982,7 @@ static int syscall_recvmsg(struct state *state, struct syscall_spec *syscall, msg_expression = get_arg(args, 1, error); if (msg_expression == NULL) goto error_out; - if (msghdr_new(msg_expression, &msg, &iov_len, error)) + if (msghdr_new(msg_expression, &msg, &iov_len, false, error)) goto error_out; if (s32_arg(args, 2, &flags, error)) @@ -2179,7 +2179,7 @@ static int syscall_sendmsg(struct state *state, struct syscall_spec *syscall, msg_expression = get_arg(args, 1, error); if (msg_expression == NULL) goto error_out; - if (msghdr_new(msg_expression, &msg, &iov_len, error)) + if (msghdr_new(msg_expression, &msg, &iov_len, true, error)) goto error_out; if (s32_arg(args, 2, &flags, error)) @@ -3616,6 +3616,7 @@ static int syscall_sctp_recvmsg(struct state *state, struct syscall_spec *syscal static int parse_expression_to_sctp_initmsg(struct expression *expr, struct sctp_initmsg *init, char **error) { if (expr->type == EXPR_SCTP_INITMSG) { struct sctp_initmsg_expr *init_expr = expr->value.sctp_initmsg; + if (get_u16(init_expr->sinit_num_ostreams, &init->sinit_num_ostreams, error)) { return STATUS_ERR; } @@ -3634,35 +3635,109 @@ static int parse_expression_to_sctp_initmsg(struct expression *expr, struct sctp return STATUS_OK; } -static int parse_expression_to_sctp_sndrcvinfo(struct expression *expr, struct sctp_sndrcvinfo *info, char **error) { +static int parse_expression_to_sctp_sndrcvinfo(struct expression *expr, + struct sctp_sndrcvinfo *info, + bool send, char **error) { if (expr->type == EXPR_SCTP_SNDRCVINFO) { struct sctp_sndrcvinfo_expr *sndrcvinfo_expr = expr->value.sctp_sndrcvinfo; - if (get_u16(sndrcvinfo_expr->sinfo_stream, &info->sinfo_stream, error)) { - return STATUS_ERR; + + if (sndrcvinfo_expr->sinfo_stream->type == EXPR_ELLIPSIS) { + if (send) { + asprintf(error, "sinfo_stream must be specified"); + return STATUS_ERR; + } else { + info->sinfo_stream = 0; + } + } else { + if (get_u16(sndrcvinfo_expr->sinfo_stream, &info->sinfo_stream, error)) { + return STATUS_ERR; + } } - if (get_u16(sndrcvinfo_expr->sinfo_ssn, &info->sinfo_ssn, error)) { - return STATUS_ERR; + if (sndrcvinfo_expr->sinfo_ssn->type == EXPR_ELLIPSIS) { + if (send) { + asprintf(error, "sinfo_ssn must be specified"); + return STATUS_ERR; + } else { + info->sinfo_ssn = 0; + } + } else { + if (get_u16(sndrcvinfo_expr->sinfo_ssn, &info->sinfo_ssn, error)) { + return STATUS_ERR; + } } - if (get_u16(sndrcvinfo_expr->sinfo_flags, &info->sinfo_flags, error)) { - return STATUS_ERR; + if (sndrcvinfo_expr->sinfo_flags->type == EXPR_ELLIPSIS) { + if (send) { + asprintf(error, "sinfo_flags must be specified"); + return STATUS_ERR; + } else { + info->sinfo_flags = 0; + } + } else { + if (get_u16(sndrcvinfo_expr->sinfo_flags, &info->sinfo_flags, error)) { + return STATUS_ERR; + } } - if (get_u32(sndrcvinfo_expr->sinfo_ppid, &info->sinfo_ppid, error)) { - return STATUS_ERR; + if (sndrcvinfo_expr->sinfo_ppid->type == EXPR_ELLIPSIS) { + if (send) { + asprintf(error, "sinfo_ppid must be specified"); + return STATUS_ERR; + } else { + info->sinfo_ppid = 0; + } + } else { + if (get_u32(sndrcvinfo_expr->sinfo_ppid, &info->sinfo_ppid, error)) { + return STATUS_ERR; + } } - if (get_u32(sndrcvinfo_expr->sinfo_context, &info->sinfo_context, error)) { - return STATUS_ERR; + if (sndrcvinfo_expr->sinfo_context->type == EXPR_ELLIPSIS) { + if (send) { + asprintf(error, "sinfo_context must be specified"); + return STATUS_ERR; + } else { + info->sinfo_context = 0; + } + } else { + if (get_u32(sndrcvinfo_expr->sinfo_context, &info->sinfo_context, error)) { + return STATUS_ERR; + } } - if (get_u32(sndrcvinfo_expr->sinfo_timetolive, &info->sinfo_timetolive, error)) { - return STATUS_ERR; + if (sndrcvinfo_expr->sinfo_timetolive->type == EXPR_ELLIPSIS) { + if (send) { + asprintf(error, "sinfo_timetolive must be specified"); + return STATUS_ERR; + } else { + info->sinfo_timetolive = 0; + } + } else { + if (get_u32(sndrcvinfo_expr->sinfo_timetolive, &info->sinfo_timetolive, error)) { + return STATUS_ERR; + } } - if (get_u32(sndrcvinfo_expr->sinfo_tsn, &info->sinfo_tsn, error)) { - return STATUS_ERR; + if (sndrcvinfo_expr->sinfo_tsn->type == EXPR_ELLIPSIS) { + info->sinfo_tsn = 0; + } else { + if (get_u32(sndrcvinfo_expr->sinfo_tsn, &info->sinfo_tsn, error)) { + return STATUS_ERR; + } } - if (get_u32(sndrcvinfo_expr->sinfo_cumtsn, &info->sinfo_cumtsn, error)) { - return STATUS_ERR; + if (sndrcvinfo_expr->sinfo_cumtsn->type == EXPR_ELLIPSIS) { + info->sinfo_cumtsn = 0; + } else { + if (get_u32(sndrcvinfo_expr->sinfo_cumtsn, &info->sinfo_cumtsn, error)) { + return STATUS_ERR; + } } - if (get_u32(sndrcvinfo_expr->sinfo_assoc_id, (u32 *)&info->sinfo_assoc_id, error)) { - return STATUS_ERR; + if (sndrcvinfo_expr->sinfo_assoc_id->type == EXPR_ELLIPSIS) { + if (send) { + asprintf(error, "sinfo_assoc_id must be specified"); + return STATUS_ERR; + } else { + info->sinfo_assoc_id = 0; + } + } else { + if (get_u32(sndrcvinfo_expr->sinfo_assoc_id, (u32 *)&info->sinfo_assoc_id, error)) { + return STATUS_ERR; + } } } else { return STATUS_ERR; @@ -3699,6 +3774,7 @@ static int parse_expression_to_sctp_sndinfo(struct expression *expr, struct sctp static 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; } @@ -3711,6 +3787,7 @@ static int parse_expression_to_sctp_authinfo(struct expression *expr, struct sct static 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; } @@ -3726,6 +3803,7 @@ static int parse_expression_to_sctp_prinfo(struct expression *expr, struct sctp_ static 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; } diff --git a/gtests/net/packetdrill/tests/bsd/sctp/recvmsg.pkt b/gtests/net/packetdrill/tests/bsd/sctp/recvmsg.pkt index b7241e4fb8548d75127b95bc1b068228f3abe8b4..e81c3d2844ad6afc21e959902ab3320a094da092 100644 --- a/gtests/net/packetdrill/tests/bsd/sctp/recvmsg.pkt +++ b/gtests/net/packetdrill/tests/bsd/sctp/recvmsg.pkt @@ -21,15 +21,15 @@ spp_ipv6_flowlabel=0, spp_dscp=0}, 152) = 0 //base test -+0.0 < sctp: DATA[flgs=BE, len=1016, tsn=1, sid=0, ssn=0, ppid=0] ++0.0 < sctp: DATA[flgs=IBE, len=1016, tsn=1, sid=0, ssn=0, ppid=0] * > sctp: SACK[flgs=0, cum_tsn=1, a_rwnd=..., gaps=[], dups=[]] -+1.0 recvmsg(3, {msg_name(...)=..., ++0.0 recvmsg(3, {msg_name(...)=..., msg_iov(1)=[{iov_base=..., iov_len=1000}], msg_control(0)=[], msg_flags=MSG_EOR}, 0) = 1000 +0.0 setsockopt(3, IPPROTO_SCTP, SCTP_RECVRCVINFO, [1], 4) = 0 +0.0 setsockopt(3, IPPROTO_SCTP, SCTP_RECVNXTINFO, [0], 4) = 0 -+0.0 < sctp: DATA[flgs=UBE, len=1016, tsn=2, sid=0, ssn=0, ppid=0] ++0.0 < sctp: DATA[flgs=IUBE, len=1016, tsn=2, sid=0, ssn=0, ppid=0] * > sctp: SACK[flgs=0, cum_tsn=2, a_rwnd=..., gaps=[], dups=[]] +0.0 recvmsg(3, {msg_name(...)=..., msg_iov(1)=[{iov_base=..., iov_len=1000}], @@ -48,9 +48,9 @@ +0.0 setsockopt(3, IPPROTO_SCTP, SCTP_RECVRCVINFO, [0], 4) = 0 +0.0 setsockopt(3, IPPROTO_SCTP, SCTP_RECVNXTINFO, [1], 4) = 0 -+0.0 < sctp: DATA[flgs=BE, len=1016, tsn=3, sid=0, ssn=1, ppid=0] ++0.0 < sctp: DATA[flgs=IBE, len=1016, tsn=3, sid=0, ssn=1, ppid=0] * > sctp: SACK[flgs=0, cum_tsn=3, a_rwnd=..., gaps=[], dups=[]] -+0.0 < sctp: DATA[flgs=BE, len=1016, tsn=4, sid=0, ssn=2, ppid=1234] ++0.0 < sctp: DATA[flgs=IBE, len=1016, tsn=4, sid=0, ssn=2, ppid=1234] * > sctp: SACK[flgs=0, cum_tsn=4, a_rwnd=..., gaps=[], dups=[]] +0.0 recvmsg(3, {msg_name(...)=..., msg_iov(1)=[{iov_base=..., iov_len=1000}], @@ -66,7 +66,7 @@ +0.0 setsockopt(3, IPPROTO_SCTP, SCTP_RECVRCVINFO, [1], 4) = 0 +0.0 setsockopt(3, IPPROTO_SCTP, SCTP_RECVNXTINFO, [1], 4) = 0 -+0.0 < sctp: DATA[flgs=UBE, len=1016, tsn=5, sid=0, ssn=0, ppid=9876] ++0.0 < sctp: DATA[flgs=IUBE, len=1016, tsn=5, sid=0, ssn=0, ppid=9876] * > sctp: SACK[flgs=0, cum_tsn=5, a_rwnd=..., gaps=[], dups=[]] +0.0 recvmsg(3, {msg_name(...)=..., msg_iov(1)=[{iov_base=..., iov_len=1000}], @@ -116,10 +116,10 @@ sinfo_timetolive=0, sinfo_tsn=5, sinfo_cumtsn=5, - sinfo_assoc_id=3}}], // FIXME + sinfo_assoc_id=...}}], msg_flags=MSG_EOR}, 0) = 1000 +0.0 setsockopt(3, IPPROTO_SCTP, SCTP_USE_EXT_RCVINFO, [1], 4) = 0 -+0.0 < sctp: DATA[flgs=BE, len=1016, tsn=6, sid=0, ssn=3, ppid=9877] ++0.0 < sctp: DATA[flgs=IBE, len=1016, tsn=6, sid=0, ssn=3, ppid=9877] * > sctp: SACK[flgs=0, cum_tsn=6, a_rwnd=..., gaps=[], dups=[]] +0.0 recvmsg(3, {msg_name(...)=..., msg_iov(1)=[{iov_base=..., iov_len=1000}], @@ -141,9 +141,9 @@ serinfo_next_ppid=htonl(0), sinfo_assoc_id=...}}], msg_flags=MSG_EOR}, 0) = 1000 -+0.0 < sctp: DATA[flgs=BE, len=1016, tsn=7, sid=0, ssn=4, ppid=9878] ++0.0 < sctp: DATA[flgs=IBE, len=1016, tsn=7, sid=0, ssn=4, ppid=9878] * > sctp: SACK[flgs=0, cum_tsn=7, a_rwnd=..., gaps=[], dups=[]] -+0.0 < sctp: DATA[flgs=UBE, len=1016, tsn=8, sid=1, ssn=0, ppid=9879] ++0.0 < sctp: DATA[flgs=IUBE, len=1016, tsn=8, sid=1, ssn=0, ppid=9879] * > sctp: SACK[flgs=0, cum_tsn=8, a_rwnd=..., gaps=[], dups=[]] +0.0 recvmsg(3, {msg_name(...)=..., msg_iov(1)=[{iov_base=..., iov_len=1000}],