aboutsummaryrefslogtreecommitdiff
path: root/example/reader_util.c
diff options
context:
space:
mode:
authorMaatuq <mahmoudmatook.mm@gmail.com>2023-04-04 16:20:11 +0400
committerGitHub <noreply@github.com>2023-04-04 14:20:11 +0200
commitf1193d5e6f7680e6b8195eea33d740987619ac9c (patch)
tree23bc44c14eb5cb5c0c49799a9dae1e4541f7fa04 /example/reader_util.c
parentcc5aec5f0ac6ff3d7d4c9ecbe02881641e8c8c92 (diff)
add support for gre decapsulation (#1442) (#1921)
Diffstat (limited to 'example/reader_util.c')
-rw-r--r--example/reader_util.c88
1 files changed, 88 insertions, 0 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 */