mirror of
https://github.com/nmap/nmap.git
synced 2025-12-29 10:59:02 +00:00
Upgrade libpcap to 1.10.4
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
|
||||
#include "pcap-int.h"
|
||||
#include "pcap-usb-linux.h"
|
||||
#include "pcap-usb-linux-common.h"
|
||||
#include "pcap/usb.h"
|
||||
|
||||
#include "extract.h"
|
||||
@@ -70,7 +71,12 @@
|
||||
#include <linux/usbdevice_fs.h>
|
||||
#endif /* HAVE_LINUX_USBDEVICE_FS_H */
|
||||
|
||||
#include "diag-control.h"
|
||||
|
||||
#define USB_IFACE "usbmon"
|
||||
|
||||
#define USBMON_DEV_PREFIX "usbmon"
|
||||
#define USBMON_DEV_PREFIX_LEN (sizeof USBMON_DEV_PREFIX - 1)
|
||||
#define USB_LINE_LEN 4096
|
||||
|
||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
|
||||
@@ -111,10 +117,10 @@ struct mon_bin_mfetch {
|
||||
#define MON_IOCX_MFETCH _IOWR(MON_IOC_MAGIC, 7, struct mon_bin_mfetch)
|
||||
#define MON_IOCH_MFLUSH _IO(MON_IOC_MAGIC, 8)
|
||||
|
||||
#define MON_BIN_SETUP 0x1 /* setup hdr is present*/
|
||||
#define MON_BIN_SETUP_ZERO 0x2 /* setup buffer is not available */
|
||||
#define MON_BIN_DATA_ZERO 0x4 /* data buffer is not available */
|
||||
#define MON_BIN_ERROR 0x8
|
||||
#define MON_BIN_SETUP 0x1 /* setup hdr is present*/
|
||||
#define MON_BIN_SETUP_ZERO 0x2 /* setup buffer is not available */
|
||||
#define MON_BIN_DATA_ZERO 0x4 /* data buffer is not available */
|
||||
#define MON_BIN_ERROR 0x8
|
||||
|
||||
/*
|
||||
* Private data for capturing on Linux USB.
|
||||
@@ -173,9 +179,6 @@ usb_dev_add(pcap_if_list_t *devlistp, int n, char *err_str)
|
||||
int
|
||||
usb_findalldevs(pcap_if_list_t *devlistp, char *err_str)
|
||||
{
|
||||
char usb_mon_dir[PATH_MAX];
|
||||
char *usb_mon_prefix;
|
||||
size_t usb_mon_prefix_len;
|
||||
struct dirent* data;
|
||||
int ret = 0;
|
||||
DIR* dir;
|
||||
@@ -184,26 +187,10 @@ usb_findalldevs(pcap_if_list_t *devlistp, char *err_str)
|
||||
|
||||
/*
|
||||
* We require 2.6.27 or later kernels, so we have binary-mode support.
|
||||
* What do the device names look like?
|
||||
* Split LINUX_USB_MON_DEV into a directory that we'll
|
||||
* scan and a file name prefix that we'll check for.
|
||||
* The devices are of the form /dev/usbmon{N}.
|
||||
* Open /dev and scan it.
|
||||
*/
|
||||
pcap_strlcpy(usb_mon_dir, LINUX_USB_MON_DEV, sizeof usb_mon_dir);
|
||||
usb_mon_prefix = strrchr(usb_mon_dir, '/');
|
||||
if (usb_mon_prefix == NULL) {
|
||||
/*
|
||||
* This "shouldn't happen". Just give up if it
|
||||
* does.
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
*usb_mon_prefix++ = '\0';
|
||||
usb_mon_prefix_len = strlen(usb_mon_prefix);
|
||||
|
||||
/*
|
||||
* Open the directory and scan it.
|
||||
*/
|
||||
dir = opendir(usb_mon_dir);
|
||||
dir = opendir("/dev");
|
||||
if (dir != NULL) {
|
||||
while ((ret == 0) && ((data = readdir(dir)) != 0)) {
|
||||
name = data->d_name;
|
||||
@@ -211,13 +198,14 @@ usb_findalldevs(pcap_if_list_t *devlistp, char *err_str)
|
||||
/*
|
||||
* Is this a usbmon device?
|
||||
*/
|
||||
if (strncmp(name, usb_mon_prefix, usb_mon_prefix_len) != 0)
|
||||
if (strncmp(name, USBMON_DEV_PREFIX,
|
||||
USBMON_DEV_PREFIX_LEN) != 0)
|
||||
continue; /* no */
|
||||
|
||||
/*
|
||||
* What's the device number?
|
||||
*/
|
||||
if (sscanf(&name[usb_mon_prefix_len], "%d", &n) == 0)
|
||||
if (sscanf(&name[USBMON_DEV_PREFIX_LEN], "%d", &n) == 0)
|
||||
continue; /* failed */
|
||||
|
||||
ret = usb_dev_add(devlistp, n, err_str);
|
||||
@@ -385,13 +373,13 @@ probe_devices(int bus)
|
||||
ctrl.bRequest = USB_REQ_GET_DESCRIPTOR;
|
||||
ctrl.wValue = USB_DT_DEVICE << 8;
|
||||
ctrl.wIndex = 0;
|
||||
ctrl.wLength = sizeof(descriptor);
|
||||
ctrl.wLength = sizeof(descriptor);
|
||||
#else
|
||||
ctrl.requesttype = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
|
||||
ctrl.request = USB_REQ_GET_DESCRIPTOR;
|
||||
ctrl.value = USB_DT_DEVICE << 8;
|
||||
ctrl.index = 0;
|
||||
ctrl.length = sizeof(descriptor);
|
||||
ctrl.length = sizeof(descriptor);
|
||||
#endif
|
||||
ctrl.data = descriptor;
|
||||
ctrl.timeout = CTRL_TIMEOUT;
|
||||
@@ -475,7 +463,7 @@ static int
|
||||
usb_activate(pcap_t* handle)
|
||||
{
|
||||
struct pcap_usb_linux *handlep = handle->priv;
|
||||
char full_path[USB_LINE_LEN];
|
||||
char full_path[USB_LINE_LEN];
|
||||
|
||||
/*
|
||||
* Turn a negative snapshot value (invalid), a snapshot value of
|
||||
@@ -512,7 +500,8 @@ usb_activate(pcap_t* handle)
|
||||
* We require 2.6.27 or later kernels, so we have binary-mode support.
|
||||
* Try to open the binary interface.
|
||||
*/
|
||||
snprintf(full_path, USB_LINE_LEN, LINUX_USB_MON_DEV"%d", handlep->bus_index);
|
||||
snprintf(full_path, USB_LINE_LEN, "/dev/"USBMON_DEV_PREFIX"%d",
|
||||
handlep->bus_index);
|
||||
handle->fd = open(full_path, O_RDONLY, 0);
|
||||
if (handle->fd < 0)
|
||||
{
|
||||
@@ -532,13 +521,23 @@ usb_activate(pcap_t* handle)
|
||||
* doesn't exist (no "scan all buses"
|
||||
* device if the bus index is 0, no
|
||||
* such bus if the bus index isn't 0).
|
||||
*
|
||||
* For now, don't provide an error message;
|
||||
* if we can determine what the particular
|
||||
* problem is, we should report that.
|
||||
*/
|
||||
handle->errbuf[0] = '\0';
|
||||
return PCAP_ERROR_NO_SUCH_DEVICE;
|
||||
|
||||
case EACCES:
|
||||
/*
|
||||
* We didn't have permission to open it.
|
||||
*/
|
||||
DIAG_OFF_FORMAT_TRUNCATION
|
||||
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
|
||||
"Attempt to open %s failed with EACCES - root privileges may be required",
|
||||
full_path);
|
||||
DIAG_ON_FORMAT_TRUNCATION
|
||||
return PCAP_ERROR_PERM_DENIED;
|
||||
|
||||
default:
|
||||
@@ -758,6 +757,7 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
|
||||
struct mon_bin_mfetch fetch;
|
||||
int32_t vec[VEC_SIZE];
|
||||
struct pcap_pkthdr pkth;
|
||||
u_char *bp;
|
||||
pcap_usb_header_mmapped* hdr;
|
||||
int nflush = 0;
|
||||
int packets = 0;
|
||||
@@ -767,13 +767,40 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
|
||||
|
||||
for (;;) {
|
||||
int i, ret;
|
||||
int limit = max_packets - packets;
|
||||
if (limit <= 0)
|
||||
limit = VEC_SIZE;
|
||||
if (limit > VEC_SIZE)
|
||||
limit = VEC_SIZE;
|
||||
int limit;
|
||||
|
||||
/* try to fetch as many events as possible*/
|
||||
if (PACKET_COUNT_IS_UNLIMITED(max_packets)) {
|
||||
/*
|
||||
* There's no limit on the number of packets
|
||||
* to process, so try to fetch VEC_SIZE packets.
|
||||
*/
|
||||
limit = VEC_SIZE;
|
||||
} else {
|
||||
/*
|
||||
* Try to fetch as many packets as we have left
|
||||
* to process, or VEC_SIZE packets, whichever
|
||||
* is less.
|
||||
*
|
||||
* At this point, max_packets > 0 (otherwise,
|
||||
* PACKET_COUNT_IS_UNLIMITED(max_packets)
|
||||
* would be true) and max_packets > packets
|
||||
* (packet starts out as 0, and the test
|
||||
* at the bottom of the loop exits if
|
||||
* max_packets <= packets), so limit is
|
||||
* guaranteed to be > 0.
|
||||
*/
|
||||
limit = max_packets - packets;
|
||||
if (limit > VEC_SIZE)
|
||||
limit = VEC_SIZE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to fetch as many events as possible, up to
|
||||
* the limit, and flush the events we've processed
|
||||
* earlier (nflush) - MON_IOCX_MFETCH does both
|
||||
* (presumably to reduce the number of system
|
||||
* calls in loops like this).
|
||||
*/
|
||||
fetch.offvec = vec;
|
||||
fetch.nfetch = limit;
|
||||
fetch.nflush = nflush;
|
||||
@@ -800,8 +827,27 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
|
||||
/* keep track of processed events, we will flush them later */
|
||||
nflush = fetch.nfetch;
|
||||
for (i=0; i<fetch.nfetch; ++i) {
|
||||
/*
|
||||
* XXX - we can't check break_loop here, as
|
||||
* we read the indices of packets into a
|
||||
* local variable, so if we're later called
|
||||
* to fetch more packets, those packets will
|
||||
* not be seen - and won't be flushed, either.
|
||||
*
|
||||
* Instead, we would have to keep the array
|
||||
* of indices in our private data, along
|
||||
* with the count of packets to flush - or
|
||||
* would have to flush the already-processed
|
||||
* packets if we break out of the loop here.
|
||||
*/
|
||||
|
||||
/* Get a pointer to this packet's buffer */
|
||||
bp = &handlep->mmapbuf[vec[i]];
|
||||
|
||||
/* That begins with a metadata header */
|
||||
hdr = (pcap_usb_header_mmapped*) bp;
|
||||
|
||||
/* discard filler */
|
||||
hdr = (pcap_usb_header_mmapped*) &handlep->mmapbuf[vec[i]];
|
||||
if (hdr->event_type == '@')
|
||||
continue;
|
||||
|
||||
@@ -846,6 +892,13 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
|
||||
*/
|
||||
pkth.len = sizeof(pcap_usb_header_mmapped) +
|
||||
(hdr->ndesc * sizeof (usb_isodesc)) + hdr->urb_len;
|
||||
|
||||
/*
|
||||
* Now clean it up if it's a completion
|
||||
* event for an incoming isochronous
|
||||
* transfer.
|
||||
*/
|
||||
fix_linux_usb_mmapped_length(&pkth, bp);
|
||||
}
|
||||
pkth.ts.tv_sec = (time_t)hdr->ts_sec;
|
||||
pkth.ts.tv_usec = hdr->ts_usec;
|
||||
@@ -859,8 +912,12 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
|
||||
}
|
||||
}
|
||||
|
||||
/* with max_packets specifying "unlimited" we stop after the first chunk*/
|
||||
if (PACKET_COUNT_IS_UNLIMITED(max_packets) || (packets == max_packets))
|
||||
/*
|
||||
* If max_packets specifiesg "unlimited", we stop after
|
||||
* the first chunk.
|
||||
*/
|
||||
if (PACKET_COUNT_IS_UNLIMITED(max_packets) ||
|
||||
(packets >= max_packets))
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user