summaryrefslogtreecommitdiffstats
path: root/tcpdump.c
diff options
context:
space:
mode:
Diffstat (limited to 'tcpdump.c')
-rw-r--r--tcpdump.c110
1 files changed, 79 insertions, 31 deletions
diff --git a/tcpdump.c b/tcpdump.c
index 0b65415..a4cdbe0 100644
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -33,12 +33,10 @@
* combined efforts of Van, Steve McCanne and Craig Leres of LBL.
*/
-#ifdef HAVE_CONFIG_H
#include <config.h>
-#endif
/*
- * Some older versions of Mac OS X may ship pcap.h from libpcap 0.6 with a
+ * Some older versions of Mac OS X ship pcap.h from libpcap 0.6 with a
* libpcap based on 0.8. That means it has pcap_findalldevs() but the
* header doesn't define pcap_if_t, meaning that we can't actually *use*
* pcap_findalldevs().
@@ -63,9 +61,7 @@ The Regents of the University of California. All rights reserved.\n";
#include <sys/stat.h>
-#ifdef HAVE_FCNTL_H
#include <fcntl.h>
-#endif
#ifdef HAVE_LIBCRYPTO
#include <openssl/crypto.h>
@@ -433,15 +429,15 @@ show_tstamp_types_and_exit(pcap_t *pc, const char *device)
device);
exit_tcpdump(S_SUCCESS);
}
- fprintf(stderr, "Time stamp types for %s (use option -j to set):\n",
+ fprintf(stdout, "Time stamp types for %s (use option -j to set):\n",
device);
for (i = 0; i < n_tstamp_types; i++) {
tstamp_type_name = pcap_tstamp_type_val_to_name(tstamp_types[i]);
if (tstamp_type_name != NULL) {
- (void) fprintf(stderr, " %s (%s)\n", tstamp_type_name,
+ (void) fprintf(stdout, " %s (%s)\n", tstamp_type_name,
pcap_tstamp_type_val_to_description(tstamp_types[i]));
} else {
- (void) fprintf(stderr, " %d\n", tstamp_types[i]);
+ (void) fprintf(stdout, " %d\n", tstamp_types[i]);
}
}
pcap_free_tstamp_types(tstamp_types);
@@ -470,28 +466,30 @@ show_dlts_and_exit(pcap_t *pc, const char *device)
* monitor mode might be different from the ones available when
* not in monitor mode).
*/
+ (void) fprintf(stdout, "Data link types for ");
if (supports_monitor_mode)
- (void) fprintf(stderr, "Data link types for %s %s (use option -y to set):\n",
+ (void) fprintf(stdout, "%s %s",
device,
Iflag ? "when in monitor mode" : "when not in monitor mode");
else
- (void) fprintf(stderr, "Data link types for %s (use option -y to set):\n",
+ (void) fprintf(stdout, "%s",
device);
+ (void) fprintf(stdout, " (use option -y to set):\n");
for (i = 0; i < n_dlts; i++) {
dlt_name = pcap_datalink_val_to_name(dlts[i]);
if (dlt_name != NULL) {
- (void) fprintf(stderr, " %s (%s)", dlt_name,
+ (void) fprintf(stdout, " %s (%s)", dlt_name,
pcap_datalink_val_to_description(dlts[i]));
/*
* OK, does tcpdump handle that type?
*/
if (!has_printer(dlts[i]))
- (void) fprintf(stderr, " (printing not supported)");
- fprintf(stderr, "\n");
+ (void) fprintf(stdout, " (printing not supported)");
+ fprintf(stdout, "\n");
} else {
- (void) fprintf(stderr, " DLT %d (printing not supported)\n",
+ (void) fprintf(stdout, " DLT %d (printing not supported)\n",
dlts[i]);
}
}
@@ -806,7 +804,7 @@ droproot(const char *username, const char *chroot_dir)
} else
error("Couldn't find user '%.32s'", username);
#ifdef HAVE_LIBCAP_NG
- /* We don't need CAP_SETUID, CAP_SETGID and CAP_SYS_CHROOT any more. */
+ /* We don't need CAP_SETUID, CAP_SETGID and CAP_SYS_CHROOT anymore. */
DIAG_OFF_ASSIGN_ENUM
capng_updatev(
CAPNG_DROP,
@@ -977,7 +975,7 @@ tstamp_precision_to_string(int precision)
* along the lines of ioctl(), the fact that ioctl() operations are
* largely specific to particular character devices but fcntl() operations
* are either generic to all descriptors or generic to all descriptors for
- * regular files nonwithstanding.
+ * regular files notwithstanding.
*
* The Capsicum people decided that fine-grained control of descriptor
* operations was required, so that you need to grant permission for
@@ -1164,7 +1162,7 @@ parse_interface_number(const char *device)
/*
* No, it's not an ordinal.
*/
- error("Invalid adapter index");
+ error("Invalid adapter index %s", device);
}
return (devnum);
} else {
@@ -1239,8 +1237,11 @@ _U_
for (i = 0, dev = devlist; i < devnum-1 && dev != NULL;
i++, dev = dev->next)
;
- if (dev == NULL)
- error("Invalid adapter index");
+ if (dev == NULL) {
+ pcap_freealldevs(devlist);
+ error("Invalid adapter index %ld: only %ld interfaces found",
+ devnum, i);
+ }
device = strdup(dev->name);
pcap_freealldevs(devlist);
return (device);
@@ -1558,6 +1559,13 @@ main(int argc, char **argv)
if (abort_on_misalignment(ebuf, sizeof(ebuf)) < 0)
error("%s", ebuf);
+ /*
+ * An explicit tzset() call is usually not needed as it happens
+ * implicitly the first time we call localtime() or mktime(),
+ * but in some cases (sandboxing, chroot) this may be too late.
+ */
+ tzset();
+
while (
(op = getopt_long(argc, argv, SHORTOPTS, longopts, NULL)) != -1)
switch (op) {
@@ -1726,7 +1734,7 @@ main(int argc, char **argv)
if (nd_load_smi_module(optarg, ebuf, sizeof(ebuf)) == -1)
error("%s", ebuf);
} else {
- (void)fprintf(stderr, "%s: ignoring option `-m %s' ",
+ (void)fprintf(stderr, "%s: ignoring option '-m %s' ",
program_name, optarg);
(void)fprintf(stderr, "(no libsmi support)\n");
}
@@ -1770,7 +1778,7 @@ main(int argc, char **argv)
else if (ascii_strcasecmp(optarg, "inout") == 0)
Qflag = PCAP_D_INOUT;
else
- error("unknown capture direction `%s'", optarg);
+ error("unknown capture direction '%s'", optarg);
break;
#endif /* HAVE_PCAP_SETDIRECTION */
@@ -1836,7 +1844,7 @@ main(int argc, char **argv)
else if (ascii_strcasecmp(optarg, "domain") == 0)
ndo->ndo_packettype = PT_DOMAIN;
else
- error("unknown packet type `%s'", optarg);
+ error("unknown packet type '%s'", optarg);
break;
case 'u':
@@ -1969,14 +1977,6 @@ main(int argc, char **argv)
show_remote_devices_and_exit();
#endif
-#if defined(DLT_LINUX_SLL2) && defined(HAVE_PCAP_SET_DATALINK)
-/* Set default linktype DLT_LINUX_SLL2 when capturing on the "any" device */
- if (device != NULL &&
- strncmp (device, "any", strlen("any")) == 0
- && yflag_dlt == -1)
- yflag_dlt = DLT_LINUX_SLL2;
-#endif
-
switch (ndo->ndo_tflag) {
case 0: /* Default */
@@ -2026,6 +2026,8 @@ main(int argc, char **argv)
/* Run with '-Z root' to restore old behaviour */
if (!username)
username = WITH_USER;
+ else if (strcmp(username, "root") == 0)
+ username = NULL;
}
#endif
@@ -2229,6 +2231,24 @@ main(int argc, char **argv)
pcap_datalink_val_to_name(yflag_dlt));
(void)fflush(stderr);
}
+#if defined(DLT_LINUX_SLL2) && defined(HAVE_PCAP_SET_DATALINK)
+ else {
+ /*
+ * Attempt to set default linktype to
+ * DLT_LINUX_SLL2 when capturing on the
+ * "any" device.
+ *
+ * If the attempt fails, just quietly drive
+ * on; this may be a non-Linux "any" device
+ * that doesn't support DLT_LINUX_SLL2.
+ */
+ if (strcmp(device, "any") == 0) {
+DIAG_OFF_WARN_UNUSED_RESULT
+ (void) pcap_set_datalink(pd, DLT_LINUX_SLL2);
+DIAG_ON_WARN_UNUSED_RESULT
+ }
+ }
+#endif
i = pcap_snapshot(pd);
if (ndo->ndo_snaplen < i) {
if (ndo->ndo_snaplen != 0)
@@ -2280,7 +2300,21 @@ main(int argc, char **argv)
#endif
/* Cooperate with nohup(1) */
#ifndef _WIN32
+ /*
+ * In illumos /usr/include/sys/iso/signal_iso.h causes Clang to
+ * generate a -Wstrict-prototypes warning here, see [1]. The
+ * __illumos__ macro is available since at least GCC 11 and Clang 13,
+ * see [2].
+ * 1: https://www.illumos.org/issues/16344
+ * 2: https://www.illumos.org/issues/13726
+ */
+#ifdef __illumos__
+ DIAG_OFF_STRICT_PROTOTYPES
+#endif /* __illumos__ */
if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL)
+#ifdef __illumos__
+ DIAG_ON_STRICT_PROTOTYPES
+#endif /* __illumos__ */
(void)setsignal(SIGHUP, oldhandler);
#endif /* _WIN32 */
@@ -2561,6 +2595,9 @@ DIAG_ON_ASSIGN_ENUM
#else
cansandbox = (cansandbox && ndo->ndo_nflag);
#endif /* HAVE_CASPER */
+ cansandbox = (cansandbox && (pcap_fileno(pd) != -1 ||
+ RFileName != NULL));
+
if (cansandbox && cap_enter() < 0 && errno != ENOSYS)
error("unable to enter the capability mode");
#endif /* HAVE_CAPSICUM */
@@ -2652,6 +2689,8 @@ DIAG_ON_ASSIGN_ENUM
*/
dlt = new_dlt;
ndo->ndo_if_printer = get_if_printer(dlt);
+ /* Free the old filter */
+ pcap_freecode(&fcode);
if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0)
error("%s", pcap_geterr(pd));
}
@@ -2712,7 +2751,14 @@ static void
)
new.sa_flags = SA_RESTART;
if (sigaction(sig, &new, &old) < 0)
+ /* The same workaround as for SIG_DFL above. */
+#ifdef __illumos__
+ DIAG_OFF_STRICT_PROTOTYPES
+#endif /* __illumos__ */
return (SIG_ERR);
+#ifdef __illumos__
+ DIAG_ON_STRICT_PROTOTYPES
+#endif /* __illumos__ */
return (old.sa_handler);
#endif
}
@@ -2774,7 +2820,7 @@ cleanup(int signo _U_)
static void
child_cleanup(int signo _U_)
{
- wait(NULL);
+ while (waitpid(-1, NULL, WNOHANG) >= 0);
}
#endif /* HAVE_FORK && HAVE_VFORK */
@@ -3216,6 +3262,8 @@ print_version(FILE *f)
(void)fprintf (f, "Compiled with MemorySanitizer/Clang.\n");
# endif
#endif /* __SANITIZE_ADDRESS__ or __has_feature */
+ (void)fprintf (f, "%zu-bit build, %zu-bit time_t\n",
+ sizeof(void *) * 8, sizeof(time_t) * 8);
}
DIAG_ON_DEPRECATION