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