diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index 647f775b17c4192112df7b9fb20dfeab5f0acaf1..e00de6cb8047587d178ea083e50a1e837ee75f19 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -307,6 +307,12 @@ sac_outbound_streams return SAC_OUTBOUND_STREAMS; sac_inbound_streams return SAC_INBOUND_STREAMS; sac_assoc_id return SAC_ASSOC_ID; sac_info return SAC_INFO; +auth_type return AUTH_TYPE; +auth_flags return AUTH_FLAGS; +auth_length return AUTH_LENGTH; +auth_keynumber return AUTH_KEYNUMBER; +auth_indication return AUTH_INDICATION; +auth_assoc_id return AUTH_ASSOC_ID; sender_dry_type return SENDER_DRY_TYPE; sender_dry_flags return SENDER_DRY_FLAGS; sender_dry_length return SENDER_DRY_LENGTH; diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index a224bc494d2a75d78eec22da076781ef0ea2bd0c..14838d613145e41603fb7db3acbd9eb70e1bbf58 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -556,6 +556,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %token <reserved> SAC_TYPE SAC_FLAGS SAC_LENGTH SAC_STATE SAC_ERROR SAC_OUTBOUND_STREAMS %token <reserved> SAC_INBOUND_STREAMS SAC_ASSOC_ID SAC_INFO %token <reserved> SSFE_TYPE SSFE_FLAGS SSFE_LENGTH SSFE_ERROR SSFE_INFO SSFE_ASSOC_ID SSFE_DATA +%token <reserved> AUTH_TYPE AUTH_FLAGS AUTH_LENGTH AUTH_INDICATION AUTH_ASSOC_ID %token <floating> FLOAT %token <integer> INTEGER HEX_INTEGER %token <string> WORD STRING BACK_QUOTED CODE IPV4_ADDR IPV6_ADDR @@ -617,6 +618,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %type <expression> sctp_assoc_change sac_type sac_flags sac_length sac_state sac_error sac_outbound_streams %type <expression> sac_inbound_streams sac_assoc_id sac_info %type <expression> sctp_send_failed_event ssfe_type ssfe_flags ssfe_length ssfe_error ssfe_assoc_id +%type <expression> sctp_authkey_event auth_type auth_flags auth_length auth_keynumber auth_indication auth_assoc_id %type <errno_info> opt_errno %type <chunk_list> sctp_chunk_list_spec %type <chunk_list_item> sctp_chunk_spec @@ -2595,6 +2597,7 @@ data | sctp_shutdown_event { $$ = $1; } | sctp_sender_dry_event { $$ = $1; } | sctp_send_failed_event { $$ = $1; } +| sctp_authkey_event { $$ = $1; } ; msghdr @@ -3580,6 +3583,87 @@ sctp_shutdown_event $$->value.sctp_shutdown_event->sse_length = $6; }; +auth_type +: AUTH_TYPE '=' INTEGER { + if (!is_valid_u16($3)) { + semantic_error("auth_type out of range"); + } + $$ = new_integer_expression($3, "%hu"); +} +| AUTH_TYPE '=' WORD { + $$ = new_expression(EXPR_WORD); + $$->value.string = $3; +} +| AUTH_TYPE '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +auth_flags +: AUTH_FLAGS '=' INTEGER { + if (!is_valid_u16($3)) { + semantic_error("auth_flags out of range"); + } + $$ = new_integer_expression($3, "%hu"); +} +| AUTH_FLAGS '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +auth_length +: AUTH_LENGTH '=' INTEGER { + if (!is_valid_u32($3)) { + semantic_error("auth_length out of range"); + } + $$ = new_integer_expression($3, "%u"); +} +| AUTH_LENGTH '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +auth_keynumber +: AUTH_KEYNUMBER '=' INTEGER { + if (!is_valid_u16($3)) { + semantic_error("auth_keynumber out of range"); + } + $$ = new_integer_expression($3, "%hu"); +} +| AUTH_KEYNUMBER '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +auth_indication +: AUTH_INDICATION '=' INTEGER { + if (!is_valid_u32($3)) { + semantic_error("auth_indication out of range"); + } + $$ = new_integer_expression($3, "%u"); +} +| AUTH_INDICATION '=' WORD { + $$ = new_expression(EXPR_WORD); + $$->value.string = $3; +} +| AUTH_INDICATION '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +auth_assoc_id +: AUTH_ASSOC_ID '=' INTEGER { + if (!is_valid_u32($3)) { + semantic_error("auth_assoc_id out of range"); + } + $$ = new_integer_expression($3, "%u"); +} +| AUTH_ASSOC_ID '=' ELLIPSIS { $$ = new_expression(EXPR_ELLIPSIS); } +; + +sctp_authkey_event +: '{' auth_type ',' auth_flags ',' auth_length ',' auth_keynumber ',' auth_indication ',' auth_assoc_id '}' { + $$ = new_expression(EXPR_SCTP_AUTHKEY_EVENT); + $$->value.sctp_authkey_event = calloc(1, sizeof(struct sctp_authkey_event_expr)); + $$->value.sctp_authkey_event->auth_type = $2; + $$->value.sctp_authkey_event->auth_flags = $4; + $$->value.sctp_authkey_event->auth_length = $6; + $$->value.sctp_authkey_event->auth_keynumber = $8; + $$->value.sctp_authkey_event->auth_indication = $10; + $$->value.sctp_authkey_event->auth_assoc_id = $12; +} +; + sender_dry_type : SENDER_DRY_TYPE '=' INTEGER { if (!is_valid_u16($3)) { diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c index bb38680c19303cf5e3b1e0502ab2490395ca3dd5..040c41965f3536ebed68c02f793f8ea470539672 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -528,6 +528,7 @@ static int iovec_new(struct expression *expression, assert(iov_expr->iov_base->type == EXPR_ELLIPSIS || iov_expr->iov_base->type == EXPR_SCTP_ASSOC_CHANGE || iov_expr->iov_base->type == EXPR_SCTP_SHUTDOWN_EVENT || + iov_expr->iov_base->type == EXPR_SCTP_AUTHKEY_EVENT || iov_expr->iov_base->type == EXPR_SCTP_SENDER_DRY_EVENT || iov_expr->iov_base->type == EXPR_SCTP_SEND_FAILED_EVENT); assert(iov_expr->iov_len->type == EXPR_INTEGER); @@ -3438,6 +3439,34 @@ static int check_sctp_shutdown_event(struct sctp_shutdown_event_expr *expr, } #endif +#if defined(__FreeBSD__) || defined(linux) +static int check_sctp_authkey_event(struct sctp_authkey_event_expr *expr, + struct sctp_authkey_event *sctp_event, + char **error) { + + if (check_u16_expr(expr->auth_type, sctp_event->auth_type, + "sctp_authkey_event.auth_type", error)) + return STATUS_ERR; + if (check_u16_expr(expr->auth_flags, sctp_event->auth_flags, + "sctp_authkey_event.auth_flags", error)) + return STATUS_ERR; + if (check_u32_expr(expr->auth_length, sctp_event->auth_length, + "sctp_authkey_event.auth_length", error)) + return STATUS_ERR; + if (check_u16_expr(expr->auth_keynumber, sctp_event->auth_keynumber, + "sctp_authkey_event.auth_keynumber", error)) + return STATUS_ERR; + if (check_u32_expr(expr->auth_indication, sctp_event->auth_indication, + "sctp_authkey_event.auth_indication", error)) + return STATUS_ERR; + if (check_u32_expr(expr->auth_assoc_id, sctp_event->auth_assoc_id, + "sctp_authkey_event.auth_assoc_id", error)) + return STATUS_ERR; + + return STATUS_OK; +} +#endif + #if defined(__FreeBSD__) || defined(linux) static int check_sctp_sender_dry_event(struct sctp_sender_dry_event_expr *expr, struct sctp_sender_dry_event *sctp_event, @@ -3518,6 +3547,12 @@ static int check_sctp_notification(struct iovec *iov, error)) return STATUS_ERR; break; + case EXPR_SCTP_AUTHKEY_EVENT: + if (check_sctp_authkey_event(script_iov_base->value.sctp_authkey_event, + (struct sctp_authkey_event *) iov->iov_base, + error)) + return STATUS_ERR; + break; case EXPR_SCTP_SENDER_DRY_EVENT: if (check_sctp_sender_dry_event(script_iov_base->value.sctp_sender_dry_event, (struct sctp_sender_dry_event *) iov->iov_base, diff --git a/gtests/net/packetdrill/script.c b/gtests/net/packetdrill/script.c index 5ceb9c6d00475a120085b825197acaa434a0a46b..a20c7f14d4f2eda680fd327bcff566a2bf3c610a 100644 --- a/gtests/net/packetdrill/script.c +++ b/gtests/net/packetdrill/script.c @@ -88,6 +88,7 @@ struct expression_type_entry expression_type_table[] = { { EXPR_SCTP_RECVV_RN, "sctp_recvv_rn " }, { EXPR_SCTP_ASSOC_CHANGE, "sctp_assoc_change"}, { EXPR_SCTP_SHUTDOWN_EVENT, "sctp_shutdown_event"}, + { EXPR_SCTP_AUTHKEY_EVENT, "sctp_authkey_event"}, { EXPR_SCTP_SENDER_DRY_EVENT,"sctp_sender_dry_event"}, { EXPR_SCTP_SEND_FAILED_EVENT,"sctp_send_failed_event"}, { NUM_EXPR_TYPES, NULL} @@ -449,6 +450,14 @@ void free_expression(struct expression *expression) free_expression(expression->value.sctp_shutdown_event->sse_flags); free_expression(expression->value.sctp_shutdown_event->sse_length); break; + case EXPR_SCTP_AUTHKEY_EVENT: + free_expression(expression->value.sctp_authkey_event->auth_type); + free_expression(expression->value.sctp_authkey_event->auth_flags); + free_expression(expression->value.sctp_authkey_event->auth_length); + free_expression(expression->value.sctp_authkey_event->auth_keynumber); + free_expression(expression->value.sctp_authkey_event->auth_indication); + free_expression(expression->value.sctp_authkey_event->auth_assoc_id); + break; case EXPR_SCTP_SENDER_DRY_EVENT: free_expression(expression->value.sctp_sender_dry_event->sender_dry_type); free_expression(expression->value.sctp_sender_dry_event->sender_dry_flags); @@ -1462,6 +1471,50 @@ static int evaluate_sctp_shutdown_event_expression(struct expression *in, return STATUS_OK; } +static int evaluate_sctp_authkey_event_expression(struct expression *in, + struct expression *out, + char **error) +{ + struct sctp_authkey_event_expr *in_event; + struct sctp_authkey_event_expr *out_event; + + assert(in->type == EXPR_SCTP_AUTHKEY_EVENT); + assert(in->value.sctp_authkey_event); + assert(out->type == EXPR_SCTP_AUTHKEY_EVENT); + + out->value.sctp_authkey_event = calloc(1, sizeof(struct sctp_authkey_event_expr)); + + in_event = in->value.sctp_authkey_event; + out_event = out->value.sctp_authkey_event; + + if (evaluate(in_event->auth_type, + &out_event->auth_type, + error)) + return STATUS_ERR; + if (evaluate(in_event->auth_flags, + &out_event->auth_flags, + error)) + return STATUS_ERR; + if (evaluate(in_event->auth_length, + &out_event->auth_length, + error)) + return STATUS_ERR; + if (evaluate(in_event->auth_keynumber, + &out_event->auth_keynumber, + error)) + return STATUS_ERR; + if (evaluate(in_event->auth_indication, + &out_event->auth_indication, + error)) + return STATUS_ERR; + if (evaluate(in_event->auth_assoc_id, + &out_event->auth_assoc_id, + error)) + return STATUS_ERR; + + return STATUS_OK; +} + static int evaluate_sctp_sender_dry_event_expression(struct expression *in, struct expression *out, char **error) @@ -1637,6 +1690,9 @@ static int evaluate(struct expression *in, case EXPR_SCTP_SHUTDOWN_EVENT: result = evaluate_sctp_shutdown_event_expression(in, out, error); break; + case EXPR_SCTP_AUTHKEY_EVENT: + result = evaluate_sctp_authkey_event_expression(in, out, error); + break; case EXPR_SCTP_SENDER_DRY_EVENT: result = evaluate_sctp_sender_dry_event_expression(in, out, error); break; diff --git a/gtests/net/packetdrill/script.h b/gtests/net/packetdrill/script.h index fe4463278ac4f5c7abd38274f148f0acc058b70d..fdf4a7f148ccec9a679fadae22391a240a8c1667 100644 --- a/gtests/net/packetdrill/script.h +++ b/gtests/net/packetdrill/script.h @@ -68,6 +68,7 @@ enum expression_t { EXPR_SCTP_RECVV_RN, /* struct sctp_recvv_rn for syscall sctp_recvv */ EXPR_SCTP_ASSOC_CHANGE, /* expression tree for sctp_assoc_change_event */ EXPR_SCTP_SHUTDOWN_EVENT, /* expression tree for sctp_shutdown_event */ + EXPR_SCTP_AUTHKEY_EVENT, /* expression tree for sctp_authentication_event */ EXPR_SCTP_SENDER_DRY_EVENT, /* expression tree for sctp_sender_dry_event */ EXPR_SCTP_SEND_FAILED_EVENT, /* expression tree for sctp_send_failed_event */ NUM_EXPR_TYPES, @@ -111,6 +112,7 @@ struct expression { struct sctp_recvv_rn_expr *sctp_recvv_rn; struct sctp_assoc_change_expr *sctp_assoc_change; struct sctp_shutdown_event_expr *sctp_shutdown_event; + struct sctp_authkey_event_expr *sctp_authkey_event; struct sctp_sender_dry_event_expr *sctp_sender_dry_event; struct sctp_send_failed_event_expr *sctp_send_failed_event; } value; @@ -343,6 +345,16 @@ struct sctp_shutdown_event_expr { struct expression *sse_length; }; +/* Parse tree for sctp_authentication_event for notifications. */ +struct sctp_authkey_event_expr { + struct expression *auth_type; + struct expression *auth_flags; + struct expression *auth_length; + struct expression *auth_keynumber; + struct expression *auth_indication; + struct expression *auth_assoc_id; +}; + /* Parse tree for sctp_sender_dry_event for notifications. */ struct sctp_sender_dry_event_expr { struct expression *sender_dry_type; diff --git a/gtests/net/packetdrill/symbols_freebsd.c b/gtests/net/packetdrill/symbols_freebsd.c index a1aceb96f248cbfcd0b7e6d0fcf3572dc209391d..d4ee1bef97420a83a94e6778e7aee9e60b66946c 100644 --- a/gtests/net/packetdrill/symbols_freebsd.c +++ b/gtests/net/packetdrill/symbols_freebsd.c @@ -211,6 +211,9 @@ struct int_symbol platform_symbols_table[] = { { SCTP_COMM_LOST, "SCTP_COMM_LOST" }, { SCTP_RESTART, "SCTP_RESTART" }, { SCTP_SHUTDOWN_COMP, "SCTP_SHUTDOWN_COMP" }, + { SCTP_AUTH_NEW_KEY, "SCTP_AUTH_NEW_KEY" }, + { SCTP_AUTH_NO_AUTH, "SCTP_AUTH_NO_AUTH" }, + { SCTP_AUTH_FREE_KEY, "SCTP_AUTH_FREE_KEY" }, { SCTP_ASSOC_SUPPORTS_PR, "SCTP_ASSOC_SUPPORTS_PR" }, { SCTP_ASSOC_SUPPORTS_AUTH, "SCTP_ASSOC_SUPPORTS_AUTH" }, { SCTP_ASSOC_SUPPORTS_ASCONF, "SCTP_ASSOC_SUPPORTS_ASCONF" }, diff --git a/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_assoc_change_event.pkt b/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_assoc_change_event.pkt index 88a49593e833e1363063e09c5680a5fc20992183..dcbf791c2fec9bc3af303e1a6e51684f79c8eb39 100644 --- a/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_assoc_change_event.pkt +++ b/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_assoc_change_event.pkt @@ -11,8 +11,7 @@ +0.1 < sctp: COOKIE_ACK[flgs=0] +0.0 sctp_recvv(3, [{iov_base={sac_type=SCTP_ASSOC_CHANGE, sac_flags=0, sac_length=21, sac_state=SCTP_COMM_UP, sac_error=0, sac_outbound_streams=1, sac_inbound_streams=1, sac_assoc_id=3, sac_info=[SCTP_ASSOC_SUPPORTS_MULTIBUF, 0x00]}, iov_len=1000}], 1, ..., 20, NULL, [0], [SCTP_RECVV_NOINFO], -[MSG_NOTIFICATION|MSG_EOR]) -= 21 +[MSG_NOTIFICATION|MSG_EOR]) = 21 +0.0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 +0.0 < sctp: SHUTDOWN[flgs=0, cum_tsn=0] diff --git a/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_authentication_event.pkt b/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_authentication_event.pkt new file mode 100644 index 0000000000000000000000000000000000000000..cf7a4ce7ec91e5ddd463685b57cb12342a8c4595 --- /dev/null +++ b/gtests/net/packetdrill/tests/bsd/sctp/notifications/sctp_authentication_event.pkt @@ -0,0 +1,20 @@ ++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 +// Check the handshake with an empty(!) cookie ++0.1 connect(3, ..., ...) = -1 EINPROGRESS (Operation now in progress) ++0.0 setsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_AUTHENTICATION_EVENT, se_on=1}, 8) = 0 ++0.0 getsockopt(3, IPPROTO_SCTP, SCTP_EVENT, {se_type=SCTP_AUTHENTICATION_EVENT, se_on=1}, [8]) = 0 ++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=1, is=1, 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 sctp_recvv(3, [{iov_base={auth_type=SCTP_AUTHENTICATION_EVENT, auth_flags=0, auth_length=20, auth_keynumber=0, auth_indication=SCTP_AUTH_NO_AUTH, +auth_assoc_id=3}, iov_len=1000}], 1, ..., 20, NULL, [0], [SCTP_RECVV_NOINFO], [MSG_NOTIFICATION|MSG_EOR]) = 20 + ++0.0 getsockopt(3, SOL_SOCKET, SO_ERROR, [0], [4]) = 0 ++0.0 < sctp: SHUTDOWN[flgs=0, cum_tsn=0] +* > sctp: SHUTDOWN_ACK[flgs=0] ++0.0 < sctp: SHUTDOWN_COMPLETE[flgs=0] +