Fixes the erratic report of TCP payload length in 'batctl tcpdump'.
Previously TCP header length size was considered fixed, while
this is actually not the case given the variable length (or no
presence at all) of the options field.

Signed-off-by: Marco Dalla Torre <[email protected]>
---
 tcpdump.c | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/tcpdump.c b/tcpdump.c
index 7e0987b..e6f8f7d 100644
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -194,6 +194,7 @@ static void dump_ip(unsigned char *packet_buff, ssize_t 
buff_len, int time_print
        struct tcphdr *tcphdr;
        struct udphdr *udphdr, *tmp_udphdr;
        struct icmphdr *icmphdr;
+       uint16_t tcp_header_len;
 
        iphdr = (struct iphdr *)packet_buff;
        LEN_CHECK((size_t)buff_len, (size_t)(iphdr->ihl * 4), "IP");
@@ -257,16 +258,18 @@ static void dump_ip(unsigned char *packet_buff, ssize_t 
buff_len, int time_print
 
                break;
        case IPPROTO_TCP:
-               LEN_CHECK((size_t)buff_len - (iphdr->ihl * 4), sizeof(struct 
tcphdr), "TCP");
-
                tcphdr = (struct tcphdr *)(packet_buff + (iphdr->ihl * 4));
+               tcp_header_len = tcphdr->doff * 4;
+               LEN_CHECK((size_t)buff_len - (iphdr->ihl * 4),
+                         (size_t)tcp_header_len, "TCP");
+
                printf("IP %s.%i > ", inet_ntoa(*(struct in_addr 
*)&iphdr->saddr), ntohs(tcphdr->source));
                printf("%s.%i: TCP, flags [%c%c%c%c%c%c], length %zu\n",
                        inet_ntoa(*(struct in_addr *)&iphdr->daddr), 
ntohs(tcphdr->dest),
                        (tcphdr->fin ? 'F' : '.'), (tcphdr->syn ? 'S' : '.'),
                        (tcphdr->rst ? 'R' : '.'), (tcphdr->psh ? 'P' : '.'),
                        (tcphdr->ack ? 'A' : '.'), (tcphdr->urg ? 'U' : '.'),
-                       (size_t)buff_len - (iphdr->ihl * 4) - sizeof(struct 
tcphdr));
+                       (size_t)buff_len - (iphdr->ihl * 4) - tcp_header_len);
                break;
        case IPPROTO_UDP:
                LEN_CHECK((size_t)buff_len - (iphdr->ihl * 4), sizeof(struct 
udphdr), "UDP");
-- 
1.8.3.2

Reply via email to