diff options
author | Maatuq <mahmoudmatook.mm@gmail.com> | 2023-04-04 16:20:11 +0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-04-04 14:20:11 +0200 |
commit | f1193d5e6f7680e6b8195eea33d740987619ac9c (patch) | |
tree | 23bc44c14eb5cb5c0c49799a9dae1e4541f7fa04 | |
parent | cc5aec5f0ac6ff3d7d4c9ecbe02881641e8c8c92 (diff) |
add support for gre decapsulation (#1442) (#1921)
-rw-r--r-- | example/reader_util.c | 88 | ||||
-rw-r--r-- | src/include/ndpi_typedefs.h | 36 | ||||
-rw-r--r-- | src/lib/ndpi_utils.c | 4 | ||||
-rw-r--r-- | tests/pcap/gre.pcap | bin | 0 -> 24384 bytes | |||
-rw-r--r-- | tests/pcap/gre_no_options.pcapng | bin | 448 -> 0 bytes | |||
-rw-r--r-- | tests/result/gre.pcap.out | 28 | ||||
-rw-r--r-- | tests/result/gre_no_options.pcapng.out | 25 |
7 files changed, 156 insertions, 25 deletions
diff --git a/example/reader_util.c b/example/reader_util.c index 678b454b7..76e54900f 100644 --- a/example/reader_util.c +++ b/example/reader_util.c @@ -1791,6 +1791,74 @@ static inline u_int ndpi_skip_vxlan(u_int16_t ip_offset, u_int16_t ip_len){ return ip_offset + ip_len + sizeof(struct ndpi_udphdr) + sizeof(struct ndpi_vxlanhdr); } +static uint32_t ndpi_is_valid_gre_tunnel(const struct pcap_pkthdr *header, + const u_char *packet, const u_int16_t ip_offset, + const u_int16_t ip_len) { + if(header->caplen < ip_offset + ip_len + sizeof(struct ndpi_gre_basehdr)) + return 0; /* Too short for GRE header*/ + uint32_t offset = ip_offset + ip_len; + struct ndpi_gre_basehdr *grehdr = (struct ndpi_gre_basehdr*)&packet[offset]; + offset += sizeof(struct ndpi_gre_basehdr); + /* + rfc-1701 + The GRE flags are encoded in the first two octets. Bit 0 is the + most significant bit, bit 15 is the least significant bit. Bits + 13 through 15 are reserved for the Version field. Bits 5 through + 12 are reserved for future use and MUST be transmitted as zero. + */ + if(NDPI_GRE_IS_FLAGS(grehdr->flags)) + return 0; + if(NDPI_GRE_IS_REC(grehdr->flags)) + return 0; + /*GRE rfc 2890 that update 1701*/ + if(NDPI_GRE_IS_VERSION_0(grehdr->flags)) { + if(NDPI_GRE_IS_CSUM(grehdr->flags)) { + if(header->caplen < offset + 4) + return 0; + /*checksum field and offset field*/ + offset += 4; + } + if(NDPI_GRE_IS_KEY(grehdr->flags)) { + if(header->caplen < offset + 4) + return 0; + offset += 4; + } + if(NDPI_GRE_IS_SEQ(grehdr->flags)) { + if(header->caplen < offset + 4) + return 0; + offset += 4; + } + } else if(NDPI_GRE_IS_VERSION_1(grehdr->flags)) { /*rfc-2637 section 4.1 enhanced gre*/ + if(NDPI_GRE_IS_CSUM(grehdr->flags)) + return 0; + if(NDPI_GRE_IS_ROUTING(grehdr->flags)) + return 0; + if(!NDPI_GRE_IS_KEY(grehdr->flags)) + return 0; + if(NDPI_GRE_IS_STRICT(grehdr->flags)) + return 0; + if(grehdr->protocol != NDPI_GRE_PROTO_PPP) + return 0; + /*key field*/ + if(header->caplen < offset + 4) + return 0; + offset += 4; + if(NDPI_GRE_IS_SEQ(grehdr->flags)) { + if(header->caplen < offset + 4) + return 0; + offset += 4; + } + if(NDPI_GRE_IS_ACK(grehdr->flags)) { + if(header->caplen < offset + 4) + return 0; + offset += 4; + } + } else { /*support only ver 0, 1*/ + return 0; + } + return offset; +} + /* ****************************************************** */ struct ndpi_proto ndpi_workflow_process_packet(struct ndpi_workflow * workflow, @@ -2295,6 +2363,26 @@ struct ndpi_proto ndpi_workflow_process_packet(struct ndpi_workflow * workflow, goto datalink_check; } } + } else if(workflow->prefs.decode_tunnels && (proto == IPPROTO_GRE)) { + if(header->caplen < ip_offset + ip_len + sizeof(struct ndpi_gre_basehdr)) + return(nproto); /* Too short for GRE header*/ + u_int32_t offset = 0; + if((offset = ndpi_is_valid_gre_tunnel(header, packet, ip_offset, ip_len))) { + tunnel_type = ndpi_gre_tunnel; + struct ndpi_gre_basehdr *grehdr = (struct ndpi_gre_basehdr*)&packet[ip_offset + ip_len]; + if(grehdr->protocol == ntohs(ETH_P_IP) || grehdr->protocol == ntohs(ETH_P_IPV6)) { + ip_offset = offset; + goto iph_check; + } else if(grehdr->protocol == NDPI_GRE_PROTO_PPP) { // ppp protocol + ip_offset = offset + NDPI_PPP_HDRLEN; + goto iph_check; + } else { + eth_offset = offset; + goto datalink_check; + } + } else { + return(nproto); + } } /* process the packet */ diff --git a/src/include/ndpi_typedefs.h b/src/include/ndpi_typedefs.h index a5b1175bc..6fa9d5581 100644 --- a/src/include/ndpi_typedefs.h +++ b/src/include/ndpi_typedefs.h @@ -53,6 +53,7 @@ typedef enum { ndpi_tzsp_tunnel, ndpi_l2tp_tunnel, ndpi_vxlan_tunnel, + ndpi_gre_tunnel, } ndpi_packet_tunnel; /* @@ -536,6 +537,41 @@ struct ndpi_vxlanhdr { u_int8_t reserved; } PACK_OFF; +#ifndef IPPROTO_GRE +#define IPPROTO_GRE 47 +#endif + +#define NDPI_GRE_CSUM ntohs(0x8000) +#define NDPI_GRE_ROUTING ntohs(0x4000) +#define NDPI_GRE_KEY ntohs(0x2000) +#define NDPI_GRE_SEQ ntohs(0x1000) +#define NDPI_GRE_STRICT ntohs(0x0800) +#define NDPI_GRE_REC ntohs(0x0700) +#define NDPI_GRE_ACK ntohs(0x0080) +#define NDPI_GRE_FLAGS ntohs(0x00f8) +#define NDPI_GRE_VERSION ntohs(0x0007) + +#define NDPI_GRE_IS_CSUM(f) ((f) & NDPI_GRE_CSUM) +#define NDPI_GRE_IS_ROUTING(f) ((f) & NDPI_GRE_ROUTING) +#define NDPI_GRE_IS_KEY(f) ((f) & NDPI_GRE_KEY) +#define NDPI_GRE_IS_SEQ(f) ((f) & NDPI_GRE_SEQ) +#define NDPI_GRE_IS_STRICT(f) ((f) & NDPI_GRE_STRICT) +#define NDPI_GRE_IS_REC(f) ((f) & NDPI_GRE_REC) +#define NDPI_GRE_IS_FLAGS(f) ((f) & NDPI_GRE_FLAGS) +#define NDPI_GRE_IS_ACK(f) ((f) & NDPI_GRE_ACK) +#define NDPI_GRE_IS_VERSION_0(f) (((f) & NDPI_GRE_VERSION) == ntohs(0x0000)) +#define NDPI_GRE_IS_VERSION_1(f) (((f) & NDPI_GRE_VERSION) == ntohs(0x0001)) + +#define NDPI_GRE_PROTO_PPP ntohs(0x880b) +#define NDPI_PPP_HDRLEN 4 /* octets for standard ppp header */ + +/* +++++++++++++++++++++++ GRE basic header +++++++++++++++++++++++ */ +PACK_ON +struct ndpi_gre_basehdr { + uint16_t flags; + uint16_t protocol; +} PACK_OFF; + /* ************************************************************ */ /** diff --git a/src/lib/ndpi_utils.c b/src/lib/ndpi_utils.c index 5976de3d4..8f89ef7bf 100644 --- a/src/lib/ndpi_utils.c +++ b/src/lib/ndpi_utils.c @@ -1645,6 +1645,10 @@ const char* ndpi_tunnel2str(ndpi_packet_tunnel tt) { case ndpi_vxlan_tunnel: return("VXLAN"); break; + + case ndpi_gre_tunnel: + return("GRE"); + break; } return(""); diff --git a/tests/pcap/gre.pcap b/tests/pcap/gre.pcap Binary files differnew file mode 100644 index 000000000..a8cd42a8b --- /dev/null +++ b/tests/pcap/gre.pcap diff --git a/tests/pcap/gre_no_options.pcapng b/tests/pcap/gre_no_options.pcapng Binary files differdeleted file mode 100644 index 10ccd46a2..000000000 --- a/tests/pcap/gre_no_options.pcapng +++ /dev/null diff --git a/tests/result/gre.pcap.out b/tests/result/gre.pcap.out new file mode 100644 index 000000000..9c22b40c6 --- /dev/null +++ b/tests/result/gre.pcap.out @@ -0,0 +1,28 @@ +Guessed flow protos: 0 + +DPI Packets (UDP): 1 (1.00 pkts/flow) +DPI Packets (other): 1 (1.00 pkts/flow) +Confidence DPI : 2 (flows) +Num dissector calls: 2 (1.00 diss/flow) +LRU cache ookla: 0/0/0 (insert/search/found) +LRU cache bittorrent: 0/0/0 (insert/search/found) +LRU cache zoom: 0/0/0 (insert/search/found) +LRU cache stun: 0/0/0 (insert/search/found) +LRU cache tls_cert: 0/0/0 (insert/search/found) +LRU cache mining: 0/0/0 (insert/search/found) +LRU cache msteams: 0/0/0 (insert/search/found) +LRU cache stun_zoom: 0/0/0 (insert/search/found) +Automa host: 0/0 (search/found) +Automa domain: 0/0 (search/found) +Automa tls cert: 0/0 (search/found) +Automa risk mask: 0/0 (search/found) +Automa common alpns: 0/0 (search/found) +Patricia risk mask: 4/0 (search/found) +Patricia risk: 2/0 (search/found) +Patricia protocols: 4/0 (search/found) + +ICMP 2 276 1 +SIP 1 506 1 + + 1 UDP 212.83.179.0:5097 -> 192.200.144.148:5060 [VLAN: 1][proto: GRE:100/SIP][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 1][cat: VoIP/10][1 pkts/506 bytes -> 0 pkts/0 bytes][Goodput ratio: 81/0][< 1 sec][Risk: ** Unidirectional Traffic **][Risk Score: 10][Risk Info: No server to client traffic][PLAIN TEXT (OPTIONS sip)][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] + 2 ICMP 10.1.2.1:0 <-> 10.1.2.2:0 [proto: GRE:81/ICMP][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 1][cat: Network/14][1 pkts/138 bytes <-> 1 pkts/138 bytes][Goodput ratio: 52/52][0.00 sec][Plen Bins: 0,0,100,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] diff --git a/tests/result/gre_no_options.pcapng.out b/tests/result/gre_no_options.pcapng.out deleted file mode 100644 index c7bc721c6..000000000 --- a/tests/result/gre_no_options.pcapng.out +++ /dev/null @@ -1,25 +0,0 @@ -Guessed flow protos: 0 - -DPI Packets (other): 1 (1.00 pkts/flow) -Confidence DPI : 1 (flows) -Num dissector calls: 1 (1.00 diss/flow) -LRU cache ookla: 0/0/0 (insert/search/found) -LRU cache bittorrent: 0/0/0 (insert/search/found) -LRU cache zoom: 0/0/0 (insert/search/found) -LRU cache stun: 0/0/0 (insert/search/found) -LRU cache tls_cert: 0/0/0 (insert/search/found) -LRU cache mining: 0/0/0 (insert/search/found) -LRU cache msteams: 0/0/0 (insert/search/found) -LRU cache stun_zoom: 0/0/0 (insert/search/found) -Automa host: 0/0 (search/found) -Automa domain: 0/0 (search/found) -Automa tls cert: 0/0 (search/found) -Automa risk mask: 0/0 (search/found) -Automa common alpns: 0/0 (search/found) -Patricia risk mask: 2/0 (search/found) -Patricia risk: 2/0 (search/found) -Patricia protocols: 2/0 (search/found) - -GRE 2 276 1 - - 1 GRE 203.0.113.1:0 <-> 192.0.2.2:0 [proto: 80/GRE][IP: 0/Unknown][ClearText][Confidence: DPI][DPI packets: 1][cat: Network/14][1 pkts/138 bytes <-> 1 pkts/138 bytes][Goodput ratio: 0/0][0.00 sec][Plen Bins: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] |