From: Eric Leblond Date: Tue, 4 Feb 2014 15:33:30 +0000 (+0100) Subject: pfring: get vlan id from header X-Git-Tag: suricata-2.0rc2~7 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1fa4233d67d068fd49155e9d153011a491125833;p=thirdparty%2Fsuricata.git pfring: get vlan id from header PF_RING is delivering the packet with VLAN header stripped. This patch updates the code to get the information from PF_RING extended header information. This patch uses the new function SCKernelVersionIsAtLeast to know that we've got a old kernel that do not strip the VLAN header from the message before sending it to userspace. --- diff --git a/src/source-pfring.c b/src/source-pfring.c index 6c966083fe..1085cf0e1e 100644 --- a/src/source-pfring.c +++ b/src/source-pfring.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2007-2013 Open Information Security Foundation +/* Copyright (C) 2007-2014 Open Information Security Foundation * * You can copy, redistribute or modify this Program under the terms of * the GNU General Public License version 2 as published by the Free @@ -46,6 +46,7 @@ #include "util-checksum.h" #include "util-privs.h" #include "util-device.h" +#include "util-host-info.h" #include "runmodes.h" #ifdef __SC_CUDA_SUPPORT__ @@ -140,6 +141,8 @@ typedef struct PfringThreadVars_ ThreadVars *tv; TmSlot *slot; + int vlan_disabled; + /* threads count */ int threads; @@ -234,6 +237,16 @@ static inline void PfringProcessPacket(void *user, struct pfring_pkthdr *h, Pack * so that is what we do here. */ p->datalink = LINKTYPE_ETHERNET; + /* get vlan id from header. Check on vlan_id not null even if comment in + * header announce NO_VLAN is used when there is no VLAN. But NO_VLAN + * is not defined nor used in PF_RING code. And vlan_id is set to 0 + * in PF_RING kernel code when there is no VLAN. */ + if ((!ptv->vlan_disabled) && h->extended_hdr.parsed_pkt.vlan_id) { + p->vlan_id[0] = h->extended_hdr.parsed_pkt.vlan_id; + p->vlan_idx = 1; + p->vlanh[0] = NULL; + } + switch (ptv->checksum_mode) { case CHECKSUM_VALIDATION_RXONLY: if (h->extended_hdr.rx_direction == 0) { @@ -407,6 +420,12 @@ TmEcode ReceivePfringThreadInit(ThreadVars *tv, void *initdata, void **data) { opflag = PF_RING_REENTRANT | PF_RING_PROMISC; + /* if suri uses VLAN and if we have a recent kernel, we need + * to use parsed_pkt to get VLAN info */ + if ((! ptv->vlan_disabled) && SCKernelVersionIsAtLeast(3, 0)) { + opflag |= PF_RING_LONG_HEADER; + } + if (ptv->checksum_mode == CHECKSUM_VALIDATION_RXONLY) { if (strncmp(ptv->interface, "dna", 3) == 0) { SCLogWarning(SC_ERR_INVALID_VALUE, @@ -506,6 +525,20 @@ TmEcode ReceivePfringThreadInit(ThreadVars *tv, void *initdata, void **data) { } #endif /* HAVE_PFRING_ENABLE */ + /* A bit strange to have this here but we only have vlan information + * during reading so we need to know if we want to keep vlan during + * the capture phase */ + int vlanbool = 0; + if ((ConfGetBool("vlan.use-for-tracking", &vlanbool)) == 1 && vlanbool == 0) { + ptv->vlan_disabled = 1; + } + + /* If kernel is older than 3.8, VLAN is not stripped so we don't + * get the info from packt extended header but we will use a standard + * parsing */ + if (! SCKernelVersionIsAtLeast(3, 0)) { + ptv->vlan_disabled = 1; + } *data = (void *)ptv; pfconf->DerefFunc(pfconf); @@ -589,6 +622,11 @@ TmEcode DecodePfring(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, Pac SCPerfCounterAddUI64(dtv->counter_avg_pkt_size, tv->sc_perf_pca, GET_PKT_LEN(p)); SCPerfCounterSetUI64(dtv->counter_max_pkt_size, tv->sc_perf_pca, GET_PKT_LEN(p)); + /* If suri has set vlan during reading, we increase vlan counter */ + if (p->vlan_idx) { + SCPerfCounterIncr(dtv->counter_vlan, tv->sc_perf_pca); + } + DecodeEthernet(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq); PacketDecodeFinalize(tv, dtv, p);