summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2017-09-30 01:10:29 -0700
committerGuy Harris <guy@alum.mit.edu>2017-09-30 01:10:29 -0700
commit62f2725b5745a2bfcd4223e2ca12566556b73d22 (patch)
treec8b9e114ceaea79eeaaf7681a81f162b30f31dc4
parent9fe69d02a510c12236b111d0b1c59670d5bb91af (diff)
downloadtcpdump-62f2725b5745a2bfcd4223e2ca12566556b73d22.tar.gz
Use pcap_dump_ftell64() if we have it.
That way, even if a file offset doesn't fit in a long, we can still handle a -C flag specifying a maximum file size >=2GB.
-rw-r--r--config.h.in3
-rwxr-xr-xconfigure14
-rw-r--r--configure.in3
-rw-r--r--tcpdump.c27
4 files changed, 40 insertions, 7 deletions
diff --git a/config.h.in b/config.h.in
index bc123628..9ccae642 100644
--- a/config.h.in
+++ b/config.h.in
@@ -124,6 +124,9 @@
/* define if libpcap has pcap_dump_ftell() */
#undef HAVE_PCAP_DUMP_FTELL
+/* Define to 1 if you have the `pcap_dump_ftell64' function. */
+#undef HAVE_PCAP_DUMP_FTELL64
+
/* Define to 1 if you have the `pcap_findalldevs' function. */
#undef HAVE_PCAP_FINDALLDEVS
diff --git a/configure b/configure
index 434c87cf..90be33f0 100755
--- a/configure
+++ b/configure
@@ -6081,7 +6081,19 @@ fi
# Check for a miscellaneous collection of functions which we use
# if we have them.
#
-for ac_func in pcap_findalldevs pcap_dump_flush pcap_lib_version pcap_setdirection pcap_set_immediate_mode
+for ac_func in pcap_findalldevs pcap_dump_flush pcap_lib_version
+do :
+ as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
+ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
+ cat >>confdefs.h <<_ACEOF
+#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+for ac_func in pcap_setdirection pcap_set_immediate_mode pcap_dump_ftell64
do :
as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
diff --git a/configure.in b/configure.in
index 6686983e..19eb7eb1 100644
--- a/configure.in
+++ b/configure.in
@@ -618,7 +618,8 @@ fi
# Check for a miscellaneous collection of functions which we use
# if we have them.
#
-AC_CHECK_FUNCS(pcap_findalldevs pcap_dump_flush pcap_lib_version pcap_setdirection pcap_set_immediate_mode)
+AC_CHECK_FUNCS(pcap_findalldevs pcap_dump_flush pcap_lib_version)
+AC_CHECK_FUNCS(pcap_setdirection pcap_set_immediate_mode pcap_dump_ftell64)
if test $ac_cv_func_pcap_findalldevs = "yes" ; then
dnl Check for Mac OS X, which may ship pcap.h from 0.6 but libpcap may
dnl be 0.8; this means that lib has pcap_findalldevs but header doesn't
diff --git a/tcpdump.c b/tcpdump.c
index d0056fe4..059596de 100644
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -140,7 +140,11 @@ The Regents of the University of California. All rights reserved.\n";
#endif
static int Bflag; /* buffer size */
+#ifdef HAVE_PCAP_FTELL64
+static int64_t Cflag; /* rotate dump files after this many bytes */
+#else
static long Cflag; /* rotate dump files after this many bytes */
+#endif
static int Cflag_count; /* Keep track of which file number we're writing */
static int Dflag; /* list available devices and exit */
/*
@@ -1280,14 +1284,22 @@ main(int argc, char **argv)
case 'C':
errno = 0;
+#ifdef HAVE_PCAP_FTELL64
+ Cflag = strtoint64_t(optarg, &endp, 10);
+#else
Cflag = strtol(optarg, &endp, 10);
+#endif
if (endp == optarg || *endp != '\0' || errno != 0
|| Cflag <= 0)
error("invalid file size %s", optarg);
/*
* Will multiplying it by 1000000 overflow?
*/
+#ifdef HAVE_PCAP_FTELL64
+ if (Cflag > INT64_T_CONSTANT(0x7fffffffffffffffU) / 1000000)
+#else
if (Cflag > LONG_MAX / 1000000)
+#endif
error("file size %s is too large", optarg);
Cflag *= 1000000;
break;
@@ -2493,14 +2505,19 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s
* XXX - this won't prevent capture files from getting
* larger than Cflag - the last packet written to the
* file could put it over Cflag.
- *
- * XXX - this only handles a Cflag value > 2^31-1 on
- * LP64 platforms; to handle ILP32 (32-bit UN*X and
- * Windows) or LLP64 (64-bit Windows) would require
- * a libpcap API that returns a 64-bit file offset.
*/
if (Cflag != 0) {
+#ifdef HAVE_PCAP_FTELL64
+ int64_t size = pcap_dump_ftell64(dump_info->p);
+#else
+ /*
+ * XXX - this only handles a Cflag value > 2^31-1 on
+ * LP64 platforms; to handle ILP32 (32-bit UN*X and
+ * Windows) or LLP64 (64-bit Windows) would require
+ * a version of libpcap with pcap_dump_ftell64().
+ */
long size = pcap_dump_ftell(dump_info->p);
+#endif
if (size == -1)
error("ftell fails on output file");