diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index 5d177ad157fbdb5c0b3ee36a48313441c339db7b..3fcb49a0f77bbdf4b4fe84ad51da51e8cca11f33 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -227,6 +227,7 @@ COOKIE_ACK return COOKIE_ACK; ECNE return ECNE; CWR return CWR; SHUTDOWN_COMPLETE return SHUTDOWN_COMPLETE; +flgs return FLAGS; tag return TAG; a_rwnd return A_RWND; is return IS; diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index 7590b0cccd5d93292c43dc034cd389a9674d19b2..6dbdf550a2965976c5ebc4f445a1f981eb22ea35 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -499,7 +499,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %token <reserved> DATA INIT INIT_ACK HEARTBEAT HEARTBEAT_ACK ABORT %token <reserved> SHUTDOWN SHUTDOWN_ACK ERROR COOKIE_ECHO COOKIE_ACK ECNE CWR %token <reserved> SHUTDOWN_COMPLETE -%token <reserved> TAG A_RWND OS IS TSN SID SSN PPID GAPS DUPS +%token <reserved> FLAGS TAG A_RWND OS IS TSN SID SSN PPID GAPS DUPS %token <floating> FLOAT %token <integer> INTEGER HEX_INTEGER %token <string> WORD STRING BACK_QUOTED CODE IPV4_ADDR IPV6_ADDR @@ -551,6 +551,7 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, %type <chunk_list_item> sctp_cookie_echo_chunk_spec sctp_cookie_ack_chunk_spec %type <chunk_list_item> sctp_ecne_chunk_spec sctp_cwr_chunk_spec %type <chunk_list_item> sctp_shutdown_complete_chunk_spec +%type <integer> opt_flags %type <integer> opt_a_rwnd opt_os opt_is opt_tsn opt_sid opt_ssn opt_ppid %type <sack_block_list> opt_gaps gap_list opt_dups dup_list %type <sack_block_list_item> gap dup @@ -762,6 +763,14 @@ sctp_chunk_spec | sctp_shutdown_complete_chunk_spec { $$ = $1; } ; +opt_flags +: { $$ = -1; } +| FLAGS '=' HEX_INTEGER {if (!is_valid_u8($3)) { + semantic_error("flags value out of range"); + } + $$ = $3;} +; + opt_a_rwnd : { $$ = -1; } | A_RWND '=' INTEGER { @@ -869,90 +878,90 @@ dup ; sctp_data_chunk_spec -: DATA '[' opt_tsn opt_sid opt_ssn opt_ppid ']' { - $$ = sctp_data_chunk_new($3, $4, $5, $6); +: DATA '[' opt_flags opt_tsn opt_sid opt_ssn opt_ppid ']' { + $$ = sctp_data_chunk_new($3, $4, $5, $6, $7); } sctp_init_chunk_spec -: INIT '[' TAG '=' INTEGER opt_a_rwnd opt_os opt_is TSN '=' INTEGER ']' { - if (!is_valid_u32($5)) { +: INIT '[' opt_flags TAG '=' INTEGER opt_a_rwnd opt_os opt_is TSN '=' INTEGER ']' { + if (!is_valid_u32($6)) { semantic_error("tag value out of range"); } - if (!is_valid_u32($11)) { + if (!is_valid_u32($12)) { semantic_error("tsn value out of range"); } - $$ = sctp_init_chunk_new($5, $6, $7, $8, $11); + $$ = sctp_init_chunk_new($3, $6, $7, $8, $9, $12); } sctp_init_ack_chunk_spec -: INIT_ACK '[' TAG '=' INTEGER opt_a_rwnd opt_os opt_is TSN '=' INTEGER ']' { - if (!is_valid_u32($5)) { +: INIT_ACK '[' opt_flags TAG '=' INTEGER opt_a_rwnd opt_os opt_is TSN '=' INTEGER ']' { + if (!is_valid_u32($6)) { semantic_error("tag value out of range"); } - if (!is_valid_u32($11)) { + if (!is_valid_u32($12)) { semantic_error("tsn value out of range"); } - $$ = sctp_init_ack_chunk_new($5, $6, $7, $8, $11); + $$ = sctp_init_ack_chunk_new($3, $6, $7, $8, $9, $12); } sctp_sack_chunk_spec -: SACK '[' opt_tsn opt_a_rwnd opt_gaps opt_dups']' { - $$ = sctp_sack_chunk_new($3, $4, $5, $6); +: SACK '[' opt_flags opt_tsn opt_a_rwnd opt_gaps opt_dups']' { + $$ = sctp_sack_chunk_new($3, $4, $5, $6, $7); } sctp_heartbeat_chunk_spec -: HEARTBEAT '[' ']' { - $$ = sctp_heartbeat_chunk_new(0); +: HEARTBEAT '[' opt_flags ']' { + $$ = sctp_heartbeat_chunk_new($3); } sctp_heartbeat_ack_chunk_spec -: HEARTBEAT_ACK '[' ']' { - $$ = sctp_heartbeat_ack_chunk_new(0); +: HEARTBEAT_ACK '[' opt_flags ']' { + $$ = sctp_heartbeat_ack_chunk_new($3); } sctp_abort_chunk_spec -: ABORT '[' ']' { - $$ = sctp_abort_chunk_new(0); +: ABORT '[' opt_flags ']' { + $$ = sctp_abort_chunk_new($3); } sctp_shutdown_chunk_spec -: SHUTDOWN '[' opt_tsn ']' { - $$ = sctp_shutdown_chunk_new($3); +: SHUTDOWN '[' opt_flags opt_tsn ']' { + $$ = sctp_shutdown_chunk_new($3, $4); } sctp_shutdown_ack_chunk_spec -: SHUTDOWN_ACK '[' ']' { - $$ = sctp_shutdown_ack_chunk_new(0); +: SHUTDOWN_ACK '[' opt_flags ']' { + $$ = sctp_shutdown_ack_chunk_new($3); } sctp_error_chunk_spec -: ERROR '[' ']' { - $$ = sctp_error_chunk_new(0); +: ERROR '[' opt_flags ']' { + $$ = sctp_error_chunk_new($3); } sctp_cookie_echo_chunk_spec -: COOKIE_ECHO '[' ']' { - $$ = sctp_cookie_echo_chunk_new(0); +: COOKIE_ECHO '[' opt_flags ']' { + $$ = sctp_cookie_echo_chunk_new($3); } sctp_cookie_ack_chunk_spec -: COOKIE_ACK '[' ']' { - $$ = sctp_cookie_ack_chunk_new(0); +: COOKIE_ACK '[' opt_flags ']' { + $$ = sctp_cookie_ack_chunk_new($3); } sctp_ecne_chunk_spec -: ECNE '[' opt_tsn ']' { - $$ = sctp_ecne_chunk_new($3); +: ECNE '[' opt_flags opt_tsn ']' { + $$ = sctp_ecne_chunk_new($3, $4); } sctp_cwr_chunk_spec -: CWR '[' opt_tsn ']' { - $$ = sctp_cwr_chunk_new($3); +: CWR '[' opt_flags opt_tsn ']' { + $$ = sctp_cwr_chunk_new($3, $4); } sctp_shutdown_complete_chunk_spec -: SHUTDOWN_COMPLETE '[' ']' { - $$ = sctp_shutdown_complete_chunk_new(0); +: SHUTDOWN_COMPLETE '[' opt_flags ']' { + $$ = sctp_shutdown_complete_chunk_new($3); } tcp_packet_spec diff --git a/gtests/net/packetdrill/sctp_packet.c b/gtests/net/packetdrill/sctp_packet.c index 6f03f44432206792693fb6e6322cd7d05f3f8437..7731e80f39bf8a6967f8b2eee5891e0b22ffa396 100644 --- a/gtests/net/packetdrill/sctp_packet.c +++ b/gtests/net/packetdrill/sctp_packet.c @@ -126,9 +126,8 @@ sctp_chunk_list_item_new(struct sctp_chunk *chunk, u32 length, u32 flags) } struct sctp_chunk_list_item * -sctp_data_chunk_new(s64 tsn, s64 sid, s64 ssn, s64 ppid) +sctp_data_chunk_new(s64 flgs, s64 tsn, s64 sid, s64 ssn, s64 ppid) { - struct sctp_chunk_list_item *item; struct sctp_data_chunk *chunk; u32 flags; u16 payload_len = 1000; @@ -137,7 +136,12 @@ sctp_data_chunk_new(s64 tsn, s64 sid, s64 ssn, s64 ppid) chunk = malloc(sizeof(struct sctp_data_chunk) + payload_len); assert(chunk != NULL); chunk->type = SCTP_DATA_CHUNK_TYPE; - chunk->flags = 0x03; /* FIXME */ + if (flgs == -1) { + chunk->flags = 0; + flags |= FLAG_CHUNK_FLAGS_NOCHECK; + } else { + chunk->flags = (u8)flgs; + } chunk->length = htons(sizeof(struct sctp_data_chunk) + payload_len); if (tsn == -1) { chunk->tsn = htonl(0); @@ -164,16 +168,14 @@ sctp_data_chunk_new(s64 tsn, s64 sid, s64 ssn, s64 ppid) chunk->ppid = htons((u32)ppid); } memset(chunk->data, 0, payload_len); - item = sctp_chunk_list_item_new((struct sctp_chunk *)chunk, + return sctp_chunk_list_item_new((struct sctp_chunk *)chunk, (u32)sizeof(struct sctp_data_chunk) + payload_len, flags); - return item; } struct sctp_chunk_list_item * -sctp_init_chunk_new(s64 tag, s64 a_rwnd, s64 os, s64 is, s64 tsn) +sctp_init_chunk_new(s64 flgs, s64 tag, s64 a_rwnd, s64 os, s64 is, s64 tsn) { - struct sctp_chunk_list_item *item; struct sctp_init_chunk *chunk; u32 flags; @@ -181,7 +183,12 @@ sctp_init_chunk_new(s64 tag, s64 a_rwnd, s64 os, s64 is, s64 tsn) chunk = malloc(sizeof(struct sctp_init_chunk)); assert(chunk != NULL); chunk->type = SCTP_INIT_CHUNK_TYPE; - chunk->flags = 0; + if (flgs == -1) { + chunk->flags = 0; + flags |= FLAG_CHUNK_FLAGS_NOCHECK; + } else { + chunk->flags = (u8)flgs; + } /* FIXME */ flags |= FLAG_CHUNK_LENGTH_NOCHECK; chunk->length = htons(sizeof(struct sctp_init_chunk)); @@ -205,17 +212,15 @@ sctp_init_chunk_new(s64 tag, s64 a_rwnd, s64 os, s64 is, s64 tsn) chunk->is = htons((u16)is); } chunk->initial_tsn = htonl((u32)tsn); - item = sctp_chunk_list_item_new((struct sctp_chunk *)chunk, + return sctp_chunk_list_item_new((struct sctp_chunk *)chunk, (u32)sizeof(struct sctp_init_chunk), flags); - return item; } /* FIXME: Don't fake the cookie that way... */ struct sctp_chunk_list_item * -sctp_init_ack_chunk_new(s64 tag, s64 a_rwnd, s64 os, s64 is, s64 tsn) +sctp_init_ack_chunk_new(s64 flgs, s64 tag, s64 a_rwnd, s64 os, s64 is, s64 tsn) { - struct sctp_chunk_list_item *item; struct sctp_init_ack_chunk *chunk; struct sctp_state_cookie_parameter state_cookie_parameter; u32 flags; @@ -224,7 +229,12 @@ sctp_init_ack_chunk_new(s64 tag, s64 a_rwnd, s64 os, s64 is, s64 tsn) chunk = malloc(sizeof(struct sctp_init_ack_chunk) + sizeof(struct sctp_state_cookie_parameter)); assert(chunk != NULL); chunk->type = SCTP_INIT_ACK_CHUNK_TYPE; - chunk->flags = 0; + if (flgs == -1) { + chunk->flags = 0; + flags |= FLAG_CHUNK_FLAGS_NOCHECK; + } else { + chunk->flags = (u8)flgs; + } /* FIXME */ flags |= FLAG_CHUNK_LENGTH_NOCHECK; chunk->length = htons(sizeof(struct sctp_init_ack_chunk) + sizeof(struct sctp_state_cookie_parameter)); @@ -251,14 +261,13 @@ sctp_init_ack_chunk_new(s64 tag, s64 a_rwnd, s64 os, s64 is, s64 tsn) state_cookie_parameter.type = htons(SCTP_STATE_COOKIE_PARAMETER_TYPE); state_cookie_parameter.length = htons(sizeof(struct sctp_state_cookie_parameter)); memcpy(chunk->parameter, &state_cookie_parameter, sizeof(struct sctp_state_cookie_parameter)); - item = sctp_chunk_list_item_new((struct sctp_chunk *)chunk, + return sctp_chunk_list_item_new((struct sctp_chunk *)chunk, (u32)sizeof(struct sctp_init_ack_chunk) + sizeof(struct sctp_state_cookie_parameter), flags); - return item; } struct sctp_chunk_list_item * -sctp_sack_chunk_new(s64 cum_tsn, s64 a_rwnd, +sctp_sack_chunk_new(s64 flgs, s64 cum_tsn, s64 a_rwnd, struct sctp_sack_block_list *gaps, struct sctp_sack_block_list *dups) { @@ -291,7 +300,12 @@ sctp_sack_chunk_new(s64 cum_tsn, s64 a_rwnd, chunk = malloc(length); assert(chunk != NULL); chunk->type = SCTP_SACK_CHUNK_TYPE; - chunk->flags = 0; + if (flgs == -1) { + chunk->flags = 0; + flags |= FLAG_CHUNK_FLAGS_NOCHECK; + } else { + chunk->flags = (u8)flgs; + } chunk->length = htons(length); if (cum_tsn == -1) { chunk->cum_tsn = htonl(0); @@ -330,60 +344,74 @@ sctp_sack_chunk_new(s64 cum_tsn, s64 a_rwnd, } struct sctp_chunk_list_item * -sctp_heartbeat_chunk_new(u8 flags) +sctp_heartbeat_chunk_new(s64 flgs) { - struct sctp_chunk_list_item *item; struct sctp_heartbeat_chunk *chunk; + u32 flags; + flags = FLAG_CHUNK_LENGTH_NOCHECK | FLAG_CHUNK_VALUE_NOCHECK; chunk = malloc(sizeof(struct sctp_heartbeat_chunk)); assert(chunk != NULL); chunk->type = SCTP_HEARTBEAT_CHUNK_TYPE; - chunk->flags = flags; + if (flgs == -1) { + chunk->flags = 0; + flags |= FLAG_CHUNK_FLAGS_NOCHECK; + } else { + chunk->flags = (u8)flgs; + } chunk->length = htons(sizeof(struct sctp_heartbeat_chunk)); - item = sctp_chunk_list_item_new((struct sctp_chunk *)chunk, + return sctp_chunk_list_item_new((struct sctp_chunk *)chunk, (u32)sizeof(struct sctp_heartbeat_chunk), - FLAG_CHUNK_LENGTH_NOCHECK | FLAG_CHUNK_VALUE_NOCHECK); - return item; + flags); } struct sctp_chunk_list_item * -sctp_heartbeat_ack_chunk_new(u8 flags) +sctp_heartbeat_ack_chunk_new(s64 flgs) { - struct sctp_chunk_list_item *item; struct sctp_heartbeat_ack_chunk *chunk; + u32 flags; + flags = FLAG_CHUNK_LENGTH_NOCHECK | FLAG_CHUNK_VALUE_NOCHECK; chunk = malloc(sizeof(struct sctp_heartbeat_ack_chunk)); assert(chunk != NULL); chunk->type = SCTP_HEARTBEAT_ACK_CHUNK_TYPE; - chunk->flags = flags; + if (flgs == -1) { + chunk->flags = 0; + flags |= FLAG_CHUNK_FLAGS_NOCHECK; + } else { + chunk->flags = (u8)flgs; + } chunk->length = htons(sizeof(struct sctp_heartbeat_ack_chunk)); - item = sctp_chunk_list_item_new((struct sctp_chunk *)chunk, + return sctp_chunk_list_item_new((struct sctp_chunk *)chunk, (u32)sizeof(struct sctp_heartbeat_ack_chunk), - FLAG_CHUNK_LENGTH_NOCHECK | FLAG_CHUNK_VALUE_NOCHECK); - return item; + flags); } struct sctp_chunk_list_item * -sctp_abort_chunk_new(u8 flags) +sctp_abort_chunk_new(s64 flgs) { - struct sctp_chunk_list_item *item; struct sctp_abort_chunk *chunk; + u32 flags; + flags = 0; chunk = malloc(sizeof(struct sctp_abort_chunk)); assert(chunk != NULL); chunk->type = SCTP_ABORT_CHUNK_TYPE; - chunk->flags = flags; + if (flgs == -1) { + chunk->flags = 0; + flags |= FLAG_CHUNK_FLAGS_NOCHECK; + } else { + chunk->flags = (u8)flgs; + } chunk->length = htons(sizeof(struct sctp_abort_chunk)); - item = sctp_chunk_list_item_new((struct sctp_chunk *)chunk, + return sctp_chunk_list_item_new((struct sctp_chunk *)chunk, (u32)sizeof(struct sctp_abort_chunk), - 0); - return item; + flags); } struct sctp_chunk_list_item * -sctp_shutdown_chunk_new(s64 cum_tsn) +sctp_shutdown_chunk_new(s64 flgs, s64 cum_tsn) { - struct sctp_chunk_list_item *item; struct sctp_shutdown_chunk *chunk; u32 flags; @@ -391,7 +419,12 @@ sctp_shutdown_chunk_new(s64 cum_tsn) chunk = malloc(sizeof(struct sctp_shutdown_chunk)); assert(chunk != NULL); chunk->type = SCTP_SHUTDOWN_CHUNK_TYPE; - chunk->flags = 0; + if (flgs == -1) { + chunk->flags = 0; + flags |= FLAG_CHUNK_FLAGS_NOCHECK; + } else { + chunk->flags = (u8)flgs; + } chunk->length = htons(sizeof(struct sctp_shutdown_chunk)); if (cum_tsn == -1) { chunk->cum_tsn = htonl(0); @@ -400,84 +433,102 @@ sctp_shutdown_chunk_new(s64 cum_tsn) chunk->cum_tsn = htonl((u32)cum_tsn); } - item = sctp_chunk_list_item_new((struct sctp_chunk *)chunk, + return sctp_chunk_list_item_new((struct sctp_chunk *)chunk, (u32)sizeof(struct sctp_shutdown_chunk), flags); - return item; } struct sctp_chunk_list_item * -sctp_shutdown_ack_chunk_new(u8 flags) +sctp_shutdown_ack_chunk_new(s64 flgs) { - struct sctp_chunk_list_item *item; struct sctp_shutdown_ack_chunk *chunk; + u32 flags; + flags = 0; chunk = malloc(sizeof(struct sctp_shutdown_ack_chunk)); assert(chunk != NULL); chunk->type = SCTP_SHUTDOWN_ACK_CHUNK_TYPE; - chunk->flags = flags; + if (flgs == -1) { + chunk->flags = 0; + flags |= FLAG_CHUNK_FLAGS_NOCHECK; + } else { + chunk->flags = (u8)flgs; + } chunk->length = htons(sizeof(struct sctp_shutdown_ack_chunk)); - item = sctp_chunk_list_item_new((struct sctp_chunk *)chunk, + return sctp_chunk_list_item_new((struct sctp_chunk *)chunk, (u32)sizeof(struct sctp_shutdown_ack_chunk), - 0); - return item; + flags); } struct sctp_chunk_list_item * -sctp_error_chunk_new(u8 flags) +sctp_error_chunk_new(s64 flgs) { - struct sctp_chunk_list_item *item; struct sctp_error_chunk *chunk; + u32 flags; + flags = FLAG_CHUNK_LENGTH_NOCHECK | FLAG_CHUNK_VALUE_NOCHECK; chunk = malloc(sizeof(struct sctp_error_chunk)); assert(chunk != NULL); chunk->type = SCTP_ERROR_CHUNK_TYPE; - chunk->flags = flags; + if (flgs == -1) { + chunk->flags = 0; + flags |= FLAG_CHUNK_FLAGS_NOCHECK; + } else { + chunk->flags = (u8)flgs; + } chunk->length = htons(sizeof(struct sctp_error_chunk)); - item = sctp_chunk_list_item_new((struct sctp_chunk *)chunk, + return sctp_chunk_list_item_new((struct sctp_chunk *)chunk, (u32)sizeof(struct sctp_error_chunk), - FLAG_CHUNK_LENGTH_NOCHECK | FLAG_CHUNK_VALUE_NOCHECK); - return item; + flags); } struct sctp_chunk_list_item * -sctp_cookie_echo_chunk_new(u8 flags) +sctp_cookie_echo_chunk_new(s64 flgs) { - struct sctp_chunk_list_item *item; struct sctp_cookie_echo_chunk *chunk; + u32 flags; + flags = FLAG_CHUNK_LENGTH_NOCHECK | FLAG_CHUNK_VALUE_NOCHECK; chunk = malloc(sizeof(struct sctp_cookie_echo_chunk)); assert(chunk != NULL); chunk->type = SCTP_COOKIE_ECHO_CHUNK_TYPE; - chunk->flags = flags; + if (flgs == -1) { + chunk->flags = 0; + flags |= FLAG_CHUNK_FLAGS_NOCHECK; + } else { + chunk->flags = (u8)flgs; + } chunk->length = htons(sizeof(struct sctp_cookie_echo_chunk)); - item = sctp_chunk_list_item_new((struct sctp_chunk *)chunk, + return sctp_chunk_list_item_new((struct sctp_chunk *)chunk, (u32)sizeof(struct sctp_cookie_echo_chunk), - FLAG_CHUNK_LENGTH_NOCHECK | FLAG_CHUNK_VALUE_NOCHECK); - return item; + flags); } struct sctp_chunk_list_item * -sctp_cookie_ack_chunk_new(u8 flags) +sctp_cookie_ack_chunk_new(s64 flgs) { - struct sctp_chunk_list_item *item; struct sctp_cookie_ack_chunk *chunk; + u32 flags; + flags = 0; chunk = malloc(sizeof(struct sctp_cookie_ack_chunk)); assert(chunk != NULL); chunk->type = SCTP_COOKIE_ACK_CHUNK_TYPE; - chunk->flags = flags; + if (flgs == -1) { + chunk->flags = 0; + flags |= FLAG_CHUNK_FLAGS_NOCHECK; + } else { + chunk->flags = (u8)flgs; + } chunk->length = htons(sizeof(struct sctp_cookie_ack_chunk)); - item = sctp_chunk_list_item_new((struct sctp_chunk *)chunk, + return sctp_chunk_list_item_new((struct sctp_chunk *)chunk, (u32)sizeof(struct sctp_cookie_ack_chunk), - 0); - return item; + flags); } struct sctp_chunk_list_item * -sctp_ecne_chunk_new(s64 lowest_tsn) +sctp_ecne_chunk_new(s64 flgs, s64 lowest_tsn) { - struct sctp_chunk_list_item *item; struct sctp_ecne_chunk *chunk; u32 flags; @@ -485,7 +536,12 @@ sctp_ecne_chunk_new(s64 lowest_tsn) chunk = malloc(sizeof(struct sctp_ecne_chunk)); assert(chunk != NULL); chunk->type = SCTP_ECNE_CHUNK_TYPE; - chunk->flags = 0; + if (flgs == -1) { + chunk->flags = 0; + flags |= FLAG_CHUNK_FLAGS_NOCHECK; + } else { + chunk->flags = (u8)flgs; + } chunk->length = htons(sizeof(struct sctp_ecne_chunk)); if (lowest_tsn == -1) { chunk->lowest_tsn = htonl(0); @@ -494,16 +550,14 @@ sctp_ecne_chunk_new(s64 lowest_tsn) chunk->lowest_tsn = htonl((u32)lowest_tsn); } - item = sctp_chunk_list_item_new((struct sctp_chunk *)chunk, + return sctp_chunk_list_item_new((struct sctp_chunk *)chunk, (u32)sizeof(struct sctp_ecne_chunk), flags); - return item; } struct sctp_chunk_list_item * -sctp_cwr_chunk_new(s64 lowest_tsn) +sctp_cwr_chunk_new(s64 flgs, s64 lowest_tsn) { - struct sctp_chunk_list_item *item; struct sctp_cwr_chunk *chunk; u32 flags; @@ -511,7 +565,12 @@ sctp_cwr_chunk_new(s64 lowest_tsn) chunk = malloc(sizeof(struct sctp_cwr_chunk)); assert(chunk != NULL); chunk->type = SCTP_CWR_CHUNK_TYPE; - chunk->flags = 0; + if (flgs == -1) { + chunk->flags = 0; + flags |= FLAG_CHUNK_FLAGS_NOCHECK; + } else { + chunk->flags = (u8)flgs; + } chunk->length = htons(sizeof(struct sctp_cwr_chunk)); if (lowest_tsn == -1) { chunk->lowest_tsn = htonl(0); @@ -520,27 +579,31 @@ sctp_cwr_chunk_new(s64 lowest_tsn) chunk->lowest_tsn = htonl((u32)lowest_tsn); } - item = sctp_chunk_list_item_new((struct sctp_chunk *)chunk, + return sctp_chunk_list_item_new((struct sctp_chunk *)chunk, (u32)sizeof(struct sctp_cwr_chunk), flags); - return item; } struct sctp_chunk_list_item * -sctp_shutdown_complete_chunk_new(u8 flags) +sctp_shutdown_complete_chunk_new(s64 flgs) { - struct sctp_chunk_list_item *item; struct sctp_shutdown_complete_chunk *chunk; + u32 flags; + flags = 0; chunk = malloc(sizeof(struct sctp_shutdown_complete_chunk)); assert(chunk != NULL); chunk->type = SCTP_SHUTDOWN_COMPLETE_CHUNK_TYPE; - chunk->flags = flags; + if (flgs == -1) { + chunk->flags = 0; + flags |= FLAG_CHUNK_FLAGS_NOCHECK; + } else { + chunk->flags = (u8)flgs; + } chunk->length = htons(sizeof(struct sctp_shutdown_complete_chunk)); - item = sctp_chunk_list_item_new((struct sctp_chunk *)chunk, + return sctp_chunk_list_item_new((struct sctp_chunk *)chunk, (u32)sizeof(struct sctp_shutdown_complete_chunk), - 0); - return item; + flags); } struct sctp_chunk_list * diff --git a/gtests/net/packetdrill/sctp_packet.h b/gtests/net/packetdrill/sctp_packet.h index dfe4eba0f91d6fe0472c6cd24c4f85fb9b1867e3..6f03fc71360e8baf7567931ae913e7078cc94407 100644 --- a/gtests/net/packetdrill/sctp_packet.h +++ b/gtests/net/packetdrill/sctp_packet.h @@ -86,21 +86,21 @@ sctp_chunk_list_item_new(struct sctp_chunk *chunk, u32 length, u32 flags); #define FLAG_DATA_CHUNK_PPID_NOCHECK 0x00000800 struct sctp_chunk_list_item * -sctp_data_chunk_new(s64 tsn, s64 sid, s64 ssn, s64 ppid); +sctp_data_chunk_new(s64 flgs, s64 tsn, s64 sid, s64 ssn, s64 ppid); #define FLAG_INIT_CHUNK_A_RWND_NOCHECK 0x00000100 #define FLAG_INIT_CHUNK_OS_NOCHECK 0x00000200 #define FLAG_INIT_CHUNK_IS_NOCHECK 0x00000400 struct sctp_chunk_list_item * -sctp_init_chunk_new(s64 tag, s64 a_rwnd, s64 os, s64 is, s64 tsn); +sctp_init_chunk_new(s64 flgs, s64 tag, s64 a_rwnd, s64 os, s64 is, s64 tsn); #define FLAG_INIT_ACK_CHUNK_A_RWND_NOCHECK 0x00000100 #define FLAG_INIT_ACK_CHUNK_OS_NOCHECK 0x00000200 #define FLAG_INIT_ACK_CHUNK_IS_NOCHECK 0x00000400 struct sctp_chunk_list_item * -sctp_init_ack_chunk_new(s64 tag, s64 a_rwnd, s64 os, s64 is, s64 tsn); +sctp_init_ack_chunk_new(s64 flgs, s64 tag, s64 a_rwnd, s64 os, s64 is, s64 tsn); #define FLAG_SACK_CHUNK_CUM_TSN_NOCHECK 0x00000100 #define FLAG_SACK_CHUNK_A_RWND_NOCHECK 0x00000200 @@ -108,48 +108,48 @@ sctp_init_ack_chunk_new(s64 tag, s64 a_rwnd, s64 os, s64 is, s64 tsn); #define FLAG_SACK_CHUNK_DUP_TSNS_NOCHECK 0x00000800 struct sctp_chunk_list_item * -sctp_sack_chunk_new(s64 cum_tsn, s64 a_rwnd, +sctp_sack_chunk_new(s64 flgs, s64 cum_tsn, s64 a_rwnd, struct sctp_sack_block_list *gaps, struct sctp_sack_block_list *dups); struct sctp_chunk_list_item * -sctp_heartbeat_chunk_new(u8 flags); +sctp_heartbeat_chunk_new(s64 flgs); struct sctp_chunk_list_item * -sctp_heartbeat_ack_chunk_new(u8 flags); +sctp_heartbeat_ack_chunk_new(s64 flgs); struct sctp_chunk_list_item * -sctp_abort_chunk_new(u8 flags); +sctp_abort_chunk_new(s64 flgs); #define FLAG_SHUTDOWN_CHUNK_CUM_TSN_NOCHECK 0x00000100 struct sctp_chunk_list_item * -sctp_shutdown_chunk_new(s64 cum_tsn); +sctp_shutdown_chunk_new(s64 flgs, s64 cum_tsn); struct sctp_chunk_list_item * -sctp_shutdown_ack_chunk_new(u8 flags); +sctp_shutdown_ack_chunk_new(s64 flgs); struct sctp_chunk_list_item * -sctp_error_chunk_new(u8 flags); +sctp_error_chunk_new(s64 flgs); struct sctp_chunk_list_item * -sctp_cookie_echo_chunk_new(u8 flags); +sctp_cookie_echo_chunk_new(s64 flgs); struct sctp_chunk_list_item * -sctp_cookie_ack_chunk_new(u8 flags); +sctp_cookie_ack_chunk_new(s64 flgs); #define FLAG_ECNE_CHUNK_LOWEST_TSN_NOCHECK 0x00000100 struct sctp_chunk_list_item * -sctp_ecne_chunk_new(s64 lowest_tsn); +sctp_ecne_chunk_new(s64 flgs, s64 lowest_tsn); #define FLAG_CWR_CHUNK_LOWEST_TSN_NOCHECK 0x00000100 struct sctp_chunk_list_item * -sctp_cwr_chunk_new(s64 lowest_tsn); +sctp_cwr_chunk_new(s64 flgs, s64 lowest_tsn); struct sctp_chunk_list_item * -sctp_shutdown_complete_chunk_new(u8 flags); +sctp_shutdown_complete_chunk_new(s64 flgs); struct sctp_chunk_list *sctp_chunk_list_new(void); diff --git a/gtests/net/packetdrill/tests/bsd/sctp/sctp_active.pkt b/gtests/net/packetdrill/tests/bsd/sctp/sctp_active.pkt index 3d3eb5881e5df739d39914802b47f758f1d34eba..5b348acaf98ec1cc42ca21bfb6776aa19806a095 100644 --- a/gtests/net/packetdrill/tests/bsd/sctp/sctp_active.pkt +++ b/gtests/net/packetdrill/tests/bsd/sctp/sctp_active.pkt @@ -13,15 +13,15 @@ +0.0 > sctp: DATA[tsn=0 sid=0 ssn=0 ppid=0] +0.1 < sctp: SACK[tsn=0 a_rwnd=1500 gaps=[] dups=[]] // Receive some data -+1.0 < sctp: DATA[tsn=3 sid=0 ssn=0 ppid=0] // How to handle ++1.0 < sctp: DATA[flgs=0x3 tsn=3 sid=0 ssn=0 ppid=0] // How to handle +0.0 read(3, ..., 2000) = 1000 +0.0 > sctp: SACK[tsn=3] // Receive more data, observe delayed SACK -+1.0 < sctp: DATA[tsn=4 sid=0 ssn=1 ppid=0] ++1.0 < sctp: DATA[flgs=0x0b tsn=4 sid=0 ssn=1 ppid=0] +0.0 read(3, ..., 2000) = 1000 -+0.2 > sctp: SACK[tsn=4] ++0.0 > sctp: SACK[tsn=4] // Tear down the association +0.0 close(3) = 0 +0.0 > sctp: SHUTDOWN[tsn=4] +0.1 < sctp: SHUTDOWN_ACK[] -+0.0 > sctp: SHUTDOWN_COMPLETE[] ++0.0 > sctp: SHUTDOWN_COMPLETE[flgs=0x01]