From 4c9a2df09bac0bd6dab0831da135892b51c12053 Mon Sep 17 00:00:00 2001 From: Francois-Xavier Le Bail Date: Wed, 20 Sep 2023 08:44:09 +0200 Subject: [PATCH] IP: Enable TSO (TCP Segmentation Offload) support It's a follow-up to c8623960f050cb81c12b31107070021f27f14b18. The support is now enabled by default. No more "#ifdef GUESS_TSO". Output example: length 2016 [was 0, presumed TSO] Add a test file with presumed TSO. (From http://cloudshark.org/captures/25e40f73bc1c, found via https://osqa-ask.wireshark.org/questions/16279/) Use ND_ICHECKMSG_U() to test an invalid total length < header length. Output example: [total length 19 < 20] (invalid) Add a test file for this case. Move ND_TCHECK_SIZE(ip) after the new tests. Add a const qualifier for the ip_print() parameter 'length'. Update the man page. (backported from commit 3465ec4a0c94f3abe774dfdb9874f966403e20ce) --- netdissect.h | 2 +- print-ip.c | 30 +++++++++++-------------- tcpdump.1.in | 3 ++- tests/TESTLIST | 2 ++ tests/ipv4_invalid_total_length_2.out | 1 + tests/ipv4_invalid_total_length_2.pcap | Bin 0 -> 138 bytes tests/ipv4_tcp_http_xml_tso.out | 14 ++++++++++++ tests/ipv4_tcp_http_xml_tso.pcap | Bin 0 -> 2070 bytes 8 files changed, 33 insertions(+), 19 deletions(-) create mode 100644 tests/ipv4_invalid_total_length_2.out create mode 100644 tests/ipv4_invalid_total_length_2.pcap create mode 100644 tests/ipv4_tcp_http_xml_tso.out create mode 100644 tests/ipv4_tcp_http_xml_tso.pcap diff --git a/netdissect.h b/netdissect.h index e49fef42a..36efe1856 100644 --- a/netdissect.h +++ b/netdissect.h @@ -657,7 +657,7 @@ extern void igmp_print(netdissect_options *, const u_char *, u_int); extern void igrp_print(netdissect_options *, const u_char *, u_int); extern void ip6_print(netdissect_options *, const u_char *, u_int); extern void ipN_print(netdissect_options *, const u_char *, u_int); -extern void ip_print(netdissect_options *, const u_char *, u_int); +extern void ip_print(netdissect_options *, const u_char *, const u_int); extern void ipcomp_print(netdissect_options *, const u_char *); extern void ipx_netbios_print(netdissect_options *, const u_char *, u_int); extern void ipx_print(netdissect_options *, const u_char *, u_int); diff --git a/print-ip.c b/print-ip.c index 62daa81a4..f04353d31 100644 --- a/print-ip.c +++ b/print-ip.c @@ -318,7 +318,7 @@ static const struct tok ip_frag_values[] = { void ip_print(netdissect_options *ndo, const u_char *bp, - u_int length) + const u_int length) { const struct ip *ip; u_int off; @@ -329,6 +329,7 @@ ip_print(netdissect_options *ndo, uint16_t sum, ip_sum; const char *p_name; int truncated = 0; + int presumed_tso = 0; ndo->ndo_protocol = "ip"; ip = (const struct ip *)bp; @@ -350,22 +351,14 @@ ip_print(netdissect_options *ndo, nd_print_invalid(ndo); ND_PRINT(" "); } - ND_TCHECK_SIZE(ip); - if (len < hlen) { -#ifdef GUESS_TSO - if (len) { - ND_PRINT("bad-len %u", len); - return; - } else { - /* we guess that it is a TSO send */ - len = length; - } -#else - ND_PRINT("bad-len %u", len); - return; -#endif /* GUESS_TSO */ - } + if (len == 0) { + /* we guess that it is a TSO send */ + len = length; + presumed_tso = 1; + } else + ND_ICHECKMSG_U("total length", len, <, hlen); + ND_TCHECK_SIZE(ip); /* * Cut off the snapshot length to the end of the IP payload. */ @@ -418,7 +411,10 @@ ip_print(netdissect_options *ndo, tok2str(ipproto_values, "unknown", ip_proto), ip_proto); - ND_PRINT(", length %u", GET_BE_U_2(ip->ip_len)); + if (presumed_tso) + ND_PRINT(", length %u [was 0, presumed TSO]", length); + else + ND_PRINT(", length %u", GET_BE_U_2(ip->ip_len)); if ((hlen - sizeof(struct ip)) > 0) { ND_PRINT(", options ("); diff --git a/tcpdump.1.in b/tcpdump.1.in index fc9d47062..4919e0448 100644 --- a/tcpdump.1.in +++ b/tcpdump.1.in @@ -1267,7 +1267,8 @@ part of a fragmented datagram or not. and \fBDF\fP is reported if F is set. If neither are set, \fB.\fP is reported. \fIproto\fP is the protocol ID field. -\fIlength\fP is the total length field. +\fIlength\fP is the total length field; if the packet is a presumed TSO +(TCP Segmentation Offload) send, [was 0, presumed TSO] is reported. \fIoptions\fP are the IP options, if any. .LP Next, for TCP and UDP packets, the source and destination IP addresses diff --git a/tests/TESTLIST b/tests/TESTLIST index b820d480c..1bd08d1e6 100644 --- a/tests/TESTLIST +++ b/tests/TESTLIST @@ -309,6 +309,8 @@ ipv4_invalid_length ipv4_invalid_length.pcap ipv4_invalid_length.out -v ipv4_invalid_hdr_length ipv4_invalid_hdr_length.pcap ipv4_invalid_hdr_length.out -v ipv4_invalid_total_length ipv4_invalid_total_length.pcap ipv4_invalid_total_length.out -v ipv4_tcp_http_xml ipv4_tcp_http_xml.pcap ipv4_tcp_http_xml.out -v +ipv4_invalid_total_length_2 ipv4_invalid_total_length_2.pcap ipv4_invalid_total_length_2.out -v +ipv4_tcp_http_xml_tso ipv4_tcp_http_xml_tso.pcap ipv4_tcp_http_xml_tso.out -v #IPv6 tests ipv6-bad-version ipv6-bad-version.pcap ipv6-bad-version.out diff --git a/tests/ipv4_invalid_total_length_2.out b/tests/ipv4_invalid_total_length_2.out new file mode 100644 index 000000000..d5136c004 --- /dev/null +++ b/tests/ipv4_invalid_total_length_2.out @@ -0,0 +1 @@ + 1 08:57:44.621711 IP [total length 19 < 20] (invalid) diff --git a/tests/ipv4_invalid_total_length_2.pcap b/tests/ipv4_invalid_total_length_2.pcap new file mode 100644 index 0000000000000000000000000000000000000000..c9111be3d91c8507ede404c8e21920b91071b46b GIT binary patch literal 138 zcmca|c+)~A1{MYcU}0bcayW8dr1aNtG9&@nAbj9jlNq!22j4}uv5PqvTp1XIKQ3cn za1eBz(sP;foUUU1oEh60Oc@;VPET6Jr~o#Cfq{{^yu6&fB)K4^G`D~`zbG9j1d`HZ Xxd1ehfq{pCi-Dv2z|*gGh1Pok4T2)$ literal 0 HcmV?d00001 diff --git a/tests/ipv4_tcp_http_xml_tso.out b/tests/ipv4_tcp_http_xml_tso.out new file mode 100644 index 000000000..16b711058 --- /dev/null +++ b/tests/ipv4_tcp_http_xml_tso.out @@ -0,0 +1,14 @@ + 1 19:50:14.587897 IP (tos 0x0, ttl 128, id 17097, offset 0, flags [DF], proto TCP (6), length 2016 [was 0, presumed TSO], bad cksum 0 (->d8df)!) + 30.7.181.121.39556 > 199.43.68.163.8080: Flags [P.], cksum 0xdf55 (incorrect -> 0x9cf2), seq 1891338696:1891340672, ack 727404759, win 256, length 1976: HTTP, length: 1976 + POST http://gwm-ml-a2.wsodqa.com//research/module-loader/module-loader.asp?user_id=test HTTP/1.1 + Content-Type: text/xml; charset=utf-8 + SOAPAction: "" + User-Agent: Axis/1.4-LISA + lisaFrameRoot: true + lisaFrameRemoteIP: 169.254.169.30 + lisaFrameID: 3ae1f0b0-0293-11e2-aa16-78e7d164f804 + Host: gwm-ml-a2.wsodqa.com + Proxy-Connection: Keep-Alive + Content-Length: 1607 + + false0falsefalseRUN_RIReviewMarketsUI_RevMktNews/RIReviewMarketsUI/RevMktNews.aspxRUN_RIReviewMarketsUI_RevMktNewsFullStory/RIReviewMarketsUI/RevMktNewsFullStory.aspxfalsefalsefalsefalseRUN_RIStocksUI_RIStocksOverview/RIStocksUI/RIStocksOverview.aspxRUN_RIMutualFundsUI_RIMFOverview/RIMutualFundsUI/RIMFOverview.aspxRUN_RIEtfsUI_RIEtfsOverview/RIEtfsUI/RIEtfsOverview.aspxRUN_RIOptionsUI_RIOptionsOverview/RIOptionsUI/RIOptionsOverview.aspxfalsefalsefalsefalsefalse diff --git a/tests/ipv4_tcp_http_xml_tso.pcap b/tests/ipv4_tcp_http_xml_tso.pcap new file mode 100644 index 0000000000000000000000000000000000000000..976a0afa3dd8fbc90931296dfb7f3295478ea951 GIT binary patch literal 2070 zcmcIlJ#5=X6sC)y4uojWl(Jk6@<>VkiE^SN$962liUr96iexY@;*&(^c*pRLqO@hm z(yep0AZw=rojP_%G6o2cF=MxmMYi-PO0r}dPzFZ;q4yrY_kHiZJKlZ#`;XT@Xg9Rk z@9S4hTT{+|KR;=VzueURUDqa$rrlcqeQos52k(n^Q#(+Iz4!OE7e8v+o%KJ*Z#VYe zyn6Z5Z{c6RzT0@(_|&+)rhRT}TH~a3s`sS~%Lw(7zznEK3RWVx_ncTA9v~Ef01|cj zDBxa9!K9pc5G{Ka5#equAUgBCiUc9`qtnv{ax5pGd%&3lCe71v2xVQuNTN|d@9CXB zi3G?>EW74TKG!;_HmV)zb5_<3BcE$4HnZAOnPt5?@`WNRna8zOHJ_utAcqkNpvk#< zE29_|gAi~DwMJQYw(eSm&61V=7wrW|ZNID+2{>K*nQhvIyG7G+pkNZ>Y?<3Tu|++z#@$mJiqvC=WqbDNK~pSjCtwmgw{$Ai`3w(zwN= z9!d=a(0( zkTWr@cupW82;<0~=&GCup1U~dNj<6Us}YonD(16Lx;Pj$sSMmMp#m_Pdbm$L;o>7s z(;tgNO^q;0 zaTrb5zgglirnDt_H2zktdBSB;H1F^l##t(@80U3pY^~6kH*{g1YGR$iWUXqMd7{43 zbQPDUID@IhTZUbp-35VqEMr0sW9DTl^~0+bmT*eu9Jf;9Kz1|k)VP{GgDBcX$V%dq zFg={T!$iE&wl!T<_-ET(R)ivAMRtmxj7$)uD(M&QRq|Zh`D@&FtBY;QkNz CHp#32 literal 0 HcmV?d00001