From 530d0de4382ab4d70cfc1dedcf8cf2ac729dfddf Mon Sep 17 00:00:00 2001 From: Maatuq Date: Wed, 22 Mar 2023 21:18:12 +0400 Subject: Add support for vxlan decapsulation (#1441) (#1900) Close #1441 --- example/reader_util.c | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) (limited to 'example/reader_util.c') diff --git a/example/reader_util.c b/example/reader_util.c index ac152813e..f5705bec0 100644 --- a/example/reader_util.c +++ b/example/reader_util.c @@ -1745,6 +1745,52 @@ int ndpi_is_datalink_supported(int datalink_type) { } } +static bool ndpi_is_valid_vxlan(const struct pcap_pkthdr *header, const u_char *packet, u_int16_t ip_offset, u_int16_t ip_len){ + if(header->caplen < ip_offset + ip_len + sizeof(struct ndpi_vxlanhdr)) { + return false; + } + u_int32_t vxlan_dst_port = ntohs(4789); + struct ndpi_udphdr *udp = (struct ndpi_udphdr *)&packet[ip_offset+ip_len]; + u_int offset = ip_offset + ip_len + sizeof(struct ndpi_udphdr); + /** + * rfc-7348 + * VXLAN Header: This is an 8-byte field that has: + + - Flags (8 bits): where the I flag MUST be set to 1 for a valid + VXLAN Network ID (VNI). The other 7 bits (designated "R") are + reserved fields and MUST be set to zero on transmission and + ignored on receipt. + + - VXLAN Segment ID/VXLAN Network Identifier (VNI): this is a + 24-bit value used to designate the individual VXLAN overlay + network on which the communicating VMs are situated. VMs in + different VXLAN overlay networks cannot communicate with each + other. + + - Reserved fields (24 bits and 8 bits): MUST be set to zero on + transmission and ignored on receipt. + VXLAN Header: + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + |R|R|R|R|I|R|R|R| Reserved | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + | VXLAN Network Identifier (VNI) | Reserved | + +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ + */ + if((udp->dest == vxlan_dst_port || udp->source == vxlan_dst_port) && + (packet[offset] == 0x8) && + (packet[offset + 1] == 0x0) && + (packet[offset + 2] == 0x0) && + (packet[offset + 3] == 0x0) && + (packet[offset + 7] == 0x0)) { + return true; + } + return false; +} + +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); +} + /* ****************************************************** */ struct ndpi_proto ndpi_workflow_process_packet(struct ndpi_workflow * workflow, @@ -2243,6 +2289,10 @@ struct ndpi_proto ndpi_workflow_process_packet(struct ndpi_workflow * workflow, } } } + }else if(ndpi_is_valid_vxlan(header, packet, ip_offset, ip_len)){ + tunnel_type = ndpi_vxlan_tunnel; + eth_offset = ndpi_skip_vxlan(ip_offset, ip_len); + goto datalink_check; } } } -- cgit v1.2.3