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).
-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
};
pcap_check_header,
pcap_ng_check_header
};
char *errbuf)
{
register pcap_t *p;
char *errbuf)
{
register pcap_t *p;
size_t amt_read;
u_int i;
int err;
size_t amt_read;
u_int i;
int err;
* Windows Sniffer, and Microsoft Network Monitor) all have magic
* numbers that are unique in their first 4 bytes.
*/
* 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");
if (ferror(fp)) {
pcap_fmt_errmsg_for_errno(errbuf, PCAP_ERRBUF_SIZE,
errno, "error reading dump file");
* relevant information from the header.
*/
pcap_t *
* 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,
struct pcap_file_header hdr;
size_t amt_read;
pcap_t *p;
struct pcap_file_header hdr;
size_t amt_read;
pcap_t *p;
* number for a pcap savefile, or for a byte-swapped pcap
* savefile.
*/
* 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;
}
return (NULL); /* nope */
swapped = 1;
}
* They are. Put the magic number in the header, and read
* the rest of the header.
*/
* They are. Put the magic number in the header, and read
* the rest of the header.
*/
amt_read = fread(((char *)&hdr) + sizeof hdr.magic, 1,
sizeof(hdr) - sizeof(hdr.magic), fp);
if (amt_read != sizeof(hdr) - sizeof(hdr.magic)) {
amt_read = fread(((char *)&hdr) + sizeof hdr.magic, 1,
sizeof(hdr) - sizeof(hdr.magic), fp);
if (amt_read != sizeof(hdr) - sizeof(hdr.magic)) {
switch (precision) {
case PCAP_TSTAMP_PRECISION_MICRO:
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
/*
* The file has nanoseconds, the user
* wants microseconds; scale the
break;
case PCAP_TSTAMP_PRECISION_NANO:
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.
/*
* The file has nanoseconds, the
* user wants nanoseconds; nothing to do.
- 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,
/*
* XXX - the patch that's in some versions of libpcap
* changes the packet header but not the magic number,
#ifndef sf_pcap_h
#define sf_pcap_h
#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
u_int precision, char *errbuf, int *err);
#endif
* relevant information from the header.
*/
pcap_t *
* 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)
size_t amt_read;
bpf_u_int32 total_length;
bpf_u_int32 byte_order_magic;
size_t amt_read;
bpf_u_int32 total_length;
bpf_u_int32 byte_order_magic;
* Check whether the first 4 bytes of the file are the block
* type for a pcapng savefile.
*/
* Check whether the first 4 bytes of the file are the block
* type for a pcapng savefile.
*/
+ 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
/*
* XXX - check whether this looks like what the block
* type would be after being munged by mapping between
*/
bhdrp = (struct block_header *)p->buffer;
shbp = (struct section_header_block *)((u_char *)p->buffer + sizeof(struct block_header));
*/
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,
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;
1, errbuf) == -1)
goto fail;
#ifndef sf_pcapng_h
#define sf_pcapng_h
#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
u_int precision, char *errbuf, int *err);
#endif