1478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
2478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *  This file is part of DOS-libpcap
3478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *  Ported to DOS/DOSX by G. Vanem <giva@bgnett.no>
4478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
5478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *  pcap-dos.c: Interface to PKTDRVR, NDIS2 and 32-bit pmode
6478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *              network drivers.
7478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *
8478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * @(#) $Header: /tcpdump/master/libpcap/pcap-dos.c,v 1.1.2.1 2005/05/03 18:54:35 guy Exp $ (LBL)
9478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
10478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
11478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdio.h>
12478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <stdlib.h>
13478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <string.h>
14478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <signal.h>
15478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <float.h>
16478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <fcntl.h>
17478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <io.h>
18478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
19478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if defined(USE_32BIT_DRIVERS)
20478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  #include "msdos/pm_drvr/pmdrvr.h"
21478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  #include "msdos/pm_drvr/pci.h"
22478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  #include "msdos/pm_drvr/bios32.h"
23478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  #include "msdos/pm_drvr/module.h"
24478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  #include "msdos/pm_drvr/3c501.h"
25478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  #include "msdos/pm_drvr/3c503.h"
26478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  #include "msdos/pm_drvr/3c509.h"
27478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  #include "msdos/pm_drvr/3c59x.h"
28478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  #include "msdos/pm_drvr/3c515.h"
29478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  #include "msdos/pm_drvr/3c90x.h"
30478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  #include "msdos/pm_drvr/3c575_cb.h"
31478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  #include "msdos/pm_drvr/ne.h"
32478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  #include "msdos/pm_drvr/wd.h"
33478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  #include "msdos/pm_drvr/accton.h"
34478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  #include "msdos/pm_drvr/cs89x0.h"
35478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  #include "msdos/pm_drvr/rtl8139.h"
36478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  #include "msdos/pm_drvr/ne2k-pci.h"
37478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
38478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
39478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "pcap.h"
40478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "pcap-dos.h"
41478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "pcap-int.h"
42478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "msdos/pktdrvr.h"
43478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
44478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef USE_NDIS2
45478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "msdos/ndis2.h"
46478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
47478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
48478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <arpa/inet.h>
49478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/if.h>
50478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/if_arp.h>
51478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/if_ether.h>
52478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <net/if_packe.h>
53478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include <tcp.h>
54478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
55478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if defined(USE_32BIT_DRIVERS)
56478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  #define FLUSHK()       do { _printk_safe = 1; _printk_flush(); } while (0)
57478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  #define NDIS_NEXT_DEV  &rtl8139_dev
58478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
59478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  static char *rx_pool = NULL;
60478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  static void init_32bit (void);
61478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
62478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  static int  pktq_init     (struct rx_ringbuf *q, int size, int num, char *pool);
63478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  static int  pktq_check    (struct rx_ringbuf *q);
64478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  static int  pktq_inc_out  (struct rx_ringbuf *q);
65478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  static int  pktq_in_index (struct rx_ringbuf *q) LOCKED_FUNC;
66478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  static void pktq_clear    (struct rx_ringbuf *q) LOCKED_FUNC;
67478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
68478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  static struct rx_elem *pktq_in_elem  (struct rx_ringbuf *q) LOCKED_FUNC;
69478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  static struct rx_elem *pktq_out_elem (struct rx_ringbuf *q);
70478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
71478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else
72478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  #define FLUSHK()      ((void)0)
73478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  #define NDIS_NEXT_DEV  NULL
74478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
75478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
76478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
77478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Internal variables/functions in Watt-32
78478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
79478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectextern WORD  _pktdevclass;
80478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectextern BOOL  _eth_is_init;
81478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectextern int   _w32_dynamic_host;
82478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectextern int   _watt_do_exit;
83478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectextern int   _watt_is_init;
84478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectextern int   _w32__bootp_on, _w32__dhcp_on, _w32__rarp_on, _w32__do_mask_req;
85478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectextern void (*_w32_usr_post_init) (void);
86478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectextern void (*_w32_print_hook)();
87478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
88478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectextern void dbug_write (const char *);  /* Watt-32 lib, pcdbug.c */
89478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectextern int  pkt_get_mtu (void);
90478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
91478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int ref_count = 0;
92478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
93478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_long mac_count    = 0;
94478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic u_long filter_count = 0;
95478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
96478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic volatile BOOL exc_occured = 0;
97478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
98478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct device *handle_to_device [20];
99478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int  pcap_read_dos (pcap_t *p, int cnt, pcap_handler callback,
101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                           u_char *data);
102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void pcap_close_dos (pcap_t *p);
103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int  pcap_stats_dos (pcap_t *p, struct pcap_stat *ps);
104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int  pcap_sendpacket_dos (pcap_t *p, const void *buf, size_t len);
105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int  pcap_setfilter_dos (pcap_t *p, struct bpf_program *fp);
106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int  ndis_probe (struct device *dev);
108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int  pkt_probe  (struct device *dev);
109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void close_driver (void);
111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int  init_watt32 (struct pcap *pcap, const char *dev_name, char *err_buf);
112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int  first_init (const char *name, char *ebuf, int promisc);
113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void watt32_recv_hook (u_char *dummy, const struct pcap_pkthdr *pcap,
115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                              const u_char *buf);
116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * These are the device we always support
119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct device ndis_dev = {
121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "ndis",
122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "NDIS2 LanManager",
123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              0,
124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              0,0,0,0,0,0,
125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              NDIS_NEXT_DEV,  /* NULL or a 32-bit device */
126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              ndis_probe
127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            };
128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct device pkt_dev = {
130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "pkt",
131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "Packet-Driver",
132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              0,
133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              0,0,0,0,0,0,
134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              &ndis_dev,
135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              pkt_probe
136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            };
137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct device *get_device (int fd)
139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (fd <= 0 || fd >= sizeof(handle_to_device)/sizeof(handle_to_device[0]))
141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     return (NULL);
142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return handle_to_device [fd-1];
143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Open MAC-driver with name 'device_name' for live capture of
147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * network packets.
148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_t *pcap_open_live (const char *device_name, int snaplen, int promisc,
150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                        int timeout_ms, char *errbuf)
151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  struct pcap *pcap;
153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (snaplen < ETH_MIN)
155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      snaplen = ETH_MIN;
156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (snaplen > ETH_MAX)   /* silently accept and truncate large MTUs */
158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      snaplen = ETH_MAX;
159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  pcap = calloc (sizeof(*pcap), 1);
161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (!pcap)
162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    strcpy (errbuf, "Not enough memory (pcap)");
164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return (NULL);
165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  pcap->snapshot          = max (ETH_MIN+8, snaplen);
168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  pcap->linktype          = DLT_EN10MB;  /* !! */
169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  pcap->inter_packet_wait = timeout_ms;
170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  pcap->close_op          = pcap_close_dos;
171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  pcap->read_op           = pcap_read_dos;
172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  pcap->stats_op          = pcap_stats_dos;
173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  pcap->inject_op         = pcap_sendpacket_dos;
174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  pcap->setfilter_op      = pcap_setfilter_dos;
175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project	pcap->setdirection_op   = NULL; /* Not implemented.*/
176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  pcap->fd                = ++ref_count;
177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (pcap->fd == 1)  /* first time we're called */
179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (!init_watt32(pcap, device_name, errbuf) ||
181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        !first_init(device_name, errbuf, promisc))
182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    {
183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      free (pcap);
184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      return (NULL);
185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    }
186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    atexit (close_driver);
187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  else if (stricmp(active_dev->name,device_name))
189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    snprintf (errbuf, PCAP_ERRBUF_SIZE,
191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "Cannot use different devices simultaneously "
192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "(`%s' vs. `%s')", active_dev->name, device_name);
193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    free (pcap);
194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    pcap = NULL;
195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  handle_to_device [pcap->fd-1] = active_dev;
197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (pcap);
198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Poll the receiver queue and call the pcap callback-handler
202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * with the packet.
203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  struct pcap_pkthdr pcap;
208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  struct bpf_insn   *fcode = p->fcode.bf_insns;
209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  struct timeval     now, expiry;
210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  BYTE  *rx_buf;
211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  int    rx_len = 0;
212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (p->inter_packet_wait > 0)
214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    gettimeofday2 (&now, NULL);
216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    expiry.tv_usec = now.tv_usec + 1000UL * p->inter_packet_wait;
217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    expiry.tv_sec  = now.tv_sec;
218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    while (expiry.tv_usec >= 1000000L)
219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    {
220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      expiry.tv_usec -= 1000000L;
221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      expiry.tv_sec++;
222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    }
223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  while (!exc_occured)
226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    volatile struct device *dev; /* might be reset by sig_handler */
228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    dev = get_device (p->fd);
230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (!dev)
231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project       break;
232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    PCAP_ASSERT (dev->copy_rx_buf || dev->peek_rx_buf);
234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    FLUSHK();
235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    /* If driver has a zero-copy receive facility, peek at the queue,
237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     * filter it, do the callback and release the buffer.
238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     */
239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (dev->peek_rx_buf)
240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    {
241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      PCAP_ASSERT (dev->release_rx_buf);
242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      rx_len = (*dev->peek_rx_buf) (&rx_buf);
243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    }
244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    else
245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    {
246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      BYTE buf [ETH_MAX+100]; /* add some margin */
247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      rx_len = (*dev->copy_rx_buf) (buf, p->snapshot);
248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      rx_buf = buf;
249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    }
250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (rx_len > 0)  /* got a packet */
252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    {
253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      mac_count++;
254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      FLUSHK();
256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      pcap.caplen = min (rx_len, p->snapshot);
258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      pcap.len    = rx_len;
259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      if (callback &&
261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project          (!fcode || bpf_filter(fcode, rx_buf, pcap.len, pcap.caplen)))
262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      {
263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        filter_count++;
264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        /* Fix-me!! Should be time of arrival. Not time of
266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project         * capture.
267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project         */
268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        gettimeofday2 (&pcap.ts, NULL);
269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        (*callback) (data, &pcap, rx_buf);
270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      }
271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      if (dev->release_rx_buf)
273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        (*dev->release_rx_buf) (rx_buf);
274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      if (pcap_pkt_debug > 0)
276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      {
277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        if (callback == watt32_recv_hook)
278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project             dbug_write ("pcap_recv_hook\n");
279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        else dbug_write ("pcap_read_op\n");
280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      }
281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      FLUSHK();
282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      return (1);
283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    }
284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    /* If not to wait for a packet or pcap_close() called from
286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     * e.g. SIGINT handler, exit loop now.
287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     */
288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (p->inter_packet_wait <= 0 || (volatile int)p->fd <= 0)
289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project       break;
290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    gettimeofday2 (&now, NULL);
292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (timercmp(&now, &expiry, >))
294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project       break;
295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef DJGPP
297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    kbhit();    /* a real CPU hog */
298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (p->wait_proc)
301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      (*p->wait_proc)();     /* call yield func */
302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (rx_len < 0)            /* receive error */
305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    p->md.stat.ps_drop++;
307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef USE_32BIT_DRIVERS
308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (pcap_pkt_debug > 1)
309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project       printk ("pkt-err %s\n", pktInfo.error);
310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return (-1);
312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (0);
314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int
317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectpcap_read_dos (pcap_t *p, int cnt, pcap_handler callback, u_char *data)
318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  int rc, num = 0;
320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  while (num <= cnt || (cnt < 0))
322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (p->fd <= 0)
324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project       return (-1);
325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    rc = pcap_read_one (p, callback, data);
326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (rc > 0)
327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project       num++;
328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (rc < 0)
329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project       break;
330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    _w32_os_yield();  /* allow SIGINT generation, yield to Win95/NT */
331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (num);
333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Return network statistics
337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pcap_stats_dos (pcap_t *p, struct pcap_stat *ps)
339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  struct net_device_stats *stats;
341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  struct device           *dev = p ? get_device(p->fd) : NULL;
342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (!dev)
344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    strcpy (p->errbuf, "illegal pcap handle");
346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return (-1);
347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (!dev->get_stats || (stats = (*dev->get_stats)(dev)) == NULL)
350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    strcpy (p->errbuf, "device statistics not available");
352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return (-1);
353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  FLUSHK();
356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  p->md.stat.ps_recv   = stats->rx_packets;
358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  p->md.stat.ps_drop  += stats->rx_missed_errors;
359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  p->md.stat.ps_ifdrop = stats->rx_dropped +  /* queue full */
360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                         stats->rx_errors;    /* HW errors */
361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (ps)
362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     *ps = p->md.stat;
363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (0);
365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Return detailed network/device statistics.
369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * May be called after 'dev->close' is called.
370478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
371478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint pcap_stats_ex (pcap_t *p, struct pcap_stat_ex *se)
372478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
373478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  struct device *dev = p ? get_device (p->fd) : NULL;
374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (!dev || !dev->get_stats)
376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    strlcpy (p->errbuf, "detailed device statistics not available",
378478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project             PCAP_ERRBUF_SIZE);
379478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return (-1);
380478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
382478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (!strnicmp(dev->name,"pkt",3))
383478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    strlcpy (p->errbuf, "pktdrvr doesn't have detailed statistics",
385478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project             PCAP_ERRBUF_SIZE);
386478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return (-1);
387478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  memcpy (se, (*dev->get_stats)(dev), sizeof(*se));
389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (0);
390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Simply store the filter-code for the pcap_read_dos() callback
394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Some day the filter-code could be handed down to the active
395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * device (pkt_rx1.s or 32-bit device interrupt handler).
396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
397478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pcap_setfilter_dos (pcap_t *p, struct bpf_program *fp)
398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (!p)
400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     return (-1);
401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  p->fcode = *fp;
402478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (0);
403478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
404478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
405478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
406478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Return # of packets received in pcap_read_dos()
407478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
408478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectu_long pcap_mac_packets (void)
409478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
410478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (mac_count);
411478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
412478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
413478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
414478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Return # of packets passed through filter in pcap_read_dos()
415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectu_long pcap_filter_packets (void)
417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
418478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (filter_count);
419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
420478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
421478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
422478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Close pcap device. Not called for offline captures.
423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void pcap_close_dos (pcap_t *p)
425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
426478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (p && !exc_occured)
427478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
428478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (pcap_stats(p,NULL) < 0)
429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project       p->md.stat.ps_drop = 0;
430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (!get_device(p->fd))
431478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project       return;
432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    handle_to_device [p->fd-1] = NULL;
434478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    p->fd = 0;
435478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (ref_count > 0)
436478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        ref_count--;
437478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (ref_count > 0)
438478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project       return;
439478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
440478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  close_driver();
441478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
442478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
443478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
444478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Return the name of the 1st network interface,
445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * or NULL if none can be found.
446478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
447478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectchar *pcap_lookupdev (char *ebuf)
448478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
449478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  struct device *dev;
450478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
451478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef USE_32BIT_DRIVERS
452478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  init_32bit();
453478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
454478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
455478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  for (dev = (struct device*)dev_base; dev; dev = dev->next)
456478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
457478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    PCAP_ASSERT (dev->probe);
458478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
459478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if ((*dev->probe)(dev))
460478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    {
461478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      FLUSHK();
462478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      probed_dev = (struct device*) dev; /* remember last probed device */
463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      return (char*) dev->name;
464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    }
465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (ebuf)
468478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     strcpy (ebuf, "No driver found");
469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (NULL);
470478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
472478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
473478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Gets localnet & netmask from Watt-32.
474478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
475478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint pcap_lookupnet (const char *device, bpf_u_int32 *localnet,
476478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                    bpf_u_int32 *netmask, char *errbuf)
477478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
478478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (!_watt_is_init)
479478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
480478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    strcpy (errbuf, "pcap_open_offline() or pcap_open_live() must be "
481478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                    "called first");
482478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return (-1);
483478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
484478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
485478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  *netmask  = _w32_sin_mask;
486478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  *localnet = my_ip_addr & *netmask;
487478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (*localnet == 0)
488478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
489478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (IN_CLASSA(*netmask))
490478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project       *localnet = IN_CLASSA_NET;
491478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    else if (IN_CLASSB(*netmask))
492478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project       *localnet = IN_CLASSB_NET;
493478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    else if (IN_CLASSC(*netmask))
494478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project       *localnet = IN_CLASSC_NET;
495478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    else
496478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    {
497478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      sprintf (errbuf, "inet class for 0x%lx unknown", *netmask);
498478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      return (-1);
499478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    }
500478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
501478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  ARGSUSED (device);
502478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (0);
503478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
504478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
505478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
506478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Get a list of all interfaces that are present and that we probe okay.
507478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Returns -1 on error, 0 otherwise.
508478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * The list, as returned through "alldevsp", may be null if no interfaces
509478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * were up and could be opened.
510478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
511478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint pcap_findalldevs (pcap_if_t **alldevsp, char *errbuf)
512478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
513478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  struct device     *dev;
514478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  struct sockaddr_ll sa_ll_1, sa_ll_2;
515478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  struct sockaddr   *addr, *netmask, *broadaddr, *dstaddr;
516478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  pcap_if_t *devlist = NULL;
517478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  int       ret = 0;
518478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  size_t    addr_size = sizeof(struct sockaddr_ll);
519478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
520478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  for (dev = (struct device*)dev_base; dev; dev = dev->next)
521478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
522478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    PCAP_ASSERT (dev->probe);
523478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
524478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (!(*dev->probe)(dev))
525478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project       continue;
526478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
527478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    PCAP_ASSERT (dev->close);  /* set by probe routine */
528478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    FLUSHK();
529478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    (*dev->close) (dev);
530478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
531478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    memset (&sa_ll_1, 0, sizeof(sa_ll_1));
532478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    memset (&sa_ll_2, 0, sizeof(sa_ll_2));
533478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    sa_ll_1.sll_family = AF_PACKET;
534478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    sa_ll_2.sll_family = AF_PACKET;
535478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
536478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    addr      = (struct sockaddr*) &sa_ll_1;
537478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    netmask   = (struct sockaddr*) &sa_ll_1;
538478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    dstaddr   = (struct sockaddr*) &sa_ll_1;
539478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    broadaddr = (struct sockaddr*) &sa_ll_2;
540478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    memset (&sa_ll_2.sll_addr, 0xFF, sizeof(sa_ll_2.sll_addr));
541478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
542478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (pcap_add_if(&devlist, dev->name, dev->flags,
543478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                    dev->long_name, errbuf) < 0)
544478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    {
545478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      ret = -1;
546478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      break;
547478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    }
548478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (add_addr_to_iflist(&devlist,dev->name, dev->flags, addr, addr_size,
549478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                           netmask, addr_size, broadaddr, addr_size,
550478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                           dstaddr, addr_size, errbuf) < 0)
551478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    {
552478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      ret = -1;
553478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      break;
554478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    }
555478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
556478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
557478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (devlist && ret < 0)
558478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
559478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    pcap_freealldevs (devlist);
560478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    devlist = NULL;
561478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
562478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  else
563478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (!devlist)
564478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     strcpy (errbuf, "No drivers found");
565478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
566478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  *alldevsp = devlist;
567478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (ret);
568478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
569478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
570478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
571478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * pcap_assert() is mainly used for debugging
572478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
573478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvoid pcap_assert (const char *what, const char *file, unsigned line)
574478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
575478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  FLUSHK();
576478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  fprintf (stderr, "%s (%u): Assertion \"%s\" failed\n",
577478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project           file, line, what);
578478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  close_driver();
579478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  _exit (-1);
580478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
581478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
582478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
583478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * For pcap_offline_read(): wait and yield between printing packets
584478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * to simulate the pace packets where actually recorded.
585478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
586478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectvoid pcap_set_wait (pcap_t *p, void (*yield)(void), int wait)
587478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
588478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (p)
589478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
590478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    p->wait_proc         = yield;
591478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    p->inter_packet_wait = wait;
592478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
593478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
594478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
595478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
596478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Initialise a named network device.
597478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
598478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct device *
599478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectopen_driver (const char *dev_name, char *ebuf, int promisc)
600478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
601478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  struct device *dev;
602478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
603478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  for (dev = (struct device*)dev_base; dev; dev = dev->next)
604478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
605478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    PCAP_ASSERT (dev->name);
606478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
607478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (strcmp (dev_name,dev->name))
608478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project       continue;
609478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
610478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (!probed_dev)   /* user didn't call pcap_lookupdev() first */
611478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    {
612478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      PCAP_ASSERT (dev->probe);
613478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
614478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      if (!(*dev->probe)(dev))    /* call the xx_probe() function */
615478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      {
616478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        sprintf (ebuf, "failed to detect device `%s'", dev_name);
617478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        return (NULL);
618478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      }
619478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      probed_dev = dev;  /* device is probed okay and may be used */
620478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    }
621478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    else if (dev != probed_dev)
622478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    {
623478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      goto not_probed;
624478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    }
625478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
626478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    FLUSHK();
627478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
628478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    /* Select what traffic to receive
629478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     */
630478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (promisc)
631478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project         dev->flags |=  (IFF_ALLMULTI | IFF_PROMISC);
632478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    else dev->flags &= ~(IFF_ALLMULTI | IFF_PROMISC);
633478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
634478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    PCAP_ASSERT (dev->open);
635478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
636478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (!(*dev->open)(dev))
637478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    {
638478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      sprintf (ebuf, "failed to activate device `%s'", dev_name);
639478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      if (pktInfo.error && !strncmp(dev->name,"pkt",3))
640478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      {
641478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        strcat (ebuf, ": ");
642478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        strcat (ebuf, pktInfo.error);
643478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      }
644478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      return (NULL);
645478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    }
646478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
647478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    /* Some devices need this to operate in promiscous mode
648478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     */
649478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (promisc && dev->set_multicast_list)
650478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project       (*dev->set_multicast_list) (dev);
651478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
652478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    active_dev = dev;   /* remember our active device */
653478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    break;
654478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
655478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
656478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  /* 'dev_name' not matched in 'dev_base' list.
657478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project   */
658478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (!dev)
659478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
660478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    sprintf (ebuf, "device `%s' not supported", dev_name);
661478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return (NULL);
662478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
663478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
664478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectnot_probed:
665478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (!probed_dev)
666478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
667478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    sprintf (ebuf, "device `%s' not probed", dev_name);
668478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return (NULL);
669478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
670478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (dev);
671478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
672478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
673478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
674478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Deinitialise MAC driver.
675478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Set receive mode back to default mode.
676478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
677478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void close_driver (void)
678478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
679478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  /* !!todo: loop over all 'handle_to_device[]' ? */
680478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  struct device *dev = active_dev;
681478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
682478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (dev && dev->close)
683478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
684478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    (*dev->close) (dev);
685478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    FLUSHK();
686478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
687478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
688478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  active_dev = NULL;
689478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
690478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef USE_32BIT_DRIVERS
691478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (rx_pool)
692478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
693478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    k_free (rx_pool);
694478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    rx_pool = NULL;
695478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
696478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (dev)
697478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     pcibios_exit();
698478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
699478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
700478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
701478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
702478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef __DJGPP__
703478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void setup_signals (void (*handler)(int))
704478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
705478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  signal (SIGSEGV,handler);
706478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  signal (SIGILL, handler);
707478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  signal (SIGFPE, handler);
708478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
709478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
710478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void exc_handler (int sig)
711478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
712478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef USE_32BIT_DRIVERS
713478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (active_dev->irq > 0)    /* excludes IRQ 0 */
714478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
715478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    disable_irq (active_dev->irq);
716478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    irq_eoi_cmd (active_dev->irq);
717478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    _printk_safe = 1;
718478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
719478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
720478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
721478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  switch (sig)
722478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
723478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    case SIGSEGV:
724478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project         fputs ("Catching SIGSEGV.\n", stderr);
725478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project         break;
726478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    case SIGILL:
727478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project         fputs ("Catching SIGILL.\n", stderr);
728478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project         break;
729478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    case SIGFPE:
730478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project         _fpreset();
731478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project         fputs ("Catching SIGFPE.\n", stderr);
732478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project         break;
733478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    default:
734478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project         fprintf (stderr, "Catching signal %d.\n", sig);
735478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
736478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  exc_occured = 1;
737478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  pcap_close_dos (NULL);
738478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
739478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif  /* __DJGPP__ */
740478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
741478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
742478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
743478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Open the pcap device for the first client calling pcap_open_live()
744478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
745478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int first_init (const char *name, char *ebuf, int promisc)
746478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
747478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  struct device *dev;
748478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
749478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef USE_32BIT_DRIVERS
750478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  rx_pool = k_calloc (RECEIVE_BUF_SIZE, RECEIVE_QUEUE_SIZE);
751478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (!rx_pool)
752478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
753478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    strcpy (ebuf, "Not enough memory (Rx pool)");
754478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return (0);
755478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
756478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
757478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
758478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef __DJGPP__
759478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  setup_signals (exc_handler);
760478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
761478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
762478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef USE_32BIT_DRIVERS
763478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  init_32bit();
764478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
765478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
766478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  dev = open_driver (name, ebuf, promisc);
767478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (!dev)
768478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
769478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef USE_32BIT_DRIVERS
770478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    k_free (rx_pool);
771478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    rx_pool = NULL;
772478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
773478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
774478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef __DJGPP__
775478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    setup_signals (SIG_DFL);
776478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
777478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return (0);
778478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
779478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
780478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef USE_32BIT_DRIVERS
781478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  /*
782478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project   * If driver is NOT a 16-bit "pkt/ndis" driver (having a 'copy_rx_buf'
783478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project   * set in it's probe handler), initialise near-memory ring-buffer for
784478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project   * the 32-bit device.
785478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project   */
786478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (dev->copy_rx_buf == NULL)
787478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
788478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    dev->get_rx_buf     = get_rxbuf;
789478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    dev->peek_rx_buf    = peek_rxbuf;
790478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    dev->release_rx_buf = release_rxbuf;
791478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    pktq_init (&dev->queue, RECEIVE_BUF_SIZE, RECEIVE_QUEUE_SIZE, rx_pool);
792478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
793478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
794478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (1);
795478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
796478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
797478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef USE_32BIT_DRIVERS
798478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void init_32bit (void)
799478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
800478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  static int init_pci = 0;
801478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
802478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (!_printk_file)
803478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     _printk_init (64*1024, NULL); /* calls atexit(printk_exit) */
804478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
805478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (!init_pci)
806478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     (void)pci_init();             /* init BIOS32+PCI interface */
807478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  init_pci = 1;
808478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
809478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
810478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
811478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
812478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
813478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Hook functions for using Watt-32 together with pcap
814478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
815478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic char rxbuf [ETH_MAX+100]; /* rx-buffer with some margin */
816478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic WORD etype;
817478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic pcap_t pcap_save;
818478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
819478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void watt32_recv_hook (u_char *dummy, const struct pcap_pkthdr *pcap,
820478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project                              const u_char *buf)
821478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
822478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  /* Fix me: assumes Ethernet II only */
823478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  struct ether_header *ep = (struct ether_header*) buf;
824478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
825478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  memcpy (rxbuf, buf, pcap->caplen);
826478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  etype = ep->ether_type;
827478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  ARGSUSED (dummy);
828478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
829478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
830478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if (WATTCP_VER >= 0x0224)
831478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
832478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This function is used by Watt-32 to poll for a packet.
833478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * i.e. it's set to bypass _eth_arrived()
834478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
835478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void *pcap_recv_hook (WORD *type)
836478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
837478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  int len = pcap_read_dos (&pcap_save, 1, watt32_recv_hook, NULL);
838478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
839478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (len < 0)
840478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     return (NULL);
841478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
842478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  *type = etype;
843478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (void*) &rxbuf;
844478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
845478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
846478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
847478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This function is called by Watt-32 (via _eth_xmit_hook).
848478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * If dbug_init() was called, we should trace packets sent.
849478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
850478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pcap_xmit_hook (const void *buf, unsigned len)
851478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
852478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  int rc = 0;
853478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
854478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (pcap_pkt_debug > 0)
855478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     dbug_write ("pcap_xmit_hook: ");
856478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
857478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (active_dev && active_dev->xmit)
858478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     if ((*active_dev->xmit) (active_dev, buf, len) > 0)
859478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        rc = len;
860478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
861478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (pcap_pkt_debug > 0)
862478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     dbug_write (rc ? "ok\n" : "fail\n");
863478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (rc);
864478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
865478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
866478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
867478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pcap_sendpacket_dos (pcap_t *p, const void *buf, size_t len)
868478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
869478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  struct device *dev = p ? get_device(p->fd) : NULL;
870478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
871478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (!dev || !dev->xmit)
872478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     return (-1);
873478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (*dev->xmit) (dev, buf, len);
874478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
875478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
876478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
877478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * This function is called by Watt-32 in tcp_post_init().
878478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * We should prevent Watt-32 from using BOOTP/DHCP/RARP etc.
879478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
880478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void (*prev_post_hook) (void);
881478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
882478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void pcap_init_hook (void)
883478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
884478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  _w32__bootp_on = _w32__dhcp_on = _w32__rarp_on = 0;
885478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  _w32__do_mask_req = 0;
886478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  _w32_dynamic_host = 0;
887478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (prev_post_hook)
888478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    (*prev_post_hook)();
889478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
890478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
891478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
892478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Supress PRINT message from Watt-32's sock_init()
893478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
894478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void null_print (void) {}
895478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
896478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
897478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * To use features of Watt-32 (netdb functions and socket etc.)
898478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * we must call sock_init(). But we set various hooks to prevent
899478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * using normal PKTDRVR functions in pcpkt.c. This should hopefully
900478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * make Watt-32 and pcap co-operate.
901478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
902478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int init_watt32 (struct pcap *pcap, const char *dev_name, char *err_buf)
903478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
904478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  char *env;
905478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  int   rc, MTU, has_ip_addr;
906478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  int   using_pktdrv = 1;
907478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
908478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  /* If user called sock_init() first, we need to reinit in
909478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project   * order to open debug/trace-file properly
910478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project   */
911478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (_watt_is_init)
912478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     sock_exit();
913478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
914478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  env = getenv ("PCAP_DEBUG");
915478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (env && atoi(env) > 0 &&
916478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      pcap_pkt_debug < 0)   /* if not already set */
917478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
918478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    dbug_init();
919478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    pcap_pkt_debug = atoi (env);
920478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
921478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
922478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  _watt_do_exit      = 0;    /* prevent sock_init() calling exit() */
923478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  prev_post_hook     = _w32_usr_post_init;
924478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  _w32_usr_post_init = pcap_init_hook;
925478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  _w32_print_hook    = null_print;
926478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
927478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (dev_name && strncmp(dev_name,"pkt",3))
928478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     using_pktdrv = FALSE;
929478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
930478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  rc = sock_init();
931478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  has_ip_addr = (rc != 8);  /* IP-address assignment failed */
932478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
933478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  /* if pcap is using a 32-bit driver w/o a pktdrvr loaded, we
934478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project   * just pretend Watt-32 is initialised okay.
935478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project   *
936478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project   * !! fix-me: The Watt-32 config isn't done if no pktdrvr
937478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project   *            was found. In that case my_ip_addr + sin_mask
938478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project   *            have default values. Should be taken from another
939478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project   *            ini-file/environment in any case (ref. tcpdump.ini)
940478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project   */
941478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  _watt_is_init = 1;
942478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
943478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (!using_pktdrv || !has_ip_addr)  /* for now .... */
944478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
945478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    static const char myip[] = "192.168.0.1";
946478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    static const char mask[] = "255.255.255.0";
947478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
948478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    printf ("Just guessing, using IP %s and netmask %s\n", myip, mask);
949478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    my_ip_addr    = aton (myip);
950478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    _w32_sin_mask = aton (mask);
951478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
952478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  else if (rc && using_pktdrv)
953478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
954478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    sprintf (err_buf, "sock_init() failed, code %d", rc);
955478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return (0);
956478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
957478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
958478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  /* Set recv-hook for peeking in _eth_arrived().
959478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project   */
960478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if (WATTCP_VER >= 0x0224)
961478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  _eth_recv_hook = pcap_recv_hook;
962478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  _eth_xmit_hook = pcap_xmit_hook;
963478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
964478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
965478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  /* Free the pkt-drvr handle allocated in pkt_init().
966478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project   * The above hooks should thus use the handle reopened in open_driver()
967478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project   */
968478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (using_pktdrv)
969478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
970478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    _eth_release();
971478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*  _eth_is_init = 1; */  /* hack to get Rx/Tx-hooks in Watt-32 working */
972478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
973478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
974478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  memcpy (&pcap_save, pcap, sizeof(pcap_save));
975478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  MTU = pkt_get_mtu();
976478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  pcap_save.fcode.bf_insns = NULL;
977478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  pcap_save.linktype       = _eth_get_hwtype (NULL, NULL);
978478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  pcap_save.snapshot       = MTU > 0 ? MTU : ETH_MAX; /* assume 1514 */
979478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
980478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if 1
981478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  /* prevent use of resolve() and resolve_ip()
982478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project   */
983478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  last_nameserver = 0;
984478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
985478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (1);
986478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
987478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
988478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint EISA_bus = 0;  /* Where is natural place for this? */
989478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
990478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
991478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Application config hooks to set various driver parameters.
992478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
993478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
994478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct config_table debug_tab[] = {
995478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "PKT.DEBUG",       ARG_ATOI,   &pcap_pkt_debug    },
996478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "PKT.VECTOR",      ARG_ATOX_W, NULL               },
997478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "NDIS.DEBUG",      ARG_ATOI,   NULL               },
998478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef USE_32BIT_DRIVERS
999478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "3C503.DEBUG",     ARG_ATOI,   &ei_debug          },
1000478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "3C503.IO_BASE",   ARG_ATOX_W, &el2_dev.base_addr },
1001478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "3C503.MEMORY",    ARG_ATOX_W, &el2_dev.mem_start },
1002478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "3C503.IRQ",       ARG_ATOI,   &el2_dev.irq       },
1003478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "3C505.DEBUG",     ARG_ATOI,   NULL               },
1004478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "3C505.BASE",      ARG_ATOX_W, NULL               },
1005478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "3C507.DEBUG",     ARG_ATOI,   NULL               },
1006478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "3C509.DEBUG",     ARG_ATOI,   &el3_debug         },
1007478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "3C509.ILOOP",     ARG_ATOI,   &el3_max_loop      },
1008478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "3C529.DEBUG",     ARG_ATOI,   NULL               },
1009478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "3C575.DEBUG",     ARG_ATOI,   &debug_3c575       },
1010478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "3C59X.DEBUG",     ARG_ATOI,   &vortex_debug      },
1011478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "3C59X.IFACE0",    ARG_ATOI,   &vortex_options[0] },
1012478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "3C59X.IFACE1",    ARG_ATOI,   &vortex_options[1] },
1013478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "3C59X.IFACE2",    ARG_ATOI,   &vortex_options[2] },
1014478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "3C59X.IFACE3",    ARG_ATOI,   &vortex_options[3] },
1015478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "3C90X.DEBUG",     ARG_ATOX_W, &tc90xbc_debug     },
1016478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "ACCT.DEBUG",      ARG_ATOI,   &ethpk_debug       },
1017478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "CS89.DEBUG",      ARG_ATOI,   &cs89_debug        },
1018478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "RTL8139.DEBUG",   ARG_ATOI,   &rtl8139_debug     },
1019478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        /*  { "RTL8139.FDUPLEX", ARG_ATOI,   &rtl8139_options   }, */
1020478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "SMC.DEBUG",       ARG_ATOI,   &ei_debug          },
1021478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project        /*  { "E100.DEBUG",      ARG_ATOI,   &e100_debug        }, */
1022478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "PCI.DEBUG",       ARG_ATOI,   &pci_debug         },
1023478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "BIOS32.DEBUG",    ARG_ATOI,   &bios32_debug      },
1024478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "IRQ.DEBUG",       ARG_ATOI,   &irq_debug         },
1025478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { "TIMER.IRQ",       ARG_ATOI,   &timer_irq         },
1026478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
1027478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            { NULL }
1028478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project          };
1029478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1030478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
1031478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * pcap_config_hook() is an extension to application's config
1032478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * handling. Uses Watt-32's config-table function.
1033478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
1034478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint pcap_config_hook (const char *name, const char *value)
1035478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1036478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return parse_config_table (debug_tab, NULL, name, value);
1037478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1038478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1039478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
1040478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Linked list of supported devices
1041478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
1042478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct device       *active_dev = NULL;      /* the device we have opened */
1043478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct device       *probed_dev = NULL;      /* the device we have probed */
1044478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectconst struct device *dev_base   = &pkt_dev;  /* list of network devices */
1045478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1046478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
1047478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * PKTDRVR device functions
1048478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
1049478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint pcap_pkt_debug = -1;
1050478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1051478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void pkt_close (struct device *dev)
1052478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1053478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  BOOL okay = PktExitDriver();
1054478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1055478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (pcap_pkt_debug > 1)
1056478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     fprintf (stderr, "pkt_close(): %d\n", okay);
1057478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1058478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (dev->priv)
1059478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     free (dev->priv);
1060478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  dev->priv = NULL;
1061478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1062478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1063478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pkt_open (struct device *dev)
1064478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1065478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  PKT_RX_MODE mode;
1066478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1067478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (dev->flags & IFF_PROMISC)
1068478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project       mode = PDRX_ALL_PACKETS;
1069478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  else mode = PDRX_BROADCAST;
1070478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1071478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (!PktInitDriver(mode))
1072478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     return (0);
1073478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1074478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  PktResetStatistics (pktInfo.handle);
1075478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  PktQueueBusy (FALSE);
1076478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (1);
1077478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1078478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1079478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pkt_xmit (struct device *dev, const void *buf, int len)
1080478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1081478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  struct net_device_stats *stats = (struct net_device_stats*) dev->priv;
1082478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1083478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (pcap_pkt_debug > 0)
1084478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     dbug_write ("pcap_xmit\n");
1085478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1086478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (!PktTransmit(buf,len))
1087478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
1088478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    stats->tx_errors++;
1089478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return (0);
1090478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
1091478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (len);
1092478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1093478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1094478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void *pkt_stats (struct device *dev)
1095478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1096478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  struct net_device_stats *stats = (struct net_device_stats*) dev->priv;
1097478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1098478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (!stats || !PktSessStatistics(pktInfo.handle))
1099478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     return (NULL);
1100478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1101478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  stats->rx_packets       = pktStat.inPackets;
1102478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  stats->rx_errors        = pktStat.lost;
1103478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  stats->rx_missed_errors = PktRxDropped();
1104478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (stats);
1105478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1106478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1107478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pkt_probe (struct device *dev)
1108478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1109478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (!PktSearchDriver())
1110478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     return (0);
1111478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1112478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  dev->open           = pkt_open;
1113478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  dev->xmit           = pkt_xmit;
1114478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  dev->close          = pkt_close;
1115478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  dev->get_stats      = pkt_stats;
1116478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  dev->copy_rx_buf    = PktReceive;  /* farmem peek and copy routine */
1117478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  dev->get_rx_buf     = NULL;
1118478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  dev->peek_rx_buf    = NULL;
1119478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  dev->release_rx_buf = NULL;
1120478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  dev->priv           = calloc (sizeof(struct net_device_stats), 1);
1121478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (!dev->priv)
1122478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     return (0);
1123478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (1);
1124478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1125478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1126478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
1127478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * NDIS device functions
1128478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
1129478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void ndis_close (struct device *dev)
1130478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1131478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef USE_NDIS2
1132478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  NdisShutdown();
1133478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
1134478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  ARGSUSED (dev);
1135478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1136478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1137478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int ndis_open (struct device *dev)
1138478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1139478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  int promis = (dev->flags & IFF_PROMISC);
1140478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1141478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef USE_NDIS2
1142478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (!NdisInit(promis))
1143478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     return (0);
1144478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (1);
1145478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else
1146478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  ARGSUSED (promis);
1147478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (0);
1148478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
1149478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1150478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1151478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void *ndis_stats (struct device *dev)
1152478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1153478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  static struct net_device_stats stats;
1154478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1155478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  /* to-do */
1156478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  ARGSUSED (dev);
1157478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (&stats);
1158478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1159478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1160478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int ndis_probe (struct device *dev)
1161478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1162478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef USE_NDIS2
1163478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (!NdisOpen())
1164478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     return (0);
1165478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
1166478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1167478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  dev->open           = ndis_open;
1168478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  dev->xmit           = NULL;
1169478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  dev->close          = ndis_close;
1170478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  dev->get_stats      = ndis_stats;
1171478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  dev->copy_rx_buf    = NULL;       /* to-do */
1172478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  dev->get_rx_buf     = NULL;       /* upcall is from rmode driver */
1173478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  dev->peek_rx_buf    = NULL;
1174478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  dev->release_rx_buf = NULL;
1175478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (0);
1176478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1177478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1178478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
1179478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Search & probe for supported 32-bit (pmode) pcap devices
1180478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
1181478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if defined(USE_32BIT_DRIVERS)
1182478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1183478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct device el2_dev LOCKED_VAR = {
1184478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "3c503",
1185478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "EtherLink II",
1186478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              0,
1187478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              0,0,0,0,0,0,
1188478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              NULL,
1189478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              el2_probe
1190478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            };
1191478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1192478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct device el3_dev LOCKED_VAR = {
1193478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "3c509",
1194478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "EtherLink III",
1195478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              0,
1196478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              0,0,0,0,0,0,
1197478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              &el2_dev,
1198478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              el3_probe
1199478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            };
1200478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1201478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct device tc515_dev LOCKED_VAR = {
1202478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "3c515",
1203478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "EtherLink PCI",
1204478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              0,
1205478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              0,0,0,0,0,0,
1206478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              &el3_dev,
1207478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              tc515_probe
1208478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            };
1209478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1210478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct device tc59_dev LOCKED_VAR = {
1211478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "3c59x",
1212478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "EtherLink PCI",
1213478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              0,
1214478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              0,0,0,0,0,0,
1215478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              &tc515_dev,
1216478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              tc59x_probe
1217478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            };
1218478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1219478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct device tc90xbc_dev LOCKED_VAR = {
1220478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "3c90x",
1221478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "EtherLink 90X",
1222478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              0,
1223478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              0,0,0,0,0,0,
1224478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              &tc59_dev,
1225478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              tc90xbc_probe
1226478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            };
1227478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1228478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct device wd_dev LOCKED_VAR = {
1229478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "wd",
1230478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "Westen Digital",
1231478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              0,
1232478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              0,0,0,0,0,0,
1233478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              &tc90xbc_dev,
1234478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              wd_probe
1235478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            };
1236478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1237478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct device ne_dev LOCKED_VAR = {
1238478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "ne",
1239478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "NEx000",
1240478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              0,
1241478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              0,0,0,0,0,0,
1242478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              &wd_dev,
1243478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              ne_probe
1244478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            };
1245478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1246478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct device acct_dev LOCKED_VAR = {
1247478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "acct",
1248478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "Accton EtherPocket",
1249478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              0,
1250478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              0,0,0,0,0,0,
1251478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              &ne_dev,
1252478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              ethpk_probe
1253478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            };
1254478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1255478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct device cs89_dev LOCKED_VAR = {
1256478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "cs89",
1257478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "Crystal Semiconductor",
1258478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              0,
1259478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              0,0,0,0,0,0,
1260478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              &acct_dev,
1261478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              cs89x0_probe
1262478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            };
1263478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1264478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstruct device rtl8139_dev LOCKED_VAR = {
1265478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "rtl8139",
1266478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              "RealTek PCI",
1267478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              0,
1268478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              0,0,0,0,0,0,
1269478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              &cs89_dev,
1270478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project              rtl8139_probe     /* dev->probe routine */
1271478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            };
1272478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1273478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
1274478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Dequeue routine is called by polling.
1275478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * NOTE: the queue-element is not copied, only a pointer is
1276478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * returned at '*buf'
1277478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
1278478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint peek_rxbuf (BYTE **buf)
1279478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1280478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  struct rx_elem *tail, *head;
1281478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1282478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  PCAP_ASSERT (pktq_check (&active_dev->queue));
1283478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1284478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  DISABLE();
1285478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  tail = pktq_out_elem (&active_dev->queue);
1286478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  head = pktq_in_elem (&active_dev->queue);
1287478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  ENABLE();
1288478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1289478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (head != tail)
1290478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
1291478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    PCAP_ASSERT (tail->size < active_dev->queue.elem_size-4-2);
1292478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1293478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    *buf = &tail->data[0];
1294478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return (tail->size);
1295478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
1296478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  *buf = NULL;
1297478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (0);
1298478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1299478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1300478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
1301478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Release buffer we peeked at above.
1302478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
1303478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectint release_rxbuf (BYTE *buf)
1304478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1305478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef NDEBUG
1306478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  struct rx_elem *tail = pktq_out_elem (&active_dev->queue);
1307478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1308478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  PCAP_ASSERT (&tail->data[0] == buf);
1309478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#else
1310478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  ARGSUSED (buf);
1311478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
1312478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  pktq_inc_out (&active_dev->queue);
1313478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (1);
1314478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1315478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1316478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
1317478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * get_rxbuf() routine (in locked code) is called from IRQ handler
1318478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * to request a buffer. Interrupts are disabled and we have a 32kB stack.
1319478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
1320478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source ProjectBYTE *get_rxbuf (int len)
1321478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1322478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  int idx;
1323478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1324478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (len < ETH_MIN || len > ETH_MAX)
1325478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     return (NULL);
1326478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1327478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  idx = pktq_in_index (&active_dev->queue);
1328478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1329478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifdef DEBUG
1330478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
1331478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    static int fan_idx LOCKED_VAR = 0;
1332478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    writew ("-\\|/"[fan_idx++] | (15 << 8),      /* white on black colour */
1333478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project            0xB8000 + 2*79);  /* upper-right corner, 80-col colour screen */
1334478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    fan_idx &= 3;
1335478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
1336478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/* writew (idx + '0' + 0x0F00, 0xB8000 + 2*78); */
1337478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
1338478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1339478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (idx != active_dev->queue.out_index)
1340478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
1341478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    struct rx_elem *head = pktq_in_elem (&active_dev->queue);
1342478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1343478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    head->size = len;
1344478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    active_dev->queue.in_index = idx;
1345478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    return (&head->data[0]);
1346478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
1347478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1348478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  /* !!to-do: drop 25% of the oldest element
1349478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project   */
1350478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  pktq_clear (&active_dev->queue);
1351478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (NULL);
1352478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1353478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1354478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
1355478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *  Simple ring-buffer queue handler for reception of packets
1356478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project *  from network driver.
1357478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
1358478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define PKTQ_MARKER  0xDEADBEEF
1359478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1360478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pktq_check (struct rx_ringbuf *q)
1361478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1362478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef NDEBUG
1363478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  int   i;
1364478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  char *buf;
1365478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
1366478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1367478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (!q || !q->num_elem || !q->buf_start)
1368478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     return (0);
1369478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1370478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#ifndef NDEBUG
1371478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  buf = q->buf_start;
1372478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1373478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  for (i = 0; i < q->num_elem; i++)
1374478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
1375478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    buf += q->elem_size;
1376478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    if (*(DWORD*)(buf - sizeof(DWORD)) != PKTQ_MARKER)
1377478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project       return (0);
1378478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
1379478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
1380478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (1);
1381478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1382478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1383478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pktq_init (struct rx_ringbuf *q, int size, int num, char *pool)
1384478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1385478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  int i;
1386478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1387478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  q->elem_size = size;
1388478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  q->num_elem  = num;
1389478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  q->buf_start = pool;
1390478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  q->in_index  = 0;
1391478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  q->out_index = 0;
1392478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1393478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  PCAP_ASSERT (size >= sizeof(struct rx_elem) + sizeof(DWORD));
1394478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  PCAP_ASSERT (num);
1395478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  PCAP_ASSERT (pool);
1396478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1397478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  for (i = 0; i < num; i++)
1398478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  {
1399478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#if 0
1400478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    struct rx_elem *elem = (struct rx_elem*) pool;
1401478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1402478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    /* assert dword aligned elements
1403478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project     */
1404478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    PCAP_ASSERT (((unsigned)(&elem->data[0]) & 3) == 0);
1405478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif
1406478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    pool += size;
1407478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project    *(DWORD*) (pool - sizeof(DWORD)) = PKTQ_MARKER;
1408478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  }
1409478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (1);
1410478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1411478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1412478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
1413478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Increment the queue 'out_index' (tail).
1414478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check for wraps.
1415478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
1416478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pktq_inc_out (struct rx_ringbuf *q)
1417478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1418478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  q->out_index++;
1419478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (q->out_index >= q->num_elem)
1420478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      q->out_index = 0;
1421478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (q->out_index);
1422478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1423478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1424478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
1425478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Return the queue's next 'in_index' (head).
1426478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Check for wraps.
1427478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
1428478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic int pktq_in_index (struct rx_ringbuf *q)
1429478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1430478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  volatile int index = q->in_index + 1;
1431478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1432478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  if (index >= q->num_elem)
1433478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project      index = 0;
1434478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (index);
1435478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1436478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1437478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
1438478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Return the queue's head-buffer.
1439478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
1440478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct rx_elem *pktq_in_elem (struct rx_ringbuf *q)
1441478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1442478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (struct rx_elem*) (q->buf_start + (q->elem_size * q->in_index));
1443478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1444478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1445478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
1446478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Return the queue's tail-buffer.
1447478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
1448478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic struct rx_elem *pktq_out_elem (struct rx_ringbuf *q)
1449478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1450478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  return (struct rx_elem*) (q->buf_start + (q->elem_size * q->out_index));
1451478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1452478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1453478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
1454478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Clear the queue ring-buffer by setting head=tail.
1455478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
1456478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Projectstatic void pktq_clear (struct rx_ringbuf *q)
1457478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project{
1458478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project  q->in_index = q->out_index;
1459478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project}
1460478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1461478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project/*
1462478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project * Symbols that must be linkable for "gcc -O0"
1463478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project */
1464478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#undef __IOPORT_H
1465478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#undef __DMA_H
1466478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1467478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define extern
1468478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#define __inline__
1469478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1470478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "msdos/pm_drvr/ioport.h"
1471478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#include "msdos/pm_drvr/dma.h"
1472478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1473478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project#endif /* USE_32BIT_DRIVERS */
1474478ab6c8b5bc982589be32eae1e5736efe721b58The Android Open Source Project
1475