summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2019-06-12 11:32:21 -0700
committerGuy Harris <guy@alum.mit.edu>2019-06-12 11:32:21 -0700
commit2e9d0ae34ece4d6f67f4d66a4c3628febf0b13dd (patch)
treec09a4191cd220422464f94b1806556d14307a2eb
parent978ccfe2193d270ad7e22ca0c7420b41e9de4f2c (diff)
downloadlibpcap-2e9d0ae34ece4d6f67f4d66a4c3628febf0b13dd.tar.gz
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).
-rw-r--r--savefile.c8
-rw-r--r--sf-pcap.c24
-rw-r--r--sf-pcap.h2
-rw-r--r--sf-pcapng.c14
-rw-r--r--sf-pcapng.h2
5 files changed, 28 insertions, 22 deletions
diff --git a/savefile.c b/savefile.c
index 9e4724b2..7adee42f 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 87fc5ce1..f56fff74 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 e9c7eafa..bc7150f4 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 7394ce46..52f795f7 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 d99b0d4e..835082a5 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