From fcb3c8528609888ef76ba7c176f78cf3800340ea Mon Sep 17 00:00:00 2001 From: lijia Date: Thu, 18 Apr 2024 16:31:39 +0800 Subject: [PATCH] print inner most layer for tunnel if has -g argument --- src/print-ether.c | 412 +++++++++++++++++++++++++++++----------------- src/tcpdump.c | 2 +- 2 files changed, 263 insertions(+), 151 deletions(-) diff --git a/src/print-ether.c b/src/print-ether.c index 5583fc6..c2e7a7e 100644 --- a/src/print-ether.c +++ b/src/print-ether.c @@ -32,63 +32,62 @@ #include "ether.h" const struct tok ethertype_values[] = { - { ETHERTYPE_IP, "IPv4" }, - { ETHERTYPE_MPLS, "MPLS unicast" }, - { ETHERTYPE_MPLS_MULTI, "MPLS multicast" }, - { ETHERTYPE_IPV6, "IPv6" }, - { ETHERTYPE_8021Q, "802.1Q" }, - { ETHERTYPE_8021Q9100, "802.1Q-9100" }, - { ETHERTYPE_8021QinQ, "802.1Q-QinQ" }, - { ETHERTYPE_8021Q9200, "802.1Q-9200" }, - { ETHERTYPE_VMAN, "VMAN" }, - { ETHERTYPE_PUP, "PUP" }, - { ETHERTYPE_ARP, "ARP"}, - { ETHERTYPE_REVARP, "Reverse ARP"}, - { ETHERTYPE_NS, "NS" }, - { ETHERTYPE_SPRITE, "Sprite" }, - { ETHERTYPE_TRAIL, "Trail" }, - { ETHERTYPE_MOPDL, "MOP DL" }, - { ETHERTYPE_MOPRC, "MOP RC" }, - { ETHERTYPE_DN, "DN" }, - { ETHERTYPE_LAT, "LAT" }, - { ETHERTYPE_SCA, "SCA" }, - { ETHERTYPE_TEB, "TEB" }, - { ETHERTYPE_LANBRIDGE, "Lanbridge" }, - { ETHERTYPE_DECDNS, "DEC DNS" }, - { ETHERTYPE_DECDTS, "DEC DTS" }, - { ETHERTYPE_VEXP, "VEXP" }, - { ETHERTYPE_VPROD, "VPROD" }, - { ETHERTYPE_ATALK, "Appletalk" }, - { ETHERTYPE_AARP, "Appletalk ARP" }, - { ETHERTYPE_IPX, "IPX" }, - { ETHERTYPE_PPP, "PPP" }, - { ETHERTYPE_MPCP, "MPCP" }, - { ETHERTYPE_SLOW, "Slow Protocols" }, - { ETHERTYPE_PPPOED, "PPPoE D" }, - { ETHERTYPE_PPPOES, "PPPoE S" }, - { ETHERTYPE_EAPOL, "EAPOL" }, - { ETHERTYPE_RRCP, "RRCP" }, - { ETHERTYPE_MS_NLB_HB, "MS NLB heartbeat" }, - { ETHERTYPE_JUMBO, "Jumbo" }, - { ETHERTYPE_LOOPBACK, "Loopback" }, - { ETHERTYPE_ISO, "OSI" }, - { ETHERTYPE_GRE_ISO, "GRE-OSI" }, - { ETHERTYPE_CFM_OLD, "CFM (old)" }, - { ETHERTYPE_CFM, "CFM" }, - { ETHERTYPE_IEEE1905_1, "IEEE1905.1" }, - { ETHERTYPE_LLDP, "LLDP" }, - { ETHERTYPE_TIPC, "TIPC"}, - { ETHERTYPE_GEONET_OLD, "GeoNet (old)"}, - { ETHERTYPE_GEONET, "GeoNet"}, - { ETHERTYPE_CALM_FAST, "CALM FAST"}, - { ETHERTYPE_AOE, "AoE" }, - { ETHERTYPE_MEDSA, "MEDSA" }, - { 0, NULL} -}; + {ETHERTYPE_IP, "IPv4"}, + {ETHERTYPE_MPLS, "MPLS unicast"}, + {ETHERTYPE_MPLS_MULTI, "MPLS multicast"}, + {ETHERTYPE_IPV6, "IPv6"}, + {ETHERTYPE_8021Q, "802.1Q"}, + {ETHERTYPE_8021Q9100, "802.1Q-9100"}, + {ETHERTYPE_8021QinQ, "802.1Q-QinQ"}, + {ETHERTYPE_8021Q9200, "802.1Q-9200"}, + {ETHERTYPE_VMAN, "VMAN"}, + {ETHERTYPE_PUP, "PUP"}, + {ETHERTYPE_ARP, "ARP"}, + {ETHERTYPE_REVARP, "Reverse ARP"}, + {ETHERTYPE_NS, "NS"}, + {ETHERTYPE_SPRITE, "Sprite"}, + {ETHERTYPE_TRAIL, "Trail"}, + {ETHERTYPE_MOPDL, "MOP DL"}, + {ETHERTYPE_MOPRC, "MOP RC"}, + {ETHERTYPE_DN, "DN"}, + {ETHERTYPE_LAT, "LAT"}, + {ETHERTYPE_SCA, "SCA"}, + {ETHERTYPE_TEB, "TEB"}, + {ETHERTYPE_LANBRIDGE, "Lanbridge"}, + {ETHERTYPE_DECDNS, "DEC DNS"}, + {ETHERTYPE_DECDTS, "DEC DTS"}, + {ETHERTYPE_VEXP, "VEXP"}, + {ETHERTYPE_VPROD, "VPROD"}, + {ETHERTYPE_ATALK, "Appletalk"}, + {ETHERTYPE_AARP, "Appletalk ARP"}, + {ETHERTYPE_IPX, "IPX"}, + {ETHERTYPE_PPP, "PPP"}, + {ETHERTYPE_MPCP, "MPCP"}, + {ETHERTYPE_SLOW, "Slow Protocols"}, + {ETHERTYPE_PPPOED, "PPPoE D"}, + {ETHERTYPE_PPPOES, "PPPoE S"}, + {ETHERTYPE_EAPOL, "EAPOL"}, + {ETHERTYPE_RRCP, "RRCP"}, + {ETHERTYPE_MS_NLB_HB, "MS NLB heartbeat"}, + {ETHERTYPE_JUMBO, "Jumbo"}, + {ETHERTYPE_LOOPBACK, "Loopback"}, + {ETHERTYPE_ISO, "OSI"}, + {ETHERTYPE_GRE_ISO, "GRE-OSI"}, + {ETHERTYPE_CFM_OLD, "CFM (old)"}, + {ETHERTYPE_CFM, "CFM"}, + {ETHERTYPE_IEEE1905_1, "IEEE1905.1"}, + {ETHERTYPE_LLDP, "LLDP"}, + {ETHERTYPE_TIPC, "TIPC"}, + {ETHERTYPE_GEONET_OLD, "GeoNet (old)"}, + {ETHERTYPE_GEONET, "GeoNet"}, + {ETHERTYPE_CALM_FAST, "CALM FAST"}, + {ETHERTYPE_AOE, "AoE"}, + {ETHERTYPE_MEDSA, "MEDSA"}, + {0, NULL}}; static inline void ether_hdr_print(netdissect_options *ndo, - const u_char *bp, u_int length) + const u_char *bp, u_int length) { register const struct ether_header *ep; uint16_t length_type; @@ -96,58 +95,149 @@ ether_hdr_print(netdissect_options *ndo, ep = (const struct ether_header *)bp; ND_PRINT((ndo, "%s > %s", - etheraddr_string(ndo, ESRC(ep)), - etheraddr_string(ndo, EDST(ep)))); + etheraddr_string(ndo, ESRC(ep)), + etheraddr_string(ndo, EDST(ep)))); length_type = EXTRACT_16BITS(&ep->ether_length_type); - if (!ndo->ndo_qflag) { - if (length_type <= ETHERMTU) { - ND_PRINT((ndo, ", 802.3")); + if (!ndo->ndo_qflag) + { + if (length_type <= ETHERMTU) + { + ND_PRINT((ndo, ", 802.3")); length = length_type; - } else - ND_PRINT((ndo, ", ethertype %s (0x%04x)", - tok2str(ethertype_values,"Unknown", length_type), - length_type)); - } else { - if (length_type <= ETHERMTU) { - ND_PRINT((ndo, ", 802.3")); + } + else + ND_PRINT((ndo, ", ethertype %s (0x%04x)", + tok2str(ethertype_values, "Unknown", length_type), + length_type)); + } + else + { + if (length_type <= ETHERMTU) + { + ND_PRINT((ndo, ", 802.3")); length = length_type; - } else - ND_PRINT((ndo, ", %s", tok2str(ethertype_values,"Unknown Ethertype (0x%04x)", length_type))); - } + } + else + ND_PRINT((ndo, ", %s", tok2str(ethertype_values, "Unknown Ethertype (0x%04x)", length_type))); + } ND_PRINT((ndo, ", length %u: ", length)); } +#include "stream_base.h" +#include "mesa_net.h" +extern int greedy_seek_flag; +extern const void *MESA_jump_layer_greedy(const void *raw_data, int raw_layer_type, int expect_layer_type); +extern const void *MESA_jump_layer(const void *raw_data, int raw_layer_type, int expect_layer_type); + +static inline void *addr_min(void *a, void *b) +{ + if(a && b){ + if((char *)a <= (char *)b) + { + return a; + }else{ + return b; + } + } + if(a){ + return a; + } + if(b){ + return b; + } + return NULL; +} + +static inline void *addr_max(void *a, void *b) +{ + if(a && b){ + if((char *)a > (char *)b) + { + return a; + }else{ + return b; + } + } + if(a){ + return a; + } + if(b){ + return b; + } + + return NULL; +} + +int seek_to_inner_most_layer(netdissect_options *ndo, const u_char *pkt, u_int length) +{ + struct mesa_ip4_hdr *ip4hdr, *ip4hdr_greedy; + struct mesa_ip6_hdr *ip6hdr, *ip6hdr_greedy; + void *outer_most_hdr; + void *inner_most_hdr; + + ip4hdr = (struct mesa_ip4_hdr *)MESA_jump_layer(pkt, ADDR_TYPE_MAC, __ADDR_TYPE_IP_PAIR_V4); + ip6hdr = (struct mesa_ip6_hdr *)MESA_jump_layer(pkt, ADDR_TYPE_MAC, __ADDR_TYPE_IP_PAIR_V6); + ip4hdr_greedy = (struct mesa_ip4_hdr *)MESA_jump_layer_greedy(pkt, ADDR_TYPE_MAC, __ADDR_TYPE_IP_PAIR_V4); + ip6hdr_greedy = (struct mesa_ip6_hdr *)MESA_jump_layer_greedy(pkt, ADDR_TYPE_MAC, __ADDR_TYPE_IP_PAIR_V6); + + outer_most_hdr = addr_min(ip4hdr, ip6hdr); + inner_most_hdr = addr_max(ip4hdr_greedy, ip6hdr_greedy); + + if ((char *)inner_most_hdr > (char *)outer_most_hdr) + { + if (inner_most_hdr == (void *)ip6hdr_greedy) + { + ND_PRINT((ndo, " --> ")); + ip6_print(ndo, (const u_char *)ip6hdr_greedy, ntohs(ip6hdr_greedy->ip6_payload_len) + sizeof(struct mesa_ip6_hdr)); + return 1; + } + if (inner_most_hdr == (void *)ip4hdr_greedy) + { + ND_PRINT((ndo, " --> ")); + ip_print(ndo, (const u_char *)ip4hdr_greedy, ntohs(ip4hdr_greedy->ip_len)); + return 1; + } + + } + + return 0; +} + /* * Print an Ethernet frame. * This might be encapsulated within another frame; we might be passed * a pointer to a function that can print header information for that * frame's protocol, and an argument to pass to that function. */ -u_int -ether_print(netdissect_options *ndo, - const u_char *p, u_int length, u_int caplen, - void (*print_encap_header)(netdissect_options *ndo, const u_char *), const u_char *encap_header_arg) +u_int ether_print(netdissect_options *ndo, + const u_char *p, u_int length, u_int caplen, + void (*print_encap_header)(netdissect_options *ndo, const u_char *), const u_char *encap_header_arg) { const struct ether_header *ep; u_int orig_length; u_short length_type; u_int hdrlen; int llc_hdrlen; + const u_char *raw_ethhdr = p; + u_int raw_ethlen = length; ep = (const struct ether_header *)p; - - if (caplen < ETHER_HDRLEN) { + + if (caplen < ETHER_HDRLEN) + { ND_PRINT((ndo, "[|ether]")); return (caplen); } - if (length < ETHER_HDRLEN) { + if (length < ETHER_HDRLEN) + { ND_PRINT((ndo, "[|ether]")); return (length); } - if (ndo->ndo_eflag) { + if (ndo->ndo_eflag) + { if (print_encap_header != NULL) (*print_encap_header)(ndo, encap_header_arg); ether_hdr_print(ndo, p, length); @@ -156,7 +246,7 @@ ether_print(netdissect_options *ndo, length -= ETHER_HDRLEN; caplen -= ETHER_HDRLEN; - + p += ETHER_HDRLEN; hdrlen = ETHER_HDRLEN; @@ -166,33 +256,40 @@ recurse: /* * Is it (gag) an 802.3 encapsulation? */ - if (length_type <= ETHERMTU) { + if (length_type <= ETHERMTU) + { /* Try to print the LLC-layer header & higher layers */ llc_hdrlen = llc_print(ndo, p, length, caplen, ESRC(ep), EDST(ep)); - if (llc_hdrlen < 0) { + if (llc_hdrlen < 0) + { /* packet type not known, print raw packet */ if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); llc_hdrlen = -llc_hdrlen; } hdrlen += llc_hdrlen; - } else if (length_type == ETHERTYPE_8021Q || - length_type == ETHERTYPE_8021Q9100 || - length_type == ETHERTYPE_8021Q9200 || - length_type == ETHERTYPE_8021QinQ) { + } + else if (length_type == ETHERTYPE_8021Q || + length_type == ETHERTYPE_8021Q9100 || + length_type == ETHERTYPE_8021Q9200 || + length_type == ETHERTYPE_8021QinQ) + { /* * Print VLAN information, and then go back and process * the enclosed type field. */ - if (caplen < 4) { + if (caplen < 4) + { ND_PRINT((ndo, "[|vlan]")); return (hdrlen + caplen); } - if (length < 4) { + if (length < 4) + { ND_PRINT((ndo, "[|vlan]")); return (hdrlen + length); } - if (ndo->ndo_eflag) { + if (ndo->ndo_eflag) + { uint16_t tag = EXTRACT_16BITS(p); ND_PRINT((ndo, "%s, ", ieee8021q_tci_string(tag))); @@ -200,13 +297,15 @@ recurse: length_type = EXTRACT_16BITS(p + 2); if (ndo->ndo_eflag && length_type > ETHERMTU) - ND_PRINT((ndo, "ethertype %s, ", tok2str(ethertype_values,"0x%04x", length_type))); + ND_PRINT((ndo, "ethertype %s, ", tok2str(ethertype_values, "0x%04x", length_type))); p += 4; length -= 4; caplen -= 4; hdrlen += 4; goto recurse; - } else if (length_type == ETHERTYPE_JUMBO) { + } + else if (length_type == ETHERTYPE_JUMBO) + { /* * Alteon jumbo frames. * See @@ -218,17 +317,22 @@ recurse: */ /* Try to print the LLC-layer header & higher layers */ llc_hdrlen = llc_print(ndo, p, length, caplen, ESRC(ep), EDST(ep)); - if (llc_hdrlen < 0) { + if (llc_hdrlen < 0) + { /* packet type not known, print raw packet */ if (!ndo->ndo_suppress_default_print) ND_DEFAULTPRINT(p, caplen); llc_hdrlen = -llc_hdrlen; } hdrlen += llc_hdrlen; - } else { - if (ethertype_print(ndo, length_type, p, length, caplen) == 0) { + } + else + { + if (ethertype_print(ndo, length_type, p, length, caplen) == 0) + { /* type not known, print raw packet */ - if (!ndo->ndo_eflag) { + if (!ndo->ndo_eflag) + { if (print_encap_header != NULL) (*print_encap_header)(ndo, encap_header_arg); ether_hdr_print(ndo, (const u_char *)ep, orig_length); @@ -238,6 +342,13 @@ recurse: ND_DEFAULTPRINT(p, caplen); } } + + /* 24.04 : print inner most layer for tunnel if has -g argument */ + if (greedy_seek_flag) + { + seek_to_inner_most_layer(ndo, raw_ethhdr, raw_ethlen); + } + return (hdrlen); } @@ -247,9 +358,8 @@ recurse: * of the packet off the wire, and 'h->caplen' is the number * of bytes actually captured. */ -u_int -ether_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, - const u_char *p) +u_int ether_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, + const u_char *p) { return (ether_print(ndo, p, h->len, h->caplen, NULL, NULL)); } @@ -263,14 +373,14 @@ ether_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, * This is for DLT_NETANALYZER, which has a 4-byte pseudo-header * before the Ethernet header. */ -u_int -netanalyzer_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, - const u_char *p) +u_int netanalyzer_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, + const u_char *p) { /* * Fail if we don't have enough data for the Hilscher pseudo-header. */ - if (h->len < 4 || h->caplen < 4) { + if (h->len < 4 || h->caplen < 4) + { ND_PRINT((ndo, "[|netanalyzer]")); return (h->caplen); } @@ -289,16 +399,16 @@ netanalyzer_if_print(netdissect_options *ndo, const struct pcap_pkthdr *h, * pseudo-header, a 7-byte Ethernet preamble, and a 1-byte Ethernet SOF * before the Ethernet header. */ -u_int -netanalyzer_transparent_if_print(netdissect_options *ndo, - const struct pcap_pkthdr *h, - const u_char *p) +u_int netanalyzer_transparent_if_print(netdissect_options *ndo, + const struct pcap_pkthdr *h, + const u_char *p) { /* * Fail if we don't have enough data for the Hilscher pseudo-header, * preamble, and SOF. */ - if (h->len < 12 || h->caplen < 12) { + if (h->len < 12 || h->caplen < 12) + { ND_PRINT((ndo, "[|netanalyzer-transparent]")); return (h->caplen); } @@ -314,121 +424,123 @@ netanalyzer_transparent_if_print(netdissect_options *ndo, * Returns non-zero if it can do so, zero if the ethertype is unknown. */ -int -ethertype_print(netdissect_options *ndo, - u_short ether_type, const u_char *p, - u_int length, u_int caplen) +int ethertype_print(netdissect_options *ndo, + u_short ether_type, const u_char *p, + u_int length, u_int caplen) { - switch (ether_type) { + int ret = 1; + + switch (ether_type) + { case ETHERTYPE_IP: - ip_print(ndo, p, length); - return (1); - + ip_print(ndo, p, length); + break; case ETHERTYPE_IPV6: ip6_print(ndo, p, length); - return (1); + break; case ETHERTYPE_ARP: case ETHERTYPE_REVARP: - arp_print(ndo, p, length, caplen); - return (1); + arp_print(ndo, p, length, caplen); + break; case ETHERTYPE_DN: decnet_print(ndo, p, length, caplen); - return (1); + break; case ETHERTYPE_ATALK: if (ndo->ndo_vflag) ND_PRINT((ndo, "et1 ")); atalk_print(ndo, p, length); - return (1); + break; case ETHERTYPE_AARP: aarp_print(ndo, p, length); - return (1); + break; case ETHERTYPE_IPX: ND_PRINT((ndo, "(NOV-ETHII) ")); ipx_print(ndo, p, length); - return (1); + break; case ETHERTYPE_ISO: isoclns_print(ndo, p + 1, length - 1, length - 1); - return(1); + return (1); case ETHERTYPE_PPPOED: case ETHERTYPE_PPPOES: case ETHERTYPE_PPPOED2: case ETHERTYPE_PPPOES2: pppoe_print(ndo, p, length); - return (1); + break; case ETHERTYPE_EAPOL: - eap_print(ndo, p, length); - return (1); + eap_print(ndo, p, length); + break; case ETHERTYPE_RRCP: - rrcp_print(ndo, p - 14 , length + 14); - return (1); + rrcp_print(ndo, p - 14, length + 14); + break; case ETHERTYPE_PPP: - if (length) { + if (length) + { ND_PRINT((ndo, ": ")); ppp_print(ndo, p, length); } - return (1); + break; case ETHERTYPE_MPCP: - mpcp_print(ndo, p, length); - return (1); + mpcp_print(ndo, p, length); + break; case ETHERTYPE_SLOW: - slow_print(ndo, p, length); - return (1); + slow_print(ndo, p, length); + break; case ETHERTYPE_CFM: case ETHERTYPE_CFM_OLD: cfm_print(ndo, p, length); - return (1); + break; case ETHERTYPE_LLDP: lldp_print(ndo, p, length); - return (1); + break; - case ETHERTYPE_LOOPBACK: + case ETHERTYPE_LOOPBACK: loopback_print(ndo, p, length); - return (1); + break; case ETHERTYPE_MPLS: case ETHERTYPE_MPLS_MULTI: mpls_print(ndo, p, length); - return (1); + break; case ETHERTYPE_TIPC: tipc_print(ndo, p, length, caplen); - return (1); + break; case ETHERTYPE_MS_NLB_HB: msnlb_print(ndo, p); - return (1); + break; - case ETHERTYPE_GEONET_OLD: - case ETHERTYPE_GEONET: - geonet_print(ndo, p-14, p, length); - return (1); + case ETHERTYPE_GEONET_OLD: + case ETHERTYPE_GEONET: + geonet_print(ndo, p - 14, p, length); + break; - case ETHERTYPE_CALM_FAST: - calm_fast_print(ndo, p-14, p, length); - return (1); + case ETHERTYPE_CALM_FAST: + calm_fast_print(ndo, p - 14, p, length); + break; case ETHERTYPE_AOE: aoe_print(ndo, p, length); - return (1); + break; case ETHERTYPE_MEDSA: medsa_print(ndo, p, length, caplen); - return (1); + break; case ETHERTYPE_LAT: case ETHERTYPE_SCA: @@ -439,8 +551,9 @@ ethertype_print(netdissect_options *ndo, default: return (0); } -} + return ret; +} /* * Local Variables: @@ -448,4 +561,3 @@ ethertype_print(netdissect_options *ndo, * c-basic-offset: 8 * End: */ - diff --git a/src/tcpdump.c b/src/tcpdump.c index 84b9a80..9a08be2 100644 --- a/src/tcpdump.c +++ b/src/tcpdump.c @@ -50,7 +50,7 @@ int tcpdump_thread_index_array_num = 0; const char *tcpdump_thread_index_str; int tcpdump_perceptive_flag = 0; unsigned int perceptive_pkt_seq[256]; /* 最大支持256个线程 */ -static int greedy_seek_flag = 0; /* 偏移到最内层IP, 便于隧道模式下查找BUG */ +int greedy_seek_flag = 0; /* 偏移到最内层IP, 便于隧道模式下查找BUG */ static int dump_to_file_flag = 0; /* 是否有-w 参数, 原有标准的WFileName变量是main()的局部变量, 不方便使用, 使用此变量表示是否写文件 */ static int has_device_flag = 0; /* 是否有-i, -r参数, 原有标准的device变量是main()的局部变量, 不方便使用, 使用此变量表示是否从某个网卡捕包 */ static int has_bpf_filter_flag = 0; /* 是否有正确的BPF过滤条件 */