summaryrefslogtreecommitdiff
path: root/pcap-dos.c
diff options
context:
space:
mode:
Diffstat (limited to 'pcap-dos.c')
-rw-r--r--pcap-dos.c200
1 files changed, 120 insertions, 80 deletions
diff --git a/pcap-dos.c b/pcap-dos.c
index 43f50c7..c159b55 100644
--- a/pcap-dos.c
+++ b/pcap-dos.c
@@ -1,6 +1,6 @@
/*
* This file is part of DOS-libpcap
- * Ported to DOS/DOSX by G. Vanem <gvanem@broadpark.no>
+ * Ported to DOS/DOSX by G. Vanem <gvanem@yahoo.no>
*
* pcap-dos.c: Interface to PKTDRVR, NDIS2 and 32-bit pmode
* network drivers.
@@ -145,15 +145,15 @@ static struct device *get_device (int fd)
* Private data for capturing on MS-DOS.
*/
struct pcap_dos {
- void (*wait_proc)(void); /* call proc while waiting */
+ void (*wait_proc)(void); /* call proc while waiting */
struct pcap_stat stat;
};
-pcap_t *pcap_create_interface (const char *device, char *ebuf)
+pcap_t *pcap_create_interface (const char *device _U_, char *ebuf)
{
pcap_t *p;
- p = pcap_create_common(device, ebuf, sizeof (struct pcap_dos));
+ p = pcap_create_common(ebuf, sizeof (struct pcap_dos));
if (p == NULL)
return (NULL);
@@ -166,9 +166,7 @@ pcap_t *pcap_create_interface (const char *device, char *ebuf)
* network packets.
*/
static int pcap_activate_dos (pcap_t *pcap)
-{
- struct pcap_dos *pcapd = pcap->priv;
-
+{
if (pcap->opt.rfmon) {
/*
* No monitor mode on DOS.
@@ -176,6 +174,17 @@ static int pcap_activate_dos (pcap_t *pcap)
return (PCAP_ERROR_RFMON_NOTSUP);
}
+ /*
+ * Turn a negative snapshot value (invalid), a snapshot value of
+ * 0 (unspecified), or a value bigger than the normal maximum
+ * value, into the maximum allowed value.
+ *
+ * If some application really *needs* a bigger snapshot
+ * length, we should just increase MAXIMUM_SNAPLEN.
+ */
+ if (pcap->snapshot <= 0 || pcap->snapshot > MAXIMUM_SNAPLEN)
+ pcap->snapshot = MAXIMUM_SNAPLEN;
+
if (pcap->snapshot < ETH_MIN+8)
pcap->snapshot = ETH_MIN+8;
@@ -188,23 +197,28 @@ static int pcap_activate_dos (pcap_t *pcap)
pcap->stats_op = pcap_stats_dos;
pcap->inject_op = pcap_sendpacket_dos;
pcap->setfilter_op = pcap_setfilter_dos;
- pcap->setdirection_op = NULL; /* Not implemented.*/
+ pcap->setdirection_op = NULL; /* Not implemented.*/
pcap->fd = ++ref_count;
+ pcap->bufsize = ETH_MAX+100; /* add some margin */
+ pcap->buffer = calloc (pcap->bufsize, 1);
+
if (pcap->fd == 1) /* first time we're called */
{
- if (!init_watt32(pcap, pcap->opt.source, pcap->errbuf) ||
- !first_init(pcap->opt.source, pcap->errbuf, pcap->opt.promisc))
+ if (!init_watt32(pcap, pcap->opt.device, pcap->errbuf) ||
+ !first_init(pcap->opt.device, pcap->errbuf, pcap->opt.promisc))
{
+ /* XXX - free pcap->buffer? */
return (PCAP_ERROR);
- }
+ }
atexit (close_driver);
}
- else if (stricmp(active_dev->name,pcap->opt.source))
+ else if (stricmp(active_dev->name,pcap->opt.device))
{
- snprintf (pcap->errbuf, PCAP_ERRBUF_SIZE,
- "Cannot use different devices simultaneously "
- "(`%s' vs. `%s')", active_dev->name, pcap->opt.source);
+ pcap_snprintf (pcap->errbuf, PCAP_ERRBUF_SIZE,
+ "Cannot use different devices simultaneously "
+ "(`%s' vs. `%s')", active_dev->name, pcap->opt.device);
+ /* XXX - free pcap->buffer? */
return (PCAP_ERROR);
}
handle_to_device [pcap->fd-1] = active_dev;
@@ -221,7 +235,6 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
struct pcap_dos *pd = p->priv;
struct pcap_pkthdr pcap;
struct timeval now, expiry = { 0,0 };
- BYTE *rx_buf;
int rx_len = 0;
if (p->opt.timeout > 0)
@@ -253,13 +266,11 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
if (dev->peek_rx_buf)
{
PCAP_ASSERT (dev->release_rx_buf);
- rx_len = (*dev->peek_rx_buf) (&rx_buf);
+ rx_len = (*dev->peek_rx_buf) (&p->buffer);
}
else
{
- BYTE buf [ETH_MAX+100]; /* add some margin */
- rx_len = (*dev->copy_rx_buf) (buf, p->snapshot);
- rx_buf = buf;
+ rx_len = (*dev->copy_rx_buf) (p->buffer, p->snapshot);
}
if (rx_len > 0) /* got a packet */
@@ -272,7 +283,7 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
pcap.len = rx_len;
if (callback &&
- (!p->fcode.bf_insns || bpf_filter(p->fcode.bf_insns, rx_buf, pcap.len, pcap.caplen)))
+ (!p->fcode.bf_insns || bpf_filter(p->fcode.bf_insns, p->buffer, pcap.len, pcap.caplen)))
{
filter_count++;
@@ -280,11 +291,11 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
* capture.
*/
gettimeofday2 (&pcap.ts, NULL);
- (*callback) (data, &pcap, rx_buf);
+ (*callback) (data, &pcap, p->buffer);
}
if (dev->release_rx_buf)
- (*dev->release_rx_buf) (rx_buf);
+ (*dev->release_rx_buf) (p->buffer);
if (pcap_pkt_debug > 0)
{
@@ -296,6 +307,18 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
return (1);
}
+ /* Has "pcap_breakloop()" been called?
+ */
+ if (p->break_loop) {
+ /*
+ * Yes - clear the flag that indicates that it
+ * has, and return -2 to indicate that we were
+ * told to break out of the loop.
+ */
+ p->break_loop = 0;
+ return (-2);
+ }
+
/* If not to wait for a packet or pcap_cleanup_dos() called from
* e.g. SIGINT handler, exit loop now.
*/
@@ -311,8 +334,8 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
kbhit(); /* a real CPU hog */
#endif
- if (p->wait_proc)
- (*p->wait_proc)(); /* call yield func */
+ if (pd->wait_proc)
+ (*pd->wait_proc)(); /* call yield func */
}
if (rx_len < 0) /* receive error */
@@ -330,7 +353,6 @@ pcap_read_one (pcap_t *p, pcap_handler callback, u_char *data)
static int
pcap_read_dos (pcap_t *p, int cnt, pcap_handler callback, u_char *data)
{
- struct pcap_dos *pd = p->priv;
int rc, num = 0;
while (num <= cnt || PACKET_COUNT_IS_UNLIMITED(cnt))
@@ -391,17 +413,17 @@ int pcap_stats_ex (pcap_t *p, struct pcap_stat_ex *se)
if (!dev || !dev->get_stats)
{
- strlcpy (p->errbuf, "detailed device statistics not available",
+ pcap_strlcpy (p->errbuf, "detailed device statistics not available",
PCAP_ERRBUF_SIZE);
return (-1);
}
if (!strnicmp(dev->name,"pkt",3))
{
- strlcpy (p->errbuf, "pktdrvr doesn't have detailed statistics",
+ pcap_strlcpy (p->errbuf, "pktdrvr doesn't have detailed statistics",
PCAP_ERRBUF_SIZE);
return (-1);
- }
+ }
memcpy (se, (*dev->get_stats)(dev), sizeof(*se));
return (0);
}
@@ -442,7 +464,7 @@ static void pcap_cleanup_dos (pcap_t *p)
{
struct pcap_dos *pd;
- if (p && !exc_occured)
+ if (!exc_occured)
{
pd = p->priv;
if (pcap_stats(p,NULL) < 0)
@@ -458,6 +480,7 @@ static void pcap_cleanup_dos (pcap_t *p)
return;
}
close_driver();
+ /* XXX - call pcap_cleanup_live_common? */
}
/*
@@ -495,6 +518,8 @@ char *pcap_lookupdev (char *ebuf)
int pcap_lookupnet (const char *device, bpf_u_int32 *localnet,
bpf_u_int32 *netmask, char *errbuf)
{
+ DWORD mask, net;
+
if (!_watt_is_init)
{
strcpy (errbuf, "pcap_open_offline() or pcap_activate() must be "
@@ -502,40 +527,44 @@ int pcap_lookupnet (const char *device, bpf_u_int32 *localnet,
return (-1);
}
- *netmask = _w32_sin_mask;
- *localnet = my_ip_addr & *netmask;
- if (*localnet == 0)
+ mask = _w32_sin_mask;
+ net = my_ip_addr & mask;
+ if (net == 0)
{
if (IN_CLASSA(*netmask))
- *localnet = IN_CLASSA_NET;
+ net = IN_CLASSA_NET;
else if (IN_CLASSB(*netmask))
- *localnet = IN_CLASSB_NET;
+ net = IN_CLASSB_NET;
else if (IN_CLASSC(*netmask))
- *localnet = IN_CLASSC_NET;
+ net = IN_CLASSC_NET;
else
{
- sprintf (errbuf, "inet class for 0x%lx unknown", *netmask);
+ pcap_snprintf (errbuf, PCAP_ERRBUF_SIZE, "inet class for 0x%lx unknown", mask);
return (-1);
}
}
+ *localnet = htonl (net);
+ *netmask = htonl (mask);
+
ARGSUSED (device);
return (0);
-}
+}
/*
* Get a list of all interfaces that are present and that we probe okay.
* Returns -1 on error, 0 otherwise.
- * The list, as returned through "alldevsp", may be null if no interfaces
- * were up and could be opened.
+ * The list may be NULL epty if no interfaces were up and could be opened.
*/
-int pcap_findalldevs (pcap_if_t **alldevsp, char *errbuf)
+int pcap_platform_finddevs (pcap_if_list_t *devlistp, char *errbuf)
{
struct device *dev;
- struct sockaddr_ll sa_ll_1, sa_ll_2;
+ pcap_if_t *curdev;
+#if 0 /* Pkt drivers should have no addresses */
+ struct sockaddr_in sa_ll_1, sa_ll_2;
struct sockaddr *addr, *netmask, *broadaddr, *dstaddr;
- pcap_if_t *devlist = NULL;
+#endif
int ret = 0;
- size_t addr_size = sizeof(struct sockaddr_ll);
+ int found = 0;
for (dev = (struct device*)dev_base; dev; dev = dev->next)
{
@@ -548,42 +577,45 @@ int pcap_findalldevs (pcap_if_t **alldevsp, char *errbuf)
FLUSHK();
(*dev->close) (dev);
+ /*
+ * XXX - find out whether it's up or running? Does that apply here?
+ * Can we find out if anything's plugged into the adapter, if it's
+ * a wired device, and set PCAP_IF_CONNECTION_STATUS_CONNECTED
+ * or PCAP_IF_CONNECTION_STATUS_DISCONNECTED?
+ */
+ if ((curdev = add_dev(devlistp, dev->name, 0,
+ dev->long_name, errbuf)) == NULL)
+ {
+ ret = -1;
+ break;
+ }
+ found = 1;
+#if 0 /* Pkt drivers should have no addresses */
memset (&sa_ll_1, 0, sizeof(sa_ll_1));
memset (&sa_ll_2, 0, sizeof(sa_ll_2));
- sa_ll_1.sll_family = AF_PACKET;
- sa_ll_2.sll_family = AF_PACKET;
+ sa_ll_1.sin_family = AF_INET;
+ sa_ll_2.sin_family = AF_INET;
addr = (struct sockaddr*) &sa_ll_1;
netmask = (struct sockaddr*) &sa_ll_1;
dstaddr = (struct sockaddr*) &sa_ll_1;
broadaddr = (struct sockaddr*) &sa_ll_2;
- memset (&sa_ll_2.sll_addr, 0xFF, sizeof(sa_ll_2.sll_addr));
+ memset (&sa_ll_2.sin_addr, 0xFF, sizeof(sa_ll_2.sin_addr));
- if (pcap_add_if(&devlist, dev->name, dev->flags,
- dev->long_name, errbuf) < 0)
- {
- ret = -1;
- break;
- }
- if (add_addr_to_iflist(&devlist,dev->name, dev->flags, addr, addr_size,
- netmask, addr_size, broadaddr, addr_size,
- dstaddr, addr_size, errbuf) < 0)
+ if (add_addr_to_dev(curdev, addr, sizeof(*addr),
+ netmask, sizeof(*netmask),
+ broadaddr, sizeof(*broadaddr),
+ dstaddr, sizeof(*dstaddr), errbuf) < 0)
{
ret = -1;
break;
}
+#endif
}
- if (devlist && ret < 0)
- {
- pcap_freealldevs (devlist);
- devlist = NULL;
- }
- else
- if (!devlist)
+ if (ret == 0 && !found)
strcpy (errbuf, "No drivers found");
- *alldevsp = devlist;
return (ret);
}
@@ -605,12 +637,12 @@ void pcap_assert (const char *what, const char *file, unsigned line)
*/
void pcap_set_wait (pcap_t *p, void (*yield)(void), int wait)
{
- struct pcap_dos *pd;
if (p)
{
- pd = p->priv;
- pd->wait_proc = yield;
- p->opt.timeout = wait;
+ struct pcap_dos *pd = p->priv;
+
+ pd->wait_proc = yield;
+ p->opt.timeout = wait;
}
}
@@ -635,7 +667,7 @@ open_driver (const char *dev_name, char *ebuf, int promisc)
if (!(*dev->probe)(dev)) /* call the xx_probe() function */
{
- sprintf (ebuf, "failed to detect device `%s'", dev_name);
+ pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "failed to detect device `%s'", dev_name);
return (NULL);
}
probed_dev = dev; /* device is probed okay and may be used */
@@ -657,7 +689,7 @@ open_driver (const char *dev_name, char *ebuf, int promisc)
if (!(*dev->open)(dev))
{
- sprintf (ebuf, "failed to activate device `%s'", dev_name);
+ pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "failed to activate device `%s'", dev_name);
if (pktInfo.error && !strncmp(dev->name,"pkt",3))
{
strcat (ebuf, ": ");
@@ -679,14 +711,14 @@ open_driver (const char *dev_name, char *ebuf, int promisc)
*/
if (!dev)
{
- sprintf (ebuf, "device `%s' not supported", dev_name);
+ pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "device `%s' not supported", dev_name);
return (NULL);
}
not_probed:
if (!probed_dev)
{
- sprintf (ebuf, "device `%s' not probed", dev_name);
+ pcap_snprintf (ebuf, PCAP_ERRBUF_SIZE, "device `%s' not probed", dev_name);
return (NULL);
}
return (dev);
@@ -756,7 +788,7 @@ static void exc_handler (int sig)
fprintf (stderr, "Catching signal %d.\n", sig);
}
exc_occured = 1;
- pcap_cleanup_dos (NULL);
+ close_driver();
}
#endif /* __DJGPP__ */
@@ -933,7 +965,7 @@ static int init_watt32 (struct pcap *pcap, const char *dev_name, char *err_buf)
if (_watt_is_init)
sock_exit();
- env = getenv ("PCAP_DEBUG");
+ env = getenv ("PCAP_TRACE");
if (env && atoi(env) > 0 &&
pcap_pkt_debug < 0) /* if not already set */
{
@@ -960,7 +992,7 @@ static int init_watt32 (struct pcap *pcap, const char *dev_name, char *err_buf)
* have default values. Should be taken from another
* ini-file/environment in any case (ref. tcpdump.ini)
*/
- _watt_is_init = 1;
+ _watt_is_init = 1;
if (!using_pktdrv || !has_ip_addr) /* for now .... */
{
@@ -973,7 +1005,7 @@ static int init_watt32 (struct pcap *pcap, const char *dev_name, char *err_buf)
}
else if (rc && using_pktdrv)
{
- sprintf (err_buf, "sock_init() failed, code %d", rc);
+ pcap_snprintf (err_buf, PCAP_ERRBUF_SIZE, "sock_init() failed, code %d", rc);
return (0);
}
@@ -1053,9 +1085,9 @@ static const struct config_table debug_tab[] = {
* pcap_config_hook() is an extension to application's config
* handling. Uses Watt-32's config-table function.
*/
-int pcap_config_hook (const char *name, const char *value)
+int pcap_config_hook (const char *keyword, const char *value)
{
- return parse_config_table (debug_tab, NULL, name, value);
+ return parse_config_table (debug_tab, NULL, keyword, value);
}
/*
@@ -1092,7 +1124,7 @@ static int pkt_open (struct device *dev)
if (!PktInitDriver(mode))
return (0);
-
+
PktResetStatistics (pktInfo.handle);
PktQueueBusy (FALSE);
return (1);
@@ -1290,7 +1322,7 @@ struct device rtl8139_dev LOCKED_VAR = {
0,0,0,0,0,0,
&cs89_dev,
rtl8139_probe /* dev->probe routine */
- };
+ };
/*
* Dequeue routine is called by polling.
@@ -1494,3 +1526,11 @@ static void pktq_clear (struct rx_ringbuf *q)
#endif /* USE_32BIT_DRIVERS */
+/*
+ * Libpcap version string.
+ */
+const char *
+pcap_lib_version(void)
+{
+ return ("DOS-" PCAP_VERSION_STRING);
+}