1
0
mirror of https://github.com/nmap/nmap.git synced 2026-01-01 12:29:03 +00:00

Update libpcap to 1.10.5

This commit is contained in:
dmiller
2025-04-14 19:06:54 +00:00
parent 2bc341de52
commit aed27d094e
141 changed files with 12626 additions and 9811 deletions

View File

@@ -28,9 +28,7 @@
* dependent values so we can print the dump file on any architecture.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <pcap-types.h>
#ifdef _WIN32
@@ -90,7 +88,7 @@
#define FMESQUITA_TCPDUMP_MAGIC 0xa1b234cd
/*
* Navtel Communcations' format, with nanosecond timestamps,
* Navtel Communications' format, with nanosecond timestamps,
* as per a request from Dumas Hwang <dumas.hwang@navtelcom.com>.
*/
#define NAVTEL_TCPDUMP_MAGIC 0xa12b3c4d
@@ -102,16 +100,79 @@
#define NSEC_TCPDUMP_MAGIC 0xa1b23c4d
/*
* Mechanism for storing information about a capture in the upper
* 6 bits of a linktype value in a capture file.
* This is a timeval as stored in a savefile.
* It has to use the same types everywhere, independent of the actual
* `struct timeval'; `struct timeval' has 32-bit tv_sec values on some
* platforms and 64-bit tv_sec values on other platforms, and writing
* out native `struct timeval' values would mean files could only be
* read on systems with the same tv_sec size as the system on which
* the file was written.
*
* LT_LINKTYPE_EXT(x) extracts the additional information.
*
* The rest of the bits are for a value describing the link-layer
* value. LT_LINKTYPE(x) extracts that value.
* THe fields are unsigned, as that's what the pcap draft specification
* says they are. (That gives pcap a 68-year Y2.038K reprieve, although
* in 2106 it runs out for good. pcapng doesn't have that problem,
* unless you pick a *really* high time stamp precision.)
*/
#define LT_LINKTYPE(x) ((x) & 0x03FFFFFF)
#define LT_LINKTYPE_EXT(x) ((x) & 0xFC000000)
struct pcap_timeval {
bpf_u_int32 tv_sec; /* seconds */
bpf_u_int32 tv_usec; /* microseconds */
};
/*
* This is a `pcap_pkthdr' as actually stored in a savefile.
*
* Do not change the format of this structure, in any way (this includes
* changes that only affect the length of fields in this structure),
* and do not make the time stamp anything other than seconds and
* microseconds (e.g., seconds and nanoseconds). Instead:
*
* introduce a new structure for the new format;
*
* send mail to "tcpdump-workers@lists.tcpdump.org", requesting
* a new magic number for your new capture file format, and, when
* you get the new magic number, put it in "savefile.c";
*
* use that magic number for save files with the changed record
* header;
*
* make the code in "savefile.c" capable of reading files with
* the old record header as well as files with the new record header
* (using the magic number to determine the header format).
*
* Then supply the changes by forking the branch at
*
* https://github.com/the-tcpdump-group/libpcap/tree/master
*
* and issuing a pull request, so that future versions of libpcap and
* programs that use it (such as tcpdump) will be able to read your new
* capture file format.
*/
struct pcap_sf_pkthdr {
struct pcap_timeval ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /* length of this packet (off wire) */
};
/*
* How a `pcap_pkthdr' is actually stored in savefiles written
* by some patched versions of libpcap (e.g. the ones in Red
* Hat Linux 6.1 and 6.2).
*
* Do not change the format of this structure, in any way (this includes
* changes that only affect the length of fields in this structure).
* Instead, introduce a new structure, as per the above.
*/
struct pcap_sf_patched_pkthdr {
struct pcap_timeval ts; /* time stamp */
bpf_u_int32 caplen; /* length of portion present */
bpf_u_int32 len; /* length of this packet (off wire) */
int index;
unsigned short protocol;
unsigned char pkt_type;
};
static int pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **datap);
@@ -196,7 +257,7 @@ pcap_check_header(const uint8_t *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_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
pcapint_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "error reading dump file");
} else {
snprintf(errbuf, PCAP_ERRBUF_SIZE,
@@ -241,6 +302,17 @@ pcap_check_header(const uint8_t *magic, FILE *fp, u_int precision, char *errbuf,
return NULL;
}
/*
* Check the main reserved field.
*/
if (LT_RESERVED1(hdr.linktype) != 0) {
snprintf(errbuf, PCAP_ERRBUF_SIZE,
"savefile linktype reserved field not zero (0x%08x)",
LT_RESERVED1(hdr.linktype));
*err = 1;
return NULL;
}
/*
* OK, this is a good pcap file.
* Allocate a pcap_t for it.
@@ -256,7 +328,7 @@ pcap_check_header(const uint8_t *magic, FILE *fp, u_int precision, char *errbuf,
p->version_minor = hdr.version_minor;
p->linktype = linktype_to_dlt(LT_LINKTYPE(hdr.linktype));
p->linktype_ext = LT_LINKTYPE_EXT(hdr.linktype);
p->snapshot = pcap_adjust_snapshot(p->linktype, hdr.snaplen);
p->snapshot = pcapint_adjust_snapshot(p->linktype, hdr.snaplen);
p->next_packet_op = pcap_next_packet;
@@ -414,7 +486,7 @@ pcap_check_header(const uint8_t *magic, FILE *fp, u_int precision, char *errbuf,
return (NULL);
}
p->cleanup_op = sf_cleanup;
p->cleanup_op = pcapint_sf_cleanup;
return (p);
}
@@ -461,7 +533,7 @@ 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_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "error reading dump file");
return (-1);
} else {
@@ -586,7 +658,7 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
* However, perhaps some versions of libpcap failed to
* set the snapshot length correctly in the file header
* or the per-packet header, or perhaps this is a
* corrupted safefile or a savefile built/modified by a
* corrupted savefile 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
@@ -615,7 +687,7 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
amt_read = fread(p->buffer, 1, p->snapshot, fp);
if (amt_read != (bpf_u_int32)p->snapshot) {
if (ferror(fp)) {
pcap_fmt_errmsg_for_errno(p->errbuf,
pcapint_fmt_errmsg_for_errno(p->errbuf,
PCAP_ERRBUF_SIZE, errno,
"error reading dump file");
} else {
@@ -646,7 +718,7 @@ 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_fmt_errmsg_for_errno(p->errbuf,
pcapint_fmt_errmsg_for_errno(p->errbuf,
PCAP_ERRBUF_SIZE, errno,
"error reading dump file");
} else {
@@ -698,7 +770,7 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
amt_read = fread(p->buffer, 1, hdr->caplen, fp);
if (amt_read != hdr->caplen) {
if (ferror(fp)) {
pcap_fmt_errmsg_for_errno(p->errbuf,
pcapint_fmt_errmsg_for_errno(p->errbuf,
PCAP_ERRBUF_SIZE, errno,
"error reading dump file");
} else {
@@ -711,7 +783,7 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
}
*data = p->buffer;
pcap_post_process(p->linktype, p->swapped, hdr, *data);
pcapint_post_process(p->linktype, p->swapped, hdr, *data);
return (1);
}
@@ -727,9 +799,8 @@ sf_write_header(pcap_t *p, FILE *fp, int linktype, int snaplen)
/*
* https://www.tcpdump.org/manpages/pcap-savefile.5.txt states:
* thiszone: 4-byte time zone offset; this is always 0.
* sigfigs: 4-byte number giving the accuracy of time stamps
* in the file; this is always 0.
* thiszone (Reserved1): 4-byte not used - SHOULD be filled with 0
* sigfigs (Reserved2): 4-byte not used - SHOULD be filled with 0
*/
hdr.thiszone = 0;
hdr.sigfigs = 0;
@@ -772,10 +843,17 @@ pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
return;
/*
* Better not try writing pcap files after
* 2038-01-19 03:14:07 UTC; switch to pcapng.
* 2106-02-07 06:28:15 UTC; switch to pcapng.
* (And better not try writing pcap files with time stamps
* that predate 1970-01-01 00:00:00 UTC; that's not supported.
* You could try using pcapng with the if_tsoffset field in
* the IDB for the interface(s) with packets with those time
* stamps, but you may also have to get a link-layer type for
* IBM Bisync or whatever link layer even older forms
* of computer communication used.)
*/
sf_hdr.ts.tv_sec = (bpf_int32)h->ts.tv_sec;
sf_hdr.ts.tv_usec = (bpf_int32)h->ts.tv_usec;
sf_hdr.ts.tv_sec = (bpf_u_int32)h->ts.tv_sec;
sf_hdr.ts.tv_usec = (bpf_u_int32)h->ts.tv_usec;
sf_hdr.caplen = h->caplen;
sf_hdr.len = h->len;
/*
@@ -809,7 +887,7 @@ pcap_setup_dump(pcap_t *p, int linktype, FILE *f, const char *fname)
setvbuf(f, NULL, _IONBF, 0);
#endif
if (sf_write_header(p, f, linktype, p->snapshot) == -1) {
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't write to %s", fname);
if (f != stdout)
(void)fclose(f);
@@ -861,9 +939,9 @@ pcap_dump_open(pcap_t *p, const char *fname)
* required on Windows, as the file is a binary file
* and must be written in binary mode.
*/
f = charset_fopen(fname, "wb");
f = pcapint_charset_fopen(fname, "wb");
if (f == NULL) {
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "%s", fname);
return (NULL);
}
@@ -884,14 +962,14 @@ pcap_dump_hopen(pcap_t *p, intptr_t osfd)
fd = _open_osfhandle(osfd, _O_APPEND);
if (fd < 0) {
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "_open_osfhandle");
return NULL;
}
file = _fdopen(fd, "wb");
if (file == NULL) {
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "_fdopen");
_close(fd);
return NULL;
@@ -961,9 +1039,9 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
* 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 = charset_fopen(fname, "ab+");
f = pcapint_charset_fopen(fname, "ab+");
if (f == NULL) {
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "%s", fname);
return (NULL);
}
@@ -981,7 +1059,7 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
* compliant systems or on Windows.
*/
if (fseek(f, 0, SEEK_SET) == -1) {
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't seek to the beginning of %s", fname);
(void)fclose(f);
return (NULL);
@@ -989,7 +1067,7 @@ 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_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "%s", fname);
(void)fclose(f);
return (NULL);
@@ -1097,7 +1175,7 @@ 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->snapshot) == -1) {
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't write to %s", fname);
(void)fclose(f);
return (NULL);
@@ -1112,7 +1190,7 @@ pcap_dump_open_append(pcap_t *p, const char *fname)
* are done at the end of the file in that mode.
*/
if (fseek(f, 0, SEEK_END) == -1) {
pcap_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
pcapint_fmt_errmsg_for_errno(p->errbuf, PCAP_ERRBUF_SIZE,
errno, "Can't seek to the end of %s", fname);
(void)fclose(f);
return (NULL);