1
0
mirror of https://github.com/nmap/nmap.git synced 2025-12-26 09:29:01 +00:00

Upgrade our included libpcap to 1.1.1.

This commit is contained in:
david
2010-04-21 04:39:45 +00:00
parent e34bd54d68
commit 4ac98563ab
160 changed files with 11540 additions and 8247 deletions

View File

@@ -34,7 +34,7 @@
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header: /tcpdump/master/libpcap/pcap-usb-linux.c,v 1.16.2.8 2008-04-14 21:06:29 guy Exp $ (LBL)";
"@(#) $Header: /tcpdump/master/libpcap/pcap-usb-linux.c,v 1.33 2008-12-23 21:38:50 guy Exp $ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
@@ -60,19 +60,17 @@ static const char rcsid[] _U_ =
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#ifdef HAVE_LINUX_USBDEVICE_FS_H
#include <linux/usbdevice_fs.h>
#endif
#define USB_IFACE "usb"
#define USB_TEXT_DIR "/sys/kernel/debug/usbmon"
#define USB_BUS_DIR "/proc/bus/usb"
#define USB_IFACE "usbmon"
#define USB_TEXT_DIR_OLD "/sys/kernel/debug/usbmon"
#define USB_TEXT_DIR "/sys/kernel/debug/usb/usbmon"
#define SYS_USB_BUS_DIR "/sys/bus/usb/devices"
#define PROC_USB_BUS_DIR "/proc/bus/usb"
#define USB_LINE_LEN 4096
#define PIPE_IN 0x80
#define PIPE_ISOCHRONOUS 0
#define PIPE_INTERRUPT 1
#define PIPE_CONTROL 2
#define PIPE_BULK 3
#if __BYTE_ORDER == __LITTLE_ENDIAN
#define htols(s) s
#define htoll(l) l
@@ -149,27 +147,52 @@ usb_platform_finddevs(pcap_if_t **alldevsp, char *err_str)
struct dirent* data;
int ret = 0;
DIR* dir;
int n;
char* name;
size_t len;
/* scan procfs usb bus directory */
dir = opendir(USB_BUS_DIR);
if (!dir) return 0;
while ((ret == 0) && ((data = readdir(dir)) != 0)) {
int n;
char* name = data->d_name;
int len = strlen(name);
/* try scanning sysfs usb bus directory */
dir = opendir(SYS_USB_BUS_DIR);
if (dir != NULL) {
while ((ret == 0) && ((data = readdir(dir)) != 0)) {
name = data->d_name;
/* if this file name does not end with a number it's not of our interest */
if ((len < 1) || !isdigit(name[--len]))
continue;
while (isdigit(name[--len]));
if (sscanf(&name[len+1], "%d", &n) != 1)
continue;
if (strncmp(name, "usb", 3) != 0)
continue;
ret = usb_dev_add(alldevsp, n, err_str);
if (sscanf(&name[3], "%d", &n) == 0)
continue;
ret = usb_dev_add(alldevsp, n, err_str);
}
closedir(dir);
return ret;
}
closedir(dir);
return ret;
/* that didn't work; try scanning procfs usb bus directory */
dir = opendir(PROC_USB_BUS_DIR);
if (dir != NULL) {
while ((ret == 0) && ((data = readdir(dir)) != 0)) {
name = data->d_name;
len = strlen(name);
/* if this file name does not end with a number it's not of our interest */
if ((len < 1) || !isdigit(name[--len]))
continue;
while (isdigit(name[--len]));
if (sscanf(&name[len+1], "%d", &n) != 1)
continue;
ret = usb_dev_add(alldevsp, n, err_str);
}
closedir(dir);
return ret;
}
/* neither of them worked */
return 0;
}
static
@@ -179,8 +202,79 @@ int usb_mmap(pcap_t* handle)
if (len < 0)
return 0;
handle->buffer = mmap(0, len, PROT_READ, MAP_SHARED, handle->fd, 0);
return handle->buffer != MAP_FAILED;
handle->md.mmapbuflen = len;
handle->md.mmapbuf = mmap(0, handle->md.mmapbuflen, PROT_READ,
MAP_SHARED, handle->fd, 0);
return handle->md.mmapbuf != MAP_FAILED;
}
#define CTRL_TIMEOUT (5*1000) /* milliseconds */
#define USB_DIR_IN 0x80
#define USB_TYPE_STANDARD 0x00
#define USB_RECIP_DEVICE 0x00
#define USB_REQ_GET_DESCRIPTOR 6
#define USB_DT_DEVICE 1
/* probe the descriptors of the devices attached to the bus */
/* the descriptors will end up in the captured packet stream */
/* and be decoded by external apps like wireshark */
/* without these identifying probes packet data can't be fully decoded */
static void
probe_devices(int bus)
{
struct usbdevfs_ctrltransfer ctrl;
struct dirent* data;
int ret = 0;
char buf[40];
DIR* dir;
/* scan usb bus directories for device nodes */
snprintf(buf, sizeof(buf), "/dev/bus/usb/%03d", bus);
dir = opendir(buf);
if (!dir)
return;
while ((ret >= 0) && ((data = readdir(dir)) != 0)) {
int fd;
char* name = data->d_name;
if (name[0] == '.')
continue;
snprintf(buf, sizeof(buf), "/dev/bus/usb/%03d/%s", bus, data->d_name);
fd = open(buf, O_RDWR);
if (fd == -1)
continue;
/*
* Sigh. Different kernels have different member names
* for this structure.
*/
#ifdef HAVE_USBDEVFS_CTRLTRANSFER_BREQUESTTYPE
ctrl.bRequestType = USB_DIR_IN | USB_TYPE_STANDARD | USB_RECIP_DEVICE;
ctrl.bRequest = USB_REQ_GET_DESCRIPTOR;
ctrl.wValue = USB_DT_DEVICE << 8;
ctrl.wIndex = 0;
ctrl.wLength = sizeof(buf);
#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(buf);
#endif
ctrl.data = buf;
ctrl.timeout = CTRL_TIMEOUT;
ret = ioctl(fd, USBDEVFS_CONTROL, &ctrl);
close(fd);
}
closedir(dir);
}
pcap_t *
@@ -230,14 +324,17 @@ usb_activate(pcap_t* handle)
/*
* Monitor mode doesn't apply to USB devices.
*/
close(handle->fd);
return PCAP_ERROR_RFMON_NOTSUP;
}
/* binary api is available, try to use fast mmap access */
if (usb_mmap(handle)) {
handle->linktype = DLT_USB_LINUX_MMAPPED;
handle->stats_op = usb_stats_linux_bin;
handle->read_op = usb_read_linux_mmap;
handle->cleanup_op = usb_cleanup_linux_mmap;
probe_devices(handle->md.ifindex);
/*
* "handle->fd" is a real file, so "select()" and
@@ -250,6 +347,7 @@ usb_activate(pcap_t* handle)
/* can't mmap, use plain binary interface access */
handle->stats_op = usb_stats_linux_bin;
handle->read_op = usb_read_linux_bin;
probe_devices(handle->md.ifindex);
}
else {
/*Binary interface not available, try open text interface */
@@ -257,22 +355,35 @@ usb_activate(pcap_t* handle)
handle->fd = open(full_path, O_RDONLY, 0);
if (handle->fd < 0)
{
/* no more fallback, give it up*/
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't open USB bus file %s: %s", full_path, strerror(errno));
return PCAP_ERROR;
if (errno == ENOENT)
{
/*
* Not found at the new location; try
* the old location.
*/
snprintf(full_path, USB_LINE_LEN, USB_TEXT_DIR_OLD"/%dt", handle->md.ifindex);
handle->fd = open(full_path, O_RDONLY, 0);
}
if (handle->fd < 0) {
/* no more fallback, give it up*/
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't open USB bus file %s: %s", full_path, strerror(errno));
return PCAP_ERROR;
}
}
if (handle->opt.rfmon) {
/*
* Monitor mode doesn't apply to USB devices.
*/
close(handle->fd);
return PCAP_ERROR_RFMON_NOTSUP;
}
handle->stats_op = usb_stats_linux;
handle->read_op = usb_read_linux;
}
if (handle->opt.rfmon) {
/*
* Monitor mode doesn't apply to USB devices.
*/
return PCAP_ERROR_RFMON_NOTSUP;
}
/*
* "handle->fd" is a real file, so "select()" and "poll()"
* work on it.
@@ -285,6 +396,7 @@ usb_activate(pcap_t* handle)
if (!handle->buffer) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"malloc: %s", pcap_strerror(errno));
close(handle->fd);
return PCAP_ERROR;
}
return 0;
@@ -351,7 +463,6 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u
return -1;
}
uhdr->id = tag;
uhdr->endpoint_number = ep_num;
uhdr->device_address = dev_addr;
uhdr->bus_id = handle->md.ifindex;
uhdr->status = 0;
@@ -378,7 +489,7 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u
else if (pipeid1 == 'B')
urb_transfer = URB_BULK;
if (pipeid2 == 'i') {
urb_transfer |= URB_TRANSFER_IN;
ep_num |= URB_TRANSFER_IN;
incoming = 1;
}
if (etype == 'C')
@@ -395,6 +506,7 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u
return 0;
uhdr->event_type = etype;
uhdr->transfer_type = urb_transfer;
uhdr->endpoint_number = ep_num;
pkth.caplen = sizeof(pcap_usb_header);
rawdata += sizeof(pcap_usb_header);
@@ -447,7 +559,7 @@ usb_read_linux(pcap_t *handle, int max_packets, pcap_handler callback, u_char *u
uhdr->urb_len = urb_len;
uhdr->data_flag = 1;
data_len = 0;
if (uhdr->urb_len == pkth.caplen)
if (uhdr->urb_len == 0)
goto got;
/* check for data presence; data is present if and only if urb tag is '=' */
@@ -508,15 +620,27 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
char string[USB_LINE_LEN];
char token[USB_LINE_LEN];
char * ptr = string;
snprintf(string, USB_LINE_LEN, USB_TEXT_DIR"/%ds", handle->md.ifindex);
int fd;
int fd = open(string, O_RDONLY, 0);
snprintf(string, USB_LINE_LEN, USB_TEXT_DIR"/%ds", handle->md.ifindex);
fd = open(string, O_RDONLY, 0);
if (fd < 0)
{
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't open USB stats file %s: %s",
string, strerror(errno));
return -1;
if (errno == ENOENT)
{
/*
* Not found at the new location; try the old
* location.
*/
snprintf(string, USB_LINE_LEN, USB_TEXT_DIR_OLD"/%ds", handle->md.ifindex);
fd = open(string, O_RDONLY, 0);
}
if (fd < 0) {
snprintf(handle->errbuf, PCAP_ERRBUF_SIZE,
"Can't open USB stats file %s: %s",
string, strerror(errno));
return -1;
}
}
/* read stats line */
@@ -541,8 +665,10 @@ usb_stats_linux(pcap_t *handle, struct pcap_stat *stats)
* of execution" but the Corrigendum seems to contradict this.
* Do not make any assumptions on the effect of %n conversions
* on the return value and explicitly check for cnt assignmet*/
int ntok;
cnt = -1;
int ntok = sscanf(ptr, "%s%n", token, &cnt);
ntok = sscanf(ptr, "%s%n", token, &cnt);
if ((ntok < 1) || (cnt < 0))
break;
consumed += cnt;
@@ -590,7 +716,8 @@ usb_stats_linux_bin(pcap_t *handle, struct pcap_stat *stats)
}
stats->ps_recv = handle->md.packets_read + st.queued;
stats->ps_ifdrop = st.dropped;
stats->ps_drop = st.dropped;
stats->ps_ifdrop = 0;
return 0;
}
@@ -636,7 +763,7 @@ usb_read_linux_bin(pcap_t *handle, int max_packets, pcap_handler callback, u_cha
clen = info.hdr->data_len;
info.hdr->data_len = clen;
pkth.caplen = clen + sizeof(pcap_usb_header);
pkth.len = info.hdr->urb_len + sizeof(pcap_usb_header);
pkth.len = info.hdr->data_len + sizeof(pcap_usb_header);
pkth.ts.tv_sec = info.hdr->ts_sec;
pkth.ts.tv_usec = info.hdr->ts_usec;
@@ -659,6 +786,9 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
pcap_usb_header* hdr;
int nflush = 0;
int packets = 0;
int clen, max_clen;
max_clen = handle->snapshot - sizeof(pcap_usb_header);
for (;;) {
int i, ret;
@@ -695,13 +825,19 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
nflush = fetch.nfetch;
for (i=0; i<fetch.nfetch; ++i) {
/* discard filler */
hdr = (pcap_usb_header*) &handle->buffer[vec[i]];
hdr = (pcap_usb_header*) &handle->md.mmapbuf[vec[i]];
if (hdr->event_type == '@')
continue;
/* we can get less that than really captured from kernel, depending on
* snaplen, so adjust header accordingly */
clen = max_clen;
if (hdr->data_len < clen)
clen = hdr->data_len;
/* get packet info from header*/
pkth.caplen = hdr->data_len + sizeof(pcap_usb_header);
pkth.len = hdr->urb_len + sizeof(pcap_usb_header);
pkth.caplen = clen + sizeof(pcap_usb_header_mmapped);
pkth.len = hdr->data_len + sizeof(pcap_usb_header_mmapped);
pkth.ts.tv_sec = hdr->ts_sec;
pkth.ts.tv_usec = hdr->ts_usec;
@@ -723,8 +859,10 @@ usb_read_linux_mmap(pcap_t *handle, int max_packets, pcap_handler callback, u_ch
static void
usb_cleanup_linux_mmap(pcap_t* handle)
{
/* buffer must not be freed because it's memory mapped */
/* XXX - does it need to be unmapped? */
handle->buffer = NULL;
/* if we have a memory-mapped buffer, unmap it */
if (handle->md.mmapbuf != NULL) {
munmap(handle->md.mmapbuf, handle->md.mmapbuflen);
handle->md.mmapbuf = NULL;
}
pcap_cleanup_live_common(handle);
}