* "pcap_open_offline_common()" allocates and fills in a pcap_t, for use
* by pcap_open_offline routines.
*
+ * "pcap_adjust_snapshot()" adjusts the snapshot to be non-zero and
+ * fit within an int.
+ *
* "sf_cleanup()" closes the file handle associated with a pcap_t, if
* appropriate, and frees all data common to all modules for handling
* savefile types.
*/
pcap_t *pcap_open_offline_common(char *ebuf, size_t size);
+bpf_u_int32 pcap_adjust_snapshot(bpf_u_int32 linktype, bpf_u_int32 snaplen);
void sf_cleanup(pcap_t *p);
/*
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#include <limits.h> /* for INT_MAX */
#include "pcap-int.h"
#include "sf-pcap.h"
#include "sf-pcapng.h"
+#include "pcap-common.h"
#ifdef _WIN32
/*
}
#endif
+/*
+ * Given a link-layer header type and snapshot length, return a
+ * snapshot length to use when reading the file; it's guaranteed
+ * to be > 0 and <= INT_MAX.
+ *
+ * XXX - the only reason why we limit it to <= INT_MAX is so that
+ * it fits in p->snapshot, and the only reason that p->snapshot is
+ * signed is that pcap_snapshot() returns an int, not an unsigned int.
+ */
+bpf_u_int32
+pcap_adjust_snapshot(bpf_u_int32 linktype, bpf_u_int32 snaplen)
+{
+ if (snaplen == 0 || snaplen > INT_MAX) {
+ /*
+ * Bogus snapshot length; use the maximum for this
+ * link-layer type as a fallback.
+ *
+ * XXX - we don't clamp snapshot lengths that are
+ * <= INT_MAX but > max_snaplen_for_dlt(linktype),
+ * so a capture file could cause us to allocate
+ * a Really Big Buffer.
+ */
+ snaplen = max_snaplen_for_dlt(linktype);
+ }
+ return snaplen;
+}
+
static pcap_t *(*check_headers[])(const uint8_t *, FILE *, u_int, char *, int *) = {
pcap_check_header,
pcap_ng_check_header
p->swapped = swapped;
p->version_major = hdr.version_major;
p->version_minor = hdr.version_minor;
- if (hdr.snaplen == 0 || hdr.snaplen > INT_MAX) {
- /*
- * Bogus snapshot length; use the maximum for this
- * link-layer type as a fallback.
- *
- * XXX - the only reason why snapshot is signed is
- * that pcap_snapshot() returns an int, not an
- * unsigned int.
- */
- p->snapshot = max_snaplen_for_dlt(hdr.linktype);
- } else
- p->snapshot = hdr.snaplen;
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->next_packet_op = pcap_next_packet;
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <limits.h> /* for INT_MAX */
#include "pcap-int.h"
}
done:
- if (idbp->snaplen == 0 || idbp->snaplen > INT_MAX) {
- /*
- * Bogus snapshot length; use the maximum for this
- * link-layer type as a fallback.
- *
- * XXX - the only reason why snapshot is signed is
- * that pcap_snapshot() returns an int, not an
- * unsigned int.
- */
- p->snapshot = max_snaplen_for_dlt(idbp->linktype);
- } else
- p->snapshot = idbp->snaplen;
p->linktype = linktype_to_dlt(idbp->linktype);
+ p->snapshot = pcap_adjust_snapshot(p->linktype, idbp->snaplen);
p->linktype_ext = 0;
/*
idbp->linktype);
return (-1);
}
- if ((bpf_u_int32)p->snapshot != idbp->snaplen) {
+
+ /*
+ * Check against the *adjusted* value of this IDB's
+ * snapshot length.
+ */
+ if ((bpf_u_int32)p->snapshot !=
+ pcap_adjust_snapshot(p->linktype, idbp->snaplen)) {
pcap_snprintf(p->errbuf, PCAP_ERRBUF_SIZE,
"an interface has a snapshot length %u different from the type of the first interface",
idbp->snaplen);