diff options
author | Thomas Winter <Thomas.Winter@alliedtelesis.co.nz> | 2023-08-29 13:14:27 +1200 |
---|---|---|
committer | Ivan Nardi <12729895+IvanNardi@users.noreply.github.com> | 2023-09-12 13:12:14 +0200 |
commit | a5f0cb7e6c4cfb45666876b79f23f2ec7a56a870 (patch) | |
tree | 1d28f046b8010caa89f94113217337f44d5f84cc /src/lib/protocols/tftp.c | |
parent | 7263562514ac8c98ca923b98cc89d4c10bbdb30f (diff) |
tftp: check incrementation for DATA and ACK packets
The 2 bytes following the opcode for DATA and ACK packets are the
block number and this should be incrementing every packet.
We should check to see that this is occurring otherwise false matches
can occur, eg L2TPv3 over UDP matches the DATA opcode but the next two
bytes are always zero.
Remove the DATA max block size assumption since this can be false if
the blksize option is used to increase it.
Fixes #2070
Diffstat (limited to 'src/lib/protocols/tftp.c')
-rw-r--r-- | src/lib/protocols/tftp.c | 22 |
1 files changed, 21 insertions, 1 deletions
diff --git a/src/lib/protocols/tftp.c b/src/lib/protocols/tftp.c index 4b505c8fd..9c8d9b6d3 100644 --- a/src/lib/protocols/tftp.c +++ b/src/lib/protocols/tftp.c @@ -40,6 +40,8 @@ static void ndpi_search_tftp(struct ndpi_detection_module_struct *ndpi_struct, struct ndpi_flow_struct *flow) { struct ndpi_packet_struct *packet = &ndpi_struct->packet; + u_int16_t block_num; + u_int16_t prev_num; NDPI_LOG_DBG(ndpi_struct, "search TFTP\n"); @@ -137,11 +139,20 @@ static void ndpi_search_tftp(struct ndpi_detection_module_struct *ndpi_struct, case 0x03: /* Data (DATA) */ - if (packet->payload_packet_len > 4 /* DATA header size */ + 512 /* max. block size */) + if (packet->payload_packet_len <= 4 /* min DATA header size */) { NDPI_EXCLUDE_PROTO(ndpi_struct, flow); return; } + /* First 2 bytes were opcode so next 16 bits are the block number. + * This should increment every packet but give some leeway for midstream and packet loss. */ + block_num = ntohs(get_u_int16_t(packet->payload, 2)); + prev_num = flow->l4.udp.tftp_data_num; + flow->l4.udp.tftp_data_num = block_num; + if (!(block_num == prev_num + 1 || (prev_num != 0 && block_num == prev_num))) + { + return; + } break; case 0x04: @@ -151,6 +162,15 @@ static void ndpi_search_tftp(struct ndpi_detection_module_struct *ndpi_struct, NDPI_EXCLUDE_PROTO(ndpi_struct, flow); return; } + /* First 2 bytes were opcode so next 16 bits are the block number. + * This should increment every packet but give some leeway for midstream and packet loss. */ + block_num = ntohs(get_u_int16_t(packet->payload, 2)); + prev_num = flow->l4.udp.tftp_ack_num; + flow->l4.udp.tftp_ack_num = block_num; + if (!(block_num == prev_num + 1 || (block_num == prev_num))) + { + return; + } break; case 0x05: |