diff --git a/src/runmode-af-packet.c b/src/runmode-af-packet.c index d9309a4ec4..d2922e4fa6 100644 --- a/src/runmode-af-packet.c +++ b/src/runmode-af-packet.c @@ -109,9 +109,11 @@ void *ParseAFPConfig(const char *iface) AFPIfaceConfig *aconf = SCMalloc(sizeof(*aconf)); char *tmpclusterid; char *tmpctype; + char *copymodestr; intmax_t value; int boolval; char *bpf_filter = NULL; + char *out_iface = NULL; if (aconf == NULL) { return NULL; @@ -134,6 +136,7 @@ void *ParseAFPConfig(const char *iface) aconf->DerefFunc = AFPDerefConfig; aconf->flags = 0; aconf->bpf_filter = NULL; + aconf->out_iface = NULL; if (ConfGet("bpf-filter", &bpf_filter) == 1) { if (strlen(bpf_filter) > 0) { @@ -169,6 +172,44 @@ void *ParseAFPConfig(const char *iface) aconf->threads = 1; } + if (ConfGetChildValue(if_root, "copy-iface", &out_iface) == 1) { + if (strlen(out_iface) > 0) { + aconf->out_iface = out_iface; + } + } + + (void)ConfGetChildValueBool(if_root, "use-mmap", (int *)&boolval); + if (boolval) { + SCLogInfo("Enabling mmaped capture on iface %s", + aconf->iface); + aconf->flags |= AFP_RING_MODE; + } + + aconf->copy_mode = AFP_COPY_MODE_NONE; + if (ConfGetChildValue(if_root, "copy-mode", ©modestr) == 1) { + if (aconf->out_iface == NULL) { + SCLogInfo("Copy mode activated but no destination" + " iface. Disabling feature"); + } else if (!(aconf->flags & AFP_RING_MODE)) { + SCLogInfo("Copy mode activated but use-mmap " + "set to no. Disabling feature"); + } else if (strlen(copymodestr) <= 0) { + aconf->out_iface = NULL; + } else if (strcmp(copymodestr, "ips") == 0) { + SCLogInfo("AF_PACKET IPS mode activated %s->%s", + iface, + aconf->out_iface); + aconf->copy_mode = AFP_COPY_MODE_IPS; + } else if (strcmp(copymodestr, "tap") == 0) { + SCLogInfo("AF_PACKET TAP mode activated %s->%s", + iface, + aconf->out_iface); + aconf->copy_mode = AFP_COPY_MODE_TAP; + } else { + SCLogInfo("Invalid mode (not in tap, ips)"); + } + } + SC_ATOMIC_RESET(aconf->ref); (void) SC_ATOMIC_ADD(aconf->ref, aconf->threads); @@ -246,13 +287,6 @@ void *ParseAFPConfig(const char *iface) aconf->iface); aconf->promisc = 0; } - (void)ConfGetChildValueBool(if_root, "use-mmap", (int *)&boolval); - if (boolval) { - SCLogInfo("Enabling mmaped capture on iface %s", - aconf->iface); - aconf->flags |= AFP_RING_MODE; - } - if (ConfGetChildValue(if_root, "checksum-checks", &tmpctype) == 1) { if (strcmp(tmpctype, "auto") == 0) { @@ -309,6 +343,11 @@ int RunModeIdsAFPAuto(DetectEngineCtx *de_ctx) (void)ConfGet("af-packet.live-interface", &live_dev); + if (AFPPeersListInit() != TM_ECODE_OK) { + SCLogError(SC_ERR_RUNMODE, "Unable to init peers list."); + exit(EXIT_FAILURE); + } + ret = RunModeSetLiveCaptureAuto(de_ctx, ParseAFPConfig, AFPConfigGeThreadsCount, @@ -320,6 +359,12 @@ int RunModeIdsAFPAuto(DetectEngineCtx *de_ctx) exit(EXIT_FAILURE); } + /* In IPS mode each threads must have a peer */ + if (AFPPeersListCheck() != TM_ECODE_OK) { + SCLogError(SC_ERR_RUNMODE, "Some IPS capture threads did not peer."); + exit(EXIT_FAILURE); + } + SCLogInfo("RunModeIdsAFPAuto initialised"); #endif SCReturnInt(0); @@ -342,6 +387,11 @@ int RunModeIdsAFPAutoFp(DetectEngineCtx *de_ctx) SCLogDebug("live_dev %s", live_dev); + if (AFPPeersListInit() != TM_ECODE_OK) { + SCLogError(SC_ERR_RUNMODE, "Unable to init peers list."); + exit(EXIT_FAILURE); + } + ret = RunModeSetLiveCaptureAutoFp(de_ctx, ParseAFPConfig, AFPConfigGeThreadsCount, @@ -353,8 +403,13 @@ int RunModeIdsAFPAutoFp(DetectEngineCtx *de_ctx) exit(EXIT_FAILURE); } - SCLogInfo("RunModeIdsAFPAutoFp initialised"); + /* In IPS mode each threads must have a peer */ + if (AFPPeersListCheck() != TM_ECODE_OK) { + SCLogError(SC_ERR_RUNMODE, "Some IPS capture threads did not peer."); + exit(EXIT_FAILURE); + } + SCLogInfo("RunModeIdsAFPAutoFp initialised"); #endif /* HAVE_AF_PACKET */ SCReturnInt(0); @@ -377,6 +432,11 @@ int RunModeIdsAFPSingle(DetectEngineCtx *de_ctx) (void)ConfGet("af-packet.live-interface", &live_dev); + if (AFPPeersListInit() != TM_ECODE_OK) { + SCLogError(SC_ERR_RUNMODE, "Unable to init peers list."); + exit(EXIT_FAILURE); + } + ret = RunModeSetLiveCaptureSingle(de_ctx, ParseAFPConfig, AFPConfigGeThreadsCount, @@ -388,6 +448,12 @@ int RunModeIdsAFPSingle(DetectEngineCtx *de_ctx) exit(EXIT_FAILURE); } + /* In IPS mode each threads must have a peer */ + if (AFPPeersListCheck() != TM_ECODE_OK) { + SCLogError(SC_ERR_RUNMODE, "Some IPS capture threads did not peer."); + exit(EXIT_FAILURE); + } + SCLogInfo("RunModeIdsAFPSingle initialised"); #endif /* HAVE_AF_PACKET */ @@ -414,6 +480,11 @@ int RunModeIdsAFPWorkers(DetectEngineCtx *de_ctx) (void)ConfGet("af-packet.live-interface", &live_dev); + if (AFPPeersListInit() != TM_ECODE_OK) { + SCLogError(SC_ERR_RUNMODE, "Unable to init peers list."); + exit(EXIT_FAILURE); + } + ret = RunModeSetLiveCaptureWorkers(de_ctx, ParseAFPConfig, AFPConfigGeThreadsCount, @@ -425,6 +496,12 @@ int RunModeIdsAFPWorkers(DetectEngineCtx *de_ctx) exit(EXIT_FAILURE); } + /* In IPS mode each threads must have a peer */ + if (AFPPeersListCheck() != TM_ECODE_OK) { + SCLogError(SC_ERR_RUNMODE, "Some IPS capture threads did not peer."); + exit(EXIT_FAILURE); + } + SCLogInfo("RunModeIdsAFPSingle initialised"); #endif /* HAVE_AF_PACKET */ diff --git a/src/source-af-packet.c b/src/source-af-packet.c index 6fa02c5983..2aaa26eb7f 100644 --- a/src/source-af-packet.c +++ b/src/source-af-packet.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2011 Open Information Security Foundation +/* Copyright (C) 2011,2012 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 @@ -166,6 +166,10 @@ typedef struct AFPThreadVars_ int promisc; ChecksumValidationMode checksum_mode; + /* IPS stuff */ + char out_iface[AFP_IFACE_NAME_LENGTH]; + AFPPeer *mpeer; + int flags; uint16_t capture_kernel_packets; uint16_t capture_kernel_drops; @@ -174,6 +178,7 @@ typedef struct AFPThreadVars_ int cluster_type; int threads; + int copy_mode; struct tpacket_req req; unsigned int tp_hdrlen; @@ -182,6 +187,7 @@ typedef struct AFPThreadVars_ char *frame_buf; unsigned int frame_offset; int ring_size; + } AFPThreadVars; TmEcode ReceiveAFP(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); @@ -194,6 +200,7 @@ TmEcode DecodeAFPThreadInit(ThreadVars *, void *, void **); TmEcode DecodeAFP(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *); TmEcode AFPSetBPFFilter(AFPThreadVars *ptv); +static int AFPGetIfnumByDev(int fd, const char *ifname, int verbose); /** * \brief Registration Function for RecieveAFP. @@ -211,6 +218,119 @@ void TmModuleReceiveAFPRegister (void) { tmm_modules[TMM_RECEIVEAFP].flags = TM_FLAG_RECEIVE_TM; } +typedef struct AFPPeersList_ { + TAILQ_HEAD(, AFPPeer_) peers; /**< Head of list of fragments. */ + int cnt; + int peered; +} AFPPeersList; + +/** + * Update the peer. + */ +void AFPPeerUpdate(AFPThreadVars *ptv) +{ + if (ptv->mpeer == NULL) { + return; + } + SCLogInfo("Updating AFP peer"); + (void)SC_ATOMIC_SET(ptv->mpeer->if_idx, AFPGetIfnumByDev(ptv->socket, ptv->iface, 0)); + (void)SC_ATOMIC_SET(ptv->mpeer->socket, ptv->socket); + (void)SC_ATOMIC_SET(ptv->mpeer->state, ptv->afp_state); +} + +void AFPPeerClean(AFPPeer *peer) +{ + if (peer->flags & AFP_SOCK_PROTECT) + SCMutexDestroy(&peer->sock_protect); + SC_ATOMIC_DESTROY(peer->socket); + SC_ATOMIC_DESTROY(peer->if_idx); + SC_ATOMIC_DESTROY(peer->state); + SCFree(peer); +} + +AFPPeersList peerslist; + + +TmEcode AFPPeersListInit() +{ + SCEnter(); + TAILQ_INIT(&peerslist.peers); + peerslist.peered = 0; + peerslist.cnt = 0; + SCReturnInt(TM_ECODE_OK); +} + +TmEcode AFPPeersListCheck() +{ +#define AFP_PEERS_MAX_TRY 4 +#define AFP_PEERS_WAIT 20000 + int try = 0; + SCEnter(); + while (try < AFP_PEERS_MAX_TRY) { + if (peerslist.cnt != peerslist.peered) { + usleep(AFP_PEERS_WAIT); + } else { + SCReturnInt(TM_ECODE_OK); + } + try++; + } + SCLogError(SC_ERR_AFP_CREATE, "Threads number not equals"); + SCReturnInt(TM_ECODE_FAILED); +} + +TmEcode AFPPeersListAdd(AFPThreadVars *ptv) +{ + SCEnter(); + AFPPeer *peer = SCMalloc(sizeof(AFPPeer)); + AFPPeer *pitem; + + if (peer == NULL) { + SCReturnInt(TM_ECODE_FAILED); + } + memset(peer, 0, sizeof(AFPPeer)); + SC_ATOMIC_INIT(peer->socket); + SC_ATOMIC_INIT(peer->if_idx); + SC_ATOMIC_INIT(peer->state); + peer->flags = ptv->flags; + + if (peer->flags & AFP_SOCK_PROTECT) { + SCMutexInit(&peer->sock_protect, NULL); + } + + (void)SC_ATOMIC_SET(peer->state, AFP_STATE_DOWN); + strlcpy(peer->iface, ptv->iface, AFP_IFACE_NAME_LENGTH); + ptv->mpeer = peer; + /* add element to iface list */ + TAILQ_INSERT_TAIL(&peerslist.peers, peer, next); + peerslist.cnt++; + + /* Iter to find a peer */ + TAILQ_FOREACH(pitem, &peerslist.peers, next) { + if (pitem->peer) + continue; + if (strcmp(pitem->iface, ptv->out_iface)) + continue; + peer->peer = pitem; + pitem->peer = peer; + peerslist.peered += 2; + break; + } + + AFPPeerUpdate(ptv); + + SCReturnInt(TM_ECODE_OK); +} + +void AFPPeersListClean() +{ + AFPPeer *pitem; + + while ((pitem = TAILQ_FIRST(&peerslist.peers))) { + TAILQ_REMOVE(&peerslist.peers, pitem, next); + AFPPeerClean(pitem); + } +} + /** * \brief Registration Function for DecodeAFP. * \todo Unit tests are needed for this module. @@ -226,6 +346,7 @@ void TmModuleDecodeAFPRegister (void) { tmm_modules[TMM_DECODEAFP].flags = TM_FLAG_DECODE_TM; } + static int AFPCreateSocket(AFPThreadVars *ptv, char *devname, int verbose); static inline void AFPDumpCounters(AFPThreadVars *ptv, int forced) @@ -368,13 +489,64 @@ int AFPRead(AFPThreadVars *ptv) SCReturnInt(AFP_READ_OK); } +TmEcode AFPWritePacket(Packet *p) +{ + struct sockaddr_ll socket_address; + int socket; + + if (p->afp_v.copy_mode == AFP_COPY_MODE_IPS) { + if (p->action & ACTION_DROP) { + return TM_ECODE_OK; + } + } + + if (SC_ATOMIC_GET(p->afp_v.peer->state) == AFP_STATE_DOWN) + return TM_ECODE_OK; + + if (p->ethh == NULL) { + SCLogWarning(SC_ERR_INVALID_VALUE, "Should have an Ethernet header"); + return TM_ECODE_FAILED; + } + /* Index of the network device */ + socket_address.sll_ifindex = SC_ATOMIC_GET(p->afp_v.peer->if_idx); + /* Address length*/ + socket_address.sll_halen = ETH_ALEN; + /* Destination MAC */ + memcpy(socket_address.sll_addr, p->ethh, 6); + + /* Send packet, locking the socket if necessary */ + if (p->afp_v.peer->flags & AFP_SOCK_PROTECT) + SCMutexLock(&p->afp_v.peer->sock_protect); + socket = SC_ATOMIC_GET(p->afp_v.peer->socket); + if (sendto(socket, GET_PKT_DATA(p), GET_PKT_LEN(p), 0, + (struct sockaddr*) &socket_address, + sizeof(struct sockaddr_ll)) < 0) { + SCLogWarning(SC_ERR_SOCKET, "Sending packet failed on socket %d: %s", + socket, + strerror(errno)); + if (p->afp_v.peer->flags & AFP_SOCK_PROTECT) + SCMutexUnlock(&p->afp_v.peer->sock_protect); + return TM_ECODE_FAILED; + } + if (p->afp_v.peer->flags & AFP_SOCK_PROTECT) + SCMutexUnlock(&p->afp_v.peer->sock_protect); + + return TM_ECODE_OK; +} + TmEcode AFPReleaseDataFromRing(ThreadVars *t, Packet *p) { + int ret = TM_ECODE_OK; + /* Need to be in copy mode and need to detect early release + where Ethernet header could not be set (and pseudo packet) */ + if ((p->afp_v.copy_mode != AFP_COPY_MODE_NONE) && !PKT_IS_PSEUDOPKT(p)) { + ret = AFPWritePacket(p); + } if (p->afp_v.relptr) { union thdr h; h.raw = p->afp_v.relptr; h.h2->tp_status = TP_STATUS_KERNEL; - return TM_ECODE_OK; + return ret; } return TM_ECODE_FAILED; } @@ -392,6 +564,7 @@ int AFPReadFromRing(AFPThreadVars *ptv) { Packet *p = NULL; union thdr h; + struct sockaddr_ll *from; /* Loop till we have packets available */ while (1) { @@ -399,12 +572,8 @@ int AFPReadFromRing(AFPThreadVars *ptv) h.raw = (((union thdr **)ptv->frame_buf)[ptv->frame_offset]); if (h.raw == NULL) { SCReturnInt(AFP_FAILURE); - } else { - if (ptv->flags & AFP_RING_MODE) { - p->afp_v.relptr = h.raw; - p->ReleaseData = AFPReleaseDataFromRing; - } } + if (h.h2->tp_status == TP_STATUS_KERNEL) { SCReturnInt(AFP_READ_OK); } @@ -414,6 +583,20 @@ int AFPReadFromRing(AFPThreadVars *ptv) SCReturnInt(AFP_FAILURE); } + if (ptv->flags & AFP_RING_MODE) { + p->afp_v.relptr = h.raw; + p->ReleaseData = AFPReleaseDataFromRing; + + p->afp_v.copy_mode = ptv->copy_mode; + if (p->afp_v.copy_mode != AFP_COPY_MODE_NONE) { + p->afp_v.peer = ptv->mpeer->peer; + } else { + p->afp_v.peer = NULL; + } + } + + from = (void *)h.raw + TPACKET_ALIGN(ptv->tp_hdrlen); + ptv->pkts++; ptv->bytes += h.h2->tp_len; (void) SC_ATOMIC_ADD(ptv->livedev->pkts, 1); @@ -422,7 +605,6 @@ int AFPReadFromRing(AFPThreadVars *ptv) /* add forged header */ if (ptv->cooked) { SllHdr * hdrp = (SllHdr *)ptv->data; - struct sockaddr_ll *from = (void *)h.raw + TPACKET_ALIGN(ptv->tp_hdrlen); /* XXX this is minimalist, but this seems enough */ hdrp->sll_protocol = from->sll_protocol; } @@ -436,6 +618,18 @@ int AFPReadFromRing(AFPThreadVars *ptv) if (PacketSetData(p, (unsigned char*)h.raw + h.h2->tp_mac, h.h2->tp_snaplen) == -1) { TmqhOutputPacketpool(ptv->tv, p); SCReturnInt(AFP_FAILURE); + } else { + if (ptv->flags & AFP_RING_MODE) { + p->afp_v.relptr = h.raw; + + p->afp_v.copy_mode = ptv->copy_mode; + if (p->afp_v.copy_mode != AFP_COPY_MODE_NONE) { + p->afp_v.peer = ptv->mpeer->peer; + } else { + p->afp_v.peer = NULL; + } + p->ReleaseData = AFPReleaseDataFromRing; + } } } else { if (PacketCopyData(p, (unsigned char*)h.raw + h.h2->tp_mac, h.h2->tp_snaplen) == -1) { @@ -499,7 +693,6 @@ static int AFPTryReopen(AFPThreadVars *ptv) } SCLogInfo("Recovering interface listening"); - ptv->afp_state = AFP_STATE_UP; return 0; } @@ -525,6 +718,9 @@ TmEcode ReceiveAFPLoop(ThreadVars *tv, void *data, void *slot) /* Start by checking the state of our interface */ if (unlikely(ptv->afp_state == AFP_STATE_DOWN)) { int dbreak = 0; + + AFPPeerUpdate(ptv); + do { usleep(AFP_RECONNECT_TIMEOUT); if (suricata_ctl_flags != 0) { @@ -702,6 +898,7 @@ static int AFPCreateSocket(AFPThreadVars *ptv, char *devname, int verbose) struct sockaddr_ll bind_address; int order; unsigned int i; + int if_idx; /* open socket */ ptv->socket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); @@ -709,12 +906,13 @@ static int AFPCreateSocket(AFPThreadVars *ptv, char *devname, int verbose) SCLogError(SC_ERR_AFP_CREATE, "Couldn't create a AF_PACKET socket, error %s", strerror(errno)); return -1; } - SCLogDebug("using interface %s", (char *)devname); + SCLogInfo("Using interface '%s' via socket %d", (char *)devname, ptv->socket); + if_idx = AFPGetIfnumByDev(ptv->socket, devname, verbose); /* bind socket */ memset(&bind_address, 0, sizeof(bind_address)); bind_address.sll_family = AF_PACKET; bind_address.sll_protocol = htons(ETH_P_ALL); - bind_address.sll_ifindex = AFPGetIfnumByDev(ptv->socket, devname, verbose); + bind_address.sll_ifindex = if_idx; if (bind_address.sll_ifindex == -1) { if (verbose) SCLogError(SC_ERR_AFP_CREATE, "Couldn't find iface %s", devname); @@ -898,6 +1096,8 @@ static int AFPCreateSocket(AFPThreadVars *ptv, char *devname, int verbose) /* Init is ok */ ptv->afp_state = AFP_STATE_UP; + + AFPPeerUpdate(ptv); return 0; } @@ -1027,6 +1227,9 @@ TmEcode ReceiveAFPThreadInit(ThreadVars *tv, void *initdata, void **data) { if (active_runmode && !strcmp("workers", active_runmode)) { ptv->flags |= AFP_ZERO_COPY; SCLogInfo("Enabling zero copy mode"); + } else { + /* If we are using copy mode we need a lock */ + ptv->flags |= AFP_SOCK_PROTECT; } /* If we are in RING mode, then we can use ZERO copy @@ -1044,6 +1247,16 @@ TmEcode ReceiveAFPThreadInit(ThreadVars *tv, void *initdata, void **data) { SCReturnInt(TM_ECODE_FAILED); } + ptv->copy_mode = afpconfig->copy_mode; + if (ptv->copy_mode != AFP_COPY_MODE_NONE) { + strlcpy(ptv->out_iface, afpconfig->out_iface, AFP_IFACE_NAME_LENGTH); + ptv->out_iface[AFP_IFACE_NAME_LENGTH - 1]= '\0'; + if (AFPPeersListAdd(ptv) == TM_ECODE_FAILED) { + SCFree(ptv); + afpconfig->DerefFunc(afpconfig); + SCReturnInt(TM_ECODE_FAILED); + } + } #define T_DATA_SIZE 70000 @@ -1099,6 +1312,7 @@ TmEcode ReceiveAFPThreadDeinit(ThreadVars *tv, void *data) { ptv->bpf_filter = NULL; close(ptv->socket); + SCReturnInt(TM_ECODE_OK); } diff --git a/src/source-af-packet.h b/src/source-af-packet.h index 97dc2c29c7..43bb21df5b 100644 --- a/src/source-af-packet.h +++ b/src/source-af-packet.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2011 Open Information Security Foundation +/* Copyright (C) 2011,2012 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 @@ -33,14 +33,19 @@ #define PACKET_FANOUT_LB 1 #define PACKET_FANOUT_CPU 2 #define PACKET_FANOUT_FLAG_DEFRAG 0x8000 - #else /* HAVE_PACKET_FANOUT */ #include #endif /* HAVE_PACKET_FANOUT */ +#include "queue.h" /* value for flags */ #define AFP_RING_MODE (1<<0) #define AFP_ZERO_COPY (1<<1) +#define AFP_SOCK_PROTECT (1<<2) + +#define AFP_COPY_MODE_NONE 0 +#define AFP_COPY_MODE_TAP 1 +#define AFP_COPY_MODE_IPS 2 #define AFP_FILE_MAX_PKTS 256 #define AFP_IFACE_NAME_LENGTH 48 @@ -61,20 +66,40 @@ typedef struct AFPIfaceConfig_ int promisc; /* misc use flags including ring mode */ int flags; + int copy_mode; ChecksumValidationMode checksum_mode; char *bpf_filter; + char *out_iface; SC_ATOMIC_DECLARE(unsigned int, ref); void (*DerefFunc)(void *); } AFPIfaceConfig; +typedef struct AFPPeer_ { + char iface[AFP_IFACE_NAME_LENGTH]; + SC_ATOMIC_DECLARE(int, socket); + SC_ATOMIC_DECLARE(int, if_idx); + SC_ATOMIC_DECLARE(uint8_t, state); + SCMutex sock_protect; + int flags; + struct AFPPeer_ *peer; + TAILQ_ENTRY(AFPPeer_) next; +} AFPPeer; + /* per packet AF_PACKET vars */ typedef struct AFPPacketVars_ { void *relptr; + int copy_mode; + AFPPeer *peer; } AFPPacketVars; void TmModuleReceiveAFPRegister (void); void TmModuleDecodeAFPRegister (void); +TmEcode AFPPeersListInit(); +TmEcode AFPPeersListCheck(); +void AFPPeersListClean(); + + #endif /* __SOURCE_AFP_H__ */ diff --git a/src/suricata.c b/src/suricata.c index 13fa3d39d6..521dc3ce75 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -2015,6 +2015,8 @@ int main(int argc, char **argv) TmqhCleanup(); TmModuleRunDeInit(); + AFPPeersListClean(); + #ifdef PROFILING if (profiling_rules_enabled) SCProfilingDump(); diff --git a/suricata.yaml.in b/suricata.yaml.in index 4fc9ef6dc3..224bd349aa 100644 --- a/suricata.yaml.in +++ b/suricata.yaml.in @@ -253,6 +253,13 @@ af-packet: #checksum-checks: kernel # BPF filter to apply to this interface. The pcap filter syntax apply here. #bpf-filter: port 80 or udp + # You can use the following variables to activate AF_PACKET tap od IPS mode. + # If copy-mode is set to ips or tap, the traffic coming to the current + # interface will be copied to the copy-iface interface. If 'tap' is set, the + # copy is complete. If 'ips' is set, the packet matching a 'drop' action + # will not be copied. + #copy-mode: ips + #copy-iface: eth1 - interface: eth1 threads: 1 cluster-id: 98