diff --git a/SCTP_SocketAPI_Status.md b/SCTP_SocketAPI_Status.md index 53bbca3622ec6f448881725942224c39dc570fa5..9e584292f04c6ef4fc81b93764640522dfd2de47 100644 --- a/SCTP_SocketAPI_Status.md +++ b/SCTP_SocketAPI_Status.md @@ -17,19 +17,19 @@ For Linux the following tables are based on [sctp.h](https://github.com/sctp/lks |`SCTP_DSTADDRV6` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-5.3.10) | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | unsupported | supported | ## SCTP Notifications -| Type | API Spec | Protocol Spec | packetdrill | Linux | FreeBSD | -|:----------------------------------|:-------------------------------------------------------------:|:----------------------------------------------:|:-----------:|:-----------:|:-----------:| -|`SCTP_ASSOC_CHANGE` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.1) | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported | supported | supported | -|`SCTP_PEER_ADDR_CHANGE` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.2) | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported | supported | supported | -|`SCTP_REMOTE_ERROR` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.3) | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported | supported | supported | -|`SCTP_SEND_FAILED` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.4) | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported | supported | supported | -|`SCTP_SHUTDOWN_EVENT` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.5) | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported | supported | supported | -|`SCTP_ADAPTATION_INDICATION` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.6) | [RFC5061](https://tools.ietf.org/html/rfc5061) | unsupported | supported | supported | -|`SCTP_PARTIAL_DELIVERY_EVENT` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.7) | [RFC3758](https://tools.ietf.org/html/rfc3758) | supported | supported | supported | -|`SCTP_AUTHENTICATION_EVENT` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.8) | [RFC4895](https://tools.ietf.org/html/rfc4895) | supported | supported | supported | -|`SCTP_SENDER_DRY_EVENT` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.9) | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported | supported | supported | -|`SCTP_NOTIFICATIONS_STOPPED_EVENT` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.10) | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | unsupported | unsupported | -|`SCTP_SEND_FAILED_EVENT` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.10) | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported | unsupported | supported | +| Type | API Spec | Protocol Spec | packetdrill | Linux | FreeBSD | +|:----------------------------------|:-------------------------------------------------------------:|:----------------------------------------------:|:-----------:|:-----------------:|:-----------:| +|`SCTP_ASSOC_CHANGE` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.1) | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported | supported | supported | +|`SCTP_PEER_ADDR_CHANGE` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.2) | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported | supported | supported | +|`SCTP_REMOTE_ERROR` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.3) | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported | supported | supported | +|`SCTP_SEND_FAILED` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.4) | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported | supported | supported | +|`SCTP_SHUTDOWN_EVENT` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.5) | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported | supported | supported | +|`SCTP_ADAPTATION_INDICATION` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.6) | [RFC5061](https://tools.ietf.org/html/rfc5061) | supported | supported | supported | +|`SCTP_PARTIAL_DELIVERY_EVENT` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.7) | [RFC3758](https://tools.ietf.org/html/rfc3758) | supported | supported (Note 1)| supported | +|`SCTP_AUTHENTICATION_EVENT` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.8) | [RFC4895](https://tools.ietf.org/html/rfc4895) | supported | supported | supported | +|`SCTP_SENDER_DRY_EVENT` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.9) | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported | supported | supported | +|`SCTP_NOTIFICATIONS_STOPPED_EVENT` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.10) | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported | unsupported | unsupported | +|`SCTP_SEND_FAILED_EVENT` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-6.1.10) | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported | unsupported | supported | ## SCTP Socket Options |Name | API Spec | Protocol Spec | packetdrill | Linux | FreeBSD | @@ -92,3 +92,6 @@ For Linux the following tables are based on [sctp.h](https://github.com/sctp/lks |`sctp_sendx()` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-9.11) | [RFC4960](https://tools.ietf.org/html/rfc4960) | unsupported | supported | supported | |`sctp_sendv()` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-9.12) | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported | unsupported | supported | |`sctp_recvv()` | [RFC6458](https://tools.ietf.org/html/rfc6458#section-9.13) | [RFC4960](https://tools.ietf.org/html/rfc4960) | supported | unsupported | supported | + +## Notes +1. Linux does not support the `pdapi_stream` and `pdapi_seq` fields. diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c index b2223b148cd947b5209859b2e255b28625a72dfd..467b59088334357ed2528fa3f9888328ae23be5a 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -48,6 +48,13 @@ static int to_live_fd(struct state *state, int script_fd, int *live_fd, char **error); +#if defined(linux) +struct sctp_tlv { + u16 sn_type; + u16 sn_flags; + u32 sn_length; +}; +#endif #if defined(__FreeBSD__) || defined(linux) static int check_sctp_notification(struct iovec *iov, struct expression *iovec_expr, char **error); @@ -210,7 +217,6 @@ static int check_type(struct expression *expression, } } -#if defined(SCTP_RTOINFO) || defined(SCTP_STATUS) || defined(SCTP_PEER_ADDR_PARAMS) || defined(SCTP_MAXSEG) || defined(SCTP_MAX_BURST) || defined(SCTP_INTERLEAVING_SUPPORTED) /* 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. @@ -230,7 +236,6 @@ static int get_u32(struct expression *expression, *value = expression->value.num; return STATUS_OK; } -#endif /* Sets the value from the expression argument, checking that it is a * valid s32 or u32, and matches the expected type. Returns STATUS_OK on @@ -437,6 +442,7 @@ static int get_sockstorage_arg(struct expression *arg, struct sockaddr_storage * } #endif +#if defined(__FreeBSD__) || defined(linux) static int check_sockaddr(struct expression *sockaddr_expr, struct sockaddr *live_addr, char **error) { if (sockaddr_expr->type != EXPR_ELLIPSIS) { @@ -499,6 +505,7 @@ static int check_sockaddr(struct expression *sockaddr_expr, struct sockaddr *liv } return STATUS_OK; } +#endif #if defined(__FreeBSD__) || defined(linux) int check_u8_expr(struct expression *expr, u8 value, char *val_name, char **error) { @@ -549,7 +556,6 @@ int check_s32_expr(struct expression *expr, s16 value, char *val_name, char **er return STATUS_OK; } -#if defined(__FreeBSD__) || defined(linux) int check_u32_expr(struct expression *expr, u32 value, char *val_name, char **error) { if (expr->type != EXPR_ELLIPSIS) { u32 script_val; @@ -564,7 +570,6 @@ int check_u32_expr(struct expression *expr, u32 value, char *val_name, char **er } return STATUS_OK; } -#endif #if defined(__FreeBSD__) || defined(linux) static int check_u8array_expr(struct expression *expr_list, u8 *data, size_t data_len, char *val_name, char **error) { @@ -681,7 +686,7 @@ error_out: return status; } -/* Allocate and fill in an +/* 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 @@ -708,37 +713,41 @@ static int cmsg_new(struct expression *expression, struct expression *cmsg_expr; cmsg_expr = get_arg(list, i, error); switch (cmsg_expr->value.cmsghdr->cmsg_data->type) { -#ifdef SCTP_INIT +#if defined(SCTP_INIT) case EXPR_SCTP_INITMSG: cmsg_size += CMSG_SPACE(sizeof(struct sctp_initmsg)); break; #endif -#ifdef SCTP_SNDRCV +#if defined(SCTP_SNDRCV) case EXPR_SCTP_SNDRCVINFO: cmsg_size += CMSG_SPACE(sizeof(struct sctp_sndrcvinfo)); break; #endif -#ifdef SCTP_SNDINFO +#if defined(SCTP_SNDINFO) case EXPR_SCTP_SNDINFO: cmsg_size += CMSG_SPACE(sizeof(struct sctp_sndinfo)); break; #endif -#ifdef SCTP_PRINFO +#if defined(SCTP_PRINFO) case EXPR_SCTP_PRINFO: cmsg_size += CMSG_SPACE(sizeof(struct sctp_prinfo)); break; #endif -#ifdef SCTP_AUTHINFO +#if defined(SCTP_AUTHINFO) case EXPR_SCTP_AUTHINFO: cmsg_size += CMSG_SPACE(sizeof(struct sctp_authinfo)); break; #endif +#if defined(SCTP_DSTADDRV4) case EXPR_SOCKET_ADDRESS_IPV4: cmsg_size += CMSG_SPACE(sizeof(struct in_addr)); break; +#endif +#if defined(SCTP_DSTADDRV6) case EXPR_SOCKET_ADDRESS_IPV6: cmsg_size += CMSG_SPACE(sizeof(struct in6_addr)); break; +#endif default: asprintf(error,"cmsg %d type not valid", i); return STATUS_ERR; @@ -764,7 +773,7 @@ static int cmsg_new(struct expression *expression, goto error_out; switch(cmsg_expr->cmsg_data->type) { -#ifdef SCTP_INIT +#if defined(SCTP_INIT) case EXPR_SCTP_INITMSG: { struct sctp_initmsg init; if (parse_expression_to_sctp_initmsg(cmsg_expr->cmsg_data, &init, error)) { @@ -775,7 +784,7 @@ static int cmsg_new(struct expression *expression, break; } #endif -#ifdef SCTP_SNDRCV +#if defined(SCTP_SNDRCV) case EXPR_SCTP_SNDRCVINFO: { struct sctp_sndrcvinfo info; if (parse_expression_to_sctp_sndrcvinfo(cmsg_expr->cmsg_data, &info, error)) { @@ -786,47 +795,51 @@ static int cmsg_new(struct expression *expression, break; } #endif -#ifdef SCTP_SNDINFO +#if defined(SCTP_SNDINFO) case EXPR_SCTP_SNDINFO: { - struct sctp_sndinfo info; + struct sctp_sndinfo info; if (parse_expression_to_sctp_sndinfo(cmsg_expr->cmsg_data, &info, error)) { goto error_out; } - memcpy(CMSG_DATA(cmsg), &info, sizeof(struct sctp_sndinfo)); + memcpy(CMSG_DATA(cmsg), &info, sizeof(struct sctp_sndinfo)); cmsg = (struct cmsghdr *) ((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_sndinfo))); break; } #endif -#ifdef SCTP_PRINFO +#if defined(SCTP_PRINFO) case EXPR_SCTP_PRINFO: { - struct sctp_prinfo info; + struct sctp_prinfo info; if (parse_expression_to_sctp_prinfo(cmsg_expr->cmsg_data, &info, error)) { goto error_out; } - memcpy(CMSG_DATA(cmsg), &info, sizeof(struct sctp_prinfo)); + memcpy(CMSG_DATA(cmsg), &info, sizeof(struct sctp_prinfo)); cmsg = (struct cmsghdr *) ((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_prinfo))); break; } #endif -#ifdef SCTP_AUTHINFO +#if defined(SCTP_AUTHINFO) case EXPR_SCTP_AUTHINFO: { - struct sctp_authinfo info; + struct sctp_authinfo info; if (parse_expression_to_sctp_authinfo(cmsg_expr->cmsg_data, &info, error)) { goto error_out; } - memcpy(CMSG_DATA(cmsg), &info, sizeof(struct sctp_authinfo)); + memcpy(CMSG_DATA(cmsg), &info, sizeof(struct sctp_authinfo)); cmsg = (struct cmsghdr *) ((caddr_t)cmsg + CMSG_SPACE(sizeof(struct sctp_authinfo))); break; } #endif +#if defined(SCTP_DSTADDRV4) case EXPR_SOCKET_ADDRESS_IPV4: memcpy(CMSG_DATA(cmsg), &cmsg_expr->cmsg_data->value.socket_address_ipv4->sin_addr, sizeof(struct in_addr)); cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct in_addr))); break; +#endif +#if defined(SCTP_DSTADDRV6) case EXPR_SOCKET_ADDRESS_IPV6: memcpy(CMSG_DATA(cmsg), &cmsg_expr->cmsg_data->value.socket_address_ipv6->sin6_addr, sizeof(struct in6_addr)); cmsg = (struct cmsghdr *)((caddr_t)cmsg + CMSG_SPACE(sizeof(struct in6_addr))); break; +#endif default: asprintf(error,"cmsg.cmsg_data %d type not valid", i); goto error_out; @@ -912,7 +925,7 @@ static int msghdr_new(struct expression *expression, if (msg->msg_controllen != cmsg_len) { asprintf(error, - "msg_controllen %u does not match %u size of cmsghdr array", + "msg_controllen %u does not match %zu size of cmsghdr array", msg->msg_controllen, cmsg_len); goto error_out; } @@ -2040,7 +2053,7 @@ static int check_cmsghdr(struct expression *expr_list, struct msghdr *msg, char asprintf(error, "sockaddr_in6 from.sin6_addr. expected: %s actual %s", expected_addr, live_addr); return STATUS_ERR; - } + } } break; #endif @@ -2051,7 +2064,7 @@ static int check_cmsghdr(struct expression *expr_list, struct msghdr *msg, char } cnt++; } - return STATUS_OK; + return STATUS_OK; } static int syscall_sendmsg(struct state *state, struct syscall_spec *syscall, @@ -2089,7 +2102,7 @@ static int syscall_sendmsg(struct state *state, struct syscall_spec *syscall, } begin_syscall(state, syscall); - + result = sendmsg(live_fd, msg, flags); if (end_syscall(state, syscall, CHECK_EXACT, result, error))