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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user