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);
* 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]);
}
}
} 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,
char *filename = malloc(PATH_MAX + 1);
if (filename == NULL)
error("%s: malloc", __func__);
+ if (strlen(orig_name) == 0)
+ error("an empty string is not a valid file name");
/* Process with strftime if Gflag is set. */
if (Gflag != 0) {
}
/* There's no good way to detect an error in strftime since a return
- * value of 0 isn't necessarily failure.
+ * value of 0 isn't necessarily failure; if orig_name is an empty
+ * string, the formatted string will be empty.
+ *
+ * However, the C90 standard says that, if there *is* a
+ * buffer overflow, the content of the buffer is undefined,
+ * so we must check for a buffer overflow.
+ *
+ * So we check above for an empty orig_name, and only call
+ * strftime() if it's non-empty, in which case the return
+ * value will only be 0 if the formatted date doesn't fit
+ * in the buffer.
+ *
+ * (We check above because, even if we don't use -G, we
+ * want a better error message than "tcpdump: : No such
+ * file or directory" for this case.)
*/
- strftime(filename, PATH_MAX, orig_name, local_tm);
+ if (strftime(filename, PATH_MAX, orig_name, local_tm) == 0) {
+ error("%s: strftime", __func__);
+ }
} else {
strncpy(filename, orig_name, PATH_MAX);
}
* 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
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 */
/* Run with '-Z root' to restore old behaviour */
if (!username)
username = WITH_USER;
+ else if (strcmp(username, "root") == 0)
+ username = NULL;
}
#endif
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)
+ (void) pcap_set_datalink(pd, DLT_LINUX_SLL2);
+ }
+#endif
i = pcap_snapshot(pd);
if (ndo->ndo_snaplen < i) {
if (ndo->ndo_snaplen != 0)
#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 */
*/
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));
}
memset(&new, 0, sizeof(new));
new.sa_handler = func;
- if (sig == SIGCHLD)
+ if ((sig == SIGCHLD)
+# ifdef SIGNAL_REQ_INFO
+ || (sig == SIGNAL_REQ_INFO)
+# endif
+# ifdef SIGNAL_FLUSH_PCAP
+ || (sig == SIGNAL_FLUSH_PCAP)
+# endif
+ )
new.sa_flags = SA_RESTART;
if (sigaction(sig, &new, &old) < 0)
return (SIG_ERR);
static void
child_cleanup(int signo _U_)
{
- wait(NULL);
+ while (waitpid(-1, NULL, WNOHANG) >= 0);
}
#endif /* HAVE_FORK && HAVE_VFORK */