docs: updated roadmap document.
[dabba.git] / libdabba / packet_rx.c
blob8c6b6aa472a9ac8ca84394f28025626f64b81a28
1 /**
2 * \file packet_rx.c
3 * \author written by Emmanuel Roullit emmanuel.roullit@gmail.com (c) 2011
4 * \date 2011
5 */
7 /* __LICENSE_HEADER_BEGIN__ */
9 /*
10 * Copyright (C) 2011 Emmanuel Roullit <emmanuel.roullit@gmail.com>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or (at
15 * your option) any later version.
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
20 * for more details.
22 * You should have received a copy of the GNU General Public License along
23 * with this program; if not, write to the Free Software Foundation, Inc.,
24 * 51 Franklin St, Fifth Floor, Boston, MA 02110, USA
28 /* __LICENSE_HEADER_END__ */
30 #define _GNU_SOURCE
32 #include <assert.h>
33 #include <string.h>
34 #include <unistd.h>
35 #include <sys/uio.h>
36 #include <poll.h>
38 #include <libdabba/packet_rx.h>
39 #include <libdabba/pcap.h>
40 #include <libdabba/macros.h>
42 /**
43 * \brief Receive packets coming from a packet mmap RX ring
44 * \param[in] arg Pointer to packet rx thread structure
45 * \return Always return NULL
47 * This function will \c poll(2) until some packets are received on the configured
48 * interface. For now this function does not much but it can be starting point
49 * for PCAP function to dump the frames into a file or for a packet dissectors.
52 void *packet_rx(void *arg)
54 struct packet_rx_thread *thread = arg;
55 struct packet_mmap *pkt_rx = &thread->pkt_rx;
56 struct pollfd pfd;
57 size_t index = 0;
59 if (!arg)
60 goto out;
62 pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
64 memset(&pfd, 0, sizeof(pfd));
66 pfd.events = POLLIN | POLLRDNORM | POLLERR;
67 pfd.fd = pkt_rx->pf_sock;
69 for (;;) {
70 for (index = 0; index < pkt_rx->layout.tp_frame_nr; index++) {
71 struct packet_mmap_header *mmap_hdr =
72 pkt_rx->vec[index].iov_base;
74 if ((mmap_hdr->tp_h.tp_status & TP_STATUS_KERNEL) ==
75 TP_STATUS_KERNEL) {
76 if (poll(&pfd, 1, -1) < 0)
77 continue;
80 if ((mmap_hdr->tp_h.tp_status & TP_STATUS_USER) ==
81 TP_STATUS_USER) {
82 if (thread->pcap_fd > 0) {
83 pcap_write(thread->pcap_fd,
84 (uint8_t *) mmap_hdr +
85 mmap_hdr->tp_h.tp_mac,
86 mmap_hdr->tp_h.tp_len,
87 min(mmap_hdr->tp_h.tp_snaplen, pkt_rx->layout.tp_frame_size),
88 mmap_hdr->tp_h.tp_sec,
89 mmap_hdr->tp_h.tp_usec);
92 mmap_hdr->tp_h.tp_status = TP_STATUS_KERNEL;
97 out:
98 pthread_exit(NULL);