]> git.ipfire.org Git - people/ms/suricata.git/blame - src/source-af-packet.c
app-layer-ssh: trigger bypass when done
[people/ms/suricata.git] / src / source-af-packet.c
CommitLineData
ecf59be4 1/* Copyright (C) 2011-2017 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
a40f08a2
EL
97#ifdef HAVE_HW_TIMESTAMPING
98#include <linux/net_tstamp.h>
99#endif
100
472e061c 101#endif /* HAVE_AF_PACKET */
49b7b00f 102
c45d8985
EL
103extern int max_pending_packets;
104
e80b30c0
EL
105#ifndef HAVE_AF_PACKET
106
ab1200fb 107TmEcode NoAFPSupportExit(ThreadVars *, const void *, void **);
e80b30c0 108
8f1d7503
KS
109void TmModuleReceiveAFPRegister (void)
110{
e80b30c0
EL
111 tmm_modules[TMM_RECEIVEAFP].name = "ReceiveAFP";
112 tmm_modules[TMM_RECEIVEAFP].ThreadInit = NoAFPSupportExit;
113 tmm_modules[TMM_RECEIVEAFP].Func = NULL;
114 tmm_modules[TMM_RECEIVEAFP].ThreadExitPrintStats = NULL;
115 tmm_modules[TMM_RECEIVEAFP].ThreadDeinit = NULL;
116 tmm_modules[TMM_RECEIVEAFP].RegisterTests = NULL;
117 tmm_modules[TMM_RECEIVEAFP].cap_flags = 0;
3f1c4efc 118 tmm_modules[TMM_RECEIVEAFP].flags = TM_FLAG_RECEIVE_TM;
e80b30c0
EL
119}
120
121/**
122 * \brief Registration Function for DecodeAFP.
123 * \todo Unit tests are needed for this module.
124 */
8f1d7503
KS
125void TmModuleDecodeAFPRegister (void)
126{
e80b30c0
EL
127 tmm_modules[TMM_DECODEAFP].name = "DecodeAFP";
128 tmm_modules[TMM_DECODEAFP].ThreadInit = NoAFPSupportExit;
129 tmm_modules[TMM_DECODEAFP].Func = NULL;
130 tmm_modules[TMM_DECODEAFP].ThreadExitPrintStats = NULL;
131 tmm_modules[TMM_DECODEAFP].ThreadDeinit = NULL;
132 tmm_modules[TMM_DECODEAFP].RegisterTests = NULL;
133 tmm_modules[TMM_DECODEAFP].cap_flags = 0;
bc6cf438 134 tmm_modules[TMM_DECODEAFP].flags = TM_FLAG_DECODE_TM;
e80b30c0
EL
135}
136
137/**
138 * \brief this function prints an error message and exits.
139 */
ab1200fb 140TmEcode NoAFPSupportExit(ThreadVars *tv, const void *initdata, void **data)
e80b30c0
EL
141{
142 SCLogError(SC_ERR_NO_AF_PACKET,"Error creating thread %s: you do not have "
143 "support for AF_PACKET enabled, on Linux host please recompile "
144 "with --enable-af-packet", tv->name);
145 exit(EXIT_FAILURE);
146}
147
148#else /* We have AF_PACKET support */
149
c45d8985
EL
150#define AFP_IFACE_NAME_LENGTH 48
151
152#define AFP_STATE_DOWN 0
153#define AFP_STATE_UP 1
154
155#define AFP_RECONNECT_TIMEOUT 500000
13f13b6d 156#define AFP_DOWN_COUNTER_INTERVAL 40
c45d8985
EL
157
158#define POLL_TIMEOUT 100
159
4a1a0080
EL
160#ifndef TP_STATUS_USER_BUSY
161/* for new use latest bit available in tp_status */
162#define TP_STATUS_USER_BUSY (1 << 31)
163#endif
164
b603ad62
EL
165#ifndef TP_STATUS_VLAN_VALID
166#define TP_STATUS_VLAN_VALID (1 << 4)
167#endif
168
f2a6fb8a 169/** protect pfring_set_bpf_filter, as it is not thread safe */
5532af46 170static SCMutex afpacket_bpf_set_filter_lock = SCMUTEX_INITIALIZER;
f2a6fb8a 171
62e63e3f
EL
172enum {
173 AFP_READ_OK,
174 AFP_READ_FAILURE,
175 AFP_FAILURE,
27b5136b 176 AFP_KERNEL_DROP,
62e63e3f
EL
177};
178
1992a227
EL
179enum {
180 AFP_FATAL_ERROR = 1,
181 AFP_RECOVERABLE_ERROR,
182};
183
49b7b00f
EL
184union thdr {
185 struct tpacket2_hdr *h2;
c2d0d938 186#ifdef HAVE_TPACKET_V3
bae1b03c 187 struct tpacket3_hdr *h3;
c2d0d938 188#endif
49b7b00f
EL
189 void *raw;
190};
191
c45d8985
EL
192/**
193 * \brief Structure to hold thread specific variables.
194 */
195typedef struct AFPThreadVars_
196{
b797fd92
EL
197 union {
198 char *ring_v2;
199 struct iovec *ring_v3;
200 };
201
c45d8985 202 /* counters */
3ce39433 203 uint64_t pkts;
c45d8985 204
ff6365dd
EL
205 ThreadVars *tv;
206 TmSlot *slot;
9500d12c
EL
207 LiveDevice *livedev;
208 /* data link type for the thread */
b797fd92 209 uint32_t datalink;
9500d12c
EL
210
211 unsigned int frame_offset;
ff6365dd 212
9500d12c
EL
213 ChecksumValidationMode checksum_mode;
214
b797fd92 215 /* references to packet and drop counters */
9500d12c
EL
216 uint16_t capture_kernel_packets;
217 uint16_t capture_kernel_drops;
218
219 /* handle state */
220 uint8_t afp_state;
221 uint8_t copy_mode;
b797fd92 222 uint8_t flags;
9500d12c
EL
223
224 /* IPS peer */
225 AFPPeer *mpeer;
226
227 /* no mmap mode */
ff6365dd
EL
228 uint8_t *data; /** Per function and thread data */
229 int datalen; /** Length of per function and thread data */
9500d12c 230 int cooked;
ff6365dd 231
9500d12c
EL
232 /*
233 * Init related members
234 */
51eb9605 235
9500d12c
EL
236 /* thread specific socket */
237 int socket;
b797fd92
EL
238
239 int ring_size;
fa902abe 240 int block_size;
234aefdf 241 int block_timeout;
e80b30c0
EL
242 /* socket buffer size */
243 int buffer_size;
fa902abe 244 /* Filter */
ab1200fb 245 const char *bpf_filter;
9500d12c 246
df7dbe36 247 int promisc;
e80b30c0 248
9500d12c 249 int down_count;
662dccd8 250
e80b30c0
EL
251 int cluster_id;
252 int cluster_type;
c45d8985 253
fbca1a4e
EL
254 int threads;
255
b797fd92
EL
256 union {
257 struct tpacket_req req;
c2d0d938 258#ifdef HAVE_TPACKET_V3
b797fd92 259 struct tpacket_req3 req3;
c2d0d938 260#endif
b797fd92
EL
261 };
262
263 char iface[AFP_IFACE_NAME_LENGTH];
264 /* IPS output iface */
265 char out_iface[AFP_IFACE_NAME_LENGTH];
662dccd8 266
c45d8985
EL
267} AFPThreadVars;
268
269TmEcode ReceiveAFP(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *);
ab1200fb 270TmEcode ReceiveAFPThreadInit(ThreadVars *, const void *, void **);
c45d8985
EL
271void ReceiveAFPThreadExitStats(ThreadVars *, void *);
272TmEcode ReceiveAFPThreadDeinit(ThreadVars *, void *);
e80b30c0 273TmEcode ReceiveAFPLoop(ThreadVars *tv, void *data, void *slot);
c45d8985 274
ab1200fb 275TmEcode DecodeAFPThreadInit(ThreadVars *, const void *, void **);
2864f9ee 276TmEcode DecodeAFPThreadDeinit(ThreadVars *tv, void *data);
c45d8985
EL
277TmEcode DecodeAFP(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *);
278
f2a6fb8a 279TmEcode AFPSetBPFFilter(AFPThreadVars *ptv);
662dccd8 280static int AFPGetIfnumByDev(int fd, const char *ifname, int verbose);
13f13b6d
EL
281static int AFPGetDevFlags(int fd, const char *ifname);
282static int AFPDerefSocket(AFPPeer* peer);
283static int AFPRefSocket(AFPPeer* peer);
f2a6fb8a 284
c45d8985
EL
285/**
286 * \brief Registration Function for RecieveAFP.
287 * \todo Unit tests are needed for this module.
288 */
8f1d7503
KS
289void TmModuleReceiveAFPRegister (void)
290{
c45d8985
EL
291 tmm_modules[TMM_RECEIVEAFP].name = "ReceiveAFP";
292 tmm_modules[TMM_RECEIVEAFP].ThreadInit = ReceiveAFPThreadInit;
ff6365dd 293 tmm_modules[TMM_RECEIVEAFP].Func = NULL;
e80b30c0 294 tmm_modules[TMM_RECEIVEAFP].PktAcqLoop = ReceiveAFPLoop;
57e0bd39 295 tmm_modules[TMM_RECEIVEAFP].PktAcqBreakLoop = NULL;
c45d8985
EL
296 tmm_modules[TMM_RECEIVEAFP].ThreadExitPrintStats = ReceiveAFPThreadExitStats;
297 tmm_modules[TMM_RECEIVEAFP].ThreadDeinit = NULL;
298 tmm_modules[TMM_RECEIVEAFP].RegisterTests = NULL;
299 tmm_modules[TMM_RECEIVEAFP].cap_flags = SC_CAP_NET_RAW;
cd4705e6 300 tmm_modules[TMM_RECEIVEAFP].flags = TM_FLAG_RECEIVE_TM;
c45d8985
EL
301}
302
a6457262
EL
303
304/**
305 * \defgroup afppeers AFP peers list
306 *
307 * AF_PACKET has an IPS mode were interface are peered: packet from
308 * on interface are sent the peered interface and the other way. The ::AFPPeer
309 * list is maitaining the list of peers. Each ::AFPPeer is storing the needed
310 * information to be able to send packet on the interface.
311 * A element of the list must not be destroyed during the run of Suricata as it
312 * is used by ::Packet and other threads.
313 *
314 * @{
315 */
316
662dccd8
EL
317typedef struct AFPPeersList_ {
318 TAILQ_HEAD(, AFPPeer_) peers; /**< Head of list of fragments. */
319 int cnt;
320 int peered;
60400163
EL
321 int turn; /**< Next value for initialisation order */
322 SC_ATOMIC_DECLARE(int, reached); /**< Counter used to synchronize start */
662dccd8
EL
323} AFPPeersList;
324
325/**
a6457262
EL
326 * \brief Update the peer.
327 *
328 * Update the AFPPeer of a thread ie set new state, socket number
329 * or iface index.
330 *
662dccd8 331 */
ab1200fb 332static void AFPPeerUpdate(AFPThreadVars *ptv)
662dccd8
EL
333{
334 if (ptv->mpeer == NULL) {
335 return;
336 }
662dccd8
EL
337 (void)SC_ATOMIC_SET(ptv->mpeer->if_idx, AFPGetIfnumByDev(ptv->socket, ptv->iface, 0));
338 (void)SC_ATOMIC_SET(ptv->mpeer->socket, ptv->socket);
339 (void)SC_ATOMIC_SET(ptv->mpeer->state, ptv->afp_state);
340}
341
a6457262
EL
342/**
343 * \brief Clean and free ressource used by an ::AFPPeer
344 */
ab1200fb 345static void AFPPeerClean(AFPPeer *peer)
662dccd8
EL
346{
347 if (peer->flags & AFP_SOCK_PROTECT)
348 SCMutexDestroy(&peer->sock_protect);
349 SC_ATOMIC_DESTROY(peer->socket);
350 SC_ATOMIC_DESTROY(peer->if_idx);
351 SC_ATOMIC_DESTROY(peer->state);
352 SCFree(peer);
353}
354
355AFPPeersList peerslist;
356
357
a6457262
EL
358/**
359 * \brief Init the global list of ::AFPPeer
360 */
662dccd8
EL
361TmEcode AFPPeersListInit()
362{
363 SCEnter();
364 TAILQ_INIT(&peerslist.peers);
365 peerslist.peered = 0;
366 peerslist.cnt = 0;
60400163
EL
367 peerslist.turn = 0;
368 SC_ATOMIC_INIT(peerslist.reached);
369 (void) SC_ATOMIC_SET(peerslist.reached, 0);
662dccd8
EL
370 SCReturnInt(TM_ECODE_OK);
371}
372
a6457262
EL
373/**
374 * \brief Check that all ::AFPPeer got a peer
375 *
376 * \retval TM_ECODE_FAILED if some threads are not peered or TM_ECODE_OK else.
377 */
662dccd8
EL
378TmEcode AFPPeersListCheck()
379{
380#define AFP_PEERS_MAX_TRY 4
381#define AFP_PEERS_WAIT 20000
382 int try = 0;
383 SCEnter();
384 while (try < AFP_PEERS_MAX_TRY) {
385 if (peerslist.cnt != peerslist.peered) {
386 usleep(AFP_PEERS_WAIT);
387 } else {
388 SCReturnInt(TM_ECODE_OK);
389 }
390 try++;
391 }
392 SCLogError(SC_ERR_AFP_CREATE, "Threads number not equals");
393 SCReturnInt(TM_ECODE_FAILED);
394}
395
a6457262
EL
396/**
397 * \brief Declare a new AFP thread to AFP peers list.
398 */
ab1200fb 399static TmEcode AFPPeersListAdd(AFPThreadVars *ptv)
662dccd8
EL
400{
401 SCEnter();
402 AFPPeer *peer = SCMalloc(sizeof(AFPPeer));
403 AFPPeer *pitem;
ac56b1bf 404 int mtu, out_mtu;
662dccd8 405
e176be6f 406 if (unlikely(peer == NULL)) {
662dccd8
EL
407 SCReturnInt(TM_ECODE_FAILED);
408 }
409 memset(peer, 0, sizeof(AFPPeer));
410 SC_ATOMIC_INIT(peer->socket);
13f13b6d 411 SC_ATOMIC_INIT(peer->sock_usage);
662dccd8
EL
412 SC_ATOMIC_INIT(peer->if_idx);
413 SC_ATOMIC_INIT(peer->state);
414 peer->flags = ptv->flags;
60400163 415 peer->turn = peerslist.turn++;
662dccd8
EL
416
417 if (peer->flags & AFP_SOCK_PROTECT) {
418 SCMutexInit(&peer->sock_protect, NULL);
419 }
420
13f13b6d 421 (void)SC_ATOMIC_SET(peer->sock_usage, 0);
662dccd8
EL
422 (void)SC_ATOMIC_SET(peer->state, AFP_STATE_DOWN);
423 strlcpy(peer->iface, ptv->iface, AFP_IFACE_NAME_LENGTH);
424 ptv->mpeer = peer;
425 /* add element to iface list */
426 TAILQ_INSERT_TAIL(&peerslist.peers, peer, next);
662dccd8 427
13f13b6d
EL
428 if (ptv->copy_mode != AFP_COPY_MODE_NONE) {
429 peerslist.cnt++;
430
431 /* Iter to find a peer */
432 TAILQ_FOREACH(pitem, &peerslist.peers, next) {
433 if (pitem->peer)
434 continue;
435 if (strcmp(pitem->iface, ptv->out_iface))
436 continue;
437 peer->peer = pitem;
438 pitem->peer = peer;
439 mtu = GetIfaceMTU(ptv->iface);
440 out_mtu = GetIfaceMTU(ptv->out_iface);
441 if (mtu != out_mtu) {
442 SCLogError(SC_ERR_AFP_CREATE,
443 "MTU on %s (%d) and %s (%d) are not equal, "
444 "transmission of packets bigger than %d will fail.",
445 ptv->iface, mtu,
446 ptv->out_iface, out_mtu,
447 (out_mtu > mtu) ? mtu : out_mtu);
448 }
449 peerslist.peered += 2;
450 break;
ac56b1bf 451 }
662dccd8
EL
452 }
453
454 AFPPeerUpdate(ptv);
455
456 SCReturnInt(TM_ECODE_OK);
457}
458
ab1200fb 459static int AFPPeersListWaitTurn(AFPPeer *peer)
60400163 460{
b2691cbe
EL
461 /* If turn is zero, we already have started threads once */
462 if (peerslist.turn == 0)
463 return 0;
464
60400163
EL
465 if (peer->turn == SC_ATOMIC_GET(peerslist.reached))
466 return 0;
467 return 1;
468}
469
ab1200fb 470static void AFPPeersListReachedInc(void)
60400163 471{
b2691cbe
EL
472 if (peerslist.turn == 0)
473 return;
474
475 if (SC_ATOMIC_ADD(peerslist.reached, 1) == peerslist.turn) {
476 SCLogInfo("All AFP capture threads are running.");
477 (void)SC_ATOMIC_SET(peerslist.reached, 0);
478 /* Set turn to 0 to skip syncrhonization when ReceiveAFPLoop is
479 * restarted.
480 */
481 peerslist.turn = 0;
482 }
60400163
EL
483}
484
ab1200fb 485static int AFPPeersListStarted(void)
919377d4
EL
486{
487 return !peerslist.turn;
488}
489
a6457262
EL
490/**
491 * \brief Clean the global peers list.
492 */
662dccd8
EL
493void AFPPeersListClean()
494{
495 AFPPeer *pitem;
496
497 while ((pitem = TAILQ_FIRST(&peerslist.peers))) {
498 TAILQ_REMOVE(&peerslist.peers, pitem, next);
499 AFPPeerClean(pitem);
500 }
501}
502
a6457262
EL
503/**
504 * @}
505 */
506
c45d8985
EL
507/**
508 * \brief Registration Function for DecodeAFP.
509 * \todo Unit tests are needed for this module.
510 */
8f1d7503
KS
511void TmModuleDecodeAFPRegister (void)
512{
c45d8985
EL
513 tmm_modules[TMM_DECODEAFP].name = "DecodeAFP";
514 tmm_modules[TMM_DECODEAFP].ThreadInit = DecodeAFPThreadInit;
515 tmm_modules[TMM_DECODEAFP].Func = DecodeAFP;
516 tmm_modules[TMM_DECODEAFP].ThreadExitPrintStats = NULL;
2864f9ee 517 tmm_modules[TMM_DECODEAFP].ThreadDeinit = DecodeAFPThreadDeinit;
c45d8985
EL
518 tmm_modules[TMM_DECODEAFP].RegisterTests = NULL;
519 tmm_modules[TMM_DECODEAFP].cap_flags = 0;
bc6cf438 520 tmm_modules[TMM_DECODEAFP].flags = TM_FLAG_DECODE_TM;
c45d8985
EL
521}
522
662dccd8 523
e80b30c0
EL
524static int AFPCreateSocket(AFPThreadVars *ptv, char *devname, int verbose);
525
e8a4a4c4 526static inline void AFPDumpCounters(AFPThreadVars *ptv)
6efd37a3 527{
6efd37a3 528#ifdef PACKET_STATISTICS
e8a4a4c4
EL
529 struct tpacket_stats kstats;
530 socklen_t len = sizeof (struct tpacket_stats);
531 if (getsockopt(ptv->socket, SOL_PACKET, PACKET_STATISTICS,
532 &kstats, &len) > -1) {
533 SCLogDebug("(%s) Kernel: Packets %" PRIu32 ", dropped %" PRIu32 "",
534 ptv->tv->name,
535 kstats.tp_packets, kstats.tp_drops);
8992275b
VJ
536 StatsAddUI64(ptv->tv, ptv->capture_kernel_packets, kstats.tp_packets);
537 StatsAddUI64(ptv->tv, ptv->capture_kernel_drops, kstats.tp_drops);
3ce39433
EL
538 (void) SC_ATOMIC_ADD(ptv->livedev->drop, (uint64_t) kstats.tp_drops);
539 (void) SC_ATOMIC_ADD(ptv->livedev->pkts, (uint64_t) kstats.tp_packets);
6efd37a3 540 }
e8a4a4c4 541#endif
6efd37a3 542}
c45d8985
EL
543
544/**
545 * \brief AF packet read function.
546 *
547 * This function fills
548 * From here the packets are picked up by the DecodeAFP thread.
549 *
550 * \param user pointer to AFPThreadVars
551 * \retval TM_ECODE_FAILED on failure and TM_ECODE_OK on success
552 */
ab1200fb 553static int AFPRead(AFPThreadVars *ptv)
c45d8985
EL
554{
555 Packet *p = NULL;
556 /* XXX should try to use read that get directly to packet */
c45d8985
EL
557 int offset = 0;
558 int caplen;
559 struct sockaddr_ll from;
560 struct iovec iov;
561 struct msghdr msg;
c45d8985
EL
562 struct cmsghdr *cmsg;
563 union {
564 struct cmsghdr cmsg;
565 char buf[CMSG_SPACE(sizeof(struct tpacket_auxdata))];
566 } cmsg_buf;
6efd37a3 567 unsigned char aux_checksum = 0;
c45d8985
EL
568
569 msg.msg_name = &from;
570 msg.msg_namelen = sizeof(from);
571 msg.msg_iov = &iov;
572 msg.msg_iovlen = 1;
c45d8985
EL
573 msg.msg_control = &cmsg_buf;
574 msg.msg_controllen = sizeof(cmsg_buf);
c45d8985
EL
575 msg.msg_flags = 0;
576
577 if (ptv->cooked)
578 offset = SLL_HEADER_LEN;
579 else
580 offset = 0;
e80b30c0
EL
581 iov.iov_len = ptv->datalen - offset;
582 iov.iov_base = ptv->data + offset;
c45d8985
EL
583
584 caplen = recvmsg(ptv->socket, &msg, MSG_TRUNC);
585
586 if (caplen < 0) {
587 SCLogWarning(SC_ERR_AFP_READ, "recvmsg failed with error code %" PRId32,
588 errno);
62e63e3f 589 SCReturnInt(AFP_READ_FAILURE);
c45d8985 590 }
ff6365dd
EL
591
592 p = PacketGetFromQueueOrAlloc();
c45d8985 593 if (p == NULL) {
62e63e3f 594 SCReturnInt(AFP_FAILURE);
c45d8985 595 }
b33986c8 596 PKT_SET_SRC(p, PKT_SRC_WIRE);
c45d8985
EL
597
598 /* get timestamp of packet via ioctl */
599 if (ioctl(ptv->socket, SIOCGSTAMP, &p->ts) == -1) {
600 SCLogWarning(SC_ERR_AFP_READ, "recvmsg failed with error code %" PRId32,
601 errno);
602 TmqhOutputPacketpool(ptv->tv, p);
62e63e3f 603 SCReturnInt(AFP_READ_FAILURE);
c45d8985
EL
604 }
605
606 ptv->pkts++;
51eb9605 607 p->livedev = ptv->livedev;
c45d8985
EL
608
609 /* add forged header */
610 if (ptv->cooked) {
e80b30c0 611 SllHdr * hdrp = (SllHdr *)ptv->data;
c45d8985
EL
612 /* XXX this is minimalist, but this seems enough */
613 hdrp->sll_protocol = from.sll_protocol;
614 }
615
616 p->datalink = ptv->datalink;
617 SET_PKT_LEN(p, caplen + offset);
e80b30c0 618 if (PacketCopyData(p, ptv->data, GET_PKT_LEN(p)) == -1) {
c45d8985 619 TmqhOutputPacketpool(ptv->tv, p);
62e63e3f 620 SCReturnInt(AFP_FAILURE);
c45d8985 621 }
e80b30c0
EL
622 SCLogDebug("pktlen: %" PRIu32 " (pkt %p, pkt data %p)",
623 GET_PKT_LEN(p), p, GET_PKT_DATA(p));
624
6062e00c
EL
625 /* We only check for checksum disable */
626 if (ptv->checksum_mode == CHECKSUM_VALIDATION_DISABLE) {
51eb9605
EL
627 p->flags |= PKT_IGNORE_CHECKSUM;
628 } else if (ptv->checksum_mode == CHECKSUM_VALIDATION_AUTO) {
629 if (ptv->livedev->ignore_checksum) {
630 p->flags |= PKT_IGNORE_CHECKSUM;
a565148f 631 } else if (ChecksumAutoModeCheck(ptv->pkts,
51eb9605
EL
632 SC_ATOMIC_GET(ptv->livedev->pkts),
633 SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) {
634 ptv->livedev->ignore_checksum = 1;
6062e00c 635 p->flags |= PKT_IGNORE_CHECKSUM;
51eb9605 636 }
6062e00c 637 } else {
6efd37a3
EL
638 aux_checksum = 1;
639 }
6062e00c 640
6efd37a3
EL
641 /* List is NULL if we don't have activated auxiliary data */
642 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
643 struct tpacket_auxdata *aux;
f6ddaf33 644
6efd37a3
EL
645 if (cmsg->cmsg_len < CMSG_LEN(sizeof(struct tpacket_auxdata)) ||
646 cmsg->cmsg_level != SOL_PACKET ||
647 cmsg->cmsg_type != PACKET_AUXDATA)
648 continue;
f6ddaf33 649
6efd37a3
EL
650 aux = (struct tpacket_auxdata *)CMSG_DATA(cmsg);
651
652 if (aux_checksum && (aux->tp_status & TP_STATUS_CSUMNOTREADY)) {
653 p->flags |= PKT_IGNORE_CHECKSUM;
f6ddaf33 654 }
6efd37a3 655 break;
f6ddaf33
EL
656 }
657
c469824b
EL
658 if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) {
659 TmqhOutputPacketpool(ptv->tv, p);
62e63e3f 660 SCReturnInt(AFP_FAILURE);
c469824b 661 }
62e63e3f 662 SCReturnInt(AFP_READ_OK);
c45d8985
EL
663}
664
ecf59be4
EL
665/**
666 * \brief AF packet write function.
667 *
668 * This function has to be called before the memory
669 * related to Packet in ring buffer is released.
670 *
671 * \param pointer to Packet
672 * \param version of capture: TPACKET_V2 or TPACKET_V3
673 * \retval TM_ECODE_FAILED on failure and TM_ECODE_OK on success
674 *
675 */
676static TmEcode AFPWritePacket(Packet *p, int version)
662dccd8
EL
677{
678 struct sockaddr_ll socket_address;
679 int socket;
ecf59be4
EL
680 uint8_t *pstart;
681 size_t plen;
ee7e689b
AG
682 union thdr h;
683 uint16_t vlan_tci = 0;
662dccd8
EL
684
685 if (p->afp_v.copy_mode == AFP_COPY_MODE_IPS) {
3f107fa1 686 if (PACKET_TEST_ACTION(p, ACTION_DROP)) {
662dccd8
EL
687 return TM_ECODE_OK;
688 }
689 }
690
691 if (SC_ATOMIC_GET(p->afp_v.peer->state) == AFP_STATE_DOWN)
692 return TM_ECODE_OK;
693
694 if (p->ethh == NULL) {
695 SCLogWarning(SC_ERR_INVALID_VALUE, "Should have an Ethernet header");
696 return TM_ECODE_FAILED;
697 }
698 /* Index of the network device */
699 socket_address.sll_ifindex = SC_ATOMIC_GET(p->afp_v.peer->if_idx);
700 /* Address length*/
701 socket_address.sll_halen = ETH_ALEN;
702 /* Destination MAC */
703 memcpy(socket_address.sll_addr, p->ethh, 6);
704
705 /* Send packet, locking the socket if necessary */
706 if (p->afp_v.peer->flags & AFP_SOCK_PROTECT)
707 SCMutexLock(&p->afp_v.peer->sock_protect);
708 socket = SC_ATOMIC_GET(p->afp_v.peer->socket);
ecf59be4 709
ee7e689b
AG
710 h.raw = p->afp_v.relptr;
711
ecf59be4 712 if (version == TPACKET_V2) {
ecf59be4
EL
713 /* Copy VLAN header from ring memory. For post june 2011 kernel we test
714 * the flag. It is not defined for older kernel so we go best effort
715 * and test for non zero value of the TCI header. */
716 if (h.h2->tp_status & TP_STATUS_VLAN_VALID || h.h2->tp_vlan_tci) {
ee7e689b
AG
717 vlan_tci = h.h2->tp_vlan_tci;
718 }
719 } else {
720#ifdef HAVE_TPACKET_V3
721 if (h.h3->tp_status & TP_STATUS_VLAN_VALID || h.h3->hv1.tp_vlan_tci) {
722 vlan_tci = h.h3->hv1.tp_vlan_tci;
ecf59be4 723 }
ee7e689b
AG
724#else
725 /* Should not get here */
726 BUG_ON(1);
727#endif
728 }
729
730 if (vlan_tci != 0) {
731 pstart = GET_PKT_DATA(p) - VLAN_HEADER_LEN;
732 plen = GET_PKT_LEN(p) + VLAN_HEADER_LEN;
733 /* move ethernet addresses */
734 memmove(pstart, GET_PKT_DATA(p), 2 * ETH_ALEN);
735 /* write vlan info */
736 *(uint16_t *)(pstart + 2 * ETH_ALEN) = htons(0x8100);
737 *(uint16_t *)(pstart + 2 * ETH_ALEN + 2) = htons(vlan_tci);
ecf59be4
EL
738 } else {
739 pstart = GET_PKT_DATA(p);
740 plen = GET_PKT_LEN(p);
741 }
742
743 if (sendto(socket, pstart, plen, 0,
662dccd8
EL
744 (struct sockaddr*) &socket_address,
745 sizeof(struct sockaddr_ll)) < 0) {
746 SCLogWarning(SC_ERR_SOCKET, "Sending packet failed on socket %d: %s",
747 socket,
748 strerror(errno));
749 if (p->afp_v.peer->flags & AFP_SOCK_PROTECT)
750 SCMutexUnlock(&p->afp_v.peer->sock_protect);
751 return TM_ECODE_FAILED;
752 }
753 if (p->afp_v.peer->flags & AFP_SOCK_PROTECT)
754 SCMutexUnlock(&p->afp_v.peer->sock_protect);
755
756 return TM_ECODE_OK;
757}
758
ab1200fb 759static void AFPReleaseDataFromRing(Packet *p)
2011a3f8 760{
662dccd8
EL
761 /* Need to be in copy mode and need to detect early release
762 where Ethernet header could not be set (and pseudo packet) */
763 if ((p->afp_v.copy_mode != AFP_COPY_MODE_NONE) && !PKT_IS_PSEUDOPKT(p)) {
ecf59be4 764 AFPWritePacket(p, TPACKET_V2);
662dccd8 765 }
13f13b6d
EL
766
767 if (AFPDerefSocket(p->afp_v.mpeer) == 0)
680e941a 768 goto cleanup;
13f13b6d 769
2011a3f8
EL
770 if (p->afp_v.relptr) {
771 union thdr h;
772 h.raw = p->afp_v.relptr;
773 h.h2->tp_status = TP_STATUS_KERNEL;
2011a3f8 774 }
680e941a
EL
775
776cleanup:
777 AFPV_CLEANUP(&p->afp_v);
b076a26c
KS
778}
779
ecf59be4 780#ifdef HAVE_TPACKET_V3
ab1200fb 781static void AFPReleasePacketV3(Packet *p)
bae1b03c
EL
782{
783 /* Need to be in copy mode and need to detect early release
784 where Ethernet header could not be set (and pseudo packet) */
785 if ((p->afp_v.copy_mode != AFP_COPY_MODE_NONE) && !PKT_IS_PSEUDOPKT(p)) {
ecf59be4 786 AFPWritePacket(p, TPACKET_V3);
bae1b03c
EL
787 }
788 PacketFreeOrRelease(p);
789}
ecf59be4 790#endif
bae1b03c 791
ab1200fb 792static void AFPReleasePacket(Packet *p)
b076a26c
KS
793{
794 AFPReleaseDataFromRing(p);
795 PacketFreeOrRelease(p);
2011a3f8
EL
796}
797
49b7b00f
EL
798/**
799 * \brief AF packet read function for ring
800 *
801 * This function fills
802 * From here the packets are picked up by the DecodeAFP thread.
803 *
804 * \param user pointer to AFPThreadVars
805 * \retval TM_ECODE_FAILED on failure and TM_ECODE_OK on success
806 */
ab1200fb 807static int AFPReadFromRing(AFPThreadVars *ptv)
49b7b00f
EL
808{
809 Packet *p = NULL;
810 union thdr h;
27b5136b 811 uint8_t emergency_flush = 0;
4d8f70c6 812 int read_pkts = 0;
b26ec603 813 int loop_start = -1;
4d8f70c6 814
49b7b00f 815
a369f8c3
EL
816 /* Loop till we have packets available */
817 while (1) {
53c02334
AS
818 if (unlikely(suricata_ctl_flags != 0)) {
819 break;
820 }
821
a369f8c3 822 /* Read packet from ring */
b797fd92 823 h.raw = (((union thdr **)ptv->ring_v2)[ptv->frame_offset]);
a369f8c3 824 if (h.raw == NULL) {
34b3f194
EL
825 SCReturnInt(AFP_FAILURE);
826 }
662dccd8 827
82a2dd85 828 if ((! h.h2->tp_status) || (h.h2->tp_status & TP_STATUS_USER_BUSY)) {
4d8f70c6 829 if (read_pkts == 0) {
b26ec603
EL
830 if (loop_start == -1) {
831 loop_start = ptv->frame_offset;
832 } else if (unlikely(loop_start == (int)ptv->frame_offset)) {
833 SCReturnInt(AFP_READ_OK);
834 }
835 if (++ptv->frame_offset >= ptv->req.tp_frame_nr) {
836 ptv->frame_offset = 0;
837 }
838 continue;
4d8f70c6 839 }
27b5136b
EL
840 if ((emergency_flush) && (ptv->flags & AFP_EMERGENCY_MODE)) {
841 SCReturnInt(AFP_KERNEL_DROP);
842 } else {
843 SCReturnInt(AFP_READ_OK);
844 }
845 }
4d8f70c6
EL
846
847 read_pkts++;
b26ec603 848 loop_start = -1;
4d8f70c6 849
4a1a0080
EL
850 /* Our packet is still used by suricata, we exit read loop to
851 * gain some time */
852 if (h.h2->tp_status & TP_STATUS_USER_BUSY) {
853 SCReturnInt(AFP_READ_OK);
854 }
855
27b5136b
EL
856 if ((ptv->flags & AFP_EMERGENCY_MODE) && (emergency_flush == 1)) {
857 h.h2->tp_status = TP_STATUS_KERNEL;
858 goto next_frame;
a369f8c3
EL
859 }
860
861 p = PacketGetFromQueueOrAlloc();
862 if (p == NULL) {
34b3f194
EL
863 SCReturnInt(AFP_FAILURE);
864 }
b33986c8 865 PKT_SET_SRC(p, PKT_SRC_WIRE);
49b7b00f 866
4a1a0080
EL
867 /* Suricata will treat packet so telling it is busy, this
868 * status will be reset to 0 (ie TP_STATUS_KERNEL) in the release
869 * function. */
870 h.h2->tp_status |= TP_STATUS_USER_BUSY;
871
a369f8c3 872 ptv->pkts++;
a369f8c3 873 p->livedev = ptv->livedev;
a369f8c3 874 p->datalink = ptv->datalink;
d0940396 875
a369f8c3
EL
876 if (h.h2->tp_len > h.h2->tp_snaplen) {
877 SCLogDebug("Packet length (%d) > snaplen (%d), truncating",
878 h.h2->tp_len, h.h2->tp_snaplen);
879 }
71e47868
EL
880
881 /* get vlan id from header */
9500d12c 882 if ((!(ptv->flags & AFP_VLAN_DISABLED)) &&
e871f713 883 (h.h2->tp_status & TP_STATUS_VLAN_VALID || h.h2->tp_vlan_tci)) {
01a8cc4e 884 p->vlan_id[0] = h.h2->tp_vlan_tci & 0x0fff;
71e47868
EL
885 p->vlan_idx = 1;
886 p->vlanh[0] = NULL;
887 }
888
a369f8c3
EL
889 if (ptv->flags & AFP_ZERO_COPY) {
890 if (PacketSetData(p, (unsigned char*)h.raw + h.h2->tp_mac, h.h2->tp_snaplen) == -1) {
891 TmqhOutputPacketpool(ptv->tv, p);
892 SCReturnInt(AFP_FAILURE);
662dccd8 893 } else {
0f2b3406 894 p->afp_v.relptr = h.raw;
b076a26c 895 p->ReleasePacket = AFPReleasePacket;
5f12b234
EL
896 p->afp_v.mpeer = ptv->mpeer;
897 AFPRefSocket(ptv->mpeer);
0f2b3406
EL
898
899 p->afp_v.copy_mode = ptv->copy_mode;
900 if (p->afp_v.copy_mode != AFP_COPY_MODE_NONE) {
901 p->afp_v.peer = ptv->mpeer->peer;
902 } else {
903 p->afp_v.peer = NULL;
662dccd8 904 }
a369f8c3
EL
905 }
906 } else {
907 if (PacketCopyData(p, (unsigned char*)h.raw + h.h2->tp_mac, h.h2->tp_snaplen) == -1) {
908 TmqhOutputPacketpool(ptv->tv, p);
909 SCReturnInt(AFP_FAILURE);
910 }
911 }
912 /* Timestamp */
913 p->ts.tv_sec = h.h2->tp_sec;
914 p->ts.tv_usec = h.h2->tp_nsec/1000;
915 SCLogDebug("pktlen: %" PRIu32 " (pkt %p, pkt data %p)",
916 GET_PKT_LEN(p), p, GET_PKT_DATA(p));
917
918 /* We only check for checksum disable */
919 if (ptv->checksum_mode == CHECKSUM_VALIDATION_DISABLE) {
920 p->flags |= PKT_IGNORE_CHECKSUM;
921 } else if (ptv->checksum_mode == CHECKSUM_VALIDATION_AUTO) {
922 if (ptv->livedev->ignore_checksum) {
923 p->flags |= PKT_IGNORE_CHECKSUM;
924 } else if (ChecksumAutoModeCheck(ptv->pkts,
925 SC_ATOMIC_GET(ptv->livedev->pkts),
926 SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) {
927 ptv->livedev->ignore_checksum = 1;
928 p->flags |= PKT_IGNORE_CHECKSUM;
929 }
930 } else {
931 if (h.h2->tp_status & TP_STATUS_CSUMNOTREADY) {
49b7b00f 932 p->flags |= PKT_IGNORE_CHECKSUM;
a369f8c3 933 }
ee6ba099
EL
934 }
935 if (h.h2->tp_status & TP_STATUS_LOSING) {
936 emergency_flush = 1;
e8a4a4c4 937 AFPDumpCounters(ptv);
a369f8c3
EL
938 }
939
5f12b234
EL
940 /* release frame if not in zero copy mode */
941 if (!(ptv->flags & AFP_ZERO_COPY)) {
942 h.h2->tp_status = TP_STATUS_KERNEL;
943 }
944
a369f8c3
EL
945 if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) {
946 h.h2->tp_status = TP_STATUS_KERNEL;
947 if (++ptv->frame_offset >= ptv->req.tp_frame_nr) {
948 ptv->frame_offset = 0;
949 }
950 TmqhOutputPacketpool(ptv->tv, p);
951 SCReturnInt(AFP_FAILURE);
49b7b00f 952 }
49b7b00f 953
27b5136b 954next_frame:
34b3f194
EL
955 if (++ptv->frame_offset >= ptv->req.tp_frame_nr) {
956 ptv->frame_offset = 0;
350d7619
EL
957 /* Get out of loop to be sure we will reach maintenance tasks */
958 SCReturnInt(AFP_READ_OK);
34b3f194 959 }
34b3f194
EL
960 }
961
49b7b00f
EL
962 SCReturnInt(AFP_READ_OK);
963}
964
f947539d 965#ifdef HAVE_TPACKET_V3
bae1b03c
EL
966static inline void AFPFlushBlock(struct tpacket_block_desc *pbd)
967{
968 pbd->hdr.bh1.block_status = TP_STATUS_KERNEL;
969}
970
971static inline int AFPParsePacketV3(AFPThreadVars *ptv, struct tpacket_block_desc *pbd, struct tpacket3_hdr *ppd)
972{
973 Packet *p = PacketGetFromQueueOrAlloc();
974 if (p == NULL) {
975 SCReturnInt(AFP_FAILURE);
976 }
977 PKT_SET_SRC(p, PKT_SRC_WIRE);
978
979 ptv->pkts++;
bae1b03c
EL
980 p->livedev = ptv->livedev;
981 p->datalink = ptv->datalink;
982
e41a9d63
AG
983 if ((!(ptv->flags & AFP_VLAN_DISABLED)) &&
984 (ppd->tp_status & TP_STATUS_VLAN_VALID || ppd->hv1.tp_vlan_tci)) {
985 p->vlan_id[0] = ppd->hv1.tp_vlan_tci & 0x0fff;
986 p->vlan_idx = 1;
987 p->vlanh[0] = NULL;
988 }
989
bae1b03c
EL
990 if (ptv->flags & AFP_ZERO_COPY) {
991 if (PacketSetData(p, (unsigned char*)ppd + ppd->tp_mac, ppd->tp_snaplen) == -1) {
992 TmqhOutputPacketpool(ptv->tv, p);
993 SCReturnInt(AFP_FAILURE);
994 }
310b27a1 995 p->afp_v.relptr = ppd;
bae1b03c
EL
996 p->ReleasePacket = AFPReleasePacketV3;
997 p->afp_v.mpeer = ptv->mpeer;
998 AFPRefSocket(ptv->mpeer);
999
1000 p->afp_v.copy_mode = ptv->copy_mode;
1001 if (p->afp_v.copy_mode != AFP_COPY_MODE_NONE) {
1002 p->afp_v.peer = ptv->mpeer->peer;
1003 } else {
1004 p->afp_v.peer = NULL;
1005 }
1006 } else {
1007 if (PacketCopyData(p, (unsigned char*)ppd + ppd->tp_mac, ppd->tp_snaplen) == -1) {
1008 TmqhOutputPacketpool(ptv->tv, p);
1009 SCReturnInt(AFP_FAILURE);
1010 }
1011 }
1012 /* Timestamp */
1013 p->ts.tv_sec = ppd->tp_sec;
1014 p->ts.tv_usec = ppd->tp_nsec/1000;
1015 SCLogDebug("pktlen: %" PRIu32 " (pkt %p, pkt data %p)",
1016 GET_PKT_LEN(p), p, GET_PKT_DATA(p));
1017
1018 /* We only check for checksum disable */
1019 if (ptv->checksum_mode == CHECKSUM_VALIDATION_DISABLE) {
1020 p->flags |= PKT_IGNORE_CHECKSUM;
1021 } else if (ptv->checksum_mode == CHECKSUM_VALIDATION_AUTO) {
1022 if (ptv->livedev->ignore_checksum) {
1023 p->flags |= PKT_IGNORE_CHECKSUM;
1024 } else if (ChecksumAutoModeCheck(ptv->pkts,
1025 SC_ATOMIC_GET(ptv->livedev->pkts),
1026 SC_ATOMIC_GET(ptv->livedev->invalid_checksums))) {
1027 ptv->livedev->ignore_checksum = 1;
1028 p->flags |= PKT_IGNORE_CHECKSUM;
1029 }
1030 } else {
1031 if (ppd->tp_status & TP_STATUS_CSUMNOTREADY) {
1032 p->flags |= PKT_IGNORE_CHECKSUM;
1033 }
1034 }
1035
1036 if (TmThreadsSlotProcessPkt(ptv->tv, ptv->slot, p) != TM_ECODE_OK) {
bae1b03c
EL
1037 TmqhOutputPacketpool(ptv->tv, p);
1038 SCReturnInt(AFP_FAILURE);
1039 }
1040
1041 SCReturnInt(AFP_READ_OK);
1042}
1043
1044static inline int AFPWalkBlock(AFPThreadVars *ptv, struct tpacket_block_desc *pbd)
1045{
1046 int num_pkts = pbd->hdr.bh1.num_pkts, i;
1047 uint8_t *ppd;
1048
1049 ppd = (uint8_t *)pbd + pbd->hdr.bh1.offset_to_first_pkt;
1050 for (i = 0; i < num_pkts; ++i) {
5f84b55d
EL
1051 if (unlikely(AFPParsePacketV3(ptv, pbd,
1052 (struct tpacket3_hdr *)ppd) == AFP_FAILURE)) {
1053 SCReturnInt(AFP_READ_FAILURE);
1054 }
bae1b03c
EL
1055 ppd = ppd + ((struct tpacket3_hdr *)ppd)->tp_next_offset;
1056 }
1057
1058 SCReturnInt(AFP_READ_OK);
1059}
f947539d 1060#endif /* HAVE_TPACKET_V3 */
bae1b03c
EL
1061
1062/**
1063 * \brief AF packet read function for ring
1064 *
1065 * This function fills
1066 * From here the packets are picked up by the DecodeAFP thread.
1067 *
1068 * \param user pointer to AFPThreadVars
1069 * \retval TM_ECODE_FAILED on failure and TM_ECODE_OK on success
1070 */
ab1200fb 1071static int AFPReadFromRingV3(AFPThreadVars *ptv)
bae1b03c 1072{
c2d0d938 1073#ifdef HAVE_TPACKET_V3
bae1b03c
EL
1074 struct tpacket_block_desc *pbd;
1075
1076 /* Loop till we have packets available */
1077 while (1) {
1078 if (unlikely(suricata_ctl_flags != 0)) {
1079 SCLogInfo("Exiting AFP V3 read loop");
1080 break;
1081 }
1082
b797fd92 1083 pbd = (struct tpacket_block_desc *) ptv->ring_v3[ptv->frame_offset].iov_base;
bae1b03c
EL
1084
1085 /* block is not ready to be read */
1086 if ((pbd->hdr.bh1.block_status & TP_STATUS_USER) == 0) {
1087 SCReturnInt(AFP_READ_OK);
1088 }
1089
1090 if (unlikely(AFPWalkBlock(ptv, pbd) != AFP_READ_OK)) {
1091 AFPFlushBlock(pbd);
1092 SCReturnInt(AFP_READ_FAILURE);
1093 }
1094
1095 AFPFlushBlock(pbd);
1096 ptv->frame_offset = (ptv->frame_offset + 1) % ptv->req3.tp_block_nr;
1097 /* return to maintenance task after one loop on the ring */
1098 if (ptv->frame_offset == 0) {
1099 SCReturnInt(AFP_READ_OK);
1100 }
1101 }
c2d0d938 1102#endif
bae1b03c
EL
1103 SCReturnInt(AFP_READ_OK);
1104}
1105
13f13b6d
EL
1106/**
1107 * \brief Reference socket
1108 *
1109 * \retval O in case of failure, 1 in case of success
1110 */
1111static int AFPRefSocket(AFPPeer* peer)
1112{
1113 if (unlikely(peer == NULL))
1114 return 0;
1115
1116 (void)SC_ATOMIC_ADD(peer->sock_usage, 1);
1117 return 1;
1118}
1119
1120
1121/**
1122 * \brief Dereference socket
1123 *
1124 * \retval 1 if socket is still alive, 0 if not
1125 */
1126static int AFPDerefSocket(AFPPeer* peer)
1127{
4424f5a2
EL
1128 if (peer == NULL)
1129 return 1;
1130
13f13b6d
EL
1131 if (SC_ATOMIC_SUB(peer->sock_usage, 1) == 0) {
1132 if (SC_ATOMIC_GET(peer->state) == AFP_STATE_DOWN) {
1133 SCLogInfo("Cleaning socket connected to '%s'", peer->iface);
1134 close(SC_ATOMIC_GET(peer->socket));
1135 return 0;
1136 }
1137 }
1138 return 1;
1139}
1140
ab1200fb 1141static void AFPSwitchState(AFPThreadVars *ptv, int state)
13f13b6d
EL
1142{
1143 ptv->afp_state = state;
1144 ptv->down_count = 0;
49b7b00f 1145
13f13b6d
EL
1146 AFPPeerUpdate(ptv);
1147
1148 /* Do cleaning if switching to down state */
1149 if (state == AFP_STATE_DOWN) {
5f84b55d
EL
1150#ifdef HAVE_TPACKET_V3
1151 if (ptv->flags & AFP_TPACKET_V3) {
1152 if (!ptv->ring_v3) {
1153 SCFree(ptv->ring_v3);
1154 ptv->ring_v3 = NULL;
1155 }
1156 } else {
1157#endif
1158 if (ptv->ring_v2) {
1159 /* only used in reading phase, we can free it */
1160 SCFree(ptv->ring_v2);
1161 ptv->ring_v2 = NULL;
1162 }
1163#ifdef HAVE_TPACKET_V3
13f13b6d 1164 }
5f84b55d 1165#endif
13f13b6d
EL
1166 if (ptv->socket != -1) {
1167 /* we need to wait for all packets to return data */
1168 if (SC_ATOMIC_SUB(ptv->mpeer->sock_usage, 1) == 0) {
1169 SCLogInfo("Cleaning socket connected to '%s'", ptv->iface);
1170 close(ptv->socket);
1171 ptv->socket = -1;
1172 }
1173 }
1174 }
1175 if (state == AFP_STATE_UP) {
1176 (void)SC_ATOMIC_SET(ptv->mpeer->sock_usage, 1);
1177 }
1178}
49b7b00f 1179
7fea0ec6
EL
1180static int AFPReadAndDiscard(AFPThreadVars *ptv, struct timeval *synctv,
1181 uint64_t *discarded_pkts)
919377d4
EL
1182{
1183 struct sockaddr_ll from;
1184 struct iovec iov;
1185 struct msghdr msg;
1186 struct timeval ts;
1187 union {
1188 struct cmsghdr cmsg;
1189 char buf[CMSG_SPACE(sizeof(struct tpacket_auxdata))];
1190 } cmsg_buf;
1191
1192
1193 if (unlikely(suricata_ctl_flags != 0)) {
1194 return 1;
1195 }
1196
1197 msg.msg_name = &from;
1198 msg.msg_namelen = sizeof(from);
1199 msg.msg_iov = &iov;
1200 msg.msg_iovlen = 1;
1201 msg.msg_control = &cmsg_buf;
1202 msg.msg_controllen = sizeof(cmsg_buf);
1203 msg.msg_flags = 0;
1204
1205 iov.iov_len = ptv->datalen;
1206 iov.iov_base = ptv->data;
1207
339f0665 1208 (void)recvmsg(ptv->socket, &msg, MSG_TRUNC);
919377d4
EL
1209
1210 if (ioctl(ptv->socket, SIOCGSTAMP, &ts) == -1) {
1211 /* FIXME */
1212 return -1;
1213 }
1214
1215 if ((ts.tv_sec > synctv->tv_sec) ||
1216 (ts.tv_sec >= synctv->tv_sec &&
1217 ts.tv_usec > synctv->tv_usec)) {
1218 return 1;
1219 }
1220 return 0;
1221}
1222
7fea0ec6
EL
1223static int AFPReadAndDiscardFromRing(AFPThreadVars *ptv, struct timeval *synctv,
1224 uint64_t *discarded_pkts)
919377d4
EL
1225{
1226 union thdr h;
1227
1228 if (unlikely(suricata_ctl_flags != 0)) {
1229 return 1;
1230 }
1231
f947539d 1232#ifdef HAVE_TPACKET_V3
bae1b03c 1233 if (ptv->flags & AFP_TPACKET_V3) {
7fea0ec6
EL
1234 struct tpacket_block_desc *pbd;
1235 pbd = (struct tpacket_block_desc *) ptv->ring_v3[ptv->frame_offset].iov_base;
1236 *discarded_pkts += pbd->hdr.bh1.num_pkts;
1237 AFPFlushBlock(pbd);
1238 ptv->frame_offset = (ptv->frame_offset + 1) % ptv->req3.tp_block_nr;
bae1b03c 1239 return 1;
f947539d
VJ
1240
1241 } else
1242#endif
1243 {
7fea0ec6
EL
1244 /* Read packet from ring */
1245 h.raw = (((union thdr **)ptv->ring_v2)[ptv->frame_offset]);
1246 if (h.raw == NULL) {
1247 return -1;
1248 }
1249 (*discarded_pkts)++;
1250 if (((time_t)h.h2->tp_sec > synctv->tv_sec) ||
1251 ((time_t)h.h2->tp_sec == synctv->tv_sec &&
1252 (suseconds_t) (h.h2->tp_nsec / 1000) > synctv->tv_usec)) {
1253 return 1;
1254 }
919377d4 1255
7fea0ec6
EL
1256 h.h2->tp_status = TP_STATUS_KERNEL;
1257 if (++ptv->frame_offset >= ptv->req.tp_frame_nr) {
1258 ptv->frame_offset = 0;
1259 }
919377d4
EL
1260 }
1261
1262
1263 return 0;
1264}
1265
806844d8
VJ
1266/** \brief wait for all afpacket threads to fully init
1267 *
1268 * Discard packets before all threads are ready, as the cluster
1269 * setup is not complete yet.
1270 *
1271 * if AFPPeersListStarted() returns true init is complete
1272 *
1273 * \retval r 1 = happy, otherwise unhappy
1274 */
7fea0ec6 1275static int AFPSynchronizeStart(AFPThreadVars *ptv, uint64_t *discarded_pkts)
919377d4
EL
1276{
1277 int r;
1278 struct timeval synctv;
806844d8
VJ
1279 struct pollfd fds;
1280
1281 fds.fd = ptv->socket;
1282 fds.events = POLLIN;
919377d4
EL
1283
1284 /* Set timeval to end of the world */
1285 synctv.tv_sec = 0xffffffff;
1286 synctv.tv_usec = 0xffffffff;
1287
1288 while (1) {
806844d8
VJ
1289 r = poll(&fds, 1, POLL_TIMEOUT);
1290 if (r > 0 &&
1291 (fds.revents & (POLLHUP|POLLRDHUP|POLLERR|POLLNVAL))) {
1292 SCLogWarning(SC_ERR_AFP_READ, "poll failed %02x",
1293 fds.revents & (POLLHUP|POLLRDHUP|POLLERR|POLLNVAL));
1294 return 0;
1295 } else if (r > 0) {
1296 if (AFPPeersListStarted() && synctv.tv_sec == (time_t) 0xffffffff) {
1297 gettimeofday(&synctv, NULL);
1298 }
1299 if (ptv->flags & AFP_RING_MODE) {
7fea0ec6 1300 r = AFPReadAndDiscardFromRing(ptv, &synctv, discarded_pkts);
806844d8 1301 } else {
7fea0ec6 1302 r = AFPReadAndDiscard(ptv, &synctv, discarded_pkts);
806844d8
VJ
1303 }
1304 SCLogDebug("Discarding on %s", ptv->tv->name);
1305 switch (r) {
1306 case 1:
9f7ba071 1307 SCLogDebug("Starting to read on %s", ptv->tv->name);
806844d8
VJ
1308 return 1;
1309 case -1:
1310 return r;
1311 }
1312 /* no packets */
1313 } else if (r == 0 && AFPPeersListStarted()) {
86a3f064 1314 SCLogDebug("Starting to read on %s", ptv->tv->name);
806844d8 1315 return 1;
43b6cbd4 1316 } else if (r < 0) { /* only exit on error */
806844d8
VJ
1317 SCLogWarning(SC_ERR_AFP_READ, "poll failed with retval %d", r);
1318 return 0;
919377d4
EL
1319 }
1320 }
1321 return 1;
1322}
1323
13f13b6d
EL
1324/**
1325 * \brief Try to reopen socket
1326 *
1327 * \retval 0 in case of success, negative if error occurs or a condition
1328 * is not met.
1329 */
c45d8985
EL
1330static int AFPTryReopen(AFPThreadVars *ptv)
1331{
1332 int afp_activate_r;
1333
13f13b6d
EL
1334 ptv->down_count++;
1335
1336
1337 /* Don't reconnect till we have packet that did not release data */
1338 if (SC_ATOMIC_GET(ptv->mpeer->sock_usage) != 0) {
1339 return -1;
1340 }
c45d8985 1341
e80b30c0 1342 afp_activate_r = AFPCreateSocket(ptv, ptv->iface, 0);
c45d8985 1343 if (afp_activate_r != 0) {
13f13b6d
EL
1344 if (ptv->down_count % AFP_DOWN_COUNTER_INTERVAL == 0) {
1345 SCLogWarning(SC_ERR_AFP_CREATE, "Can not open iface '%s'",
1346 ptv->iface);
1347 }
c45d8985
EL
1348 return afp_activate_r;
1349 }
1350
3bea3b39 1351 SCLogInfo("Interface '%s' is back", ptv->iface);
c45d8985
EL
1352 return 0;
1353}
1354
e80b30c0
EL
1355/**
1356 * \brief Main AF_PACKET reading Loop function
1357 */
1358TmEcode ReceiveAFPLoop(ThreadVars *tv, void *data, void *slot)
1359{
34581ce9
AS
1360 SCEnter();
1361
e80b30c0 1362 AFPThreadVars *ptv = (AFPThreadVars *)data;
e80b30c0
EL
1363 struct pollfd fds;
1364 int r;
34581ce9 1365 TmSlot *s = (TmSlot *)slot;
e8a4a4c4 1366 time_t last_dump = 0;
49612128 1367 time_t current_time;
5f400785 1368 int (*AFPReadFunc) (AFPThreadVars *);
7fea0ec6 1369 uint64_t discarded_pkts = 0;
e80b30c0 1370
34581ce9 1371 ptv->slot = s->slot_next;
e80b30c0 1372
5f400785 1373 if (ptv->flags & AFP_RING_MODE) {
bae1b03c
EL
1374 if (ptv->flags & AFP_TPACKET_V3) {
1375 AFPReadFunc = AFPReadFromRingV3;
1376 } else {
1377 AFPReadFunc = AFPReadFromRing;
1378 }
5f400785
EL
1379 } else {
1380 AFPReadFunc = AFPRead;
1381 }
1382
60400163
EL
1383 if (ptv->afp_state == AFP_STATE_DOWN) {
1384 /* Wait for our turn, threads before us must have opened the socket */
1385 while (AFPPeersListWaitTurn(ptv->mpeer)) {
1386 usleep(1000);
1992a227
EL
1387 if (suricata_ctl_flags != 0) {
1388 break;
1389 }
60400163
EL
1390 }
1391 r = AFPCreateSocket(ptv, ptv->iface, 1);
1392 if (r < 0) {
1992a227
EL
1393 switch (-r) {
1394 case AFP_FATAL_ERROR:
1395 SCLogError(SC_ERR_AFP_CREATE, "Couldn't init AF_PACKET socket, fatal error");
1992a227
EL
1396 SCReturnInt(TM_ECODE_FAILED);
1397 case AFP_RECOVERABLE_ERROR:
1398 SCLogWarning(SC_ERR_AFP_CREATE, "Couldn't init AF_PACKET socket, retrying soon");
1399 }
60400163
EL
1400 }
1401 AFPPeersListReachedInc();
1402 }
1403 if (ptv->afp_state == AFP_STATE_UP) {
86a3f064 1404 SCLogDebug("Thread %s using socket %d", tv->name, ptv->socket);
bae1b03c 1405 if ((ptv->flags & AFP_TPACKET_V3) != 0) {
7fea0ec6 1406 AFPSynchronizeStart(ptv, &discarded_pkts);
bae1b03c 1407 }
7fea0ec6
EL
1408 /* let's reset counter as we will start the capture at the
1409 * next function call */
1410#ifdef PACKET_STATISTICS
1411 struct tpacket_stats kstats;
1412 socklen_t len = sizeof (struct tpacket_stats);
1413 if (getsockopt(ptv->socket, SOL_PACKET, PACKET_STATISTICS,
1414 &kstats, &len) > -1) {
1415 uint64_t pkts = 0;
1416 SCLogDebug("(%s) Kernel socket startup: Packets %" PRIu32
1417 ", dropped %" PRIu32 "",
1418 ptv->tv->name,
1419 kstats.tp_packets, kstats.tp_drops);
1420 pkts = kstats.tp_packets - discarded_pkts - kstats.tp_drops;
1421 StatsAddUI64(ptv->tv, ptv->capture_kernel_packets, pkts);
1422 (void) SC_ATOMIC_ADD(ptv->livedev->pkts, pkts);
1423 }
1424#endif
60400163
EL
1425 }
1426
e80b30c0
EL
1427 fds.fd = ptv->socket;
1428 fds.events = POLLIN;
1429
1430 while (1) {
1431 /* Start by checking the state of our interface */
1432 if (unlikely(ptv->afp_state == AFP_STATE_DOWN)) {
1433 int dbreak = 0;
662dccd8 1434
e80b30c0
EL
1435 do {
1436 usleep(AFP_RECONNECT_TIMEOUT);
1437 if (suricata_ctl_flags != 0) {
1438 dbreak = 1;
1439 break;
1440 }
1441 r = AFPTryReopen(ptv);
09e709d1 1442 fds.fd = ptv->socket;
e80b30c0
EL
1443 } while (r < 0);
1444 if (dbreak == 1)
1445 break;
1446 }
1447
1448 /* make sure we have at least one packet in the packet pool, to prevent
1449 * us from alloc'ing packets at line rate */
3c6e01f6 1450 PacketPoolWait();
e80b30c0
EL
1451
1452 r = poll(&fds, 1, POLL_TIMEOUT);
1453
1454 if (suricata_ctl_flags != 0) {
1455 break;
1456 }
1457
1458 if (r > 0 &&
1459 (fds.revents & (POLLHUP|POLLRDHUP|POLLERR|POLLNVAL))) {
1460 if (fds.revents & (POLLHUP | POLLRDHUP)) {
13f13b6d 1461 AFPSwitchState(ptv, AFP_STATE_DOWN);
e80b30c0 1462 continue;
ff6365dd 1463 } else if (fds.revents & POLLERR) {
e80b30c0
EL
1464 char c;
1465 /* Do a recv to get errno */
1466 if (recv(ptv->socket, &c, sizeof c, MSG_PEEK) != -1)
1467 continue; /* what, no error? */
3bea3b39
EL
1468 SCLogError(SC_ERR_AFP_READ,
1469 "Error reading data from iface '%s': (%d" PRIu32 ") %s",
1470 ptv->iface, errno, strerror(errno));
13f13b6d 1471 AFPSwitchState(ptv, AFP_STATE_DOWN);
e80b30c0 1472 continue;
ff6365dd 1473 } else if (fds.revents & POLLNVAL) {
e80b30c0 1474 SCLogError(SC_ERR_AFP_READ, "Invalid polling request");
13f13b6d 1475 AFPSwitchState(ptv, AFP_STATE_DOWN);
e80b30c0
EL
1476 continue;
1477 }
1478 } else if (r > 0) {
5f400785 1479 r = AFPReadFunc(ptv);
62e63e3f 1480 switch (r) {
27adbfa8
EL
1481 case AFP_READ_OK:
1482 /* Trigger one dump of stats every second */
49612128
EL
1483 current_time = time(NULL);
1484 if (current_time != last_dump) {
27adbfa8 1485 AFPDumpCounters(ptv);
49612128 1486 last_dump = current_time;
27adbfa8
EL
1487 }
1488 break;
62e63e3f
EL
1489 case AFP_READ_FAILURE:
1490 /* AFPRead in error: best to reset the socket */
3bea3b39
EL
1491 SCLogError(SC_ERR_AFP_READ,
1492 "AFPRead error reading data from iface '%s': (%d" PRIu32 ") %s",
1493 ptv->iface, errno, strerror(errno));
13f13b6d 1494 AFPSwitchState(ptv, AFP_STATE_DOWN);
62e63e3f
EL
1495 continue;
1496 case AFP_FAILURE:
13f13b6d 1497 AFPSwitchState(ptv, AFP_STATE_DOWN);
62e63e3f
EL
1498 SCReturnInt(TM_ECODE_FAILED);
1499 break;
27b5136b 1500 case AFP_KERNEL_DROP:
e8a4a4c4 1501 AFPDumpCounters(ptv);
27b5136b 1502 break;
e80b30c0 1503 }
11099cfa
VJ
1504 } else if (unlikely(r == 0)) {
1505 /* poll timed out, lets see if we need to inject a fake packet */
1506 TmThreadsCaptureInjectPacket(tv, ptv->slot, NULL);
1507
e80b30c0 1508 } else if ((r < 0) && (errno != EINTR)) {
3bea3b39
EL
1509 SCLogError(SC_ERR_AFP_READ, "Error reading data from iface '%s': (%d" PRIu32 ") %s",
1510 ptv->iface,
e80b30c0 1511 errno, strerror(errno));
13f13b6d 1512 AFPSwitchState(ptv, AFP_STATE_DOWN);
e80b30c0
EL
1513 continue;
1514 }
752f03e7 1515 StatsSyncCountersIfSignalled(tv);
e80b30c0
EL
1516 }
1517
4e561d6b 1518 AFPDumpCounters(ptv);
752f03e7 1519 StatsSyncCountersIfSignalled(tv);
e80b30c0
EL
1520 SCReturnInt(TM_ECODE_OK);
1521}
1522
13f13b6d
EL
1523static int AFPGetDevFlags(int fd, const char *ifname)
1524{
1525 struct ifreq ifr;
1526
1527 memset(&ifr, 0, sizeof(ifr));
1528 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
1529
1530 if (ioctl(fd, SIOCGIFFLAGS, &ifr) == -1) {
1531 SCLogError(SC_ERR_AFP_CREATE, "Unable to find type for iface \"%s\": %s",
1532 ifname, strerror(errno));
1533 return -1;
1534 }
1535
1536 return ifr.ifr_flags;
1537}
1538
1539
e80b30c0 1540static int AFPGetIfnumByDev(int fd, const char *ifname, int verbose)
c45d8985
EL
1541{
1542 struct ifreq ifr;
1543
1544 memset(&ifr, 0, sizeof(ifr));
e80b30c0 1545 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
c45d8985
EL
1546
1547 if (ioctl(fd, SIOCGIFINDEX, &ifr) == -1) {
1548 if (verbose)
1549 SCLogError(SC_ERR_AFP_CREATE, "Unable to find iface %s: %s",
1550 ifname, strerror(errno));
1551 return -1;
1552 }
1553
1554 return ifr.ifr_ifindex;
1555}
1556
e80b30c0 1557static int AFPGetDevLinktype(int fd, const char *ifname)
c45d8985
EL
1558{
1559 struct ifreq ifr;
1560
1561 memset(&ifr, 0, sizeof(ifr));
e80b30c0 1562 strlcpy(ifr.ifr_name, ifname, sizeof(ifr.ifr_name));
c45d8985
EL
1563
1564 if (ioctl(fd, SIOCGIFHWADDR, &ifr) == -1) {
1565 SCLogError(SC_ERR_AFP_CREATE, "Unable to find type for iface \"%s\": %s",
1566 ifname, strerror(errno));
1567 return -1;
1568 }
1569
e80b30c0
EL
1570 switch (ifr.ifr_hwaddr.sa_family) {
1571 case ARPHRD_LOOPBACK:
1572 return LINKTYPE_ETHERNET;
1573 case ARPHRD_PPP:
11eb1d7c 1574 case ARPHRD_NONE:
e80b30c0
EL
1575 return LINKTYPE_RAW;
1576 default:
1577 return ifr.ifr_hwaddr.sa_family;
1578 }
c45d8985
EL
1579}
1580
b7bf299e
EL
1581int AFPGetLinkType(const char *ifname)
1582{
1583 int ltype;
1584
1585 int fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
1586 if (fd == -1) {
1587 SCLogError(SC_ERR_AFP_CREATE, "Couldn't create a AF_PACKET socket, error %s", strerror(errno));
1588 return LINKTYPE_RAW;
1589 }
1590
1591 ltype = AFPGetDevLinktype(fd, ifname);
1592 close(fd);
1593
1594 return ltype;
1595}
1596
49b7b00f
EL
1597static int AFPComputeRingParams(AFPThreadVars *ptv, int order)
1598{
1599 /* Compute structure:
1600 Target is to store all pending packets
1601 with a size equal to MTU + auxdata
1602 And we keep a decent number of block
1603
1604 To do so:
1605 Compute frame_size (aligned to be able to fit in block
1606 Check which block size we need. Blocksize is a 2^n * pagesize
1607 We then need to get order, big enough to have
1608 frame_size < block size
1609 Find number of frame per block (divide)
1610 Fill in packet_req
1611
1612 Compute frame size:
1613 described in packet_mmap.txt
1614 dependant on snaplen (need to use a variable ?)
1615snaplen: MTU ?
1616tp_hdrlen determine_version in daq_afpacket
1617in V1: sizeof(struct tpacket_hdr);
1618in V2: val in getsockopt(instance->fd, SOL_PACKET, PACKET_HDRLEN, &val, &len)
1619frame size: TPACKET_ALIGN(snaplen + TPACKET_ALIGN(TPACKET_ALIGN(tp_hdrlen) + sizeof(struct sockaddr_ll) + ETH_HLEN) - ETH_HLEN);
1620
1621 */
1622 int tp_hdrlen = sizeof(struct tpacket_hdr);
1623 int snaplen = default_packet_size;
1624
03032457
EL
1625 if (snaplen == 0) {
1626 snaplen = GetIfaceMaxPacketSize(ptv->iface);
1627 if (snaplen <= 0) {
1628 SCLogWarning(SC_ERR_INVALID_VALUE,
1629 "Unable to get MTU, setting snaplen to sane default of 1514");
1630 snaplen = 1514;
1631 }
1632 }
1633
49b7b00f
EL
1634 ptv->req.tp_frame_size = TPACKET_ALIGN(snaplen +TPACKET_ALIGN(TPACKET_ALIGN(tp_hdrlen) + sizeof(struct sockaddr_ll) + ETH_HLEN) - ETH_HLEN);
1635 ptv->req.tp_block_size = getpagesize() << order;
1636 int frames_per_block = ptv->req.tp_block_size / ptv->req.tp_frame_size;
1637 if (frames_per_block == 0) {
bae1b03c 1638 SCLogError(SC_ERR_INVALID_VALUE, "Frame size bigger than block size");
49b7b00f
EL
1639 return -1;
1640 }
8879df80 1641 ptv->req.tp_frame_nr = ptv->ring_size;
d8d9b098 1642 ptv->req.tp_block_nr = ptv->req.tp_frame_nr / frames_per_block + 1;
49b7b00f
EL
1643 /* exact division */
1644 ptv->req.tp_frame_nr = ptv->req.tp_block_nr * frames_per_block;
b3bf7a57 1645 SCLogPerf("AF_PACKET RX Ring params: block_size=%d block_nr=%d frame_size=%d frame_nr=%d",
49b7b00f
EL
1646 ptv->req.tp_block_size, ptv->req.tp_block_nr,
1647 ptv->req.tp_frame_size, ptv->req.tp_frame_nr);
1648 return 1;
1649}
1650
c2d0d938 1651#ifdef HAVE_TPACKET_V3
bae1b03c
EL
1652static int AFPComputeRingParamsV3(AFPThreadVars *ptv)
1653{
fa902abe 1654 ptv->req3.tp_block_size = ptv->block_size;
bae1b03c
EL
1655 ptv->req3.tp_frame_size = 2048;
1656 int frames_per_block = 0;
1657 int tp_hdrlen = sizeof(struct tpacket3_hdr);
1658 int snaplen = default_packet_size;
1659
1660 if (snaplen == 0) {
1661 snaplen = GetIfaceMaxPacketSize(ptv->iface);
1662 if (snaplen <= 0) {
1663 SCLogWarning(SC_ERR_INVALID_VALUE,
1664 "Unable to get MTU, setting snaplen to sane default of 1514");
1665 snaplen = 1514;
1666 }
1667 }
1668
1669 ptv->req.tp_frame_size = TPACKET_ALIGN(snaplen +TPACKET_ALIGN(TPACKET_ALIGN(tp_hdrlen) + sizeof(struct sockaddr_ll) + ETH_HLEN) - ETH_HLEN);
1670 frames_per_block = ptv->req3.tp_block_size / ptv->req3.tp_frame_size;
1671
1672 if (frames_per_block == 0) {
1673 SCLogError(SC_ERR_INVALID_VALUE,
1674 "Block size is too small, it should be at least %d",
1675 ptv->req3.tp_frame_size);
1676 return -1;
1677 }
1678 ptv->req3.tp_block_nr = ptv->ring_size / frames_per_block + 1;
1679 /* exact division */
1680 ptv->req3.tp_frame_nr = ptv->req3.tp_block_nr * frames_per_block;
234aefdf 1681 ptv->req3.tp_retire_blk_tov = ptv->block_timeout;
bae1b03c 1682 ptv->req3.tp_feature_req_word = TP_FT_REQ_FILL_RXHASH;
b3bf7a57 1683 SCLogPerf("AF_PACKET V3 RX Ring params: block_size=%d block_nr=%d frame_size=%d frame_nr=%d (mem: %d)",
bae1b03c
EL
1684 ptv->req3.tp_block_size, ptv->req3.tp_block_nr,
1685 ptv->req3.tp_frame_size, ptv->req3.tp_frame_nr,
1686 ptv->req3.tp_block_size * ptv->req3.tp_block_nr
1687 );
1688 return 1;
1689}
c2d0d938 1690#endif
bae1b03c 1691
c7bde9df
EL
1692static int AFPSetupRing(AFPThreadVars *ptv, char *devname)
1693{
1694 int val;
1695 unsigned int len = sizeof(val), i;
1696 unsigned int ring_buflen;
1697 uint8_t * ring_buf;
1698 int order;
f5c20191 1699 int r, mmap_flag;
c7bde9df 1700
c2d0d938 1701#ifdef HAVE_TPACKET_V3
c7bde9df
EL
1702 if (ptv->flags & AFP_TPACKET_V3) {
1703 val = TPACKET_V3;
f947539d 1704 } else
c2d0d938 1705#endif
f947539d 1706 {
c7bde9df
EL
1707 val = TPACKET_V2;
1708 }
1709 if (getsockopt(ptv->socket, SOL_PACKET, PACKET_HDRLEN, &val, &len) < 0) {
1710 if (errno == ENOPROTOOPT) {
1711 if (ptv->flags & AFP_TPACKET_V3) {
1712 SCLogError(SC_ERR_AFP_CREATE,
1713 "Too old kernel giving up (need 3.2 for TPACKET_V3)");
1714 } else {
1715 SCLogError(SC_ERR_AFP_CREATE,
1716 "Too old kernel giving up (need 2.6.27 at least)");
1717 }
1718 }
1719 SCLogError(SC_ERR_AFP_CREATE, "Error when retrieving packet header len");
1720 return AFP_FATAL_ERROR;
1721 }
1722
f947539d
VJ
1723 val = TPACKET_V2;
1724#ifdef HAVE_TPACKET_V3
c7bde9df
EL
1725 if (ptv->flags & AFP_TPACKET_V3) {
1726 val = TPACKET_V3;
c7bde9df 1727 }
f947539d 1728#endif
c7bde9df
EL
1729 if (setsockopt(ptv->socket, SOL_PACKET, PACKET_VERSION, &val,
1730 sizeof(val)) < 0) {
1731 SCLogError(SC_ERR_AFP_CREATE,
1732 "Can't activate TPACKET_V2/TPACKET_V3 on packet socket: %s",
1733 strerror(errno));
1734 return AFP_FATAL_ERROR;
1735 }
1736
a40f08a2
EL
1737#ifdef HAVE_HW_TIMESTAMPING
1738 int req = SOF_TIMESTAMPING_RAW_HARDWARE;
1739 if (setsockopt(ptv->socket, SOL_PACKET, PACKET_TIMESTAMP, (void *) &req,
1740 sizeof(req)) < 0) {
1741 SCLogWarning(SC_ERR_AFP_CREATE,
1742 "Can't activate hardware timestamping on packet socket: %s",
1743 strerror(errno));
1744 }
1745#endif
1746
ecf59be4
EL
1747 /* Let's reserve head room so we can add the VLAN header in IPS
1748 * or TAP mode before write the packet */
1749 if (ptv->copy_mode != AFP_COPY_MODE_NONE) {
1750 /* Only one vlan is extracted from AFP header so
1751 * one VLAN header length is enough. */
1752 int reserve = VLAN_HEADER_LEN;
1753 if (setsockopt(ptv->socket, SOL_PACKET, PACKET_RESERVE, (void *) &reserve,
1754 sizeof(reserve)) < 0) {
1755 SCLogError(SC_ERR_AFP_CREATE,
1756 "Can't activate reserve on packet socket: %s",
1757 strerror(errno));
1758 return AFP_FATAL_ERROR;
1759 }
1760 }
1761
c7bde9df 1762 /* Allocate RX ring */
c2d0d938 1763#ifdef HAVE_TPACKET_V3
c7bde9df
EL
1764 if (ptv->flags & AFP_TPACKET_V3) {
1765 if (AFPComputeRingParamsV3(ptv) != 1) {
1766 return AFP_FATAL_ERROR;
1767 }
1768 r = setsockopt(ptv->socket, SOL_PACKET, PACKET_RX_RING,
1769 (void *) &ptv->req3, sizeof(ptv->req3));
1770 if (r < 0) {
1771 SCLogError(SC_ERR_MEM_ALLOC,
1772 "Unable to allocate RX Ring for iface %s: (%d) %s",
1773 devname,
1774 errno,
1775 strerror(errno));
1776 return AFP_FATAL_ERROR;
1777 }
1778 } else {
c2d0d938 1779#endif
fa902abe 1780 for (order = AFP_BLOCK_SIZE_DEFAULT_ORDER; order >= 0; order--) {
c7bde9df
EL
1781 if (AFPComputeRingParams(ptv, order) != 1) {
1782 SCLogInfo("Ring parameter are incorrect. Please correct the devel");
1783 return AFP_FATAL_ERROR;
1784 }
1785
1786 r = setsockopt(ptv->socket, SOL_PACKET, PACKET_RX_RING,
1787 (void *) &ptv->req, sizeof(ptv->req));
1788
1789 if (r < 0) {
1790 if (errno == ENOMEM) {
1791 SCLogInfo("Memory issue with ring parameters. Retrying.");
1792 continue;
1793 }
1794 SCLogError(SC_ERR_MEM_ALLOC,
1795 "Unable to allocate RX Ring for iface %s: (%d) %s",
1796 devname,
1797 errno,
1798 strerror(errno));
1799 return AFP_FATAL_ERROR;
1800 } else {
1801 break;
1802 }
1803 }
1804 if (order < 0) {
1805 SCLogError(SC_ERR_MEM_ALLOC,
1806 "Unable to allocate RX Ring for iface %s (order 0 failed)",
1807 devname);
1808 return AFP_FATAL_ERROR;
1809 }
c2d0d938 1810#ifdef HAVE_TPACKET_V3
c7bde9df 1811 }
c2d0d938 1812#endif
c7bde9df
EL
1813
1814 /* Allocate the Ring */
c2d0d938 1815#ifdef HAVE_TPACKET_V3
c7bde9df
EL
1816 if (ptv->flags & AFP_TPACKET_V3) {
1817 ring_buflen = ptv->req3.tp_block_nr * ptv->req3.tp_block_size;
1818 } else {
c2d0d938 1819#endif
c7bde9df 1820 ring_buflen = ptv->req.tp_block_nr * ptv->req.tp_block_size;
c2d0d938 1821#ifdef HAVE_TPACKET_V3
c7bde9df 1822 }
c2d0d938 1823#endif
f5c20191
EL
1824 mmap_flag = MAP_SHARED;
1825 if (ptv->flags & AFP_MMAP_LOCKED)
1826 mmap_flag |= MAP_LOCKED;
c7bde9df 1827 ring_buf = mmap(0, ring_buflen, PROT_READ|PROT_WRITE,
f5c20191 1828 mmap_flag, ptv->socket, 0);
c7bde9df 1829 if (ring_buf == MAP_FAILED) {
88f5d7d1
EL
1830 SCLogError(SC_ERR_MEM_ALLOC, "Unable to mmap, error %s",
1831 strerror(errno));
c7bde9df
EL
1832 goto mmap_err;
1833 }
c2d0d938 1834#ifdef HAVE_TPACKET_V3
c7bde9df
EL
1835 if (ptv->flags & AFP_TPACKET_V3) {
1836 ptv->ring_v3 = SCMalloc(ptv->req3.tp_block_nr * sizeof(*ptv->ring_v3));
1837 if (!ptv->ring_v3) {
1838 SCLogError(SC_ERR_MEM_ALLOC, "Unable to malloc ptv ring_v3");
291af719 1839 goto postmmap_err;
c7bde9df
EL
1840 }
1841 for (i = 0; i < ptv->req3.tp_block_nr; ++i) {
1842 ptv->ring_v3[i].iov_base = ring_buf + (i * ptv->req3.tp_block_size);
1843 ptv->ring_v3[i].iov_len = ptv->req3.tp_block_size;
1844 }
1845 } else {
c2d0d938 1846#endif
c7bde9df
EL
1847 /* allocate a ring for each frame header pointer*/
1848 ptv->ring_v2 = SCMalloc(ptv->req.tp_frame_nr * sizeof (union thdr *));
1849 if (ptv->ring_v2 == NULL) {
1850 SCLogError(SC_ERR_MEM_ALLOC, "Unable to allocate frame buf");
291af719 1851 goto postmmap_err;
c7bde9df
EL
1852 }
1853 memset(ptv->ring_v2, 0, ptv->req.tp_frame_nr * sizeof (union thdr *));
1854 /* fill the header ring with proper frame ptr*/
1855 ptv->frame_offset = 0;
1856 for (i = 0; i < ptv->req.tp_block_nr; ++i) {
1857 void *base = &ring_buf[i * ptv->req.tp_block_size];
1858 unsigned int j;
1859 for (j = 0; j < ptv->req.tp_block_size / ptv->req.tp_frame_size; ++j, ++ptv->frame_offset) {
1860 (((union thdr **)ptv->ring_v2)[ptv->frame_offset]) = base;
1861 base += ptv->req.tp_frame_size;
1862 }
1863 }
1864 ptv->frame_offset = 0;
c2d0d938 1865#ifdef HAVE_TPACKET_V3
c7bde9df 1866 }
c2d0d938 1867#endif
c7bde9df
EL
1868
1869 return 0;
1870
291af719
EL
1871postmmap_err:
1872 munmap(ring_buf, ring_buflen);
1873 if (ptv->ring_v2)
1874 SCFree(ptv->ring_v2);
1875 if (ptv->ring_v3)
1876 SCFree(ptv->ring_v3);
c7bde9df
EL
1877mmap_err:
1878 /* Packet mmap does the cleaning when socket is closed */
1879 return AFP_FATAL_ERROR;
1880}
1881
402bdf9b
VJ
1882/** \brief test if we can use FANOUT. Older kernels like those in
1883 * CentOS6 have HAVE_PACKET_FANOUT defined but fail to work
1884 */
1885int AFPIsFanoutSupported(void)
1886{
1887#ifdef HAVE_PACKET_FANOUT
1888 int fd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
6227d095
VJ
1889 if (fd < 0)
1890 return 0;
402bdf9b 1891
6227d095
VJ
1892 uint16_t mode = PACKET_FANOUT_HASH | PACKET_FANOUT_FLAG_DEFRAG;
1893 uint16_t id = 1;
1894 uint32_t option = (mode << 16) | (id & 0xffff);
1895 int r = setsockopt(fd, SOL_PACKET, PACKET_FANOUT,(void *)&option, sizeof(option));
1896 close(fd);
1897
1898 if (r < 0) {
1899 SCLogPerf("fanout not supported by kernel: %s", strerror(errno));
1900 return 0;
402bdf9b 1901 }
6227d095
VJ
1902 return 1;
1903#else
402bdf9b 1904 return 0;
6227d095 1905#endif
402bdf9b
VJ
1906}
1907
e80b30c0 1908static int AFPCreateSocket(AFPThreadVars *ptv, char *devname, int verbose)
c45d8985
EL
1909{
1910 int r;
1992a227 1911 int ret = AFP_FATAL_ERROR;
c45d8985
EL
1912 struct packet_mreq sock_params;
1913 struct sockaddr_ll bind_address;
662dccd8 1914 int if_idx;
49b7b00f 1915
c45d8985
EL
1916 /* open socket */
1917 ptv->socket = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
1918 if (ptv->socket == -1) {
e80b30c0 1919 SCLogError(SC_ERR_AFP_CREATE, "Couldn't create a AF_PACKET socket, error %s", strerror(errno));
13f13b6d 1920 goto error;
c45d8985 1921 }
662dccd8 1922 if_idx = AFPGetIfnumByDev(ptv->socket, devname, verbose);
c45d8985
EL
1923 /* bind socket */
1924 memset(&bind_address, 0, sizeof(bind_address));
1925 bind_address.sll_family = AF_PACKET;
1926 bind_address.sll_protocol = htons(ETH_P_ALL);
662dccd8 1927 bind_address.sll_ifindex = if_idx;
c45d8985
EL
1928 if (bind_address.sll_ifindex == -1) {
1929 if (verbose)
e80b30c0 1930 SCLogError(SC_ERR_AFP_CREATE, "Couldn't find iface %s", devname);
1992a227 1931 ret = AFP_RECOVERABLE_ERROR;
13f13b6d
EL
1932 goto socket_err;
1933 }
1934
13f13b6d
EL
1935 if (ptv->promisc != 0) {
1936 /* Force promiscuous mode */
1937 memset(&sock_params, 0, sizeof(sock_params));
1938 sock_params.mr_type = PACKET_MR_PROMISC;
1939 sock_params.mr_ifindex = bind_address.sll_ifindex;
1940 r = setsockopt(ptv->socket, SOL_PACKET, PACKET_ADD_MEMBERSHIP,(void *)&sock_params, sizeof(sock_params));
1941 if (r < 0) {
1942 SCLogError(SC_ERR_AFP_CREATE,
1943 "Couldn't switch iface %s to promiscuous, error %s",
1944 devname, strerror(errno));
c7bde9df 1945 goto socket_err;
13f13b6d
EL
1946 }
1947 }
1948
1949 if (ptv->checksum_mode == CHECKSUM_VALIDATION_KERNEL) {
1950 int val = 1;
1951 if (setsockopt(ptv->socket, SOL_PACKET, PACKET_AUXDATA, &val,
1952 sizeof(val)) == -1 && errno != ENOPROTOOPT) {
1953 SCLogWarning(SC_ERR_NO_AF_PACKET,
4111331a 1954 "'kernel' checksum mode not supported, falling back to full mode.");
13f13b6d
EL
1955 ptv->checksum_mode = CHECKSUM_VALIDATION_ENABLE;
1956 }
1957 }
1958
1959 /* set socket recv buffer size */
1960 if (ptv->buffer_size != 0) {
1961 /*
1962 * Set the socket buffer size to the specified value.
1963 */
b3bf7a57 1964 SCLogPerf("Setting AF_PACKET socket buffer to %d", ptv->buffer_size);
13f13b6d
EL
1965 if (setsockopt(ptv->socket, SOL_SOCKET, SO_RCVBUF,
1966 &ptv->buffer_size,
1967 sizeof(ptv->buffer_size)) == -1) {
1968 SCLogError(SC_ERR_AFP_CREATE,
1969 "Couldn't set buffer size to %d on iface %s, error %s",
1970 ptv->buffer_size, devname, strerror(errno));
c7bde9df 1971 goto socket_err;
13f13b6d
EL
1972 }
1973 }
1974
1975 r = bind(ptv->socket, (struct sockaddr *)&bind_address, sizeof(bind_address));
1976 if (r < 0) {
1977 if (verbose) {
1978 if (errno == ENETDOWN) {
1979 SCLogError(SC_ERR_AFP_CREATE,
1980 "Couldn't bind AF_PACKET socket, iface %s is down",
1981 devname);
1982 } else {
1983 SCLogError(SC_ERR_AFP_CREATE,
1984 "Couldn't bind AF_PACKET socket to iface %s, error %s",
1985 devname, strerror(errno));
1986 }
1987 }
1992a227 1988 ret = AFP_RECOVERABLE_ERROR;
c7bde9df 1989 goto socket_err;
13f13b6d
EL
1990 }
1991
238ff231
EL
1992#ifdef HAVE_PACKET_FANOUT
1993 /* add binded socket to fanout group */
1994 if (ptv->threads > 1) {
238ff231
EL
1995 uint16_t mode = ptv->cluster_type;
1996 uint16_t id = ptv->cluster_id;
4111331a 1997 uint32_t option = (mode << 16) | (id & 0xffff);
238ff231
EL
1998 r = setsockopt(ptv->socket, SOL_PACKET, PACKET_FANOUT,(void *)&option, sizeof(option));
1999 if (r < 0) {
2000 SCLogError(SC_ERR_AFP_CREATE,
4111331a 2001 "Couldn't set fanout mode, error %s",
238ff231 2002 strerror(errno));
c7bde9df 2003 goto socket_err;
238ff231
EL
2004 }
2005 }
2006#endif
2007
13f13b6d
EL
2008 int if_flags = AFPGetDevFlags(ptv->socket, ptv->iface);
2009 if (if_flags == -1) {
2010 if (verbose) {
2011 SCLogError(SC_ERR_AFP_READ,
4111331a 2012 "Couldn't get flags for interface '%s'",
13f13b6d
EL
2013 ptv->iface);
2014 }
1992a227 2015 ret = AFP_RECOVERABLE_ERROR;
c7bde9df 2016 goto socket_err;
13f13b6d
EL
2017 }
2018 if ((if_flags & IFF_UP) == 0) {
2019 if (verbose) {
2020 SCLogError(SC_ERR_AFP_READ,
2021 "Interface '%s' is down",
2022 ptv->iface);
2023 }
1992a227 2024 ret = AFP_RECOVERABLE_ERROR;
c7bde9df 2025 goto socket_err;
c45d8985 2026 }
49b7b00f
EL
2027
2028 if (ptv->flags & AFP_RING_MODE) {
c7bde9df
EL
2029 ret = AFPSetupRing(ptv, devname);
2030 if (ret != 0)
13f13b6d 2031 goto socket_err;
49b7b00f
EL
2032 }
2033
86a3f064 2034 SCLogDebug("Using interface '%s' via socket %d", (char *)devname, ptv->socket);
c45d8985 2035
c85ee1e3
EL
2036 ptv->datalink = AFPGetDevLinktype(ptv->socket, ptv->iface);
2037 switch (ptv->datalink) {
2038 case ARPHRD_PPP:
2039 case ARPHRD_ATM:
2040 ptv->cooked = 1;
619414c5 2041 break;
c85ee1e3
EL
2042 }
2043
f2a6fb8a
EL
2044 TmEcode rc;
2045 rc = AFPSetBPFFilter(ptv);
2046 if (rc == TM_ECODE_FAILED) {
2047 SCLogError(SC_ERR_AFP_CREATE, "Set AF_PACKET bpf filter \"%s\" failed.", ptv->bpf_filter);
13f13b6d 2048 goto frame_err;
f2a6fb8a
EL
2049 }
2050
49b7b00f 2051 /* Init is ok */
13f13b6d 2052 AFPSwitchState(ptv, AFP_STATE_UP);
c45d8985 2053 return 0;
13f13b6d
EL
2054
2055frame_err:
b797fd92
EL
2056 if (ptv->flags & AFP_TPACKET_V3) {
2057 if (ptv->ring_v3)
2058 SCFree(ptv->ring_v3);
2059 } else {
2060 if (ptv->ring_v2)
2061 SCFree(ptv->ring_v2);
2062 }
13f13b6d
EL
2063socket_err:
2064 close(ptv->socket);
2065 ptv->socket = -1;
2066error:
1992a227 2067 return -ret;
c45d8985
EL
2068}
2069
f2a6fb8a
EL
2070TmEcode AFPSetBPFFilter(AFPThreadVars *ptv)
2071{
2072 struct bpf_program filter;
2073 struct sock_fprog fcode;
2074 int rc;
2075
2076 if (!ptv->bpf_filter)
2077 return TM_ECODE_OK;
2078
2079 SCMutexLock(&afpacket_bpf_set_filter_lock);
2080
2081 SCLogInfo("Using BPF '%s' on iface '%s'",
2082 ptv->bpf_filter,
2083 ptv->iface);
2084 if (pcap_compile_nopcap(default_packet_size, /* snaplen_arg */
2085 ptv->datalink, /* linktype_arg */
2086 &filter, /* program */
2087 ptv->bpf_filter, /* const char *buf */
2088 0, /* optimize */
2089 0 /* mask */
2090 ) == -1) {
2091 SCLogError(SC_ERR_AFP_CREATE, "Filter compilation failed.");
2092 SCMutexUnlock(&afpacket_bpf_set_filter_lock);
2093 return TM_ECODE_FAILED;
2094 }
2095 SCMutexUnlock(&afpacket_bpf_set_filter_lock);
2096
2097 if (filter.bf_insns == NULL) {
2098 SCLogError(SC_ERR_AFP_CREATE, "Filter badly setup.");
2099 return TM_ECODE_FAILED;
2100 }
2101
2102 fcode.len = filter.bf_len;
2103 fcode.filter = (struct sock_filter*)filter.bf_insns;
2104
2105 rc = setsockopt(ptv->socket, SOL_SOCKET, SO_ATTACH_FILTER, &fcode, sizeof(fcode));
2106
2107 if(rc == -1) {
2108 SCLogError(SC_ERR_AFP_CREATE, "Failed to attach filter: %s", strerror(errno));
2109 return TM_ECODE_FAILED;
2110 }
2111
f2a6fb8a
EL
2112 return TM_ECODE_OK;
2113}
2114
c45d8985
EL
2115
2116/**
2117 * \brief Init function for ReceiveAFP.
2118 *
2119 * \param tv pointer to ThreadVars
2120 * \param initdata pointer to the interface passed from the user
2121 * \param data pointer gets populated with AFPThreadVars
2122 *
2123 * \todo Create a general AFP setup function.
2124 */
ab1200fb 2125TmEcode ReceiveAFPThreadInit(ThreadVars *tv, const void *initdata, void **data)
8f1d7503 2126{
c45d8985 2127 SCEnter();
ab1200fb 2128 AFPIfaceConfig *afpconfig = (AFPIfaceConfig *)initdata;
c45d8985 2129
c45d8985
EL
2130 if (initdata == NULL) {
2131 SCLogError(SC_ERR_INVALID_ARGUMENT, "initdata == NULL");
2132 SCReturnInt(TM_ECODE_FAILED);
2133 }
2134
2135 AFPThreadVars *ptv = SCMalloc(sizeof(AFPThreadVars));
e176be6f 2136 if (unlikely(ptv == NULL)) {
45d5c3ca 2137 afpconfig->DerefFunc(afpconfig);
c45d8985 2138 SCReturnInt(TM_ECODE_FAILED);
45d5c3ca 2139 }
c45d8985
EL
2140 memset(ptv, 0, sizeof(AFPThreadVars));
2141
2142 ptv->tv = tv;
2143 ptv->cooked = 0;
2144
fbca1a4e 2145 strlcpy(ptv->iface, afpconfig->iface, AFP_IFACE_NAME_LENGTH);
c45d8985
EL
2146 ptv->iface[AFP_IFACE_NAME_LENGTH - 1]= '\0';
2147
51eb9605
EL
2148 ptv->livedev = LiveGetDevice(ptv->iface);
2149 if (ptv->livedev == NULL) {
2150 SCLogError(SC_ERR_INVALID_VALUE, "Unable to find Live device");
11bdf483 2151 SCFree(ptv);
51eb9605
EL
2152 SCReturnInt(TM_ECODE_FAILED);
2153 }
2154
fbca1a4e 2155 ptv->buffer_size = afpconfig->buffer_size;
8879df80 2156 ptv->ring_size = afpconfig->ring_size;
fa902abe 2157 ptv->block_size = afpconfig->block_size;
e80b30c0 2158
df7dbe36 2159 ptv->promisc = afpconfig->promisc;
6062e00c 2160 ptv->checksum_mode = afpconfig->checksum_mode;
6efd37a3 2161 ptv->bpf_filter = NULL;
df7dbe36 2162
fbca1a4e 2163 ptv->threads = 1;
e80b30c0
EL
2164#ifdef HAVE_PACKET_FANOUT
2165 ptv->cluster_type = PACKET_FANOUT_LB;
2166 ptv->cluster_id = 1;
2167 /* We only set cluster info if the number of reader threads is greater than 1 */
fbca1a4e 2168 if (afpconfig->threads > 1) {
9d882116
VJ
2169 ptv->cluster_id = afpconfig->cluster_id;
2170 ptv->cluster_type = afpconfig->cluster_type;
2171 ptv->threads = afpconfig->threads;
e80b30c0
EL
2172 }
2173#endif
49b7b00f 2174 ptv->flags = afpconfig->flags;
e80b30c0 2175
f2a6fb8a
EL
2176 if (afpconfig->bpf_filter) {
2177 ptv->bpf_filter = afpconfig->bpf_filter;
2178 }
2179
6efd37a3 2180#ifdef PACKET_STATISTICS
1ef786e7
VJ
2181 ptv->capture_kernel_packets = StatsRegisterCounter("capture.kernel_packets",
2182 ptv->tv);
2183 ptv->capture_kernel_drops = StatsRegisterCounter("capture.kernel_drops",
2184 ptv->tv);
6efd37a3
EL
2185#endif
2186
662dccd8
EL
2187 ptv->copy_mode = afpconfig->copy_mode;
2188 if (ptv->copy_mode != AFP_COPY_MODE_NONE) {
2189 strlcpy(ptv->out_iface, afpconfig->out_iface, AFP_IFACE_NAME_LENGTH);
2190 ptv->out_iface[AFP_IFACE_NAME_LENGTH - 1]= '\0';
b7e78d33
EL
2191 /* Warn about BPF filter consequence */
2192 if (ptv->bpf_filter) {
2193 SCLogWarning(SC_WARN_UNCOMMON, "Enabling a BPF filter in IPS mode result"
2194 " in dropping all non matching packets.");
2195 }
662dccd8 2196 }
c85ee1e3 2197
b7e78d33 2198
0581a23f
EL
2199 if (AFPPeersListAdd(ptv) == TM_ECODE_FAILED) {
2200 SCFree(ptv);
2201 afpconfig->DerefFunc(afpconfig);
2202 SCReturnInt(TM_ECODE_FAILED);
2203 }
2204
e80b30c0
EL
2205#define T_DATA_SIZE 70000
2206 ptv->data = SCMalloc(T_DATA_SIZE);
2207 if (ptv->data == NULL) {
45d5c3ca 2208 afpconfig->DerefFunc(afpconfig);
6019ae3d 2209 SCFree(ptv);
e80b30c0 2210 SCReturnInt(TM_ECODE_FAILED);
c45d8985 2211 }
e80b30c0
EL
2212 ptv->datalen = T_DATA_SIZE;
2213#undef T_DATA_SIZE
2214
c45d8985 2215 *data = (void *)ptv;
fbca1a4e 2216
45d5c3ca 2217 afpconfig->DerefFunc(afpconfig);
71e47868
EL
2218
2219 /* A bit strange to have this here but we only have vlan information
2220 * during reading so we need to know if we want to keep vlan during
2221 * the capture phase */
2222 int vlanbool = 0;
2223 if ((ConfGetBool("vlan.use-for-tracking", &vlanbool)) == 1 && vlanbool == 0) {
9500d12c 2224 ptv->flags |= AFP_VLAN_DISABLED;
71e47868
EL
2225 }
2226
2cd6e128
EL
2227 /* If kernel is older than 3.0, VLAN is not stripped so we don't
2228 * get the info from packet extended header but we will use a standard
2229 * parsing of packet data (See Linux commit bcc6d47903612c3861201cc3a866fb604f26b8b2) */
2230 if (! SCKernelVersionIsAtLeast(3, 0)) {
9500d12c 2231 ptv->flags |= AFP_VLAN_DISABLED;
2cd6e128
EL
2232 }
2233
c45d8985
EL
2234 SCReturnInt(TM_ECODE_OK);
2235}
2236
2237/**
2238 * \brief This function prints stats to the screen at exit.
2239 * \param tv pointer to ThreadVars
2240 * \param data pointer that gets cast into AFPThreadVars for ptv
2241 */
8f1d7503
KS
2242void ReceiveAFPThreadExitStats(ThreadVars *tv, void *data)
2243{
c45d8985
EL
2244 SCEnter();
2245 AFPThreadVars *ptv = (AFPThreadVars *)data;
9549faae
EL
2246
2247#ifdef PACKET_STATISTICS
e8a4a4c4 2248 AFPDumpCounters(ptv);
b3bf7a57 2249 SCLogPerf("(%s) Kernel: Packets %" PRIu64 ", dropped %" PRIu64 "",
6efd37a3 2250 tv->name,
752f03e7
VJ
2251 StatsGetLocalCounterValue(tv, ptv->capture_kernel_packets),
2252 StatsGetLocalCounterValue(tv, ptv->capture_kernel_drops));
9549faae 2253#endif
c45d8985
EL
2254}
2255
2256/**
2257 * \brief DeInit function closes af packet socket at exit.
2258 * \param tv pointer to ThreadVars
2259 * \param data pointer that gets cast into AFPThreadVars for ptv
2260 */
8f1d7503
KS
2261TmEcode ReceiveAFPThreadDeinit(ThreadVars *tv, void *data)
2262{
c45d8985
EL
2263 AFPThreadVars *ptv = (AFPThreadVars *)data;
2264
13f13b6d
EL
2265 AFPSwitchState(ptv, AFP_STATE_DOWN);
2266
e80b30c0
EL
2267 if (ptv->data != NULL) {
2268 SCFree(ptv->data);
2269 ptv->data = NULL;
2270 }
2271 ptv->datalen = 0;
2272
f2a6fb8a
EL
2273 ptv->bpf_filter = NULL;
2274
c45d8985
EL
2275 SCReturnInt(TM_ECODE_OK);
2276}
2277
2278/**
2279 * \brief This function passes off to link type decoders.
2280 *
2281 * DecodeAFP reads packets from the PacketQueue and passes
2282 * them off to the proper link type decoder.
2283 *
2284 * \param t pointer to ThreadVars
2285 * \param p pointer to the current packet
2286 * \param data pointer that gets cast into AFPThreadVars for ptv
2287 * \param pq pointer to the current PacketQueue
2288 */
2289TmEcode DecodeAFP(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, PacketQueue *postpq)
2290{
2291 SCEnter();
2292 DecodeThreadVars *dtv = (DecodeThreadVars *)data;
2293
f7b1aefa
VJ
2294 /* XXX HACK: flow timeout can call us for injected pseudo packets
2295 * see bug: https://redmine.openinfosecfoundation.org/issues/1107 */
2296 if (p->flags & PKT_PSEUDO_STREAM_END)
2297 return TM_ECODE_OK;
2298
c45d8985 2299 /* update counters */
14466a80 2300 DecodeUpdatePacketCounters(tv, dtv, p);
c45d8985 2301
1fb7c0dd
EL
2302 /* If suri has set vlan during reading, we increase vlan counter */
2303 if (p->vlan_idx) {
1c0b4ee0 2304 StatsIncr(tv, dtv->counter_vlan);
1fb7c0dd
EL
2305 }
2306
c45d8985 2307 /* call the decoder */
49dbb455 2308 switch (p->datalink) {
c45d8985
EL
2309 case LINKTYPE_ETHERNET:
2310 DecodeEthernet(tv, dtv, p,GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
2311 break;
49dbb455
VJ
2312 case LINKTYPE_LINUX_SLL:
2313 DecodeSll(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
2314 break;
c45d8985
EL
2315 case LINKTYPE_PPP:
2316 DecodePPP(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
2317 break;
2318 case LINKTYPE_RAW:
2319 DecodeRaw(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
2320 break;
49dbb455
VJ
2321 case LINKTYPE_NULL:
2322 DecodeNull(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
2323 break;
c45d8985
EL
2324 default:
2325 SCLogError(SC_ERR_DATALINK_UNIMPLEMENTED, "Error: datalink type %" PRId32 " not yet supported in module DecodeAFP", p->datalink);
2326 break;
2327 }
2328
3088b6ac 2329 PacketDecodeFinalize(tv, dtv, p);
e7f09f24 2330
c45d8985
EL
2331 SCReturnInt(TM_ECODE_OK);
2332}
2333
ab1200fb 2334TmEcode DecodeAFPThreadInit(ThreadVars *tv, const void *initdata, void **data)
c45d8985
EL
2335{
2336 SCEnter();
2337 DecodeThreadVars *dtv = NULL;
2338
5f307aca 2339 dtv = DecodeThreadVarsAlloc(tv);
c45d8985
EL
2340
2341 if (dtv == NULL)
2342 SCReturnInt(TM_ECODE_FAILED);
2343
2344 DecodeRegisterPerfCounters(dtv, tv);
2345
2346 *data = (void *)dtv;
2347
e7f09f24
AS
2348#ifdef __SC_CUDA_SUPPORT__
2349 if (CudaThreadVarsInit(&dtv->cuda_vars) < 0)
2350 SCReturnInt(TM_ECODE_FAILED);
2351#endif
2352
c45d8985
EL
2353 SCReturnInt(TM_ECODE_OK);
2354}
2355
2864f9ee
VJ
2356TmEcode DecodeAFPThreadDeinit(ThreadVars *tv, void *data)
2357{
2358 if (data != NULL)
98c88d51 2359 DecodeThreadVarsFree(tv, data);
2864f9ee
VJ
2360 SCReturnInt(TM_ECODE_OK);
2361}
2362
e80b30c0 2363#endif /* HAVE_AF_PACKET */
c45d8985 2364/* eof */
a6457262
EL
2365/**
2366 * @}
2367 */