]> git.ipfire.org Git - people/ms/suricata.git/blame - src/source-af-packet.c
AC: shrink output table after initialization
[people/ms/suricata.git] / src / source-af-packet.c
CommitLineData
b076a26c 1/* Copyright (C) 2011-2013 Open Information Security Foundation
c45d8985
EL
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
a6457262
EL
18/**
19 * \defgroup afppacket AF_PACKET running mode
20 *
21 * @{
22 */
23
c45d8985
EL
24/**
25 * \file
26 *
27 * \author Eric Leblond <eric@regit.org>
28 *
29 * AF_PACKET socket acquisition support
30 *
e80b30c0
EL
31 * \todo watch other interface event to detect suppression of the monitored
32 * interface
c45d8985
EL
33 */
34
35#include "suricata-common.h"
e80b30c0 36#include "config.h"
c45d8985
EL
37#include "suricata.h"
38#include "decode.h"
39#include "packet-queue.h"
40#include "threads.h"
41#include "threadvars.h"
42#include "tm-queuehandlers.h"
43#include "tm-modules.h"
44#include "tm-threads.h"
45#include "tm-threads-common.h"
46#include "conf.h"
47#include "util-debug.h"
51eb9605 48#include "util-device.h"
c45d8985
EL
49#include "util-error.h"
50#include "util-privs.h"
e80b30c0 51#include "util-optimize.h"
51eb9605 52#include "util-checksum.h"
ac56b1bf 53#include "util-ioctl.h"
2cd6e128 54#include "util-host-info.h"
c45d8985
EL
55#include "tmqh-packetpool.h"
56#include "source-af-packet.h"
34b3f194 57#include "runmodes.h"
c45d8985 58
e7f09f24
AS
59#ifdef __SC_CUDA_SUPPORT__
60
61#include "util-cuda.h"
62#include "util-cuda-buffer.h"
63#include "util-mpm-ac.h"
64#include "util-cuda-handlers.h"
65#include "detect-engine.h"
66#include "detect-engine-mpm.h"
67#include "util-cuda-vars.h"
68
69#endif /* __SC_CUDA_SUPPORT__ */
70
e80b30c0 71#ifdef HAVE_AF_PACKET
472e061c
VJ
72
73#if HAVE_SYS_IOCTL_H
2bc0be6e 74#include <sys/ioctl.h>
472e061c
VJ
75#endif
76
77#if HAVE_LINUX_IF_ETHER_H
c45d8985 78#include <linux/if_ether.h>
472e061c
VJ
79#endif
80
81#if HAVE_LINUX_IF_PACKET_H
c45d8985 82#include <linux/if_packet.h>
472e061c
VJ
83#endif
84
85#if HAVE_LINUX_IF_ARP_H
c45d8985 86#include <linux/if_arp.h>
472e061c 87#endif
f2a6fb8a 88
472e061c 89#if HAVE_LINUX_FILTER_H
f2a6fb8a 90#include <linux/filter.h>
e80b30c0 91#endif
c45d8985 92
472e061c 93#if HAVE_SYS_MMAN_H
49b7b00f 94#include <sys/mman.h>
472e061c
VJ
95#endif
96
97#endif /* HAVE_AF_PACKET */
49b7b00f 98
c45d8985
EL
99extern uint8_t suricata_ctl_flags;
100extern int max_pending_packets;
101
e80b30c0
EL
102#ifndef HAVE_AF_PACKET
103
104TmEcode NoAFPSupportExit(ThreadVars *, void *, void **);
105
106void TmModuleReceiveAFPRegister (void) {
107 tmm_modules[TMM_RECEIVEAFP].name = "ReceiveAFP";
108 tmm_modules[TMM_RECEIVEAFP].ThreadInit = NoAFPSupportExit;
109 tmm_modules[TMM_RECEIVEAFP].Func = NULL;
110 tmm_modules[TMM_RECEIVEAFP].ThreadExitPrintStats = NULL;
111 tmm_modules[TMM_RECEIVEAFP].ThreadDeinit = NULL;
112 tmm_modules[TMM_RECEIVEAFP].RegisterTests = NULL;
113 tmm_modules[TMM_RECEIVEAFP].cap_flags = 0;
3f1c4efc 114 tmm_modules[TMM_RECEIVEAFP].flags = TM_FLAG_RECEIVE_TM;
e80b30c0
EL
115}
116
117/**
118 * \brief Registration Function for DecodeAFP.
119 * \todo Unit tests are needed for this module.
120 */
121void TmModuleDecodeAFPRegister (void) {
122 tmm_modules[TMM_DECODEAFP].name = "DecodeAFP";
123 tmm_modules[TMM_DECODEAFP].ThreadInit = NoAFPSupportExit;
124 tmm_modules[TMM_DECODEAFP].Func = NULL;
125 tmm_modules[TMM_DECODEAFP].ThreadExitPrintStats = NULL;
126 tmm_modules[TMM_DECODEAFP].ThreadDeinit = NULL;
127 tmm_modules[TMM_DECODEAFP].RegisterTests = NULL;
128 tmm_modules[TMM_DECODEAFP].cap_flags = 0;
bc6cf438 129 tmm_modules[TMM_DECODEAFP].flags = TM_FLAG_DECODE_TM;
e80b30c0
EL
130}
131
132/**
133 * \brief this function prints an error message and exits.
134 */
135TmEcode NoAFPSupportExit(ThreadVars *tv, void *initdata, void **data)
136{
137 SCLogError(SC_ERR_NO_AF_PACKET,"Error creating thread %s: you do not have "
138 "support for AF_PACKET enabled, on Linux host please recompile "
139 "with --enable-af-packet", tv->name);
140 exit(EXIT_FAILURE);
141}
142
143#else /* We have AF_PACKET support */
144
c45d8985
EL
145#define AFP_IFACE_NAME_LENGTH 48
146
147#define AFP_STATE_DOWN 0
148#define AFP_STATE_UP 1
149
150#define AFP_RECONNECT_TIMEOUT 500000
13f13b6d 151#define AFP_DOWN_COUNTER_INTERVAL 40
c45d8985
EL
152
153#define POLL_TIMEOUT 100
154
4a1a0080
EL
155#ifndef TP_STATUS_USER_BUSY
156/* for new use latest bit available in tp_status */
157#define TP_STATUS_USER_BUSY (1 << 31)
158#endif
159
b603ad62
EL
160#ifndef TP_STATUS_VLAN_VALID
161#define TP_STATUS_VLAN_VALID (1 << 4)
162#endif
163
f2a6fb8a 164/** protect pfring_set_bpf_filter, as it is not thread safe */
5532af46 165static SCMutex afpacket_bpf_set_filter_lock = SCMUTEX_INITIALIZER;
f2a6fb8a 166
62e63e3f
EL
167enum {
168 AFP_READ_OK,
169 AFP_READ_FAILURE,
170 AFP_FAILURE,
27b5136b 171 AFP_KERNEL_DROP,
62e63e3f
EL
172};
173
1992a227
EL
174enum {
175 AFP_FATAL_ERROR = 1,
176 AFP_RECOVERABLE_ERROR,
177};
178
49b7b00f
EL
179union thdr {
180 struct tpacket2_hdr *h2;
181 void *raw;
182};
183
c45d8985
EL
184/**
185 * \brief Structure to hold thread specific variables.
186 */
187typedef struct AFPThreadVars_
188{
189 /* thread specific socket */
190 int socket;
191 /* handle state */
192 unsigned char afp_state;
c45d8985
EL
193
194 /* data link type for the thread */
195 int datalink;
196 int cooked;
197
198 /* counters */
3ce39433 199 uint64_t pkts;
c45d8985 200 uint64_t bytes;
3ce39433 201 uint64_t errs;
c45d8985 202
ff6365dd
EL
203 ThreadVars *tv;
204 TmSlot *slot;
205
206 uint8_t *data; /** Per function and thread data */
207 int datalen; /** Length of per function and thread data */
208
71e47868
EL
209 int vlan_disabled;
210
ff6365dd 211 char iface[AFP_IFACE_NAME_LENGTH];
51eb9605 212 LiveDevice *livedev;
13f13b6d 213 int down_count;
51eb9605 214
f2a6fb8a
EL
215 /* Filter */
216 char *bpf_filter;
217
e80b30c0
EL
218 /* socket buffer size */
219 int buffer_size;
df7dbe36 220 int promisc;
6062e00c 221 ChecksumValidationMode checksum_mode;
e80b30c0 222
662dccd8
EL
223 /* IPS stuff */
224 char out_iface[AFP_IFACE_NAME_LENGTH];
225 AFPPeer *mpeer;
226
49b7b00f 227 int flags;
6efd37a3
EL
228 uint16_t capture_kernel_packets;
229 uint16_t capture_kernel_drops;
49b7b00f 230
e80b30c0
EL
231 int cluster_id;
232 int cluster_type;
c45d8985 233
fbca1a4e 234 int threads;
662dccd8 235 int copy_mode;
fbca1a4e 236
49b7b00f
EL
237 struct tpacket_req req;
238 unsigned int tp_hdrlen;
239 unsigned int ring_buflen;
240 char *ring_buf;
241 char *frame_buf;
242 unsigned int frame_offset;
8879df80 243 int ring_size;
662dccd8 244
c45d8985
EL
245} AFPThreadVars;
246
247TmEcode ReceiveAFP(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *);
248TmEcode ReceiveAFPThreadInit(ThreadVars *, void *, void **);
249void ReceiveAFPThreadExitStats(ThreadVars *, void *);
250TmEcode ReceiveAFPThreadDeinit(ThreadVars *, void *);
e80b30c0 251TmEcode ReceiveAFPLoop(ThreadVars *tv, void *data, void *slot);
c45d8985
EL
252
253TmEcode DecodeAFPThreadInit(ThreadVars *, void *, void **);
2864f9ee 254TmEcode DecodeAFPThreadDeinit(ThreadVars *tv, void *data);
c45d8985
EL
255TmEcode DecodeAFP(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *);
256
f2a6fb8a 257TmEcode AFPSetBPFFilter(AFPThreadVars *ptv);
662dccd8 258static int AFPGetIfnumByDev(int fd, const char *ifname, int verbose);
13f13b6d
EL
259static int AFPGetDevFlags(int fd, const char *ifname);
260static int AFPDerefSocket(AFPPeer* peer);
261static int AFPRefSocket(AFPPeer* peer);
f2a6fb8a 262
c45d8985
EL
263/**
264 * \brief Registration Function for RecieveAFP.
265 * \todo Unit tests are needed for this module.
266 */
267void TmModuleReceiveAFPRegister (void) {
268 tmm_modules[TMM_RECEIVEAFP].name = "ReceiveAFP";
269 tmm_modules[TMM_RECEIVEAFP].ThreadInit = ReceiveAFPThreadInit;
ff6365dd 270 tmm_modules[TMM_RECEIVEAFP].Func = NULL;
e80b30c0 271 tmm_modules[TMM_RECEIVEAFP].PktAcqLoop = ReceiveAFPLoop;
c45d8985
EL
272 tmm_modules[TMM_RECEIVEAFP].ThreadExitPrintStats = ReceiveAFPThreadExitStats;
273 tmm_modules[TMM_RECEIVEAFP].ThreadDeinit = NULL;
274 tmm_modules[TMM_RECEIVEAFP].RegisterTests = NULL;
275 tmm_modules[TMM_RECEIVEAFP].cap_flags = SC_CAP_NET_RAW;
cd4705e6 276 tmm_modules[TMM_RECEIVEAFP].flags = TM_FLAG_RECEIVE_TM;
c45d8985
EL
277}
278
a6457262
EL
279
280/**
281 * \defgroup afppeers AFP peers list
282 *
283 * AF_PACKET has an IPS mode were interface are peered: packet from
284 * on interface are sent the peered interface and the other way. The ::AFPPeer
285 * list is maitaining the list of peers. Each ::AFPPeer is storing the needed
286 * information to be able to send packet on the interface.
287 * A element of the list must not be destroyed during the run of Suricata as it
288 * is used by ::Packet and other threads.
289 *
290 * @{
291 */
292
662dccd8
EL
293typedef struct AFPPeersList_ {
294 TAILQ_HEAD(, AFPPeer_) peers; /**< Head of list of fragments. */
295 int cnt;
296 int peered;
60400163
EL
297 int turn; /**< Next value for initialisation order */
298 SC_ATOMIC_DECLARE(int, reached); /**< Counter used to synchronize start */
662dccd8
EL
299} AFPPeersList;
300
301/**
a6457262
EL
302 * \brief Update the peer.
303 *
304 * Update the AFPPeer of a thread ie set new state, socket number
305 * or iface index.
306 *
662dccd8
EL
307 */
308void AFPPeerUpdate(AFPThreadVars *ptv)
309{
310 if (ptv->mpeer == NULL) {
311 return;
312 }
662dccd8
EL
313 (void)SC_ATOMIC_SET(ptv->mpeer->if_idx, AFPGetIfnumByDev(ptv->socket, ptv->iface, 0));
314 (void)SC_ATOMIC_SET(ptv->mpeer->socket, ptv->socket);
315 (void)SC_ATOMIC_SET(ptv->mpeer->state, ptv->afp_state);
316}
317
a6457262
EL
318/**
319 * \brief Clean and free ressource used by an ::AFPPeer
320 */
662dccd8
EL
321void AFPPeerClean(AFPPeer *peer)
322{
323 if (peer->flags & AFP_SOCK_PROTECT)
324 SCMutexDestroy(&peer->sock_protect);
325 SC_ATOMIC_DESTROY(peer->socket);
326 SC_ATOMIC_DESTROY(peer->if_idx);
327 SC_ATOMIC_DESTROY(peer->state);
328 SCFree(peer);
329}
330
331AFPPeersList peerslist;
332
333
a6457262
EL
334/**
335 * \brief Init the global list of ::AFPPeer
336 */
662dccd8
EL
337TmEcode AFPPeersListInit()
338{
339 SCEnter();
340 TAILQ_INIT(&peerslist.peers);
341 peerslist.peered = 0;
342 peerslist.cnt = 0;
60400163
EL
343 peerslist.turn = 0;
344 SC_ATOMIC_INIT(peerslist.reached);
345 (void) SC_ATOMIC_SET(peerslist.reached, 0);
662dccd8
EL
346 SCReturnInt(TM_ECODE_OK);
347}
348
a6457262
EL
349/**
350 * \brief Check that all ::AFPPeer got a peer
351 *
352 * \retval TM_ECODE_FAILED if some threads are not peered or TM_ECODE_OK else.
353 */
662dccd8
EL
354TmEcode AFPPeersListCheck()
355{
356#define AFP_PEERS_MAX_TRY 4
357#define AFP_PEERS_WAIT 20000
358 int try = 0;
359 SCEnter();
360 while (try < AFP_PEERS_MAX_TRY) {
361 if (peerslist.cnt != peerslist.peered) {
362 usleep(AFP_PEERS_WAIT);
363 } else {
364 SCReturnInt(TM_ECODE_OK);
365 }
366 try++;
367 }
368 SCLogError(SC_ERR_AFP_CREATE, "Threads number not equals");
369 SCReturnInt(TM_ECODE_FAILED);
370}
371
a6457262
EL
372/**
373 * \brief Declare a new AFP thread to AFP peers list.
374 */
662dccd8
EL
375TmEcode AFPPeersListAdd(AFPThreadVars *ptv)
376{
377 SCEnter();
378 AFPPeer *peer = SCMalloc(sizeof(AFPPeer));
379 AFPPeer *pitem;
ac56b1bf 380 int mtu, out_mtu;
662dccd8 381
e176be6f 382 if (unlikely(peer == NULL)) {
662dccd8
EL
383 SCReturnInt(TM_ECODE_FAILED);
384 }
385 memset(peer, 0, sizeof(AFPPeer));
386 SC_ATOMIC_INIT(peer->socket);
13f13b6d 387 SC_ATOMIC_INIT(peer->sock_usage);
662dccd8
EL
388 SC_ATOMIC_INIT(peer->if_idx);
389 SC_ATOMIC_INIT(peer->state);
390 peer->flags = ptv->flags;
60400163 391 peer->turn = peerslist.turn++;
662dccd8
EL
392
393 if (peer->flags & AFP_SOCK_PROTECT) {
394 SCMutexInit(&peer->sock_protect, NULL);
395 }
396
13f13b6d 397 (void)SC_ATOMIC_SET(peer->sock_usage, 0);
662dccd8
EL
398 (void)SC_ATOMIC_SET(peer->state, AFP_STATE_DOWN);
399 strlcpy(peer->iface, ptv->iface, AFP_IFACE_NAME_LENGTH);
400 ptv->mpeer = peer;
401 /* add element to iface list */
402 TAILQ_INSERT_TAIL(&peerslist.peers, peer, next);
662dccd8 403
13f13b6d
EL
404 if (ptv->copy_mode != AFP_COPY_MODE_NONE) {
405 peerslist.cnt++;
406
407 /* Iter to find a peer */
408 TAILQ_FOREACH(pitem, &peerslist.peers, next) {
409 if (pitem->peer)
410 continue;
411 if (strcmp(pitem->iface, ptv->out_iface))
412 continue;
413 peer->peer = pitem;
414 pitem->peer = peer;
415 mtu = GetIfaceMTU(ptv->iface);
416 out_mtu = GetIfaceMTU(ptv->out_iface);
417 if (mtu != out_mtu) {
418 SCLogError(SC_ERR_AFP_CREATE,
419 "MTU on %s (%d) and %s (%d) are not equal, "
420 "transmission of packets bigger than %d will fail.",
421 ptv->iface, mtu,
422 ptv->out_iface, out_mtu,
423 (out_mtu > mtu) ? mtu : out_mtu);
424 }
425 peerslist.peered += 2;
426 break;
ac56b1bf 427 }
662dccd8
EL
428 }
429
430 AFPPeerUpdate(ptv);
431
432 SCReturnInt(TM_ECODE_OK);
433}
434
60400163
EL
435int AFPPeersListWaitTurn(AFPPeer *peer)
436{
b2691cbe
EL
437 /* If turn is zero, we already have started threads once */
438 if (peerslist.turn == 0)
439 return 0;
440
60400163
EL
441 if (peer->turn == SC_ATOMIC_GET(peerslist.reached))
442 return 0;
443 return 1;
444}
445
446void AFPPeersListReachedInc()
447{
b2691cbe
EL
448 if (peerslist.turn == 0)
449 return;
450
451 if (SC_ATOMIC_ADD(peerslist.reached, 1) == peerslist.turn) {
452 SCLogInfo("All AFP capture threads are running.");
453 (void)SC_ATOMIC_SET(peerslist.reached, 0);
454 /* Set turn to 0 to skip syncrhonization when ReceiveAFPLoop is
455 * restarted.
456 */
457 peerslist.turn = 0;
458 }
60400163
EL
459}
460
919377d4
EL
461static int AFPPeersListStarted()
462{
463 return !peerslist.turn;
464}
465
a6457262
EL
466/**
467 * \brief Clean the global peers list.
468 */
662dccd8
EL
469void AFPPeersListClean()
470{
471 AFPPeer *pitem;
472
473 while ((pitem = TAILQ_FIRST(&peerslist.peers))) {
474 TAILQ_REMOVE(&peerslist.peers, pitem, next);
475 AFPPeerClean(pitem);
476 }
477}
478
a6457262
EL
479/**
480 * @}
481 */
482
c45d8985
EL
483/**
484 * \brief Registration Function for DecodeAFP.
485 * \todo Unit tests are needed for this module.
486 */
487void TmModuleDecodeAFPRegister (void) {
488 tmm_modules[TMM_DECODEAFP].name = "DecodeAFP";
489 tmm_modules[TMM_DECODEAFP].ThreadInit = DecodeAFPThreadInit;
490 tmm_modules[TMM_DECODEAFP].Func = DecodeAFP;
491 tmm_modules[TMM_DECODEAFP].ThreadExitPrintStats = NULL;
2864f9ee 492 tmm_modules[TMM_DECODEAFP].ThreadDeinit = DecodeAFPThreadDeinit;
c45d8985
EL
493 tmm_modules[TMM_DECODEAFP].RegisterTests = NULL;
494 tmm_modules[TMM_DECODEAFP].cap_flags = 0;
bc6cf438 495 tmm_modules[TMM_DECODEAFP].flags = TM_FLAG_DECODE_TM;
c45d8985
EL
496}
497
662dccd8 498
e80b30c0
EL
499static int AFPCreateSocket(AFPThreadVars *ptv, char *devname, int verbose);
500
e8a4a4c4 501static inline void AFPDumpCounters(AFPThreadVars *ptv)
6efd37a3 502{
6efd37a3 503#ifdef PACKET_STATISTICS
e8a4a4c4
EL
504 struct tpacket_stats kstats;
505 socklen_t len = sizeof (struct tpacket_stats);
506 if (getsockopt(ptv->socket, SOL_PACKET, PACKET_STATISTICS,
507 &kstats, &len) > -1) {
508 SCLogDebug("(%s) Kernel: Packets %" PRIu32 ", dropped %" PRIu32 "",
509 ptv->tv->name,
510 kstats.tp_packets, kstats.tp_drops);
511 SCPerfCounterAddUI64(ptv->capture_kernel_packets, ptv->tv->sc_perf_pca, kstats.tp_packets);
512 SCPerfCounterAddUI64(ptv->capture_kernel_drops, ptv->tv->sc_perf_pca, kstats.tp_drops);
3ce39433
EL
513 (void) SC_ATOMIC_ADD(ptv->livedev->drop, (uint64_t) kstats.tp_drops);
514 (void) SC_ATOMIC_ADD(ptv->livedev->pkts, (uint64_t) kstats.tp_packets);
6efd37a3 515 }
e8a4a4c4 516#endif
6efd37a3 517}
c45d8985
EL
518
519/**
520 * \brief AF packet read function.
521 *
522 * This function fills
523 * From here the packets are picked up by the DecodeAFP thread.
524 *
525 * \param user pointer to AFPThreadVars
526 * \retval TM_ECODE_FAILED on failure and TM_ECODE_OK on success
527 */
62e63e3f 528int AFPRead(AFPThreadVars *ptv)
c45d8985
EL
529{
530 Packet *p = NULL;
531 /* XXX should try to use read that get directly to packet */
c45d8985
EL
532 int offset = 0;
533 int caplen;
534 struct sockaddr_ll from;
535 struct iovec iov;
536 struct msghdr msg;
c45d8985
EL
537 struct cmsghdr *cmsg;
538 union {
539 struct cmsghdr cmsg;
540 char buf[CMSG_SPACE(sizeof(struct tpacket_auxdata))];
541 } cmsg_buf;
6efd37a3 542 unsigned char aux_checksum = 0;
c45d8985
EL
543
544 msg.msg_name = &from;
545 msg.msg_namelen = sizeof(from);
546 msg.msg_iov = &iov;
547 msg.msg_iovlen = 1;
c45d8985
EL
548 msg.msg_control = &cmsg_buf;
549 msg.msg_controllen = sizeof(cmsg_buf);
c45d8985
EL
550 msg.msg_flags = 0;
551
552 if (ptv->cooked)
553 offset = SLL_HEADER_LEN;
554 else
555 offset = 0;
e80b30c0
EL
556 iov.iov_len = ptv->datalen - offset;
557 iov.iov_base = ptv->data + offset;
c45d8985
EL
558
559 caplen = recvmsg(ptv->socket, &msg, MSG_TRUNC);
560
561 if (caplen < 0) {
562 SCLogWarning(SC_ERR_AFP_READ, "recvmsg failed with error code %" PRId32,
563 errno);
62e63e3f 564 SCReturnInt(AFP_READ_FAILURE);
c45d8985 565 }
ff6365dd
EL
566
567 p = PacketGetFromQueueOrAlloc();
c45d8985 568 if (p == NULL) {
62e63e3f 569 SCReturnInt(AFP_FAILURE);
c45d8985 570 }
b33986c8 571 PKT_SET_SRC(p, PKT_SRC_WIRE);
c45d8985
EL
572
573 /* get timestamp of packet via ioctl */
574 if (ioctl(ptv->socket, SIOCGSTAMP, &p->ts) == -1) {
575 SCLogWarning(SC_ERR_AFP_READ, "recvmsg failed with error code %" PRId32,
576 errno);
577 TmqhOutputPacketpool(ptv->tv, p);
62e63e3f 578 SCReturnInt(AFP_READ_FAILURE);
c45d8985
EL
579 }
580
581 ptv->pkts++;
582 ptv->bytes += caplen + offset;
51eb9605 583 p->livedev = ptv->livedev;
c45d8985
EL
584
585 /* add forged header */
586 if (ptv->cooked) {
e80b30c0 587 SllHdr * hdrp = (SllHdr *)ptv->data;
c45d8985
EL
588 /* XXX this is minimalist, but this seems enough */
589 hdrp->sll_protocol = from.sll_protocol;
590 }
591
592 p->datalink = ptv->datalink;
593 SET_PKT_LEN(p, caplen + offset);
e80b30c0 594 if (PacketCopyData(p, ptv->data, GET_PKT_LEN(p)) == -1) {
c45d8985 595 TmqhOutputPacketpool(ptv->tv, p);
62e63e3f 596 SCReturnInt(AFP_FAILURE);
c45d8985 597 }
e80b30c0
EL
598 SCLogDebug("pktlen: %" PRIu32 " (pkt %p, pkt data %p)",
599 GET_PKT_LEN(p), p, GET_PKT_DATA(p));
600
6062e00c
EL
601 /* We only check for checksum disable */
602 if (ptv->checksum_mode == CHECKSUM_VALIDATION_DISABLE) {
51eb9605
EL
603 p->flags |= PKT_IGNORE_CHECKSUM;
604 } else if (ptv->checksum_mode == CHECKSUM_VALIDATION_AUTO) {
605 if (ptv->livedev->ignore_checksum) {
606 p->flags |= PKT_IGNORE_CHECKSUM;
a565148f 607 } else if (ChecksumAutoModeCheck(ptv->pkts,
51eb9605
EL
608 SC_ATOMIC_GET(ptv->livedev->pkts),
609 SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) {
610 ptv->livedev->ignore_checksum = 1;
6062e00c 611 p->flags |= PKT_IGNORE_CHECKSUM;
51eb9605 612 }
6062e00c 613 } else {
6efd37a3
EL
614 aux_checksum = 1;
615 }
6062e00c 616
6efd37a3
EL
617 /* List is NULL if we don't have activated auxiliary data */
618 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
619 struct tpacket_auxdata *aux;
f6ddaf33 620
6efd37a3
EL
621 if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct tpacket_auxdata)) ||
622 cmsg->cmsg_level != SOL_PACKET ||
623 cmsg->cmsg_type != PACKET_AUXDATA)
624 continue;
f6ddaf33 625
6efd37a3
EL
626 aux = (struct tpacket_auxdata *)CMSG_DATA(cmsg);
627
628 if (aux_checksum && (aux->tp_status & TP_STATUS_CSUMNOTREADY)) {
629 p->flags |= PKT_IGNORE_CHECKSUM;
f6ddaf33 630 }
6efd37a3 631 break;
f6ddaf33
EL
632 }
633
c469824b
EL
634 if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) {
635 TmqhOutputPacketpool(ptv->tv, p);
62e63e3f 636 SCReturnInt(AFP_FAILURE);
c469824b 637 }
62e63e3f 638 SCReturnInt(AFP_READ_OK);
c45d8985
EL
639}
640
662dccd8
EL
641TmEcode AFPWritePacket(Packet *p)
642{
643 struct sockaddr_ll socket_address;
644 int socket;
645
646 if (p->afp_v.copy_mode == AFP_COPY_MODE_IPS) {
3f107fa1 647 if (PACKET_TEST_ACTION(p, ACTION_DROP)) {
662dccd8
EL
648 return TM_ECODE_OK;
649 }
650 }
651
652 if (SC_ATOMIC_GET(p->afp_v.peer->state) == AFP_STATE_DOWN)
653 return TM_ECODE_OK;
654
655 if (p->ethh == NULL) {
656 SCLogWarning(SC_ERR_INVALID_VALUE, "Should have an Ethernet header");
657 return TM_ECODE_FAILED;
658 }
659 /* Index of the network device */
660 socket_address.sll_ifindex = SC_ATOMIC_GET(p->afp_v.peer->if_idx);
661 /* Address length*/
662 socket_address.sll_halen = ETH_ALEN;
663 /* Destination MAC */
664 memcpy(socket_address.sll_addr, p->ethh, 6);
665
666 /* Send packet, locking the socket if necessary */
667 if (p->afp_v.peer->flags & AFP_SOCK_PROTECT)
668 SCMutexLock(&p->afp_v.peer->sock_protect);
669 socket = SC_ATOMIC_GET(p->afp_v.peer->socket);
670 if (sendto(socket, GET_PKT_DATA(p), GET_PKT_LEN(p), 0,
671 (struct sockaddr*) &socket_address,
672 sizeof(struct sockaddr_ll)) < 0) {
673 SCLogWarning(SC_ERR_SOCKET, "Sending packet failed on socket %d: %s",
674 socket,
675 strerror(errno));
676 if (p->afp_v.peer->flags & AFP_SOCK_PROTECT)
677 SCMutexUnlock(&p->afp_v.peer->sock_protect);
678 return TM_ECODE_FAILED;
679 }
680 if (p->afp_v.peer->flags & AFP_SOCK_PROTECT)
681 SCMutexUnlock(&p->afp_v.peer->sock_protect);
682
683 return TM_ECODE_OK;
684}
685
b076a26c 686void AFPReleaseDataFromRing(Packet *p)
2011a3f8 687{
662dccd8
EL
688 /* Need to be in copy mode and need to detect early release
689 where Ethernet header could not be set (and pseudo packet) */
690 if ((p->afp_v.copy_mode != AFP_COPY_MODE_NONE) && !PKT_IS_PSEUDOPKT(p)) {
b076a26c 691 AFPWritePacket(p);
662dccd8 692 }
13f13b6d
EL
693
694 if (AFPDerefSocket(p->afp_v.mpeer) == 0)
680e941a 695 goto cleanup;
13f13b6d 696
2011a3f8
EL
697 if (p->afp_v.relptr) {
698 union thdr h;
699 h.raw = p->afp_v.relptr;
700 h.h2->tp_status = TP_STATUS_KERNEL;
2011a3f8 701 }
680e941a
EL
702
703cleanup:
704 AFPV_CLEANUP(&p->afp_v);
b076a26c
KS
705}
706
707void AFPReleasePacket(Packet *p)
708{
709 AFPReleaseDataFromRing(p);
710 PacketFreeOrRelease(p);
2011a3f8
EL
711}
712
49b7b00f
EL
713/**
714 * \brief AF packet read function for ring
715 *
716 * This function fills
717 * From here the packets are picked up by the DecodeAFP thread.
718 *
719 * \param user pointer to AFPThreadVars
720 * \retval TM_ECODE_FAILED on failure and TM_ECODE_OK on success
721 */
722int AFPReadFromRing(AFPThreadVars *ptv)
723{
724 Packet *p = NULL;
725 union thdr h;
662dccd8 726 struct sockaddr_ll *from;
27b5136b 727 uint8_t emergency_flush = 0;
4d8f70c6 728 int read_pkts = 0;
b26ec603 729 int loop_start = -1;
4d8f70c6 730
49b7b00f 731
a369f8c3
EL
732 /* Loop till we have packets available */
733 while (1) {
53c02334
AS
734 if (unlikely(suricata_ctl_flags != 0)) {
735 break;
736 }
737
a369f8c3
EL
738 /* Read packet from ring */
739 h.raw = (((union thdr **)ptv->frame_buf)[ptv->frame_offset]);
740 if (h.raw == NULL) {
34b3f194
EL
741 SCReturnInt(AFP_FAILURE);
742 }
662dccd8 743
82a2dd85 744 if ((! h.h2->tp_status) || (h.h2->tp_status & TP_STATUS_USER_BUSY)) {
4d8f70c6 745 if (read_pkts == 0) {
b26ec603
EL
746 if (loop_start == -1) {
747 loop_start = ptv->frame_offset;
748 } else if (unlikely(loop_start == (int)ptv->frame_offset)) {
749 SCReturnInt(AFP_READ_OK);
750 }
751 if (++ptv->frame_offset >= ptv->req.tp_frame_nr) {
752 ptv->frame_offset = 0;
753 }
754 continue;
4d8f70c6 755 }
27b5136b
EL
756 if ((emergency_flush) && (ptv->flags & AFP_EMERGENCY_MODE)) {
757 SCReturnInt(AFP_KERNEL_DROP);
758 } else {
759 SCReturnInt(AFP_READ_OK);
760 }
761 }
4d8f70c6
EL
762
763 read_pkts++;
b26ec603 764 loop_start = -1;
4d8f70c6 765
4a1a0080
EL
766 /* Our packet is still used by suricata, we exit read loop to
767 * gain some time */
768 if (h.h2->tp_status & TP_STATUS_USER_BUSY) {
769 SCReturnInt(AFP_READ_OK);
770 }
771
27b5136b
EL
772 if ((ptv->flags & AFP_EMERGENCY_MODE) && (emergency_flush == 1)) {
773 h.h2->tp_status = TP_STATUS_KERNEL;
774 goto next_frame;
a369f8c3
EL
775 }
776
777 p = PacketGetFromQueueOrAlloc();
778 if (p == NULL) {
34b3f194
EL
779 SCReturnInt(AFP_FAILURE);
780 }
b33986c8 781 PKT_SET_SRC(p, PKT_SRC_WIRE);
49b7b00f 782
4a1a0080
EL
783 /* Suricata will treat packet so telling it is busy, this
784 * status will be reset to 0 (ie TP_STATUS_KERNEL) in the release
785 * function. */
786 h.h2->tp_status |= TP_STATUS_USER_BUSY;
787
662dccd8
EL
788 from = (void *)h.raw + TPACKET_ALIGN(ptv->tp_hdrlen);
789
a369f8c3
EL
790 ptv->pkts++;
791 ptv->bytes += h.h2->tp_len;
a369f8c3
EL
792 p->livedev = ptv->livedev;
793
794 /* add forged header */
795 if (ptv->cooked) {
796 SllHdr * hdrp = (SllHdr *)ptv->data;
a369f8c3
EL
797 /* XXX this is minimalist, but this seems enough */
798 hdrp->sll_protocol = from->sll_protocol;
49b7b00f 799 }
a369f8c3
EL
800
801 p->datalink = ptv->datalink;
802 if (h.h2->tp_len > h.h2->tp_snaplen) {
803 SCLogDebug("Packet length (%d) > snaplen (%d), truncating",
804 h.h2->tp_len, h.h2->tp_snaplen);
805 }
71e47868
EL
806
807 /* get vlan id from header */
e871f713
EL
808 if ((!ptv->vlan_disabled) &&
809 (h.h2->tp_status & TP_STATUS_VLAN_VALID || h.h2->tp_vlan_tci)) {
71e47868
EL
810 p->vlan_id[0] = h.h2->tp_vlan_tci;
811 p->vlan_idx = 1;
812 p->vlanh[0] = NULL;
813 }
814
a369f8c3
EL
815 if (ptv->flags & AFP_ZERO_COPY) {
816 if (PacketSetData(p, (unsigned char*)h.raw + h.h2->tp_mac, h.h2->tp_snaplen) == -1) {
817 TmqhOutputPacketpool(ptv->tv, p);
818 SCReturnInt(AFP_FAILURE);
662dccd8 819 } else {
0f2b3406 820 p->afp_v.relptr = h.raw;
b076a26c 821 p->ReleasePacket = AFPReleasePacket;
5f12b234
EL
822 p->afp_v.mpeer = ptv->mpeer;
823 AFPRefSocket(ptv->mpeer);
0f2b3406
EL
824
825 p->afp_v.copy_mode = ptv->copy_mode;
826 if (p->afp_v.copy_mode != AFP_COPY_MODE_NONE) {
827 p->afp_v.peer = ptv->mpeer->peer;
828 } else {
829 p->afp_v.peer = NULL;
662dccd8 830 }
a369f8c3
EL
831 }
832 } else {
833 if (PacketCopyData(p, (unsigned char*)h.raw + h.h2->tp_mac, h.h2->tp_snaplen) == -1) {
834 TmqhOutputPacketpool(ptv->tv, p);
835 SCReturnInt(AFP_FAILURE);
836 }
837 }
838 /* Timestamp */
839 p->ts.tv_sec = h.h2->tp_sec;
840 p->ts.tv_usec = h.h2->tp_nsec/1000;
841 SCLogDebug("pktlen: %" PRIu32 " (pkt %p, pkt data %p)",
842 GET_PKT_LEN(p), p, GET_PKT_DATA(p));
843
844 /* We only check for checksum disable */
845 if (ptv->checksum_mode == CHECKSUM_VALIDATION_DISABLE) {
846 p->flags |= PKT_IGNORE_CHECKSUM;
847 } else if (ptv->checksum_mode == CHECKSUM_VALIDATION_AUTO) {
848 if (ptv->livedev->ignore_checksum) {
849 p->flags |= PKT_IGNORE_CHECKSUM;
850 } else if (ChecksumAutoModeCheck(ptv->pkts,
851 SC_ATOMIC_GET(ptv->livedev->pkts),
852 SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) {
853 ptv->livedev->ignore_checksum = 1;
854 p->flags |= PKT_IGNORE_CHECKSUM;
855 }
856 } else {
857 if (h.h2->tp_status & TP_STATUS_CSUMNOTREADY) {
49b7b00f 858 p->flags |= PKT_IGNORE_CHECKSUM;
a369f8c3 859 }
ee6ba099
EL
860 }
861 if (h.h2->tp_status & TP_STATUS_LOSING) {
862 emergency_flush = 1;
e8a4a4c4 863 AFPDumpCounters(ptv);
a369f8c3
EL
864 }
865
5f12b234
EL
866 /* release frame if not in zero copy mode */
867 if (!(ptv->flags & AFP_ZERO_COPY)) {
868 h.h2->tp_status = TP_STATUS_KERNEL;
869 }
870
a369f8c3
EL
871 if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) {
872 h.h2->tp_status = TP_STATUS_KERNEL;
873 if (++ptv->frame_offset >= ptv->req.tp_frame_nr) {
874 ptv->frame_offset = 0;
875 }
876 TmqhOutputPacketpool(ptv->tv, p);
877 SCReturnInt(AFP_FAILURE);
49b7b00f 878 }
49b7b00f 879
27b5136b 880next_frame:
34b3f194
EL
881 if (++ptv->frame_offset >= ptv->req.tp_frame_nr) {
882 ptv->frame_offset = 0;
350d7619
EL
883 /* Get out of loop to be sure we will reach maintenance tasks */
884 SCReturnInt(AFP_READ_OK);
34b3f194 885 }
34b3f194
EL
886 }
887
49b7b00f
EL
888 SCReturnInt(AFP_READ_OK);
889}
890
13f13b6d
EL
891/**
892 * \brief Reference socket
893 *
894 * \retval O in case of failure, 1 in case of success
895 */
896static int AFPRefSocket(AFPPeer* peer)
897{
898 if (unlikely(peer == NULL))
899 return 0;
900
901 (void)SC_ATOMIC_ADD(peer->sock_usage, 1);
902 return 1;
903}
904
905
906/**
907 * \brief Dereference socket
908 *
909 * \retval 1 if socket is still alive, 0 if not
910 */
911static int AFPDerefSocket(AFPPeer* peer)
912{
4424f5a2
EL
913 if (peer == NULL)
914 return 1;
915
13f13b6d
EL
916 if (SC_ATOMIC_SUB(peer->sock_usage, 1) == 0) {
917 if (SC_ATOMIC_GET(peer->state) == AFP_STATE_DOWN) {
918 SCLogInfo("Cleaning socket connected to '%s'", peer->iface);
919 close(SC_ATOMIC_GET(peer->socket));
920 return 0;
921 }
922 }
923 return 1;
924}
925
926void AFPSwitchState(AFPThreadVars *ptv, int state)
927{
928 ptv->afp_state = state;
929 ptv->down_count = 0;
49b7b00f 930
13f13b6d
EL
931 AFPPeerUpdate(ptv);
932
933 /* Do cleaning if switching to down state */
934 if (state == AFP_STATE_DOWN) {
935 if (ptv->frame_buf) {
936 /* only used in reading phase, we can free it */
937 SCFree(ptv->frame_buf);
938 ptv->frame_buf = NULL;
939 }
940 if (ptv->socket != -1) {
941 /* we need to wait for all packets to return data */
942 if (SC_ATOMIC_SUB(ptv->mpeer->sock_usage, 1) == 0) {
943 SCLogInfo("Cleaning socket connected to '%s'", ptv->iface);
944 close(ptv->socket);
945 ptv->socket = -1;
946 }
947 }
948 }
949 if (state == AFP_STATE_UP) {
950 (void)SC_ATOMIC_SET(ptv->mpeer->sock_usage, 1);
951 }
952}
49b7b00f 953
919377d4
EL
954static int AFPReadAndDiscard(AFPThreadVars *ptv, struct timeval *synctv)
955{
956 struct sockaddr_ll from;
957 struct iovec iov;
958 struct msghdr msg;
959 struct timeval ts;
960 union {
961 struct cmsghdr cmsg;
962 char buf[CMSG_SPACE(sizeof(struct tpacket_auxdata))];
963 } cmsg_buf;
964
965
966 if (unlikely(suricata_ctl_flags != 0)) {
967 return 1;
968 }
969
970 msg.msg_name = &from;
971 msg.msg_namelen = sizeof(from);
972 msg.msg_iov = &iov;
973 msg.msg_iovlen = 1;
974 msg.msg_control = &cmsg_buf;
975 msg.msg_controllen = sizeof(cmsg_buf);
976 msg.msg_flags = 0;
977
978 iov.iov_len = ptv->datalen;
979 iov.iov_base = ptv->data;
980
981 recvmsg(ptv->socket, &msg, MSG_TRUNC);
982
983 if (ioctl(ptv->socket, SIOCGSTAMP, &ts) == -1) {
984 /* FIXME */
985 return -1;
986 }
987
988 if ((ts.tv_sec > synctv->tv_sec) ||
989 (ts.tv_sec >= synctv->tv_sec &&
990 ts.tv_usec > synctv->tv_usec)) {
991 return 1;
992 }
993 return 0;
994}
995
996static int AFPReadAndDiscardFromRing(AFPThreadVars *ptv, struct timeval *synctv)
997{
998 union thdr h;
999
1000 if (unlikely(suricata_ctl_flags != 0)) {
1001 return 1;
1002 }
1003
1004 /* Read packet from ring */
1005 h.raw = (((union thdr **)ptv->frame_buf)[ptv->frame_offset]);
1006 if (h.raw == NULL) {
1007 return -1;
1008 }
1009
1010 if (((time_t)h.h2->tp_sec > synctv->tv_sec) ||
1011 ((time_t)h.h2->tp_sec == synctv->tv_sec &&
1012 (suseconds_t) (h.h2->tp_nsec / 1000) > synctv->tv_usec)) {
1013 return 1;
1014 }
1015
1016 h.h2->tp_status = TP_STATUS_KERNEL;
1017 if (++ptv->frame_offset >= ptv->req.tp_frame_nr) {
1018 ptv->frame_offset = 0;
1019 }
1020
1021
1022 return 0;
1023}
1024
806844d8
VJ
1025/** \brief wait for all afpacket threads to fully init
1026 *
1027 * Discard packets before all threads are ready, as the cluster
1028 * setup is not complete yet.
1029 *
1030 * if AFPPeersListStarted() returns true init is complete
1031 *
1032 * \retval r 1 = happy, otherwise unhappy
1033 */
919377d4
EL
1034static int AFPSynchronizeStart(AFPThreadVars *ptv)
1035{
1036 int r;
1037 struct timeval synctv;
806844d8
VJ
1038 struct pollfd fds;
1039
1040 fds.fd = ptv->socket;
1041 fds.events = POLLIN;
919377d4
EL
1042
1043 /* Set timeval to end of the world */
1044 synctv.tv_sec = 0xffffffff;
1045 synctv.tv_usec = 0xffffffff;
1046
1047 while (1) {
806844d8
VJ
1048 r = poll(&fds, 1, POLL_TIMEOUT);
1049 if (r > 0 &&
1050 (fds.revents & (POLLHUP|POLLRDHUP|POLLERR|POLLNVAL))) {
1051 SCLogWarning(SC_ERR_AFP_READ, "poll failed %02x",
1052 fds.revents & (POLLHUP|POLLRDHUP|POLLERR|POLLNVAL));
1053 return 0;
1054 } else if (r > 0) {
1055 if (AFPPeersListStarted() && synctv.tv_sec == (time_t) 0xffffffff) {
1056 gettimeofday(&synctv, NULL);
1057 }
1058 if (ptv->flags & AFP_RING_MODE) {
1059 r = AFPReadAndDiscardFromRing(ptv, &synctv);
1060 } else {
1061 r = AFPReadAndDiscard(ptv, &synctv);
1062 }
1063 SCLogDebug("Discarding on %s", ptv->tv->name);
1064 switch (r) {
1065 case 1:
1066 SCLogInfo("Starting to read on %s", ptv->tv->name);
1067 return 1;
1068 case -1:
1069 return r;
1070 }
1071 /* no packets */
1072 } else if (r == 0 && AFPPeersListStarted()) {
1073 SCLogInfo("Starting to read on %s", ptv->tv->name);
1074 return 1;
43b6cbd4 1075 } else if (r < 0) { /* only exit on error */
806844d8
VJ
1076 SCLogWarning(SC_ERR_AFP_READ, "poll failed with retval %d", r);
1077 return 0;
919377d4
EL
1078 }
1079 }
1080 return 1;
1081}
1082
13f13b6d
EL
1083/**
1084 * \brief Try to reopen socket
1085 *
1086 * \retval 0 in case of success, negative if error occurs or a condition
1087 * is not met.
1088 */
c45d8985
EL
1089static int AFPTryReopen(AFPThreadVars *ptv)
1090{
1091 int afp_activate_r;
1092
13f13b6d
EL
1093 ptv->down_count++;
1094
1095
1096 /* Don't reconnect till we have packet that did not release data */
1097 if (SC_ATOMIC_GET(ptv->mpeer->sock_usage) != 0) {
1098 return -1;
1099 }
c45d8985 1100
e80b30c0 1101 afp_activate_r = AFPCreateSocket(ptv, ptv->iface, 0);
c45d8985 1102 if (afp_activate_r != 0) {
13f13b6d
EL
1103 if (ptv->down_count % AFP_DOWN_COUNTER_INTERVAL == 0) {
1104 SCLogWarning(SC_ERR_AFP_CREATE, "Can not open iface '%s'",
1105 ptv->iface);
1106 }
c45d8985
EL
1107 return afp_activate_r;
1108 }
1109
3bea3b39 1110 SCLogInfo("Interface '%s' is back", ptv->iface);
c45d8985
EL
1111 return 0;
1112}
1113
e80b30c0
EL
1114/**
1115 * \brief Main AF_PACKET reading Loop function
1116 */
1117TmEcode ReceiveAFPLoop(ThreadVars *tv, void *data, void *slot)
1118{
34581ce9
AS
1119 SCEnter();
1120
e80b30c0
EL
1121 uint16_t packet_q_len = 0;
1122 AFPThreadVars *ptv = (AFPThreadVars *)data;
e80b30c0
EL
1123 struct pollfd fds;
1124 int r;
34581ce9 1125 TmSlot *s = (TmSlot *)slot;
e8a4a4c4
EL
1126 time_t last_dump = 0;
1127 struct timeval current_time;
e80b30c0 1128
34581ce9 1129 ptv->slot = s->slot_next;
e80b30c0 1130
60400163
EL
1131 if (ptv->afp_state == AFP_STATE_DOWN) {
1132 /* Wait for our turn, threads before us must have opened the socket */
1133 while (AFPPeersListWaitTurn(ptv->mpeer)) {
1134 usleep(1000);
1992a227
EL
1135 if (suricata_ctl_flags != 0) {
1136 break;
1137 }
60400163
EL
1138 }
1139 r = AFPCreateSocket(ptv, ptv->iface, 1);
1140 if (r < 0) {
1992a227
EL
1141 switch (-r) {
1142 case AFP_FATAL_ERROR:
1143 SCLogError(SC_ERR_AFP_CREATE, "Couldn't init AF_PACKET socket, fatal error");
1144 /* fatal is fatal, we want suri to exit */
1145 EngineKill();
1146 //tv->aof = THV_ENGINE_EXIT;
1147 SCReturnInt(TM_ECODE_FAILED);
1148 case AFP_RECOVERABLE_ERROR:
1149 SCLogWarning(SC_ERR_AFP_CREATE, "Couldn't init AF_PACKET socket, retrying soon");
1150 }
60400163
EL
1151 }
1152 AFPPeersListReachedInc();
1153 }
1154 if (ptv->afp_state == AFP_STATE_UP) {
1155 SCLogInfo("Thread %s using socket %d", tv->name, ptv->socket);
919377d4 1156 AFPSynchronizeStart(ptv);
60400163
EL
1157 }
1158
e80b30c0
EL
1159 fds.fd = ptv->socket;
1160 fds.events = POLLIN;
1161
1162 while (1) {
1163 /* Start by checking the state of our interface */
1164 if (unlikely(ptv->afp_state == AFP_STATE_DOWN)) {
1165 int dbreak = 0;
662dccd8 1166
e80b30c0
EL
1167 do {
1168 usleep(AFP_RECONNECT_TIMEOUT);
1169 if (suricata_ctl_flags != 0) {
1170 dbreak = 1;
1171 break;
1172 }
1173 r = AFPTryReopen(ptv);
09e709d1 1174 fds.fd = ptv->socket;
e80b30c0
EL
1175 } while (r < 0);
1176 if (dbreak == 1)
1177 break;
1178 }
1179
1180 /* make sure we have at least one packet in the packet pool, to prevent
1181 * us from alloc'ing packets at line rate */
1182 do {
1183 packet_q_len = PacketPoolSize();
1184 if (unlikely(packet_q_len == 0)) {
1185 PacketPoolWait();
1186 }
1187 } while (packet_q_len == 0);
1188
1189 r = poll(&fds, 1, POLL_TIMEOUT);
1190
1191 if (suricata_ctl_flags != 0) {
1192 break;
1193 }
1194
1195 if (r > 0 &&
1196 (fds.revents & (POLLHUP|POLLRDHUP|POLLERR|POLLNVAL))) {
1197 if (fds.revents & (POLLHUP | POLLRDHUP)) {
13f13b6d 1198 AFPSwitchState(ptv, AFP_STATE_DOWN);
e80b30c0 1199 continue;
ff6365dd 1200 } else if (fds.revents & POLLERR) {
e80b30c0
EL
1201 char c;
1202 /* Do a recv to get errno */
1203 if (recv(ptv->socket, &c, sizeof c, MSG_PEEK) != -1)
1204 continue; /* what, no error? */
3bea3b39
EL
1205 SCLogError(SC_ERR_AFP_READ,
1206 "Error reading data from iface '%s': (%d" PRIu32 ") %s",
1207 ptv->iface, errno, strerror(errno));
13f13b6d 1208 AFPSwitchState(ptv, AFP_STATE_DOWN);
e80b30c0 1209 continue;
ff6365dd 1210 } else if (fds.revents & POLLNVAL) {
e80b30c0 1211 SCLogError(SC_ERR_AFP_READ, "Invalid polling request");
13f13b6d 1212 AFPSwitchState(ptv, AFP_STATE_DOWN);
e80b30c0
EL
1213 continue;
1214 }
1215 } else if (r > 0) {
49b7b00f
EL
1216 if (ptv->flags & AFP_RING_MODE) {
1217 r = AFPReadFromRing(ptv);
1218 } else {
1219 /* AFPRead will call TmThreadsSlotProcessPkt on read packets */
1220 r = AFPRead(ptv);
1221 }
62e63e3f
EL
1222 switch (r) {
1223 case AFP_READ_FAILURE:
1224 /* AFPRead in error: best to reset the socket */
3bea3b39
EL
1225 SCLogError(SC_ERR_AFP_READ,
1226 "AFPRead error reading data from iface '%s': (%d" PRIu32 ") %s",
1227 ptv->iface, errno, strerror(errno));
13f13b6d 1228 AFPSwitchState(ptv, AFP_STATE_DOWN);
62e63e3f
EL
1229 continue;
1230 case AFP_FAILURE:
13f13b6d 1231 AFPSwitchState(ptv, AFP_STATE_DOWN);
62e63e3f
EL
1232 SCReturnInt(TM_ECODE_FAILED);
1233 break;
1234 case AFP_READ_OK:
e8a4a4c4
EL
1235 /* Trigger one dump of stats every second */
1236 TimeGet(&current_time);
1237 if (current_time.tv_sec != last_dump) {
1238 AFPDumpCounters(ptv);
1239 last_dump = current_time.tv_sec;
1240 }
62e63e3f 1241 break;
27b5136b 1242 case AFP_KERNEL_DROP:
e8a4a4c4 1243 AFPDumpCounters(ptv);
27b5136b 1244 break;
e80b30c0
EL
1245 }
1246 } else if ((r < 0) && (errno != EINTR)) {
3bea3b39
EL
1247 SCLogError(SC_ERR_AFP_READ, "Error reading data from iface '%s': (%d" PRIu32 ") %s",
1248 ptv->iface,
e80b30c0 1249 errno, strerror(errno));
13f13b6d 1250 AFPSwitchState(ptv, AFP_STATE_DOWN);
e80b30c0
EL
1251 continue;
1252 }
677cd03e 1253 SCPerfSyncCountersIfSignalled(tv);
e80b30c0
EL
1254 }
1255
4e561d6b
VJ
1256 AFPDumpCounters(ptv);
1257 SCPerfSyncCountersIfSignalled(tv);
e80b30c0
EL
1258 SCReturnInt(TM_ECODE_OK);
1259}
1260
13f13b6d
EL
1261static int AFPGetDevFlags(int fd, const char *ifname)
1262{
1263 struct ifreq ifr;
1264
1265 memset(&ifr, 0, sizeof(ifr));
1266 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
1267
1268 if (ioctl(fd, SIOCGIFFLAGS, &ifr) == -1) {
1269 SCLogError(SC_ERR_AFP_CREATE, "Unable to find type for iface \"%s\": %s",
1270 ifname, strerror(errno));
1271 return -1;
1272 }
1273
1274 return ifr.ifr_flags;
1275}
1276
1277
e80b30c0 1278static int AFPGetIfnumByDev(int fd, const char *ifname, int verbose)
c45d8985
EL
1279{
1280 struct ifreq ifr;
1281
1282 memset(&ifr, 0, sizeof(ifr));
e80b30c0 1283 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
c45d8985
EL
1284
1285 if (ioctl(fd, SIOCGIFINDEX, &ifr) == -1) {
1286 if (verbose)
1287 SCLogError(SC_ERR_AFP_CREATE, "Unable to find iface %s: %s",
1288 ifname, strerror(errno));
1289 return -1;
1290 }
1291
1292 return ifr.ifr_ifindex;
1293}
1294
e80b30c0 1295static int AFPGetDevLinktype(int fd, const char *ifname)
c45d8985
EL
1296{
1297 struct ifreq ifr;
1298
1299 memset(&ifr, 0, sizeof(ifr));
e80b30c0 1300 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
c45d8985
EL
1301
1302 if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) {
1303 SCLogError(SC_ERR_AFP_CREATE, "Unable to find type for iface \"%s\": %s",
1304 ifname, strerror(errno));
1305 return -1;
1306 }
1307
e80b30c0
EL
1308 switch (ifr.ifr_hwaddr.sa_family) {
1309 case ARPHRD_LOOPBACK:
1310 return LINKTYPE_ETHERNET;
1311 case ARPHRD_PPP:
1312 return LINKTYPE_RAW;
1313 default:
1314 return ifr.ifr_hwaddr.sa_family;
1315 }
c45d8985
EL
1316}
1317
49b7b00f
EL
1318static int AFPComputeRingParams(AFPThreadVars *ptv, int order)
1319{
1320 /* Compute structure:
1321 Target is to store all pending packets
1322 with a size equal to MTU + auxdata
1323 And we keep a decent number of block
1324
1325 To do so:
1326 Compute frame_size (aligned to be able to fit in block
1327 Check which block size we need. Blocksize is a 2^n * pagesize
1328 We then need to get order, big enough to have
1329 frame_size < block size
1330 Find number of frame per block (divide)
1331 Fill in packet_req
1332
1333 Compute frame size:
1334 described in packet_mmap.txt
1335 dependant on snaplen (need to use a variable ?)
1336snaplen: MTU ?
1337tp_hdrlen determine_version in daq_afpacket
1338in V1: sizeof(struct tpacket_hdr);
1339in V2: val in getsockopt(instance->fd, SOL_PACKET, PACKET_HDRLEN, &val, &len)
1340frame size: TPACKET_ALIGN(snaplen + TPACKET_ALIGN(TPACKET_ALIGN(tp_hdrlen) + sizeof(struct sockaddr_ll) + ETH_HLEN) - ETH_HLEN);
1341
1342 */
1343 int tp_hdrlen = sizeof(struct tpacket_hdr);
1344 int snaplen = default_packet_size;
1345
1346 ptv->req.tp_frame_size = TPACKET_ALIGN(snaplen +TPACKET_ALIGN(TPACKET_ALIGN(tp_hdrlen) + sizeof(struct sockaddr_ll) + ETH_HLEN) - ETH_HLEN);
1347 ptv->req.tp_block_size = getpagesize() << order;
1348 int frames_per_block = ptv->req.tp_block_size / ptv->req.tp_frame_size;
1349 if (frames_per_block == 0) {
1350 SCLogInfo("frame size to big");
1351 return -1;
1352 }
8879df80 1353 ptv->req.tp_frame_nr = ptv->ring_size;
d8d9b098 1354 ptv->req.tp_block_nr = ptv->req.tp_frame_nr / frames_per_block + 1;
49b7b00f
EL
1355 /* exact division */
1356 ptv->req.tp_frame_nr = ptv->req.tp_block_nr * frames_per_block;
1357 SCLogInfo("AF_PACKET RX Ring params: block_size=%d block_nr=%d frame_size=%d frame_nr=%d",
1358 ptv->req.tp_block_size, ptv->req.tp_block_nr,
1359 ptv->req.tp_frame_size, ptv->req.tp_frame_nr);
1360 return 1;
1361}
1362
e80b30c0 1363static int AFPCreateSocket(AFPThreadVars *ptv, char *devname, int verbose)
c45d8985
EL
1364{
1365 int r;
1992a227 1366 int ret = AFP_FATAL_ERROR;
c45d8985
EL
1367 struct packet_mreq sock_params;
1368 struct sockaddr_ll bind_address;
49b7b00f
EL
1369 int order;
1370 unsigned int i;
662dccd8 1371 int if_idx;
49b7b00f 1372
c45d8985
EL
1373 /* open socket */
1374 ptv->socket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
1375 if (ptv->socket == -1) {
e80b30c0 1376 SCLogError(SC_ERR_AFP_CREATE, "Couldn't create a AF_PACKET socket, error %s", strerror(errno));
13f13b6d 1377 goto error;
c45d8985 1378 }
662dccd8 1379 if_idx = AFPGetIfnumByDev(ptv->socket, devname, verbose);
c45d8985
EL
1380 /* bind socket */
1381 memset(&bind_address, 0, sizeof(bind_address));
1382 bind_address.sll_family = AF_PACKET;
1383 bind_address.sll_protocol = htons(ETH_P_ALL);
662dccd8 1384 bind_address.sll_ifindex = if_idx;
c45d8985
EL
1385 if (bind_address.sll_ifindex == -1) {
1386 if (verbose)
e80b30c0 1387 SCLogError(SC_ERR_AFP_CREATE, "Couldn't find iface %s", devname);
1992a227 1388 ret = AFP_RECOVERABLE_ERROR;
13f13b6d
EL
1389 goto socket_err;
1390 }
1391
13f13b6d
EL
1392 if (ptv->promisc != 0) {
1393 /* Force promiscuous mode */
1394 memset(&sock_params, 0, sizeof(sock_params));
1395 sock_params.mr_type = PACKET_MR_PROMISC;
1396 sock_params.mr_ifindex = bind_address.sll_ifindex;
1397 r = setsockopt(ptv->socket, SOL_PACKET, PACKET_ADD_MEMBERSHIP,(void *)&sock_params, sizeof(sock_params));
1398 if (r < 0) {
1399 SCLogError(SC_ERR_AFP_CREATE,
1400 "Couldn't switch iface %s to promiscuous, error %s",
1401 devname, strerror(errno));
1402 goto frame_err;
1403 }
1404 }
1405
1406 if (ptv->checksum_mode == CHECKSUM_VALIDATION_KERNEL) {
1407 int val = 1;
1408 if (setsockopt(ptv->socket, SOL_PACKET, PACKET_AUXDATA, &val,
1409 sizeof(val)) == -1 && errno != ENOPROTOOPT) {
1410 SCLogWarning(SC_ERR_NO_AF_PACKET,
1411 "'kernel' checksum mode not supported, failling back to full mode.");
1412 ptv->checksum_mode = CHECKSUM_VALIDATION_ENABLE;
1413 }
1414 }
1415
1416 /* set socket recv buffer size */
1417 if (ptv->buffer_size != 0) {
1418 /*
1419 * Set the socket buffer size to the specified value.
1420 */
1421 SCLogInfo("Setting AF_PACKET socket buffer to %d", ptv->buffer_size);
1422 if (setsockopt(ptv->socket, SOL_SOCKET, SO_RCVBUF,
1423 &ptv->buffer_size,
1424 sizeof(ptv->buffer_size)) == -1) {
1425 SCLogError(SC_ERR_AFP_CREATE,
1426 "Couldn't set buffer size to %d on iface %s, error %s",
1427 ptv->buffer_size, devname, strerror(errno));
1428 goto frame_err;
1429 }
1430 }
1431
1432 r = bind(ptv->socket, (struct sockaddr *)&bind_address, sizeof(bind_address));
1433 if (r < 0) {
1434 if (verbose) {
1435 if (errno == ENETDOWN) {
1436 SCLogError(SC_ERR_AFP_CREATE,
1437 "Couldn't bind AF_PACKET socket, iface %s is down",
1438 devname);
1439 } else {
1440 SCLogError(SC_ERR_AFP_CREATE,
1441 "Couldn't bind AF_PACKET socket to iface %s, error %s",
1442 devname, strerror(errno));
1443 }
1444 }
1992a227 1445 ret = AFP_RECOVERABLE_ERROR;
13f13b6d
EL
1446 goto frame_err;
1447 }
1448
238ff231
EL
1449#ifdef HAVE_PACKET_FANOUT
1450 /* add binded socket to fanout group */
1451 if (ptv->threads > 1) {
1452 uint32_t option = 0;
1453 uint16_t mode = ptv->cluster_type;
1454 uint16_t id = ptv->cluster_id;
1455 option = (mode << 16) | (id & 0xffff);
1456 r = setsockopt(ptv->socket, SOL_PACKET, PACKET_FANOUT,(void *)&option, sizeof(option));
1457 if (r < 0) {
1458 SCLogError(SC_ERR_AFP_CREATE,
1459 "Coudn't set fanout mode, error %s",
1460 strerror(errno));
1461 goto frame_err;
1462 }
1463 }
1464#endif
1465
13f13b6d
EL
1466 int if_flags = AFPGetDevFlags(ptv->socket, ptv->iface);
1467 if (if_flags == -1) {
1468 if (verbose) {
1469 SCLogError(SC_ERR_AFP_READ,
1470 "Can not acces to interface '%s'",
1471 ptv->iface);
1472 }
1992a227 1473 ret = AFP_RECOVERABLE_ERROR;
13f13b6d
EL
1474 goto frame_err;
1475 }
1476 if ((if_flags & IFF_UP) == 0) {
1477 if (verbose) {
1478 SCLogError(SC_ERR_AFP_READ,
1479 "Interface '%s' is down",
1480 ptv->iface);
1481 }
1992a227 1482 ret = AFP_RECOVERABLE_ERROR;
13f13b6d 1483 goto frame_err;
c45d8985 1484 }
49b7b00f
EL
1485
1486 if (ptv->flags & AFP_RING_MODE) {
1487 int val = TPACKET_V2;
1488 unsigned int len = sizeof(val);
1489 if (getsockopt(ptv->socket, SOL_PACKET, PACKET_HDRLEN, &val, &len) < 0) {
1490 if (errno == ENOPROTOOPT) {
1491 SCLogError(SC_ERR_AFP_CREATE,
1492 "Too old kernel giving up (need 2.6.27 at least)");
1493 }
1494 SCLogError(SC_ERR_AFP_CREATE, "Error when retrieving packet header len");
13f13b6d 1495 goto socket_err;
49b7b00f
EL
1496 }
1497 ptv->tp_hdrlen = val;
1498
1499 val = TPACKET_V2;
1500 if (setsockopt(ptv->socket, SOL_PACKET, PACKET_VERSION, &val,
1501 sizeof(val)) < 0) {
1502 SCLogError(SC_ERR_AFP_CREATE,
1503 "Can't activate TPACKET_V2 on packet socket: %s",
1504 strerror(errno));
13f13b6d 1505 goto socket_err;
49b7b00f
EL
1506 }
1507
2855ee5a
EL
1508 if (GetIfaceOffloading(devname) == 1) {
1509 SCLogWarning(SC_ERR_AFP_CREATE,
1510 "Using mmap mode with GRO or LRO activated can lead to capture problems");
1511 }
1512
49b7b00f
EL
1513 /* Allocate RX ring */
1514#define DEFAULT_ORDER 3
1515 for (order = DEFAULT_ORDER; order >= 0; order--) {
1516 if (AFPComputeRingParams(ptv, order) != 1) {
1517 SCLogInfo("Ring parameter are incorrect. Please correct the devel");
1518 }
1519
1520 r = setsockopt(ptv->socket, SOL_PACKET, PACKET_RX_RING, (void *) &ptv->req, sizeof(ptv->req));
1521 if (r < 0) {
1522 if (errno == ENOMEM) {
1523 SCLogInfo("Memory issue with ring parameters. Retrying.");
1524 continue;
1525 }
1526 SCLogError(SC_ERR_MEM_ALLOC,
1527 "Unable to allocate RX Ring for iface %s: (%d) %s",
1528 devname,
1529 errno,
1530 strerror(errno));
13f13b6d 1531 goto socket_err;
49b7b00f
EL
1532 } else {
1533 break;
1534 }
1535 }
1536
1537 if (order < 0) {
1538 SCLogError(SC_ERR_MEM_ALLOC,
1539 "Unable to allocate RX Ring for iface %s (order 0 failed)",
1540 devname);
13f13b6d 1541 goto socket_err;
49b7b00f
EL
1542 }
1543
1544 /* Allocate the Ring */
1545 ptv->ring_buflen = ptv->req.tp_block_nr * ptv->req.tp_block_size;
1546 ptv->ring_buf = mmap(0, ptv->ring_buflen, PROT_READ|PROT_WRITE,
1547 MAP_SHARED, ptv->socket, 0);
1548 if (ptv->ring_buf == MAP_FAILED) {
1549 SCLogError(SC_ERR_MEM_ALLOC, "Unable to mmap");
13f13b6d 1550 goto socket_err;
49b7b00f
EL
1551 }
1552 /* allocate a ring for each frame header pointer*/
1553 ptv->frame_buf = SCMalloc(ptv->req.tp_frame_nr * sizeof (union thdr *));
1554 if (ptv->frame_buf == NULL) {
1555 SCLogError(SC_ERR_MEM_ALLOC, "Unable to allocate frame buf");
13f13b6d 1556 goto mmap_err;
49b7b00f
EL
1557 }
1558 memset(ptv->frame_buf, 0, ptv->req.tp_frame_nr * sizeof (union thdr *));
1559 /* fill the header ring with proper frame ptr*/
1560 ptv->frame_offset = 0;
1561 for (i = 0; i < ptv->req.tp_block_nr; ++i) {
1562 void *base = &ptv->ring_buf[i * ptv->req.tp_block_size];
1563 unsigned int j;
1564 for (j = 0; j < ptv->req.tp_block_size / ptv->req.tp_frame_size; ++j, ++ptv->frame_offset) {
1565 (((union thdr **)ptv->frame_buf)[ptv->frame_offset]) = base;
1566 base += ptv->req.tp_frame_size;
1567 }
1568 }
1569 ptv->frame_offset = 0;
1570 }
1571
13f13b6d 1572 SCLogInfo("Using interface '%s' via socket %d", (char *)devname, ptv->socket);
ec76742c 1573
c45d8985 1574
c85ee1e3
EL
1575 ptv->datalink = AFPGetDevLinktype(ptv->socket, ptv->iface);
1576 switch (ptv->datalink) {
1577 case ARPHRD_PPP:
1578 case ARPHRD_ATM:
1579 ptv->cooked = 1;
619414c5 1580 break;
c85ee1e3
EL
1581 }
1582
f2a6fb8a
EL
1583 TmEcode rc;
1584 rc = AFPSetBPFFilter(ptv);
1585 if (rc == TM_ECODE_FAILED) {
1586 SCLogError(SC_ERR_AFP_CREATE, "Set AF_PACKET bpf filter \"%s\" failed.", ptv->bpf_filter);
13f13b6d 1587 goto frame_err;
f2a6fb8a
EL
1588 }
1589
49b7b00f 1590 /* Init is ok */
13f13b6d 1591 AFPSwitchState(ptv, AFP_STATE_UP);
c45d8985 1592 return 0;
13f13b6d
EL
1593
1594frame_err:
1595 if (ptv->frame_buf)
1596 SCFree(ptv->frame_buf);
1597mmap_err:
1598 /* Packet mmap does the cleaning when socket is closed */
1599socket_err:
1600 close(ptv->socket);
1601 ptv->socket = -1;
1602error:
1992a227 1603 return -ret;
c45d8985
EL
1604}
1605
f2a6fb8a
EL
1606TmEcode AFPSetBPFFilter(AFPThreadVars *ptv)
1607{
1608 struct bpf_program filter;
1609 struct sock_fprog fcode;
1610 int rc;
1611
1612 if (!ptv->bpf_filter)
1613 return TM_ECODE_OK;
1614
1615 SCMutexLock(&afpacket_bpf_set_filter_lock);
1616
1617 SCLogInfo("Using BPF '%s' on iface '%s'",
1618 ptv->bpf_filter,
1619 ptv->iface);
1620 if (pcap_compile_nopcap(default_packet_size, /* snaplen_arg */
1621 ptv->datalink, /* linktype_arg */
1622 &filter, /* program */
1623 ptv->bpf_filter, /* const char *buf */
1624 0, /* optimize */
1625 0 /* mask */
1626 ) == -1) {
1627 SCLogError(SC_ERR_AFP_CREATE, "Filter compilation failed.");
1628 SCMutexUnlock(&afpacket_bpf_set_filter_lock);
1629 return TM_ECODE_FAILED;
1630 }
1631 SCMutexUnlock(&afpacket_bpf_set_filter_lock);
1632
1633 if (filter.bf_insns == NULL) {
1634 SCLogError(SC_ERR_AFP_CREATE, "Filter badly setup.");
1635 return TM_ECODE_FAILED;
1636 }
1637
1638 fcode.len = filter.bf_len;
1639 fcode.filter = (struct sock_filter*)filter.bf_insns;
1640
1641 rc = setsockopt(ptv->socket, SOL_SOCKET, SO_ATTACH_FILTER, &fcode, sizeof(fcode));
1642
1643 if(rc == -1) {
1644 SCLogError(SC_ERR_AFP_CREATE, "Failed to attach filter: %s", strerror(errno));
1645 return TM_ECODE_FAILED;
1646 }
1647
1648 SCMutexUnlock(&afpacket_bpf_set_filter_lock);
1649 return TM_ECODE_OK;
1650}
1651
c45d8985
EL
1652
1653/**
1654 * \brief Init function for ReceiveAFP.
1655 *
1656 * \param tv pointer to ThreadVars
1657 * \param initdata pointer to the interface passed from the user
1658 * \param data pointer gets populated with AFPThreadVars
1659 *
1660 * \todo Create a general AFP setup function.
1661 */
1662TmEcode ReceiveAFPThreadInit(ThreadVars *tv, void *initdata, void **data) {
1663 SCEnter();
fbca1a4e 1664 AFPIfaceConfig *afpconfig = initdata;
c45d8985 1665
c45d8985
EL
1666 if (initdata == NULL) {
1667 SCLogError(SC_ERR_INVALID_ARGUMENT, "initdata == NULL");
1668 SCReturnInt(TM_ECODE_FAILED);
1669 }
1670
1671 AFPThreadVars *ptv = SCMalloc(sizeof(AFPThreadVars));
e176be6f 1672 if (unlikely(ptv == NULL)) {
45d5c3ca 1673 afpconfig->DerefFunc(afpconfig);
c45d8985 1674 SCReturnInt(TM_ECODE_FAILED);
45d5c3ca 1675 }
c45d8985
EL
1676 memset(ptv, 0, sizeof(AFPThreadVars));
1677
1678 ptv->tv = tv;
1679 ptv->cooked = 0;
1680
fbca1a4e 1681 strlcpy(ptv->iface, afpconfig->iface, AFP_IFACE_NAME_LENGTH);
c45d8985
EL
1682 ptv->iface[AFP_IFACE_NAME_LENGTH - 1]= '\0';
1683
51eb9605
EL
1684 ptv->livedev = LiveGetDevice(ptv->iface);
1685 if (ptv->livedev == NULL) {
1686 SCLogError(SC_ERR_INVALID_VALUE, "Unable to find Live device");
11bdf483 1687 SCFree(ptv);
51eb9605
EL
1688 SCReturnInt(TM_ECODE_FAILED);
1689 }
1690
fbca1a4e 1691 ptv->buffer_size = afpconfig->buffer_size;
8879df80 1692 ptv->ring_size = afpconfig->ring_size;
e80b30c0 1693
df7dbe36 1694 ptv->promisc = afpconfig->promisc;
6062e00c 1695 ptv->checksum_mode = afpconfig->checksum_mode;
6efd37a3 1696 ptv->bpf_filter = NULL;
df7dbe36 1697
fbca1a4e 1698 ptv->threads = 1;
e80b30c0
EL
1699#ifdef HAVE_PACKET_FANOUT
1700 ptv->cluster_type = PACKET_FANOUT_LB;
1701 ptv->cluster_id = 1;
1702 /* We only set cluster info if the number of reader threads is greater than 1 */
fbca1a4e
EL
1703 if (afpconfig->threads > 1) {
1704 ptv->cluster_id = afpconfig->cluster_id;
1705 ptv->cluster_type = afpconfig->cluster_type;
1706 ptv->threads = afpconfig->threads;
e80b30c0
EL
1707 }
1708#endif
49b7b00f 1709 ptv->flags = afpconfig->flags;
e80b30c0 1710
f2a6fb8a
EL
1711 if (afpconfig->bpf_filter) {
1712 ptv->bpf_filter = afpconfig->bpf_filter;
1713 }
1714
6efd37a3
EL
1715#ifdef PACKET_STATISTICS
1716 ptv->capture_kernel_packets = SCPerfTVRegisterCounter("capture.kernel_packets",
1717 ptv->tv,
1718 SC_PERF_TYPE_UINT64,
1719 "NULL");
1720 ptv->capture_kernel_drops = SCPerfTVRegisterCounter("capture.kernel_drops",
1721 ptv->tv,
1722 SC_PERF_TYPE_UINT64,
1723 "NULL");
1724#endif
1725
34b3f194
EL
1726 char *active_runmode = RunmodeGetActive();
1727
1728 if (active_runmode && !strcmp("workers", active_runmode)) {
1729 ptv->flags |= AFP_ZERO_COPY;
1730 SCLogInfo("Enabling zero copy mode");
662dccd8
EL
1731 } else {
1732 /* If we are using copy mode we need a lock */
1733 ptv->flags |= AFP_SOCK_PROTECT;
34b3f194 1734 }
2011a3f8
EL
1735
1736 /* If we are in RING mode, then we can use ZERO copy
1737 * by using the data release mechanism */
1738 if (ptv->flags & AFP_RING_MODE) {
1739 ptv->flags |= AFP_ZERO_COPY;
1740 SCLogInfo("Enabling zero copy mode by using data release call");
1741 }
34b3f194 1742
662dccd8
EL
1743 ptv->copy_mode = afpconfig->copy_mode;
1744 if (ptv->copy_mode != AFP_COPY_MODE_NONE) {
1745 strlcpy(ptv->out_iface, afpconfig->out_iface, AFP_IFACE_NAME_LENGTH);
1746 ptv->out_iface[AFP_IFACE_NAME_LENGTH - 1]= '\0';
b7e78d33
EL
1747 /* Warn about BPF filter consequence */
1748 if (ptv->bpf_filter) {
1749 SCLogWarning(SC_WARN_UNCOMMON, "Enabling a BPF filter in IPS mode result"
1750 " in dropping all non matching packets.");
1751 }
662dccd8 1752 }
c85ee1e3 1753
b7e78d33 1754
0581a23f
EL
1755 if (AFPPeersListAdd(ptv) == TM_ECODE_FAILED) {
1756 SCFree(ptv);
1757 afpconfig->DerefFunc(afpconfig);
1758 SCReturnInt(TM_ECODE_FAILED);
1759 }
1760
e80b30c0
EL
1761#define T_DATA_SIZE 70000
1762 ptv->data = SCMalloc(T_DATA_SIZE);
1763 if (ptv->data == NULL) {
45d5c3ca 1764 afpconfig->DerefFunc(afpconfig);
6019ae3d 1765 SCFree(ptv);
e80b30c0 1766 SCReturnInt(TM_ECODE_FAILED);
c45d8985 1767 }
e80b30c0
EL
1768 ptv->datalen = T_DATA_SIZE;
1769#undef T_DATA_SIZE
1770
c45d8985 1771 *data = (void *)ptv;
fbca1a4e 1772
45d5c3ca 1773 afpconfig->DerefFunc(afpconfig);
71e47868
EL
1774
1775 /* A bit strange to have this here but we only have vlan information
1776 * during reading so we need to know if we want to keep vlan during
1777 * the capture phase */
1778 int vlanbool = 0;
1779 if ((ConfGetBool("vlan.use-for-tracking", &vlanbool)) == 1 && vlanbool == 0) {
1780 ptv->vlan_disabled = 1;
1781 }
1782
2cd6e128
EL
1783 /* If kernel is older than 3.0, VLAN is not stripped so we don't
1784 * get the info from packet extended header but we will use a standard
1785 * parsing of packet data (See Linux commit bcc6d47903612c3861201cc3a866fb604f26b8b2) */
1786 if (! SCKernelVersionIsAtLeast(3, 0)) {
1787 ptv->vlan_disabled = 1;
1788 }
1789
c45d8985
EL
1790 SCReturnInt(TM_ECODE_OK);
1791}
1792
1793/**
1794 * \brief This function prints stats to the screen at exit.
1795 * \param tv pointer to ThreadVars
1796 * \param data pointer that gets cast into AFPThreadVars for ptv
1797 */
1798void ReceiveAFPThreadExitStats(ThreadVars *tv, void *data) {
1799 SCEnter();
1800 AFPThreadVars *ptv = (AFPThreadVars *)data;
9549faae
EL
1801
1802#ifdef PACKET_STATISTICS
e8a4a4c4 1803 AFPDumpCounters(ptv);
6efd37a3
EL
1804 SCLogInfo("(%s) Kernel: Packets %" PRIu64 ", dropped %" PRIu64 "",
1805 tv->name,
1806 (uint64_t) SCPerfGetLocalCounterValue(ptv->capture_kernel_packets, tv->sc_perf_pca),
1807 (uint64_t) SCPerfGetLocalCounterValue(ptv->capture_kernel_drops, tv->sc_perf_pca));
9549faae 1808#endif
e80b30c0 1809
3ce39433 1810 SCLogInfo("(%s) Packets %" PRIu64 ", bytes %" PRIu64 "", tv->name, ptv->pkts, ptv->bytes);
c45d8985
EL
1811}
1812
1813/**
1814 * \brief DeInit function closes af packet socket at exit.
1815 * \param tv pointer to ThreadVars
1816 * \param data pointer that gets cast into AFPThreadVars for ptv
1817 */
1818TmEcode ReceiveAFPThreadDeinit(ThreadVars *tv, void *data) {
1819 AFPThreadVars *ptv = (AFPThreadVars *)data;
1820
13f13b6d
EL
1821 AFPSwitchState(ptv, AFP_STATE_DOWN);
1822
e80b30c0
EL
1823 if (ptv->data != NULL) {
1824 SCFree(ptv->data);
1825 ptv->data = NULL;
1826 }
1827 ptv->datalen = 0;
1828
f2a6fb8a
EL
1829 ptv->bpf_filter = NULL;
1830
c45d8985
EL
1831 SCReturnInt(TM_ECODE_OK);
1832}
1833
1834/**
1835 * \brief This function passes off to link type decoders.
1836 *
1837 * DecodeAFP reads packets from the PacketQueue and passes
1838 * them off to the proper link type decoder.
1839 *
1840 * \param t pointer to ThreadVars
1841 * \param p pointer to the current packet
1842 * \param data pointer that gets cast into AFPThreadVars for ptv
1843 * \param pq pointer to the current PacketQueue
1844 */
1845TmEcode DecodeAFP(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
1846{
1847 SCEnter();
1848 DecodeThreadVars *dtv = (DecodeThreadVars *)data;
1849
f7b1aefa
VJ
1850 /* XXX HACK: flow timeout can call us for injected pseudo packets
1851 * see bug: https://redmine.openinfosecfoundation.org/issues/1107 */
1852 if (p->flags & PKT_PSEUDO_STREAM_END)
1853 return TM_ECODE_OK;
1854
c45d8985
EL
1855 /* update counters */
1856 SCPerfCounterIncr(dtv->counter_pkts, tv->sc_perf_pca);
698ff4e4 1857// SCPerfCounterIncr(dtv->counter_pkts_per_sec, tv->sc_perf_pca);
c45d8985
EL
1858
1859 SCPerfCounterAddUI64(dtv->counter_bytes, tv->sc_perf_pca, GET_PKT_LEN(p));
1860#if 0
1861 SCPerfCounterAddDouble(dtv->counter_bytes_per_sec, tv->sc_perf_pca, GET_PKT_LEN(p));
1862 SCPerfCounterAddDouble(dtv->counter_mbit_per_sec, tv->sc_perf_pca,
1863 (GET_PKT_LEN(p) * 8)/1000000.0);
1864#endif
1865
1866 SCPerfCounterAddUI64(dtv->counter_avg_pkt_size, tv->sc_perf_pca, GET_PKT_LEN(p));
1867 SCPerfCounterSetUI64(dtv->counter_max_pkt_size, tv->sc_perf_pca, GET_PKT_LEN(p));
1868
1fb7c0dd
EL
1869 /* If suri has set vlan during reading, we increase vlan counter */
1870 if (p->vlan_idx) {
1871 SCPerfCounterIncr(dtv->counter_vlan, tv->sc_perf_pca);
1872 }
1873
c45d8985
EL
1874 /* call the decoder */
1875 switch(p->datalink) {
1876 case LINKTYPE_LINUX_SLL:
1877 DecodeSll(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
1878 break;
1879 case LINKTYPE_ETHERNET:
1880 DecodeEthernet(tv, dtv, p,GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
1881 break;
1882 case LINKTYPE_PPP:
1883 DecodePPP(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
1884 break;
1885 case LINKTYPE_RAW:
1886 DecodeRaw(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
1887 break;
1888 default:
1889 SCLogError(SC_ERR_DATALINK_UNIMPLEMENTED, "Error: datalink type %" PRId32 " not yet supported in module DecodeAFP", p->datalink);
1890 break;
1891 }
1892
3088b6ac 1893 PacketDecodeFinalize(tv, dtv, p);
e7f09f24 1894
c45d8985
EL
1895 SCReturnInt(TM_ECODE_OK);
1896}
1897
1898TmEcode DecodeAFPThreadInit(ThreadVars *tv, void *initdata, void **data)
1899{
1900 SCEnter();
1901 DecodeThreadVars *dtv = NULL;
1902
5f307aca 1903 dtv = DecodeThreadVarsAlloc(tv);
c45d8985
EL
1904
1905 if (dtv == NULL)
1906 SCReturnInt(TM_ECODE_FAILED);
1907
1908 DecodeRegisterPerfCounters(dtv, tv);
1909
1910 *data = (void *)dtv;
1911
e7f09f24
AS
1912#ifdef __SC_CUDA_SUPPORT__
1913 if (CudaThreadVarsInit(&dtv->cuda_vars) < 0)
1914 SCReturnInt(TM_ECODE_FAILED);
1915#endif
1916
c45d8985
EL
1917 SCReturnInt(TM_ECODE_OK);
1918}
1919
2864f9ee
VJ
1920TmEcode DecodeAFPThreadDeinit(ThreadVars *tv, void *data)
1921{
1922 if (data != NULL)
1923 DecodeThreadVarsFree(data);
1924 SCReturnInt(TM_ECODE_OK);
1925}
1926
e80b30c0 1927#endif /* HAVE_AF_PACKET */
c45d8985 1928/* eof */
a6457262
EL
1929/**
1930 * @}
1931 */