diff --git a/src/Linux/Makefile b/src/Linux/Makefile index 97980021..9da8a4bf 100644 --- a/src/Linux/Makefile +++ b/src/Linux/Makefile @@ -321,7 +321,7 @@ EAPI: mod_eapi.so ######### hsflowd ######### hsflowd: $(OBJS_HSFLOWD) $(HEADERS) - $(CC) $(CFLAGS) -o $@ $(OBJS_HSFLOWD) mod_docker.o $(LIBS) $(LIBS_HSFLOWD) -rdynamic + $(CC) $(CFLAGS) -o $@ $(OBJS_HSFLOWD) $(LIBS) $(LIBS_HSFLOWD) -rdynamic ######## DBUS utils ########## diff --git a/src/Linux/hsflowconfig.c b/src/Linux/hsflowconfig.c index 81418849..8343742d 100644 --- a/src/Linux/hsflowconfig.c +++ b/src/Linux/hsflowconfig.c @@ -1597,6 +1597,9 @@ extern "C" { if((tok = expectIntegerRange64(sp, tok, &pc->speed_min, &pc->speed_max, 0, LLONG_MAX)) == NULL) return NO; pc->speed_set = YES; break; + case HSPTOKEN_OUTBOUND_ONLY: + if((tok = expectONOFF(sp, tok, &pc->outbound_only)) == NULL) return NO; + break; default: unexpectedToken(sp, tok, level[depth]); return NO; diff --git a/src/Linux/hsflowd.h b/src/Linux/hsflowd.h index 04a12a8e..aa2ea81b 100644 --- a/src/Linux/hsflowd.h +++ b/src/Linux/hsflowd.h @@ -166,6 +166,7 @@ extern "C" { uint64_t speed_min; uint64_t speed_max; bool speed_set; + bool outbound_only; } HSPPcap; typedef struct _HSPPort { diff --git a/src/Linux/hsflowtokens.h b/src/Linux/hsflowtokens.h index 614ff734..e0ed4a23 100644 --- a/src/Linux/hsflowtokens.h +++ b/src/Linux/hsflowtokens.h @@ -44,6 +44,7 @@ HSPTOKEN_DATA( HSPTOKEN_DEV, "dev", HSPTOKENTYPE_ATTRIB, NULL) HSPTOKEN_DATA( HSPTOKEN_SPEED, "speed", HSPTOKENTYPE_ATTRIB, NULL) HSPTOKEN_DATA( HSPTOKEN_PROMISC, "promisc", HSPTOKENTYPE_ATTRIB, NULL) HSPTOKEN_DATA( HSPTOKEN_VPORT, "vport", HSPTOKENTYPE_ATTRIB, NULL) +HSPTOKEN_DATA( HSPTOKEN_OUTBOUND_ONLY, "outbound_only", HSPTOKENTYPE_ATTRIB, NULL) HSPTOKEN_DATA( HSPTOKEN_KVM, "kvm", HSPTOKENTYPE_OBJ, NULL) HSPTOKEN_DATA( HSPTOKEN_XEN, "xen", HSPTOKENTYPE_OBJ, NULL) HSPTOKEN_DATA( HSPTOKEN_XEN_UPDATE_DOMINFO, "xen.update.dominfo", HSPTOKENTYPE_ATTRIB, "xen { update.dominfo=[on|off] }") diff --git a/src/Linux/mod_pcap.c b/src/Linux/mod_pcap.c index 2010a033..a93b4ec6 100644 --- a/src/Linux/mod_pcap.c +++ b/src/Linux/mod_pcap.c @@ -32,6 +32,7 @@ extern "C" { bool promisc:1; bool vport:1; bool vport_set:1; + bool outbound_only:1; pcap_t *pcap; char pcap_err[PCAP_ERRBUF_SIZE]; } BPFSoc; @@ -197,6 +198,10 @@ extern "C" { } struct sock_filter code[] = { + // for outbound_only check + { 0x28, 0, 0, 0xfffff004 }, // ld direction + { 0x15, 0, 4, 0x00000004 }, // true:outbound, false:inbound + // for stochastic sampling { 0x20, 0, 0, 0xfffff038 }, // ld rand { 0x94, 0, 0, 0x00000100 }, // mod #256 { 0x15, 0, 1, 0x00000001 }, // jneq #1, drop @@ -205,12 +210,20 @@ extern "C" { }; // overwrite the sampling-rate - code[1].k = bpfs->samplingRate; - myDebug(1, "PCAP: sampling rate set to %u for dev=%s", code[1].k, bpfs->deviceName); - struct sock_fprog bpf = { - .len = 5, // ARRAY_SIZE(code), - .filter = code, - }; + code[3].k = bpfs->samplingRate; + myDebug(1, "PCAP: sampling rate set to %u for dev=%s", code[3].k, bpfs->deviceName); + + // set filter code range for outboud_only or all + struct sock_fprog bpf = { 0, 0 }; + if (bpfs->outbound_only) { + bpf.len = 7; + bpf.filter = code; + } + else { + bpf.len = 5; + bpf.filter = code + 2; + } + myDebug(1, "PCAP: sampling outbound_only=%s", bpfs->outbound_only? "on" : "off"); // install the sock_filter directly, rather than using pcap_setfilter() int status = setsockopt(fd, SOL_SOCKET, SO_ATTACH_FILTER, &bpf, sizeof(bpf)); @@ -307,6 +320,7 @@ extern "C" { bpfs->promisc = pcap->promisc; bpfs->vport = pcap->vport; bpfs->vport_set = pcap->vport_set; + bpfs->outbound_only = pcap->outbound_only; tap_open(mod, bpfs); }