213 lines
7.6 KiB
Diff
213 lines
7.6 KiB
Diff
From 2e9d0ae34ece4d6f67f4d66a4c3628febf0b13dd Mon Sep 17 00:00:00 2001
|
|
From: Guy Harris <guy@alum.mit.edu>
|
|
Date: Wed, 12 Jun 2019 11:32:21 -0700
|
|
Subject: [PATCH 70/83] Read the magic number into a byte array.
|
|
|
|
Apparently, in some C implementations, attempting to do an fread() into
|
|
a variable of a 32-bit unsigned integral type with a size of 1 and a
|
|
count of 4 returns 0 with an EOF indication; see GitHub pull request
|
|
|
|
We can make the size be the size of the variable and the count be 1, but
|
|
that means that the count returned by an fread() terminated by an EOF
|
|
will be 0, not the number of bytes successfully read, so the "truncated
|
|
dump file" message will give an invalid count:
|
|
|
|
tcpdump: truncated dump file; tried to read 4 file header bytes,
|
|
only got 0
|
|
|
|
If, instead, we read into an array of 4 bytes, with a size of 1 and a
|
|
count of 4, we'll get the right short count back.
|
|
|
|
Pass the byte array to the file-type-specific "is this a file of this
|
|
type?" routines, so that if we add support for files where the magic
|
|
number isn't byte-order dependent (e.g., Microsoft Network Monitor), we
|
|
can handle them more cleanly (check for the standard magic number as a
|
|
4-byte array, rather than as its numerical value in both the host's byte
|
|
order and the byte-swapped byte order).
|
|
---
|
|
savefile.c | 8 ++++----
|
|
sf-pcap.c | 24 ++++++++++++++----------
|
|
sf-pcap.h | 2 +-
|
|
sf-pcapng.c | 14 ++++++++------
|
|
sf-pcapng.h | 2 +-
|
|
5 files changed, 28 insertions(+), 22 deletions(-)
|
|
|
|
diff --git a/savefile.c b/savefile.c
|
|
index 9e4724b..7adee42 100644
|
|
--- a/savefile.c
|
|
+++ b/savefile.c
|
|
@@ -332,7 +332,7 @@ pcap_t* pcap_hopen_offline(intptr_t osfd, char *errbuf)
|
|
}
|
|
#endif
|
|
|
|
-static pcap_t *(*check_headers[])(bpf_u_int32, FILE *, u_int, char *, int *) = {
|
|
+static pcap_t *(*check_headers[])(const uint8_t *, FILE *, u_int, char *, int *) = {
|
|
pcap_check_header,
|
|
pcap_ng_check_header
|
|
};
|
|
@@ -347,7 +347,7 @@ pcap_fopen_offline_with_tstamp_precision(FILE *fp, u_int precision,
|
|
char *errbuf)
|
|
{
|
|
register pcap_t *p;
|
|
- bpf_u_int32 magic;
|
|
+ uint8_t magic[4];
|
|
size_t amt_read;
|
|
u_int i;
|
|
int err;
|
|
@@ -359,8 +359,8 @@ pcap_fopen_offline_with_tstamp_precision(FILE *fp, u_int precision,
|
|
* Windows Sniffer, and Microsoft Network Monitor) all have magic
|
|
* numbers that are unique in their first 4 bytes.
|
|
*/
|
|
- amt_read = fread(&magic, sizeof(magic), 1, fp);
|
|
- if (amt_read != 1) {
|
|
+ amt_read = fread(&magic, 1, sizeof(magic), fp);
|
|
+ if (amt_read != sizeof(magic)) {
|
|
if (ferror(fp)) {
|
|
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
|
|
errno, "error reading dump file");
|
|
diff --git a/sf-pcap.c b/sf-pcap.c
|
|
index 87fc5ce..f56fff7 100644
|
|
--- a/sf-pcap.c
|
|
+++ b/sf-pcap.c
|
|
@@ -150,9 +150,10 @@ struct pcap_sf {
|
|
* relevant information from the header.
|
|
*/
|
|
pcap_t *
|
|
-pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
|
+pcap_check_header(const uint8_t *magic, FILE *fp, u_int precision, char *errbuf,
|
|
int *err)
|
|
{
|
|
+ bpf_u_int32 magic_int;
|
|
struct pcap_file_header hdr;
|
|
size_t amt_read;
|
|
pcap_t *p;
|
|
@@ -169,11 +170,14 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
|
* number for a pcap savefile, or for a byte-swapped pcap
|
|
* savefile.
|
|
*/
|
|
- if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC &&
|
|
- magic != NSEC_TCPDUMP_MAGIC) {
|
|
- magic = SWAPLONG(magic);
|
|
- if (magic != TCPDUMP_MAGIC && magic != KUZNETZOV_TCPDUMP_MAGIC &&
|
|
- magic != NSEC_TCPDUMP_MAGIC)
|
|
+ memcpy(&magic_int, magic, sizeof(magic_int));
|
|
+ if (magic_int != TCPDUMP_MAGIC &&
|
|
+ magic_int != KUZNETZOV_TCPDUMP_MAGIC &&
|
|
+ magic_int != NSEC_TCPDUMP_MAGIC) {
|
|
+ magic_int = SWAPLONG(magic_int);
|
|
+ if (magic_int != TCPDUMP_MAGIC &&
|
|
+ magic_int != KUZNETZOV_TCPDUMP_MAGIC &&
|
|
+ magic_int != NSEC_TCPDUMP_MAGIC)
|
|
return (NULL); /* nope */
|
|
swapped = 1;
|
|
}
|
|
@@ -182,7 +186,7 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
|
* They are. Put the magic number in the header, and read
|
|
* the rest of the header.
|
|
*/
|
|
- hdr.magic = magic;
|
|
+ hdr.magic = magic_int;
|
|
amt_read = fread(((char *)&hdr) + sizeof hdr.magic, 1,
|
|
sizeof(hdr) - sizeof(hdr.magic), fp);
|
|
if (amt_read != sizeof(hdr) - sizeof(hdr.magic)) {
|
|
@@ -273,7 +277,7 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
|
switch (precision) {
|
|
|
|
case PCAP_TSTAMP_PRECISION_MICRO:
|
|
- if (magic == NSEC_TCPDUMP_MAGIC) {
|
|
+ if (magic_int == NSEC_TCPDUMP_MAGIC) {
|
|
/*
|
|
* The file has nanoseconds, the user
|
|
* wants microseconds; scale the
|
|
@@ -290,7 +294,7 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
|
break;
|
|
|
|
case PCAP_TSTAMP_PRECISION_NANO:
|
|
- if (magic == NSEC_TCPDUMP_MAGIC) {
|
|
+ if (magic_int == NSEC_TCPDUMP_MAGIC) {
|
|
/*
|
|
* The file has nanoseconds, the
|
|
* user wants nanoseconds; nothing to do.
|
|
@@ -344,7 +348,7 @@ pcap_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
|
break;
|
|
}
|
|
|
|
- if (magic == KUZNETZOV_TCPDUMP_MAGIC) {
|
|
+ if (magic_int == KUZNETZOV_TCPDUMP_MAGIC) {
|
|
/*
|
|
* XXX - the patch that's in some versions of libpcap
|
|
* changes the packet header but not the magic number,
|
|
diff --git a/sf-pcap.h b/sf-pcap.h
|
|
index e9c7eaf..bc7150f 100644
|
|
--- a/sf-pcap.h
|
|
+++ b/sf-pcap.h
|
|
@@ -31,7 +31,7 @@
|
|
#ifndef sf_pcap_h
|
|
#define sf_pcap_h
|
|
|
|
-extern pcap_t *pcap_check_header(bpf_u_int32 magic, FILE *fp,
|
|
+extern pcap_t *pcap_check_header(const uint8_t *magic, FILE *fp,
|
|
u_int precision, char *errbuf, int *err);
|
|
|
|
#endif
|
|
diff --git a/sf-pcapng.c b/sf-pcapng.c
|
|
index 7394ce4..52f795f 100644
|
|
--- a/sf-pcapng.c
|
|
+++ b/sf-pcapng.c
|
|
@@ -761,9 +761,10 @@ add_interface(pcap_t *p, struct block_cursor *cursor, char *errbuf)
|
|
* relevant information from the header.
|
|
*/
|
|
pcap_t *
|
|
-pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
|
- int *err)
|
|
+pcap_ng_check_header(const uint8_t *magic, FILE *fp, u_int precision,
|
|
+ char *errbuf, int *err)
|
|
{
|
|
+ bpf_u_int32 magic_int;
|
|
size_t amt_read;
|
|
bpf_u_int32 total_length;
|
|
bpf_u_int32 byte_order_magic;
|
|
@@ -785,7 +786,8 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
|
* Check whether the first 4 bytes of the file are the block
|
|
* type for a pcapng savefile.
|
|
*/
|
|
- if (magic != BT_SHB) {
|
|
+ memcpy(&magic_int, magic, sizeof(magic_int));
|
|
+ if (magic_int != BT_SHB) {
|
|
/*
|
|
* XXX - check whether this looks like what the block
|
|
* type would be after being munged by mapping between
|
|
@@ -944,12 +946,12 @@ pcap_ng_check_header(bpf_u_int32 magic, FILE *fp, u_int precision, char *errbuf,
|
|
*/
|
|
bhdrp = (struct block_header *)p->buffer;
|
|
shbp = (struct section_header_block *)((u_char *)p->buffer + sizeof(struct block_header));
|
|
- bhdrp->block_type = magic;
|
|
+ bhdrp->block_type = magic_int;
|
|
bhdrp->total_length = total_length;
|
|
shbp->byte_order_magic = byte_order_magic;
|
|
if (read_bytes(fp,
|
|
- (u_char *)p->buffer + (sizeof(magic) + sizeof(total_length) + sizeof(byte_order_magic)),
|
|
- total_length - (sizeof(magic) + sizeof(total_length) + sizeof(byte_order_magic)),
|
|
+ (u_char *)p->buffer + (sizeof(magic_int) + sizeof(total_length) + sizeof(byte_order_magic)),
|
|
+ total_length - (sizeof(magic_int) + sizeof(total_length) + sizeof(byte_order_magic)),
|
|
1, errbuf) == -1)
|
|
goto fail;
|
|
|
|
diff --git a/sf-pcapng.h b/sf-pcapng.h
|
|
index d99b0d4..835082a 100644
|
|
--- a/sf-pcapng.h
|
|
+++ b/sf-pcapng.h
|
|
@@ -26,7 +26,7 @@
|
|
#ifndef sf_pcapng_h
|
|
#define sf_pcapng_h
|
|
|
|
-extern pcap_t *pcap_ng_check_header(bpf_u_int32 magic, FILE *fp,
|
|
+extern pcap_t *pcap_ng_check_header(const uint8_t *magic, FILE *fp,
|
|
u_int precision, char *errbuf, int *err);
|
|
|
|
#endif
|
|
--
|
|
1.8.3.1
|
|
|
|
|