1478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
2478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * pcap-dag.c: Packet capture interface for Endace DAG card.
3478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
4478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The functionality of this code attempts to mimic that of pcap-linux as much
5478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * as possible.  This code is compiled in several different ways depending on
6478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * whether DAG_ONLY and HAVE_DAG_API are defined.  If HAVE_DAG_API is not
7478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * defined it should not get compiled in, otherwise if DAG_ONLY is defined then
8478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * the 'dag_' function calls are renamed to 'pcap_' equivalents.  If DAG_ONLY
9478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * is not defined then nothing is altered - the dag_ functions will be
10478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * called as required from their pcap-linux/bpf equivalents.
11478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
12478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Authors: Richard Littin, Sean Irvine ({richard,sean}@reeltwo.com)
13478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Modifications: Jesper Peterson  <support@endace.com>
14478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *                Koryn Grant      <support@endace.com>
15478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *                Stephen Donnelly <support@endace.com>
16478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
17478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
18478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef lint
19478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic const char rcsid[] _U_ =
20478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	"@(#) $Header: /tcpdump/master/libpcap/pcap-dag.c,v 1.21.2.7 2007/06/22 06:43:58 guy Exp $ (LBL)";
21478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
22478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
23478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_CONFIG_H
24478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "config.h"
25478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
26478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
27478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/param.h>			/* optionally get BSD define */
28478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
29478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdlib.h>
30478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <string.h>
31478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <errno.h>
32478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
33478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "pcap-int.h"
34478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
35478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <ctype.h>
36478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <netinet/in.h>
37478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/mman.h>
38478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/socket.h>
39478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <sys/types.h>
40478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <unistd.h>
41478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
42478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct mbuf;		/* Squelch compiler warnings on some platforms for */
43478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct rtentry;		/* declarations in <net/if.h> */
44478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/if.h>
45478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
46478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "dagnew.h"
47478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "dagapi.h"
48478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
49478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define ATM_CELL_SIZE		52
50478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define ATM_HDR_SIZE		4
51478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
52478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
53478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * A header containing additional MTP information.
54478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
55478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define MTP2_SENT_OFFSET		0	/* 1 byte */
56478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define MTP2_ANNEX_A_USED_OFFSET	1	/* 1 byte */
57478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define MTP2_LINK_NUMBER_OFFSET		2	/* 2 bytes */
58478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define MTP2_HDR_LEN			4	/* length of the header */
59478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
60478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define MTP2_ANNEX_A_NOT_USED      0
61478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define MTP2_ANNEX_A_USED          1
62478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define MTP2_ANNEX_A_USED_UNKNOWN  2
63478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
64478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* SunATM pseudo header */
65478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct sunatm_hdr {
66478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	unsigned char	flags;		/* destination and traffic type */
67478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	unsigned char	vpi;		/* VPI */
68478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	unsigned short	vci;		/* VCI */
69478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project};
70478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
71478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projecttypedef struct pcap_dag_node {
72478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct pcap_dag_node *next;
73478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	pcap_t *p;
74478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	pid_t pid;
75478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project} pcap_dag_node_t;
76478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
77478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic pcap_dag_node_t *pcap_dags = NULL;
78478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int atexit_handler_installed = 0;
79478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic const unsigned short endian_test_word = 0x0100;
80478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
81478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define IS_BIGENDIAN() (*((unsigned char *)&endian_test_word))
82478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
83478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
84478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef DAG_ONLY
85478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* This code is required when compiling for a DAG device only. */
86478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "pcap-dag.h"
87478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
88478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* Replace dag function names with pcap equivalent. */
89478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define dag_open_live pcap_open_live
90478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define dag_platform_finddevs pcap_platform_finddevs
91478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* DAG_ONLY */
92478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
93478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define MAX_DAG_PACKET 65536
94478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
95478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic unsigned char TempPkt[MAX_DAG_PACKET];
96478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
97478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int dag_setfilter(pcap_t *p, struct bpf_program *fp);
98478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int dag_stats(pcap_t *p, struct pcap_stat *ps);
99478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int dag_set_datalink(pcap_t *p, int dlt);
100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int dag_get_datalink(pcap_t *p);
101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int dag_setnonblock(pcap_t *p, int nonblock, char *errbuf);
102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void
104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectdelete_pcap_dag(pcap_t *p)
105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	pcap_dag_node_t *curr = NULL, *prev = NULL;
107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	for (prev = NULL, curr = pcap_dags; curr != NULL && curr->p != p; prev = curr, curr = curr->next) {
109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* empty */
110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (curr != NULL && curr->p == p) {
113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (prev != NULL) {
114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			prev->next = curr->next;
115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		} else {
116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			pcap_dags = curr->next;
117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Performs a graceful shutdown of the DAG card, frees dynamic memory held
123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * in the pcap_t structure, and closes the file descriptor for the DAG card.
124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void
127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectdag_platform_close(pcap_t *p)
128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (p != NULL) {
131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_DAG_STREAMS_API
132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if(dag_stop_stream(p->fd, p->md.dag_stream) < 0)
133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if(dag_detach_stream(p->fd, p->md.dag_stream) < 0)
136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else
138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if(dag_stop(p->fd) < 0)
139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			fprintf(stderr,"dag_stop: %s\n", strerror(errno));
140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_DAG_STREAMS_API */
141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if(dag_close(p->fd) < 0)
142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			fprintf(stderr,"dag_close: %s\n", strerror(errno));
143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	delete_pcap_dag(p);
145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Note: don't need to call close(p->fd) here as dag_close(p->fd) does this. */
146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void
149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectatexit_handler(void)
150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	while (pcap_dags != NULL) {
152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (pcap_dags->pid == getpid()) {
153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			dag_platform_close(pcap_dags->p);
154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		} else {
155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			delete_pcap_dag(pcap_dags->p);
156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectnew_pcap_dag(pcap_t *p)
162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	pcap_dag_node_t *node = NULL;
164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if ((node = malloc(sizeof(pcap_dag_node_t))) == NULL) {
166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return -1;
167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (!atexit_handler_installed) {
170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		atexit(atexit_handler);
171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		atexit_handler_installed = 1;
172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	node->next = pcap_dags;
175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	node->p = p;
176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	node->pid = getpid();
177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	pcap_dags = node;
179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return 0;
181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *  Read at most max_packets from the capture stream and call the callback
185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *  for each of them. Returns the number of packets handled, -1 if an
186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *  error occured, or -2 if we were told to break out of the loop.
187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectdag_read(pcap_t *p, int cnt, pcap_handler callback, u_char *user)
190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	unsigned int processed = 0;
192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int flags = p->md.dag_offset_flags;
193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	unsigned int nonblocking = flags & DAGF_NONBLOCK;
194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Get the next bufferful of packets (if necessary). */
196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	while (p->md.dag_mem_top - p->md.dag_mem_bottom < dag_record_size) {
197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Has "pcap_breakloop()" been called?
200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (p->break_loop) {
202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Yes - clear the flag that indicates that
204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * it has, and return -2 to indicate that
205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * we were told to break out of the loop.
206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			p->break_loop = 0;
208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return -2;
209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_DAG_STREAMS_API
212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* dag_advance_stream() will block (unless nonblock is called)
213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * until 64kB of data has accumulated.
214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * If to_ms is set, it will timeout before 64kB has accumulated.
215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * We wait for 64kB because processing a few packets at a time
216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * can cause problems at high packet rates (>200kpps) due
217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * to inefficiencies.
218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * This does mean if to_ms is not specified the capture may 'hang'
219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * for long periods if the data rate is extremely slow (<64kB/sec)
220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * If non-block is specified it will return immediately. The user
221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * is then responsible for efficiency.
222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->md.dag_mem_top = dag_advance_stream(p->fd, p->md.dag_stream, &(p->md.dag_mem_bottom));
224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else
225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* dag_offset does not support timeouts */
226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->md.dag_mem_top = dag_offset(p->fd, &(p->md.dag_mem_bottom), flags);
227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_DAG_STREAMS_API */
228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (nonblocking && (p->md.dag_mem_top - p->md.dag_mem_bottom < dag_record_size))
230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* Pcap is configured to process only available packets, and there aren't any, return immediately. */
232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return 0;
233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if(!nonblocking &&
236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		   p->md.dag_timeout &&
237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		   (p->md.dag_mem_top - p->md.dag_mem_bottom < dag_record_size))
238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* Blocking mode, but timeout set and no data has arrived, return anyway.*/
240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return 0;
241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Process the packets. */
246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	while (p->md.dag_mem_top - p->md.dag_mem_bottom >= dag_record_size) {
247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		unsigned short packet_len = 0;
249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		int caplen = 0;
250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		struct pcap_pkthdr	pcap_header;
251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_DAG_STREAMS_API
253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		dag_record_t *header = (dag_record_t *)(p->md.dag_mem_bottom);
254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else
255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		dag_record_t *header = (dag_record_t *)(p->md.dag_mem_base + p->md.dag_mem_bottom);
256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_DAG_STREAMS_API */
257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		u_char *dp = ((u_char *)header) + dag_record_size;
259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		unsigned short rlen;
260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Has "pcap_breakloop()" been called?
263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (p->break_loop) {
265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Yes - clear the flag that indicates that
267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * it has, and return -2 to indicate that
268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * we were told to break out of the loop.
269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			p->break_loop = 0;
271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return -2;
272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		rlen = ntohs(header->rlen);
275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (rlen < dag_record_size)
276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			strncpy(p->errbuf, "dag_read: record too small", PCAP_ERRBUF_SIZE);
278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return -1;
279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->md.dag_mem_bottom += rlen;
281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		switch(header->type) {
283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_ATM:
284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef TYPE_AAL5
285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_AAL5:
286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (header->type == TYPE_AAL5) {
287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				packet_len = ntohs(header->wlen);
288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				caplen = rlen - dag_record_size;
289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef TYPE_MC_ATM
292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_MC_ATM:
293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (header->type == TYPE_MC_ATM) {
294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				caplen = packet_len = ATM_CELL_SIZE;
295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				dp+=4;
296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef TYPE_MC_AAL5
299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_MC_AAL5:
300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (header->type == TYPE_MC_AAL5) {
301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				packet_len = ntohs(header->wlen);
302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				caplen = rlen - dag_record_size - 4;
303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				dp+=4;
304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (header->type == TYPE_ATM) {
307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				caplen = packet_len = ATM_CELL_SIZE;
308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (p->linktype == DLT_SUNATM) {
310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				struct sunatm_hdr *sunatm = (struct sunatm_hdr *)dp;
311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				unsigned long rawatm;
312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				rawatm = ntohl(*((unsigned long *)dp));
314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				sunatm->vci = htons((rawatm >>  4) & 0xffff);
315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				sunatm->vpi = (rawatm >> 20) & 0x00ff;
316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				sunatm->flags = ((header->flags.iface & 1) ? 0x80 : 0x00) |
317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					((sunatm->vpi == 0 && sunatm->vci == htons(5)) ? 6 :
318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					 ((sunatm->vpi == 0 && sunatm->vci == htons(16)) ? 5 :
319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					  ((dp[ATM_HDR_SIZE] == 0xaa &&
320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					    dp[ATM_HDR_SIZE+1] == 0xaa &&
321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					    dp[ATM_HDR_SIZE+2] == 0x03) ? 2 : 1)));
322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			} else {
324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				packet_len -= ATM_HDR_SIZE;
325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				caplen -= ATM_HDR_SIZE;
326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				dp += ATM_HDR_SIZE;
327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef TYPE_DSM_COLOR_ETH
331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_DSM_COLOR_ETH:
332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef TYPE_COLOR_ETH
334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_COLOR_ETH:
335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_ETH:
337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			packet_len = ntohs(header->wlen);
338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			packet_len -= (p->md.dag_fcs_bits >> 3);
339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			caplen = rlen - dag_record_size - 2;
340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (caplen > packet_len) {
341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				caplen = packet_len;
342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			dp += 2;
344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef TYPE_DSM_COLOR_HDLC_POS
346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_DSM_COLOR_HDLC_POS:
347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef TYPE_COLOR_HDLC_POS
349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_COLOR_HDLC_POS:
350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_HDLC_POS:
352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			packet_len = ntohs(header->wlen);
353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			packet_len -= (p->md.dag_fcs_bits >> 3);
354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			caplen = rlen - dag_record_size;
355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (caplen > packet_len) {
356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				caplen = packet_len;
357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef TYPE_COLOR_MC_HDLC_POS
360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_COLOR_MC_HDLC_POS:
361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef TYPE_MC_HDLC
363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_MC_HDLC:
364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			packet_len = ntohs(header->wlen);
365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			packet_len -= (p->md.dag_fcs_bits >> 3);
366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			caplen = rlen - dag_record_size - 4;
367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (caplen > packet_len) {
368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				caplen = packet_len;
369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
370478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* jump the MC_HDLC_HEADER */
371478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			dp += 4;
372478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (p->linktype == DLT_MTP2_WITH_PHDR) {
373478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				/* Add the MTP2 Pseudo Header */
374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				caplen += MTP2_HDR_LEN;
375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				packet_len += MTP2_HDR_LEN;
376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				TempPkt[MTP2_SENT_OFFSET] = 0;
378478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				TempPkt[MTP2_ANNEX_A_USED_OFFSET] = MTP2_ANNEX_A_USED_UNKNOWN;
379478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				*(TempPkt+MTP2_LINK_NUMBER_OFFSET) = ((header->rec.mc_hdlc.mc_header>>16)&0x01);
380478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				*(TempPkt+MTP2_LINK_NUMBER_OFFSET+1) = ((header->rec.mc_hdlc.mc_header>>24)&0xff);
381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				memcpy(TempPkt+MTP2_HDR_LEN, dp, caplen);
382478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				dp = TempPkt;
383478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
385478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
386478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		default:
387478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* Unhandled ERF type.
388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Ignore rather than generating error
389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			continue;
391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (caplen > p->snapshot)
394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			caplen = p->snapshot;
395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Count lost packets. */
397478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		switch(header->type) {
398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef TYPE_COLOR_HDLC_POS
399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* in this type the color value overwrites the lctr */
400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_COLOR_HDLC_POS:
401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
402478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
403478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef TYPE_COLOR_ETH
404478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* in this type the color value overwrites the lctr */
405478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_COLOR_ETH:
406478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
407478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
408478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef TYPE_DSM_COLOR_HDLC_POS
409478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* in this type the color value overwrites the lctr */
410478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_DSM_COLOR_HDLC_POS:
411478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
412478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
413478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef TYPE_DSM_COLOR_ETH
414478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* in this type the color value overwrites the lctr */
415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_DSM_COLOR_ETH:
416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
418478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef TYPE_COLOR_MC_HDLC_POS
419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_COLOR_MC_HDLC_POS:
420478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
421478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
422478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		default:
424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (header->lctr) {
425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				if (p->md.stat.ps_drop > (UINT_MAX - ntohs(header->lctr))) {
426478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					p->md.stat.ps_drop = UINT_MAX;
427478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				} else {
428478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					p->md.stat.ps_drop += ntohs(header->lctr);
429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				}
430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
431478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Run the packet filter if there is one. */
434478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if ((p->fcode.bf_insns == NULL) || bpf_filter(p->fcode.bf_insns, dp, packet_len, caplen)) {
435478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
436478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* convert between timestamp formats */
437478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			register unsigned long long ts;
438478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
439478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (IS_BIGENDIAN()) {
440478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				ts = SWAPLL(header->ts);
441478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			} else {
442478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				ts = header->ts;
443478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
444478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			pcap_header.ts.tv_sec = ts >> 32;
446478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			ts = (ts & 0xffffffffULL) * 1000000;
447478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			ts += 0x80000000; /* rounding */
448478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			pcap_header.ts.tv_usec = ts >> 32;
449478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (pcap_header.ts.tv_usec >= 1000000) {
450478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				pcap_header.ts.tv_usec -= 1000000;
451478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				pcap_header.ts.tv_sec++;
452478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
453478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
454478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* Fill in our own header data */
455478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			pcap_header.caplen = caplen;
456478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			pcap_header.len = packet_len;
457478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
458478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* Count the packet. */
459478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			p->md.stat.ps_recv++;
460478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
461478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* Call the user supplied callback function */
462478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			callback(user, &pcap_header, dp);
463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/* Only count packets that pass the filter, for consistency with standard Linux behaviour. */
465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			processed++;
466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (processed == cnt)
467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			{
468478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				/* Reached the user-specified limit. */
469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				return cnt;
470478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
472478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
473478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
474478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return processed;
475478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
476478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
477478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectdag_inject(pcap_t *p, const void *buf _U_, size_t size _U_)
479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	strlcpy(p->errbuf, "Sending packets isn't supported on DAG cards",
481478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	    PCAP_ERRBUF_SIZE);
482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (-1);
483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *  Get a handle for a live capture from the given DAG device.  Passing a NULL
487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *  device will result in a failure.  The promisc flag is ignored because DAG
488478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *  cards are always promiscuous.  The to_ms parameter is also ignored as it is
489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *  not supported in hardware.
490478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
491478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *  snaplen is now also ignored, until we get per-stream slen support. Set
492478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *  slen with approprite DAG tool BEFORE pcap_open_live().
493478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *  See also pcap(3).
495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_t *
497478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectdag_open_live(const char *device, int snaplen, int promisc, int to_ms, char *ebuf)
498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	char conf[30]; /* dag configure string */
500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	pcap_t *handle;
501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	char *s;
502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int n;
503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	daginf_t* daginf;
504478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	char * newDev = NULL;
505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_DAG_STREAMS_API
506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	uint32_t mindata;
507478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct timeval maxwait;
508478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	struct timeval poll;
509478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
510478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
511478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (device == NULL) {
512478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(ebuf, PCAP_ERRBUF_SIZE, "device is NULL: %s", pcap_strerror(errno));
513478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return NULL;
514478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
515478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Allocate a handle for this session. */
516478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
517478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	handle = malloc(sizeof(*handle));
518478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (handle == NULL) {
519478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(ebuf, PCAP_ERRBUF_SIZE, "malloc %s: %s", device, pcap_strerror(errno));
520478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return NULL;
521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
522478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
523478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Initialize some components of the pcap structure. */
524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	memset(handle, 0, sizeof(*handle));
526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_DAG_STREAMS_API
528478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	newDev = (char *)malloc(strlen(device) + 16);
529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (newDev == NULL) {
530478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(ebuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s\n", pcap_strerror(errno));
531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		goto fail;
532478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Parse input name to get dag device and stream number if provided */
535478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (dag_parse_name(device, newDev, strlen(device) + 16, &handle->md.dag_stream) < 0) {
536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_parse_name: %s\n", pcap_strerror(errno));
537478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		goto fail;
538478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	device = newDev;
540478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
541478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (handle->md.dag_stream%2) {
542478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_parse_name: tx (even numbered) streams not supported for capture\n");
543478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		goto fail;
544478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else
546478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (strncmp(device, "/dev/", 5) != 0) {
547478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		newDev = (char *)malloc(strlen(device) + 5);
548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (newDev == NULL) {
549478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			snprintf(ebuf, PCAP_ERRBUF_SIZE, "Can't allocate string for device name: %s\n", pcap_strerror(errno));
550478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			goto fail;
551478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
552478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		strcpy(newDev, "/dev/");
553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		strcat(newDev, device);
554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		device = newDev;
555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
556478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_DAG_STREAMS_API */
557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
558478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* setup device parameters */
559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if((handle->fd = dag_open((char *)device)) < 0) {
560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_open %s: %s", device, pcap_strerror(errno));
561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		goto fail;
562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
563478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_DAG_STREAMS_API
565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Open requested stream. Can fail if already locked or on error */
566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (dag_attach_stream(handle->fd, handle->md.dag_stream, 0, 0) < 0) {
567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_attach_stream: %s\n", pcap_strerror(errno));
568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		goto failclose;
569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Set up default poll parameters for stream
572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Can be overridden by pcap_set_nonblock()
573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (dag_get_stream_poll(handle->fd, handle->md.dag_stream,
575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				&mindata, &maxwait, &poll) < 0) {
576478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s\n", pcap_strerror(errno));
577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		goto faildetach;
578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
580478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Amount of data to collect in Bytes before calling callbacks.
581478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Important for efficiency, but can introduce latency
582478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * at low packet rates if to_ms not set!
583478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
584478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	mindata = 65536;
585478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Obey to_ms if supplied. This is a good idea!
587478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Recommend 10-100ms. Calls will time out even if no data arrived.
588478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
589478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	maxwait.tv_sec = to_ms/1000;
590478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	maxwait.tv_usec = (to_ms%1000) * 1000;
591478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
592478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (dag_set_stream_poll(handle->fd, handle->md.dag_stream,
593478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				mindata, &maxwait, &poll) < 0) {
594478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s\n", pcap_strerror(errno));
595478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		goto faildetach;
596478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
598478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else
599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if((handle->md.dag_mem_base = dag_mmap(handle->fd)) == MAP_FAILED) {
600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(ebuf, PCAP_ERRBUF_SIZE,"dag_mmap %s: %s\n", device, pcap_strerror(errno));
601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		goto failclose;
602478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_DAG_STREAMS_API */
605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        /* XXX Not calling dag_configure() to set slen; this is unsafe in
607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * multi-stream environments as the gpp config is global.
608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project         * Once the firmware provides 'per-stream slen' this can be supported
609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * again via the Config API without side-effects */
610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if 0
611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* set the card snap length to the specified snaplen parameter */
612478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* This is a really bad idea, as different cards have different
613478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * valid slen ranges. Should fix in Config API. */
614478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (snaplen == 0 || snaplen > MAX_DAG_SNAPLEN) {
615478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snaplen = MAX_DAG_SNAPLEN;
616478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	} else if (snaplen < MIN_DAG_SNAPLEN) {
617478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snaplen = MIN_DAG_SNAPLEN;
618478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
619478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* snap len has to be a multiple of 4 */
620478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	snprintf(conf, 30, "varlen slen=%d", (snaplen + 3) & ~3);
621478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
622478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if(dag_configure(handle->fd, conf) < 0) {
623478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(ebuf, PCAP_ERRBUF_SIZE,"dag_configure %s: %s\n", device, pcap_strerror(errno));
624478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		goto faildetach;
625478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
626478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
627478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
628478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_DAG_STREAMS_API
629478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if(dag_start_stream(handle->fd, handle->md.dag_stream) < 0) {
630478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_start_stream %s: %s\n", device, pcap_strerror(errno));
631478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		goto faildetach;
632478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
633478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else
634478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if(dag_start(handle->fd) < 0) {
635478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(ebuf, PCAP_ERRBUF_SIZE, "dag_start %s: %s\n", device, pcap_strerror(errno));
636478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		goto failclose;
637478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
638478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_DAG_STREAMS_API */
639478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
640478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
641478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Important! You have to ensure bottom is properly
642478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * initialized to zero on startup, it won't give you
643478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * a compiler warning if you make this mistake!
644478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
645478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	handle->md.dag_mem_bottom = 0;
646478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	handle->md.dag_mem_top = 0;
647478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	handle->md.dag_fcs_bits = 32;
648478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
649478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Query the card first for special cases. */
650478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	daginf = dag_info(handle->fd);
651478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if ((0x4200 == daginf->device_code) || (0x4230 == daginf->device_code))
652478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
653478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* DAG 4.2S and 4.23S already strip the FCS.  Stripping the final word again truncates the packet. */
654478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		handle->md.dag_fcs_bits = 0;
655478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
657478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Then allow an environment variable to override. */
658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if ((s = getenv("ERF_FCS_BITS")) != NULL) {
659478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if ((n = atoi(s)) == 0 || n == 16|| n == 32) {
660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			handle->md.dag_fcs_bits = n;
661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		} else {
662478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			snprintf(ebuf, PCAP_ERRBUF_SIZE,
663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				"pcap_open_live %s: bad ERF_FCS_BITS value (%d) in environment\n", device, n);
664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			goto failstop;
665478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
667478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
668478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	handle->snapshot	= snaplen;
669478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	handle->md.dag_timeout	= to_ms;
670478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
671478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	handle->linktype = -1;
672478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (dag_get_datalink(handle) < 0) {
673478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		strcpy(ebuf, handle->errbuf);
674478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		goto failstop;
675478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
676478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
677478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	handle->bufsize = 0;
678478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
679478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (new_pcap_dag(handle) < 0) {
680478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(ebuf, PCAP_ERRBUF_SIZE, "new_pcap_dag %s: %s\n", device, pcap_strerror(errno));
681478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		goto failstop;
682478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
683478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
684478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
685478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * "select()" and "poll()" don't work on DAG device descriptors.
686478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	handle->selectable_fd = -1;
688478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (newDev != NULL) {
690478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		free((char *)newDev);
691478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
692478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
693478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	handle->read_op = dag_read;
694478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	handle->inject_op = dag_inject;
695478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	handle->setfilter_op = dag_setfilter;
696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	handle->setdirection_op = NULL; /* Not implemented.*/
697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	handle->set_datalink_op = dag_set_datalink;
698478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	handle->getnonblock_op = pcap_getnonblock_fd;
699478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	handle->setnonblock_op = dag_setnonblock;
700478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	handle->stats_op = dag_stats;
701478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	handle->close_op = dag_platform_close;
702478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	handle->md.stat.ps_drop = 0;
703478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	handle->md.stat.ps_recv = 0;
704478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return handle;
705478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
706478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_DAG_STREAMS_API
707478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectfailstop:
708478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (handle != NULL) {
709478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (dag_stop_stream(handle->fd, handle->md.dag_stream) < 0)
710478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			fprintf(stderr,"dag_stop_stream: %s\n", strerror(errno));
711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectfaildetach:
714478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (handle != NULL) {
715478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (dag_detach_stream(handle->fd, handle->md.dag_stream) < 0)
716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			fprintf(stderr,"dag_detach_stream: %s\n", strerror(errno));
717478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
718478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else
719478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectfailstop:
720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (handle != NULL) {
721478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (dag_stop(p->fd) < 0)
722478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			fprintf(stderr,"dag_stop: %s\n", strerror(errno));
723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
724478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_DAG_STREAMS_API */
725478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
726478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectfailclose:
727478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (handle != NULL) {
728478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (dag_close(handle->fd) < 0)
729478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			fprintf(stderr,"dag_close: %s\n", strerror(errno));
730478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
731478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (handle != NULL)
732478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		delete_pcap_dag(handle);
733478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
734478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectfail:
735478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (newDev != NULL) {
736478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		free((char *)newDev);
737478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
738478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (handle != NULL) {
739478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/*
740478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Get rid of any link-layer type list we allocated.
741478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
742478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (handle->dlt_list != NULL) {
743478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			free(handle->dlt_list);
744478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
745478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		free(handle);
746478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
747478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
748478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return NULL;
749478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
750478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
751478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
752478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectdag_stats(pcap_t *p, struct pcap_stat *ps) {
753478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* This needs to be filled out correctly.  Hopefully a dagapi call will
754478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 provide all necessary information.
755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	*/
756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*p->md.stat.ps_recv = 0;*/
757478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*p->md.stat.ps_drop = 0;*/
758478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
759478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	*ps = p->md.stat;
760478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
761478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return 0;
762478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
763478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
764478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
765478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Simply submit all possible dag names as candidates.
766478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * pcap_add_if() internally tests each candidate with pcap_open_live(),
767478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * so any non-existent devices are dropped.
768478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For 2.5 try all rx stream names as well.
769478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
770478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint
771478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectdag_platform_finddevs(pcap_if_t **devlistp, char *errbuf)
772478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
773478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	char name[12];	/* XXX - pick a size */
774478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int ret = 0;
775478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int c;
776478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
777478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Try all the DAGs 0-9 */
778478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	for (c = 0; c < 9; c++) {
779478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(name, 12, "dag%d", c);
780478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (pcap_add_if(devlistp, name, 0, NULL, errbuf) == -1) {
781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
782478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Failure.
783478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
784478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			ret = -1;
785478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
786478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_DAG_STREAMS_API
787478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		{
788478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			int stream;
789478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			for(stream=0;stream<16;stream+=2) {
790478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				snprintf(name,  10, "dag%d:%d", c, stream);
791478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				if (pcap_add_if(devlistp, name, 0, NULL, errbuf) == -1) {
792478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					/*
793478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					 * Failure.
794478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					 */
795478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					ret = -1;
796478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				}
797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
798478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
799478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif  /* HAVE_DAG_STREAMS_API */
800478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
801478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (ret);
802478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
803478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
804478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
805478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Installs the given bpf filter program in the given pcap structure.  There is
806478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * no attempt to store the filter in kernel memory as that is not supported
807478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * with DAG cards.
808478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
809478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
810478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectdag_setfilter(pcap_t *p, struct bpf_program *fp)
811478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
812478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (!p)
813478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return -1;
814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (!fp) {
815478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		strncpy(p->errbuf, "setfilter: No filter specified",
816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			sizeof(p->errbuf));
817478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return -1;
818478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
819478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
820478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Make our private copy of the filter */
821478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
822478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (install_bpf_program(p, fp) < 0)
823478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return -1;
824478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
825478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->md.use_bpf = 0;
826478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
827478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (0);
828478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
829478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
830478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
831478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectdag_set_datalink(pcap_t *p, int dlt)
832478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
833478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->linktype = dlt;
834478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
835478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (0);
836478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
837478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
838478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
839478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectdag_setnonblock(pcap_t *p, int nonblock, char *errbuf)
840478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
841478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/*
842478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * Set non-blocking mode on the FD.
843478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * XXX - is that necessary?  If not, don't bother calling it,
844478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * and have a "dag_getnonblock()" function that looks at
845478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 * "p->md.dag_offset_flags".
846478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	 */
847478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (pcap_setnonblock_fd(p, nonblock, errbuf) < 0)
848478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return (-1);
849478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_DAG_STREAMS_API
850478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
851478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		uint32_t mindata;
852478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		struct timeval maxwait;
853478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		struct timeval poll;
854478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
855478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (dag_get_stream_poll(p->fd, p->md.dag_stream,
856478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					&mindata, &maxwait, &poll) < 0) {
857478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_get_stream_poll: %s\n", pcap_strerror(errno));
858478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return -1;
859478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
860478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
861478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		/* Amount of data to collect in Bytes before calling callbacks.
862478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * Important for efficiency, but can introduce latency
863478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 * at low packet rates if to_ms not set!
864478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		 */
865478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if(nonblock)
866478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			mindata = 0;
867478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		else
868478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			mindata = 65536;
869478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
870478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		if (dag_set_stream_poll(p->fd, p->md.dag_stream,
871478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project					mindata, &maxwait, &poll) < 0) {
872478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			snprintf(errbuf, PCAP_ERRBUF_SIZE, "dag_set_stream_poll: %s\n", pcap_strerror(errno));
873478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return -1;
874478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		}
875478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
876478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* HAVE_DAG_STREAMS_API */
877478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (nonblock) {
878478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->md.dag_offset_flags |= DAGF_NONBLOCK;
879478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	} else {
880478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		p->md.dag_offset_flags &= ~DAGF_NONBLOCK;
881478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
882478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return (0);
883478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
884478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
885478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
886478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectdag_get_datalink(pcap_t *p)
887478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
888478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	int index=0;
889478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	uint8_t types[255];
890478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
891478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	memset(types, 0, 255);
892478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (p->dlt_list == NULL && (p->dlt_list = malloc(255*sizeof(*(p->dlt_list)))) == NULL) {
894478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		(void)snprintf(p->errbuf, sizeof(p->errbuf), "malloc: %s", pcap_strerror(errno));
895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return (-1);
896478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
897478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
898478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->linktype = 0;
899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
900478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef HAVE_DAG_GET_ERF_TYPES
901478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Get list of possible ERF types for this card */
902478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	if (dag_get_erf_types(p->fd, types, 255) < 0) {
903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		snprintf(p->errbuf, sizeof(p->errbuf), "dag_get_erf_types: %s", pcap_strerror(errno));
904478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		return (-1);
905478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
906478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
907478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	while (types[index]) {
908478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else
909478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	/* Check the type through a dagapi call. */
910478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	types[index] = dag_linktype(p->fd);
911478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
912478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	{
913478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
914478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		switch(types[index]) {
915478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
916478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_HDLC_POS:
917478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef TYPE_COLOR_HDLC_POS
918478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_COLOR_HDLC_POS:
919478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
920478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef TYPE_DSM_COLOR_HDLC_POS
921478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_DSM_COLOR_HDLC_POS:
922478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
923478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (p->dlt_list != NULL) {
924478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->dlt_list[index++] = DLT_CHDLC;
925478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->dlt_list[index++] = DLT_PPP_SERIAL;
926478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->dlt_list[index++] = DLT_FRELAY;
927478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
928478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if(!p->linktype)
929478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->linktype = DLT_CHDLC;
930478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
931478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
932478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_ETH:
933478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef TYPE_COLOR_ETH
934478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_COLOR_ETH:
935478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
936478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef TYPE_DSM_COLOR_ETH
937478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_DSM_COLOR_ETH:
938478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
939478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			/*
940478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * This is (presumably) a real Ethernet capture; give it a
941478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * link-layer-type list with DLT_EN10MB and DLT_DOCSIS, so
942478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * that an application can let you choose it, in case you're
943478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * capturing DOCSIS traffic that a Cisco Cable Modem
944478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Termination System is putting out onto an Ethernet (it
945478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * doesn't put an Ethernet header onto the wire, it puts raw
946478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * DOCSIS frames out on the wire inside the low-level
947478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 * Ethernet framing).
948478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			 */
949478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (p->dlt_list != NULL) {
950478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->dlt_list[index++] = DLT_EN10MB;
951478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->dlt_list[index++] = DLT_DOCSIS;
952478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
953478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if(!p->linktype)
954478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->linktype = DLT_EN10MB;
955478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
956478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
957478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_ATM:
958478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef TYPE_AAL5
959478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_AAL5:
960478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
961478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef TYPE_MC_ATM
962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_MC_ATM:
963478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef TYPE_MC_AAL5
965478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_MC_AAL5:
966478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
967478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (p->dlt_list != NULL) {
968478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->dlt_list[index++] = DLT_ATM_RFC1483;
969478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->dlt_list[index++] = DLT_SUNATM;
970478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
971478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if(!p->linktype)
972478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->linktype = DLT_ATM_RFC1483;
973478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
974478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
975478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef TYPE_COLOR_MC_HDLC_POS
976478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_COLOR_MC_HDLC_POS:
977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
978478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef TYPE_MC_HDLC
979478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_MC_HDLC:
980478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if (p->dlt_list != NULL) {
981478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->dlt_list[index++] = DLT_CHDLC;
982478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->dlt_list[index++] = DLT_PPP_SERIAL;
983478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->dlt_list[index++] = DLT_FRELAY;
984478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->dlt_list[index++] = DLT_MTP2;
985478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->dlt_list[index++] = DLT_MTP2_WITH_PHDR;
986478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			}
987478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if(!p->linktype)
988478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->linktype = DLT_CHDLC;
989478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
990478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
991478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
992478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		case TYPE_LEGACY:
993478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			if(!p->linktype)
994478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project				p->linktype = DLT_NULL;
995478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			break;
996478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
997478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		default:
998478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			snprintf(p->errbuf, sizeof(p->errbuf), "unknown DAG linktype %d", types[index]);
999478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project			return (-1);
1000478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1001478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project		} /* switch */
1002478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	}
1003478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1004478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	p->dlt_count = index;
1005478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1006478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	return p->linktype;
1007478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1008