From 820fdaae845358a3392da57f2ff94df029dff765 Mon Sep 17 00:00:00 2001 From: AmPaschal Date: Sat, 24 Sep 2022 15:06:42 +0000 Subject: [PATCH 01/17] When a test fails, before exiting, call function to free the shared object state. --- gtests/net/packetdrill/code.c | 2 +- gtests/net/packetdrill/logging.c | 16 ++++++++++++++++ gtests/net/packetdrill/logging.h | 3 +++ gtests/net/packetdrill/packetdrill.c | 1 + gtests/net/packetdrill/run.c | 4 +++- gtests/net/packetdrill/run_command.c | 2 +- gtests/net/packetdrill/run_packet.c | 4 ++-- gtests/net/packetdrill/run_system_call.c | 4 ++-- 8 files changed, 29 insertions(+), 7 deletions(-) diff --git a/gtests/net/packetdrill/code.c b/gtests/net/packetdrill/code.c index 47ec79e5..64c2c09b 100644 --- a/gtests/net/packetdrill/code.c +++ b/gtests/net/packetdrill/code.c @@ -777,7 +777,7 @@ void run_code_event(struct state *state, struct event *event, return; error_out: - die("%s:%d: runtime error in code: %s\n", + die_free_so(state, "%s:%d: runtime error in code: %s\n", state->config->script_path, event->line_number, error); free(error); } diff --git a/gtests/net/packetdrill/logging.c b/gtests/net/packetdrill/logging.c index 730add4b..16483d47 100644 --- a/gtests/net/packetdrill/logging.c +++ b/gtests/net/packetdrill/logging.c @@ -49,3 +49,19 @@ void __attribute__((noreturn)) die_perror(char *message) exit(EXIT_FAILURE); } + +extern void __attribute__((noreturn)) die_free_so(struct state *state, char *format, ...) +{ + va_list ap; + + if (state->so_instance) + so_instance_free(state->so_instance); + + va_start(ap, format); + vfprintf(stderr, format, ap); + va_end(ap); + + run_cleanup_command(); + + exit(EXIT_FAILURE); +} diff --git a/gtests/net/packetdrill/logging.h b/gtests/net/packetdrill/logging.h index d961c9d5..47234065 100644 --- a/gtests/net/packetdrill/logging.h +++ b/gtests/net/packetdrill/logging.h @@ -43,4 +43,7 @@ extern void __attribute__((noreturn)) die(char *format, ...); /* Call perror() with message and then exit with a failure status code. */ extern void __attribute__((noreturn)) die_perror(char *message); +/* Call so_instance_free() to free the so instance, then log the message to stderr and exit */ +extern void __attribute__((noreturn)) die_free_so(struct state *state, char *format, ...); + #endif /* __LOGGING_H__ */ diff --git a/gtests/net/packetdrill/packetdrill.c b/gtests/net/packetdrill/packetdrill.c index 4afa038e..8318c0e0 100644 --- a/gtests/net/packetdrill/packetdrill.c +++ b/gtests/net/packetdrill/packetdrill.c @@ -63,6 +63,7 @@ static void run_init_scripts(struct config *config) int main(int argc, char *argv[]) { + printf("Starting Packetdrill v1"); struct config config; set_default_config(&config); /* Get command line options and list of test scripts. */ diff --git a/gtests/net/packetdrill/run.c b/gtests/net/packetdrill/run.c index 37ec449e..f3a4cc0f 100644 --- a/gtests/net/packetdrill/run.c +++ b/gtests/net/packetdrill/run.c @@ -430,7 +430,9 @@ static void run_local_packet_event(struct state *state, struct event *event, fprintf(stderr, "%s", error); free(error); } else if (result == STATUS_ERR) { - die("%s", error); + + die_free_so(state, "%s", error); + } } diff --git a/gtests/net/packetdrill/run_command.c b/gtests/net/packetdrill/run_command.c index a55e596d..71d39ade 100644 --- a/gtests/net/packetdrill/run_command.c +++ b/gtests/net/packetdrill/run_command.c @@ -48,7 +48,7 @@ void run_command_event( return; error_out: - die("%s:%d: error executing `%s` command: %s\n", + die_free_so(state, "%s:%d: error executing `%s` command: %s\n", state->config->script_path, event->line_number, command->command_line, error); free(error); diff --git a/gtests/net/packetdrill/run_packet.c b/gtests/net/packetdrill/run_packet.c index 7ca353ab..436126bb 100644 --- a/gtests/net/packetdrill/run_packet.c +++ b/gtests/net/packetdrill/run_packet.c @@ -1407,10 +1407,10 @@ static int verify_outbound_live_packet( out: add_packet_dump(error, "script", script_packet, script_usecs, - DUMP_SHORT); + DUMP_VERBOSE); if (actual_packet != NULL) { add_packet_dump(error, "actual", actual_packet, actual_usecs, - DUMP_SHORT); + DUMP_VERBOSE); packet_free(actual_packet); } if (result == STATUS_ERR && diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c index c35ea135..a520388e 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -3336,7 +3336,7 @@ static void invoke_system_call( return; error_out: - die("%s:%d: runtime error in %s call: %s\n", + die_free_so(state, "%s:%d: runtime error in %s call: %s\n", state->config->script_path, event->line_number, syscall->name, error); free(error); @@ -3434,7 +3434,7 @@ static void enqueue_system_call( return; error_out: - die("%s:%d: runtime error in %s call: %s\n", + die_free_so(state, "%s:%d: runtime error in %s call: %s\n", state->config->script_path, event->line_number, syscall->name, error); free(error); From e236e6ec5666a2614b7b175bde19e3da13a4703d Mon Sep 17 00:00:00 2001 From: AmPaschal Date: Sat, 24 Sep 2022 15:08:11 +0000 Subject: [PATCH 02/17] Modified packets and removed linux calls --- gtests/net/tcp/blocking/blocking-read.pkt | 4 ++-- gtests/net/tcp/close/close-remote-fin-then-close.pkt | 4 ++-- gtests/net/tcp/limited_transmit/limited-transmit-sack.pkt | 2 +- gtests/net/tcp/md5/md5-only-on-client-ack.pkt | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/gtests/net/tcp/blocking/blocking-read.pkt b/gtests/net/tcp/blocking/blocking-read.pkt index 47a2df06..32837fe9 100644 --- a/gtests/net/tcp/blocking/blocking-read.pkt +++ b/gtests/net/tcp/blocking/blocking-read.pkt @@ -1,7 +1,7 @@ // Test for blocking read. ---tolerance_usecs=10000 +//--tolerance_usecs=10000 -`../common/defaults.sh` +//`../common/defaults.sh` // Establish a connection. 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 diff --git a/gtests/net/tcp/close/close-remote-fin-then-close.pkt b/gtests/net/tcp/close/close-remote-fin-then-close.pkt index de5b1c72..45dd4a3a 100644 --- a/gtests/net/tcp/close/close-remote-fin-then-close.pkt +++ b/gtests/net/tcp/close/close-remote-fin-then-close.pkt @@ -1,7 +1,7 @@ // Verify behavior for the sequence: remote side sends FIN, then we close(). // Since the remote side (client) closes first, we test our LAST_ACK code path. -`../common/defaults.sh` +//`../common/defaults.sh` // Initialize a server socket. 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 @@ -20,7 +20,7 @@ +0 > . 1:1(0) ack 2 // App notices that client closed. - +0 read(4, ..., 1000) = 0 +// +0 read(4, ..., 1000) = 0 // Then we close. +.01 close(4) = 0 diff --git a/gtests/net/tcp/limited_transmit/limited-transmit-sack.pkt b/gtests/net/tcp/limited_transmit/limited-transmit-sack.pkt index 4b135231..b971ad65 100644 --- a/gtests/net/tcp/limited_transmit/limited-transmit-sack.pkt +++ b/gtests/net/tcp/limited_transmit/limited-transmit-sack.pkt @@ -3,7 +3,7 @@ // arrive at the sender". // This variation tests a receiver that supports SACK. -`../common/defaults.sh` +//`../common/defaults.sh` // Establish a connection. 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 diff --git a/gtests/net/tcp/md5/md5-only-on-client-ack.pkt b/gtests/net/tcp/md5/md5-only-on-client-ack.pkt index 1fb838c9..4240f20c 100644 --- a/gtests/net/tcp/md5/md5-only-on-client-ack.pkt +++ b/gtests/net/tcp/md5/md5-only-on-client-ack.pkt @@ -1,7 +1,7 @@ // Test what happens when client does not provide MD5 on SYN, // but then does on the ACK that completes the three-way handshake. -`../../common/defaults.sh` +//`../../common/defaults.sh` // Establish a connection. 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 @@ -16,7 +16,7 @@ +.01 < . 1:1(0) ack 1 win 514 // The TCP listener refcount should be 2, but on buggy kernels it can be 0: - +0 `grep " 0A " /proc/net/tcp /proc/net/tcp6 | grep ":1F90"` +// +0 `grep " 0A " /proc/net/tcp /proc/net/tcp6 | grep ":1F90"` // Now here comes the legit ACK: +.01 < . 1:1(0) ack 1 win 514 From 0369ca4fbb87a98e0cd94b2f3765b5d5951c3f63 Mon Sep 17 00:00:00 2001 From: AmPaschal Date: Mon, 26 Sep 2022 19:08:53 +0000 Subject: [PATCH 03/17] Started extending PacketDrill's grammar. --- gtests/net/packetdrill/lexer.l | 8 +++++++ gtests/net/packetdrill/logging.h | 2 ++ gtests/net/packetdrill/parser.y | 36 +++++++++++++++++++++++++++++++- 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index 7d063d37..ba2a90be 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -262,6 +262,14 @@ ect1 return ECT1; noecn return NO_ECN; ce return CE; id return ID; +mut return MUTATE; +trun return TRUNCATE; +ins return INSERT; +ip return IP; +tcp return TCP; +ihl return IHL; +source_port return SOURCE_PORT; + [.][.][.] return ELLIPSIS; --[a-zA-Z0-9_]+ yylval.string = option(yytext); return OPTION; [-]?[0-9]*[.][0-9]+ yylval.floating = atof(yytext); return FLOAT; diff --git a/gtests/net/packetdrill/logging.h b/gtests/net/packetdrill/logging.h index 47234065..fed3dd62 100644 --- a/gtests/net/packetdrill/logging.h +++ b/gtests/net/packetdrill/logging.h @@ -37,6 +37,8 @@ fflush(stdout); \ } +struct state; + /* Log the message to stderr and then exit with a failure status code. */ extern void __attribute__((noreturn)) die(char *format, ...); diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index 08aff3ea..5165d7f8 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -546,6 +546,9 @@ static struct packet *append_gre(struct packet *packet, struct expression *expr) %token NONE CHECKSUM SEQUENCE PRESENT %token EE_ERRNO EE_CODE EE_DATA EE_INFO EE_ORIGIN EE_TYPE %token SCM_SEC SCM_NSEC +%token MUTATE TRUNCATE INSERT +%token IP TCP +%token IHL SOURCE_PORT %token FLOAT %token INTEGER HEX_INTEGER %token WORD STRING BACK_QUOTED CODE IPV4_ADDR IPV6_ADDR @@ -580,6 +583,10 @@ static struct packet *append_gre(struct packet *packet, struct expression *expr) %type seq opt_icmp_echoed %type opt_tcp_options tcp_option_list %type tcp_option sack_block_list sack_block +%type opt_fuzz_info opt_fuzz_params +%type opt_fuzz_param +%type fuzz_type header_type fuzz_field field_name +%type field_pos field_offset %type function_name %type expression_list function_arguments %type expression binary_expression array sub_expr_list @@ -784,7 +791,7 @@ packet_spec ; tcp_packet_spec -: packet_prefix opt_ip_info opt_port_info flags seq opt_ack opt_window opt_urg_ptr opt_tcp_options { +: packet_prefix opt_ip_info opt_port_info flags seq opt_ack opt_window opt_urg_ptr opt_tcp_options opt_fuzz_info { char *error = NULL; struct packet *outer = $1, *inner = NULL; enum direction_t direction = outer->direction; @@ -1365,6 +1372,33 @@ sack_block } ; +opt_fuzz_info +: '{' opt_fuzz_params '}'; + +opt_fuzz_params +: opt_fuzz_param | opt_fuzz_params ';' opt_fuzz_param; + +opt_fuzz_param +: fuzz_type header_type fuzz_field; + +fuzz_type +: MUTATE | TRUNCATE | INSERT; + +header_type +: IP | TCP; + +fuzz_field +: field_name | field_pos | field_offset; + +field_name +: MSS | IHL | SOURCE_PORT; + +field_pos +: INTEGER '-' INTEGER; + +field_offset +: INTEGER INTEGER; + syscall_spec : opt_end_time function_name function_arguments '=' expression opt_errno opt_note { From 03a108cce4cf95a6b0f97eab11eb9e4fdba254de Mon Sep 17 00:00:00 2001 From: AmPaschal Date: Fri, 30 Sep 2022 19:27:01 +0000 Subject: [PATCH 04/17] Grammar has been extended with fuzz instructions --- .gitignore | 2 + gtests/net/packetdrill/Makefile.common | 2 +- gtests/net/packetdrill/fuzz_options.c | 45 +++++++ gtests/net/packetdrill/fuzz_options.h | 46 +++++++ gtests/net/packetdrill/lexer.l | 2 +- gtests/net/packetdrill/parser.y | 113 +++++++++++++++--- gtests/net/packetdrill/run_packet.c | 2 +- gtests/net/packetdrill/tcp_packet.c | 1 + gtests/net/packetdrill/tcp_packet.h | 2 + .../tcp/blocking/blocking-connect-fuzz-2.pkt | 12 ++ .../tcp/blocking/blocking-connect-fuzz.pkt | 12 ++ gtests/net/tcp/blocking/blocking-read-2.pkt | 28 +++++ 12 files changed, 246 insertions(+), 21 deletions(-) create mode 100644 .gitignore create mode 100644 gtests/net/packetdrill/fuzz_options.c create mode 100644 gtests/net/packetdrill/fuzz_options.h create mode 100644 gtests/net/tcp/blocking/blocking-connect-fuzz-2.pkt create mode 100644 gtests/net/tcp/blocking/blocking-connect-fuzz.pkt create mode 100644 gtests/net/tcp/blocking/blocking-read-2.pkt diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..f2c8c65e --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +/.idea/ +/.vscode/ \ No newline at end of file diff --git a/gtests/net/packetdrill/Makefile.common b/gtests/net/packetdrill/Makefile.common index b614d085..e81f3359 100644 --- a/gtests/net/packetdrill/Makefile.common +++ b/gtests/net/packetdrill/Makefile.common @@ -29,7 +29,7 @@ packetdrill-lib := \ link_layer.o wire_conn.o wire_protocol.o \ wire_client.o wire_client_netdev.o \ wire_server.o wire_server_netdev.o \ - epoll.o pipe.o file.o so_testing.o wrap.o + epoll.o pipe.o file.o so_testing.o wrap.o fuzz_options.o packetdrill-objs := packetdrill.o $(packetdrill-lib) diff --git a/gtests/net/packetdrill/fuzz_options.c b/gtests/net/packetdrill/fuzz_options.c new file mode 100644 index 00000000..bb74f151 --- /dev/null +++ b/gtests/net/packetdrill/fuzz_options.c @@ -0,0 +1,45 @@ +#include "fuzz_options.h" + +#include +#include + +struct fuzz_options* fuzz_options_new(void) { + struct fuzz_options *options = (struct fuzz_options *) malloc(sizeof(struct fuzz_options)); + + options->options = malloc(sizeof(struct fuzz_option)); + options->capacity = sizeof(struct fuzz_option); + + return options; +} + +void fuzz_options_grow(struct fuzz_options *fuzz_options, size_t capacity) { + if (capacity > fuzz_options->capacity) { + fuzz_options->options = realloc(fuzz_options->options, capacity); + fuzz_options->capacity = capacity; + } +} + +int fuzz_options_append(struct fuzz_options *fuzz_options, struct fuzz_option *option) { + size_t fuzz_option_size = sizeof(struct fuzz_option); + if (fuzz_option_size + fuzz_options->size > fuzz_options->capacity) { + fuzz_options_grow(fuzz_options, fuzz_options->capacity * 2); + } + + memcpy(fuzz_options->options + fuzz_options->size, option, fuzz_option_size); + fuzz_options->size += fuzz_option_size; + + free(option); + + return STATUS_OK; +} + +struct fuzz_option* fuzz_option_new(enum fuzz_type_t fuzz_type, enum header_type_t header_type, u8 fuzz_offset, u8 fuzz_length) { + struct fuzz_option *option = calloc(1, sizeof(struct fuzz_option)); + + option->fuzz_type = fuzz_type; + option->header_type = header_type; + option->fuzz_offset = fuzz_offset; + option->fuzz_length = fuzz_length; + + return option; +} \ No newline at end of file diff --git a/gtests/net/packetdrill/fuzz_options.h b/gtests/net/packetdrill/fuzz_options.h new file mode 100644 index 00000000..cfe9457e --- /dev/null +++ b/gtests/net/packetdrill/fuzz_options.h @@ -0,0 +1,46 @@ +#ifndef __FUZZ_OPTIONS_H__ +#define __FUZZ_OPTIONS_H__ + +#include "types.h" + +struct fuzz_options { + struct fuzz_option *options; // Pointer to first fuzz_option + u8 capacity; // Allocated space in the buffer + u8 size; // Size (in bytes) of items in the buffer +}; + + +enum fuzz_type_t { + OP_MUTATE = 0, + OP_TRUNCATE = 1, + OP_INSERT = 2 +}; + +struct fuzz_option { + enum fuzz_type_t fuzz_type; + u8 header_type; + u8 fuzz_offset; + u8 fuzz_length; +} __packed; + +struct fuzz_field { + u8 fuzz_offset; + u8 fuzz_length; +}; + + +enum header_type_t { + IPv4, + IPv6, + xTCP +}; + +extern struct fuzz_options* fuzz_options_new(void); + +extern void fuzz_options_grow(struct fuzz_options *fuzz_options, size_t capacity); + +extern int fuzz_options_append(struct fuzz_options *fuzz_options, struct fuzz_option *option); + +extern struct fuzz_option* fuzz_option_new(enum fuzz_type_t fuzz_type, enum header_type_t header_type, u8 fuzz_offset, u8 fuzz_length); + +#endif /* __FUZZ_OPTIONS_H__ */ \ No newline at end of file diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index ba2a90be..f7883b4d 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -51,6 +51,7 @@ #include "tcp_options.h" #include "parse.h" #include "config.h" +#include "fuzz_options.h" /* This include of the bison-generated .h file must go last so that we * can first include all of the declarations on which it depends. @@ -265,7 +266,6 @@ id return ID; mut return MUTATE; trun return TRUNCATE; ins return INSERT; -ip return IP; tcp return TCP; ihl return IHL; source_port return SOURCE_PORT; diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index 5165d7f8..56a4c896 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -103,6 +103,7 @@ #include "script.h" #include "tcp.h" #include "tcp_options.h" +#include "fuzz_options.h" /* This include of the bison-generated .h file must go last so that we * can first include all of the declarations on which it depends. @@ -523,6 +524,14 @@ static struct packet *append_gre(struct packet *packet, struct expression *expr) u16 src_port; u16 dst_port; } port_info; + struct { + u8 offset; + u8 length; + } fuzz_field_t; + struct fuzz_options *fuzz_options; + struct fuzz_option *fuzz_option; + enum fuzz_type_t fuzz_type; + enum header_type_t header_type; } /* The specific type of the output for a symbol is given by the %type @@ -583,10 +592,11 @@ static struct packet *append_gre(struct packet *packet, struct expression *expr) %type seq opt_icmp_echoed %type opt_tcp_options tcp_option_list %type tcp_option sack_block_list sack_block -%type opt_fuzz_info opt_fuzz_params -%type opt_fuzz_param -%type fuzz_type header_type fuzz_field field_name -%type field_pos field_offset +%type opt_fuzz_options fuzz_option_list +%type fuzz_option +%type fuzz_field field_name field_pos field_offset +%type fuzz_type +%type header_type %type function_name %type expression_list function_arguments %type expression binary_expression array sub_expr_list @@ -791,7 +801,7 @@ packet_spec ; tcp_packet_spec -: packet_prefix opt_ip_info opt_port_info flags seq opt_ack opt_window opt_urg_ptr opt_tcp_options opt_fuzz_info { +: packet_prefix opt_ip_info opt_port_info flags seq opt_ack opt_window opt_urg_ptr opt_tcp_options opt_fuzz_options { char *error = NULL; struct packet *outer = $1, *inner = NULL; enum direction_t direction = outer->direction; @@ -807,12 +817,15 @@ tcp_packet_spec "outbound packets"); } + //TODO: verify fuzz options is added to only incoming packets. + inner = new_tcp_packet(in_config->wire_protocol, direction, $2, $3.src_port, $3.dst_port, $4, $5.start_sequence, $5.payload_bytes, - $6, $7, $8, $9, &error); + $6, $7, $8, $9, $10, &error); free($4); free($9); + free($10); if (inner == NULL) { assert(error != NULL); semantic_error(error); @@ -1372,32 +1385,96 @@ sack_block } ; -opt_fuzz_info -: '{' opt_fuzz_params '}'; +opt_fuzz_options +: { $$ = fuzz_options_new(); } +| '{' fuzz_option_list '}' { $$ = $2; } +; -opt_fuzz_params -: opt_fuzz_param | opt_fuzz_params ';' opt_fuzz_param; +fuzz_option_list +: fuzz_option { + $$ = fuzz_options_new(); + if (fuzz_options_append($$, $1)) { + semantic_error("Error adding to fuzz option list."); + } +} +| fuzz_option_list ';' fuzz_option { + $$ = $1; + if (fuzz_options_append($$, $3)) { + semantic_error("Error adding to fuzz option list."); + } +} +; -opt_fuzz_param -: fuzz_type header_type fuzz_field; +fuzz_option +: fuzz_type header_type fuzz_field { + $$ = fuzz_option_new($1, $2, $3.offset, $3.length); +} +; fuzz_type -: MUTATE | TRUNCATE | INSERT; +: MUTATE { + $$ = OP_MUTATE; +} +| TRUNCATE { + $$ = OP_TRUNCATE; +} +| INSERT { + $$ = OP_INSERT; +} +; header_type -: IP | TCP; +: IPV4 { + $$ = IPv4; +} +| IPV6 { + $$ = IPv6; +} +| TCP { + $$ = xTCP; +} +; fuzz_field -: field_name | field_pos | field_offset; +: field_name { + $$ = $1; +} +| field_pos { + $$ = $1; +} +| field_offset { + $$ = $1; +} +; field_name -: MSS | IHL | SOURCE_PORT; +: MSS { + $$.offset = 25; + $$.length = 4; +} +| IHL { + $$.offset = 2; + $$.length = 1; +} +| SOURCE_PORT { + $$.offset = 20; + $$.length = 2; +} +; field_pos -: INTEGER '-' INTEGER; +: INTEGER '-' INTEGER { + $$.offset = $1; + $$.length = $3 - $1; +} +; field_offset -: INTEGER INTEGER; +: INTEGER INTEGER { + $$.offset = $1; + $$.length = $2; +} +; syscall_spec : opt_end_time function_name function_arguments '=' diff --git a/gtests/net/packetdrill/run_packet.c b/gtests/net/packetdrill/run_packet.c index 436126bb..dc1b27dd 100644 --- a/gtests/net/packetdrill/run_packet.c +++ b/gtests/net/packetdrill/run_packet.c @@ -1919,7 +1919,7 @@ int reset_connection(struct state *state, struct socket *socket) packet = new_tcp_packet(socket->address_family, DIRECTION_INBOUND, ip_info, 0, 0, - "R.", seq, 0, ack_seq, window, 0, NULL, + "R.", seq, 0, ack_seq, window, 0, NULL, NULL, &error); if (packet == NULL) die("%s", error); diff --git a/gtests/net/packetdrill/tcp_packet.c b/gtests/net/packetdrill/tcp_packet.c index d1ef65b5..f6b7a422 100644 --- a/gtests/net/packetdrill/tcp_packet.c +++ b/gtests/net/packetdrill/tcp_packet.c @@ -100,6 +100,7 @@ struct packet *new_tcp_packet(int address_family, s32 window, u16 urg_ptr, const struct tcp_options *tcp_options, + const struct fuzz_options *fuzz_options, char **error) { struct packet *packet = NULL; /* the newly-allocated result packet */ diff --git a/gtests/net/packetdrill/tcp_packet.h b/gtests/net/packetdrill/tcp_packet.h index 6e2a6b08..4fa41466 100644 --- a/gtests/net/packetdrill/tcp_packet.h +++ b/gtests/net/packetdrill/tcp_packet.h @@ -29,6 +29,7 @@ #include "packet.h" #include "tcp_options.h" +#include "fuzz_options.h" /* Create and initialize a new struct packet containing a TCP segment. * The 'flags' are a tcpdump-style sequence of TCP header flags. @@ -47,5 +48,6 @@ extern struct packet *new_tcp_packet(int address_family, s32 window, u16 urg_ptr, const struct tcp_options *tcp_options, + const struct fuzz_options *fuzz_options, char **error); #endif /* __TCP_PACKET_H__ */ diff --git a/gtests/net/tcp/blocking/blocking-connect-fuzz-2.pkt b/gtests/net/tcp/blocking/blocking-connect-fuzz-2.pkt new file mode 100644 index 00000000..3bf734fa --- /dev/null +++ b/gtests/net/tcp/blocking/blocking-connect-fuzz-2.pkt @@ -0,0 +1,12 @@ +// Test for blocking connect. + +//`../common/defaults.sh` + +// Establish a connection. + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 + + +.1...0.200 connect(3, ..., ...) = 0 + + +0 > S 0:0(0) { mut ipv4 ihl; mut tcp mss; trun tcp source_port; trun tcp 34-36; mut ipv4 12-15; ins ipv4 34 2 } + +.1 < S. 0:0(0) ack 1 win 5792 + +0 > . 1:1(0) ack 1 diff --git a/gtests/net/tcp/blocking/blocking-connect-fuzz.pkt b/gtests/net/tcp/blocking/blocking-connect-fuzz.pkt new file mode 100644 index 00000000..cbe687fe --- /dev/null +++ b/gtests/net/tcp/blocking/blocking-connect-fuzz.pkt @@ -0,0 +1,12 @@ +// Test for blocking connect. + +//`../common/defaults.sh` + +// Establish a connection. + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 + + +.1...0.200 connect(3, ..., ...) = 0 + + +0 > S 0:0(0) { mut tcp mss } + +.1 < S. 0:0(0) ack 1 win 5792 + +0 > . 1:1(0) ack 1 diff --git a/gtests/net/tcp/blocking/blocking-read-2.pkt b/gtests/net/tcp/blocking/blocking-read-2.pkt new file mode 100644 index 00000000..42cea3e8 --- /dev/null +++ b/gtests/net/tcp/blocking/blocking-read-2.pkt @@ -0,0 +1,28 @@ +// Test for blocking read. +//--tolerance_usecs=10000 + +//`../common/defaults.sh` + +// Establish a connection. + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 + +0 bind(3, ..., ...) = 0 + +0 listen(3, 1) = 0 + + +.1 < S 0:0(0) win 32792 + +0 > S. 0:0(0) ack 1 + +.1 < . 1:1(0) ack 1 win 257 + +0 accept(3, ..., ...) = 4 + + +0...0.100 read(4, ..., 2000) = 2000 + +.1 < P. 1:2001(2000) ack 1 win 257 + +0 > . 1:1(0) ack 2001 + + +.1...0.200 read(4, ..., 2000) = 2000 + +.1 < P. 2001:4001(2000) ack 1 win 257 + +0 > . 1:1(0) ack 4001 + +// +.1 < P. 4001:6001(2000) ack 1 win 257 +// +0 > . 1:1(0) ack 6001 +// +0...0.000 read(4, ..., 1000) = 1000 +// +0...0.000 read(4, ..., 1000) = 1000 From a0af9f3bd244ddb09cb07835d158db08a3292ec9 Mon Sep 17 00:00:00 2001 From: AmPaschal Date: Sun, 2 Oct 2022 00:32:14 +0000 Subject: [PATCH 05/17] Integrated support for external fuzz mutation file --- gtests/net/packetdrill/Makefile.common | 2 +- gtests/net/packetdrill/config.c | 7 ++++ gtests/net/packetdrill/config.h | 3 ++ gtests/net/packetdrill/fm_testing.c | 48 ++++++++++++++++++++++++++ gtests/net/packetdrill/fm_testing.h | 39 +++++++++++++++++++++ gtests/net/packetdrill/fuzz_options.c | 2 ++ gtests/net/packetdrill/fuzz_options.h | 1 + gtests/net/packetdrill/packet.h | 3 ++ gtests/net/packetdrill/run.c | 9 +++++ gtests/net/packetdrill/run.h | 1 + gtests/net/packetdrill/tcp_packet.c | 2 ++ 11 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 gtests/net/packetdrill/fm_testing.c create mode 100644 gtests/net/packetdrill/fm_testing.h diff --git a/gtests/net/packetdrill/Makefile.common b/gtests/net/packetdrill/Makefile.common index e81f3359..13baa815 100644 --- a/gtests/net/packetdrill/Makefile.common +++ b/gtests/net/packetdrill/Makefile.common @@ -29,7 +29,7 @@ packetdrill-lib := \ link_layer.o wire_conn.o wire_protocol.o \ wire_client.o wire_client_netdev.o \ wire_server.o wire_server_netdev.o \ - epoll.o pipe.o file.o so_testing.o wrap.o fuzz_options.o + epoll.o pipe.o file.o so_testing.o wrap.o fuzz_options.o fm_testing.o packetdrill-objs := packetdrill.o $(packetdrill-lib) diff --git a/gtests/net/packetdrill/config.c b/gtests/net/packetdrill/config.c index 37e2eb08..ca78ab23 100644 --- a/gtests/net/packetdrill/config.c +++ b/gtests/net/packetdrill/config.c @@ -65,6 +65,7 @@ enum option_codes { OPT_DRY_RUN, OPT_IS_ANYIP, OPT_SEND_OMIT_FREE, + OPT_FM_FILENAME, OPT_DEFINE = 'D', /* a '-D' single-letter option */ OPT_VERBOSE = 'v', /* a '-v' single-letter option */ }; @@ -103,6 +104,7 @@ struct option options[] = { { "send_omit_free", .has_arg = false, NULL, OPT_SEND_OMIT_FREE }, { "define", .has_arg = true, NULL, OPT_DEFINE }, { "verbose", .has_arg = false, NULL, OPT_VERBOSE }, + { "fm_filename", .has_arg = true, NULL, OPT_FM_FILENAME}, { NULL }, }; @@ -513,6 +515,11 @@ static void process_option(int opt, char *optarg, struct config *config, case OPT_VERBOSE: config->verbose = true; break; + + case OPT_FM_FILENAME: + config->fm_filename = strdup(optarg); + break; + default: show_usage(); exit(EXIT_FAILURE); diff --git a/gtests/net/packetdrill/config.h b/gtests/net/packetdrill/config.h index 649a8c4f..b498343c 100644 --- a/gtests/net/packetdrill/config.h +++ b/gtests/net/packetdrill/config.h @@ -159,6 +159,9 @@ struct config { char *so_filename; char *so_flags; + /* Fuzz mutation file for fuzzing, using an external mutation file */ + char *fm_filename; + /* For anyip testing */ bool is_anyip; diff --git a/gtests/net/packetdrill/fm_testing.c b/gtests/net/packetdrill/fm_testing.c new file mode 100644 index 00000000..02d25e34 --- /dev/null +++ b/gtests/net/packetdrill/fm_testing.c @@ -0,0 +1,48 @@ +/* + * Author: pamusuo@purdue.edu (Paschal Amusuo) + * + * Testing using mutated packets + */ + +#include "fm_testing.h" +#include + +struct config; + +struct fm_instance *fm_instance_new(void) { + return calloc(1, sizeof(struct fm_instance)); +} + +int fm_instance_init(struct fm_instance *instance, + const struct config *config) { + fm_interface_init_t init; + char *error; + + instance->handle = dlopen(config->fm_filename, + RTLD_NOW | RTLD_LOCAL | RTLD_NODELETE | + RTLD_DEEPBIND); + if (!instance->handle) + die("%s\n", dlerror()); + dlerror(); /* clear any existing error */ + + init = dlsym(instance->handle, "fm_interface_init"); + error = dlerror(); + if (error) + die("%s\n", error); + + init(&instance->fm_interface); + return STATUS_OK; +} + +void fm_instance_free(struct fm_instance *instance) { + if (!instance) + return; + + instance->fm_interface.free(); + + if (instance->handle) + dlclose(instance->handle); + + memset(instance, 0, sizeof(*instance)); + free(instance); +} diff --git a/gtests/net/packetdrill/fm_testing.h b/gtests/net/packetdrill/fm_testing.h new file mode 100644 index 00000000..b66bab43 --- /dev/null +++ b/gtests/net/packetdrill/fm_testing.h @@ -0,0 +1,39 @@ + +/* + * Author: pamusuo@purdue.edu (Paschal Amusuo) + * + * Testing using mutated packets + */ + +#ifndef __FM_TESTING_H__ +#define __FM_TESTING_H__ + +#include "packet.h" +#include "config.h" + +struct config; + +struct fm_interface { + struct packet (*mutate)(struct packet *original); + void (*free)(); +}; + +typedef void (*fm_interface_init_t)(struct fm_interface *); + +struct fm_instance { + struct fm_interface fm_interface; + void *handle; +}; + + +/* Allocate a new fm_instance. */ +struct fm_instance *fm_instance_new(void); + +/* Load the fuzz mutation shared object and setup callback functions. */ +int fm_instance_init(struct fm_instance *instance, + const struct config *config); + +/* Delete a so_instance and its associated objects. */ +void fm_instance_free(struct fm_instance *instance); + +#endif /* __FM_TESTING_H__ */ diff --git a/gtests/net/packetdrill/fuzz_options.c b/gtests/net/packetdrill/fuzz_options.c index bb74f151..970a0fb4 100644 --- a/gtests/net/packetdrill/fuzz_options.c +++ b/gtests/net/packetdrill/fuzz_options.c @@ -8,6 +8,7 @@ struct fuzz_options* fuzz_options_new(void) { options->options = malloc(sizeof(struct fuzz_option)); options->capacity = sizeof(struct fuzz_option); + options->count = 0; return options; } @@ -27,6 +28,7 @@ int fuzz_options_append(struct fuzz_options *fuzz_options, struct fuzz_option *o memcpy(fuzz_options->options + fuzz_options->size, option, fuzz_option_size); fuzz_options->size += fuzz_option_size; + fuzz_options->count += 1; free(option); diff --git a/gtests/net/packetdrill/fuzz_options.h b/gtests/net/packetdrill/fuzz_options.h index cfe9457e..2dd823bd 100644 --- a/gtests/net/packetdrill/fuzz_options.h +++ b/gtests/net/packetdrill/fuzz_options.h @@ -7,6 +7,7 @@ struct fuzz_options { struct fuzz_option *options; // Pointer to first fuzz_option u8 capacity; // Allocated space in the buffer u8 size; // Size (in bytes) of items in the buffer + u8 count; // Count of fuzz instructions in the buffer }; diff --git a/gtests/net/packetdrill/packet.h b/gtests/net/packetdrill/packet.h index bd484b87..5e7d1253 100644 --- a/gtests/net/packetdrill/packet.h +++ b/gtests/net/packetdrill/packet.h @@ -39,6 +39,7 @@ #include "tcp.h" #include "udp.h" #include "unaligned.h" +#include "fuzz_options.h" /* The data offset field is 4 bits, and specifies the length of the TCP header, * including options, in 32-bit words. @@ -111,6 +112,8 @@ struct packet { __be32 *tcp_ts_val; /* location of TCP timestamp val, or NULL */ __be32 *tcp_ts_ecr; /* location of TCP timestamp ecr, or NULL */ int mss; + + struct fuzz_options fuzz_options; /* specifies fuzz instructions that should be executed on this packet */ }; /* A simple list of packets. */ diff --git a/gtests/net/packetdrill/run.c b/gtests/net/packetdrill/run.c index f3a4cc0f..ddbd3b0f 100644 --- a/gtests/net/packetdrill/run.c +++ b/gtests/net/packetdrill/run.c @@ -49,6 +49,7 @@ #include "system.h" #include "tcp.h" #include "tcp_options.h" +#include "fm_testing.h" /* MAX_SPIN_USECS is the maximum amount of time (in microseconds) to * spin waiting for an event. We sleep up until this many microseconds @@ -142,6 +143,9 @@ void state_free(struct state *state) if (state->so_instance) so_instance_free(state->so_instance); + if (state->fm_instance) + fm_instance_free(state->fm_instance); + run_unlock(state); if (pthread_mutex_destroy(&state->mutex) != 0) die_perror("pthread_mutex_destroy"); @@ -583,6 +587,11 @@ void run_script(struct config *config, struct script *script) so_instance_init(state->so_instance, config, script, state); } + if (config->fm_filename) { + state->fm_instance = fm_instance_new(); + fm_instance_init(state->fm_instance, config); + } + init_cmd_exed = false; if (script->init_command != NULL) { if (safe_system(script->init_command->command_line, diff --git a/gtests/net/packetdrill/run.h b/gtests/net/packetdrill/run.h index da564547..4bb7b569 100644 --- a/gtests/net/packetdrill/run.h +++ b/gtests/net/packetdrill/run.h @@ -102,6 +102,7 @@ struct state { struct code_state *code; /* for running post-processing code */ struct wire_client *wire_client; /* for on-the-wire tests */ struct so_instance *so_instance; /* for SO testing */ + struct fm_instance *fm_instance; /* for fuzz mutations */ s64 script_start_time_usecs; /* time of first event in script */ s64 script_last_time_usecs; /* time of previous event in script */ s64 live_start_time_usecs; /* time of first event in live test */ diff --git a/gtests/net/packetdrill/tcp_packet.c b/gtests/net/packetdrill/tcp_packet.c index f6b7a422..f34f8484 100644 --- a/gtests/net/packetdrill/tcp_packet.c +++ b/gtests/net/packetdrill/tcp_packet.c @@ -218,5 +218,7 @@ struct packet *new_tcp_packet(int address_family, } packet->ip_bytes = ip_bytes; + + packet->fuzz_options = *fuzz_options; return packet; } From 69fdc5885f81fb919cf18b0a84d9eda880f90adc Mon Sep 17 00:00:00 2001 From: AmPaschal Date: Wed, 5 Oct 2022 14:00:08 +0000 Subject: [PATCH 06/17] Invokes mutation file for packets to fuzz --- gtests/net/packetdrill/fm_testing.c | 46 +++++++++++++++++++++++++++++ gtests/net/packetdrill/fm_testing.h | 8 ++++- gtests/net/packetdrill/packet.h | 2 +- gtests/net/packetdrill/run_packet.c | 15 ++++++++-- gtests/net/packetdrill/tcp_packet.c | 6 +++- 5 files changed, 71 insertions(+), 6 deletions(-) diff --git a/gtests/net/packetdrill/fm_testing.c b/gtests/net/packetdrill/fm_testing.c index 02d25e34..3ebacf71 100644 --- a/gtests/net/packetdrill/fm_testing.c +++ b/gtests/net/packetdrill/fm_testing.c @@ -9,6 +9,52 @@ struct config; +struct fm_packet { + u8 *buffer; /* data buffer: full contents of packet */ + u32 buffer_bytes; /* bytes of space in data buffer */ + + /* Layer 3 */ + u8 *ipv4; /* start of IPv4 header, if present */ + u8 *ipv6; /* start of IPv6 header, if present */ + + /* Layer 4 */ + u8 *tcp; /* start of TCP header, if present */ + u8 *udp; /* start of UDP header, if present */ + u8 *icmpv4; /* start of ICMPv4 header, if present */ + u8 *icmpv6; /* start of ICMPv6 header, if present */ +}; + +struct packet *handle_packet_mutation(struct packet *packet, struct fm_instance *fm_instance) { + + printf("ip_bytes: %d\n", packet->ip_bytes); + printf("buffer_bytes: %d\n", packet->buffer_bytes); + + struct fm_packet fm_packet = { + .buffer = (u8 *) packet->buffer, + .buffer_bytes = packet->ip_bytes, + .icmpv4 = (u8 *) packet->icmpv4, + .icmpv6 = (u8 *) packet->icmpv6, + .ipv4 = (u8 *) packet->ipv4, + .ipv6 = (u8 *) packet->ipv6, + .tcp = (u8 *) packet->tcp, + .udp = (u8 *) packet->udp + }; + + struct fm_packet *mutated_fm_packet = fm_instance->fm_interface.mutate(&fm_packet, packet->fuzz_options); + + packet->buffer = mutated_fm_packet->buffer; + packet->ip_bytes = mutated_fm_packet->buffer_bytes; + packet->icmpv4 = (struct icmpv4 *) mutated_fm_packet->icmpv4; + packet->icmpv6 = (struct icmpv6 *) mutated_fm_packet->icmpv6; + packet->ipv4 = (struct ipv4 *) mutated_fm_packet->ipv4; + packet->ipv6 = (struct ipv6 *) mutated_fm_packet->ipv6; + packet->tcp = (struct tcp *) mutated_fm_packet->tcp; + packet->udp = (struct udp *) mutated_fm_packet->udp; + + return packet; + +} + struct fm_instance *fm_instance_new(void) { return calloc(1, sizeof(struct fm_instance)); } diff --git a/gtests/net/packetdrill/fm_testing.h b/gtests/net/packetdrill/fm_testing.h index b66bab43..a80ed3bb 100644 --- a/gtests/net/packetdrill/fm_testing.h +++ b/gtests/net/packetdrill/fm_testing.h @@ -8,13 +8,15 @@ #ifndef __FM_TESTING_H__ #define __FM_TESTING_H__ +#include "fm_testing.h" #include "packet.h" #include "config.h" struct config; +struct fm_packet; struct fm_interface { - struct packet (*mutate)(struct packet *original); + struct fm_packet *(*mutate)(struct fm_packet *original, struct fuzz_options *fuzz_options); void (*free)(); }; @@ -26,6 +28,10 @@ struct fm_instance { }; +/* Invoke mutate method of fm_interface */ +struct packet *handle_packet_mutation(struct packet *packet, struct fm_instance *fm_instance); + + /* Allocate a new fm_instance. */ struct fm_instance *fm_instance_new(void); diff --git a/gtests/net/packetdrill/packet.h b/gtests/net/packetdrill/packet.h index 5e7d1253..1e173fd9 100644 --- a/gtests/net/packetdrill/packet.h +++ b/gtests/net/packetdrill/packet.h @@ -113,7 +113,7 @@ struct packet { __be32 *tcp_ts_ecr; /* location of TCP timestamp ecr, or NULL */ int mss; - struct fuzz_options fuzz_options; /* specifies fuzz instructions that should be executed on this packet */ + struct fuzz_options *fuzz_options; /* specifies fuzz instructions that should be executed on this packet */ }; /* A simple list of packets. */ diff --git a/gtests/net/packetdrill/run_packet.c b/gtests/net/packetdrill/run_packet.c index dc1b27dd..36f44790 100644 --- a/gtests/net/packetdrill/run_packet.c +++ b/gtests/net/packetdrill/run_packet.c @@ -45,6 +45,7 @@ #include "tcp_options_to_string.h" #include "tcp_packet.h" #include "wrap.h" +#include "fm_testing.h" /* To avoid issues with TIME_WAIT, FIN_WAIT1, and FIN_WAIT2 we use * dynamically-chosen, unique 4-tuples for each test. We implement the @@ -1749,15 +1750,23 @@ static int do_outbound_script_packet( } /* Checksum the packet and inject it into the kernel under test. */ -static int send_live_ip_packet(struct netdev *netdev, +static int send_live_ip_packet(struct state *state, struct packet *packet) { + + struct netdev *netdev = state->netdev; + assert(packet->ip_bytes > 0); /* We do IPv4 and IPv6 */ assert(packet->ipv4 || packet->ipv6); /* We only do TCP, UDP, and ICMP */ assert(packet->tcp || packet->udp || packet->icmpv4 || packet->icmpv6); + /* Mutate packet if enabled */ + if (state->fm_instance) { + packet = handle_packet_mutation(packet, state->fm_instance); + } + /* Fill in layer 3 and layer 4 checksums */ checksum_packet(packet); @@ -1817,7 +1826,7 @@ static int do_inbound_script_packet( } /* Inject live packet into kernel. */ - result = send_live_ip_packet(state->netdev, live_packet); + result = send_live_ip_packet(state, live_packet); out: packet_free(live_packet); @@ -1929,7 +1938,7 @@ int reset_connection(struct state *state, struct socket *socket) set_packet_tuple(packet, &live_inbound); /* Inject live packet into kernel. */ - result = send_live_ip_packet(state->netdev, packet); + result = send_live_ip_packet(state, packet); packet_free(packet); diff --git a/gtests/net/packetdrill/tcp_packet.c b/gtests/net/packetdrill/tcp_packet.c index f34f8484..f22488c5 100644 --- a/gtests/net/packetdrill/tcp_packet.c +++ b/gtests/net/packetdrill/tcp_packet.c @@ -219,6 +219,10 @@ struct packet *new_tcp_packet(int address_family, packet->ip_bytes = ip_bytes; - packet->fuzz_options = *fuzz_options; + if (fuzz_options != NULL) { + packet->fuzz_options = malloc(fuzz_options->size); + memcpy(packet->fuzz_options, fuzz_options, fuzz_options->size); + } + return packet; } From 68e059c872238ebf211aa924a7b5c59a1649cd8b Mon Sep 17 00:00:00 2001 From: AmPaschal Date: Thu, 13 Oct 2022 03:52:57 +0000 Subject: [PATCH 07/17] Let so_instance manage closing of socket it creates --- gtests/net/packetdrill/fd_state.h | 1 + gtests/net/packetdrill/run_system_call.c | 3 +++ gtests/net/packetdrill/socket.c | 3 ++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/gtests/net/packetdrill/fd_state.h b/gtests/net/packetdrill/fd_state.h index f08a5591..d206734b 100644 --- a/gtests/net/packetdrill/fd_state.h +++ b/gtests/net/packetdrill/fd_state.h @@ -52,6 +52,7 @@ struct fd_state { int script_fd; /* file descriptor in the script source */ int live_fd; /* file descriptor in packetdrill runtime */ bool is_closed; /* has app called close(2) ? */ + bool so_managed; /* so_instance was used to create this syscall. Should be in charge of closing it */ struct fd_state *next; /* next fd in linked list */ }; diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c index a520388e..b4dff606 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -1355,6 +1355,7 @@ static int run_syscall_socket(struct state *state, int address_family, int type, socket->protocol = protocol; socket->fd.script_fd = script_fd; socket->fd.live_fd = live_fd; + socket->fd.so_managed = state->so_instance != NULL; /* Any later packets in the test script will now be mapped here. */ state->socket_under_test = socket; @@ -1472,6 +1473,8 @@ static int run_syscall_accept(struct state *state, htons(port))); socket->fd.script_fd = script_accepted_fd; socket->fd.live_fd = live_accepted_fd; + socket->fd.so_managed = state->so_instance != NULL; + return STATUS_OK; } } diff --git a/gtests/net/packetdrill/socket.c b/gtests/net/packetdrill/socket.c index c661c5af..c83d9462 100644 --- a/gtests/net/packetdrill/socket.c +++ b/gtests/net/packetdrill/socket.c @@ -32,7 +32,8 @@ void socket_close(struct state *state, struct fd_state *fd) { struct socket *socket = fd_to_socket(fd); - if (fd->live_fd >= 0 && !socket->fd.is_closed) { + if (fd->live_fd >= 0 && !socket->fd.is_closed && !fd->so_managed) { + /* Let the so_instance be in charge of closing sockets it created as these sockets may not have been on linux */ assert(fd->script_fd >= 0); DEBUGP("closing struct state socket " "live.fd:%d script.fd:%d\n", From c8c894c2a4998c3a0433a4c17830cc847e6369d8 Mon Sep 17 00:00:00 2001 From: AmPaschal Date: Wed, 21 Dec 2022 03:20:25 +0000 Subject: [PATCH 08/17] Extended Packetdrill's grammar to support fuzz instructions --- gtests/net/packetdrill/Makefile.common | 2 +- gtests/net/packetdrill/fuzz_options.c | 8 +- gtests/net/packetdrill/fuzz_options.h | 53 ++++-- gtests/net/packetdrill/ip_address.h | 17 ++ gtests/net/packetdrill/lexer.l | 22 ++- gtests/net/packetdrill/packet.c | 1 + gtests/net/packetdrill/parser.y | 155 ++++++++++++++---- gtests/net/packetdrill/run_system_call.c | 2 +- .../blocking-accept-fuzz-template.pkt | 18 ++ .../net/tcp/blocking/blocking-accept-fuzz.pkt | 13 ++ .../tcp/blocking/blocking-connect-data.pkt | 24 +++ 11 files changed, 260 insertions(+), 55 deletions(-) create mode 100644 gtests/net/tcp/blocking/blocking-accept-fuzz-template.pkt create mode 100644 gtests/net/tcp/blocking/blocking-accept-fuzz.pkt create mode 100644 gtests/net/tcp/blocking/blocking-connect-data.pkt diff --git a/gtests/net/packetdrill/Makefile.common b/gtests/net/packetdrill/Makefile.common index 13baa815..e2b80a51 100644 --- a/gtests/net/packetdrill/Makefile.common +++ b/gtests/net/packetdrill/Makefile.common @@ -1,6 +1,6 @@ all: binaries -CFLAGS = -g -Wall -Werror +CFLAGS = -g -Wall -Werror -Wno-unused-result -Wno-stringop-truncation parser.o: parser.y bison --output=parser.c --defines=parser.h --report=state parser.y diff --git a/gtests/net/packetdrill/fuzz_options.c b/gtests/net/packetdrill/fuzz_options.c index 970a0fb4..d133dd3a 100644 --- a/gtests/net/packetdrill/fuzz_options.c +++ b/gtests/net/packetdrill/fuzz_options.c @@ -9,6 +9,7 @@ struct fuzz_options* fuzz_options_new(void) { options->options = malloc(sizeof(struct fuzz_option)); options->capacity = sizeof(struct fuzz_option); options->count = 0; + options->size = 0; return options; } @@ -35,13 +36,14 @@ int fuzz_options_append(struct fuzz_options *fuzz_options, struct fuzz_option *o return STATUS_OK; } -struct fuzz_option* fuzz_option_new(enum fuzz_type_t fuzz_type, enum header_type_t header_type, u8 fuzz_offset, u8 fuzz_length) { +struct fuzz_option* fuzz_option_new(enum fuzz_type_t fuzz_type, enum header_type_t header_type, u8 fuzz_field, struct fuzz_value_t fuzz_value) { struct fuzz_option *option = calloc(1, sizeof(struct fuzz_option)); option->fuzz_type = fuzz_type; option->header_type = header_type; - option->fuzz_offset = fuzz_offset; - option->fuzz_length = fuzz_length; + option->fuzz_field = fuzz_field; + option->fuzz_value = fuzz_value.value; + option->fuzz_value_byte_count = fuzz_value.byte_count; return option; } \ No newline at end of file diff --git a/gtests/net/packetdrill/fuzz_options.h b/gtests/net/packetdrill/fuzz_options.h index 2dd823bd..9c637799 100644 --- a/gtests/net/packetdrill/fuzz_options.h +++ b/gtests/net/packetdrill/fuzz_options.h @@ -12,36 +12,65 @@ struct fuzz_options { enum fuzz_type_t { - OP_MUTATE = 0, + OP_REPLACE = 0, OP_TRUNCATE = 1, OP_INSERT = 2 }; +enum field_name_t { + F_SOURCE_PORT = 0, + F_DST_PORT = 1, + F_SEQ_NUM = 2, + F_ACK_NUM = 3, + F_TCP_HDR_LEN = 4, + F_FLAGS = 5, + F_WIN_SIZE = 6, + F_TCP_CHECKSUM = 7, + F_URG_POINTER = 8, + F_VERSION_IHL = 9, + F_DSCP_ESN = 10, + F_TOT_LEN = 11, + F_IDEN = 12, + F_FLAGS_FLAGOFF = 13, + F_TTL = 14, + F_PROTOCOL = 15, + F_IP_CHECKSUM = 16, + F_SRC_IP = 17, + F_DEST_IP = 18 +}; + + + +enum header_type_t { + IPv4 = 0, + IPv6 = 1, + xTCP = 2 +}; + struct fuzz_option { enum fuzz_type_t fuzz_type; - u8 header_type; - u8 fuzz_offset; - u8 fuzz_length; + enum header_type_t header_type; + u8 fuzz_field; + char *fuzz_value; + u8 fuzz_value_byte_count; } __packed; +struct fuzz_value_t { + char *value; + u8 byte_count; +}; + struct fuzz_field { u8 fuzz_offset; u8 fuzz_length; }; - -enum header_type_t { - IPv4, - IPv6, - xTCP -}; - extern struct fuzz_options* fuzz_options_new(void); extern void fuzz_options_grow(struct fuzz_options *fuzz_options, size_t capacity); extern int fuzz_options_append(struct fuzz_options *fuzz_options, struct fuzz_option *option); -extern struct fuzz_option* fuzz_option_new(enum fuzz_type_t fuzz_type, enum header_type_t header_type, u8 fuzz_offset, u8 fuzz_length); +extern struct fuzz_option* fuzz_option_new(enum fuzz_type_t fuzz_type, enum header_type_t header_type, u8 fuzz_field, struct fuzz_value_t fuzz_value); #endif /* __FUZZ_OPTIONS_H__ */ \ No newline at end of file diff --git a/gtests/net/packetdrill/ip_address.h b/gtests/net/packetdrill/ip_address.h index 6ee586ba..15fb085c 100644 --- a/gtests/net/packetdrill/ip_address.h +++ b/gtests/net/packetdrill/ip_address.h @@ -60,10 +60,27 @@ extern int ip_address_length(int address_family); /* Return the number of bytes in sockaddr of the given family. */ extern int sockaddr_length(int address_family); +static void print_hex( char * bin_data, size_t len) + +{ + size_t i; + + for( i = 0; i < len; ++i ) + { + printf( "%.2X ", bin_data[ i ] ); + } + + printf( "\n" ); +} + /* Return true iff the two addresses are the same. */ static inline bool is_equal_ip(const struct ip_address *a, const struct ip_address *b) { + printf("Original ip address\n"); + print_hex((char *) &a->ip.v4.s_addr, ip_address_length(a->address_family)); + printf("Returned ip address\n"); + print_hex((char *) &b->ip.v4.s_addr, ip_address_length(b->address_family)); return ((a->address_family == b->address_family) && !memcmp(&a->ip, &b->ip, ip_address_length(a->address_family))); } diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index f7883b4d..5139943b 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -263,12 +263,30 @@ ect1 return ECT1; noecn return NO_ECN; ce return CE; id return ID; -mut return MUTATE; +rep return REPLACE; trun return TRUNCATE; ins return INSERT; tcp return TCP; ihl return IHL; -source_port return SOURCE_PORT; +src_port return SOURCE_PORT; +dst_port return DST_PORT; +seq_num return SEQ_NUM; +ack_num return ACK_NUM; +tcp_hdr_len return TCP_HDR_LEN; +win_size return WIN_SIZE; +tcp_checksum return TCP_CHECKSUM; +urg_pointer return URG_POINTER; +version_ihl return VERSION_IHL; +dscp_esn return DSCP_ESN; +tot_len return TOT_LEN; +iden return IDEN; +flags_fragoff return FLAGS_FLAGOFF; +protocol return PROTOCOL; +ip_checksum return IP4_CHECKSUM; +src_ip return SRC_IP; +dest_ip return DEST_IP; + + [.][.][.] return ELLIPSIS; --[a-zA-Z0-9_]+ yylval.string = option(yytext); return OPTION; diff --git a/gtests/net/packetdrill/packet.c b/gtests/net/packetdrill/packet.c index d2d792a2..2377f248 100644 --- a/gtests/net/packetdrill/packet.c +++ b/gtests/net/packetdrill/packet.c @@ -179,6 +179,7 @@ static void packet_duplicate_info(struct packet *packet, packet->tcp_ts_ecr = offset_ptr(old_base, new_base, old_packet->tcp_ts_ecr); packet->echoed_header = old_packet->echoed_header; + packet->fuzz_options = old_packet->fuzz_options; } /* Make a copy of the given old packet, but in the new copy reserve the diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index 56a4c896..8c23d0d5 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -440,6 +440,35 @@ static struct tcp_option *new_tcp_fast_open_option(const char *cookie_string, return option; } +static struct fuzz_value_t* parse_hex_blob(const char *hex_blob, + char **error) +{ + int hex_blob_len = strlen(hex_blob); + int hex_bytes = hex_blob_len / 2; + int parsed_bytes = 0; + + char *parsed_hex_blob = malloc(hex_bytes); + + /* Parse MD5 digest. This should be an ASCII hex string representing 16 + * bytes. But we allow smaller buffers, since we want to allow test + * cases that supply invalid cookies. + */ + if (parse_hex_string(hex_blob, + (u8 *) parsed_hex_blob, + hex_bytes, + &parsed_bytes)) { + free(parsed_hex_blob); + asprintf(error, "Hex blob is not a valid hex string"); + return NULL; + } + + struct fuzz_value_t *value = malloc(sizeof(struct fuzz_value_t)); + value->value = parsed_hex_blob; + value->byte_count = parsed_bytes; + + return value; +} + static struct tcp_option *new_md5_option(const char *digest_string, char **error) { @@ -524,14 +553,12 @@ static struct packet *append_gre(struct packet *packet, struct expression *expr) u16 src_port; u16 dst_port; } port_info; - struct { - u8 offset; - u8 length; - } fuzz_field_t; + struct fuzz_value_t fuzz_value_t; struct fuzz_options *fuzz_options; struct fuzz_option *fuzz_option; enum fuzz_type_t fuzz_type; enum header_type_t header_type; + enum field_name_t field_name; } /* The specific type of the output for a symbol is given by the %type @@ -555,9 +582,10 @@ static struct packet *append_gre(struct packet *packet, struct expression *expr) %token NONE CHECKSUM SEQUENCE PRESENT %token EE_ERRNO EE_CODE EE_DATA EE_INFO EE_ORIGIN EE_TYPE %token SCM_SEC SCM_NSEC -%token MUTATE TRUNCATE INSERT +%token REPLACE TRUNCATE INSERT %token IP TCP -%token IHL SOURCE_PORT +%token IHL SOURCE_PORT DST_PORT SEQ_NUM ACK_NUM TCP_HDR_LEN WIN_SIZE URG_POINTER VERSION_IHL; +%token TCP_CHECKSUM DSCP_ESN TOT_LEN IDEN FLAGS_FLAGOFF PROTOCOL IP4_CHECKSUM SRC_IP DEST_IP; %token FLOAT %token INTEGER HEX_INTEGER %token WORD STRING BACK_QUOTED CODE IPV4_ADDR IPV6_ADDR @@ -580,7 +608,8 @@ static struct packet *append_gre(struct packet *packet, struct expression *expr) %type gre_flags_list gre_flags gre_flag %type gre_sum gre_off gre_key gre_seq %type opt_icmp_echo_id -%type flow_label +%type flow_label +%type fuzz_field field_offset %type icmp_type opt_icmp_code opt_ack_flag opt_word ack_and_ace flags %type opt_tcp_fast_open_cookie hex_blob %type opt_note note word_list @@ -594,10 +623,11 @@ static struct packet *append_gre(struct packet *packet, struct expression *expr) %type tcp_option sack_block_list sack_block %type opt_fuzz_options fuzz_option_list %type fuzz_option -%type fuzz_field field_name field_pos field_offset %type fuzz_type %type header_type -%type function_name +%type field_name +%type function_name +%type fuzz_value %type expression_list function_arguments %type expression binary_expression array sub_expr_list %type any_int decimal_integer hex_integer @@ -1386,7 +1416,7 @@ sack_block ; opt_fuzz_options -: { $$ = fuzz_options_new(); } +: { $$ = NULL; } | '{' fuzz_option_list '}' { $$ = $2; } ; @@ -1406,14 +1436,14 @@ fuzz_option_list ; fuzz_option -: fuzz_type header_type fuzz_field { - $$ = fuzz_option_new($1, $2, $3.offset, $3.length); +: fuzz_type header_type fuzz_field fuzz_value { + $$ = fuzz_option_new($1, $2, $3, $4); } ; fuzz_type -: MUTATE { - $$ = OP_MUTATE; +: REPLACE { + $$ = OP_REPLACE; } | TRUNCATE { $$ = OP_TRUNCATE; @@ -1435,44 +1465,97 @@ header_type } ; -fuzz_field +fuzz_field : field_name { $$ = $1; } -| field_pos { - $$ = $1; -} | field_offset { $$ = $1; } -; field_name -: MSS { - $$.offset = 25; - $$.length = 4; +: SOURCE_PORT { + $$ = F_SOURCE_PORT; +} +| DST_PORT { + $$ = F_DST_PORT; +} +| SEQ_NUM { + $$ = F_SEQ_NUM; +} +| ACK_NUM { + $$ = F_ACK_NUM; } -| IHL { - $$.offset = 2; - $$.length = 1; +| TCP_HDR_LEN { + $$ = F_TCP_HDR_LEN; } -| SOURCE_PORT { - $$.offset = 20; - $$.length = 2; +| FLAGS { + $$ = F_FLAGS; +} +| WIN_SIZE { + $$ = F_WIN_SIZE; +} +| TCP_CHECKSUM { + $$ = F_TCP_CHECKSUM; +} +| URG_POINTER { + $$ = F_URG_POINTER; +} +| VERSION_IHL { + $$ = F_VERSION_IHL; +} +| DSCP_ESN { + $$ = F_DSCP_ESN; +} +| TOT_LEN { + $$ = F_TOT_LEN; +} +| IDEN { + $$ = F_IDEN; +} +| FLAGS_FLAGOFF { + $$ = F_FLAGS_FLAGOFF; +} +| TTL { + $$ = F_TTL; +} +| PROTOCOL { + $$ = F_PROTOCOL; +} +| IP4_CHECKSUM { + $$ = F_IP_CHECKSUM; +} +| SRC_IP { + $$ = F_SRC_IP; +} +| DEST_IP { + $$ = F_DEST_IP; } ; -field_pos -: INTEGER '-' INTEGER { - $$.offset = $1; - $$.length = $3 - $1; +field_offset +: INTEGER { + char *field_offset = strdup(yytext); + $$ = atoi(field_offset); } ; -field_offset -: INTEGER INTEGER { - $$.offset = $1; - $$.length = $2; +fuzz_value +: INTEGER { + struct fuzz_value_t value = {strdup(yytext), 0}; + $$ = value; +} +| HEX_INTEGER { + char *error = NULL; + char *hex_string = strdup(yytext); + hex_string += 2; /* We remove the '0x' at the start of the hex */ + struct fuzz_value_t *value = parse_hex_blob(hex_string, &error); + if (value == NULL) { + assert(error != NULL); + semantic_error(error); + free(error); + } + $$ = *value; } ; diff --git a/gtests/net/packetdrill/run_system_call.c b/gtests/net/packetdrill/run_system_call.c index b4dff606..0997c07c 100644 --- a/gtests/net/packetdrill/run_system_call.c +++ b/gtests/net/packetdrill/run_system_call.c @@ -3574,7 +3574,7 @@ void syscalls_free(struct state *state, struct syscalls *syscalls) { /* Wait a bit for the thread to go idle. */ if (await_idle_thread(state)) { - die("%s:%d: runtime error: exiting while " + die_free_so(state, "%s:%d: runtime error: exiting while " "a blocking system call is in progress\n", state->config->script_path, syscalls->event->line_number); diff --git a/gtests/net/tcp/blocking/blocking-accept-fuzz-template.pkt b/gtests/net/tcp/blocking/blocking-accept-fuzz-template.pkt new file mode 100644 index 00000000..9c196c04 --- /dev/null +++ b/gtests/net/tcp/blocking/blocking-accept-fuzz-template.pkt @@ -0,0 +1,18 @@ + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 + +0 bind(3, ..., ...) = 0 + +0 listen(3, 1) = 0 + +0...0.200 accept(3, ..., ...) = 4 ++.1 < S 0:0(0) win 32792 + +0 > S. 0:0(0) ack 1 ++.1 < . 1:1(0) ack 1 win 257 ++.1 < P. 1:21(20) ack 1 win 257 ++.1 < P. 1:21(20) ack 1 win 257 ++.1 < P. 1:21(20) ack 1 win 257 ++.1 < P. 1:21(20) ack 1 win 257 ++.1 < P. 1:21(20) ack 1 win 257 ++.1 < P. 1:21(20) ack 1 win 257 ++.1 < P. 1:21(20) ack 1 win 257 ++.1 < P. 1:21(20) ack 1 win 257 ++.1 < P. 1:21(20) ack 1 win 257 ++.1 < P. 1:21(20) ack 1 win 257 \ No newline at end of file diff --git a/gtests/net/tcp/blocking/blocking-accept-fuzz.pkt b/gtests/net/tcp/blocking/blocking-accept-fuzz.pkt new file mode 100644 index 00000000..a754d64a --- /dev/null +++ b/gtests/net/tcp/blocking/blocking-accept-fuzz.pkt @@ -0,0 +1,13 @@ + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 + +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 + +0 bind(3, ..., ...) = 0 + +0 listen(3, 1) = 0 + +0...0.200 accept(3, ..., ...) = 4 ++.1 < S 0:0(0) win 32792 + +0 > S. 0:0(0) ack 1 ++.1 < . 1:1(0) ack 1 win 257 ++.1 < P. 1:21(20) ack 1 win 257 {rep ipv4 version_ihl 0x35} ++.1 < P. 1:21(20) ack 1 win 257 {rep tcp src_port 0x0B63} ++.1 < P. 1:21(20) ack 1 win 257 {rep tcp seq_num 0x01234321} ++.1 < P. 1:21(20) ack 1 win 257 {rep ipv4 protocol 0x02} ++.1 < P. 1:21(20) ack 1 win 257 {rep tcp win_size 0x1021} \ No newline at end of file diff --git a/gtests/net/tcp/blocking/blocking-connect-data.pkt b/gtests/net/tcp/blocking/blocking-connect-data.pkt new file mode 100644 index 00000000..992d0e40 --- /dev/null +++ b/gtests/net/tcp/blocking/blocking-connect-data.pkt @@ -0,0 +1,24 @@ +// Test for blocking connect. + +//`../common/defaults.sh` + +// Establish a connection. + 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 + + +.1...0.200 connect(3, ..., ...) = 0 + + +0 > S 0:0(0) + +.1 < S. 0:0(0) ack 1 win 5792 + +0 > . 1:1(0) ack 1 + + +0 < . 1:101(100) ack 1 win 27510 + +0 < . 101:201(100) ack 1 win 27510 + +0 < . 201:401(200) ack 1 win 27510 + +0 < . 401:501(100) ack 1 win 27510 + +0 < . 501:1001(500) ack 1 win 27510 + +0 < . 1001:2001(1000) ack 1 win 27510 + +0 < . 2001:5001(3000) ack 1 win 27510 + +0 < . 1:10001(10000) ack 1 win 27510 + +0 < . 10001:30001(20000) ack 1 win 27510 + +0 < . 1:101(100) ack 1 win 27510 + From 75f6bcc58d97a810ef626519088b2e8555776edf Mon Sep 17 00:00:00 2001 From: AmPaschal Date: Mon, 13 Feb 2023 03:09:35 +0000 Subject: [PATCH 09/17] Enabled UDP fuzzing --- gtests/net/packetdrill/fuzz_options.h | 3 ++- gtests/net/packetdrill/ip_address.h | 4 ---- gtests/net/packetdrill/packet_checksum.c | 4 ++-- gtests/net/packetdrill/parser.y | 11 ++++++++-- gtests/net/packetdrill/run_packet.c | 2 +- gtests/net/packetdrill/udp_packet.c | 6 ++++++ gtests/net/packetdrill/udp_packet.h | 2 ++ .../blocking-accept-fuzz-template.pkt | 9 +-------- gtests/net/tcp/blocking/blocking-accept.pkt | 9 ++++++--- gtests/net/tcp/blocking/blocking-connect.pkt | 2 +- gtests/net/udp/blocking-write.pkt | 20 +++++++++++++++++++ 11 files changed, 50 insertions(+), 22 deletions(-) create mode 100644 gtests/net/udp/blocking-write.pkt diff --git a/gtests/net/packetdrill/fuzz_options.h b/gtests/net/packetdrill/fuzz_options.h index 9c637799..d18b9e03 100644 --- a/gtests/net/packetdrill/fuzz_options.h +++ b/gtests/net/packetdrill/fuzz_options.h @@ -44,7 +44,8 @@ enum field_name_t { enum header_type_t { IPv4 = 0, IPv6 = 1, - xTCP = 2 + xTCP = 2, + xUDP = 3 }; struct fuzz_option { diff --git a/gtests/net/packetdrill/ip_address.h b/gtests/net/packetdrill/ip_address.h index 15fb085c..e134956a 100644 --- a/gtests/net/packetdrill/ip_address.h +++ b/gtests/net/packetdrill/ip_address.h @@ -77,10 +77,6 @@ static void print_hex( char * bin_data, size_t len) static inline bool is_equal_ip(const struct ip_address *a, const struct ip_address *b) { - printf("Original ip address\n"); - print_hex((char *) &a->ip.v4.s_addr, ip_address_length(a->address_family)); - printf("Returned ip address\n"); - print_hex((char *) &b->ip.v4.s_addr, ip_address_length(b->address_family)); return ((a->address_family == b->address_family) && !memcmp(&a->ip, &b->ip, ip_address_length(a->address_family))); } diff --git a/gtests/net/packetdrill/packet_checksum.c b/gtests/net/packetdrill/packet_checksum.c index d5164b34..31364e2c 100644 --- a/gtests/net/packetdrill/packet_checksum.c +++ b/gtests/net/packetdrill/packet_checksum.c @@ -42,7 +42,7 @@ static void checksum_ipv4_packet(struct packet *packet) /* Find the length of layer 4 header, options, and payload. */ const int l4_bytes = ntohs(ipv4->tot_len) - ipv4_header_len(ipv4); - assert(l4_bytes > 0); + //assert(l4_bytes > 0); // When fuzzing, we can remove the l4 header /* Fill in IPv4-based layer 4 checksum. */ if (packet->tcp != NULL) { @@ -76,7 +76,7 @@ static void checksum_ipv6_packet(struct packet *packet) /* Find the length of layer 4 header, options, and payload. */ const int l4_bytes = ntohs(ipv6->payload_len); - assert(l4_bytes > 0); + //assert(l4_bytes > 0); /* Fill in IPv6-based layer 4 checksum. */ if (packet->tcp != NULL) { diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index 8c23d0d5..172fba07 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -867,7 +867,7 @@ tcp_packet_spec ; udp_packet_spec -: packet_prefix opt_ip_info UDP opt_port_info '(' INTEGER ')' { +: packet_prefix opt_ip_info UDP opt_port_info '(' INTEGER ')' opt_fuzz_options { char *error = NULL; struct packet *outer = $1, *inner = NULL; enum direction_t direction = outer->direction; @@ -881,13 +881,17 @@ udp_packet_spec } inner = new_udp_packet(in_config->wire_protocol, direction, $2, - $6, $4.src_port, $4.dst_port, &error); + $6, $4.src_port, $4.dst_port, $8, &error); + + free($8); + if (inner == NULL) { assert(error != NULL); semantic_error(error); free(error); } + $$ = packet_encapsulate_and_free(outer, inner); } ; @@ -1463,6 +1467,9 @@ header_type | TCP { $$ = xTCP; } +| UDP { + $$ = xUDP; +} ; fuzz_field diff --git a/gtests/net/packetdrill/run_packet.c b/gtests/net/packetdrill/run_packet.c index 36f44790..4d0656aa 100644 --- a/gtests/net/packetdrill/run_packet.c +++ b/gtests/net/packetdrill/run_packet.c @@ -113,7 +113,7 @@ static void verbose_packet_dump(struct state *state, const char *type, if (state->config->verbose) { char *dump = NULL, *dump_error = NULL; - packet_to_string(live_packet, DUMP_SHORT, + packet_to_string(live_packet, DUMP_VERBOSE, &dump, &dump_error); printf("%s packet: %9.6f %s%s%s\n", diff --git a/gtests/net/packetdrill/udp_packet.c b/gtests/net/packetdrill/udp_packet.c index 81c91873..9ba1318e 100644 --- a/gtests/net/packetdrill/udp_packet.c +++ b/gtests/net/packetdrill/udp_packet.c @@ -33,6 +33,7 @@ struct packet *new_udp_packet(int address_family, u16 udp_payload_bytes, u16 src_port, u16 dst_port, + const struct fuzz_options *fuzz_options, char **error) { struct packet *packet = NULL; /* the newly-allocated result packet */ @@ -87,5 +88,10 @@ struct packet *new_udp_packet(int address_family, packet->udp->check = 0; packet->ip_bytes = ip_bytes; + + if (fuzz_options != NULL) { + packet->fuzz_options = malloc(fuzz_options->size); + memcpy(packet->fuzz_options, fuzz_options, fuzz_options->size); + } return packet; } diff --git a/gtests/net/packetdrill/udp_packet.h b/gtests/net/packetdrill/udp_packet.h index 9ace4403..64be78a3 100644 --- a/gtests/net/packetdrill/udp_packet.h +++ b/gtests/net/packetdrill/udp_packet.h @@ -28,6 +28,7 @@ #include "types.h" #include "packet.h" +#include "fuzz_options.h" /* Create and initialize a new struct packet containing a UDP segment. * The 'flags' are a tcpdump-style sequence of UDP header flags. @@ -40,5 +41,6 @@ extern struct packet *new_udp_packet(int address_family, u16 udp_payload_bytes, u16 src_port, u16 dst_port, + const struct fuzz_options *fuzz_options, char **error); #endif /* __UDP_PACKET_H__ */ diff --git a/gtests/net/tcp/blocking/blocking-accept-fuzz-template.pkt b/gtests/net/tcp/blocking/blocking-accept-fuzz-template.pkt index 9c196c04..3cc9a69c 100644 --- a/gtests/net/tcp/blocking/blocking-accept-fuzz-template.pkt +++ b/gtests/net/tcp/blocking/blocking-accept-fuzz-template.pkt @@ -7,12 +7,5 @@ +0 > S. 0:0(0) ack 1 +.1 < . 1:1(0) ack 1 win 257 +.1 < P. 1:21(20) ack 1 win 257 -+.1 < P. 1:21(20) ack 1 win 257 -+.1 < P. 1:21(20) ack 1 win 257 -+.1 < P. 1:21(20) ack 1 win 257 -+.1 < P. 1:21(20) ack 1 win 257 -+.1 < P. 1:21(20) ack 1 win 257 -+.1 < P. 1:21(20) ack 1 win 257 -+.1 < P. 1:21(20) ack 1 win 257 -+.1 < P. 1:21(20) ack 1 win 257 ++.1 < P. 1:21(20) ack 1 win 257 +.1 < P. 1:21(20) ack 1 win 257 \ No newline at end of file diff --git a/gtests/net/tcp/blocking/blocking-accept.pkt b/gtests/net/tcp/blocking/blocking-accept.pkt index 8d23a76f..d088fd98 100644 --- a/gtests/net/tcp/blocking/blocking-accept.pkt +++ b/gtests/net/tcp/blocking/blocking-accept.pkt @@ -1,6 +1,6 @@ // Test for blocking accept. -`../common/defaults.sh` +//`../common/defaults.sh` // Establish a connection. 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 @@ -13,5 +13,8 @@ +0 > S. 0:0(0) ack 1 +.1 < . 1:1(0) ack 1 win 257 - +.1 write(4, ..., 2000) = 2000 - +0 > P. 1:2001(2000) ack 1 + +.1 write(4, ..., 200) = 200 + +0 > P. 1:201(200) ack 1 + + +.1 < P. 1:1(0) ack 1 win 257 {rep tcp tcp_hdr_len 0x70} + +0 read(4, ..., 200) = 200 diff --git a/gtests/net/tcp/blocking/blocking-connect.pkt b/gtests/net/tcp/blocking/blocking-connect.pkt index 602cca56..b67c1b47 100644 --- a/gtests/net/tcp/blocking/blocking-connect.pkt +++ b/gtests/net/tcp/blocking/blocking-connect.pkt @@ -1,6 +1,6 @@ // Test for blocking connect. -`../common/defaults.sh` +//`../common/defaults.sh` // Establish a connection. 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 diff --git a/gtests/net/udp/blocking-write.pkt b/gtests/net/udp/blocking-write.pkt new file mode 100644 index 00000000..3969a50f --- /dev/null +++ b/gtests/net/udp/blocking-write.pkt @@ -0,0 +1,20 @@ +// Test for blocking write. +//--tolerance_usecs=10000 + +//`../common/defaults.sh +//` + +// Establish a connection. + 0 socket(..., SOCK_DGRAM, IPPROTO_UDP) = 3 + +0 bind(3, ..., ...) = 0 + +// +0 sendto(3, ..., 20, MSG_CONFIRM, ..., ...) = 20 + +// +0 > udp (20) + + +0 < udp (0) + + +0 recvfrom(3, ..., 1024, MSG_WAITALL, ..., ...) = 30 + + + From 02e16309089e0dadcfbc2e6101f4684ecceda899 Mon Sep 17 00:00:00 2001 From: AmPaschal Date: Fri, 10 Mar 2023 12:54:19 +0000 Subject: [PATCH 10/17] Added fuzz terminating signal + other minor changes --- gtests/net/packetdrill/Makefile.common | 2 +- gtests/net/packetdrill/fuzz_testing.h | 14 +++++ gtests/net/packetdrill/ip_address.h | 13 ----- gtests/net/packetdrill/run_packet.c | 51 ++++++++++++++++--- gtests/net/packetdrill/run_packet.h | 8 +++ gtests/net/packetdrill/so_testing.c | 2 +- gtests/net/packetdrill/socket.c | 45 ++++++++++++++++ .../net/tcp/blocking/blocking-accept-fuzz.pkt | 6 +-- gtests/net/tcp/blocking/blocking-accept.pkt | 4 +- gtests/net/udp/blocking-write.pkt | 4 +- 10 files changed, 119 insertions(+), 30 deletions(-) create mode 100644 gtests/net/packetdrill/fuzz_testing.h diff --git a/gtests/net/packetdrill/Makefile.common b/gtests/net/packetdrill/Makefile.common index e2b80a51..8a5c6718 100644 --- a/gtests/net/packetdrill/Makefile.common +++ b/gtests/net/packetdrill/Makefile.common @@ -1,6 +1,6 @@ all: binaries -CFLAGS = -g -Wall -Werror -Wno-unused-result -Wno-stringop-truncation +CFLAGS = -g -Wall -Werror -Wno-unused-result -Wno-stringop-truncation -Wno-int-to-pointer-cast parser.o: parser.y bison --output=parser.c --defines=parser.h --report=state parser.y diff --git a/gtests/net/packetdrill/fuzz_testing.h b/gtests/net/packetdrill/fuzz_testing.h new file mode 100644 index 00000000..ff088508 --- /dev/null +++ b/gtests/net/packetdrill/fuzz_testing.h @@ -0,0 +1,14 @@ + +/* + * Author: pamusuo@purdue.edu (Paschal Amusuo) + * + * Testing using mutated packets + */ + +#ifndef __FUZZ_TESTING_H__ +#define __FUZZ_TESTING_H__ + +static uint8_t termination_payload[5] = {0x11, 0x22, 0x11, 0x33, 0x44}; +static uint8_t termination_offset = 28; + +#endif /* __FUZZ_TESTING_H__ */ diff --git a/gtests/net/packetdrill/ip_address.h b/gtests/net/packetdrill/ip_address.h index e134956a..6ee586ba 100644 --- a/gtests/net/packetdrill/ip_address.h +++ b/gtests/net/packetdrill/ip_address.h @@ -60,19 +60,6 @@ extern int ip_address_length(int address_family); /* Return the number of bytes in sockaddr of the given family. */ extern int sockaddr_length(int address_family); -static void print_hex( char * bin_data, size_t len) - -{ - size_t i; - - for( i = 0; i < len; ++i ) - { - printf( "%.2X ", bin_data[ i ] ); - } - - printf( "\n" ); -} - /* Return true iff the two addresses are the same. */ static inline bool is_equal_ip(const struct ip_address *a, const struct ip_address *b) diff --git a/gtests/net/packetdrill/run_packet.c b/gtests/net/packetdrill/run_packet.c index 4d0656aa..7584e395 100644 --- a/gtests/net/packetdrill/run_packet.c +++ b/gtests/net/packetdrill/run_packet.c @@ -44,8 +44,10 @@ #include "tcp_options_iterator.h" #include "tcp_options_to_string.h" #include "tcp_packet.h" +#include "udp_packet.h" #include "wrap.h" #include "fm_testing.h" +#include "fuzz_testing.h" /* To avoid issues with TIME_WAIT, FIN_WAIT1, and FIN_WAIT2 we use * dynamically-chosen, unique 4-tuples for each test. We implement the @@ -128,10 +130,12 @@ static void verbose_packet_dump(struct state *state, const char *type, /* See if the live packet matches the live 4-tuple of the socket (UDP/TCP) * or matches the src/dst IP addr for the ICMP socket + * + * With compare_ip, we allow matching a socket with only matching ip address */ static struct socket *find_socket_for_live_packet( struct state *state, const struct packet *packet, - enum direction_t *direction) + enum direction_t *direction, uint8_t compare_ip) { struct socket *socket = state->socket_under_test; /* shortcut */ if (socket == NULL) @@ -139,7 +143,7 @@ static struct socket *find_socket_for_live_packet( struct tuple packet_tuple, live_outbound, live_inbound; bool is_icmp = (socket->protocol == IPPROTO_ICMP && packet->icmpv4) || - (socket->protocol == IPPROTO_ICMPV6 && packet->icmpv6); + (socket->protocol == IPPROTO_ICMPV6 && packet->icmpv6) || compare_ip; get_packet_tuple(packet, &packet_tuple); /* Is packet inbound to the socket under test? */ @@ -1460,9 +1464,9 @@ static int verify_packet_fragments( } /* Sniff the next outbound live packet and return it. */ -static int sniff_outbound_live_packet( +int sniff_outbound_live_packet( struct state *state, struct socket *expected_socket, - struct packet **packet, char **error) + struct packet **packet, char **error, uint8_t compare_ip) { DEBUGP("sniff_outbound_live_packet\n"); struct socket *socket = NULL; @@ -1473,7 +1477,7 @@ static int sniff_outbound_live_packet( return STATUS_ERR; /* See if the packet matches an existing, known socket. */ socket = find_socket_for_live_packet(state, *packet, - &direction); + &direction, compare_ip); if ((socket != NULL) && (direction == DIRECTION_OUTBOUND)) break; /* See if the packet matches a recent connect() call. */ @@ -1608,7 +1612,7 @@ static int do_outbound_script_packet( * socket. */ if (sniff_outbound_live_packet(state, socket, &live_packet, - error)) + error, 0)) goto out; live_payload = packet_payload_len(live_packet); DEBUGP("Sniffed packet with payload %d bytes\n", live_payload); @@ -1945,6 +1949,41 @@ int reset_connection(struct state *state, struct socket *socket) return result; } + +int send_test_complete_signal(struct state *state, struct socket *socket) +{ + char *error = NULL; + struct packet *packet = NULL; + struct tuple live_inbound; + const struct ip_info ip_info = {{TOS_CHECK_NONE, 0}, 0}; + int result = 0; + + /* Create UDP packet targeted at port 5700*/ + packet = new_udp_packet(socket->address_family, + DIRECTION_INBOUND, ip_info, 5, 0, + 0, NULL, &error); + + + if (packet == NULL) + die("%s", error); + + /* Rewrite addresses and port to match inbound live traffic. */ + socket_get_inbound(&socket->live, &live_inbound); + + /* We update the destination port to 5700, which informs the target the test is completed */ + memcpy(packet->buffer + termination_offset, termination_payload, sizeof(termination_payload)); + + set_packet_tuple(packet, &live_inbound); + + /* Inject live packet into kernel. */ + result = send_live_ip_packet(state, packet); + + packet_free(packet); + + return result; +} + + struct packets *packets_new(const struct state *state) { struct packets *packets = calloc(1, sizeof(struct packets)); diff --git a/gtests/net/packetdrill/run_packet.h b/gtests/net/packetdrill/run_packet.h index b4220343..242eda05 100644 --- a/gtests/net/packetdrill/run_packet.h +++ b/gtests/net/packetdrill/run_packet.h @@ -58,4 +58,12 @@ extern int run_packet_event(struct state *state, extern int reset_connection(struct state *state, struct socket *socket); +/* Send a custom packet to tell the target this test has ended, and wait for response from target */ +extern int send_test_complete_signal(struct state *state, + struct socket *socket); + +extern int sniff_outbound_live_packet( + struct state *state, struct socket *expected_socket, + struct packet **packet, char **error, uint8_t compare_ip); + #endif /* __RUN_PACKET_H__ */ diff --git a/gtests/net/packetdrill/so_testing.c b/gtests/net/packetdrill/so_testing.c index ee4b645f..28200922 100644 --- a/gtests/net/packetdrill/so_testing.c +++ b/gtests/net/packetdrill/so_testing.c @@ -61,7 +61,7 @@ static int so_netdev_send(struct netdev *a_netdev, struct packet *packet) assert(packet->tcp || packet->udp || packet->icmpv4 || packet->icmpv6); return netdev->ifc->netdev_send(netdev->ifc->userdata, - packet_start(packet), + packet->buffer, packet->ip_bytes); } diff --git a/gtests/net/packetdrill/socket.c b/gtests/net/packetdrill/socket.c index c83d9462..6b975ade 100644 --- a/gtests/net/packetdrill/socket.c +++ b/gtests/net/packetdrill/socket.c @@ -27,11 +27,47 @@ #include #include #include "run.h" +#include "fuzz_testing.h" + +int perform_termination_handshake(struct state *state, struct socket *socket) { + int sendResult = send_test_complete_signal(state, socket); + + if (sendResult == 0) { + struct packet *live_packet = NULL; + char *error = NULL; + + while (true) { + int receiveResult = sniff_outbound_live_packet(state, socket, &live_packet, + &error, 1); + + if (receiveResult != 0) { + continue; + } + + uint8_t comparisonBytes[5]; + memcpy(comparisonBytes, packet_start(live_packet) + termination_offset, sizeof(termination_payload)); // Get destination port field + + if (memcmp(comparisonBytes, termination_payload, 5) == 0) { + // The extracted bytes are equal + break; + } + + if (live_packet != NULL) { + packet_free(live_packet); + live_packet = NULL; + } + } + + } + + return sendResult; +} void socket_close(struct state *state, struct fd_state *fd) { struct socket *socket = fd_to_socket(fd); + if (fd->live_fd >= 0 && !socket->fd.is_closed && !fd->so_managed) { /* Let the so_instance be in charge of closing sockets it created as these sockets may not have been on linux */ assert(fd->script_fd >= 0); @@ -49,6 +85,15 @@ void socket_close(struct state *state, struct fd_state *fd) die("error reseting connection\n"); } + // Send a signal to tell target test has completed + if (socket->live.local.port != 0 && + socket->live.remote.port != 0 && + !state->config->is_wire_client && + perform_termination_handshake(state, socket)) { + die("error terminating test\n"); + } + + socket_free(socket); } diff --git a/gtests/net/tcp/blocking/blocking-accept-fuzz.pkt b/gtests/net/tcp/blocking/blocking-accept-fuzz.pkt index a754d64a..8e6b3a9d 100644 --- a/gtests/net/tcp/blocking/blocking-accept-fuzz.pkt +++ b/gtests/net/tcp/blocking/blocking-accept-fuzz.pkt @@ -6,8 +6,4 @@ +.1 < S 0:0(0) win 32792 +0 > S. 0:0(0) ack 1 +.1 < . 1:1(0) ack 1 win 257 -+.1 < P. 1:21(20) ack 1 win 257 {rep ipv4 version_ihl 0x35} -+.1 < P. 1:21(20) ack 1 win 257 {rep tcp src_port 0x0B63} -+.1 < P. 1:21(20) ack 1 win 257 {rep tcp seq_num 0x01234321} -+.1 < P. 1:21(20) ack 1 win 257 {rep ipv4 protocol 0x02} -+.1 < P. 1:21(20) ack 1 win 257 {rep tcp win_size 0x1021} \ No newline at end of file ++.1 < P. 1:21(20) ack 1 win 257 {rep ipv4 version_ihl 0x35} \ No newline at end of file diff --git a/gtests/net/tcp/blocking/blocking-accept.pkt b/gtests/net/tcp/blocking/blocking-accept.pkt index d088fd98..58396d90 100644 --- a/gtests/net/tcp/blocking/blocking-accept.pkt +++ b/gtests/net/tcp/blocking/blocking-accept.pkt @@ -16,5 +16,5 @@ +.1 write(4, ..., 200) = 200 +0 > P. 1:201(200) ack 1 - +.1 < P. 1:1(0) ack 1 win 257 {rep tcp tcp_hdr_len 0x70} - +0 read(4, ..., 200) = 200 + +.1 < P. 1:11(10) ack 1 win 257 + +0 read(4, ..., 10) = 10 diff --git a/gtests/net/udp/blocking-write.pkt b/gtests/net/udp/blocking-write.pkt index 3969a50f..a1e3a25e 100644 --- a/gtests/net/udp/blocking-write.pkt +++ b/gtests/net/udp/blocking-write.pkt @@ -12,9 +12,9 @@ // +0 > udp (20) - +0 < udp (0) + +0 < udp (10) - +0 recvfrom(3, ..., 1024, MSG_WAITALL, ..., ...) = 30 + +0 recvfrom(3, ..., 1024, MSG_WAITALL, ..., ...) = 10 From 2f76b2c7954dd7512e46a1f84530f4eb3fbbb7b5 Mon Sep 17 00:00:00 2001 From: AmPaschal Date: Sat, 11 Mar 2023 16:57:27 +0000 Subject: [PATCH 11/17] Changed implementation of fuzz terminating signal --- gtests/net/packetdrill/fuzz_testing.h | 2 - gtests/net/packetdrill/run.c | 64 +++++++++++++++++++++++++++ gtests/net/packetdrill/run_packet.c | 3 ++ gtests/net/packetdrill/socket.c | 41 ----------------- gtests/net/udp/blocking-write.pkt | 4 +- 5 files changed, 69 insertions(+), 45 deletions(-) diff --git a/gtests/net/packetdrill/fuzz_testing.h b/gtests/net/packetdrill/fuzz_testing.h index ff088508..567b05ab 100644 --- a/gtests/net/packetdrill/fuzz_testing.h +++ b/gtests/net/packetdrill/fuzz_testing.h @@ -8,7 +8,5 @@ #ifndef __FUZZ_TESTING_H__ #define __FUZZ_TESTING_H__ -static uint8_t termination_payload[5] = {0x11, 0x22, 0x11, 0x33, 0x44}; -static uint8_t termination_offset = 28; #endif /* __FUZZ_TESTING_H__ */ diff --git a/gtests/net/packetdrill/run.c b/gtests/net/packetdrill/run.c index ddbd3b0f..72bfe3c2 100644 --- a/gtests/net/packetdrill/run.c +++ b/gtests/net/packetdrill/run.c @@ -50,6 +50,7 @@ #include "tcp.h" #include "tcp_options.h" #include "fm_testing.h" +#include "fuzz_testing.h" /* MAX_SPIN_USECS is the maximum amount of time (in microseconds) to * spin waiting for an event. We sleep up until this many microseconds @@ -120,6 +121,57 @@ static void close_all_fds(struct state *state) } } +int perform_termination_handshake(struct state *state, struct socket *socket) { + int sendResult = send_test_complete_signal(state, socket); + + if (sendResult == 0) { + struct packet *live_packet = NULL; + char *error = NULL; + + struct tuple packet_tuple, live_outbound; + + while (true) { + + if (netdev_receive(state->netdev, &live_packet, &error)) + return 1; + + get_packet_tuple(live_packet, &packet_tuple); + socket_get_outbound(&socket->live, &live_outbound); + + if (!is_equal_ip(&packet_tuple.dst.ip, &live_outbound.dst.ip) || + !is_equal_ip(&packet_tuple.src.ip, &live_outbound.src.ip)) { + + printf("Not expected outbound packet\n"); + packet_free(live_packet); + live_packet = NULL; + continue; + } + + uint8_t termination_offset = live_packet->ipv4 != NULL ? 28 : 48; + uint8_t termination_payload[5] = {0x11, 0x22, 0x11, 0x33, 0x44}; + + uint8_t comparisonBytes[5]; + memcpy(comparisonBytes, packet_start(live_packet) + termination_offset, sizeof(termination_payload)); // Get destination port field + + if (memcmp(comparisonBytes, termination_payload, 5) == 0) { + // The extracted bytes are equal + printf("Termination handshake successful\n"); + break; + } else { + printf("Termination handshake failed\n"); + } + + if (live_packet != NULL) { + packet_free(live_packet); + live_packet = NULL; + } + } + + } + + return sendResult; +} + void state_free(struct state *state) { /* We have to stop the system call thread first, since it's using @@ -127,12 +179,24 @@ void state_free(struct state *state) */ syscalls_free(state, state->syscalls); + /* We make a copy of the socket under test */ + struct socket *sut = malloc(sizeof(struct socket)); + memcpy(sut, state->socket_under_test, sizeof(struct socket)); + /* Then we close the sockets and reset the connections, while * we still have a netdev for injecting reset packets to free * per-connection kernel state. */ close_all_fds(state); + /* We perform the termination handshake */ + if (perform_termination_handshake(state, sut) != 0) { + printf("Termination handshake failed\n"); + } + + /* We free the socket under test */ + free(sut); + netdev_free(state->netdev); packets_free(state->packets); code_free(state->code); diff --git a/gtests/net/packetdrill/run_packet.c b/gtests/net/packetdrill/run_packet.c index 7584e395..b092d591 100644 --- a/gtests/net/packetdrill/run_packet.c +++ b/gtests/net/packetdrill/run_packet.c @@ -1970,6 +1970,9 @@ int send_test_complete_signal(struct state *state, struct socket *socket) /* Rewrite addresses and port to match inbound live traffic. */ socket_get_inbound(&socket->live, &live_inbound); + uint8_t termination_offset = packet->ipv4 != NULL ? 28 : 48; + uint8_t termination_payload[5] = {0x11, 0x22, 0x11, 0x33, 0x44}; + /* We update the destination port to 5700, which informs the target the test is completed */ memcpy(packet->buffer + termination_offset, termination_payload, sizeof(termination_payload)); diff --git a/gtests/net/packetdrill/socket.c b/gtests/net/packetdrill/socket.c index 6b975ade..4eccbe85 100644 --- a/gtests/net/packetdrill/socket.c +++ b/gtests/net/packetdrill/socket.c @@ -29,39 +29,6 @@ #include "run.h" #include "fuzz_testing.h" -int perform_termination_handshake(struct state *state, struct socket *socket) { - int sendResult = send_test_complete_signal(state, socket); - - if (sendResult == 0) { - struct packet *live_packet = NULL; - char *error = NULL; - - while (true) { - int receiveResult = sniff_outbound_live_packet(state, socket, &live_packet, - &error, 1); - - if (receiveResult != 0) { - continue; - } - - uint8_t comparisonBytes[5]; - memcpy(comparisonBytes, packet_start(live_packet) + termination_offset, sizeof(termination_payload)); // Get destination port field - - if (memcmp(comparisonBytes, termination_payload, 5) == 0) { - // The extracted bytes are equal - break; - } - - if (live_packet != NULL) { - packet_free(live_packet); - live_packet = NULL; - } - } - - } - - return sendResult; -} void socket_close(struct state *state, struct fd_state *fd) { @@ -85,14 +52,6 @@ void socket_close(struct state *state, struct fd_state *fd) die("error reseting connection\n"); } - // Send a signal to tell target test has completed - if (socket->live.local.port != 0 && - socket->live.remote.port != 0 && - !state->config->is_wire_client && - perform_termination_handshake(state, socket)) { - die("error terminating test\n"); - } - socket_free(socket); } diff --git a/gtests/net/udp/blocking-write.pkt b/gtests/net/udp/blocking-write.pkt index a1e3a25e..69153939 100644 --- a/gtests/net/udp/blocking-write.pkt +++ b/gtests/net/udp/blocking-write.pkt @@ -12,9 +12,9 @@ // +0 > udp (20) - +0 < udp (10) + +0 < udp (0) - +0 recvfrom(3, ..., 1024, MSG_WAITALL, ..., ...) = 10 +// +0 recvfrom(3, ..., 1024, MSG_WAITALL, ..., ...) = 0 From d9cd0f984d0e0bebc2c1db0f7a3f17c102076339 Mon Sep 17 00:00:00 2001 From: Ricardo Andres Calvo Mendez Date: Fri, 31 Mar 2023 16:33:41 +0000 Subject: [PATCH 12/17] IPv6, IPv4 and TCP working --- gtests/net/packetdrill/fuzz_options.h | 53 ++++++++----- gtests/net/packetdrill/lexer.l | 41 ++++++++--- gtests/net/packetdrill/packet_checksum.c | 2 +- gtests/net/packetdrill/parser.y | 94 +++++++++++++++++++----- 4 files changed, 140 insertions(+), 50 deletions(-) diff --git a/gtests/net/packetdrill/fuzz_options.h b/gtests/net/packetdrill/fuzz_options.h index 9c637799..6a068da6 100644 --- a/gtests/net/packetdrill/fuzz_options.h +++ b/gtests/net/packetdrill/fuzz_options.h @@ -18,25 +18,43 @@ enum fuzz_type_t { }; enum field_name_t { - F_SOURCE_PORT = 0, + F_SRC_PORT = 0, F_DST_PORT = 1, F_SEQ_NUM = 2, F_ACK_NUM = 3, - F_TCP_HDR_LEN = 4, - F_FLAGS = 5, - F_WIN_SIZE = 6, - F_TCP_CHECKSUM = 7, - F_URG_POINTER = 8, - F_VERSION_IHL = 9, - F_DSCP_ESN = 10, - F_TOT_LEN = 11, - F_IDEN = 12, - F_FLAGS_FLAGOFF = 13, - F_TTL = 14, - F_PROTOCOL = 15, - F_IP_CHECKSUM = 16, - F_SRC_IP = 17, - F_DEST_IP = 18 + F_DATA_OFF = 4, + F_RESERVED = 5, + F_FLAGS = 6, + F_CWR_FLAG = 7, + F_ECE_FLAG = 8, + F_URG_FLAG = 9, + F_ACK_FLAG = 10, + F_PSH_FLAG = 11, + F_RST_FLAG = 12, + F_SYN_FLAG = 13, + F_FIN_FLAG = 14, + F_WIN_SIZE = 15, + F_CHECKSUM = 16, + F_URG_POINTER = 17, + F_VERSION = 18, + F_IHL = 19, + F_DSCP = 20, + F_ECN = 21, + F_TOT_LEN = 22, + F_IDEN = 23, + F_RSV_FLAG = 24, + F_DF_FLAG = 25, + F_MF_FLAG = 26, + F_FRAG_OFF = 27, + F_TTL = 28, + F_PROTOCOL = 29, + F_SRC_ADDR = 30, + F_DST_ADDR = 31, + F_TRF_CLASS = 32, + F_FLOW_LABEL = 33, + F_PYLD_LEN = 34, + F_NEXT_HEADER = 35, + F_HOP_LIMIT = 36 }; @@ -44,7 +62,8 @@ enum field_name_t { enum header_type_t { IPv4 = 0, IPv6 = 1, - xTCP = 2 + xTCP = 2, + xUDP = 3 }; struct fuzz_option { diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index 5139943b..c0c0179e 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -234,7 +234,6 @@ present return PRESENT; mpls return MPLS; label return LABEL; tc return TC; -ttl return TTL; inet_addr return INET_ADDR; inet6_addr return INET6_ADDR; ack return ACK; @@ -251,7 +250,6 @@ FO return FAST_OPEN; FOEXP return FAST_OPEN_EXP; tos return TOS; flowlabel return FLOWLABEL; -flags return FLAGS; Flags return FLAGS; val return VAL; win return WIN; @@ -268,24 +266,43 @@ trun return TRUNCATE; ins return INSERT; tcp return TCP; ihl return IHL; -src_port return SOURCE_PORT; + +src_port return SRC_PORT; dst_port return DST_PORT; seq_num return SEQ_NUM; ack_num return ACK_NUM; -tcp_hdr_len return TCP_HDR_LEN; +data_off return DATA_OFF; +reserved return RESERVED; +flags return FLAGS; +cwr_flag return CWR_FLAG; +ece_flag return ECE_FLAG; +urg_flag return URG_FLAG; +ack_flag return ACK_FLAG; +psh_flag return PSH_FLAG; +rst_flag return RST_FLAG; +syn_flag return SYN_FLAG; +fin_flag return FIN_FLAG; win_size return WIN_SIZE; -tcp_checksum return TCP_CHECKSUM; +checksum return CHECKSUM; urg_pointer return URG_POINTER; -version_ihl return VERSION_IHL; -dscp_esn return DSCP_ESN; +version return VERSION; +dscp return DSCP; +ecn return ECN; tot_len return TOT_LEN; iden return IDEN; -flags_fragoff return FLAGS_FLAGOFF; +rsv_flag return RSV_FLAG; +df_flag return DF_FLAG; +mf_flag return MF_FLAG; +frag_off return FRAG_OFF; +ttl return TTL; protocol return PROTOCOL; -ip_checksum return IP4_CHECKSUM; -src_ip return SRC_IP; -dest_ip return DEST_IP; - +src_addr return SRC_ADDR; +dst_addr return DST_ADDR; +trf_class return TRF_CLASS; +flow_label return FLOW_LABEL; +pyld_len return PYLD_LEN; +next_header return NEXT_HEADER; +hop_limit return HOP_LIMIT; [.][.][.] return ELLIPSIS; diff --git a/gtests/net/packetdrill/packet_checksum.c b/gtests/net/packetdrill/packet_checksum.c index d5164b34..cbcbed7a 100644 --- a/gtests/net/packetdrill/packet_checksum.c +++ b/gtests/net/packetdrill/packet_checksum.c @@ -42,7 +42,7 @@ static void checksum_ipv4_packet(struct packet *packet) /* Find the length of layer 4 header, options, and payload. */ const int l4_bytes = ntohs(ipv4->tot_len) - ipv4_header_len(ipv4); - assert(l4_bytes > 0); + //assert(l4_bytes > 0); /* Fill in IPv4-based layer 4 checksum. */ if (packet->tcp != NULL) { diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index 8c23d0d5..4f838d36 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -584,8 +584,8 @@ static struct packet *append_gre(struct packet *packet, struct expression *expr) %token SCM_SEC SCM_NSEC %token REPLACE TRUNCATE INSERT %token IP TCP -%token IHL SOURCE_PORT DST_PORT SEQ_NUM ACK_NUM TCP_HDR_LEN WIN_SIZE URG_POINTER VERSION_IHL; -%token TCP_CHECKSUM DSCP_ESN TOT_LEN IDEN FLAGS_FLAGOFF PROTOCOL IP4_CHECKSUM SRC_IP DEST_IP; +%token IHL SRC_PORT DST_PORT SEQ_NUM ACK_NUM DATA_OFF RESERVED WIN_SIZE URG_POINTER VERSION FRAG_OFF MF_FLAG DF_FLAG RSV_FLAG ECN DSCP FIN_FLAG SYN_FLAG RST_FLAG PSH_FLAG ACK_FLAG URG_FLAG ECE_FLAG CWR_FLAG; +%token DSCP_ESN TOT_LEN IDEN FLAGS_FLAGOFF PROTOCOL SRC_ADDR DST_ADDR TRF_CLASS VERSION_TRF TRF_FLOW FLOW_LABEL PYLD_LEN NEXT_HEADER HOP_LIMIT; %token FLOAT %token INTEGER HEX_INTEGER %token WORD STRING BACK_QUOTED CODE IPV4_ADDR IPV6_ADDR @@ -1474,8 +1474,8 @@ fuzz_field } field_name -: SOURCE_PORT { - $$ = F_SOURCE_PORT; +: SRC_PORT { + $$ = F_SRC_PORT; } | DST_PORT { $$ = F_DST_PORT; @@ -1486,26 +1486,59 @@ field_name | ACK_NUM { $$ = F_ACK_NUM; } -| TCP_HDR_LEN { - $$ = F_TCP_HDR_LEN; +| DATA_OFF { + $$ = F_DATA_OFF; +} +| RESERVED { + $$ = F_RESERVED; } | FLAGS { $$ = F_FLAGS; } +| CWR_FLAG { + $$ = F_CWR_FLAG; +} +| ECE_FLAG { + $$ = F_ECE_FLAG; +} +| URG_FLAG { + $$ = F_URG_FLAG; +} +| ACK_FLAG { + $$ = F_ACK_FLAG; +} +| PSH_FLAG { + $$ = F_PSH_FLAG; +} +| RST_FLAG { + $$ = F_RST_FLAG; +} +| SYN_FLAG { + $$ = F_SYN_FLAG; +} +| FIN_FLAG { + $$ = F_FIN_FLAG; +} | WIN_SIZE { $$ = F_WIN_SIZE; } -| TCP_CHECKSUM { - $$ = F_TCP_CHECKSUM; +| CHECKSUM { + $$ = F_CHECKSUM; } | URG_POINTER { $$ = F_URG_POINTER; } -| VERSION_IHL { - $$ = F_VERSION_IHL; +| VERSION { + $$ = F_VERSION; } -| DSCP_ESN { - $$ = F_DSCP_ESN; +| IHL { + $$ = F_IHL; +} +| DSCP { + $$ = F_DSCP; +} +| ECN { + $$ = F_ECN; } | TOT_LEN { $$ = F_TOT_LEN; @@ -1513,8 +1546,17 @@ field_name | IDEN { $$ = F_IDEN; } -| FLAGS_FLAGOFF { - $$ = F_FLAGS_FLAGOFF; +| RSV_FLAG { + $$ = F_RSV_FLAG; +} +| DF_FLAG { + $$ = F_DF_FLAG; +} +| MF_FLAG { + $$ = F_MF_FLAG; +} +| FRAG_OFF { + $$ = F_FRAG_OFF; } | TTL { $$ = F_TTL; @@ -1522,14 +1564,26 @@ field_name | PROTOCOL { $$ = F_PROTOCOL; } -| IP4_CHECKSUM { - $$ = F_IP_CHECKSUM; +| SRC_ADDR { + $$ = F_SRC_ADDR; +} +| DST_ADDR { + $$ = F_DST_ADDR; +} +| TRF_CLASS { + $$ = F_TRF_CLASS; +} +| FLOW_LABEL { + $$ = F_FLOW_LABEL; +} +| PYLD_LEN { + $$ = F_PYLD_LEN; } -| SRC_IP { - $$ = F_SRC_IP; +| NEXT_HEADER { + $$ = F_NEXT_HEADER; } -| DEST_IP { - $$ = F_DEST_IP; +| HOP_LIMIT { + $$ = F_HOP_LIMIT; } ; From 09c7fa7d4f2ca90f18b2aa240f0499a12f506766 Mon Sep 17 00:00:00 2001 From: AmPaschal Date: Mon, 3 Apr 2023 19:52:46 +0000 Subject: [PATCH 13/17] Updated fuzz terminating signal and added mutation field --- gtests/net/packetdrill/fuzz_options.c | 2 +- gtests/net/packetdrill/fuzz_options.h | 5 +++-- gtests/net/packetdrill/lexer.l | 1 + gtests/net/packetdrill/parser.y | 5 ++++- gtests/net/packetdrill/udp_packet.c | 1 + .../net/tcp/blocking/blocking-accept-fuzz.pkt | 22 ++++++++++++++++--- gtests/net/tcp/blocking/blocking-accept.pkt | 6 +---- 7 files changed, 30 insertions(+), 12 deletions(-) diff --git a/gtests/net/packetdrill/fuzz_options.c b/gtests/net/packetdrill/fuzz_options.c index d133dd3a..e5ab0c5a 100644 --- a/gtests/net/packetdrill/fuzz_options.c +++ b/gtests/net/packetdrill/fuzz_options.c @@ -27,7 +27,7 @@ int fuzz_options_append(struct fuzz_options *fuzz_options, struct fuzz_option *o fuzz_options_grow(fuzz_options, fuzz_options->capacity * 2); } - memcpy(fuzz_options->options + fuzz_options->size, option, fuzz_option_size); + memcpy(fuzz_options->options + fuzz_options->count, option, fuzz_option_size); fuzz_options->size += fuzz_option_size; fuzz_options->count += 1; diff --git a/gtests/net/packetdrill/fuzz_options.h b/gtests/net/packetdrill/fuzz_options.h index d18b9e03..68369f68 100644 --- a/gtests/net/packetdrill/fuzz_options.h +++ b/gtests/net/packetdrill/fuzz_options.h @@ -36,7 +36,8 @@ enum field_name_t { F_PROTOCOL = 15, F_IP_CHECKSUM = 16, F_SRC_IP = 17, - F_DEST_IP = 18 + F_DEST_IP = 18, + F_NXT_HDR = 19 }; @@ -54,7 +55,7 @@ struct fuzz_option { u8 fuzz_field; char *fuzz_value; u8 fuzz_value_byte_count; -} __packed; +}; struct fuzz_value_t { char *value; diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index 5139943b..18ea4a12 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -285,6 +285,7 @@ protocol return PROTOCOL; ip_checksum return IP4_CHECKSUM; src_ip return SRC_IP; dest_ip return DEST_IP; +nxt_hdr return NXT_HDR; diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index 172fba07..03df5fc9 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -585,7 +585,7 @@ static struct packet *append_gre(struct packet *packet, struct expression *expr) %token REPLACE TRUNCATE INSERT %token IP TCP %token IHL SOURCE_PORT DST_PORT SEQ_NUM ACK_NUM TCP_HDR_LEN WIN_SIZE URG_POINTER VERSION_IHL; -%token TCP_CHECKSUM DSCP_ESN TOT_LEN IDEN FLAGS_FLAGOFF PROTOCOL IP4_CHECKSUM SRC_IP DEST_IP; +%token TCP_CHECKSUM DSCP_ESN TOT_LEN IDEN FLAGS_FLAGOFF PROTOCOL IP4_CHECKSUM SRC_IP DEST_IP NXT_HDR; %token FLOAT %token INTEGER HEX_INTEGER %token WORD STRING BACK_QUOTED CODE IPV4_ADDR IPV6_ADDR @@ -1538,6 +1538,9 @@ field_name | DEST_IP { $$ = F_DEST_IP; } +| NXT_HDR { + $$ = F_NXT_HDR; +} ; field_offset diff --git a/gtests/net/packetdrill/udp_packet.c b/gtests/net/packetdrill/udp_packet.c index 9ba1318e..565c46f7 100644 --- a/gtests/net/packetdrill/udp_packet.c +++ b/gtests/net/packetdrill/udp_packet.c @@ -90,6 +90,7 @@ struct packet *new_udp_packet(int address_family, packet->ip_bytes = ip_bytes; if (fuzz_options != NULL) { + // TODO: This is a memory leak. We need to free the fuzz_options struct later packet->fuzz_options = malloc(fuzz_options->size); memcpy(packet->fuzz_options, fuzz_options, fuzz_options->size); } diff --git a/gtests/net/tcp/blocking/blocking-accept-fuzz.pkt b/gtests/net/tcp/blocking/blocking-accept-fuzz.pkt index 8e6b3a9d..761e6fa3 100644 --- a/gtests/net/tcp/blocking/blocking-accept-fuzz.pkt +++ b/gtests/net/tcp/blocking/blocking-accept-fuzz.pkt @@ -1,9 +1,25 @@ +// Test for blocking accept. + +//`../common/defaults.sh` + +// Establish a connection. 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 +0 bind(3, ..., ...) = 0 +0 listen(3, 1) = 0 +0...0.200 accept(3, ..., ...) = 4 -+.1 < S 0:0(0) win 32792 + + +.1 < S 0:0(0) win 32792 +0 > S. 0:0(0) ack 1 -+.1 < . 1:1(0) ack 1 win 257 -+.1 < P. 1:21(20) ack 1 win 257 {rep ipv4 version_ihl 0x35} \ No newline at end of file + +.1 < . 1:1(0) ack 1 win 257 + + +.1 write(4, ..., 200) = 200 + +0 > P. 1:201(200) ack 1 + +.1 < . 201:201(0) ack 1 win 257 + + +.1 < P. 1:11(10) ack 1 win 257 + +0 read(4, ..., 10) = 10 + + +0 close(3) = 0 + +0 > F. 201:201(0) ack 1 + +0 < . 1:1(0) ack 1002 win 257 \ No newline at end of file diff --git a/gtests/net/tcp/blocking/blocking-accept.pkt b/gtests/net/tcp/blocking/blocking-accept.pkt index 58396d90..95c5bc24 100644 --- a/gtests/net/tcp/blocking/blocking-accept.pkt +++ b/gtests/net/tcp/blocking/blocking-accept.pkt @@ -13,8 +13,4 @@ +0 > S. 0:0(0) ack 1 +.1 < . 1:1(0) ack 1 win 257 - +.1 write(4, ..., 200) = 200 - +0 > P. 1:201(200) ack 1 - - +.1 < P. 1:11(10) ack 1 win 257 - +0 read(4, ..., 10) = 10 + \ No newline at end of file From 7955048a5f1dd7c6989536b0e8845f3d841e6a43 Mon Sep 17 00:00:00 2001 From: Ricardo Andres Calvo Mendez Date: Wed, 5 Apr 2023 20:13:02 +0000 Subject: [PATCH 14/17] Remove incorrect Rule in Parser --- gtests/net/packetdrill/parser.y | 3 --- 1 file changed, 3 deletions(-) diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index 2d3e70ff..d85b348f 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -1592,9 +1592,6 @@ field_name | HOP_LIMIT { $$ = F_HOP_LIMIT; } -| NXT_HDR { - $$ = F_NXT_HDR; -} ; field_offset From 3195b91f38bf2f777e477fe316a93b876913c457 Mon Sep 17 00:00:00 2001 From: Ricardo Andres Calvo Mendez Date: Thu, 6 Apr 2023 15:35:16 +0000 Subject: [PATCH 15/17] addes packet statement to fuzz option --- gtests/net/packetdrill/fuzz_options.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gtests/net/packetdrill/fuzz_options.h b/gtests/net/packetdrill/fuzz_options.h index 73b9b150..6a068da6 100644 --- a/gtests/net/packetdrill/fuzz_options.h +++ b/gtests/net/packetdrill/fuzz_options.h @@ -72,7 +72,7 @@ struct fuzz_option { u8 fuzz_field; char *fuzz_value; u8 fuzz_value_byte_count; -}; +} __packed; struct fuzz_value_t { char *value; From 437dbf742704f3dd572b6804253d5f9e45d5767a Mon Sep 17 00:00:00 2001 From: Ricardo Andres Calvo Mendez Date: Wed, 3 May 2023 18:47:32 +0000 Subject: [PATCH 16/17] Ajustes --- gtests/net/packetdrill/fuzz_options.h | 39 ++++++++++++++------------- gtests/net/packetdrill/lexer.l | 1 + gtests/net/packetdrill/parser.y | 5 +++- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/gtests/net/packetdrill/fuzz_options.h b/gtests/net/packetdrill/fuzz_options.h index 6a068da6..26630fbd 100644 --- a/gtests/net/packetdrill/fuzz_options.h +++ b/gtests/net/packetdrill/fuzz_options.h @@ -36,25 +36,26 @@ enum field_name_t { F_WIN_SIZE = 15, F_CHECKSUM = 16, F_URG_POINTER = 17, - F_VERSION = 18, - F_IHL = 19, - F_DSCP = 20, - F_ECN = 21, - F_TOT_LEN = 22, - F_IDEN = 23, - F_RSV_FLAG = 24, - F_DF_FLAG = 25, - F_MF_FLAG = 26, - F_FRAG_OFF = 27, - F_TTL = 28, - F_PROTOCOL = 29, - F_SRC_ADDR = 30, - F_DST_ADDR = 31, - F_TRF_CLASS = 32, - F_FLOW_LABEL = 33, - F_PYLD_LEN = 34, - F_NEXT_HEADER = 35, - F_HOP_LIMIT = 36 + F_UDP_LEN = 18, + F_VERSION = 19, + F_IHL = 20, + F_DSCP = 21, + F_ECN = 22, + F_TOT_LEN = 23, + F_IDEN = 24, + F_RSV_FLAG = 25, + F_DF_FLAG = 26, + F_MF_FLAG = 27, + F_FRAG_OFF = 28, + F_TTL = 29, + F_PROTOCOL = 30, + F_SRC_ADDR = 31, + F_DST_ADDR = 32, + F_TRF_CLASS = 33, + F_FLOW_LABEL = 34, + F_PYLD_LEN = 35, + F_NEXT_HEADER = 36, + F_HOP_LIMIT = 37 }; diff --git a/gtests/net/packetdrill/lexer.l b/gtests/net/packetdrill/lexer.l index c0c0179e..d4824b3d 100644 --- a/gtests/net/packetdrill/lexer.l +++ b/gtests/net/packetdrill/lexer.l @@ -285,6 +285,7 @@ fin_flag return FIN_FLAG; win_size return WIN_SIZE; checksum return CHECKSUM; urg_pointer return URG_POINTER; +udp_len return UDP_LEN; version return VERSION; dscp return DSCP; ecn return ECN; diff --git a/gtests/net/packetdrill/parser.y b/gtests/net/packetdrill/parser.y index d85b348f..ee750efb 100644 --- a/gtests/net/packetdrill/parser.y +++ b/gtests/net/packetdrill/parser.y @@ -584,7 +584,7 @@ static struct packet *append_gre(struct packet *packet, struct expression *expr) %token SCM_SEC SCM_NSEC %token REPLACE TRUNCATE INSERT %token IP TCP -%token IHL SRC_PORT DST_PORT SEQ_NUM ACK_NUM DATA_OFF RESERVED WIN_SIZE URG_POINTER VERSION FRAG_OFF MF_FLAG DF_FLAG RSV_FLAG ECN DSCP FIN_FLAG SYN_FLAG RST_FLAG PSH_FLAG ACK_FLAG URG_FLAG ECE_FLAG CWR_FLAG; +%token IHL UDP_LEN SRC_PORT DST_PORT SEQ_NUM ACK_NUM DATA_OFF RESERVED WIN_SIZE URG_POINTER VERSION FRAG_OFF MF_FLAG DF_FLAG RSV_FLAG ECN DSCP FIN_FLAG SYN_FLAG RST_FLAG PSH_FLAG ACK_FLAG URG_FLAG ECE_FLAG CWR_FLAG; %token DSCP_ESN TOT_LEN IDEN FLAGS_FLAGOFF PROTOCOL SRC_ADDR DST_ADDR TRF_CLASS VERSION_TRF TRF_FLOW FLOW_LABEL PYLD_LEN NEXT_HEADER HOP_LIMIT; %token FLOAT %token INTEGER HEX_INTEGER @@ -1535,6 +1535,9 @@ field_name | URG_POINTER { $$ = F_URG_POINTER; } +| UDP_LEN { + $$ = F_UDP_LEN; +} | VERSION { $$ = F_VERSION; } From f10e770dba9502904045f6460969086381986f42 Mon Sep 17 00:00:00 2001 From: AmPaschal <30577286+AmPaschal@users.noreply.github.com> Date: Fri, 28 Jul 2023 17:37:19 +0000 Subject: [PATCH 17/17] Added sample mutated scripts --- .../blocking-accept-fuzz-template.pkt | 2 -- .../blocking-accept-fuzz.pkt | 2 +- .../blocking-connect-fuzz.pkt | 6 ++-- .../tcp/blocking/blocking-connect-fuzz-2.pkt | 12 -------- gtests/net/tcp/blocking/blocking-read-2.pkt | 28 ------------------- 5 files changed, 3 insertions(+), 47 deletions(-) rename gtests/net/{tcp/blocking => mutation-scripts}/blocking-accept-fuzz-template.pkt (83%) rename gtests/net/{tcp/blocking => mutation-scripts}/blocking-accept-fuzz.pkt (85%) rename gtests/net/{tcp/blocking => mutation-scripts}/blocking-connect-fuzz.pkt (82%) delete mode 100644 gtests/net/tcp/blocking/blocking-connect-fuzz-2.pkt delete mode 100644 gtests/net/tcp/blocking/blocking-read-2.pkt diff --git a/gtests/net/tcp/blocking/blocking-accept-fuzz-template.pkt b/gtests/net/mutation-scripts/blocking-accept-fuzz-template.pkt similarity index 83% rename from gtests/net/tcp/blocking/blocking-accept-fuzz-template.pkt rename to gtests/net/mutation-scripts/blocking-accept-fuzz-template.pkt index 3cc9a69c..628534ad 100644 --- a/gtests/net/tcp/blocking/blocking-accept-fuzz-template.pkt +++ b/gtests/net/mutation-scripts/blocking-accept-fuzz-template.pkt @@ -6,6 +6,4 @@ +.1 < S 0:0(0) win 32792 +0 > S. 0:0(0) ack 1 +.1 < . 1:1(0) ack 1 win 257 -+.1 < P. 1:21(20) ack 1 win 257 -+.1 < P. 1:21(20) ack 1 win 257 +.1 < P. 1:21(20) ack 1 win 257 \ No newline at end of file diff --git a/gtests/net/tcp/blocking/blocking-accept-fuzz.pkt b/gtests/net/mutation-scripts/blocking-accept-fuzz.pkt similarity index 85% rename from gtests/net/tcp/blocking/blocking-accept-fuzz.pkt rename to gtests/net/mutation-scripts/blocking-accept-fuzz.pkt index 761e6fa3..0c7c9270 100644 --- a/gtests/net/tcp/blocking/blocking-accept-fuzz.pkt +++ b/gtests/net/mutation-scripts/blocking-accept-fuzz.pkt @@ -9,7 +9,7 @@ +0 listen(3, 1) = 0 +0...0.200 accept(3, ..., ...) = 4 - +.1 < S 0:0(0) win 32792 + +.1 < S 0:0(0) win 32792 { mut tcp data_offset 0xFF ; ins tcp 20 0x02040000 } +0 > S. 0:0(0) ack 1 +.1 < . 1:1(0) ack 1 win 257 diff --git a/gtests/net/tcp/blocking/blocking-connect-fuzz.pkt b/gtests/net/mutation-scripts/blocking-connect-fuzz.pkt similarity index 82% rename from gtests/net/tcp/blocking/blocking-connect-fuzz.pkt rename to gtests/net/mutation-scripts/blocking-connect-fuzz.pkt index cbe687fe..2499aa6e 100644 --- a/gtests/net/tcp/blocking/blocking-connect-fuzz.pkt +++ b/gtests/net/mutation-scripts/blocking-connect-fuzz.pkt @@ -1,12 +1,10 @@ // Test for blocking connect. -//`../common/defaults.sh` - // Establish a connection. 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 +.1...0.200 connect(3, ..., ...) = 0 - +0 > S 0:0(0) { mut tcp mss } - +.1 < S. 0:0(0) ack 1 win 5792 + +0 > S 0:0(0) + +.1 < S. 0:0(0) ack 1 win 5792 { mut tcp data_offset 0xFF ; ins tcp 20 0x02040000 } +0 > . 1:1(0) ack 1 diff --git a/gtests/net/tcp/blocking/blocking-connect-fuzz-2.pkt b/gtests/net/tcp/blocking/blocking-connect-fuzz-2.pkt deleted file mode 100644 index 3bf734fa..00000000 --- a/gtests/net/tcp/blocking/blocking-connect-fuzz-2.pkt +++ /dev/null @@ -1,12 +0,0 @@ -// Test for blocking connect. - -//`../common/defaults.sh` - -// Establish a connection. - 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 - - +.1...0.200 connect(3, ..., ...) = 0 - - +0 > S 0:0(0) { mut ipv4 ihl; mut tcp mss; trun tcp source_port; trun tcp 34-36; mut ipv4 12-15; ins ipv4 34 2 } - +.1 < S. 0:0(0) ack 1 win 5792 - +0 > . 1:1(0) ack 1 diff --git a/gtests/net/tcp/blocking/blocking-read-2.pkt b/gtests/net/tcp/blocking/blocking-read-2.pkt deleted file mode 100644 index 42cea3e8..00000000 --- a/gtests/net/tcp/blocking/blocking-read-2.pkt +++ /dev/null @@ -1,28 +0,0 @@ -// Test for blocking read. -//--tolerance_usecs=10000 - -//`../common/defaults.sh` - -// Establish a connection. - 0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3 - +0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0 - +0 bind(3, ..., ...) = 0 - +0 listen(3, 1) = 0 - - +.1 < S 0:0(0) win 32792 - +0 > S. 0:0(0) ack 1 - +.1 < . 1:1(0) ack 1 win 257 - +0 accept(3, ..., ...) = 4 - - +0...0.100 read(4, ..., 2000) = 2000 - +.1 < P. 1:2001(2000) ack 1 win 257 - +0 > . 1:1(0) ack 2001 - - +.1...0.200 read(4, ..., 2000) = 2000 - +.1 < P. 2001:4001(2000) ack 1 win 257 - +0 > . 1:1(0) ack 4001 - -// +.1 < P. 4001:6001(2000) ack 1 win 257 -// +0 > . 1:1(0) ack 6001 -// +0...0.000 read(4, ..., 1000) = 1000 -// +0...0.000 read(4, ..., 1000) = 1000