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