X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/541c1ab5e795684abb3e3b372a68055404190a1a..b84bd2b4b55067d1eea6181e1a09043ac093d48c:/tcpdump.c diff --git a/tcpdump.c b/tcpdump.c index b0d3aa5b..28f68077 100644 --- a/tcpdump.c +++ b/tcpdump.c @@ -157,7 +157,6 @@ The Regents of the University of California. All rights reserved.\n"; #include "netdissect.h" #include "interface.h" #include "addrtoname.h" -#include "machdep.h" #include "pcap-missing.h" #include "ascii_strcasecmp.h" @@ -563,8 +562,21 @@ show_remote_devices_and_exit(void) int i; if (pcap_findalldevs_ex(remote_interfaces_source, NULL, &devlist, - ebuf) < 0) + ebuf) < 0) { + if (strcmp(ebuf, "not supported") == 0) { + /* + * macOS 14's pcap_findalldevs_ex(), which is a + * stub that always returns -1 with an error + * message of "not supported". + * + * In this case, as we passed it an rpcap:// + * URL, treat that as meaning "remote capture + * not supported". + */ + error("Remote capture not supported"); + } error("%s", ebuf); + } for (i = 0, dev = devlist; dev != NULL; i++, dev = dev->next) { printf("%d.%s", i+1, dev->name); if (dev->description != NULL) @@ -692,6 +704,7 @@ show_remote_devices_and_exit(void) #define OPTION_FP_TYPE 135 #define OPTION_COUNT 136 #define OPTION_PRINT_SAMPLING 137 +#define OPTION_LENGTHS 138 static const struct option longopts[] = { #if defined(HAVE_PCAP_CREATE) || defined(_WIN32) @@ -740,12 +753,13 @@ static const struct option longopts[] = { { "number", no_argument, NULL, '#' }, { "print", no_argument, NULL, OPTION_PRINT }, { "print-sampling", required_argument, NULL, OPTION_PRINT_SAMPLING }, + { "lengths", no_argument, NULL, OPTION_LENGTHS }, { "version", no_argument, NULL, OPTION_VERSION }, { NULL, 0, NULL, 0 } }; #ifdef HAVE_PCAP_FINDALLDEVS_EX -#define LIST_REMOTE_INTERFACES_USAGE "[ --list-remote-interfaces remote-source ]" +#define LIST_REMOTE_INTERFACES_USAGE " [ --list-remote-interfaces remote-source ]" #else #define LIST_REMOTE_INTERFACES_USAGE #endif @@ -796,7 +810,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, @@ -968,7 +982,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 @@ -984,7 +998,7 @@ tstamp_precision_to_string(int precision) * that requires that it be able to do an F_GETFL fcntl() to read * the O_ flags. * - * Tcpdump uses ftell() to determine how much data has been written + * tcpdump uses ftell() to determine how much data has been written * to a file in order to, when used with -C, determine when it's time * to rotate capture files. ftell() therefore needs to do an lseek() * to find out the file offset and must, thanks to the aforementioned @@ -1269,6 +1283,18 @@ open_interface(const char *device, netdissect_options *ndo, char *ebuf) pflag ? 0 : PCAP_OPENFLAG_PROMISCUOUS, timeout, NULL, ebuf); if (pc == NULL) { + /* + * macOS 14's pcap_pcap_open(), which is a + * stub that always returns NULL with an error + * message of "not supported". + * + * In this case, as we passed it an rpcap:// + * URL, treat that as meaning "remote capture + * not supported". + */ + if (strcmp(ebuf, "not supported") == 0) + error("Remote capture not supported"); + /* * If this failed with "No such device" or "The system * cannot find the device specified", that means @@ -1438,7 +1464,7 @@ open_interface(const char *device, netdissect_options *ndo, char *ebuf) if (status != 0) error("%s: pcap_setdirection() failed: %s", device, pcap_geterr(pc)); - } + } #endif /* HAVE_PCAP_SETDIRECTION */ #else /* HAVE_PCAP_CREATE */ *ebuf = '\0'; @@ -1541,14 +1567,11 @@ main(int argc, char **argv) #endif /* - * On platforms where the CPU doesn't support unaligned loads, - * force unaligned accesses to abort with SIGBUS, rather than - * being fixed up (slowly) by the OS kernel; on those platforms, - * misaligned accesses are bugs, and we want tcpdump to crash so - * that the bugs are reported. + * 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. */ - if (abort_on_misalignment(ebuf, sizeof(ebuf)) < 0) - error("%s", ebuf); + tzset(); while ( (op = getopt_long(argc, argv, SHORTOPTS, longopts, NULL)) != -1) @@ -1717,7 +1740,7 @@ main(int argc, char **argv) case 'h': print_usage(stdout); exit_tcpdump(S_SUCCESS); - break; + /* NOTREACHED */ case 'H': ++ndo->ndo_Hflag; @@ -1776,7 +1799,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"); } @@ -1820,7 +1843,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 */ @@ -1888,7 +1911,7 @@ main(int argc, char **argv) else if (ascii_strcasecmp(optarg, "quic") == 0) ndo->ndo_packettype = PT_QUIC; else - error("unknown packet type `%s'", optarg); + error("unknown packet type '%s'", optarg); break; case 'u': @@ -1958,10 +1981,14 @@ main(int argc, char **argv) ndo->ndo_packet_number = 1; break; + case OPTION_LENGTHS: + ndo->ndo_lengths = 1; + break; + case OPTION_VERSION: print_version(stdout); exit_tcpdump(S_SUCCESS); - break; + /* NOTREACHED */ #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION case OPTION_TSTAMP_PRECISION: @@ -2029,14 +2056,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 */ @@ -2049,7 +2068,7 @@ main(int argc, char **argv) default: /* Not supported */ error("only -t, -tt, -ttt, -tttt and -ttttt are supported"); - break; + /* NOTREACHED */ } if (ndo->ndo_fflag != 0 && (VFileName != NULL || RFileName != NULL)) @@ -2086,6 +2105,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 @@ -2289,6 +2310,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) @@ -2340,7 +2379,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 */ @@ -2353,7 +2406,7 @@ main(int argc, char **argv) * devices, and can't just give users that permission, * you'd make tcpdump set-UID or set-GID). * - * Tcpdump doesn't necessarily write only to one savefile; + * tcpdump doesn't necessarily write only to one savefile; * the general only way to allow a -Z instance to write to * savefiles as the user under whose UID it's run, rather * than as the user specified with -Z, would thus be to switch @@ -2621,6 +2674,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 */ @@ -2774,7 +2830,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 } @@ -3278,6 +3341,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 @@ -3291,10 +3356,8 @@ print_usage(FILE *f) "\t\t[ -C file_size ] [ -E algo:secret ] [ -F file ] [ -G seconds ]\n"); (void)fprintf(f, "\t\t[ -i interface ]" IMMEDIATE_MODE_USAGE j_FLAG_USAGE "\n"); -#ifdef HAVE_PCAP_FINDALLDEVS_EX (void)fprintf(f, -"\t\t" LIST_REMOTE_INTERFACES_USAGE "\n"); -#endif +"\t\t[ --lengths ]" LIST_REMOTE_INTERFACES_USAGE "\n"); #ifdef USE_LIBSMI (void)fprintf(f, "\t\t" m_FLAG_USAGE "\n");