From 252ee3e82f99906523095f26c6442c6a20d66ed1 Mon Sep 17 00:00:00 2001 From: emanuele-f Date: Sat, 21 Sep 2019 17:02:24 +0200 Subject: [PATCH] Call pcap_set_immediate_mode if available --- CMakeLists.txt | 7 +++++++ configure.seed | 6 ++++++ tools/n2n_decode.c | 42 +++++++++++++++++++++++++++++++++--------- 3 files changed, 46 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index deb6a3b..68d0097 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,6 @@ project(n2n) cmake_minimum_required(VERSION 2.6) +include(CheckFunctionExists) # N2n information set(N2N_VERSION 2.5.1) @@ -98,6 +99,12 @@ if(PCAP_LIB) add_executable(n2n-decode tools/n2n_decode.c) target_link_libraries(n2n-decode n2n pcap) install(TARGETS n2n-decode RUNTIME DESTINATION bin) + + set(CMAKE_REQUIRED_LIBRARIES ${PCAP_LIB}) + check_function_exists(pcap_set_immediate_mode HAVE_PCAP_IMMEDIATE_MODE) + IF(HAVE_PCAP_IMMEDIATE_MODE) + ADD_DEFINITIONS("-DHAVE_PCAP_IMMEDIATE_MODE") + ENDIF() endif() install(TARGETS n2n-benchmark RUNTIME DESTINATION bin) diff --git a/configure.seed b/configure.seed index 432650a..0f8b596 100644 --- a/configure.seed +++ b/configure.seed @@ -31,6 +31,12 @@ if test x$pcap != x; then ADDITIONAL_TOOLS="$ADDITIONAL_TOOLS n2n-decode" fi +AC_CHECK_LIB([pcap], [pcap_set_immediate_mode], pcap_immediate_mode=true) + +if test x$pcap_immediate_mode != x; then + AC_DEFINE([HAVE_PCAP_IMMEDIATE_MODE], [], [Have pcap_immediate_mode]) +fi + MACHINE=`uname -m` SYSTEM=`uname -s` diff --git a/tools/n2n_decode.c b/tools/n2n_decode.c index bfe1156..6caf85c 100644 --- a/tools/n2n_decode.c +++ b/tools/n2n_decode.c @@ -20,11 +20,13 @@ #include "n2n.h" #define SNAPLEN 1500 +#define TIMEOUT 200 /* *************************************************** */ static int aes_mode = 0; static int running = 1; +static char *ifname = NULL; static n2n_edge_conf_t conf; static n2n_trans_op_t transop; static pcap_t *handle; @@ -146,17 +148,22 @@ static int run_packet_loop() { struct pcap_pkthdr header; const u_char *packet; - traceEvent(TRACE_NORMAL, "Running loop"); + traceEvent(TRACE_NORMAL, "Capturing packets on %s...", ifname); - // TODO handle timeout while(running) { - n2n_common_t common = {0}; - n2n_PACKET_t pkt = {0}; + n2n_common_t common; + n2n_PACKET_t pkt; uint ipsize, common_offset; size_t idx, rem; + memset(&common, 0, sizeof(common)); + memset(&pkt, 0, sizeof(pkt)); + packet = pcap_next(handle, &header); + if(!packet) + continue; + if(header.caplen < MIN_LEN) { traceEvent(TRACE_INFO, "Skipping packet too small: size=%d", header.caplen); continue; @@ -219,7 +226,7 @@ static int run_packet_loop() { int main(int argc, char* argv[]) { u_char c; struct bpf_program fcode; - char *bpf_filter = NULL, *ifname = NULL, *out_fname = NULL; + char *bpf_filter = NULL, *out_fname = NULL; char errbuf[PCAP_ERRBUF_SIZE]; int rv = 0; FILE *outf = stdout; @@ -240,7 +247,7 @@ int main(int argc, char* argv[]) { switch(c) { case 'c': - strncpy((char*)conf.community_name, optarg, sizeof(conf.community_name)); + strncpy((char*)conf.community_name, optarg, sizeof(conf.community_name)-1); break; case 'i': ifname = strdup(optarg); @@ -278,13 +285,30 @@ int main(int argc, char* argv[]) { #endif n2n_transop_twofish_init(&conf, &transop); - handle = pcap_open_live(ifname, SNAPLEN, 1, 1000, errbuf); - - if(handle == NULL) { + if((handle = pcap_create(ifname, errbuf)) == NULL) { traceEvent(TRACE_ERROR, "Cannot open device %s: %s", ifname, errbuf); return(1); } + if((pcap_set_timeout(handle, TIMEOUT) != 0) || + (pcap_set_snaplen(handle, SNAPLEN) != 0)) { + traceEvent(TRACE_ERROR, "Error while setting timeout/snaplen"); + return(1); + } + +#ifdef HAVE_PCAP_IMMEDIATE_MODE + /* The timeout is not honored unless immediate mode is set. + * See https://github.com/mfontanini/libtins/issues/180 */ + if(pcap_set_immediate_mode(handle, 1) != 0) { + traceEvent(TRACE_ERROR, "Could not set PCAP immediate mode"); + return(1); + } +#endif + + if(pcap_activate(handle) != 0) { + traceEvent(TRACE_ERROR, "pcap_activate failed: %s", pcap_geterr(handle)); + } + if(pcap_datalink(handle) != DLT_EN10MB) { traceEvent(TRACE_ERROR, "Device %s doesn't provide Ethernet headers - not supported", ifname); return(2);