Upgrade to libpcap 1.8.1.
From CHANGES:
Tuesday, Oct. 25, 2016 mcr@sandelman.ca
Summary for 1.8.1 libpcap release
Add a target in Makefile.in for Exuberant Ctags use: 'extags'.
Rename configure.in to configure.ac: autoconf 2.59
Clean up the name-to-DLT mapping table.
Add some newer DLT_ values: IPMI_HPM_2,ZWAVE_R1_R2,ZWAVE_R3,WATTSTOPPER_DLM,ISO_14443,RDS
Clarify what the return values are for both success and failure.
Many changes to build on windows
Check for the "break the loop" condition in the inner loop for TPACKET_V3.
Fix handling of packet count in the TPACKET_V3 inner loop: GitHub issue #493.
Filter out duplicate looped back CAN frames.
Fix the handling of loopback filters for IPv6 packets.
Add a link-layer header type for RDS (IEC 62106) groups.
Use different intermediate folders for x86 and x64 builds on Windows.
On Linux, handle all CAN captures with pcap-linux.c, in cooked mode.
Removes the need for the "host-endian" link-layer header type.
Compile with '-Wused-but-marked-unused' in devel mode if supported
Have separate DLTs for big-endian and host-endian SocketCAN headers.
Reflect version.h being renamed to pcap_version.h.
Require that version.h be generated: all build procedures we support generate version.h (autoconf, CMake, MSVC)!
Properly check for sock_recv() errors.
Re-impose some of Winsock's limitations on sock_recv().
Replace sprintf() with pcap_snprintf().
Fix signature of pcap_stats_ex_remote().
Initial cmake support for remote packet capture.
Have rpcap_remoteact_getsock() return a SOCKET and supply an "is active" flag.
Clean up {DAG, Septel, Myricom SNF}-only builds.
Do UTF-16-to-ASCII conversion into the right place.
pcap_create_interface() needs the interface name on Linux.
Clean up hardware time stamp support: the "any" device does not support any time stamp types.
Add support for capturing on FreeBSD usbusN interfaces.
Add a LINKTYPE/DLT_ value for FreeBSD USB.
Go back to using PCAP_API on Windows.
CMake support
Add TurboCap support from WinPcap.
Recognize 802.1ad nested VLAN tag in vlan filter.
Thursday Sep. 3, 2015 guy@alum.mit.edu
Summary for 1.7.5 libpcap release
Man page cleanups.
Add some allocation failure checks.
Fix a number of Linux/ucLinux configure/build issues.
Fix some memory leaks.
Recognize 802.1ad nested VLAN tag in vlan filter.
Fix building Bluetooth Linux Monitor support with BlueZ 5.1+
Bug: N/A
Test: builds
Change-Id: I943408b8a42a44ab15c9649f360edf3e771871e9
diff --git a/pcap-dos.c b/pcap-dos.c
index 8632cee..ea6b225 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 @@
* 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);
@@ -167,8 +167,6 @@
*/
static int pcap_activate_dos (pcap_t *pcap)
{
- struct pcap_dos *pcapd = pcap->priv;
-
if (pcap->opt.rfmon) {
/*
* No monitor mode on DOS.
@@ -188,23 +186,26 @@
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))
{
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);
return (PCAP_ERROR);
}
handle_to_device [pcap->fd-1] = active_dev;
@@ -221,7 +222,6 @@
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 +253,11 @@
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 +270,7 @@
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 +278,11 @@
* 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 +294,18 @@
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 +321,8 @@
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 +340,6 @@
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))
@@ -442,7 +451,7 @@
{
struct pcap_dos *pd;
- if (p && !exc_occured)
+ if (!exc_occured)
{
pd = p->priv;
if (pcap_stats(p,NULL) < 0)
@@ -495,6 +504,8 @@
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,22 +513,25 @@
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);
}
@@ -525,17 +539,17 @@
/*
* 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
+ * The list, as returned through "alldevsp", may be NULL if no interfaces
* were up and could be opened.
*/
-int pcap_findalldevs (pcap_if_t **alldevsp, char *errbuf)
+int pcap_platform_finddevs (pcap_if_t **alldevsp, char *errbuf)
{
struct device *dev;
- struct sockaddr_ll sa_ll_1, sa_ll_2;
+ struct sockaddr_in sa_ll_1, sa_ll_2;
struct sockaddr *addr, *netmask, *broadaddr, *dstaddr;
pcap_if_t *devlist = NULL;
int ret = 0;
- size_t addr_size = sizeof(struct sockaddr_ll);
+ size_t addr_size = sizeof(*addr);
for (dev = (struct device*)dev_base; dev; dev = dev->next)
{
@@ -550,14 +564,14 @@
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)
@@ -565,13 +579,15 @@
ret = -1;
break;
}
- if (add_addr_to_iflist(&devlist,dev->name, dev->flags, addr, addr_size,
+#if 0 /* Pkt drivers should have no addresses */
+ if (add_addr_to_iflist(&devlist, dev->name, dev->flags, addr, addr_size,
netmask, addr_size, broadaddr, addr_size,
dstaddr, addr_size, errbuf) < 0)
{
ret = -1;
break;
}
+#endif
}
if (devlist && ret < 0)
@@ -605,12 +621,12 @@
*/
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 +651,7 @@
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 +673,7 @@
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 +695,14 @@
*/
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 +772,7 @@
fprintf (stderr, "Catching signal %d.\n", sig);
}
exc_occured = 1;
- pcap_cleanup_dos (NULL);
+ close_driver();
}
#endif /* __DJGPP__ */
@@ -933,7 +949,7 @@
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 */
{
@@ -973,7 +989,7 @@
}
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 +1069,9 @@
* 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);
}
/*