1 /*
2 ** Copyright (C) 2014-2015 Cisco and/or its affiliates. All rights reserved.
3 ** Copyright (C) 2010-2013 Sourcefire, Inc.
4 ** Author: Michael R. Altizer <mialtize@cisco.com>
5 **
6 ** This program is free software; you can redistribute it and/or modify
7 ** it under the terms of the GNU General Public License Version 2 as
8 ** published by the Free Software Foundation.  You may not use, modify or
9 ** distribute this program under any other version of the GNU General
10 ** Public License.
11 **
12 ** This program is distributed in the hope that it will be useful,
13 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ** GNU General Public License for more details.
16 **
17 ** You should have received a copy of the GNU General Public License
18 ** along with this program; if not, write to the Free Software
19 ** Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
20 */
21 
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 
26 #include <errno.h>
27 #include <limits.h>
28 #include <linux/if_ether.h>
29 #include <linux/if_packet.h>
30 #include <net/if.h>
31 #include <net/if_arp.h>
32 #include <netinet/in.h>
33 #include <stdbool.h>
34 #include <stdint.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <string.h>
38 #include <sys/ioctl.h>
39 #include <sys/mman.h>
40 #include <sys/poll.h>
41 #include <sys/socket.h>
42 #include <unistd.h>
43 
44 #include "daq_api.h"
45 #include "sfbpf.h"
46 
47 #define DAQ_AFPACKET_VERSION 6
48 
49 #define AF_PACKET_DEFAULT_BUFFER_SIZE   128
50 #define AF_PACKET_MAX_INTERFACES    32
51 
52 union thdr
53 {
54     struct tpacket2_hdr *h2;
55     uint8_t *raw;
56 };
57 
58 typedef struct _af_packet_entry
59 {
60     struct _af_packet_entry *next;
61     union thdr hdr;
62 } AFPacketEntry;
63 
64 typedef struct _af_packet_ring
65 {
66     struct tpacket_req layout;
67     unsigned int size;
68     void *start;
69     AFPacketEntry *entries;
70     AFPacketEntry *cursor;
71 } AFPacketRing;
72 
73 typedef struct _af_packet_instance
74 {
75     struct _af_packet_instance *next;
76     int fd;
77     unsigned tp_version;
78     unsigned tp_hdrlen;
79     void *buffer;
80     AFPacketRing rx_ring;
81     AFPacketRing tx_ring;
82     char *name;
83     int index;
84     struct _af_packet_instance *peer;
85     struct sockaddr_ll sll;
86 } AFPacketInstance;
87 
88 #ifdef PACKET_FANOUT
89 typedef struct _af_packet_fanout_cfg
90 {
91     uint16_t fanout_flags;
92     uint16_t fanout_type;
93     bool enabled;
94 } AFPacketFanoutCfg;
95 #endif
96 
97 typedef struct _afpacket_context
98 {
99     char *device;
100     char *filter;
101     int snaplen;
102     int timeout;
103     uint32_t size;
104     int debug;
105     AFPacketInstance *instances;
106     uint32_t intf_count;
107     struct sfbpf_program fcode;
108     volatile int break_loop;
109     DAQ_Stats_t stats;
110     DAQ_State state;
111     char errbuf[256];
112 #ifdef PACKET_FANOUT
113     AFPacketFanoutCfg fanout_cfg;
114 #endif
115 } AFPacket_Context_t;
116 
117 /* VLAN defintions stolen from LibPCAP's vlan.h. */
118 struct vlan_tag {
119     u_int16_t   vlan_tpid;      /* ETH_P_8021Q */
120     u_int16_t   vlan_tci;       /* VLAN TCI */
121 };
122 #define VLAN_TAG_LEN    4
123 
124 static const int vlan_offset = 2 * ETH_ALEN;
125 
bind_instance_interface(AFPacket_Context_t * afpc,AFPacketInstance * instance)126 static int bind_instance_interface(AFPacket_Context_t *afpc, AFPacketInstance *instance)
127 {
128     struct sockaddr_ll sll;
129     int err;
130     socklen_t errlen = sizeof(err);
131 
132     /* Bind to the specified device so we only see packets from it. */
133     memset(&sll, 0, sizeof(struct sockaddr_ll));
134     sll.sll_family = AF_PACKET;
135     sll.sll_ifindex = instance->index;
136     sll.sll_protocol = htons(ETH_P_ALL);
137 
138     if (bind(instance->fd, (struct sockaddr *) &sll, sizeof(sll)) == -1)
139     {
140         DPE(afpc->errbuf, "%s: bind(%s): %s\n", __func__, instance->name, strerror(errno));
141         return DAQ_ERROR;
142     }
143 
144     /* Any pending errors, e.g., network is down? */
145     if (getsockopt(instance->fd, SOL_SOCKET, SO_ERROR, &err, &errlen) || err)
146     {
147         DPE(afpc->errbuf, "%s: getsockopt: %s", __func__, err ? strerror(err) : strerror(errno));
148         return DAQ_ERROR;
149     }
150 
151     return DAQ_SUCCESS;
152 }
153 
set_up_ring(AFPacket_Context_t * afpc,AFPacketInstance * instance,AFPacketRing * ring)154 static int set_up_ring(AFPacket_Context_t *afpc, AFPacketInstance *instance, AFPacketRing *ring)
155 {
156     unsigned int idx, block, block_offset, frame, frame_offset;
157 
158     /* Allocate a ring to hold packet pointers. */
159     ring->entries = calloc(ring->layout.tp_frame_nr, sizeof(AFPacketEntry));
160     if (!ring->entries)
161     {
162         DPE(afpc->errbuf, "%s: Could not allocate ring buffer entries for device %s!", __func__, instance->name);
163         return DAQ_ERROR_NOMEM;
164     }
165 
166     /* Set up the buffer entry pointers in the ring. */
167     idx = 0;
168     for (block = 0; block < ring->layout.tp_block_nr; block++)
169     {
170         block_offset = block * ring->layout.tp_block_size;
171         for (frame = 0; frame < (ring->layout.tp_block_size / ring->layout.tp_frame_size) && idx < ring->layout.tp_frame_nr; frame++)
172         {
173             frame_offset = frame * ring->layout.tp_frame_size;
174             ring->entries[idx].hdr.raw = (uint8_t *) ring->start + block_offset + frame_offset;
175             ring->entries[idx].next = &ring->entries[idx + 1];
176             idx++;
177         }
178     }
179     /* Make this a circular buffer ... a RING if you will! */
180     ring->entries[ring->layout.tp_frame_nr - 1].next = &ring->entries[0];
181     /* Initialize our entry point into the ring as the first buffer entry. */
182     ring->cursor = &ring->entries[0];
183 
184     return DAQ_SUCCESS;
185 }
186 
destroy_instance(AFPacketInstance * instance)187 static void destroy_instance(AFPacketInstance *instance)
188 {
189     unsigned int ringsize;
190     struct tpacket_req req;
191 
192     if (instance)
193     {
194         if (instance->fd != -1)
195         {
196             /* Destroy the userspace RX ring. */
197             if (instance->rx_ring.entries)
198             {
199                 free(instance->rx_ring.entries);
200                 instance->rx_ring.entries = NULL;
201             }
202             /* Destroy the userspace TX ring. */
203             if (instance->tx_ring.entries)
204             {
205                 free(instance->tx_ring.entries);
206                 instance->tx_ring.entries = NULL;
207             }
208             /* Unmap the kernel packet ring. */
209             if (instance->buffer != MAP_FAILED)
210             {
211                 ringsize = instance->rx_ring.size + instance->tx_ring.size;
212                 munmap(instance->buffer, ringsize);
213                 instance->buffer = MAP_FAILED;
214             }
215             /* Tell the kernel to destroy the rings. */
216             memset(&req, 0, sizeof(req));
217             setsockopt(instance->fd, SOL_PACKET, PACKET_RX_RING, (void *) &req, sizeof(req));
218             setsockopt(instance->fd, SOL_PACKET, PACKET_TX_RING, (void *) &req, sizeof(req));
219             close(instance->fd);
220         }
221         if (instance->name)
222         {
223             free(instance->name);
224             instance->name = NULL;
225         }
226         free(instance);
227     }
228 }
229 
230 
iface_get_arptype(AFPacketInstance * instance)231 static int iface_get_arptype(AFPacketInstance *instance)
232 {
233     struct ifreq ifr;
234 
235     memset(&ifr, 0, sizeof(ifr));
236     strncpy(ifr.ifr_name, instance->name, sizeof(ifr.ifr_name));
237 
238     if (ioctl(instance->fd, SIOCGIFHWADDR, &ifr) == -1)
239     {
240         if (errno == ENODEV)
241         {
242             return DAQ_ERROR_NODEV;
243         }
244         return DAQ_ERROR;
245     }
246 
247     return ifr.ifr_hwaddr.sa_family;
248 }
249 
create_instance(const char * device,char * errbuf,size_t errlen)250 static AFPacketInstance *create_instance(const char *device, char *errbuf, size_t errlen)
251 {
252     AFPacketInstance *instance = NULL;
253     struct ifreq ifr;
254 
255     instance = calloc(1, sizeof(AFPacketInstance));
256     if (!instance)
257     {
258         snprintf(errbuf, errlen, "%s: Could not allocate a new instance structure.", __func__);
259         goto err;
260     }
261     instance->buffer = MAP_FAILED;
262 
263     if ((instance->name = strdup(device)) == NULL)
264     {
265         snprintf(errbuf, errlen, "%s: Could not allocate a copy of the device name.", __func__);
266         goto err;;
267     }
268 
269     /* Open the PF_PACKET raw socket to receive all network traffic completely unmodified. */
270     instance->fd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
271     if (instance->fd == -1)
272     {
273         snprintf(errbuf, errlen, "%s: Could not open the PF_PACKET socket: %s", __func__, strerror(errno));
274         goto err;
275     }
276 
277     /* Find the device index of the specified interface. */
278     memset(&ifr, 0, sizeof(ifr));
279     strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));
280     if (ioctl(instance->fd, SIOCGIFINDEX, &ifr) == -1)
281     {
282         snprintf(errbuf, errlen, "%s: Could not find index for device %s", __func__, instance->name);
283         goto err;
284     }
285     instance->index = ifr.ifr_ifindex;
286 
287     /* Initialize the sockaddr for this instance's interface for later injection/forwarding use. */
288     instance->sll.sll_family = AF_PACKET;
289     instance->sll.sll_ifindex = instance->index;
290     instance->sll.sll_protocol = htons(ETH_P_ALL);
291 
292     return instance;
293 
294 err:
295     destroy_instance(instance);
296     return NULL;
297 }
298 
299 /* The function below was heavily influenced by LibPCAP's pcap-linux.c.  Thanks! */
determine_version(AFPacket_Context_t * afpc,AFPacketInstance * instance)300 static int determine_version(AFPacket_Context_t *afpc, AFPacketInstance *instance)
301 {
302     socklen_t len;
303     int val;
304 
305     /* Probe whether kernel supports TPACKET_V2 */
306     val = TPACKET_V2;
307     len = sizeof(val);
308     if (getsockopt(instance->fd, SOL_PACKET, PACKET_HDRLEN, &val, &len) < 0)
309     {
310         DPE(afpc->errbuf, "Couldn't retrieve TPACKET_V2 header length: %s", strerror(errno));
311         return -1;
312     }
313     instance->tp_hdrlen = val;
314 
315     /* Tell the kernel to use TPACKET_V2 */
316     val = TPACKET_V2;
317     if (setsockopt(instance->fd, SOL_PACKET, PACKET_VERSION, &val, sizeof(val)) < 0)
318     {
319         DPE(afpc->errbuf, "Couldn't activate TPACKET_V2 on packet socket: %s", strerror(errno));
320         return -1;
321     }
322     instance->tp_version = TPACKET_V2;
323 
324     /* Reserve space for VLAN tag reconstruction */
325     val = VLAN_TAG_LEN;
326     if (setsockopt(instance->fd, SOL_PACKET, PACKET_RESERVE, &val, sizeof(val)) < 0)
327     {
328         DPE(afpc->errbuf, "Couldn't set up a %d-byte reservation packet socket: %s", val, strerror(errno));
329         return -1;
330     }
331 
332     if (afpc->debug)
333     {
334         printf("Version: %u\n", instance->tp_version);
335         printf("Header Length: %u\n", instance->tp_hdrlen);
336     }
337 
338     return DAQ_SUCCESS;
339 }
340 
calculate_layout(AFPacket_Context_t * afpc,struct tpacket_req * layout,unsigned int tp_hdrlen,int order)341 static int calculate_layout(AFPacket_Context_t *afpc, struct tpacket_req *layout, unsigned int tp_hdrlen, int order)
342 {
343     unsigned int tp_hdrlen_sll, netoff, frames_per_block;
344 
345     /* Calculate the frame size and minimum block size required. */
346     tp_hdrlen_sll = TPACKET_ALIGN(tp_hdrlen) + sizeof(struct sockaddr_ll);
347     netoff = TPACKET_ALIGN(tp_hdrlen_sll + ETH_HLEN) + VLAN_TAG_LEN;
348     layout->tp_frame_size = TPACKET_ALIGN(netoff - ETH_HLEN + afpc->snaplen);
349     layout->tp_block_size = getpagesize() << order;
350     while (layout->tp_block_size < layout->tp_frame_size)
351         layout->tp_block_size <<= 1;
352     frames_per_block = layout->tp_block_size / layout->tp_frame_size;
353     if (frames_per_block == 0)
354     {
355         DPE(afpc->errbuf, "%s: Invalid frames per block (%u/%u) for %s",
356                 __func__, layout->tp_block_size, layout->tp_frame_size, afpc->device);
357         return DAQ_ERROR;
358     }
359 
360     /* Find the total number of frames required to amount to the requested per-interface memory.
361         Then find the number of blocks required to hold those packet buffer frames. */
362     layout->tp_frame_nr = afpc->size / layout->tp_frame_size;
363     layout->tp_block_nr = layout->tp_frame_nr / frames_per_block;
364     /* afpc->layout.tp_frame_nr is requested to match frames_per_block*n_blocks */
365     layout->tp_frame_nr = layout->tp_block_nr * frames_per_block;
366     if (afpc->debug)
367     {
368         printf("AFPacket Layout:\n");
369         printf("  Frame Size: %u\n", layout->tp_frame_size);
370         printf("  Frames:     %u\n", layout->tp_frame_nr);
371         printf("  Block Size: %u (Order %d)\n", layout->tp_block_size, order);
372         printf("  Blocks:     %u\n", layout->tp_block_nr);
373     }
374 
375     return DAQ_SUCCESS;
376 }
377 
378 #define DEFAULT_ORDER 3
create_ring(AFPacket_Context_t * afpc,AFPacketInstance * instance,AFPacketRing * ring,int optname)379 static int create_ring(AFPacket_Context_t *afpc, AFPacketInstance *instance, AFPacketRing *ring, int optname)
380 {
381     int rc, order;
382 
383     /* Starting with page allocations of order 3, try to allocate an RX ring in the kernel. */
384     for (order = DEFAULT_ORDER; order >= 0; order--)
385     {
386         if (calculate_layout(afpc, &ring->layout, instance->tp_hdrlen, order))
387             return DAQ_ERROR;
388 
389         /* Ask the kernel to create the ring. */
390         rc = setsockopt(instance->fd, SOL_PACKET, optname, (void*) &ring->layout, sizeof(struct tpacket_req));
391         if (rc)
392         {
393             if (errno == ENOMEM)
394             {
395                 if (afpc->debug)
396                     printf("%s: Allocation of kernel packet ring failed with order %d, retrying...\n", instance->name, order);
397                 continue;
398             }
399             DPE(afpc->errbuf, "%s: Couldn't create kernel ring on packet socket: %s",
400                     __func__, strerror(errno));
401             return DAQ_ERROR;
402         }
403         /* Store the total ring size for later. */
404         ring->size = ring->layout.tp_block_size * ring->layout.tp_block_nr;
405         if (afpc->debug)
406             printf("Created a ring of type %d with total size of %u\n", optname, ring->size);
407         return DAQ_SUCCESS;
408     }
409 
410     /* If we got here, it means we failed allocation on order 0. */
411     DPE(afpc->errbuf, "%s: Couldn't allocate enough memory for the kernel packet ring!", instance->name);
412     return DAQ_ERROR;
413 }
414 
mmap_rings(AFPacket_Context_t * afpc,AFPacketInstance * instance)415 static int mmap_rings(AFPacket_Context_t *afpc, AFPacketInstance *instance)
416 {
417     unsigned int ringsize;
418 
419     /* Map the ring into userspace. */
420     ringsize = instance->rx_ring.size + instance->tx_ring.size;
421     instance->buffer = mmap(0, ringsize, PROT_READ | PROT_WRITE, MAP_SHARED, instance->fd, 0);
422     if (instance->buffer == MAP_FAILED)
423     {
424         DPE(afpc->errbuf, "%s: Could not MMAP the ring: %s", __func__, strerror(errno));
425         return DAQ_ERROR;
426     }
427     instance->rx_ring.start = instance->buffer;
428     instance->tx_ring.start = (uint8_t *) instance->buffer + instance->rx_ring.size;
429 
430     return DAQ_SUCCESS;
431 }
432 
433 #ifdef PACKET_FANOUT
configure_fanout(AFPacket_Context_t * afpc,AFPacketInstance * instance)434 static int configure_fanout(AFPacket_Context_t *afpc, AFPacketInstance *instance)
435 {
436     int fanout_arg;
437 
438     fanout_arg = ((afpc->fanout_cfg.fanout_type | afpc->fanout_cfg.fanout_flags)) << 16 | instance->index;
439     if (setsockopt(instance->fd, SOL_PACKET, PACKET_FANOUT, &fanout_arg, sizeof(fanout_arg)) == -1)
440     {
441         DPE(afpc->errbuf, "%s: Could not configure packet fanout: %s", __func__, strerror(errno));
442         return DAQ_ERROR;
443     }
444 
445     return DAQ_SUCCESS;
446 }
447 #endif
448 
start_instance(AFPacket_Context_t * afpc,AFPacketInstance * instance)449 static int start_instance(AFPacket_Context_t *afpc, AFPacketInstance *instance)
450 {
451     struct packet_mreq mr;
452     int arptype;
453 
454     /* Bind the RX ring to this interface. */
455     if (bind_instance_interface(afpc, instance) != 0)
456         return -1;
457 
458     /* Turn on promiscuous mode for the device. */
459     memset(&mr, 0, sizeof(mr));
460     mr.mr_ifindex = instance->index;
461     mr.mr_type = PACKET_MR_PROMISC;
462     if (setsockopt(instance->fd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr, sizeof(mr)) == -1)
463     {
464         DPE(afpc->errbuf, "%s: setsockopt: %s", __func__, strerror(errno));
465         return -1;
466     }
467 
468     /* Get the link-layer type. */
469     arptype = iface_get_arptype(instance);
470     if (arptype < 0)
471     {
472         DPE(afpc->errbuf, "%s: failed to get interface type for device %s: (%d) %s",
473                 __func__, instance->name, errno, strerror(errno));
474         return -1;
475     }
476 
477     if (arptype != ARPHRD_ETHER)
478     {
479         DPE(afpc->errbuf, "%s: invalid interface type for device %s: %d != %d",
480                 __func__, instance->name, arptype, ARPHRD_ETHER);
481         return -1;
482     }
483 
484     /* Determine which versions of TPACKET the socket supports. */
485     if (determine_version(afpc, instance) != DAQ_SUCCESS)
486         return -1;
487 
488     /* Request the kernel RX ring from af_packet... */
489     if (create_ring(afpc, instance, &instance->rx_ring, PACKET_RX_RING) != DAQ_SUCCESS)
490         return -1;
491     /* ...request the kernel TX ring from af_packet if we're in inline mode... */
492     if (instance->peer && create_ring(afpc, instance, &instance->tx_ring, PACKET_TX_RING) != DAQ_SUCCESS)
493         return -1;
494     /* ...map the memory for the kernel ring(s) into userspace... */
495     if (mmap_rings(afpc, instance) != DAQ_SUCCESS)
496         return -1;
497     /* ...and, finally, set up a userspace ring buffer to represent the kernel RX ring... */
498     if (set_up_ring(afpc, instance, &instance->rx_ring) != DAQ_SUCCESS)
499         return -1;
500     /* ...as well as one for the TX ring if we're in inline mode... */
501     if (instance->peer && set_up_ring(afpc, instance, &instance->tx_ring) != DAQ_SUCCESS)
502         return -1;
503 #ifdef PACKET_FANOUT
504     /* ...and configure packet fanout if requested. */
505     if (afpc->fanout_cfg.enabled && configure_fanout(afpc, instance) != DAQ_SUCCESS)
506         return -1;
507 #endif
508 
509     return 0;
510 }
511 
update_hw_stats(AFPacket_Context_t * afpc)512 static void update_hw_stats(AFPacket_Context_t *afpc)
513 {
514     AFPacketInstance *instance;
515     struct tpacket_stats kstats;
516     socklen_t len = sizeof (struct tpacket_stats);
517 
518     if (afpc->state != DAQ_STATE_STARTED)
519         return;
520 
521     for (instance = afpc->instances; instance; instance = instance->next)
522     {
523         memset(&kstats, 0, len);
524         if (getsockopt(instance->fd, SOL_PACKET, PACKET_STATISTICS, &kstats, &len) > -1)
525         {
526             /* The IOCTL adds tp_drops to tp_packets in the returned structure for some mind-boggling reason... */
527             afpc->stats.hw_packets_received += kstats.tp_packets - kstats.tp_drops;
528             afpc->stats.hw_packets_dropped += kstats.tp_drops;
529         }
530         else
531             fprintf(stderr, "Failed to get stats for %s: %d %s\n", instance->name, errno, strerror(errno));
532     }
533 }
534 
af_packet_close(AFPacket_Context_t * afpc)535 static int af_packet_close(AFPacket_Context_t *afpc)
536 {
537     AFPacketInstance *instance;
538 
539     if (!afpc)
540         return -1;
541 
542     /* Cache the latest hardware stats before stopping. */
543     update_hw_stats(afpc);
544 
545     while ((instance = afpc->instances) != NULL)
546     {
547         afpc->instances = instance->next;
548         destroy_instance(instance);
549     }
550 
551     sfbpf_freecode(&afpc->fcode);
552 
553     afpc->state = DAQ_STATE_STOPPED;
554 
555     return 0;
556 }
557 
create_bridge(AFPacket_Context_t * afpc,const char * device_name1,const char * device_name2)558 static int create_bridge(AFPacket_Context_t *afpc, const char *device_name1, const char *device_name2)
559 {
560     AFPacketInstance *instance, *peer1, *peer2;
561 
562     peer1 = peer2 = NULL;
563     for (instance = afpc->instances; instance; instance = instance->next)
564     {
565         if (!strcmp(instance->name, device_name1))
566             peer1 = instance;
567         else if (!strcmp(instance->name, device_name2))
568             peer2 = instance;
569     }
570 
571     if (!peer1 || !peer2)
572         return DAQ_ERROR_NODEV;
573 
574     peer1->peer = peer2;
575     peer2->peer = peer1;
576 
577     return DAQ_SUCCESS;
578 }
579 
reset_stats(AFPacket_Context_t * afpc)580 static void reset_stats(AFPacket_Context_t *afpc)
581 {
582     AFPacketInstance *instance;
583     struct tpacket_stats kstats;
584     socklen_t len = sizeof (struct tpacket_stats);
585 
586     memset(&afpc->stats, 0, sizeof(DAQ_Stats_t));
587     /* Just call PACKET_STATISTICS to clear each instance's stats. */
588     for (instance = afpc->instances; instance; instance = instance->next)
589         getsockopt(instance->fd, SOL_PACKET, PACKET_STATISTICS, &kstats, &len);
590 }
591 
afpacket_daq_initialize(const DAQ_Config_t * config,void ** ctxt_ptr,char * errbuf,size_t errlen)592 static int afpacket_daq_initialize(const DAQ_Config_t *config, void **ctxt_ptr, char *errbuf, size_t errlen)
593 {
594     AFPacket_Context_t *afpc;
595     AFPacketInstance *instance;
596     const char *size_str = NULL;
597     char *name1, *name2, *dev;
598     char intf[IFNAMSIZ];
599     uint32_t size;
600     size_t len;
601     int num_rings, num_intfs = 0;
602     int rval = DAQ_ERROR;
603     DAQ_Dict *entry;
604 
605     afpc = calloc(1, sizeof(AFPacket_Context_t));
606     if (!afpc)
607     {
608         snprintf(errbuf, errlen, "%s: Couldn't allocate memory for the new AFPacket context!", __func__);
609         rval = DAQ_ERROR_NOMEM;
610         goto err;
611     }
612 
613     afpc->device = strdup(config->name);
614     if (!afpc->device)
615     {
616         snprintf(errbuf, errlen, "%s: Couldn't allocate memory for the device string!", __func__);
617         rval = DAQ_ERROR_NOMEM;
618         goto err;
619     }
620 
621     afpc->snaplen = config->snaplen;
622     afpc->timeout = (config->timeout > 0) ? (int) config->timeout : -1;
623 
624     dev = afpc->device;
625     if (*dev == ':' || ((len = strlen(dev)) > 0 && *(dev + len - 1) == ':') || (config->mode == DAQ_MODE_PASSIVE && strstr(dev, "::")))
626     {
627         snprintf(errbuf, errlen, "%s: Invalid interface specification: '%s'!", __func__, afpc->device);
628         goto err;
629     }
630 
631     while (*dev != '\0')
632     {
633         len = strcspn(dev, ":");
634         if (len >= IFNAMSIZ)
635         {
636             snprintf(errbuf, errlen, "%s: Interface name too long! (%zu)", __func__, len);
637             goto err;
638         }
639         if (len != 0)
640         {
641             afpc->intf_count++;
642             if (afpc->intf_count >= AF_PACKET_MAX_INTERFACES)
643             {
644                 snprintf(errbuf, errlen, "%s: Using more than %d interfaces is not supported!", __func__, AF_PACKET_MAX_INTERFACES);
645                 goto err;
646             }
647             snprintf(intf, len + 1, "%s", dev);
648             instance = create_instance(intf, errbuf, errlen);
649             if (!instance)
650                 goto err;
651 
652             instance->next = afpc->instances;
653             afpc->instances = instance;
654             num_intfs++;
655             if (config->mode != DAQ_MODE_PASSIVE)
656             {
657                 if (num_intfs == 2)
658                 {
659                     name1 = afpc->instances->next->name;
660                     name2 = afpc->instances->name;
661 
662                     if (create_bridge(afpc, name1, name2) != DAQ_SUCCESS)
663                     {
664                         snprintf(errbuf, errlen, "%s: Couldn't create the bridge between %s and %s!", __func__, name1, name2);
665                         goto err;
666                     }
667                     num_intfs = 0;
668                 }
669                 else if (num_intfs > 2)
670                     break;
671             }
672         }
673         else
674             len = 1;
675         dev += len;
676     }
677 
678     /* If there are any leftover unbridged interfaces and we're not in Passive mode, error out. */
679     if (!afpc->instances || (config->mode != DAQ_MODE_PASSIVE && num_intfs != 0))
680     {
681         snprintf(errbuf, errlen, "%s: Invalid interface specification: '%s'!", __func__, afpc->device);
682         goto err;
683     }
684 
685     /*
686      * Determine the dimensions of the kernel RX ring(s) to request.
687      */
688     /* 1. Find the total desired packet buffer memory for all instances. */
689     for (entry = config->values; entry; entry = entry->next)
690     {
691         if (!strcmp(entry->key, "buffer_size_mb"))
692             size_str = entry->value;
693         else if (!strcmp(entry->key, "debug"))
694             afpc->debug = 1;
695 #ifdef PACKET_FANOUT
696         else if (!strcmp(entry->key, "fanout_type"))
697         {
698             if (!entry->value)
699             {
700                 snprintf(errbuf, errlen, "%s: %s requires an argument!", __func__, entry->key);
701                 goto err;
702             }
703             /* Using anything other than 'hash' is probably asking for trouble, but
704                 I'll never stop you from shooting yourself in the foot. */
705             if (!strcmp(entry->value, "hash"))
706                 afpc->fanout_cfg.fanout_type = PACKET_FANOUT_HASH;
707             else if (!strcmp(entry->value, "lb"))
708                 afpc->fanout_cfg.fanout_type = PACKET_FANOUT_LB;
709             else if (!strcmp(entry->value, "cpu"))
710                 afpc->fanout_cfg.fanout_type = PACKET_FANOUT_CPU;
711             else if (!strcmp(entry->value, "rollover"))
712                 afpc->fanout_cfg.fanout_type = PACKET_FANOUT_ROLLOVER;
713             else if (!strcmp(entry->value, "rnd"))
714                 afpc->fanout_cfg.fanout_type = PACKET_FANOUT_RND;
715 #ifdef PACKET_FANOUT_QM
716             else if (!strcmp(entry->value, "qm"))
717                 afpc->fanout_cfg.fanout_type = PACKET_FANOUT_QM;
718 #endif
719             else
720             {
721                 snprintf(errbuf, errlen, "%s: Unrecognized argument for %s: '%s'!", __func__, entry->key, entry->value);
722                 goto err;
723             }
724             afpc->fanout_cfg.enabled = true;
725         }
726         else if (!strcmp(entry->key, "fanout_flag"))
727         {
728             if (!entry->value)
729             {
730                 snprintf(errbuf, errlen, "%s: %s requires an argument!", __func__, entry->key);
731                 goto err;
732             }
733             if (!strcmp(entry->value, "rollover"))
734                 afpc->fanout_cfg.fanout_flags |= PACKET_FANOUT_FLAG_ROLLOVER;
735             else if (!strcmp(entry->value, "defrag"))
736                 afpc->fanout_cfg.fanout_flags |= PACKET_FANOUT_FLAG_DEFRAG;
737             else
738             {
739                 snprintf(errbuf, errlen, "%s: Unrecognized argument for %s: '%s'!", __func__, entry->key, entry->value);
740                 goto err;
741             }
742         }
743 #endif /* PACKET_FANOUT */
744     }
745 
746     /* Fall back to the environment variable. */
747     if (!size_str)
748         size_str = getenv("AF_PACKET_BUFFER_SIZE");
749     if (size_str && strcmp("max", size_str) != 0)
750         size = strtoul(size_str, NULL, 10);
751     else
752         size = AF_PACKET_DEFAULT_BUFFER_SIZE;
753     /* The size is specified in megabytes. */
754     size = size * 1024 * 1024;
755 
756     /* 2. Divide it evenly across the number of rings.  (One per passive interface, two per inline.) */
757     num_rings = 0;
758     for (instance = afpc->instances; instance; instance = instance->next)
759         num_rings += instance->peer ? 2 : 1;
760     afpc->size = size / num_rings;
761 
762     afpc->state = DAQ_STATE_INITIALIZED;
763 
764     *ctxt_ptr = afpc;
765     return DAQ_SUCCESS;
766 
767 err:
768     if (afpc)
769     {
770         af_packet_close(afpc);
771         if (afpc->device)
772             free(afpc->device);
773         free(afpc);
774     }
775     return rval;
776 }
777 
afpacket_daq_set_filter(void * handle,const char * filter)778 static int afpacket_daq_set_filter(void *handle, const char *filter)
779 {
780     AFPacket_Context_t *afpc = (AFPacket_Context_t *) handle;
781     struct sfbpf_program fcode;
782 
783     if (afpc->filter)
784         free(afpc->filter);
785 
786     afpc->filter = strdup(filter);
787     if (!afpc->filter)
788     {
789         DPE(afpc->errbuf, "%s: Couldn't allocate memory for the filter string!", __func__);
790         return DAQ_ERROR;
791     }
792 
793     if (sfbpf_compile(afpc->snaplen, DLT_EN10MB, &fcode, afpc->filter, 1, 0) < 0)
794     {
795         DPE(afpc->errbuf, "%s: BPF state machine compilation failed!", __func__);
796         return DAQ_ERROR;
797     }
798 
799     sfbpf_freecode(&afpc->fcode);
800     afpc->fcode.bf_len = fcode.bf_len;
801     afpc->fcode.bf_insns = fcode.bf_insns;
802 
803     return DAQ_SUCCESS;
804 }
805 
afpacket_daq_start(void * handle)806 static int afpacket_daq_start(void *handle)
807 {
808     AFPacket_Context_t *afpc = (AFPacket_Context_t *) handle;
809     AFPacketInstance *instance;
810 
811     for (instance = afpc->instances; instance; instance = instance->next)
812     {
813         if (start_instance(afpc, instance) != 0)
814             return DAQ_ERROR;
815     }
816 
817     reset_stats(afpc);
818 
819     afpc->state = DAQ_STATE_STARTED;
820 
821     return DAQ_SUCCESS;
822 }
823 
824 static const DAQ_Verdict verdict_translation_table[MAX_DAQ_VERDICT] = {
825     DAQ_VERDICT_PASS,       /* DAQ_VERDICT_PASS */
826     DAQ_VERDICT_BLOCK,      /* DAQ_VERDICT_BLOCK */
827     DAQ_VERDICT_PASS,       /* DAQ_VERDICT_REPLACE */
828     DAQ_VERDICT_PASS,       /* DAQ_VERDICT_WHITELIST */
829     DAQ_VERDICT_BLOCK,      /* DAQ_VERDICT_BLACKLIST */
830     DAQ_VERDICT_PASS,       /* DAQ_VERDICT_IGNORE */
831     DAQ_VERDICT_BLOCK       /* DAQ_VERDICT_RETRY */
832 };
833 
afpacket_daq_acquire(void * handle,int cnt,DAQ_Analysis_Func_t callback,DAQ_Meta_Func_t metaback,void * user)834 static int afpacket_daq_acquire(void *handle, int cnt, DAQ_Analysis_Func_t callback, DAQ_Meta_Func_t metaback, void *user)
835 {
836     AFPacket_Context_t *afpc = (AFPacket_Context_t *) handle;
837     AFPacketInstance *instance;
838     DAQ_PktHdr_t daqhdr;
839     DAQ_Verdict verdict;
840     union thdr hdr;
841     struct pollfd pfd[AF_PACKET_MAX_INTERFACES];
842     const uint8_t *data;
843     uint32_t i;
844     int got_one, ignored_one;
845     int ret, c = 0;
846     unsigned int tp_len, tp_mac, tp_snaplen, tp_sec, tp_usec;
847 
848     while (c < cnt || cnt <= 0)
849     {
850         got_one = 0;
851         ignored_one = 0;
852         for (instance = afpc->instances; instance; instance = instance->next)
853         {
854             /* Has breakloop() been called? */
855             if (afpc->break_loop)
856             {
857                 afpc->break_loop = 0;
858                 return 0;
859             }
860 
861             hdr = instance->rx_ring.cursor->hdr;
862             if (instance->tp_version == TPACKET_V2 && (hdr.h2->tp_status & TP_STATUS_USER))
863             {
864                 switch (instance->tp_version)
865                 {
866                     case TPACKET_V2:
867                         tp_len = hdr.h2->tp_len;
868                         tp_mac = hdr.h2->tp_mac;
869                         tp_snaplen = hdr.h2->tp_snaplen;
870                         tp_sec = hdr.h2->tp_sec;
871                         tp_usec = hdr.h2->tp_nsec / 1000;
872                         break;
873 
874                     default:
875                         DPE(afpc->errbuf, "%s: Unknown TPACKET version: %u!", __func__, instance->tp_version);
876                         return DAQ_ERROR;
877                 }
878                 if (tp_mac + tp_snaplen > instance->rx_ring.layout.tp_frame_size)
879                 {
880                     DPE(afpc->errbuf, "%s: Corrupted frame on kernel ring (MAC offset %u + CapLen %u > FrameSize %d)",
881                         __func__, tp_mac, tp_snaplen, instance->rx_ring.layout.tp_frame_size);
882                     return DAQ_ERROR;
883                 }
884                 data = instance->rx_ring.cursor->hdr.raw + tp_mac;
885 
886                 /* Make a valiant attempt at reconstructing the VLAN tag if it has been stripped.  This really sucks. :( */
887                 if ((instance->tp_version == TPACKET_V2) &&
888 #if defined(TP_STATUS_VLAN_VALID)
889                     (hdr.h2->tp_vlan_tci || (hdr.h2->tp_status & TP_STATUS_VLAN_VALID)) &&
890 #else
891                     hdr.h2->tp_vlan_tci &&
892 #endif
893                     tp_snaplen >= (unsigned int) vlan_offset)
894                 {
895                     struct vlan_tag *tag;
896 
897                     data -= VLAN_TAG_LEN;
898                     memmove((void *) data, data + VLAN_TAG_LEN, vlan_offset);
899 
900                     tag = (struct vlan_tag *) (data + vlan_offset);
901 #if defined(TP_STATUS_VLAN_TPID_VALID)
902                     if (hdr.h2->tp_vlan_tpid && (hdr.h2->tp_status & TP_STATUS_VLAN_TPID_VALID))
903                         tag->vlan_tpid = htons(hdr.h2->tp_vlan_tpid);
904                     else
905 #endif
906                         tag->vlan_tpid = htons(ETH_P_8021Q);
907                     tag->vlan_tci = htons(hdr.h2->tp_vlan_tci);
908 
909                     tp_snaplen += VLAN_TAG_LEN;
910                     tp_len += VLAN_TAG_LEN;
911                 }
912 
913                 verdict = DAQ_VERDICT_PASS;
914                 if (afpc->fcode.bf_insns && sfbpf_filter(afpc->fcode.bf_insns, data, tp_len, tp_snaplen) == 0)
915                 {
916                     ignored_one = 1;
917                     afpc->stats.packets_filtered++;
918                     goto send_packet;
919                 }
920                 got_one = 1;
921 
922                 daqhdr.ts.tv_sec = tp_sec;
923                 daqhdr.ts.tv_usec = tp_usec;
924                 daqhdr.caplen = tp_snaplen;
925                 daqhdr.pktlen = tp_len;
926                 daqhdr.ingress_index = instance->index;
927                 daqhdr.egress_index = instance->peer ? instance->peer->index : DAQ_PKTHDR_UNKNOWN;
928                 daqhdr.ingress_group = DAQ_PKTHDR_UNKNOWN;
929                 daqhdr.egress_group = DAQ_PKTHDR_UNKNOWN;
930                 daqhdr.flags = 0;
931                 daqhdr.opaque = 0;
932                 daqhdr.priv_ptr = NULL;
933                 daqhdr.address_space_id = 0;
934 
935                 if (callback)
936                 {
937                     verdict = callback(user, &daqhdr, data);
938                     if (verdict >= MAX_DAQ_VERDICT)
939                         verdict = DAQ_VERDICT_PASS;
940                     afpc->stats.verdicts[verdict]++;
941                     verdict = verdict_translation_table[verdict];
942                 }
943                 afpc->stats.packets_received++;
944                 c++;
945 send_packet:
946                 if (verdict == DAQ_VERDICT_PASS && instance->peer)
947                 {
948                     AFPacketEntry *entry = instance->peer->tx_ring.cursor;
949                     int rc;
950 
951                     if (entry->hdr.h2->tp_status == TP_STATUS_AVAILABLE)
952                     {
953                         memcpy(entry->hdr.raw + TPACKET_ALIGN(instance->peer->tp_hdrlen), data, tp_snaplen);
954                         entry->hdr.h2->tp_len = tp_snaplen;
955                         entry->hdr.h2->tp_status = TP_STATUS_SEND_REQUEST;
956                         rc = send(instance->peer->fd, NULL, 0, 0);
957                         instance->peer->tx_ring.cursor = entry->next;
958                     }
959                     /* Else, don't forward the packet... */
960                 }
961                 /* Release the TPACKET buffer back to the kernel. */
962                 switch (instance->tp_version)
963                 {
964                     case TPACKET_V2:
965                         hdr.h2->tp_status = TP_STATUS_KERNEL;
966                         break;
967                 }
968                 instance->rx_ring.cursor = instance->rx_ring.cursor->next;
969             }
970         }
971         if (!got_one && !ignored_one)
972         {
973             for (i = 0, instance = afpc->instances; instance; i++, instance = instance->next)
974             {
975                 pfd[i].fd = instance->fd;
976                 pfd[i].revents = 0;
977                 pfd[i].events = POLLIN;
978             }
979             ret = poll(pfd, afpc->intf_count, afpc->timeout);
980             /* If we were interrupted by a signal, start the loop over.  The user should call daq_breakloop to actually exit. */
981             if (ret < 0 && errno != EINTR)
982             {
983                 DPE(afpc->errbuf, "%s: Poll failed: %s (%d)", __func__, strerror(errno), errno);
984                 return DAQ_ERROR;
985             }
986             /* If the poll times out, return control to the caller. */
987             if (ret == 0)
988                 break;
989             /* If some number of of sockets have events returned, check them all for badness. */
990             if (ret > 0)
991             {
992                 for (i = 0; i < afpc->intf_count; i++)
993                 {
994                     if (pfd[i].revents & (POLLHUP | POLLRDHUP | POLLERR | POLLNVAL))
995                     {
996                         if (pfd[i].revents & (POLLHUP | POLLRDHUP))
997                             DPE(afpc->errbuf, "%s: Hang-up on a packet socket", __func__);
998                         else if (pfd[i].revents & POLLERR)
999                             DPE(afpc->errbuf, "%s: Encountered error condition on a packet socket", __func__);
1000                         else if (pfd[i].revents & POLLNVAL)
1001                             DPE(afpc->errbuf, "%s: Invalid polling request on a packet socket", __func__);
1002                         return DAQ_ERROR;
1003                     }
1004                 }
1005             }
1006         }
1007     }
1008     return 0;
1009 }
1010 
afpacket_daq_inject(void * handle,const DAQ_PktHdr_t * hdr,const uint8_t * packet_data,uint32_t len,int reverse)1011 static int afpacket_daq_inject(void *handle, const DAQ_PktHdr_t *hdr, const uint8_t *packet_data, uint32_t len, int reverse)
1012 {
1013     AFPacket_Context_t *afpc = (AFPacket_Context_t *) handle;
1014     AFPacketInstance *instance;
1015     AFPacketEntry *entry;
1016 
1017     /* Find the instance that the packet was received on. */
1018     for (instance = afpc->instances; instance; instance = instance->next)
1019     {
1020         if (instance->index == hdr->ingress_index)
1021             break;
1022     }
1023 
1024     if (!instance || (!reverse && !(instance = instance->peer)))
1025         return DAQ_ERROR;
1026 
1027     if (instance->tx_ring.entries)
1028     {
1029         entry = instance->tx_ring.cursor;
1030         if (entry->hdr.h2->tp_status == TP_STATUS_AVAILABLE)
1031         {
1032             memcpy(entry->hdr.raw + TPACKET_ALIGN(instance->tp_hdrlen), packet_data, len);
1033             entry->hdr.h2->tp_len = len;
1034             entry->hdr.h2->tp_status = TP_STATUS_SEND_REQUEST;
1035             instance->tx_ring.cursor = entry->next;
1036             if (send(instance->fd, NULL, 0, 0) < 0)
1037             {
1038                 DPE(afpc->errbuf, "%s: Error sending packet: %s (%d)", __func__, strerror(errno), errno);
1039                 return DAQ_ERROR;
1040             }
1041             afpc->stats.packets_injected++;
1042         }
1043     }
1044     else
1045     {
1046         const struct ethhdr *eth;
1047         struct sockaddr_ll *sll;
1048 
1049         eth = (const struct ethhdr *)packet_data;
1050         sll = &instance->sll;
1051         sll->sll_protocol = eth->h_proto;
1052 
1053         if (sendto(instance->fd, packet_data, len, 0, (struct sockaddr *) sll, sizeof(*sll)) < 0)
1054         {
1055             DPE(afpc->errbuf, "%s: Error sending packet: %s (%d)", __func__, strerror(errno), errno);
1056             return DAQ_ERROR;
1057         }
1058         afpc->stats.packets_injected++;
1059     }
1060 
1061     return DAQ_SUCCESS;
1062 }
1063 
afpacket_daq_breakloop(void * handle)1064 static int afpacket_daq_breakloop(void *handle)
1065 {
1066     AFPacket_Context_t *afpc = (AFPacket_Context_t *) handle;
1067 
1068     afpc->break_loop = 1;
1069 
1070     return DAQ_SUCCESS;
1071 }
1072 
afpacket_daq_stop(void * handle)1073 static int afpacket_daq_stop(void *handle)
1074 {
1075     AFPacket_Context_t *afpc = (AFPacket_Context_t *) handle;
1076 
1077     af_packet_close(afpc);
1078 
1079     return DAQ_SUCCESS;
1080 }
1081 
afpacket_daq_shutdown(void * handle)1082 static void afpacket_daq_shutdown(void *handle)
1083 {
1084     AFPacket_Context_t *afpc = (AFPacket_Context_t *) handle;
1085 
1086     af_packet_close(afpc);
1087     if (afpc->device)
1088         free(afpc->device);
1089     if (afpc->filter)
1090         free(afpc->filter);
1091     free(afpc);
1092 }
1093 
afpacket_daq_check_status(void * handle)1094 static DAQ_State afpacket_daq_check_status(void *handle)
1095 {
1096     AFPacket_Context_t *afpc = (AFPacket_Context_t *) handle;
1097 
1098     return afpc->state;
1099 }
1100 
afpacket_daq_get_stats(void * handle,DAQ_Stats_t * stats)1101 static int afpacket_daq_get_stats(void *handle, DAQ_Stats_t *stats)
1102 {
1103     AFPacket_Context_t *afpc = (AFPacket_Context_t *) handle;
1104 
1105     update_hw_stats(afpc);
1106     memcpy(stats, &afpc->stats, sizeof(DAQ_Stats_t));
1107 
1108     return DAQ_SUCCESS;
1109 }
1110 
afpacket_daq_reset_stats(void * handle)1111 static void afpacket_daq_reset_stats(void *handle)
1112 {
1113     AFPacket_Context_t *afpc = (AFPacket_Context_t *) handle;
1114 
1115     reset_stats(afpc);
1116 }
1117 
afpacket_daq_get_snaplen(void * handle)1118 static int afpacket_daq_get_snaplen(void *handle)
1119 {
1120     AFPacket_Context_t *afpc = (AFPacket_Context_t *) handle;
1121 
1122     return afpc->snaplen;
1123 }
1124 
afpacket_daq_get_capabilities(void * handle)1125 static uint32_t afpacket_daq_get_capabilities(void *handle)
1126 {
1127     return DAQ_CAPA_BLOCK | DAQ_CAPA_REPLACE | DAQ_CAPA_INJECT | DAQ_CAPA_UNPRIV_START | DAQ_CAPA_BREAKLOOP | DAQ_CAPA_BPF | DAQ_CAPA_DEVICE_INDEX;
1128 }
1129 
afpacket_daq_get_datalink_type(void * handle)1130 static int afpacket_daq_get_datalink_type(void *handle)
1131 {
1132     return DLT_EN10MB;
1133 }
1134 
afpacket_daq_get_errbuf(void * handle)1135 static const char *afpacket_daq_get_errbuf(void *handle)
1136 {
1137     AFPacket_Context_t *afpc = (AFPacket_Context_t *) handle;
1138 
1139     return afpc->errbuf;
1140 }
1141 
afpacket_daq_set_errbuf(void * handle,const char * string)1142 static void afpacket_daq_set_errbuf(void *handle, const char *string)
1143 {
1144     AFPacket_Context_t *afpc = (AFPacket_Context_t *) handle;
1145 
1146     if (!string)
1147         return;
1148 
1149     DPE(afpc->errbuf, "%s", string);
1150 }
1151 
afpacket_daq_get_device_index(void * handle,const char * device)1152 static int afpacket_daq_get_device_index(void *handle, const char *device)
1153 {
1154     AFPacket_Context_t *afpc = (AFPacket_Context_t *) handle;
1155     AFPacketInstance *instance;
1156 
1157     for (instance = afpc->instances; instance; instance = instance->next)
1158     {
1159         if (!strcmp(device, instance->name))
1160             return instance->index;
1161     }
1162 
1163     return DAQ_ERROR_NODEV;
1164 }
1165 
1166 #ifdef BUILDING_SO
1167 DAQ_SO_PUBLIC const DAQ_Module_t DAQ_MODULE_DATA =
1168 #else
1169 const DAQ_Module_t afpacket_daq_module_data =
1170 #endif
1171 {
1172     .api_version = DAQ_API_VERSION,
1173     .module_version = DAQ_AFPACKET_VERSION,
1174     .name = "afpacket",
1175     .type = DAQ_TYPE_INTF_CAPABLE | DAQ_TYPE_INLINE_CAPABLE | DAQ_TYPE_MULTI_INSTANCE,
1176     .initialize = afpacket_daq_initialize,
1177     .set_filter = afpacket_daq_set_filter,
1178     .start = afpacket_daq_start,
1179     .acquire = afpacket_daq_acquire,
1180     .inject = afpacket_daq_inject,
1181     .breakloop = afpacket_daq_breakloop,
1182     .stop = afpacket_daq_stop,
1183     .shutdown = afpacket_daq_shutdown,
1184     .check_status = afpacket_daq_check_status,
1185     .get_stats = afpacket_daq_get_stats,
1186     .reset_stats = afpacket_daq_reset_stats,
1187     .get_snaplen = afpacket_daq_get_snaplen,
1188     .get_capabilities = afpacket_daq_get_capabilities,
1189     .get_datalink_type = afpacket_daq_get_datalink_type,
1190     .get_errbuf = afpacket_daq_get_errbuf,
1191     .set_errbuf = afpacket_daq_set_errbuf,
1192     .get_device_index = afpacket_daq_get_device_index,
1193     .modify_flow = NULL,
1194     .hup_prep = NULL,
1195     .hup_apply = NULL,
1196     .hup_post = NULL,
1197 };
1198