X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/4a2fb51da7ada0cecf94a5a94c7146bc36dd72b0..e95b7bd6979e942e49c55387266da04d64c289b5:/tcpdump.c diff --git a/tcpdump.c b/tcpdump.c index bde74864..d9c7f7ab 100644 --- a/tcpdump.c +++ b/tcpdump.c @@ -130,7 +130,7 @@ The Regents of the University of California. All rights reserved.\n"; #endif static int Bflag; /* buffer size */ -static int Cflag; /* rotate dump files after this many bytes */ +static long Cflag; /* rotate dump files after this many bytes */ static int Cflag_count; /* Keep track of which file number we're writing */ static int Dflag; /* list available devices and exit */ /* @@ -157,7 +157,7 @@ static int Jflag; /* list available time stamp types */ static int jflag = -1; /* packet time stamp source */ static int pflag; /* don't go promiscuous */ #ifdef HAVE_PCAP_SETDIRECTION -int Qflag = -1; /* restrict captured packet by send/receive direction */ +static int Qflag = -1; /* restrict captured packet by send/receive direction */ #endif static int Uflag; /* "unbuffered" output of dump files */ static int Wflag; /* recycle output files after this number of files */ @@ -171,26 +171,17 @@ static int infoprint; char *program_name; /* Forwards */ -static void error(const char *, ...) - __attribute__((noreturn)) -#ifdef __ATTRIBUTE___FORMAT_OK - __attribute__((format (printf, 1, 2))) -#endif /* __ATTRIBUTE___FORMAT_OK */ - ; -static void warning(const char *, ...) -#ifdef __ATTRIBUTE___FORMAT_OK - __attribute__((format (printf, 1, 2))) -#endif /* __ATTRIBUTE___FORMAT_OK */ - ; -static void exit_tcpdump(int) __attribute__((noreturn)); +static void error(FORMAT_STRING(const char *), ...) NORETURN PRINTFLIKE(1, 2); +static void warning(FORMAT_STRING(const char *), ...) PRINTFLIKE(1, 2); +static void exit_tcpdump(int) NORETURN; static RETSIGTYPE cleanup(int); static RETSIGTYPE child_cleanup(int); static void print_version(void); static void print_usage(void); -static void show_tstamp_types_and_exit(const char *device) __attribute__((noreturn)); -static void show_dlts_and_exit(const char *device) __attribute__((noreturn)); +static void show_tstamp_types_and_exit(pcap_t *, const char *device) NORETURN; +static void show_dlts_and_exit(pcap_t *, const char *device) NORETURN; #ifdef HAVE_PCAP_FINDALLDEVS -static void show_devices_and_exit (void) __attribute__((noreturn)); +static void show_devices_and_exit (void) NORETURN; #endif static void print_packet(u_char *, const struct pcap_pkthdr *, const u_char *); @@ -340,16 +331,16 @@ exit_tcpdump(int status) #ifdef HAVE_PCAP_SET_TSTAMP_TYPE static void -show_tstamp_types_and_exit(const char *device) +show_tstamp_types_and_exit(pcap_t *pc, const char *device) { int n_tstamp_types; int *tstamp_types = 0; const char *tstamp_type_name; int i; - n_tstamp_types = pcap_list_tstamp_types(pd, &tstamp_types); + n_tstamp_types = pcap_list_tstamp_types(pc, &tstamp_types); if (n_tstamp_types < 0) - error("%s", pcap_geterr(pd)); + error("%s", pcap_geterr(pc)); if (n_tstamp_types == 0) { fprintf(stderr, "Time stamp type cannot be set for %s\n", @@ -373,15 +364,15 @@ show_tstamp_types_and_exit(const char *device) #endif static void -show_dlts_and_exit(const char *device) +show_dlts_and_exit(pcap_t *pc, const char *device) { int n_dlts, i; int *dlts = 0; const char *dlt_name; - n_dlts = pcap_list_datalinks(pd, &dlts); + n_dlts = pcap_list_datalinks(pc, &dlts); if (n_dlts < 0) - error("%s", pcap_geterr(pd)); + error("%s", pcap_geterr(pc)); else if (n_dlts == 0 || !dlts) error("No data link types."); @@ -458,7 +449,7 @@ show_devices_and_exit (void) * OS X tcpdump uses -g to force non--v output for IP to be on one * line, making it more "g"repable; * - * OS X tcpdump uses -k tospecify that packet comments in pcap-ng files + * OS X tcpdump uses -k to specify that packet comments in pcap-ng files * should be printed; * * OpenBSD tcpdump uses -o to indicate that OS fingerprinting should be done @@ -643,12 +634,13 @@ droproot(const char *username, const char *chroot_dir) exit_tcpdump(1); } #ifdef HAVE_LIBCAP_NG - /* We don't need CAP_SETUID and CAP_SETGID any more. */ + /* We don't need CAP_SETUID, CAP_SETGID and CAP_SYS_CHROOT any more. */ capng_updatev( CAPNG_DROP, CAPNG_EFFECTIVE | CAPNG_PERMITTED, CAP_SETUID, CAP_SETGID, + CAP_SYS_CHROOT, -1); capng_apply(CAPNG_SELECT_BOTH); #endif /* HAVE_LIBCAP_NG */ @@ -974,7 +966,7 @@ open_interface(const char *device, netdissect_options *ndo, char *ebuf) } #ifdef HAVE_PCAP_SET_TSTAMP_TYPE if (Jflag) - show_tstamp_types_and_exit(device); + show_tstamp_types_and_exit(pc, device); #endif #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION status = pcap_set_tstamp_precision(pc, ndo->ndo_tstamp_precision); @@ -1045,9 +1037,9 @@ open_interface(const char *device, netdissect_options *ndo, char *ebuf) /* * Return an error for our caller to handle. */ - pcap_close(pc); snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s\n(%s)", device, pcap_statustostr(status), cp); + pcap_close(pc); return (NULL); } else if (status == PCAP_ERROR_PERM_DENIED && *cp != '\0') error("%s: %s\n(%s)", device, @@ -1729,7 +1721,7 @@ main(int argc, char **argv) } #endif /* !defined(HAVE_PCAP_CREATE) && defined(_WIN32) */ if (Lflag) - show_dlts_and_exit(device); + show_dlts_and_exit(pd, device); if (yflag_dlt >= 0) { #ifdef HAVE_PCAP_SET_DATALINK if (pcap_set_datalink(pd, yflag_dlt) < 0) @@ -1825,6 +1817,13 @@ main(int argc, char **argv) CAP_SETGID, -1); } + if (chroot_dir) { + capng_update( + CAPNG_ADD, + CAPNG_PERMITTED | CAPNG_EFFECTIVE, + CAP_SYS_CHROOT + ); + } if (WFileName) { capng_update( @@ -1847,7 +1846,12 @@ main(int argc, char **argv) if (RFileName == NULL && VFileName == NULL) { static const unsigned long cmds[] = { BIOCGSTATS, BIOCROTZBUF }; - cap_rights_init(&rights, CAP_IOCTL, CAP_READ); + /* + * The various libpcap devices use a combination of + * read (bpf), ioctl (bpf, netmap), poll (netmap) + * so we add the relevant access rights. + */ + cap_rights_init(&rights, CAP_IOCTL, CAP_READ, CAP_EVENT); if (cap_rights_limit(pcap_fileno(pd), &rights) < 0 && errno != ENOSYS) { error("unable to limit pcap descriptor"); @@ -2322,6 +2326,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s if (Cflag == 0 && Wflag > 0 && Gflag_count >= Wflag) { (void)fprintf(stderr, "Maximum file limit reached: %d\n", Wflag); + info(1); exit_tcpdump(0); /* NOTREACHED */ } @@ -2590,6 +2595,14 @@ print_version(void) smi_version_string = nd_smi_version_string(); if (smi_version_string != NULL) (void)fprintf (stderr, "SMI-library: %s\n", smi_version_string); + +#if defined(__SANITIZE_ADDRESS__) + (void)fprintf (stderr, "Compiled with AddressSanitizer/GCC.\n"); +#elif defined(__has_feature) +# if __has_feature(address_sanitizer) + (void)fprintf (stderr, "Compiled with AddressSanitizer/CLang.\n"); +# endif +#endif /* __SANITIZE_ADDRESS__ or __has_feature */ } USES_APPLE_RST