diff options
author | John Thacker <johnthacker@gmail.com> | 2021-12-18 20:23:15 -0500 |
---|---|---|
committer | John Thacker <johnthacker@gmail.com> | 2021-12-18 22:45:02 -0500 |
commit | db10235d689d35ca8b53a1ed108db12b887c4126 (patch) | |
tree | 72d3ecbf7fdeacbe61d91450e7ad735c463f7bfd /ui/text_import.c | |
parent | 8cc527cce334c2e13bbb9a82d94b0ec980b375fd (diff) |
text_import: Handle SCTP and minimum packet lengths
Correctly handle when a minimum packet length forces fragmentation of
SCTP and we are generating dummy SCTP DATA chunk headers: mark fragmentation
in the chunk flags and set the transmission sequence number and
stream sequence number appropriately.
Port from text2pcap commit f8d48662c872813a62c4b87cad4fd5b1afc2fd3c
Part of #16724.
Diffstat (limited to 'ui/text_import.c')
-rw-r--r-- | ui/text_import.c | 63 |
1 files changed, 42 insertions, 21 deletions
diff --git a/ui/text_import.c b/ui/text_import.c index b404ff8abf..192db5fbd2 100644 --- a/ui/text_import.c +++ b/ui/text_import.c @@ -176,7 +176,7 @@ static guint32 hdr_sctp_tag = 0; /* Dummy DATA chunk header */ static gboolean hdr_data_chunk = FALSE; static guint8 hdr_data_chunk_type = 0; -static guint8 hdr_data_chunk_bits = 3; +static guint8 hdr_data_chunk_bits = 0; static guint32 hdr_data_chunk_tsn = 0; static guint16 hdr_data_chunk_sid = 0; static guint16 hdr_data_chunk_ssn = 0; @@ -197,7 +197,7 @@ static guint8 *packet_buf; static guint32 curr_offset = 0; static guint32 max_offset = WTAP_MAX_PACKET_SIZE_STANDARD; static guint32 packet_start = 0; -static void start_new_packet (void); +static void start_new_packet(gboolean); /* This buffer contains strings present before the packet offset 0 */ #define PACKET_PREAMBLE_MAX_LEN 2048 @@ -385,7 +385,7 @@ write_byte (const char *str) packet_buf[curr_offset] = (guint8) num; curr_offset ++; if (curr_offset >= max_offset) /* packet full */ - start_new_packet(); + start_new_packet(TRUE); } /*---------------------------------------------------------------------- @@ -415,9 +415,14 @@ number_of_padding_bytes (guint32 length) /*---------------------------------------------------------------------- * Write current packet out + * + * @param cont [IN] TRUE if a packet is being written because the max frame + * length was reached, and the original packet from the input file is + * continued in a later frame. Used to set fragmentation fields in dummy + * headers (currently only implemented for SCTP; IPv4 could be added later.) */ static void -write_current_packet (void) +write_current_packet(gboolean cont) { int prefix_length = 0; int proto_length = 0; @@ -558,6 +563,13 @@ write_current_packet (void) /* Compute DATA chunk header and append padding */ if (hdr_data_chunk) { + hdr_data_chunk_bits = 0; + if (packet_start == 0) { + hdr_data_chunk_bits |= 0x02; + } + if (!cont) { + hdr_data_chunk_bits |= 0x01; + } HDR_DATA_CHUNK.type = hdr_data_chunk_type; HDR_DATA_CHUNK.bits = hdr_data_chunk_bits; HDR_DATA_CHUNK.length = g_htons(curr_offset + sizeof(HDR_DATA_CHUNK)); @@ -565,7 +577,10 @@ write_current_packet (void) HDR_DATA_CHUNK.sid = g_htons(hdr_data_chunk_sid); HDR_DATA_CHUNK.ssn = g_htons(hdr_data_chunk_ssn); HDR_DATA_CHUNK.ppid = g_htonl(hdr_data_chunk_ppid); - + hdr_data_chunk_tsn++; + if (!cont) { + hdr_data_chunk_ssn++; + } padding_length = number_of_padding_bytes(curr_offset); for (i=0; i<padding_length; i++) packet_buf[prefix_length+curr_offset+i] = 0; @@ -901,7 +916,7 @@ void parse_data(guchar* start_field, guchar* end_field, enum data_encoding encod parse_plain_data(&start_field, end_field, &dest, dest_end, table, NULL); curr_offset = (int) (dest - packet_buf); if (curr_offset == max_offset) { - write_current_packet(); + write_current_packet(TRUE); dest = &packet_buf[curr_offset]; } else break; @@ -1047,7 +1062,7 @@ void parse_seqno(const guchar* start_field, const guchar* end_field) { } void flush_packet(void) { - write_current_packet(); + write_current_packet(FALSE); } /*---------------------------------------------------------------------- @@ -1106,15 +1121,21 @@ parse_preamble (void) /*---------------------------------------------------------------------- * Start a new packet + * + * @param cont [IN] TRUE if a new packet is starting because the max frame + * length was reached on the current packet, and the original packet from the + * input file is continued in a later frame. Passed to write_current_packet, + * where it is used to set fragmentation fields in dummy headers (currently + * only implemented for SCTP; IPv4 could be added later.) */ static void -start_new_packet (void) +start_new_packet(gboolean cont) { if (debug>=1) - fprintf(stderr, "Start new packet\n"); + fprintf(stderr, "Start new packet (cont = %s).\n", cont ? "TRUE" : "FALSE"); /* Write out the current packet, if required */ - write_current_packet(); + write_current_packet(cont); /* Ensure we parse the packet preamble as it may contain the time */ /* THIS IMPLIES A STATE TRANSITION OUTSIDE THE STATE MACHINE */ @@ -1167,21 +1188,21 @@ parse_token (token_t token, char *str) break; case T_OFFSET: num = parse_num(str, TRUE); - if (num==0) { + if (num == 0) { /* New packet starts here */ - start_new_packet(); + start_new_packet(FALSE); state = READ_OFFSET; } break; case T_BYTE: if (offset_base == 0) { - start_new_packet(); + start_new_packet(FALSE); write_byte(str); state = READ_BYTE; } break; case T_EOF: - write_current_packet(); + write_current_packet(FALSE); break; default: break; @@ -1199,9 +1220,9 @@ parse_token (token_t token, char *str) break; case T_OFFSET: num = parse_num(str, TRUE); - if (num==0) { + if (num == 0) { /* New packet starts here */ - start_new_packet(); + start_new_packet(FALSE); packet_start = 0; state = READ_OFFSET; } else if ((num - packet_start) != curr_offset) { @@ -1222,7 +1243,7 @@ parse_token (token_t token, char *str) if (debug>=1) fprintf(stderr, "Inconsistent offset. Expecting %0X, got %0X. Ignoring rest of packet\n", curr_offset, num); - write_current_packet(); + write_current_packet(FALSE); state = INIT; } } else @@ -1235,7 +1256,7 @@ parse_token (token_t token, char *str) } break; case T_EOF: - write_current_packet(); + write_current_packet(FALSE); break; default: break; @@ -1259,7 +1280,7 @@ parse_token (token_t token, char *str) state = START_OF_LINE; break; case T_EOF: - write_current_packet(); + write_current_packet(FALSE); break; default: break; @@ -1282,7 +1303,7 @@ parse_token (token_t token, char *str) state = START_OF_LINE; break; case T_EOF: - write_current_packet(); + write_current_packet(FALSE); break; default: break; @@ -1296,7 +1317,7 @@ parse_token (token_t token, char *str) state = START_OF_LINE; break; case T_EOF: - write_current_packet(); + write_current_packet(FALSE); break; default: break; |