X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/ee05ce47216925fbc816d2cd016a2798279994ae..d5be981c91f153934cda3361567c857fc8d64886:/tcpdump.c diff --git a/tcpdump.c b/tcpdump.c index de0e320e..1eb2e206 100644 --- a/tcpdump.c +++ b/tcpdump.c @@ -43,6 +43,17 @@ The Regents of the University of California. All rights reserved.\n"; #include "config.h" #endif +/* + * Mac OS X may 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(). + */ +#ifdef HAVE_PCAP_FINDALLDEVS +#ifndef HAVE_PCAP_IF_T +#undef HAVE_PCAP_FINDALLDEVS +#endif +#endif + #include #ifdef WIN32 @@ -66,12 +77,10 @@ extern int SIZE_BUF; #else #include "getopt_long.h" #endif -#include -#include -#include -#include -#include -#include +/* Capsicum-specific code requires macros from , which will fail + * to compile if has already been included; including the headers + * in the opposite order works fine. + */ #ifdef HAVE_CAPSICUM #include #include @@ -79,6 +88,12 @@ extern int SIZE_BUF; #include #include #endif /* HAVE_CAPSICUM */ +#include +#include +#include +#include +#include +#include #ifndef WIN32 #include #include @@ -614,12 +629,6 @@ show_devices_and_exit (void) #define J_FLAG #endif /* PCAP_ERROR_TSTAMP_TYPE_NOTSUP */ -#ifdef HAVE_PCAP_FINDALLDEVS -#ifndef HAVE_PCAP_IF_T -#undef HAVE_PCAP_FINDALLDEVS -#endif -#endif - #ifdef HAVE_PCAP_FINDALLDEVS #define D_FLAG "D" #else @@ -660,6 +669,7 @@ show_devices_and_exit (void) */ #define OPTION_VERSION 128 #define OPTION_TSTAMP_PRECISION 129 +#define OPTION_IMMEDIATE_MODE 130 static const struct option longopts[] = { #if defined(HAVE_PCAP_CREATE) || defined(WIN32) @@ -691,6 +701,9 @@ static const struct option longopts[] = { { "packet-buffered", no_argument, NULL, 'U' }, #endif { "linktype", required_argument, NULL, 'y' }, +#ifdef HAVE_PCAP_SET_IMMEDIATE_MODE + { "immediate-mode", no_argument, NULL, OPTION_IMMEDIATE_MODE }, +#endif #if defined(HAVE_PCAP_DEBUG) || defined(HAVE_YYDEBUG) { "debug-filter-parser", no_argument, NULL, 'Y' }, #endif @@ -727,13 +740,15 @@ droproot(const char *username, const char *chroot_dir) fprintf(stderr, "error : ret %d\n", ret); } else { - printf("dropped privs to %s\n", username); + fprintf(stderr, "dropped privs to %s\n", username); } /* We don't need CAP_SETUID and CAP_SETGID */ - capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, CAP_SETUID); - capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, CAP_SETUID); - capng_update(CAPNG_DROP, CAPNG_PERMITTED, CAP_SETUID); - capng_update(CAPNG_DROP, CAPNG_PERMITTED, CAP_SETUID); + capng_updatev( + CAPNG_DROP, + CAPNG_EFFECTIVE | CAPNG_PERMITTED, + CAP_SETUID, + CAP_SETGID, + -1); capng_apply(CAPNG_SELECT_BOTH); #else @@ -747,7 +762,7 @@ droproot(const char *username, const char *chroot_dir) exit(1); } else { - printf("dropped privs to %s\n", username); + fprintf(stderr, "dropped privs to %s\n", username); } #endif /* HAVE_CAP_NG_H */ } @@ -937,6 +952,7 @@ main(int argc, char **argv) gndo->ndo_error=ndo_error; gndo->ndo_warning=ndo_warning; gndo->ndo_snaplen = DEFAULT_SNAPLEN; + gndo->ndo_immediate = 0; cnt = -1; device = NULL; @@ -1344,6 +1360,12 @@ main(int argc, char **argv) break; #endif +#ifdef HAVE_PCAP_SET_IMMEDIATE_MODE + case OPTION_IMMEDIATE_MODE: + gndo->ndo_immediate = 1; + break; +#endif + default: print_usage(); exit(1); @@ -1379,6 +1401,17 @@ main(int argc, char **argv) if (VFileName != NULL && RFileName != NULL) error("-V and -r are mutually exclusive."); +#ifdef HAVE_PCAP_SET_IMMEDIATE_MODE + /* + * If we're printing dissected packets to the standard output + * rather than saving raw packets to a file, and the standard + * output is a terminal, use immediate mode, as the user's + * probably expecting to see packets pop up immediately. + */ + if (WFileName == NULL && isatty(1)) + gndo->ndo_immediate = 1; +#endif + #ifdef WITH_CHROOT /* if run as root, prepare for chrooting */ if (getuid() == 0 || geteuid() == 0) { @@ -1504,6 +1537,15 @@ main(int argc, char **argv) pcap_statustostr(status)); #endif +#ifdef HAVE_PCAP_SET_IMMEDIATE_MODE + if (gndo->ndo_immediate) { + status = pcap_set_immediate_mode(pd, 1); + if (status != 0) + error("%s: Can't set immediate mode: %s", + device, + pcap_statustostr(status)); + } +#endif /* * Is this an interface that supports monitor mode? */ @@ -1686,27 +1728,23 @@ main(int argc, char **argv) * savefile doesn't handle the general case. */ + if (getuid() == 0 || geteuid() == 0) { #ifdef HAVE_CAP_NG_H - /* We are running as root and we will be writing to savefile */ - if ((getuid() == 0 || geteuid() == 0) && WFileName) { - if (username) { - /* Drop all capabilities from effective set */ - capng_clear(CAPNG_EFFECTIVE); + /* Drop all capabilities from effective set */ + capng_clear(CAPNG_EFFECTIVE); + /* We are running as root and we will be writing to savefile */ + if (WFileName && username) { /* Add capabilities we will need*/ - capng_update(CAPNG_ADD, CAPNG_PERMITTED, CAP_SETUID); - capng_update(CAPNG_ADD, CAPNG_PERMITTED, CAP_SETGID); - capng_update(CAPNG_ADD, CAPNG_PERMITTED, CAP_DAC_OVERRIDE); - - capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_SETUID); - capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_SETGID); - capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE); - + capng_updatev( + CAPNG_ADD, + CAPNG_PERMITTED | CAPNG_EFFECTIVE, + CAP_SETUID, + CAP_SETGID, + CAP_DAC_OVERRIDE, + -1); capng_apply(CAPNG_SELECT_BOTH); } - } #endif /* HAVE_CAP_NG_H */ - - if (getuid() == 0 || geteuid() == 0) { if (username || chroot_dir) droproot(username, chroot_dir); @@ -2310,7 +2348,8 @@ print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) /* * Some printers want to check that they're not walking off the * end of the packet. - * Rather than pass it all the way down, we set this global. + * Rather than pass it all the way down, we set this member + * of the netdissect_options structure. */ ndo->ndo_snapend = sp + h->caplen; @@ -2320,6 +2359,11 @@ print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) hdrlen = (*print_info->p.printer)(h, sp); } + /* + * Restore the original snapend, as a printer might have + * changed it. + */ + ndo->ndo_snapend = sp + h->caplen; if (ndo->ndo_Xflag) { /* * Print the raw packet data in hex and ASCII. @@ -2418,7 +2462,7 @@ print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) static void ndo_default_print(netdissect_options *ndo, const u_char *bp, u_int length) { - hex_and_ascii_print(ndo, "\n\t", bp, length); /* pass on lf and identation string */ + hex_and_ascii_print(ndo, "\n\t", bp, length); /* pass on lf and indentation string */ } void @@ -2520,6 +2564,9 @@ print_usage(void) (void)fprintf(stderr, "[ --time-stamp-precision precision ]\n"); (void)fprintf(stderr, "\t\t"); +#endif +#ifdef HAVE_PCAP_SET_IMMEDIATE_MODE + (void)fprintf(stderr, "[ --immediate-mode ] "); #endif (void)fprintf(stderr, "[ -T type ] [ --version ] [ -V file ]\n"); (void)fprintf(stderr,