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

Update libpcap to 1.9.0 (no patches applied yet)

This commit is contained in:
dmiller
2019-03-30 03:24:44 +00:00
parent 7d860b04e5
commit a2442ea29f
197 changed files with 26419 additions and 22082 deletions

View File

@@ -28,27 +28,14 @@
* dependent values so we can print the dump file on any architecture.
*/
#ifndef lint
static const char rcsid[] _U_ =
"@(#) $Header$ (LBL)";
#endif
#ifdef HAVE_CONFIG_H
#include "config.h"
#include <config.h>
#endif
#include <pcap-types.h>
#ifdef _WIN32
#include <pcap-stdinc.h>
#else /* _WIN32 */
#if HAVE_INTTYPES_H
#include <inttypes.h>
#elif HAVE_STDINT_H
#include <stdint.h>
#endif
#ifdef HAVE_SYS_BITYPES_H
#include <sys/bitypes.h>
#endif
#include <sys/types.h>
#include <io.h>
#include <fcntl.h>
#endif /* _WIN32 */
#include <errno.h>
@@ -185,9 +172,8 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
sizeof(hdr) - sizeof(hdr.magic), fp);
if (amt_read != sizeof(hdr) - sizeof(hdr.magic)) {
if (ferror(fp)) {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"error reading dump file: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "error reading dump file");
} else {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"truncated dump file; tried to read %lu file header bytes, only got %lu",
@@ -232,14 +218,6 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
return NULL;
}
if (hdr.snaplen > MAXIMUM_SNAPLEN) {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE,
"invalid file capture length %u, bigger than "
"maximum of %u", hdr.snaplen, MAXIMUM_SNAPLEN);
*err = 1;
return NULL;
}
/*
* OK, this is a good pcap file.
* Allocate a pcap_t for it.
@@ -255,6 +233,17 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
p->version_minor = hdr.version_minor;
p->tzoff = hdr.thiszone;
p->snapshot = hdr.snaplen;
if (p->snapshot <= 0) {
/*
* Bogus snapshot length; use the maximum for this
* link-layer type as a fallback.
*
* XXX - the only reason why snapshot is signed is
* that pcap_snapshot() returns an int, not an
* unsigned int.
*/
p->snapshot = max_snaplen_for_dlt(hdr.linktype);
}
p->linktype = linktype_to_dlt(LT_LINKTYPE(hdr.linktype));
p->linktype_ext = LT_LINKTYPE_EXT(hdr.linktype);
@@ -390,14 +379,16 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
/*
* Allocate a buffer for the packet data.
* Choose the minimum of the file's snapshot length and 2K bytes;
* that should be enough for most network packets - we'll grow it
* if necessary. That way, we don't allocate a huge chunk of
* memory just because there's a huge snapshot length, as the
* snapshot length might be larger than the size of the largest
* packet.
*/
p->bufsize = p->snapshot;
if (p->bufsize <= 0) {
/*
* Bogus snapshot length; use the maximum as a fallback.
*/
p->bufsize = MAXIMUM_SNAPLEN;
}
if (p->bufsize > 2048)
p->bufsize = 2048;
p->buffer = malloc(p->bufsize);
if (p->buffer == NULL) {
pcap_snprintf(errbuf, PCAP_ERRBUF_SIZE, "out of memory");
@@ -411,6 +402,24 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
return (p);
}
/*
* Grow the packet buffer to the specified size.
*/
static int
grow_buffer(pcap_t *p, u_int bufsize)
{
void *bigger_buffer;
bigger_buffer = realloc(p->buffer, bufsize);
if (bigger_buffer == NULL) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "out of memory");
return (0);
}
p->buffer = bigger_buffer;
p->bufsize = bufsize;
return (1);
}
/*
* Read and return the next packet from the savefile. Return the header
* in hdr and a pointer to the contents in data. Return 0 on success, 1
@@ -435,9 +444,8 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
amt_read = fread(&sf_hdr, 1, ps->hdrsize, fp);
if (amt_read != ps->hdrsize) {
if (ferror(fp)) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"error reading dump file: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "error reading dump file");
return (-1);
} else {
if (amt_read != 0) {
@@ -513,41 +521,87 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
break;
}
if (hdr->caplen > p->bufsize) {
/*
* Is the packet bigger than we consider sane?
*/
if (hdr->caplen > max_snaplen_for_dlt(p->linktype)) {
/*
* Yes. This may be a damaged or fuzzed file.
*
* Is it bigger than the snapshot length?
* (We don't treat that as an error if it's not
* bigger than the maximum we consider sane; see
* below.)
*/
if (hdr->caplen > (bpf_u_int32)p->snapshot) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"invalid packet capture length %u, bigger than "
"snaplen of %d", hdr->caplen, p->snapshot);
} else {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"invalid packet capture length %u, bigger than "
"maximum of %u", hdr->caplen,
max_snaplen_for_dlt(p->linktype));
}
return (-1);
}
if (hdr->caplen > (bpf_u_int32)p->snapshot) {
/*
* The packet is bigger than the snapshot length
* for this file.
*
* This can happen due to Solaris 2.3 systems tripping
* over the BUFMOD problem and not setting the snapshot
* correctly in the savefile header.
* This can also happen with a corrupted savefile or a
* savefile built/modified by a fuzz tester.
* If the caplen isn't grossly wrong, try to salvage.
* length correctly in the savefile header.
*
* libpcap 0.4 and later on Solaris 2.3 should set the
* snapshot length correctly in the pcap file header,
* even though they don't set a snapshot length in bufmod
* (the buggy bufmod chops off the *beginning* of the
* packet if a snapshot length is specified); they should
* also reduce the captured length, as supplied to the
* per-packet callback, to the snapshot length if it's
* greater than the snapshot length, so the code using
* libpcap should see the packet cut off at the snapshot
* length, even though the full packet is copied up to
* userland.
*
* However, perhaps some versions of libpcap failed to
* set the snapshot length currectly in the file header
* or the per-packet header, or perhaps this is a
* corrupted safefile or a savefile built/modified by a
* fuzz tester, so we check anyway. We grow the buffer
* to be big enough for the snapshot length, read up
* to the snapshot length, discard the rest of the
* packet, and report the snapshot length as the captured
* length; we don't want to hand our caller a packet
* bigger than the snapshot length, because they might
* be assuming they'll never be handed such a packet,
* and might copy the packet into a snapshot-length-
* sized buffer, assuming it'll fit.
*/
size_t bytes_to_discard;
size_t bytes_to_read, bytes_read;
char discard_buf[4096];
if (hdr->caplen > MAXIMUM_SNAPLEN) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"invalid packet capture length %u, bigger than "
"maximum of %u", hdr->caplen, MAXIMUM_SNAPLEN);
return (-1);
if (hdr->caplen > p->bufsize) {
/*
* Grow the buffer to the snapshot length.
*/
if (!grow_buffer(p, p->snapshot))
return (-1);
}
/*
* XXX - we don't grow the buffer here because some
* program might assume that it will never get packets
* bigger than the snapshot length; for example, it might
* copy data from our buffer to a buffer of its own,
* allocated based on the return value of pcap_snapshot().
*
* Read the first p->bufsize bytes into the buffer.
* Read the first p->snapshot bytes into the buffer.
*/
amt_read = fread(p->buffer, 1, p->bufsize, fp);
if (amt_read != p->bufsize) {
amt_read = fread(p->buffer, 1, p->snapshot, fp);
if (amt_read != (bpf_u_int32)p->snapshot) {
if (ferror(fp)) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"error reading dump file: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf,
PCAP_ERRBUF_SIZE, errno,
"error reading dump file");
} else {
/*
* Yes, this uses hdr->caplen; technically,
@@ -558,7 +612,7 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
*/
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"truncated dump file; tried to read %u captured bytes, only got %lu",
hdr->caplen, (unsigned long)amt_read);
p->snapshot, (unsigned long)amt_read);
}
return (-1);
}
@@ -566,7 +620,7 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
/*
* Now read and discard what's left.
*/
bytes_to_discard = hdr->caplen - p->bufsize;
bytes_to_discard = hdr->caplen - p->snapshot;
bytes_read = amt_read;
while (bytes_to_discard != 0) {
bytes_to_read = bytes_to_discard;
@@ -576,9 +630,9 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
bytes_read += amt_read;
if (amt_read != bytes_to_read) {
if (ferror(fp)) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"error reading dump file: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf,
PCAP_ERRBUF_SIZE, errno,
"error reading dump file");
} else {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"truncated dump file; tried to read %u captured bytes, only got %lu",
@@ -593,15 +647,41 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
* Adjust caplen accordingly, so we don't get confused later
* as to how many bytes we have to play with.
*/
hdr->caplen = p->bufsize;
hdr->caplen = p->snapshot;
} else {
if (hdr->caplen > p->bufsize) {
/*
* Grow the buffer to the next power of 2, or
* the snaplen, whichever is lower.
*/
u_int new_bufsize;
new_bufsize = hdr->caplen;
/*
* http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
*/
new_bufsize--;
new_bufsize |= new_bufsize >> 1;
new_bufsize |= new_bufsize >> 2;
new_bufsize |= new_bufsize >> 4;
new_bufsize |= new_bufsize >> 8;
new_bufsize |= new_bufsize >> 16;
new_bufsize++;
if (new_bufsize > (u_int)p->snapshot)
new_bufsize = p->snapshot;
if (!grow_buffer(p, new_bufsize))
return (-1);
}
/* read the packet itself */
amt_read = fread(p->buffer, 1, hdr->caplen, fp);
if (amt_read != hdr->caplen) {
if (ferror(fp)) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"error reading dump file: %s",
pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf,
PCAP_ERRBUF_SIZE, errno,
"error reading dump file");
} else {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"truncated dump file; tried to read %u captured bytes, only got %lu",
@@ -672,11 +752,11 @@ pcap_setup_dump(pcap_t *p, int linktype, FILE *f, const char *fname)
if (f == stdout)
SET_BINMODE(f);
else
setbuf(f, NULL);
setvbuf(f, NULL, _IONBF, 0);
#endif
if (sf_write_header(p, f, linktype, p->tzoff, p->snapshot) == -1) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Can't write to %s: %s",
fname, pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't write to %s", fname);
if (f != stdout)
(void)fclose(f);
return (NULL);
@@ -721,14 +801,16 @@ pcap_dump_open(pcap_t *p, const char *fname)
f = stdout;
fname = "standard output";
} else {
#if !defined(_WIN32) && !defined(MSDOS)
f = fopen(fname, "w");
#else
/*
* "b" is supported as of C90, so *all* UN*Xes should
* support it, even though it does nothing. It's
* required on Windows, as the file is a binary file
* and must be written in binary mode.
*/
f = fopen(fname, "wb");
#endif
if (f == NULL) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
fname, pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "%s", fname);
return (NULL);
}
}
@@ -779,14 +861,15 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
if (fname[0] == '-' && fname[1] == '\0')
return (pcap_setup_dump(p, linktype, stdout, "standard output"));
#if !defined(_WIN32) && !defined(MSDOS)
f = fopen(fname, "r+");
#else
/*
* "b" is supported as of C90, so *all* UN*Xes should support it,
* even though it does nothing. It's required on Windows, as the
* file is a binary file and must be read in binary mode.
*/
f = fopen(fname, "rb+");
#endif
if (f == NULL) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
fname, pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "%s", fname);
return (NULL);
}
@@ -796,8 +879,8 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
amt_read = fread(&ph, 1, sizeof (ph), f);
if (amt_read != sizeof (ph)) {
if (ferror(f)) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "%s: %s",
fname, pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "%s", fname);
fclose(f);
return (NULL);
} else if (feof(f) && amt_read > 0) {
@@ -813,7 +896,7 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
* We turn off buffering.
* XXX - why? And why not on the standard output?
*/
setbuf(f, NULL);
setvbuf(f, NULL, _IONBF, 0);
#endif
/*
@@ -904,8 +987,8 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
* A header isn't present; attempt to write it.
*/
if (sf_write_header(p, f, linktype, p->tzoff, p->snapshot) == -1) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Can't write to %s: %s",
fname, pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't write to %s", fname);
(void)fclose(f);
return (NULL);
}
@@ -915,8 +998,8 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
* Start writing at the end of the file.
*/
if (fseek(f, 0, SEEK_END) == -1) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE, "Can't seek to end of %s: %s",
fname, pcap_strerror(errno));
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't seek to end of %s", fname);
(void)fclose(f);
return (NULL);
}
@@ -935,6 +1018,45 @@ pcap_dump_ftell(pcap_dumper_t *p)
return (ftell((FILE *)p));
}
#if defined(HAVE_FSEEKO)
/*
* We have fseeko(), so we have ftello().
* If we have large file support (files larger than 2^31-1 bytes),
* ftello() will give us a current file position with more than 32
* bits.
*/
int64_t
pcap_dump_ftell64(pcap_dumper_t *p)
{
return (ftello((FILE *)p));
}
#elif defined(_MSC_VER)
/*
* We have Visual Studio; we support only 2005 and later, so we have
* _ftelli64().
*/
int64_t
pcap_dump_ftell64(pcap_dumper_t *p)
{
return (_ftelli64((FILE *)p));
}
#else
/*
* We don't have ftello() or _ftelli64(), so fall back on ftell().
* Either long is 64 bits, in which case ftell() should suffice,
* or this is probably an older 32-bit UN*X without large file
* support, which means you'll probably get errors trying to
* write files > 2^31-1, so it won't matter anyway.
*
* XXX - what about MinGW?
*/
int64_t
pcap_dump_ftell64(pcap_dumper_t *p)
{
return (ftell((FILE *)p));
}
#endif
int
pcap_dump_flush(pcap_dumper_t *p)
{