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