aboutsummaryrefslogtreecommitdiff
path: root/sf-pcap.c
diff options
context:
space:
mode:
Diffstat (limited to 'sf-pcap.c')
-rw-r--r--sf-pcap.c63
1 files changed, 44 insertions, 19 deletions
diff --git a/sf-pcap.c b/sf-pcap.c
index d8443e98..78437031 100644
--- a/sf-pcap.c
+++ b/sf-pcap.c
@@ -96,18 +96,6 @@
*/
#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.
- *
- * 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.
- */
-#define LT_LINKTYPE(x) ((x) & 0x03FFFFFF)
-#define LT_LINKTYPE_EXT(x) ((x) & 0xFC000000)
-
static int pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **datap);
#ifdef _WIN32
@@ -237,6 +225,17 @@ pcap_check_header(const uint8_t *magic, FILE *fp, u_int precision, char *errbuf,
}
/*
+ * 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.
*/
@@ -434,7 +433,7 @@ grow_buffer(pcap_t *p, u_int bufsize)
/*
* Read and return the next packet from the savefile. Return the header
- * in hdr and a pointer to the contents in data. Return 0 on success, 1
+ * in hdr and a pointer to the contents in data. Return 1 on success, 0
* if there were no more packets, and -1 on an error.
*/
static int
@@ -467,7 +466,7 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
return (-1);
}
/* EOF */
- return (1);
+ return (0);
}
}
@@ -622,7 +621,7 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
* the read finished.
*/
snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
- "truncated dump file; tried to read %u captured bytes, only got %zu",
+ "truncated dump file; tried to read %d captured bytes, only got %zu",
p->snapshot, amt_read);
}
return (-1);
@@ -709,7 +708,7 @@ pcap_next_packet(pcap_t *p, struct pcap_pkthdr *hdr, u_char **data)
if (p->swapped)
swap_pseudo_headers(p->linktype, hdr, *data);
- return (0);
+ return (1);
}
static int
@@ -749,6 +748,24 @@ pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
f = (FILE *)user;
/*
+ * If the output file handle is in an error state, don't write
+ * anything.
+ *
+ * While in principle a file handle can return from an error state
+ * to a normal state (for example if a disk that is full has space
+ * freed), we have possibly left a broken file already, and won't
+ * be able to clean it up. The safest option is to do nothing.
+ *
+ * Note that if we could guarantee that fwrite() was atomic we
+ * might be able to insure that we don't produce a corrupted file,
+ * but the standard defines fwrite() as a series of fputc() calls,
+ * so we really have no insurance that things are not fubared.
+ *
+ * http://pubs.opengroup.org/onlinepubs/009695399/functions/fwrite.html
+ */
+ if (ferror(f))
+ return;
+ /*
* Better not try writing pcap files after
* 2038-01-19 03:14:07 UTC; switch to pcapng.
*/
@@ -756,9 +773,17 @@ pcap_dump(u_char *user, const struct pcap_pkthdr *h, const u_char *sp)
sf_hdr.ts.tv_usec = (bpf_int32)h->ts.tv_usec;
sf_hdr.caplen = h->caplen;
sf_hdr.len = h->len;
- /* XXX we should check the return status */
- (void)fwrite(&sf_hdr, sizeof(sf_hdr), 1, f);
- (void)fwrite(sp, h->caplen, 1, f);
+ /*
+ * We only write the packet if we can write the header properly.
+ *
+ * This doesn't prevent us from having corrupted output, and if we
+ * for some reason don't get a complete write we don't have any
+ * way to set ferror() to prevent future writes from being
+ * attempted, but it is better than nothing.
+ */
+ if (fwrite(&sf_hdr, sizeof(sf_hdr), 1, f) == 1) {
+ (void)fwrite(sp, h->caplen, 1, f);
+ }
}
static pcap_dumper_t *