From b98579ab8f23b436b54fa0a0a3371ec71362f827 Mon Sep 17 00:00:00 2001 From: stubbsw Date: Sun, 17 Aug 2014 11:50:56 -0400 Subject: [PATCH 1/2] workaround libpcap 4 extra bytes Workaround for libpcap returning a length that is 4 bytes longer than the packet on the wire. Observed on: Linux beaglebone 3.8.13-bone50 #1 SMP Tue May 13 13:24:52 UTC 2014 armv7l GNU/Linux ldd fwknopd libfko.so.2 => /usr/local/lib/libfko.so.2 (0xb6f62000) libpcap.so.0.8 => /usr/lib/arm-linux-gnueabihf/libpcap.so.0.8 (0xb6f20000) libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xb6e3b000) /lib/ld-linux-armhf.so.3 (0xb6f94000) libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0xb6e17000) Calculate the new pkt_end from the length in the ip header. --- server/process_packet.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/server/process_packet.c b/server/process_packet.c index 79098241..4a11c669 100644 --- a/server/process_packet.c +++ b/server/process_packet.c @@ -134,6 +134,33 @@ process_packet(unsigned char *args, const struct pcap_pkthdr *packet_header, if (ip_hdr_words < MIN_IPV4_WORDS) return; + + + /* Workaround for libpcap returning a length that is 4 bytes longer than + * the packet on the wire. Observed on: + * + * Linux beaglebone 3.8.13-bone50 #1 SMP Tue May 13 13:24:52 UTC 2014 armv7l GNU/Linux + * ldd fwknopd + * libfko.so.2 => /usr/local/lib/libfko.so.2 (0xb6f62000) + * libpcap.so.0.8 => /usr/lib/arm-linux-gnueabihf/libpcap.so.0.8 (0xb6f20000) + * libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xb6e3b000) + * /lib/ld-linux-armhf.so.3 (0xb6f94000) + * libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0xb6e17000) + * + * Calculate the new pkt_end from the length in the ip header. + */ + unsigned char *pcap_bug_workaround_pkt_end = + ((unsigned char*)iph_p) + ntohs(iph_p->tot_len); + + /* Only accept the new end if it is shorter than the original pkt_end + * provided by libpcap. + */ + if(pcap_bug_workaround_pkt_end < pkt_end) { + pkt_end = pcap_bug_workaround_pkt_end; + } + + + /* Now, find the packet data payload (depending on IPPROTO). */ src_ip = iph_p->saddr; From 19f31c3e2300226f8414b2d050315190168cf6d9 Mon Sep 17 00:00:00 2001 From: stubbsw Date: Tue, 19 Aug 2014 06:54:18 -0400 Subject: [PATCH 2/2] update to indicate Ethernet FCS support vs. bug --- server/process_packet.c | 26 +++++++++++--------------- 1 file changed, 11 insertions(+), 15 deletions(-) diff --git a/server/process_packet.c b/server/process_packet.c index 4a11c669..72fca720 100644 --- a/server/process_packet.c +++ b/server/process_packet.c @@ -38,6 +38,7 @@ #include "process_packet.h" #include "incoming_spa.h" #include "utils.h" +#include "log_msg.h" void process_packet(unsigned char *args, const struct pcap_pkthdr *packet_header, @@ -135,32 +136,27 @@ process_packet(unsigned char *args, const struct pcap_pkthdr *packet_header, return; - - /* Workaround for libpcap returning a length that is 4 bytes longer than - * the packet on the wire. Observed on: - * - * Linux beaglebone 3.8.13-bone50 #1 SMP Tue May 13 13:24:52 UTC 2014 armv7l GNU/Linux - * ldd fwknopd - * libfko.so.2 => /usr/local/lib/libfko.so.2 (0xb6f62000) - * libpcap.so.0.8 => /usr/lib/arm-linux-gnueabihf/libpcap.so.0.8 (0xb6f20000) - * libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xb6e3b000) - * /lib/ld-linux-armhf.so.3 (0xb6f94000) - * libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0xb6e17000) + /* Support for the cases where libpcap returns the Ethernet Frame Check + * Sequence (4 bytes at the end of the Ethernet frame) as part of the + * capture. libpcap returning the FCS is fairly rare. Default settings on + * the following system included an Ethernet FCS in the libpcap capture: + * BeagleBone Black rev C running 3.8.13-bone50 #1 SMP Tue May 13 + * 13:24:52 UTC 2014 armv7l GNU/Linux * * Calculate the new pkt_end from the length in the ip header. */ - unsigned char *pcap_bug_workaround_pkt_end = + unsigned char *pcap_with_fcs_workaround_pkt_end = ((unsigned char*)iph_p) + ntohs(iph_p->tot_len); /* Only accept the new end if it is shorter than the original pkt_end * provided by libpcap. */ - if(pcap_bug_workaround_pkt_end < pkt_end) { - pkt_end = pcap_bug_workaround_pkt_end; + if(pcap_with_fcs_workaround_pkt_end < pkt_end) { + log_msg(LOG_DEBUG, "Adjusting packet end from %u to %u (likely due to Ethernet FCS being included in the capture)", pkt_end, pcap_with_fcs_workaround_pkt_end); + pkt_end = pcap_with_fcs_workaround_pkt_end; } - /* Now, find the packet data payload (depending on IPPROTO). */ src_ip = iph_p->saddr;