1*8b26181fSAndroid Build Coastguard Worker /*
2*8b26181fSAndroid Build Coastguard Worker * pcap-dag.c: Packet capture interface for Endace DAG cards.
3*8b26181fSAndroid Build Coastguard Worker *
4*8b26181fSAndroid Build Coastguard Worker * Authors: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com)
5*8b26181fSAndroid Build Coastguard Worker * Modifications: Jesper Peterson
6*8b26181fSAndroid Build Coastguard Worker * Koryn Grant
7*8b26181fSAndroid Build Coastguard Worker * Stephen Donnelly <[email protected]>
8*8b26181fSAndroid Build Coastguard Worker */
9*8b26181fSAndroid Build Coastguard Worker
10*8b26181fSAndroid Build Coastguard Worker #ifdef HAVE_CONFIG_H
11*8b26181fSAndroid Build Coastguard Worker #include <config.h>
12*8b26181fSAndroid Build Coastguard Worker #endif
13*8b26181fSAndroid Build Coastguard Worker
14*8b26181fSAndroid Build Coastguard Worker #include <sys/param.h> /* optionally get BSD define */
15*8b26181fSAndroid Build Coastguard Worker
16*8b26181fSAndroid Build Coastguard Worker #include <stdlib.h>
17*8b26181fSAndroid Build Coastguard Worker #include <string.h>
18*8b26181fSAndroid Build Coastguard Worker #include <errno.h>
19*8b26181fSAndroid Build Coastguard Worker
20*8b26181fSAndroid Build Coastguard Worker #include "pcap-int.h"
21*8b26181fSAndroid Build Coastguard Worker
22*8b26181fSAndroid Build Coastguard Worker #include <netinet/in.h>
23*8b26181fSAndroid Build Coastguard Worker #include <sys/mman.h>
24*8b26181fSAndroid Build Coastguard Worker #include <sys/socket.h>
25*8b26181fSAndroid Build Coastguard Worker #include <sys/types.h>
26*8b26181fSAndroid Build Coastguard Worker #include <unistd.h>
27*8b26181fSAndroid Build Coastguard Worker
28*8b26181fSAndroid Build Coastguard Worker struct mbuf; /* Squelch compiler warnings on some platforms for */
29*8b26181fSAndroid Build Coastguard Worker struct rtentry; /* declarations in <net/if.h> */
30*8b26181fSAndroid Build Coastguard Worker #include <net/if.h>
31*8b26181fSAndroid Build Coastguard Worker
32*8b26181fSAndroid Build Coastguard Worker #include "dagnew.h"
33*8b26181fSAndroid Build Coastguard Worker #include "dagapi.h"
34*8b26181fSAndroid Build Coastguard Worker #include "dagpci.h"
35*8b26181fSAndroid Build Coastguard Worker #include "dag_config_api.h"
36*8b26181fSAndroid Build Coastguard Worker
37*8b26181fSAndroid Build Coastguard Worker #include "pcap-dag.h"
38*8b26181fSAndroid Build Coastguard Worker
39*8b26181fSAndroid Build Coastguard Worker /*
40*8b26181fSAndroid Build Coastguard Worker * DAG devices have names beginning with "dag", followed by a number
41*8b26181fSAndroid Build Coastguard Worker * from 0 to DAG_MAX_BOARDS, then optionally a colon and a stream number
42*8b26181fSAndroid Build Coastguard Worker * from 0 to DAG_STREAM_MAX.
43*8b26181fSAndroid Build Coastguard Worker */
44*8b26181fSAndroid Build Coastguard Worker #ifndef DAG_MAX_BOARDS
45*8b26181fSAndroid Build Coastguard Worker #define DAG_MAX_BOARDS 32
46*8b26181fSAndroid Build Coastguard Worker #endif
47*8b26181fSAndroid Build Coastguard Worker
48*8b26181fSAndroid Build Coastguard Worker
49*8b26181fSAndroid Build Coastguard Worker #ifndef ERF_TYPE_AAL5
50*8b26181fSAndroid Build Coastguard Worker #define ERF_TYPE_AAL5 4
51*8b26181fSAndroid Build Coastguard Worker #endif
52*8b26181fSAndroid Build Coastguard Worker
53*8b26181fSAndroid Build Coastguard Worker #ifndef ERF_TYPE_MC_HDLC
54*8b26181fSAndroid Build Coastguard Worker #define ERF_TYPE_MC_HDLC 5
55*8b26181fSAndroid Build Coastguard Worker #endif
56*8b26181fSAndroid Build Coastguard Worker
57*8b26181fSAndroid Build Coastguard Worker #ifndef ERF_TYPE_MC_RAW
58*8b26181fSAndroid Build Coastguard Worker #define ERF_TYPE_MC_RAW 6
59*8b26181fSAndroid Build Coastguard Worker #endif
60*8b26181fSAndroid Build Coastguard Worker
61*8b26181fSAndroid Build Coastguard Worker #ifndef ERF_TYPE_MC_ATM
62*8b26181fSAndroid Build Coastguard Worker #define ERF_TYPE_MC_ATM 7
63*8b26181fSAndroid Build Coastguard Worker #endif
64*8b26181fSAndroid Build Coastguard Worker
65*8b26181fSAndroid Build Coastguard Worker #ifndef ERF_TYPE_MC_RAW_CHANNEL
66*8b26181fSAndroid Build Coastguard Worker #define ERF_TYPE_MC_RAW_CHANNEL 8
67*8b26181fSAndroid Build Coastguard Worker #endif
68*8b26181fSAndroid Build Coastguard Worker
69*8b26181fSAndroid Build Coastguard Worker #ifndef ERF_TYPE_MC_AAL5
70*8b26181fSAndroid Build Coastguard Worker #define ERF_TYPE_MC_AAL5 9
71*8b26181fSAndroid Build Coastguard Worker #endif
72*8b26181fSAndroid Build Coastguard Worker
73*8b26181fSAndroid Build Coastguard Worker #ifndef ERF_TYPE_COLOR_HDLC_POS
74*8b26181fSAndroid Build Coastguard Worker #define ERF_TYPE_COLOR_HDLC_POS 10
75*8b26181fSAndroid Build Coastguard Worker #endif
76*8b26181fSAndroid Build Coastguard Worker
77*8b26181fSAndroid Build Coastguard Worker #ifndef ERF_TYPE_COLOR_ETH
78*8b26181fSAndroid Build Coastguard Worker #define ERF_TYPE_COLOR_ETH 11
79*8b26181fSAndroid Build Coastguard Worker #endif
80*8b26181fSAndroid Build Coastguard Worker
81*8b26181fSAndroid Build Coastguard Worker #ifndef ERF_TYPE_MC_AAL2
82*8b26181fSAndroid Build Coastguard Worker #define ERF_TYPE_MC_AAL2 12
83*8b26181fSAndroid Build Coastguard Worker #endif
84*8b26181fSAndroid Build Coastguard Worker
85*8b26181fSAndroid Build Coastguard Worker #ifndef ERF_TYPE_IP_COUNTER
86*8b26181fSAndroid Build Coastguard Worker #define ERF_TYPE_IP_COUNTER 13
87*8b26181fSAndroid Build Coastguard Worker #endif
88*8b26181fSAndroid Build Coastguard Worker
89*8b26181fSAndroid Build Coastguard Worker #ifndef ERF_TYPE_TCP_FLOW_COUNTER
90*8b26181fSAndroid Build Coastguard Worker #define ERF_TYPE_TCP_FLOW_COUNTER 14
91*8b26181fSAndroid Build Coastguard Worker #endif
92*8b26181fSAndroid Build Coastguard Worker
93*8b26181fSAndroid Build Coastguard Worker #ifndef ERF_TYPE_DSM_COLOR_HDLC_POS
94*8b26181fSAndroid Build Coastguard Worker #define ERF_TYPE_DSM_COLOR_HDLC_POS 15
95*8b26181fSAndroid Build Coastguard Worker #endif
96*8b26181fSAndroid Build Coastguard Worker
97*8b26181fSAndroid Build Coastguard Worker #ifndef ERF_TYPE_DSM_COLOR_ETH
98*8b26181fSAndroid Build Coastguard Worker #define ERF_TYPE_DSM_COLOR_ETH 16
99*8b26181fSAndroid Build Coastguard Worker #endif
100*8b26181fSAndroid Build Coastguard Worker
101*8b26181fSAndroid Build Coastguard Worker #ifndef ERF_TYPE_COLOR_MC_HDLC_POS
102*8b26181fSAndroid Build Coastguard Worker #define ERF_TYPE_COLOR_MC_HDLC_POS 17
103*8b26181fSAndroid Build Coastguard Worker #endif
104*8b26181fSAndroid Build Coastguard Worker
105*8b26181fSAndroid Build Coastguard Worker #ifndef ERF_TYPE_AAL2
106*8b26181fSAndroid Build Coastguard Worker #define ERF_TYPE_AAL2 18
107*8b26181fSAndroid Build Coastguard Worker #endif
108*8b26181fSAndroid Build Coastguard Worker
109*8b26181fSAndroid Build Coastguard Worker #ifndef ERF_TYPE_COLOR_HASH_POS
110*8b26181fSAndroid Build Coastguard Worker #define ERF_TYPE_COLOR_HASH_POS 19
111*8b26181fSAndroid Build Coastguard Worker #endif
112*8b26181fSAndroid Build Coastguard Worker
113*8b26181fSAndroid Build Coastguard Worker #ifndef ERF_TYPE_COLOR_HASH_ETH
114*8b26181fSAndroid Build Coastguard Worker #define ERF_TYPE_COLOR_HASH_ETH 20
115*8b26181fSAndroid Build Coastguard Worker #endif
116*8b26181fSAndroid Build Coastguard Worker
117*8b26181fSAndroid Build Coastguard Worker #ifndef ERF_TYPE_INFINIBAND
118*8b26181fSAndroid Build Coastguard Worker #define ERF_TYPE_INFINIBAND 21
119*8b26181fSAndroid Build Coastguard Worker #endif
120*8b26181fSAndroid Build Coastguard Worker
121*8b26181fSAndroid Build Coastguard Worker #ifndef ERF_TYPE_IPV4
122*8b26181fSAndroid Build Coastguard Worker #define ERF_TYPE_IPV4 22
123*8b26181fSAndroid Build Coastguard Worker #endif
124*8b26181fSAndroid Build Coastguard Worker
125*8b26181fSAndroid Build Coastguard Worker #ifndef ERF_TYPE_IPV6
126*8b26181fSAndroid Build Coastguard Worker #define ERF_TYPE_IPV6 23
127*8b26181fSAndroid Build Coastguard Worker #endif
128*8b26181fSAndroid Build Coastguard Worker
129*8b26181fSAndroid Build Coastguard Worker #ifndef ERF_TYPE_RAW_LINK
130*8b26181fSAndroid Build Coastguard Worker #define ERF_TYPE_RAW_LINK 24
131*8b26181fSAndroid Build Coastguard Worker #endif
132*8b26181fSAndroid Build Coastguard Worker
133*8b26181fSAndroid Build Coastguard Worker #ifndef ERF_TYPE_INFINIBAND_LINK
134*8b26181fSAndroid Build Coastguard Worker #define ERF_TYPE_INFINIBAND_LINK 25
135*8b26181fSAndroid Build Coastguard Worker #endif
136*8b26181fSAndroid Build Coastguard Worker
137*8b26181fSAndroid Build Coastguard Worker #ifndef ERF_TYPE_META
138*8b26181fSAndroid Build Coastguard Worker #define ERF_TYPE_META 27
139*8b26181fSAndroid Build Coastguard Worker #endif
140*8b26181fSAndroid Build Coastguard Worker
141*8b26181fSAndroid Build Coastguard Worker #ifndef ERF_TYPE_PAD
142*8b26181fSAndroid Build Coastguard Worker #define ERF_TYPE_PAD 48
143*8b26181fSAndroid Build Coastguard Worker #endif
144*8b26181fSAndroid Build Coastguard Worker
145*8b26181fSAndroid Build Coastguard Worker #define ATM_CELL_SIZE 52
146*8b26181fSAndroid Build Coastguard Worker #define ATM_HDR_SIZE 4
147*8b26181fSAndroid Build Coastguard Worker
148*8b26181fSAndroid Build Coastguard Worker /*
149*8b26181fSAndroid Build Coastguard Worker * A header containing additional MTP information.
150*8b26181fSAndroid Build Coastguard Worker */
151*8b26181fSAndroid Build Coastguard Worker #define MTP2_SENT_OFFSET 0 /* 1 byte */
152*8b26181fSAndroid Build Coastguard Worker #define MTP2_ANNEX_A_USED_OFFSET 1 /* 1 byte */
153*8b26181fSAndroid Build Coastguard Worker #define MTP2_LINK_NUMBER_OFFSET 2 /* 2 bytes */
154*8b26181fSAndroid Build Coastguard Worker #define MTP2_HDR_LEN 4 /* length of the header */
155*8b26181fSAndroid Build Coastguard Worker
156*8b26181fSAndroid Build Coastguard Worker #define MTP2_ANNEX_A_NOT_USED 0
157*8b26181fSAndroid Build Coastguard Worker #define MTP2_ANNEX_A_USED 1
158*8b26181fSAndroid Build Coastguard Worker #define MTP2_ANNEX_A_USED_UNKNOWN 2
159*8b26181fSAndroid Build Coastguard Worker
160*8b26181fSAndroid Build Coastguard Worker /* SunATM pseudo header */
161*8b26181fSAndroid Build Coastguard Worker struct sunatm_hdr {
162*8b26181fSAndroid Build Coastguard Worker unsigned char flags; /* destination and traffic type */
163*8b26181fSAndroid Build Coastguard Worker unsigned char vpi; /* VPI */
164*8b26181fSAndroid Build Coastguard Worker unsigned short vci; /* VCI */
165*8b26181fSAndroid Build Coastguard Worker };
166*8b26181fSAndroid Build Coastguard Worker
167*8b26181fSAndroid Build Coastguard Worker /*
168*8b26181fSAndroid Build Coastguard Worker * Private data for capturing on DAG devices.
169*8b26181fSAndroid Build Coastguard Worker */
170*8b26181fSAndroid Build Coastguard Worker struct pcap_dag {
171*8b26181fSAndroid Build Coastguard Worker struct pcap_stat stat;
172*8b26181fSAndroid Build Coastguard Worker u_char *dag_mem_bottom; /* DAG card current memory bottom pointer */
173*8b26181fSAndroid Build Coastguard Worker u_char *dag_mem_top; /* DAG card current memory top pointer */
174*8b26181fSAndroid Build Coastguard Worker int dag_fcs_bits; /* Number of checksum bits from link layer */
175*8b26181fSAndroid Build Coastguard Worker int dag_flags; /* Flags */
176*8b26181fSAndroid Build Coastguard Worker int dag_stream; /* DAG stream number */
177*8b26181fSAndroid Build Coastguard Worker int dag_timeout; /* timeout specified to pcap_open_live.
178*8b26181fSAndroid Build Coastguard Worker * Same as in linux above, introduce
179*8b26181fSAndroid Build Coastguard Worker * generally? */
180*8b26181fSAndroid Build Coastguard Worker dag_card_ref_t dag_ref; /* DAG Configuration/Status API card reference */
181*8b26181fSAndroid Build Coastguard Worker dag_component_t dag_root; /* DAG CSAPI Root component */
182*8b26181fSAndroid Build Coastguard Worker attr_uuid_t drop_attr; /* DAG Stream Drop Attribute handle, if available */
183*8b26181fSAndroid Build Coastguard Worker struct timeval required_select_timeout;
184*8b26181fSAndroid Build Coastguard Worker /* Timeout caller must use in event loops */
185*8b26181fSAndroid Build Coastguard Worker };
186*8b26181fSAndroid Build Coastguard Worker
187*8b26181fSAndroid Build Coastguard Worker typedef struct pcap_dag_node {
188*8b26181fSAndroid Build Coastguard Worker struct pcap_dag_node *next;
189*8b26181fSAndroid Build Coastguard Worker pcap_t *p;
190*8b26181fSAndroid Build Coastguard Worker pid_t pid;
191*8b26181fSAndroid Build Coastguard Worker } pcap_dag_node_t;
192*8b26181fSAndroid Build Coastguard Worker
193*8b26181fSAndroid Build Coastguard Worker static pcap_dag_node_t *pcap_dags = NULL;
194*8b26181fSAndroid Build Coastguard Worker static int atexit_handler_installed = 0;
195*8b26181fSAndroid Build Coastguard Worker static const unsigned short endian_test_word = 0x0100;
196*8b26181fSAndroid Build Coastguard Worker
197*8b26181fSAndroid Build Coastguard Worker #define IS_BIGENDIAN() (*((unsigned char *)&endian_test_word))
198*8b26181fSAndroid Build Coastguard Worker
199*8b26181fSAndroid Build Coastguard Worker #define MAX_DAG_PACKET 65536
200*8b26181fSAndroid Build Coastguard Worker
201*8b26181fSAndroid Build Coastguard Worker static unsigned char TempPkt[MAX_DAG_PACKET];
202*8b26181fSAndroid Build Coastguard Worker
203*8b26181fSAndroid Build Coastguard Worker #ifndef HAVE_DAG_LARGE_STREAMS_API
204*8b26181fSAndroid Build Coastguard Worker #define dag_attach_stream64(a, b, c, d) dag_attach_stream(a, b, c, d)
205*8b26181fSAndroid Build Coastguard Worker #define dag_get_stream_poll64(a, b, c, d, e) dag_get_stream_poll(a, b, c, d, e)
206*8b26181fSAndroid Build Coastguard Worker #define dag_set_stream_poll64(a, b, c, d, e) dag_set_stream_poll(a, b, c, d, e)
207*8b26181fSAndroid Build Coastguard Worker #define dag_size_t uint32_t
208*8b26181fSAndroid Build Coastguard Worker #endif
209*8b26181fSAndroid Build Coastguard Worker
210*8b26181fSAndroid Build Coastguard Worker static int dag_stats(pcap_t *p, struct pcap_stat *ps);
211*8b26181fSAndroid Build Coastguard Worker static int dag_set_datalink(pcap_t *p, int dlt);
212*8b26181fSAndroid Build Coastguard Worker static int dag_get_datalink(pcap_t *p);
213*8b26181fSAndroid Build Coastguard Worker static int dag_setnonblock(pcap_t *p, int nonblock);
214*8b26181fSAndroid Build Coastguard Worker
215*8b26181fSAndroid Build Coastguard Worker static void
delete_pcap_dag(const pcap_t * p)216*8b26181fSAndroid Build Coastguard Worker delete_pcap_dag(const pcap_t *p)
217*8b26181fSAndroid Build Coastguard Worker {
218*8b26181fSAndroid Build Coastguard Worker pcap_dag_node_t *curr = NULL, *prev = NULL;
219*8b26181fSAndroid Build Coastguard Worker
220*8b26181fSAndroid Build Coastguard Worker for (prev = NULL, curr = pcap_dags; curr != NULL && curr->p != p; prev = curr, curr = curr->next) {
221*8b26181fSAndroid Build Coastguard Worker /* empty */
222*8b26181fSAndroid Build Coastguard Worker }
223*8b26181fSAndroid Build Coastguard Worker
224*8b26181fSAndroid Build Coastguard Worker if (curr != NULL && curr->p == p) {
225*8b26181fSAndroid Build Coastguard Worker if (prev != NULL) {
226*8b26181fSAndroid Build Coastguard Worker prev->next = curr->next;
227*8b26181fSAndroid Build Coastguard Worker } else {
228*8b26181fSAndroid Build Coastguard Worker pcap_dags = curr->next;
229*8b26181fSAndroid Build Coastguard Worker }
230*8b26181fSAndroid Build Coastguard Worker }
231*8b26181fSAndroid Build Coastguard Worker }
232*8b26181fSAndroid Build Coastguard Worker
233*8b26181fSAndroid Build Coastguard Worker /*
234*8b26181fSAndroid Build Coastguard Worker * Performs a graceful shutdown of the DAG card, frees dynamic memory held
235*8b26181fSAndroid Build Coastguard Worker * in the pcap_t structure, and closes the file descriptor for the DAG card.
236*8b26181fSAndroid Build Coastguard Worker */
237*8b26181fSAndroid Build Coastguard Worker
238*8b26181fSAndroid Build Coastguard Worker static void
dag_platform_cleanup(pcap_t * p)239*8b26181fSAndroid Build Coastguard Worker dag_platform_cleanup(pcap_t *p)
240*8b26181fSAndroid Build Coastguard Worker {
241*8b26181fSAndroid Build Coastguard Worker struct pcap_dag *pd = p->priv;
242*8b26181fSAndroid Build Coastguard Worker
243*8b26181fSAndroid Build Coastguard Worker if(dag_stop_stream(p->fd, pd->dag_stream) < 0)
244*8b26181fSAndroid Build Coastguard Worker fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
245*8b26181fSAndroid Build Coastguard Worker
246*8b26181fSAndroid Build Coastguard Worker if(dag_detach_stream(p->fd, pd->dag_stream) < 0)
247*8b26181fSAndroid Build Coastguard Worker fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
248*8b26181fSAndroid Build Coastguard Worker
249*8b26181fSAndroid Build Coastguard Worker if(pd->dag_ref != NULL) {
250*8b26181fSAndroid Build Coastguard Worker dag_config_dispose(pd->dag_ref);
251*8b26181fSAndroid Build Coastguard Worker /*
252*8b26181fSAndroid Build Coastguard Worker * Note: we don't need to call close(p->fd) or
253*8b26181fSAndroid Build Coastguard Worker * dag_close(p->fd), as dag_config_dispose(pd->dag_ref)
254*8b26181fSAndroid Build Coastguard Worker * does this.
255*8b26181fSAndroid Build Coastguard Worker *
256*8b26181fSAndroid Build Coastguard Worker * Set p->fd to -1 to make sure that's not done.
257*8b26181fSAndroid Build Coastguard Worker */
258*8b26181fSAndroid Build Coastguard Worker p->fd = -1;
259*8b26181fSAndroid Build Coastguard Worker pd->dag_ref = NULL;
260*8b26181fSAndroid Build Coastguard Worker }
261*8b26181fSAndroid Build Coastguard Worker delete_pcap_dag(p);
262*8b26181fSAndroid Build Coastguard Worker pcap_cleanup_live_common(p);
263*8b26181fSAndroid Build Coastguard Worker }
264*8b26181fSAndroid Build Coastguard Worker
265*8b26181fSAndroid Build Coastguard Worker static void
atexit_handler(void)266*8b26181fSAndroid Build Coastguard Worker atexit_handler(void)
267*8b26181fSAndroid Build Coastguard Worker {
268*8b26181fSAndroid Build Coastguard Worker while (pcap_dags != NULL) {
269*8b26181fSAndroid Build Coastguard Worker if (pcap_dags->pid == getpid()) {
270*8b26181fSAndroid Build Coastguard Worker if (pcap_dags->p != NULL)
271*8b26181fSAndroid Build Coastguard Worker dag_platform_cleanup(pcap_dags->p);
272*8b26181fSAndroid Build Coastguard Worker } else {
273*8b26181fSAndroid Build Coastguard Worker delete_pcap_dag(pcap_dags->p);
274*8b26181fSAndroid Build Coastguard Worker }
275*8b26181fSAndroid Build Coastguard Worker }
276*8b26181fSAndroid Build Coastguard Worker }
277*8b26181fSAndroid Build Coastguard Worker
278*8b26181fSAndroid Build Coastguard Worker static int
new_pcap_dag(pcap_t * p)279*8b26181fSAndroid Build Coastguard Worker new_pcap_dag(pcap_t *p)
280*8b26181fSAndroid Build Coastguard Worker {
281*8b26181fSAndroid Build Coastguard Worker pcap_dag_node_t *node = NULL;
282*8b26181fSAndroid Build Coastguard Worker
283*8b26181fSAndroid Build Coastguard Worker if ((node = malloc(sizeof(pcap_dag_node_t))) == NULL) {
284*8b26181fSAndroid Build Coastguard Worker return -1;
285*8b26181fSAndroid Build Coastguard Worker }
286*8b26181fSAndroid Build Coastguard Worker
287*8b26181fSAndroid Build Coastguard Worker if (!atexit_handler_installed) {
288*8b26181fSAndroid Build Coastguard Worker atexit(atexit_handler);
289*8b26181fSAndroid Build Coastguard Worker atexit_handler_installed = 1;
290*8b26181fSAndroid Build Coastguard Worker }
291*8b26181fSAndroid Build Coastguard Worker
292*8b26181fSAndroid Build Coastguard Worker node->next = pcap_dags;
293*8b26181fSAndroid Build Coastguard Worker node->p = p;
294*8b26181fSAndroid Build Coastguard Worker node->pid = getpid();
295*8b26181fSAndroid Build Coastguard Worker
296*8b26181fSAndroid Build Coastguard Worker pcap_dags = node;
297*8b26181fSAndroid Build Coastguard Worker
298*8b26181fSAndroid Build Coastguard Worker return 0;
299*8b26181fSAndroid Build Coastguard Worker }
300*8b26181fSAndroid Build Coastguard Worker
301*8b26181fSAndroid Build Coastguard Worker static unsigned int
dag_erf_ext_header_count(const uint8_t * erf,size_t len)302*8b26181fSAndroid Build Coastguard Worker dag_erf_ext_header_count(const uint8_t *erf, size_t len)
303*8b26181fSAndroid Build Coastguard Worker {
304*8b26181fSAndroid Build Coastguard Worker uint32_t hdr_num = 0;
305*8b26181fSAndroid Build Coastguard Worker uint8_t hdr_type;
306*8b26181fSAndroid Build Coastguard Worker
307*8b26181fSAndroid Build Coastguard Worker /* basic sanity checks */
308*8b26181fSAndroid Build Coastguard Worker if ( erf == NULL )
309*8b26181fSAndroid Build Coastguard Worker return 0;
310*8b26181fSAndroid Build Coastguard Worker if ( len < 16 )
311*8b26181fSAndroid Build Coastguard Worker return 0;
312*8b26181fSAndroid Build Coastguard Worker
313*8b26181fSAndroid Build Coastguard Worker /* check if we have any extension headers */
314*8b26181fSAndroid Build Coastguard Worker if ( (erf[8] & 0x80) == 0x00 )
315*8b26181fSAndroid Build Coastguard Worker return 0;
316*8b26181fSAndroid Build Coastguard Worker
317*8b26181fSAndroid Build Coastguard Worker /* loop over the extension headers */
318*8b26181fSAndroid Build Coastguard Worker do {
319*8b26181fSAndroid Build Coastguard Worker
320*8b26181fSAndroid Build Coastguard Worker /* sanity check we have enough bytes */
321*8b26181fSAndroid Build Coastguard Worker if ( len < (24 + (hdr_num * 8)) )
322*8b26181fSAndroid Build Coastguard Worker return hdr_num;
323*8b26181fSAndroid Build Coastguard Worker
324*8b26181fSAndroid Build Coastguard Worker /* get the header type */
325*8b26181fSAndroid Build Coastguard Worker hdr_type = erf[(16 + (hdr_num * 8))];
326*8b26181fSAndroid Build Coastguard Worker hdr_num++;
327*8b26181fSAndroid Build Coastguard Worker
328*8b26181fSAndroid Build Coastguard Worker } while ( hdr_type & 0x80 );
329*8b26181fSAndroid Build Coastguard Worker
330*8b26181fSAndroid Build Coastguard Worker return hdr_num;
331*8b26181fSAndroid Build Coastguard Worker }
332*8b26181fSAndroid Build Coastguard Worker
333*8b26181fSAndroid Build Coastguard Worker /*
334*8b26181fSAndroid Build Coastguard Worker * Read at most max_packets from the capture stream and call the callback
335*8b26181fSAndroid Build Coastguard Worker * for each of them. Returns the number of packets handled, -1 if an
336*8b26181fSAndroid Build Coastguard Worker * error occurred, or -2 if we were told to break out of the loop.
337*8b26181fSAndroid Build Coastguard Worker */
338*8b26181fSAndroid Build Coastguard Worker static int
dag_read(pcap_t * p,int cnt,pcap_handler callback,u_char * user)339*8b26181fSAndroid Build Coastguard Worker dag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
340*8b26181fSAndroid Build Coastguard Worker {
341*8b26181fSAndroid Build Coastguard Worker struct pcap_dag *pd = p->priv;
342*8b26181fSAndroid Build Coastguard Worker unsigned int processed = 0;
343*8b26181fSAndroid Build Coastguard Worker unsigned int nonblocking = pd->dag_flags & DAGF_NONBLOCK;
344*8b26181fSAndroid Build Coastguard Worker unsigned int num_ext_hdr = 0;
345*8b26181fSAndroid Build Coastguard Worker unsigned int ticks_per_second;
346*8b26181fSAndroid Build Coastguard Worker
347*8b26181fSAndroid Build Coastguard Worker /* Get the next bufferful of packets (if necessary). */
348*8b26181fSAndroid Build Coastguard Worker while (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size) {
349*8b26181fSAndroid Build Coastguard Worker
350*8b26181fSAndroid Build Coastguard Worker /*
351*8b26181fSAndroid Build Coastguard Worker * Has "pcap_breakloop()" been called?
352*8b26181fSAndroid Build Coastguard Worker */
353*8b26181fSAndroid Build Coastguard Worker if (p->break_loop) {
354*8b26181fSAndroid Build Coastguard Worker /*
355*8b26181fSAndroid Build Coastguard Worker * Yes - clear the flag that indicates that
356*8b26181fSAndroid Build Coastguard Worker * it has, and return -2 to indicate that
357*8b26181fSAndroid Build Coastguard Worker * we were told to break out of the loop.
358*8b26181fSAndroid Build Coastguard Worker */
359*8b26181fSAndroid Build Coastguard Worker p->break_loop = 0;
360*8b26181fSAndroid Build Coastguard Worker return -2;
361*8b26181fSAndroid Build Coastguard Worker }
362*8b26181fSAndroid Build Coastguard Worker
363*8b26181fSAndroid Build Coastguard Worker /* dag_advance_stream() will block (unless nonblock is called)
364*8b26181fSAndroid Build Coastguard Worker * until 64kB of data has accumulated.
365*8b26181fSAndroid Build Coastguard Worker * If to_ms is set, it will timeout before 64kB has accumulated.
366*8b26181fSAndroid Build Coastguard Worker * We wait for 64kB because processing a few packets at a time
367*8b26181fSAndroid Build Coastguard Worker * can cause problems at high packet rates (>200kpps) due
368*8b26181fSAndroid Build Coastguard Worker * to inefficiencies.
369*8b26181fSAndroid Build Coastguard Worker * This does mean if to_ms is not specified the capture may 'hang'
370*8b26181fSAndroid Build Coastguard Worker * for long periods if the data rate is extremely slow (<64kB/sec)
371*8b26181fSAndroid Build Coastguard Worker * If non-block is specified it will return immediately. The user
372*8b26181fSAndroid Build Coastguard Worker * is then responsible for efficiency.
373*8b26181fSAndroid Build Coastguard Worker */
374*8b26181fSAndroid Build Coastguard Worker if ( NULL == (pd->dag_mem_top = dag_advance_stream(p->fd, pd->dag_stream, &(pd->dag_mem_bottom))) ) {
375*8b26181fSAndroid Build Coastguard Worker return -1;
376*8b26181fSAndroid Build Coastguard Worker }
377*8b26181fSAndroid Build Coastguard Worker
378*8b26181fSAndroid Build Coastguard Worker if (nonblocking && (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size))
379*8b26181fSAndroid Build Coastguard Worker {
380*8b26181fSAndroid Build Coastguard Worker /* Pcap is configured to process only available packets, and there aren't any, return immediately. */
381*8b26181fSAndroid Build Coastguard Worker return 0;
382*8b26181fSAndroid Build Coastguard Worker }
383*8b26181fSAndroid Build Coastguard Worker
384*8b26181fSAndroid Build Coastguard Worker if(!nonblocking &&
385*8b26181fSAndroid Build Coastguard Worker pd->dag_timeout &&
386*8b26181fSAndroid Build Coastguard Worker (pd->dag_mem_top - pd->dag_mem_bottom < dag_record_size))
387*8b26181fSAndroid Build Coastguard Worker {
388*8b26181fSAndroid Build Coastguard Worker /* Blocking mode, but timeout set and no data has arrived, return anyway.*/
389*8b26181fSAndroid Build Coastguard Worker return 0;
390*8b26181fSAndroid Build Coastguard Worker }
391*8b26181fSAndroid Build Coastguard Worker
392*8b26181fSAndroid Build Coastguard Worker }
393*8b26181fSAndroid Build Coastguard Worker
394*8b26181fSAndroid Build Coastguard Worker /*
395*8b26181fSAndroid Build Coastguard Worker * Process the packets.
396*8b26181fSAndroid Build Coastguard Worker *
397*8b26181fSAndroid Build Coastguard Worker * This assumes that a single buffer of packets will have
398*8b26181fSAndroid Build Coastguard Worker * <= INT_MAX packets, so the packet count doesn't overflow.
399*8b26181fSAndroid Build Coastguard Worker */
400*8b26181fSAndroid Build Coastguard Worker while (pd->dag_mem_top - pd->dag_mem_bottom >= dag_record_size) {
401*8b26181fSAndroid Build Coastguard Worker
402*8b26181fSAndroid Build Coastguard Worker unsigned short packet_len = 0;
403*8b26181fSAndroid Build Coastguard Worker int caplen = 0;
404*8b26181fSAndroid Build Coastguard Worker struct pcap_pkthdr pcap_header;
405*8b26181fSAndroid Build Coastguard Worker
406*8b26181fSAndroid Build Coastguard Worker dag_record_t *header = (dag_record_t *)(pd->dag_mem_bottom);
407*8b26181fSAndroid Build Coastguard Worker
408*8b26181fSAndroid Build Coastguard Worker u_char *dp = ((u_char *)header); /* + dag_record_size; */
409*8b26181fSAndroid Build Coastguard Worker unsigned short rlen;
410*8b26181fSAndroid Build Coastguard Worker
411*8b26181fSAndroid Build Coastguard Worker /*
412*8b26181fSAndroid Build Coastguard Worker * Has "pcap_breakloop()" been called?
413*8b26181fSAndroid Build Coastguard Worker */
414*8b26181fSAndroid Build Coastguard Worker if (p->break_loop) {
415*8b26181fSAndroid Build Coastguard Worker /*
416*8b26181fSAndroid Build Coastguard Worker * Yes - clear the flag that indicates that
417*8b26181fSAndroid Build Coastguard Worker * it has, and return -2 to indicate that
418*8b26181fSAndroid Build Coastguard Worker * we were told to break out of the loop.
419*8b26181fSAndroid Build Coastguard Worker */
420*8b26181fSAndroid Build Coastguard Worker p->break_loop = 0;
421*8b26181fSAndroid Build Coastguard Worker return -2;
422*8b26181fSAndroid Build Coastguard Worker }
423*8b26181fSAndroid Build Coastguard Worker
424*8b26181fSAndroid Build Coastguard Worker rlen = ntohs(header->rlen);
425*8b26181fSAndroid Build Coastguard Worker if (rlen < dag_record_size)
426*8b26181fSAndroid Build Coastguard Worker {
427*8b26181fSAndroid Build Coastguard Worker pcap_strlcpy(p->errbuf, "dag_read: record too small",
428*8b26181fSAndroid Build Coastguard Worker PCAP_ERRBUF_SIZE);
429*8b26181fSAndroid Build Coastguard Worker return -1;
430*8b26181fSAndroid Build Coastguard Worker }
431*8b26181fSAndroid Build Coastguard Worker pd->dag_mem_bottom += rlen;
432*8b26181fSAndroid Build Coastguard Worker
433*8b26181fSAndroid Build Coastguard Worker /* Count lost packets. */
434*8b26181fSAndroid Build Coastguard Worker switch((header->type & 0x7f)) {
435*8b26181fSAndroid Build Coastguard Worker /* in these types the color value overwrites the lctr */
436*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_COLOR_HDLC_POS:
437*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_COLOR_ETH:
438*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_DSM_COLOR_HDLC_POS:
439*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_DSM_COLOR_ETH:
440*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_COLOR_MC_HDLC_POS:
441*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_COLOR_HASH_ETH:
442*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_COLOR_HASH_POS:
443*8b26181fSAndroid Build Coastguard Worker break;
444*8b26181fSAndroid Build Coastguard Worker
445*8b26181fSAndroid Build Coastguard Worker default:
446*8b26181fSAndroid Build Coastguard Worker if ( (pd->drop_attr == kNullAttributeUuid) && (header->lctr) ) {
447*8b26181fSAndroid Build Coastguard Worker pd->stat.ps_drop += ntohs(header->lctr);
448*8b26181fSAndroid Build Coastguard Worker }
449*8b26181fSAndroid Build Coastguard Worker }
450*8b26181fSAndroid Build Coastguard Worker
451*8b26181fSAndroid Build Coastguard Worker if ((header->type & 0x7f) == ERF_TYPE_PAD) {
452*8b26181fSAndroid Build Coastguard Worker continue;
453*8b26181fSAndroid Build Coastguard Worker }
454*8b26181fSAndroid Build Coastguard Worker
455*8b26181fSAndroid Build Coastguard Worker num_ext_hdr = dag_erf_ext_header_count(dp, rlen);
456*8b26181fSAndroid Build Coastguard Worker
457*8b26181fSAndroid Build Coastguard Worker /* ERF encapsulation */
458*8b26181fSAndroid Build Coastguard Worker /* The Extensible Record Format is not dropped for this kind of encapsulation,
459*8b26181fSAndroid Build Coastguard Worker * and will be handled as a pseudo header by the decoding application.
460*8b26181fSAndroid Build Coastguard Worker * The information carried in the ERF header and in the optional subheader (if present)
461*8b26181fSAndroid Build Coastguard Worker * could be merged with the libpcap information, to offer a better decoding.
462*8b26181fSAndroid Build Coastguard Worker * The packet length is
463*8b26181fSAndroid Build Coastguard Worker * o the length of the packet on the link (header->wlen),
464*8b26181fSAndroid Build Coastguard Worker * o plus the length of the ERF header (dag_record_size), as the length of the
465*8b26181fSAndroid Build Coastguard Worker * pseudo header will be adjusted during the decoding,
466*8b26181fSAndroid Build Coastguard Worker * o plus the length of the optional subheader (if present).
467*8b26181fSAndroid Build Coastguard Worker *
468*8b26181fSAndroid Build Coastguard Worker * The capture length is header.rlen and the byte stuffing for alignment will be dropped
469*8b26181fSAndroid Build Coastguard Worker * if the capture length is greater than the packet length.
470*8b26181fSAndroid Build Coastguard Worker */
471*8b26181fSAndroid Build Coastguard Worker if (p->linktype == DLT_ERF) {
472*8b26181fSAndroid Build Coastguard Worker packet_len = ntohs(header->wlen) + dag_record_size;
473*8b26181fSAndroid Build Coastguard Worker caplen = rlen;
474*8b26181fSAndroid Build Coastguard Worker switch ((header->type & 0x7f)) {
475*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_MC_AAL5:
476*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_MC_ATM:
477*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_MC_HDLC:
478*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_MC_RAW_CHANNEL:
479*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_MC_RAW:
480*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_MC_AAL2:
481*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_COLOR_MC_HDLC_POS:
482*8b26181fSAndroid Build Coastguard Worker packet_len += 4; /* MC header */
483*8b26181fSAndroid Build Coastguard Worker break;
484*8b26181fSAndroid Build Coastguard Worker
485*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_COLOR_HASH_ETH:
486*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_DSM_COLOR_ETH:
487*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_COLOR_ETH:
488*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_ETH:
489*8b26181fSAndroid Build Coastguard Worker packet_len += 2; /* ETH header */
490*8b26181fSAndroid Build Coastguard Worker break;
491*8b26181fSAndroid Build Coastguard Worker } /* switch type */
492*8b26181fSAndroid Build Coastguard Worker
493*8b26181fSAndroid Build Coastguard Worker /* Include ERF extension headers */
494*8b26181fSAndroid Build Coastguard Worker packet_len += (8 * num_ext_hdr);
495*8b26181fSAndroid Build Coastguard Worker
496*8b26181fSAndroid Build Coastguard Worker if (caplen > packet_len) {
497*8b26181fSAndroid Build Coastguard Worker caplen = packet_len;
498*8b26181fSAndroid Build Coastguard Worker }
499*8b26181fSAndroid Build Coastguard Worker } else {
500*8b26181fSAndroid Build Coastguard Worker /* Other kind of encapsulation according to the header Type */
501*8b26181fSAndroid Build Coastguard Worker
502*8b26181fSAndroid Build Coastguard Worker /* Skip over generic ERF header */
503*8b26181fSAndroid Build Coastguard Worker dp += dag_record_size;
504*8b26181fSAndroid Build Coastguard Worker /* Skip over extension headers */
505*8b26181fSAndroid Build Coastguard Worker dp += 8 * num_ext_hdr;
506*8b26181fSAndroid Build Coastguard Worker
507*8b26181fSAndroid Build Coastguard Worker switch((header->type & 0x7f)) {
508*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_ATM:
509*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_AAL5:
510*8b26181fSAndroid Build Coastguard Worker if ((header->type & 0x7f) == ERF_TYPE_AAL5) {
511*8b26181fSAndroid Build Coastguard Worker packet_len = ntohs(header->wlen);
512*8b26181fSAndroid Build Coastguard Worker caplen = rlen - dag_record_size;
513*8b26181fSAndroid Build Coastguard Worker }
514*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_MC_ATM:
515*8b26181fSAndroid Build Coastguard Worker if ((header->type & 0x7f) == ERF_TYPE_MC_ATM) {
516*8b26181fSAndroid Build Coastguard Worker caplen = packet_len = ATM_CELL_SIZE;
517*8b26181fSAndroid Build Coastguard Worker dp+=4;
518*8b26181fSAndroid Build Coastguard Worker }
519*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_MC_AAL5:
520*8b26181fSAndroid Build Coastguard Worker if ((header->type & 0x7f) == ERF_TYPE_MC_AAL5) {
521*8b26181fSAndroid Build Coastguard Worker packet_len = ntohs(header->wlen);
522*8b26181fSAndroid Build Coastguard Worker caplen = rlen - dag_record_size - 4;
523*8b26181fSAndroid Build Coastguard Worker dp+=4;
524*8b26181fSAndroid Build Coastguard Worker }
525*8b26181fSAndroid Build Coastguard Worker /* Skip over extension headers */
526*8b26181fSAndroid Build Coastguard Worker caplen -= (8 * num_ext_hdr);
527*8b26181fSAndroid Build Coastguard Worker
528*8b26181fSAndroid Build Coastguard Worker if ((header->type & 0x7f) == ERF_TYPE_ATM) {
529*8b26181fSAndroid Build Coastguard Worker caplen = packet_len = ATM_CELL_SIZE;
530*8b26181fSAndroid Build Coastguard Worker }
531*8b26181fSAndroid Build Coastguard Worker if (p->linktype == DLT_SUNATM) {
532*8b26181fSAndroid Build Coastguard Worker struct sunatm_hdr *sunatm = (struct sunatm_hdr *)dp;
533*8b26181fSAndroid Build Coastguard Worker unsigned long rawatm;
534*8b26181fSAndroid Build Coastguard Worker
535*8b26181fSAndroid Build Coastguard Worker rawatm = ntohl(*((unsigned long *)dp));
536*8b26181fSAndroid Build Coastguard Worker sunatm->vci = htons((rawatm >> 4) & 0xffff);
537*8b26181fSAndroid Build Coastguard Worker sunatm->vpi = (rawatm >> 20) & 0x00ff;
538*8b26181fSAndroid Build Coastguard Worker sunatm->flags = ((header->flags.iface & 1) ? 0x80 : 0x00) |
539*8b26181fSAndroid Build Coastguard Worker ((sunatm->vpi == 0 && sunatm->vci == htons(5)) ? 6 :
540*8b26181fSAndroid Build Coastguard Worker ((sunatm->vpi == 0 && sunatm->vci == htons(16)) ? 5 :
541*8b26181fSAndroid Build Coastguard Worker ((dp[ATM_HDR_SIZE] == 0xaa &&
542*8b26181fSAndroid Build Coastguard Worker dp[ATM_HDR_SIZE+1] == 0xaa &&
543*8b26181fSAndroid Build Coastguard Worker dp[ATM_HDR_SIZE+2] == 0x03) ? 2 : 1)));
544*8b26181fSAndroid Build Coastguard Worker
545*8b26181fSAndroid Build Coastguard Worker } else if (p->linktype == DLT_ATM_RFC1483) {
546*8b26181fSAndroid Build Coastguard Worker packet_len -= ATM_HDR_SIZE;
547*8b26181fSAndroid Build Coastguard Worker caplen -= ATM_HDR_SIZE;
548*8b26181fSAndroid Build Coastguard Worker dp += ATM_HDR_SIZE;
549*8b26181fSAndroid Build Coastguard Worker } else
550*8b26181fSAndroid Build Coastguard Worker continue;
551*8b26181fSAndroid Build Coastguard Worker break;
552*8b26181fSAndroid Build Coastguard Worker
553*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_COLOR_HASH_ETH:
554*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_DSM_COLOR_ETH:
555*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_COLOR_ETH:
556*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_ETH:
557*8b26181fSAndroid Build Coastguard Worker if ((p->linktype != DLT_EN10MB) &&
558*8b26181fSAndroid Build Coastguard Worker (p->linktype != DLT_DOCSIS))
559*8b26181fSAndroid Build Coastguard Worker continue;
560*8b26181fSAndroid Build Coastguard Worker packet_len = ntohs(header->wlen);
561*8b26181fSAndroid Build Coastguard Worker packet_len -= (pd->dag_fcs_bits >> 3);
562*8b26181fSAndroid Build Coastguard Worker caplen = rlen - dag_record_size - 2;
563*8b26181fSAndroid Build Coastguard Worker /* Skip over extension headers */
564*8b26181fSAndroid Build Coastguard Worker caplen -= (8 * num_ext_hdr);
565*8b26181fSAndroid Build Coastguard Worker if (caplen > packet_len) {
566*8b26181fSAndroid Build Coastguard Worker caplen = packet_len;
567*8b26181fSAndroid Build Coastguard Worker }
568*8b26181fSAndroid Build Coastguard Worker dp += 2;
569*8b26181fSAndroid Build Coastguard Worker break;
570*8b26181fSAndroid Build Coastguard Worker
571*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_COLOR_HASH_POS:
572*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_DSM_COLOR_HDLC_POS:
573*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_COLOR_HDLC_POS:
574*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_HDLC_POS:
575*8b26181fSAndroid Build Coastguard Worker if ((p->linktype != DLT_CHDLC) &&
576*8b26181fSAndroid Build Coastguard Worker (p->linktype != DLT_PPP_SERIAL) &&
577*8b26181fSAndroid Build Coastguard Worker (p->linktype != DLT_FRELAY))
578*8b26181fSAndroid Build Coastguard Worker continue;
579*8b26181fSAndroid Build Coastguard Worker packet_len = ntohs(header->wlen);
580*8b26181fSAndroid Build Coastguard Worker packet_len -= (pd->dag_fcs_bits >> 3);
581*8b26181fSAndroid Build Coastguard Worker caplen = rlen - dag_record_size;
582*8b26181fSAndroid Build Coastguard Worker /* Skip over extension headers */
583*8b26181fSAndroid Build Coastguard Worker caplen -= (8 * num_ext_hdr);
584*8b26181fSAndroid Build Coastguard Worker if (caplen > packet_len) {
585*8b26181fSAndroid Build Coastguard Worker caplen = packet_len;
586*8b26181fSAndroid Build Coastguard Worker }
587*8b26181fSAndroid Build Coastguard Worker break;
588*8b26181fSAndroid Build Coastguard Worker
589*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_COLOR_MC_HDLC_POS:
590*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_MC_HDLC:
591*8b26181fSAndroid Build Coastguard Worker if ((p->linktype != DLT_CHDLC) &&
592*8b26181fSAndroid Build Coastguard Worker (p->linktype != DLT_PPP_SERIAL) &&
593*8b26181fSAndroid Build Coastguard Worker (p->linktype != DLT_FRELAY) &&
594*8b26181fSAndroid Build Coastguard Worker (p->linktype != DLT_MTP2) &&
595*8b26181fSAndroid Build Coastguard Worker (p->linktype != DLT_MTP2_WITH_PHDR) &&
596*8b26181fSAndroid Build Coastguard Worker (p->linktype != DLT_LAPD))
597*8b26181fSAndroid Build Coastguard Worker continue;
598*8b26181fSAndroid Build Coastguard Worker packet_len = ntohs(header->wlen);
599*8b26181fSAndroid Build Coastguard Worker packet_len -= (pd->dag_fcs_bits >> 3);
600*8b26181fSAndroid Build Coastguard Worker caplen = rlen - dag_record_size - 4;
601*8b26181fSAndroid Build Coastguard Worker /* Skip over extension headers */
602*8b26181fSAndroid Build Coastguard Worker caplen -= (8 * num_ext_hdr);
603*8b26181fSAndroid Build Coastguard Worker if (caplen > packet_len) {
604*8b26181fSAndroid Build Coastguard Worker caplen = packet_len;
605*8b26181fSAndroid Build Coastguard Worker }
606*8b26181fSAndroid Build Coastguard Worker /* jump the MC_HDLC_HEADER */
607*8b26181fSAndroid Build Coastguard Worker dp += 4;
608*8b26181fSAndroid Build Coastguard Worker #ifdef DLT_MTP2_WITH_PHDR
609*8b26181fSAndroid Build Coastguard Worker if (p->linktype == DLT_MTP2_WITH_PHDR) {
610*8b26181fSAndroid Build Coastguard Worker /* Add the MTP2 Pseudo Header */
611*8b26181fSAndroid Build Coastguard Worker caplen += MTP2_HDR_LEN;
612*8b26181fSAndroid Build Coastguard Worker packet_len += MTP2_HDR_LEN;
613*8b26181fSAndroid Build Coastguard Worker
614*8b26181fSAndroid Build Coastguard Worker TempPkt[MTP2_SENT_OFFSET] = 0;
615*8b26181fSAndroid Build Coastguard Worker TempPkt[MTP2_ANNEX_A_USED_OFFSET] = MTP2_ANNEX_A_USED_UNKNOWN;
616*8b26181fSAndroid Build Coastguard Worker *(TempPkt+MTP2_LINK_NUMBER_OFFSET) = ((header->rec.mc_hdlc.mc_header>>16)&0x01);
617*8b26181fSAndroid Build Coastguard Worker *(TempPkt+MTP2_LINK_NUMBER_OFFSET+1) = ((header->rec.mc_hdlc.mc_header>>24)&0xff);
618*8b26181fSAndroid Build Coastguard Worker memcpy(TempPkt+MTP2_HDR_LEN, dp, caplen);
619*8b26181fSAndroid Build Coastguard Worker dp = TempPkt;
620*8b26181fSAndroid Build Coastguard Worker }
621*8b26181fSAndroid Build Coastguard Worker #endif
622*8b26181fSAndroid Build Coastguard Worker break;
623*8b26181fSAndroid Build Coastguard Worker
624*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_IPV4:
625*8b26181fSAndroid Build Coastguard Worker if ((p->linktype != DLT_RAW) &&
626*8b26181fSAndroid Build Coastguard Worker (p->linktype != DLT_IPV4))
627*8b26181fSAndroid Build Coastguard Worker continue;
628*8b26181fSAndroid Build Coastguard Worker packet_len = ntohs(header->wlen);
629*8b26181fSAndroid Build Coastguard Worker caplen = rlen - dag_record_size;
630*8b26181fSAndroid Build Coastguard Worker /* Skip over extension headers */
631*8b26181fSAndroid Build Coastguard Worker caplen -= (8 * num_ext_hdr);
632*8b26181fSAndroid Build Coastguard Worker if (caplen > packet_len) {
633*8b26181fSAndroid Build Coastguard Worker caplen = packet_len;
634*8b26181fSAndroid Build Coastguard Worker }
635*8b26181fSAndroid Build Coastguard Worker break;
636*8b26181fSAndroid Build Coastguard Worker
637*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_IPV6:
638*8b26181fSAndroid Build Coastguard Worker if ((p->linktype != DLT_RAW) &&
639*8b26181fSAndroid Build Coastguard Worker (p->linktype != DLT_IPV6))
640*8b26181fSAndroid Build Coastguard Worker continue;
641*8b26181fSAndroid Build Coastguard Worker packet_len = ntohs(header->wlen);
642*8b26181fSAndroid Build Coastguard Worker caplen = rlen - dag_record_size;
643*8b26181fSAndroid Build Coastguard Worker /* Skip over extension headers */
644*8b26181fSAndroid Build Coastguard Worker caplen -= (8 * num_ext_hdr);
645*8b26181fSAndroid Build Coastguard Worker if (caplen > packet_len) {
646*8b26181fSAndroid Build Coastguard Worker caplen = packet_len;
647*8b26181fSAndroid Build Coastguard Worker }
648*8b26181fSAndroid Build Coastguard Worker break;
649*8b26181fSAndroid Build Coastguard Worker
650*8b26181fSAndroid Build Coastguard Worker /* These types have no matching 'native' DLT, but can be used with DLT_ERF above */
651*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_MC_RAW:
652*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_MC_RAW_CHANNEL:
653*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_IP_COUNTER:
654*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_TCP_FLOW_COUNTER:
655*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_INFINIBAND:
656*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_RAW_LINK:
657*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_INFINIBAND_LINK:
658*8b26181fSAndroid Build Coastguard Worker default:
659*8b26181fSAndroid Build Coastguard Worker /* Unhandled ERF type.
660*8b26181fSAndroid Build Coastguard Worker * Ignore rather than generating error
661*8b26181fSAndroid Build Coastguard Worker */
662*8b26181fSAndroid Build Coastguard Worker continue;
663*8b26181fSAndroid Build Coastguard Worker } /* switch type */
664*8b26181fSAndroid Build Coastguard Worker
665*8b26181fSAndroid Build Coastguard Worker } /* ERF encapsulation */
666*8b26181fSAndroid Build Coastguard Worker
667*8b26181fSAndroid Build Coastguard Worker if (caplen > p->snapshot)
668*8b26181fSAndroid Build Coastguard Worker caplen = p->snapshot;
669*8b26181fSAndroid Build Coastguard Worker
670*8b26181fSAndroid Build Coastguard Worker /* Run the packet filter if there is one. */
671*8b26181fSAndroid Build Coastguard Worker if ((p->fcode.bf_insns == NULL) || pcap_filter(p->fcode.bf_insns, dp, packet_len, caplen)) {
672*8b26181fSAndroid Build Coastguard Worker
673*8b26181fSAndroid Build Coastguard Worker /* convert between timestamp formats */
674*8b26181fSAndroid Build Coastguard Worker register unsigned long long ts;
675*8b26181fSAndroid Build Coastguard Worker
676*8b26181fSAndroid Build Coastguard Worker if (IS_BIGENDIAN()) {
677*8b26181fSAndroid Build Coastguard Worker ts = SWAPLL(header->ts);
678*8b26181fSAndroid Build Coastguard Worker } else {
679*8b26181fSAndroid Build Coastguard Worker ts = header->ts;
680*8b26181fSAndroid Build Coastguard Worker }
681*8b26181fSAndroid Build Coastguard Worker
682*8b26181fSAndroid Build Coastguard Worker switch (p->opt.tstamp_precision) {
683*8b26181fSAndroid Build Coastguard Worker case PCAP_TSTAMP_PRECISION_NANO:
684*8b26181fSAndroid Build Coastguard Worker ticks_per_second = 1000000000;
685*8b26181fSAndroid Build Coastguard Worker break;
686*8b26181fSAndroid Build Coastguard Worker case PCAP_TSTAMP_PRECISION_MICRO:
687*8b26181fSAndroid Build Coastguard Worker default:
688*8b26181fSAndroid Build Coastguard Worker ticks_per_second = 1000000;
689*8b26181fSAndroid Build Coastguard Worker break;
690*8b26181fSAndroid Build Coastguard Worker
691*8b26181fSAndroid Build Coastguard Worker }
692*8b26181fSAndroid Build Coastguard Worker pcap_header.ts.tv_sec = ts >> 32;
693*8b26181fSAndroid Build Coastguard Worker ts = (ts & 0xffffffffULL) * ticks_per_second;
694*8b26181fSAndroid Build Coastguard Worker ts += 0x80000000; /* rounding */
695*8b26181fSAndroid Build Coastguard Worker pcap_header.ts.tv_usec = ts >> 32;
696*8b26181fSAndroid Build Coastguard Worker if (pcap_header.ts.tv_usec >= ticks_per_second) {
697*8b26181fSAndroid Build Coastguard Worker pcap_header.ts.tv_usec -= ticks_per_second;
698*8b26181fSAndroid Build Coastguard Worker pcap_header.ts.tv_sec++;
699*8b26181fSAndroid Build Coastguard Worker }
700*8b26181fSAndroid Build Coastguard Worker
701*8b26181fSAndroid Build Coastguard Worker /* Fill in our own header data */
702*8b26181fSAndroid Build Coastguard Worker pcap_header.caplen = caplen;
703*8b26181fSAndroid Build Coastguard Worker pcap_header.len = packet_len;
704*8b26181fSAndroid Build Coastguard Worker
705*8b26181fSAndroid Build Coastguard Worker /* Count the packet. */
706*8b26181fSAndroid Build Coastguard Worker pd->stat.ps_recv++;
707*8b26181fSAndroid Build Coastguard Worker
708*8b26181fSAndroid Build Coastguard Worker /* Call the user supplied callback function */
709*8b26181fSAndroid Build Coastguard Worker callback(user, &pcap_header, dp);
710*8b26181fSAndroid Build Coastguard Worker
711*8b26181fSAndroid Build Coastguard Worker /* Only count packets that pass the filter, for consistency with standard Linux behaviour. */
712*8b26181fSAndroid Build Coastguard Worker processed++;
713*8b26181fSAndroid Build Coastguard Worker if (processed == cnt && !PACKET_COUNT_IS_UNLIMITED(cnt))
714*8b26181fSAndroid Build Coastguard Worker {
715*8b26181fSAndroid Build Coastguard Worker /* Reached the user-specified limit. */
716*8b26181fSAndroid Build Coastguard Worker return cnt;
717*8b26181fSAndroid Build Coastguard Worker }
718*8b26181fSAndroid Build Coastguard Worker }
719*8b26181fSAndroid Build Coastguard Worker }
720*8b26181fSAndroid Build Coastguard Worker
721*8b26181fSAndroid Build Coastguard Worker return processed;
722*8b26181fSAndroid Build Coastguard Worker }
723*8b26181fSAndroid Build Coastguard Worker
724*8b26181fSAndroid Build Coastguard Worker static int
dag_inject(pcap_t * p,const void * buf _U_,int size _U_)725*8b26181fSAndroid Build Coastguard Worker dag_inject(pcap_t *p, const void *buf _U_, int size _U_)
726*8b26181fSAndroid Build Coastguard Worker {
727*8b26181fSAndroid Build Coastguard Worker pcap_strlcpy(p->errbuf, "Sending packets isn't supported on DAG cards",
728*8b26181fSAndroid Build Coastguard Worker PCAP_ERRBUF_SIZE);
729*8b26181fSAndroid Build Coastguard Worker return (-1);
730*8b26181fSAndroid Build Coastguard Worker }
731*8b26181fSAndroid Build Coastguard Worker
732*8b26181fSAndroid Build Coastguard Worker /*
733*8b26181fSAndroid Build Coastguard Worker * Get a handle for a live capture from the given DAG device. Passing a NULL
734*8b26181fSAndroid Build Coastguard Worker * device will result in a failure. The promisc flag is ignored because DAG
735*8b26181fSAndroid Build Coastguard Worker * cards are always promiscuous. The to_ms parameter is used in setting the
736*8b26181fSAndroid Build Coastguard Worker * API polling parameters.
737*8b26181fSAndroid Build Coastguard Worker *
738*8b26181fSAndroid Build Coastguard Worker * snaplen is now also ignored, until we get per-stream slen support. Set
739*8b26181fSAndroid Build Coastguard Worker * slen with appropriate DAG tool BEFORE pcap_activate().
740*8b26181fSAndroid Build Coastguard Worker *
741*8b26181fSAndroid Build Coastguard Worker * See also pcap(3).
742*8b26181fSAndroid Build Coastguard Worker */
dag_activate(pcap_t * p)743*8b26181fSAndroid Build Coastguard Worker static int dag_activate(pcap_t* p)
744*8b26181fSAndroid Build Coastguard Worker {
745*8b26181fSAndroid Build Coastguard Worker struct pcap_dag *pd = p->priv;
746*8b26181fSAndroid Build Coastguard Worker char *s;
747*8b26181fSAndroid Build Coastguard Worker int n;
748*8b26181fSAndroid Build Coastguard Worker daginf_t* daginf;
749*8b26181fSAndroid Build Coastguard Worker char * newDev = NULL;
750*8b26181fSAndroid Build Coastguard Worker char * device = p->opt.device;
751*8b26181fSAndroid Build Coastguard Worker int ret;
752*8b26181fSAndroid Build Coastguard Worker dag_size_t mindata;
753*8b26181fSAndroid Build Coastguard Worker struct timeval maxwait;
754*8b26181fSAndroid Build Coastguard Worker struct timeval poll;
755*8b26181fSAndroid Build Coastguard Worker
756*8b26181fSAndroid Build Coastguard Worker if (device == NULL) {
757*8b26181fSAndroid Build Coastguard Worker snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "device is NULL");
758*8b26181fSAndroid Build Coastguard Worker return PCAP_ERROR;
759*8b26181fSAndroid Build Coastguard Worker }
760*8b26181fSAndroid Build Coastguard Worker
761*8b26181fSAndroid Build Coastguard Worker /* Initialize some components of the pcap structure. */
762*8b26181fSAndroid Build Coastguard Worker newDev = (char *)malloc(strlen(device) + 16);
763*8b26181fSAndroid Build Coastguard Worker if (newDev == NULL) {
764*8b26181fSAndroid Build Coastguard Worker ret = PCAP_ERROR;
765*8b26181fSAndroid Build Coastguard Worker pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
766*8b26181fSAndroid Build Coastguard Worker errno, "Can't allocate string for device name");
767*8b26181fSAndroid Build Coastguard Worker goto fail;
768*8b26181fSAndroid Build Coastguard Worker }
769*8b26181fSAndroid Build Coastguard Worker
770*8b26181fSAndroid Build Coastguard Worker /* Parse input name to get dag device and stream number if provided */
771*8b26181fSAndroid Build Coastguard Worker if (dag_parse_name(device, newDev, strlen(device) + 16, &pd->dag_stream) < 0) {
772*8b26181fSAndroid Build Coastguard Worker /*
773*8b26181fSAndroid Build Coastguard Worker * XXX - it'd be nice if this indicated what was wrong
774*8b26181fSAndroid Build Coastguard Worker * with the name. Does this reliably set errno?
775*8b26181fSAndroid Build Coastguard Worker * Should this return PCAP_ERROR_NO_SUCH_DEVICE in some
776*8b26181fSAndroid Build Coastguard Worker * cases?
777*8b26181fSAndroid Build Coastguard Worker */
778*8b26181fSAndroid Build Coastguard Worker ret = PCAP_ERROR;
779*8b26181fSAndroid Build Coastguard Worker pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
780*8b26181fSAndroid Build Coastguard Worker errno, "dag_parse_name");
781*8b26181fSAndroid Build Coastguard Worker goto fail;
782*8b26181fSAndroid Build Coastguard Worker }
783*8b26181fSAndroid Build Coastguard Worker device = newDev;
784*8b26181fSAndroid Build Coastguard Worker
785*8b26181fSAndroid Build Coastguard Worker if (pd->dag_stream%2) {
786*8b26181fSAndroid Build Coastguard Worker ret = PCAP_ERROR;
787*8b26181fSAndroid Build Coastguard Worker snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture");
788*8b26181fSAndroid Build Coastguard Worker goto fail;
789*8b26181fSAndroid Build Coastguard Worker }
790*8b26181fSAndroid Build Coastguard Worker
791*8b26181fSAndroid Build Coastguard Worker /* setup device parameters */
792*8b26181fSAndroid Build Coastguard Worker if((pd->dag_ref = dag_config_init((char *)device)) == NULL) {
793*8b26181fSAndroid Build Coastguard Worker /*
794*8b26181fSAndroid Build Coastguard Worker * XXX - does this reliably set errno?
795*8b26181fSAndroid Build Coastguard Worker */
796*8b26181fSAndroid Build Coastguard Worker if (errno == ENOENT) {
797*8b26181fSAndroid Build Coastguard Worker /*
798*8b26181fSAndroid Build Coastguard Worker * There's nothing more to say, so clear
799*8b26181fSAndroid Build Coastguard Worker * the error message.
800*8b26181fSAndroid Build Coastguard Worker */
801*8b26181fSAndroid Build Coastguard Worker ret = PCAP_ERROR_NO_SUCH_DEVICE;
802*8b26181fSAndroid Build Coastguard Worker p->errbuf[0] = '\0';
803*8b26181fSAndroid Build Coastguard Worker } else if (errno == EPERM || errno == EACCES) {
804*8b26181fSAndroid Build Coastguard Worker ret = PCAP_ERROR_PERM_DENIED;
805*8b26181fSAndroid Build Coastguard Worker snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
806*8b26181fSAndroid Build Coastguard Worker "Attempt to open %s failed with %s - additional privileges may be required",
807*8b26181fSAndroid Build Coastguard Worker device, (errno == EPERM) ? "EPERM" : "EACCES");
808*8b26181fSAndroid Build Coastguard Worker } else {
809*8b26181fSAndroid Build Coastguard Worker ret = PCAP_ERROR;
810*8b26181fSAndroid Build Coastguard Worker pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
811*8b26181fSAndroid Build Coastguard Worker errno, "dag_config_init %s", device);
812*8b26181fSAndroid Build Coastguard Worker }
813*8b26181fSAndroid Build Coastguard Worker goto fail;
814*8b26181fSAndroid Build Coastguard Worker }
815*8b26181fSAndroid Build Coastguard Worker
816*8b26181fSAndroid Build Coastguard Worker if((p->fd = dag_config_get_card_fd(pd->dag_ref)) < 0) {
817*8b26181fSAndroid Build Coastguard Worker /*
818*8b26181fSAndroid Build Coastguard Worker * XXX - does this reliably set errno?
819*8b26181fSAndroid Build Coastguard Worker */
820*8b26181fSAndroid Build Coastguard Worker ret = PCAP_ERROR;
821*8b26181fSAndroid Build Coastguard Worker pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
822*8b26181fSAndroid Build Coastguard Worker errno, "dag_config_get_card_fd %s", device);
823*8b26181fSAndroid Build Coastguard Worker goto failclose;
824*8b26181fSAndroid Build Coastguard Worker }
825*8b26181fSAndroid Build Coastguard Worker
826*8b26181fSAndroid Build Coastguard Worker /* Open requested stream. Can fail if already locked or on error */
827*8b26181fSAndroid Build Coastguard Worker if (dag_attach_stream64(p->fd, pd->dag_stream, 0, 0) < 0) {
828*8b26181fSAndroid Build Coastguard Worker ret = PCAP_ERROR;
829*8b26181fSAndroid Build Coastguard Worker pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
830*8b26181fSAndroid Build Coastguard Worker errno, "dag_attach_stream");
831*8b26181fSAndroid Build Coastguard Worker goto failclose;
832*8b26181fSAndroid Build Coastguard Worker }
833*8b26181fSAndroid Build Coastguard Worker
834*8b26181fSAndroid Build Coastguard Worker /* Try to find Stream Drop attribute */
835*8b26181fSAndroid Build Coastguard Worker pd->drop_attr = kNullAttributeUuid;
836*8b26181fSAndroid Build Coastguard Worker pd->dag_root = dag_config_get_root_component(pd->dag_ref);
837*8b26181fSAndroid Build Coastguard Worker if ( dag_component_get_subcomponent(pd->dag_root, kComponentStreamFeatures, 0) )
838*8b26181fSAndroid Build Coastguard Worker {
839*8b26181fSAndroid Build Coastguard Worker pd->drop_attr = dag_config_get_indexed_attribute_uuid(pd->dag_ref, kUint32AttributeStreamDropCount, pd->dag_stream/2);
840*8b26181fSAndroid Build Coastguard Worker }
841*8b26181fSAndroid Build Coastguard Worker
842*8b26181fSAndroid Build Coastguard Worker /* Set up default poll parameters for stream
843*8b26181fSAndroid Build Coastguard Worker * Can be overridden by pcap_set_nonblock()
844*8b26181fSAndroid Build Coastguard Worker */
845*8b26181fSAndroid Build Coastguard Worker if (dag_get_stream_poll64(p->fd, pd->dag_stream,
846*8b26181fSAndroid Build Coastguard Worker &mindata, &maxwait, &poll) < 0) {
847*8b26181fSAndroid Build Coastguard Worker ret = PCAP_ERROR;
848*8b26181fSAndroid Build Coastguard Worker pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
849*8b26181fSAndroid Build Coastguard Worker errno, "dag_get_stream_poll");
850*8b26181fSAndroid Build Coastguard Worker goto faildetach;
851*8b26181fSAndroid Build Coastguard Worker }
852*8b26181fSAndroid Build Coastguard Worker
853*8b26181fSAndroid Build Coastguard Worker /* Use the poll time as the required select timeout for callers
854*8b26181fSAndroid Build Coastguard Worker * who are using select()/etc. in an event loop waiting for
855*8b26181fSAndroid Build Coastguard Worker * packets to arrive.
856*8b26181fSAndroid Build Coastguard Worker */
857*8b26181fSAndroid Build Coastguard Worker pd->required_select_timeout = poll;
858*8b26181fSAndroid Build Coastguard Worker p->required_select_timeout = &pd->required_select_timeout;
859*8b26181fSAndroid Build Coastguard Worker
860*8b26181fSAndroid Build Coastguard Worker /*
861*8b26181fSAndroid Build Coastguard Worker * Turn a negative snapshot value (invalid), a snapshot value of
862*8b26181fSAndroid Build Coastguard Worker * 0 (unspecified), or a value bigger than the normal maximum
863*8b26181fSAndroid Build Coastguard Worker * value, into the maximum allowed value.
864*8b26181fSAndroid Build Coastguard Worker *
865*8b26181fSAndroid Build Coastguard Worker * If some application really *needs* a bigger snapshot
866*8b26181fSAndroid Build Coastguard Worker * length, we should just increase MAXIMUM_SNAPLEN.
867*8b26181fSAndroid Build Coastguard Worker */
868*8b26181fSAndroid Build Coastguard Worker if (p->snapshot <= 0 || p->snapshot > MAXIMUM_SNAPLEN)
869*8b26181fSAndroid Build Coastguard Worker p->snapshot = MAXIMUM_SNAPLEN;
870*8b26181fSAndroid Build Coastguard Worker
871*8b26181fSAndroid Build Coastguard Worker if (p->opt.immediate) {
872*8b26181fSAndroid Build Coastguard Worker /* Call callback immediately.
873*8b26181fSAndroid Build Coastguard Worker * XXX - is this the right way to p this?
874*8b26181fSAndroid Build Coastguard Worker */
875*8b26181fSAndroid Build Coastguard Worker mindata = 0;
876*8b26181fSAndroid Build Coastguard Worker } else {
877*8b26181fSAndroid Build Coastguard Worker /* Amount of data to collect in Bytes before calling callbacks.
878*8b26181fSAndroid Build Coastguard Worker * Important for efficiency, but can introduce latency
879*8b26181fSAndroid Build Coastguard Worker * at low packet rates if to_ms not set!
880*8b26181fSAndroid Build Coastguard Worker */
881*8b26181fSAndroid Build Coastguard Worker mindata = 65536;
882*8b26181fSAndroid Build Coastguard Worker }
883*8b26181fSAndroid Build Coastguard Worker
884*8b26181fSAndroid Build Coastguard Worker /* Obey opt.timeout (was to_ms) if supplied. This is a good idea!
885*8b26181fSAndroid Build Coastguard Worker * Recommend 10-100ms. Calls will time out even if no data arrived.
886*8b26181fSAndroid Build Coastguard Worker */
887*8b26181fSAndroid Build Coastguard Worker maxwait.tv_sec = p->opt.timeout/1000;
888*8b26181fSAndroid Build Coastguard Worker maxwait.tv_usec = (p->opt.timeout%1000) * 1000;
889*8b26181fSAndroid Build Coastguard Worker
890*8b26181fSAndroid Build Coastguard Worker if (dag_set_stream_poll64(p->fd, pd->dag_stream,
891*8b26181fSAndroid Build Coastguard Worker mindata, &maxwait, &poll) < 0) {
892*8b26181fSAndroid Build Coastguard Worker ret = PCAP_ERROR;
893*8b26181fSAndroid Build Coastguard Worker pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
894*8b26181fSAndroid Build Coastguard Worker errno, "dag_set_stream_poll");
895*8b26181fSAndroid Build Coastguard Worker goto faildetach;
896*8b26181fSAndroid Build Coastguard Worker }
897*8b26181fSAndroid Build Coastguard Worker
898*8b26181fSAndroid Build Coastguard Worker /* XXX Not calling dag_configure() to set slen; this is unsafe in
899*8b26181fSAndroid Build Coastguard Worker * multi-stream environments as the gpp config is global.
900*8b26181fSAndroid Build Coastguard Worker * Once the firmware provides 'per-stream slen' this can be supported
901*8b26181fSAndroid Build Coastguard Worker * again via the Config API without side-effects */
902*8b26181fSAndroid Build Coastguard Worker #if 0
903*8b26181fSAndroid Build Coastguard Worker /* set the card snap length to the specified snaplen parameter */
904*8b26181fSAndroid Build Coastguard Worker /* This is a really bad idea, as different cards have different
905*8b26181fSAndroid Build Coastguard Worker * valid slen ranges. Should fix in Config API. */
906*8b26181fSAndroid Build Coastguard Worker if (p->snapshot == 0 || p->snapshot > MAX_DAG_SNAPLEN) {
907*8b26181fSAndroid Build Coastguard Worker p->snapshot = MAX_DAG_SNAPLEN;
908*8b26181fSAndroid Build Coastguard Worker } else if (snaplen < MIN_DAG_SNAPLEN) {
909*8b26181fSAndroid Build Coastguard Worker p->snapshot = MIN_DAG_SNAPLEN;
910*8b26181fSAndroid Build Coastguard Worker }
911*8b26181fSAndroid Build Coastguard Worker /* snap len has to be a multiple of 4 */
912*8b26181fSAndroid Build Coastguard Worker #endif
913*8b26181fSAndroid Build Coastguard Worker
914*8b26181fSAndroid Build Coastguard Worker if(dag_start_stream(p->fd, pd->dag_stream) < 0) {
915*8b26181fSAndroid Build Coastguard Worker ret = PCAP_ERROR;
916*8b26181fSAndroid Build Coastguard Worker pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
917*8b26181fSAndroid Build Coastguard Worker errno, "dag_start_stream %s", device);
918*8b26181fSAndroid Build Coastguard Worker goto faildetach;
919*8b26181fSAndroid Build Coastguard Worker }
920*8b26181fSAndroid Build Coastguard Worker
921*8b26181fSAndroid Build Coastguard Worker /*
922*8b26181fSAndroid Build Coastguard Worker * Important! You have to ensure bottom is properly
923*8b26181fSAndroid Build Coastguard Worker * initialized to zero on startup, it won't give you
924*8b26181fSAndroid Build Coastguard Worker * a compiler warning if you make this mistake!
925*8b26181fSAndroid Build Coastguard Worker */
926*8b26181fSAndroid Build Coastguard Worker pd->dag_mem_bottom = 0;
927*8b26181fSAndroid Build Coastguard Worker pd->dag_mem_top = 0;
928*8b26181fSAndroid Build Coastguard Worker
929*8b26181fSAndroid Build Coastguard Worker /*
930*8b26181fSAndroid Build Coastguard Worker * Find out how many FCS bits we should strip.
931*8b26181fSAndroid Build Coastguard Worker * First, query the card to see if it strips the FCS.
932*8b26181fSAndroid Build Coastguard Worker */
933*8b26181fSAndroid Build Coastguard Worker daginf = dag_info(p->fd);
934*8b26181fSAndroid Build Coastguard Worker if ((0x4200 == daginf->device_code) || (0x4230 == daginf->device_code)) {
935*8b26181fSAndroid Build Coastguard Worker /* DAG 4.2S and 4.23S already strip the FCS. Stripping the final word again truncates the packet. */
936*8b26181fSAndroid Build Coastguard Worker pd->dag_fcs_bits = 0;
937*8b26181fSAndroid Build Coastguard Worker
938*8b26181fSAndroid Build Coastguard Worker /* Note that no FCS will be supplied. */
939*8b26181fSAndroid Build Coastguard Worker p->linktype_ext = LT_FCS_DATALINK_EXT(0);
940*8b26181fSAndroid Build Coastguard Worker } else {
941*8b26181fSAndroid Build Coastguard Worker /*
942*8b26181fSAndroid Build Coastguard Worker * Start out assuming it's 32 bits.
943*8b26181fSAndroid Build Coastguard Worker */
944*8b26181fSAndroid Build Coastguard Worker pd->dag_fcs_bits = 32;
945*8b26181fSAndroid Build Coastguard Worker
946*8b26181fSAndroid Build Coastguard Worker /* Allow an environment variable to override. */
947*8b26181fSAndroid Build Coastguard Worker if ((s = getenv("ERF_FCS_BITS")) != NULL) {
948*8b26181fSAndroid Build Coastguard Worker if ((n = atoi(s)) == 0 || n == 16 || n == 32) {
949*8b26181fSAndroid Build Coastguard Worker pd->dag_fcs_bits = n;
950*8b26181fSAndroid Build Coastguard Worker } else {
951*8b26181fSAndroid Build Coastguard Worker ret = PCAP_ERROR;
952*8b26181fSAndroid Build Coastguard Worker snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
953*8b26181fSAndroid Build Coastguard Worker "pcap_activate %s: bad ERF_FCS_BITS value (%d) in environment", device, n);
954*8b26181fSAndroid Build Coastguard Worker goto failstop;
955*8b26181fSAndroid Build Coastguard Worker }
956*8b26181fSAndroid Build Coastguard Worker }
957*8b26181fSAndroid Build Coastguard Worker
958*8b26181fSAndroid Build Coastguard Worker /*
959*8b26181fSAndroid Build Coastguard Worker * Did the user request that they not be stripped?
960*8b26181fSAndroid Build Coastguard Worker */
961*8b26181fSAndroid Build Coastguard Worker if ((s = getenv("ERF_DONT_STRIP_FCS")) != NULL) {
962*8b26181fSAndroid Build Coastguard Worker /* Yes. Note the number of 16-bit words that will be
963*8b26181fSAndroid Build Coastguard Worker supplied. */
964*8b26181fSAndroid Build Coastguard Worker p->linktype_ext = LT_FCS_DATALINK_EXT(pd->dag_fcs_bits/16);
965*8b26181fSAndroid Build Coastguard Worker
966*8b26181fSAndroid Build Coastguard Worker /* And don't strip them. */
967*8b26181fSAndroid Build Coastguard Worker pd->dag_fcs_bits = 0;
968*8b26181fSAndroid Build Coastguard Worker }
969*8b26181fSAndroid Build Coastguard Worker }
970*8b26181fSAndroid Build Coastguard Worker
971*8b26181fSAndroid Build Coastguard Worker pd->dag_timeout = p->opt.timeout;
972*8b26181fSAndroid Build Coastguard Worker
973*8b26181fSAndroid Build Coastguard Worker p->linktype = -1;
974*8b26181fSAndroid Build Coastguard Worker if (dag_get_datalink(p) < 0) {
975*8b26181fSAndroid Build Coastguard Worker ret = PCAP_ERROR;
976*8b26181fSAndroid Build Coastguard Worker goto failstop;
977*8b26181fSAndroid Build Coastguard Worker }
978*8b26181fSAndroid Build Coastguard Worker
979*8b26181fSAndroid Build Coastguard Worker p->bufsize = 0;
980*8b26181fSAndroid Build Coastguard Worker
981*8b26181fSAndroid Build Coastguard Worker if (new_pcap_dag(p) < 0) {
982*8b26181fSAndroid Build Coastguard Worker ret = PCAP_ERROR;
983*8b26181fSAndroid Build Coastguard Worker pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
984*8b26181fSAndroid Build Coastguard Worker errno, "new_pcap_dag %s", device);
985*8b26181fSAndroid Build Coastguard Worker goto failstop;
986*8b26181fSAndroid Build Coastguard Worker }
987*8b26181fSAndroid Build Coastguard Worker
988*8b26181fSAndroid Build Coastguard Worker /*
989*8b26181fSAndroid Build Coastguard Worker * "select()" and "poll()" don't work on DAG device descriptors.
990*8b26181fSAndroid Build Coastguard Worker */
991*8b26181fSAndroid Build Coastguard Worker p->selectable_fd = -1;
992*8b26181fSAndroid Build Coastguard Worker
993*8b26181fSAndroid Build Coastguard Worker if (newDev != NULL) {
994*8b26181fSAndroid Build Coastguard Worker free((char *)newDev);
995*8b26181fSAndroid Build Coastguard Worker }
996*8b26181fSAndroid Build Coastguard Worker
997*8b26181fSAndroid Build Coastguard Worker p->read_op = dag_read;
998*8b26181fSAndroid Build Coastguard Worker p->inject_op = dag_inject;
999*8b26181fSAndroid Build Coastguard Worker p->setfilter_op = install_bpf_program;
1000*8b26181fSAndroid Build Coastguard Worker p->setdirection_op = NULL; /* Not implemented.*/
1001*8b26181fSAndroid Build Coastguard Worker p->set_datalink_op = dag_set_datalink;
1002*8b26181fSAndroid Build Coastguard Worker p->getnonblock_op = pcap_getnonblock_fd;
1003*8b26181fSAndroid Build Coastguard Worker p->setnonblock_op = dag_setnonblock;
1004*8b26181fSAndroid Build Coastguard Worker p->stats_op = dag_stats;
1005*8b26181fSAndroid Build Coastguard Worker p->cleanup_op = dag_platform_cleanup;
1006*8b26181fSAndroid Build Coastguard Worker pd->stat.ps_drop = 0;
1007*8b26181fSAndroid Build Coastguard Worker pd->stat.ps_recv = 0;
1008*8b26181fSAndroid Build Coastguard Worker pd->stat.ps_ifdrop = 0;
1009*8b26181fSAndroid Build Coastguard Worker return 0;
1010*8b26181fSAndroid Build Coastguard Worker
1011*8b26181fSAndroid Build Coastguard Worker failstop:
1012*8b26181fSAndroid Build Coastguard Worker if (dag_stop_stream(p->fd, pd->dag_stream) < 0) {
1013*8b26181fSAndroid Build Coastguard Worker fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
1014*8b26181fSAndroid Build Coastguard Worker }
1015*8b26181fSAndroid Build Coastguard Worker
1016*8b26181fSAndroid Build Coastguard Worker faildetach:
1017*8b26181fSAndroid Build Coastguard Worker if (dag_detach_stream(p->fd, pd->dag_stream) < 0)
1018*8b26181fSAndroid Build Coastguard Worker fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
1019*8b26181fSAndroid Build Coastguard Worker
1020*8b26181fSAndroid Build Coastguard Worker failclose:
1021*8b26181fSAndroid Build Coastguard Worker dag_config_dispose(pd->dag_ref);
1022*8b26181fSAndroid Build Coastguard Worker /*
1023*8b26181fSAndroid Build Coastguard Worker * Note: we don't need to call close(p->fd) or dag_close(p->fd),
1024*8b26181fSAndroid Build Coastguard Worker * as dag_config_dispose(pd->dag_ref) does this.
1025*8b26181fSAndroid Build Coastguard Worker *
1026*8b26181fSAndroid Build Coastguard Worker * Set p->fd to -1 to make sure that's not done.
1027*8b26181fSAndroid Build Coastguard Worker */
1028*8b26181fSAndroid Build Coastguard Worker p->fd = -1;
1029*8b26181fSAndroid Build Coastguard Worker pd->dag_ref = NULL;
1030*8b26181fSAndroid Build Coastguard Worker delete_pcap_dag(p);
1031*8b26181fSAndroid Build Coastguard Worker
1032*8b26181fSAndroid Build Coastguard Worker fail:
1033*8b26181fSAndroid Build Coastguard Worker pcap_cleanup_live_common(p);
1034*8b26181fSAndroid Build Coastguard Worker if (newDev != NULL) {
1035*8b26181fSAndroid Build Coastguard Worker free((char *)newDev);
1036*8b26181fSAndroid Build Coastguard Worker }
1037*8b26181fSAndroid Build Coastguard Worker
1038*8b26181fSAndroid Build Coastguard Worker return ret;
1039*8b26181fSAndroid Build Coastguard Worker }
1040*8b26181fSAndroid Build Coastguard Worker
dag_create(const char * device,char * ebuf,int * is_ours)1041*8b26181fSAndroid Build Coastguard Worker pcap_t *dag_create(const char *device, char *ebuf, int *is_ours)
1042*8b26181fSAndroid Build Coastguard Worker {
1043*8b26181fSAndroid Build Coastguard Worker const char *cp;
1044*8b26181fSAndroid Build Coastguard Worker char *cpend;
1045*8b26181fSAndroid Build Coastguard Worker long devnum;
1046*8b26181fSAndroid Build Coastguard Worker pcap_t *p;
1047*8b26181fSAndroid Build Coastguard Worker long stream = 0;
1048*8b26181fSAndroid Build Coastguard Worker
1049*8b26181fSAndroid Build Coastguard Worker /* Does this look like a DAG device? */
1050*8b26181fSAndroid Build Coastguard Worker cp = strrchr(device, '/');
1051*8b26181fSAndroid Build Coastguard Worker if (cp == NULL)
1052*8b26181fSAndroid Build Coastguard Worker cp = device;
1053*8b26181fSAndroid Build Coastguard Worker /* Does it begin with "dag"? */
1054*8b26181fSAndroid Build Coastguard Worker if (strncmp(cp, "dag", 3) != 0) {
1055*8b26181fSAndroid Build Coastguard Worker /* Nope, doesn't begin with "dag" */
1056*8b26181fSAndroid Build Coastguard Worker *is_ours = 0;
1057*8b26181fSAndroid Build Coastguard Worker return NULL;
1058*8b26181fSAndroid Build Coastguard Worker }
1059*8b26181fSAndroid Build Coastguard Worker /* Yes - is "dag" followed by a number from 0 to DAG_MAX_BOARDS-1 */
1060*8b26181fSAndroid Build Coastguard Worker cp += 3;
1061*8b26181fSAndroid Build Coastguard Worker devnum = strtol(cp, &cpend, 10);
1062*8b26181fSAndroid Build Coastguard Worker if (*cpend == ':') {
1063*8b26181fSAndroid Build Coastguard Worker /* Followed by a stream number. */
1064*8b26181fSAndroid Build Coastguard Worker stream = strtol(++cpend, &cpend, 10);
1065*8b26181fSAndroid Build Coastguard Worker }
1066*8b26181fSAndroid Build Coastguard Worker
1067*8b26181fSAndroid Build Coastguard Worker if (cpend == cp || *cpend != '\0') {
1068*8b26181fSAndroid Build Coastguard Worker /* Not followed by a number. */
1069*8b26181fSAndroid Build Coastguard Worker *is_ours = 0;
1070*8b26181fSAndroid Build Coastguard Worker return NULL;
1071*8b26181fSAndroid Build Coastguard Worker }
1072*8b26181fSAndroid Build Coastguard Worker
1073*8b26181fSAndroid Build Coastguard Worker if (devnum < 0 || devnum >= DAG_MAX_BOARDS) {
1074*8b26181fSAndroid Build Coastguard Worker /* Followed by a non-valid number. */
1075*8b26181fSAndroid Build Coastguard Worker *is_ours = 0;
1076*8b26181fSAndroid Build Coastguard Worker return NULL;
1077*8b26181fSAndroid Build Coastguard Worker }
1078*8b26181fSAndroid Build Coastguard Worker
1079*8b26181fSAndroid Build Coastguard Worker if (stream <0 || stream >= DAG_STREAM_MAX) {
1080*8b26181fSAndroid Build Coastguard Worker /* Followed by a non-valid stream number. */
1081*8b26181fSAndroid Build Coastguard Worker *is_ours = 0;
1082*8b26181fSAndroid Build Coastguard Worker return NULL;
1083*8b26181fSAndroid Build Coastguard Worker }
1084*8b26181fSAndroid Build Coastguard Worker
1085*8b26181fSAndroid Build Coastguard Worker /* OK, it's probably ours. */
1086*8b26181fSAndroid Build Coastguard Worker *is_ours = 1;
1087*8b26181fSAndroid Build Coastguard Worker
1088*8b26181fSAndroid Build Coastguard Worker p = PCAP_CREATE_COMMON(ebuf, struct pcap_dag);
1089*8b26181fSAndroid Build Coastguard Worker if (p == NULL)
1090*8b26181fSAndroid Build Coastguard Worker return NULL;
1091*8b26181fSAndroid Build Coastguard Worker
1092*8b26181fSAndroid Build Coastguard Worker p->activate_op = dag_activate;
1093*8b26181fSAndroid Build Coastguard Worker
1094*8b26181fSAndroid Build Coastguard Worker /*
1095*8b26181fSAndroid Build Coastguard Worker * We claim that we support microsecond and nanosecond time
1096*8b26181fSAndroid Build Coastguard Worker * stamps.
1097*8b26181fSAndroid Build Coastguard Worker *
1098*8b26181fSAndroid Build Coastguard Worker * XXX Our native precision is 2^-32s, but libpcap doesn't support
1099*8b26181fSAndroid Build Coastguard Worker * power of two precisions yet. We can convert to either MICRO or NANO.
1100*8b26181fSAndroid Build Coastguard Worker */
1101*8b26181fSAndroid Build Coastguard Worker p->tstamp_precision_list = malloc(2 * sizeof(u_int));
1102*8b26181fSAndroid Build Coastguard Worker if (p->tstamp_precision_list == NULL) {
1103*8b26181fSAndroid Build Coastguard Worker pcap_fmt_errmsg_for_errno(ebuf, PCAP_ERRBUF_SIZE,
1104*8b26181fSAndroid Build Coastguard Worker errno, "malloc");
1105*8b26181fSAndroid Build Coastguard Worker pcap_close(p);
1106*8b26181fSAndroid Build Coastguard Worker return NULL;
1107*8b26181fSAndroid Build Coastguard Worker }
1108*8b26181fSAndroid Build Coastguard Worker p->tstamp_precision_list[0] = PCAP_TSTAMP_PRECISION_MICRO;
1109*8b26181fSAndroid Build Coastguard Worker p->tstamp_precision_list[1] = PCAP_TSTAMP_PRECISION_NANO;
1110*8b26181fSAndroid Build Coastguard Worker p->tstamp_precision_count = 2;
1111*8b26181fSAndroid Build Coastguard Worker return p;
1112*8b26181fSAndroid Build Coastguard Worker }
1113*8b26181fSAndroid Build Coastguard Worker
1114*8b26181fSAndroid Build Coastguard Worker static int
dag_stats(pcap_t * p,struct pcap_stat * ps)1115*8b26181fSAndroid Build Coastguard Worker dag_stats(pcap_t *p, struct pcap_stat *ps) {
1116*8b26181fSAndroid Build Coastguard Worker struct pcap_dag *pd = p->priv;
1117*8b26181fSAndroid Build Coastguard Worker uint32_t stream_drop;
1118*8b26181fSAndroid Build Coastguard Worker dag_err_t dag_error;
1119*8b26181fSAndroid Build Coastguard Worker
1120*8b26181fSAndroid Build Coastguard Worker /*
1121*8b26181fSAndroid Build Coastguard Worker * Packet records received (ps_recv) are counted in dag_read().
1122*8b26181fSAndroid Build Coastguard Worker * Packet records dropped (ps_drop) are read from Stream Drop attribute if present,
1123*8b26181fSAndroid Build Coastguard Worker * otherwise integrate the ERF Header lctr counts (if available) in dag_read().
1124*8b26181fSAndroid Build Coastguard Worker * We are reporting that no records are dropped by the card/driver (ps_ifdrop).
1125*8b26181fSAndroid Build Coastguard Worker */
1126*8b26181fSAndroid Build Coastguard Worker
1127*8b26181fSAndroid Build Coastguard Worker if(pd->drop_attr != kNullAttributeUuid) {
1128*8b26181fSAndroid Build Coastguard Worker /* Note this counter is cleared at start of capture and will wrap at UINT_MAX.
1129*8b26181fSAndroid Build Coastguard Worker * The application is responsible for polling ps_drop frequently enough
1130*8b26181fSAndroid Build Coastguard Worker * to detect each wrap and integrate total drop with a wider counter */
1131*8b26181fSAndroid Build Coastguard Worker if ((dag_error = dag_config_get_uint32_attribute_ex(pd->dag_ref, pd->drop_attr, &stream_drop)) == kDagErrNone) {
1132*8b26181fSAndroid Build Coastguard Worker pd->stat.ps_drop = stream_drop;
1133*8b26181fSAndroid Build Coastguard Worker } else {
1134*8b26181fSAndroid Build Coastguard Worker snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "reading stream drop attribute: %s",
1135*8b26181fSAndroid Build Coastguard Worker dag_config_strerror(dag_error));
1136*8b26181fSAndroid Build Coastguard Worker return -1;
1137*8b26181fSAndroid Build Coastguard Worker }
1138*8b26181fSAndroid Build Coastguard Worker }
1139*8b26181fSAndroid Build Coastguard Worker
1140*8b26181fSAndroid Build Coastguard Worker *ps = pd->stat;
1141*8b26181fSAndroid Build Coastguard Worker
1142*8b26181fSAndroid Build Coastguard Worker return 0;
1143*8b26181fSAndroid Build Coastguard Worker }
1144*8b26181fSAndroid Build Coastguard Worker
1145*8b26181fSAndroid Build Coastguard Worker /*
1146*8b26181fSAndroid Build Coastguard Worker * Add all DAG devices.
1147*8b26181fSAndroid Build Coastguard Worker */
1148*8b26181fSAndroid Build Coastguard Worker int
dag_findalldevs(pcap_if_list_t * devlistp,char * errbuf)1149*8b26181fSAndroid Build Coastguard Worker dag_findalldevs(pcap_if_list_t *devlistp, char *errbuf)
1150*8b26181fSAndroid Build Coastguard Worker {
1151*8b26181fSAndroid Build Coastguard Worker char name[12]; /* XXX - pick a size */
1152*8b26181fSAndroid Build Coastguard Worker int c;
1153*8b26181fSAndroid Build Coastguard Worker char dagname[DAGNAME_BUFSIZE];
1154*8b26181fSAndroid Build Coastguard Worker int dagstream;
1155*8b26181fSAndroid Build Coastguard Worker int dagfd;
1156*8b26181fSAndroid Build Coastguard Worker dag_card_inf_t *inf;
1157*8b26181fSAndroid Build Coastguard Worker char *description;
1158*8b26181fSAndroid Build Coastguard Worker int stream, rxstreams;
1159*8b26181fSAndroid Build Coastguard Worker
1160*8b26181fSAndroid Build Coastguard Worker /* Try all the DAGs 0-DAG_MAX_BOARDS */
1161*8b26181fSAndroid Build Coastguard Worker for (c = 0; c < DAG_MAX_BOARDS; c++) {
1162*8b26181fSAndroid Build Coastguard Worker snprintf(name, 12, "dag%d", c);
1163*8b26181fSAndroid Build Coastguard Worker if (-1 == dag_parse_name(name, dagname, DAGNAME_BUFSIZE, &dagstream))
1164*8b26181fSAndroid Build Coastguard Worker {
1165*8b26181fSAndroid Build Coastguard Worker (void) snprintf(errbuf, PCAP_ERRBUF_SIZE,
1166*8b26181fSAndroid Build Coastguard Worker "dag: device name %s can't be parsed", name);
1167*8b26181fSAndroid Build Coastguard Worker return (-1);
1168*8b26181fSAndroid Build Coastguard Worker }
1169*8b26181fSAndroid Build Coastguard Worker if ( (dagfd = dag_open(dagname)) >= 0 ) {
1170*8b26181fSAndroid Build Coastguard Worker description = NULL;
1171*8b26181fSAndroid Build Coastguard Worker if ((inf = dag_pciinfo(dagfd)))
1172*8b26181fSAndroid Build Coastguard Worker description = dag_device_name(inf->device_code, 1);
1173*8b26181fSAndroid Build Coastguard Worker /*
1174*8b26181fSAndroid Build Coastguard Worker * XXX - is there a way to determine whether
1175*8b26181fSAndroid Build Coastguard Worker * the card is plugged into a network or not?
1176*8b26181fSAndroid Build Coastguard Worker * If so, we should check that and set
1177*8b26181fSAndroid Build Coastguard Worker * PCAP_IF_CONNECTION_STATUS_CONNECTED or
1178*8b26181fSAndroid Build Coastguard Worker * PCAP_IF_CONNECTION_STATUS_DISCONNECTED.
1179*8b26181fSAndroid Build Coastguard Worker *
1180*8b26181fSAndroid Build Coastguard Worker * Also, are there notions of "up" and "running"?
1181*8b26181fSAndroid Build Coastguard Worker */
1182*8b26181fSAndroid Build Coastguard Worker if (add_dev(devlistp, name, 0, description, errbuf) == NULL) {
1183*8b26181fSAndroid Build Coastguard Worker /*
1184*8b26181fSAndroid Build Coastguard Worker * Failure.
1185*8b26181fSAndroid Build Coastguard Worker */
1186*8b26181fSAndroid Build Coastguard Worker return (-1);
1187*8b26181fSAndroid Build Coastguard Worker }
1188*8b26181fSAndroid Build Coastguard Worker rxstreams = dag_rx_get_stream_count(dagfd);
1189*8b26181fSAndroid Build Coastguard Worker for(stream=0;stream<DAG_STREAM_MAX;stream+=2) {
1190*8b26181fSAndroid Build Coastguard Worker if (0 == dag_attach_stream64(dagfd, stream, 0, 0)) {
1191*8b26181fSAndroid Build Coastguard Worker dag_detach_stream(dagfd, stream);
1192*8b26181fSAndroid Build Coastguard Worker
1193*8b26181fSAndroid Build Coastguard Worker snprintf(name, 10, "dag%d:%d", c, stream);
1194*8b26181fSAndroid Build Coastguard Worker if (add_dev(devlistp, name, 0, description, errbuf) == NULL) {
1195*8b26181fSAndroid Build Coastguard Worker /*
1196*8b26181fSAndroid Build Coastguard Worker * Failure.
1197*8b26181fSAndroid Build Coastguard Worker */
1198*8b26181fSAndroid Build Coastguard Worker return (-1);
1199*8b26181fSAndroid Build Coastguard Worker }
1200*8b26181fSAndroid Build Coastguard Worker
1201*8b26181fSAndroid Build Coastguard Worker rxstreams--;
1202*8b26181fSAndroid Build Coastguard Worker if(rxstreams <= 0) {
1203*8b26181fSAndroid Build Coastguard Worker break;
1204*8b26181fSAndroid Build Coastguard Worker }
1205*8b26181fSAndroid Build Coastguard Worker }
1206*8b26181fSAndroid Build Coastguard Worker }
1207*8b26181fSAndroid Build Coastguard Worker dag_close(dagfd);
1208*8b26181fSAndroid Build Coastguard Worker }
1209*8b26181fSAndroid Build Coastguard Worker
1210*8b26181fSAndroid Build Coastguard Worker }
1211*8b26181fSAndroid Build Coastguard Worker return (0);
1212*8b26181fSAndroid Build Coastguard Worker }
1213*8b26181fSAndroid Build Coastguard Worker
1214*8b26181fSAndroid Build Coastguard Worker static int
dag_set_datalink(pcap_t * p,int dlt)1215*8b26181fSAndroid Build Coastguard Worker dag_set_datalink(pcap_t *p, int dlt)
1216*8b26181fSAndroid Build Coastguard Worker {
1217*8b26181fSAndroid Build Coastguard Worker p->linktype = dlt;
1218*8b26181fSAndroid Build Coastguard Worker
1219*8b26181fSAndroid Build Coastguard Worker return (0);
1220*8b26181fSAndroid Build Coastguard Worker }
1221*8b26181fSAndroid Build Coastguard Worker
1222*8b26181fSAndroid Build Coastguard Worker static int
dag_setnonblock(pcap_t * p,int nonblock)1223*8b26181fSAndroid Build Coastguard Worker dag_setnonblock(pcap_t *p, int nonblock)
1224*8b26181fSAndroid Build Coastguard Worker {
1225*8b26181fSAndroid Build Coastguard Worker struct pcap_dag *pd = p->priv;
1226*8b26181fSAndroid Build Coastguard Worker dag_size_t mindata;
1227*8b26181fSAndroid Build Coastguard Worker struct timeval maxwait;
1228*8b26181fSAndroid Build Coastguard Worker struct timeval poll;
1229*8b26181fSAndroid Build Coastguard Worker
1230*8b26181fSAndroid Build Coastguard Worker /*
1231*8b26181fSAndroid Build Coastguard Worker * Set non-blocking mode on the FD.
1232*8b26181fSAndroid Build Coastguard Worker * XXX - is that necessary? If not, don't bother calling it,
1233*8b26181fSAndroid Build Coastguard Worker * and have a "dag_getnonblock()" function that looks at
1234*8b26181fSAndroid Build Coastguard Worker * "pd->dag_flags".
1235*8b26181fSAndroid Build Coastguard Worker */
1236*8b26181fSAndroid Build Coastguard Worker if (pcap_setnonblock_fd(p, nonblock) < 0)
1237*8b26181fSAndroid Build Coastguard Worker return (-1);
1238*8b26181fSAndroid Build Coastguard Worker
1239*8b26181fSAndroid Build Coastguard Worker if (dag_get_stream_poll64(p->fd, pd->dag_stream,
1240*8b26181fSAndroid Build Coastguard Worker &mindata, &maxwait, &poll) < 0) {
1241*8b26181fSAndroid Build Coastguard Worker pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
1242*8b26181fSAndroid Build Coastguard Worker errno, "dag_get_stream_poll");
1243*8b26181fSAndroid Build Coastguard Worker return -1;
1244*8b26181fSAndroid Build Coastguard Worker }
1245*8b26181fSAndroid Build Coastguard Worker
1246*8b26181fSAndroid Build Coastguard Worker /* Amount of data to collect in Bytes before calling callbacks.
1247*8b26181fSAndroid Build Coastguard Worker * Important for efficiency, but can introduce latency
1248*8b26181fSAndroid Build Coastguard Worker * at low packet rates if to_ms not set!
1249*8b26181fSAndroid Build Coastguard Worker */
1250*8b26181fSAndroid Build Coastguard Worker if(nonblock)
1251*8b26181fSAndroid Build Coastguard Worker mindata = 0;
1252*8b26181fSAndroid Build Coastguard Worker else
1253*8b26181fSAndroid Build Coastguard Worker mindata = 65536;
1254*8b26181fSAndroid Build Coastguard Worker
1255*8b26181fSAndroid Build Coastguard Worker if (dag_set_stream_poll64(p->fd, pd->dag_stream,
1256*8b26181fSAndroid Build Coastguard Worker mindata, &maxwait, &poll) < 0) {
1257*8b26181fSAndroid Build Coastguard Worker pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
1258*8b26181fSAndroid Build Coastguard Worker errno, "dag_set_stream_poll");
1259*8b26181fSAndroid Build Coastguard Worker return -1;
1260*8b26181fSAndroid Build Coastguard Worker }
1261*8b26181fSAndroid Build Coastguard Worker
1262*8b26181fSAndroid Build Coastguard Worker if (nonblock) {
1263*8b26181fSAndroid Build Coastguard Worker pd->dag_flags |= DAGF_NONBLOCK;
1264*8b26181fSAndroid Build Coastguard Worker } else {
1265*8b26181fSAndroid Build Coastguard Worker pd->dag_flags &= ~DAGF_NONBLOCK;
1266*8b26181fSAndroid Build Coastguard Worker }
1267*8b26181fSAndroid Build Coastguard Worker return (0);
1268*8b26181fSAndroid Build Coastguard Worker }
1269*8b26181fSAndroid Build Coastguard Worker
1270*8b26181fSAndroid Build Coastguard Worker static int
dag_get_datalink(pcap_t * p)1271*8b26181fSAndroid Build Coastguard Worker dag_get_datalink(pcap_t *p)
1272*8b26181fSAndroid Build Coastguard Worker {
1273*8b26181fSAndroid Build Coastguard Worker struct pcap_dag *pd = p->priv;
1274*8b26181fSAndroid Build Coastguard Worker int index=0, dlt_index=0;
1275*8b26181fSAndroid Build Coastguard Worker uint8_t types[255];
1276*8b26181fSAndroid Build Coastguard Worker
1277*8b26181fSAndroid Build Coastguard Worker memset(types, 0, 255);
1278*8b26181fSAndroid Build Coastguard Worker
1279*8b26181fSAndroid Build Coastguard Worker if (p->dlt_list == NULL && (p->dlt_list = malloc(255*sizeof(*(p->dlt_list)))) == NULL) {
1280*8b26181fSAndroid Build Coastguard Worker pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
1281*8b26181fSAndroid Build Coastguard Worker errno, "malloc");
1282*8b26181fSAndroid Build Coastguard Worker return (-1);
1283*8b26181fSAndroid Build Coastguard Worker }
1284*8b26181fSAndroid Build Coastguard Worker
1285*8b26181fSAndroid Build Coastguard Worker p->linktype = 0;
1286*8b26181fSAndroid Build Coastguard Worker
1287*8b26181fSAndroid Build Coastguard Worker #ifdef HAVE_DAG_GET_STREAM_ERF_TYPES
1288*8b26181fSAndroid Build Coastguard Worker /* Get list of possible ERF types for this card */
1289*8b26181fSAndroid Build Coastguard Worker if (dag_get_stream_erf_types(p->fd, pd->dag_stream, types, 255) < 0) {
1290*8b26181fSAndroid Build Coastguard Worker pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
1291*8b26181fSAndroid Build Coastguard Worker errno, "dag_get_stream_erf_types");
1292*8b26181fSAndroid Build Coastguard Worker return (-1);
1293*8b26181fSAndroid Build Coastguard Worker }
1294*8b26181fSAndroid Build Coastguard Worker
1295*8b26181fSAndroid Build Coastguard Worker while (types[index]) {
1296*8b26181fSAndroid Build Coastguard Worker
1297*8b26181fSAndroid Build Coastguard Worker #elif defined HAVE_DAG_GET_ERF_TYPES
1298*8b26181fSAndroid Build Coastguard Worker /* Get list of possible ERF types for this card */
1299*8b26181fSAndroid Build Coastguard Worker if (dag_get_erf_types(p->fd, types, 255) < 0) {
1300*8b26181fSAndroid Build Coastguard Worker pcap_fmt_errmsg_for_errno(p->errbuf, sizeof(p->errbuf),
1301*8b26181fSAndroid Build Coastguard Worker errno, "dag_get_erf_types");
1302*8b26181fSAndroid Build Coastguard Worker return (-1);
1303*8b26181fSAndroid Build Coastguard Worker }
1304*8b26181fSAndroid Build Coastguard Worker
1305*8b26181fSAndroid Build Coastguard Worker while (types[index]) {
1306*8b26181fSAndroid Build Coastguard Worker #else
1307*8b26181fSAndroid Build Coastguard Worker /* Check the type through a dagapi call. */
1308*8b26181fSAndroid Build Coastguard Worker types[index] = dag_linktype(p->fd);
1309*8b26181fSAndroid Build Coastguard Worker
1310*8b26181fSAndroid Build Coastguard Worker {
1311*8b26181fSAndroid Build Coastguard Worker #endif
1312*8b26181fSAndroid Build Coastguard Worker switch((types[index] & 0x7f)) {
1313*8b26181fSAndroid Build Coastguard Worker
1314*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_HDLC_POS:
1315*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_COLOR_HDLC_POS:
1316*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_DSM_COLOR_HDLC_POS:
1317*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_COLOR_HASH_POS:
1318*8b26181fSAndroid Build Coastguard Worker
1319*8b26181fSAndroid Build Coastguard Worker if (p->dlt_list != NULL) {
1320*8b26181fSAndroid Build Coastguard Worker p->dlt_list[dlt_index++] = DLT_CHDLC;
1321*8b26181fSAndroid Build Coastguard Worker p->dlt_list[dlt_index++] = DLT_PPP_SERIAL;
1322*8b26181fSAndroid Build Coastguard Worker p->dlt_list[dlt_index++] = DLT_FRELAY;
1323*8b26181fSAndroid Build Coastguard Worker }
1324*8b26181fSAndroid Build Coastguard Worker if(!p->linktype)
1325*8b26181fSAndroid Build Coastguard Worker p->linktype = DLT_CHDLC;
1326*8b26181fSAndroid Build Coastguard Worker break;
1327*8b26181fSAndroid Build Coastguard Worker
1328*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_ETH:
1329*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_COLOR_ETH:
1330*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_DSM_COLOR_ETH:
1331*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_COLOR_HASH_ETH:
1332*8b26181fSAndroid Build Coastguard Worker /*
1333*8b26181fSAndroid Build Coastguard Worker * This is (presumably) a real Ethernet capture; give it a
1334*8b26181fSAndroid Build Coastguard Worker * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
1335*8b26181fSAndroid Build Coastguard Worker * that an application can let you choose it, in case you're
1336*8b26181fSAndroid Build Coastguard Worker * capturing DOCSIS traffic that a Cisco Cable Modem
1337*8b26181fSAndroid Build Coastguard Worker * Termination System is putting out onto an Ethernet (it
1338*8b26181fSAndroid Build Coastguard Worker * doesn't put an Ethernet header onto the wire, it puts raw
1339*8b26181fSAndroid Build Coastguard Worker * DOCSIS frames out on the wire inside the low-level
1340*8b26181fSAndroid Build Coastguard Worker * Ethernet framing).
1341*8b26181fSAndroid Build Coastguard Worker */
1342*8b26181fSAndroid Build Coastguard Worker if (p->dlt_list != NULL) {
1343*8b26181fSAndroid Build Coastguard Worker p->dlt_list[dlt_index++] = DLT_EN10MB;
1344*8b26181fSAndroid Build Coastguard Worker p->dlt_list[dlt_index++] = DLT_DOCSIS;
1345*8b26181fSAndroid Build Coastguard Worker }
1346*8b26181fSAndroid Build Coastguard Worker if(!p->linktype)
1347*8b26181fSAndroid Build Coastguard Worker p->linktype = DLT_EN10MB;
1348*8b26181fSAndroid Build Coastguard Worker break;
1349*8b26181fSAndroid Build Coastguard Worker
1350*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_ATM:
1351*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_AAL5:
1352*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_MC_ATM:
1353*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_MC_AAL5:
1354*8b26181fSAndroid Build Coastguard Worker if (p->dlt_list != NULL) {
1355*8b26181fSAndroid Build Coastguard Worker p->dlt_list[dlt_index++] = DLT_ATM_RFC1483;
1356*8b26181fSAndroid Build Coastguard Worker p->dlt_list[dlt_index++] = DLT_SUNATM;
1357*8b26181fSAndroid Build Coastguard Worker }
1358*8b26181fSAndroid Build Coastguard Worker if(!p->linktype)
1359*8b26181fSAndroid Build Coastguard Worker p->linktype = DLT_ATM_RFC1483;
1360*8b26181fSAndroid Build Coastguard Worker break;
1361*8b26181fSAndroid Build Coastguard Worker
1362*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_COLOR_MC_HDLC_POS:
1363*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_MC_HDLC:
1364*8b26181fSAndroid Build Coastguard Worker if (p->dlt_list != NULL) {
1365*8b26181fSAndroid Build Coastguard Worker p->dlt_list[dlt_index++] = DLT_CHDLC;
1366*8b26181fSAndroid Build Coastguard Worker p->dlt_list[dlt_index++] = DLT_PPP_SERIAL;
1367*8b26181fSAndroid Build Coastguard Worker p->dlt_list[dlt_index++] = DLT_FRELAY;
1368*8b26181fSAndroid Build Coastguard Worker p->dlt_list[dlt_index++] = DLT_MTP2;
1369*8b26181fSAndroid Build Coastguard Worker p->dlt_list[dlt_index++] = DLT_MTP2_WITH_PHDR;
1370*8b26181fSAndroid Build Coastguard Worker p->dlt_list[dlt_index++] = DLT_LAPD;
1371*8b26181fSAndroid Build Coastguard Worker }
1372*8b26181fSAndroid Build Coastguard Worker if(!p->linktype)
1373*8b26181fSAndroid Build Coastguard Worker p->linktype = DLT_CHDLC;
1374*8b26181fSAndroid Build Coastguard Worker break;
1375*8b26181fSAndroid Build Coastguard Worker
1376*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_IPV4:
1377*8b26181fSAndroid Build Coastguard Worker if (p->dlt_list != NULL) {
1378*8b26181fSAndroid Build Coastguard Worker p->dlt_list[dlt_index++] = DLT_RAW;
1379*8b26181fSAndroid Build Coastguard Worker p->dlt_list[dlt_index++] = DLT_IPV4;
1380*8b26181fSAndroid Build Coastguard Worker }
1381*8b26181fSAndroid Build Coastguard Worker if(!p->linktype)
1382*8b26181fSAndroid Build Coastguard Worker p->linktype = DLT_RAW;
1383*8b26181fSAndroid Build Coastguard Worker break;
1384*8b26181fSAndroid Build Coastguard Worker
1385*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_IPV6:
1386*8b26181fSAndroid Build Coastguard Worker if (p->dlt_list != NULL) {
1387*8b26181fSAndroid Build Coastguard Worker p->dlt_list[dlt_index++] = DLT_RAW;
1388*8b26181fSAndroid Build Coastguard Worker p->dlt_list[dlt_index++] = DLT_IPV6;
1389*8b26181fSAndroid Build Coastguard Worker }
1390*8b26181fSAndroid Build Coastguard Worker if(!p->linktype)
1391*8b26181fSAndroid Build Coastguard Worker p->linktype = DLT_RAW;
1392*8b26181fSAndroid Build Coastguard Worker break;
1393*8b26181fSAndroid Build Coastguard Worker
1394*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_LEGACY:
1395*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_MC_RAW:
1396*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_MC_RAW_CHANNEL:
1397*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_IP_COUNTER:
1398*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_TCP_FLOW_COUNTER:
1399*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_INFINIBAND:
1400*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_RAW_LINK:
1401*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_INFINIBAND_LINK:
1402*8b26181fSAndroid Build Coastguard Worker case ERF_TYPE_META:
1403*8b26181fSAndroid Build Coastguard Worker default:
1404*8b26181fSAndroid Build Coastguard Worker /* Libpcap cannot deal with these types yet */
1405*8b26181fSAndroid Build Coastguard Worker /* Add no 'native' DLTs, but still covered by DLT_ERF */
1406*8b26181fSAndroid Build Coastguard Worker break;
1407*8b26181fSAndroid Build Coastguard Worker
1408*8b26181fSAndroid Build Coastguard Worker } /* switch */
1409*8b26181fSAndroid Build Coastguard Worker index++;
1410*8b26181fSAndroid Build Coastguard Worker }
1411*8b26181fSAndroid Build Coastguard Worker
1412*8b26181fSAndroid Build Coastguard Worker p->dlt_list[dlt_index++] = DLT_ERF;
1413*8b26181fSAndroid Build Coastguard Worker
1414*8b26181fSAndroid Build Coastguard Worker p->dlt_count = dlt_index;
1415*8b26181fSAndroid Build Coastguard Worker
1416*8b26181fSAndroid Build Coastguard Worker if(!p->linktype)
1417*8b26181fSAndroid Build Coastguard Worker p->linktype = DLT_ERF;
1418*8b26181fSAndroid Build Coastguard Worker
1419*8b26181fSAndroid Build Coastguard Worker return p->linktype;
1420*8b26181fSAndroid Build Coastguard Worker }
1421*8b26181fSAndroid Build Coastguard Worker
1422*8b26181fSAndroid Build Coastguard Worker #ifdef DAG_ONLY
1423*8b26181fSAndroid Build Coastguard Worker /*
1424*8b26181fSAndroid Build Coastguard Worker * This libpcap build supports only DAG cards, not regular network
1425*8b26181fSAndroid Build Coastguard Worker * interfaces.
1426*8b26181fSAndroid Build Coastguard Worker */
1427*8b26181fSAndroid Build Coastguard Worker
1428*8b26181fSAndroid Build Coastguard Worker /*
1429*8b26181fSAndroid Build Coastguard Worker * There are no regular interfaces, just DAG interfaces.
1430*8b26181fSAndroid Build Coastguard Worker */
1431*8b26181fSAndroid Build Coastguard Worker int
1432*8b26181fSAndroid Build Coastguard Worker pcap_platform_finddevs(pcap_if_list_t *devlistp _U_, char *errbuf)
1433*8b26181fSAndroid Build Coastguard Worker {
1434*8b26181fSAndroid Build Coastguard Worker return (0);
1435*8b26181fSAndroid Build Coastguard Worker }
1436*8b26181fSAndroid Build Coastguard Worker
1437*8b26181fSAndroid Build Coastguard Worker /*
1438*8b26181fSAndroid Build Coastguard Worker * Attempts to open a regular interface fail.
1439*8b26181fSAndroid Build Coastguard Worker */
1440*8b26181fSAndroid Build Coastguard Worker pcap_t *
1441*8b26181fSAndroid Build Coastguard Worker pcap_create_interface(const char *device, char *errbuf)
1442*8b26181fSAndroid Build Coastguard Worker {
1443*8b26181fSAndroid Build Coastguard Worker snprintf(errbuf, PCAP_ERRBUF_SIZE,
1444*8b26181fSAndroid Build Coastguard Worker "This version of libpcap only supports DAG cards");
1445*8b26181fSAndroid Build Coastguard Worker return NULL;
1446*8b26181fSAndroid Build Coastguard Worker }
1447*8b26181fSAndroid Build Coastguard Worker
1448*8b26181fSAndroid Build Coastguard Worker /*
1449*8b26181fSAndroid Build Coastguard Worker * Libpcap version string.
1450*8b26181fSAndroid Build Coastguard Worker */
1451*8b26181fSAndroid Build Coastguard Worker const char *
1452*8b26181fSAndroid Build Coastguard Worker pcap_lib_version(void)
1453*8b26181fSAndroid Build Coastguard Worker {
1454*8b26181fSAndroid Build Coastguard Worker return (PCAP_VERSION_STRING " (DAG-only)");
1455*8b26181fSAndroid Build Coastguard Worker }
1456*8b26181fSAndroid Build Coastguard Worker #endif
1457