]> The Tcpdump Group git mirrors - tcpdump/blobdiff - tcpdump.c
Merge pull request #429 from mkirkhart/inverse-arp-print-fix
[tcpdump] / tcpdump.c
index 2ec7d2006b375bedf50e8ce5d7c51e33029944e6..1eb2e206b6ec1b9a6a12eebc8f576117983aa9b1 100644 (file)
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -77,12 +77,10 @@ extern int SIZE_BUF;
 #else
 #include "getopt_long.h"
 #endif
-#include <pcap.h>
-#include <signal.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
+/* Capsicum-specific code requires macros from <net/bpf.h>, which will fail
+ * to compile if <pcap.h> has already been included; including the headers
+ * in the opposite order works fine.
+ */
 #ifdef HAVE_CAPSICUM
 #include <sys/capability.h>
 #include <sys/ioccom.h>
@@ -90,6 +88,12 @@ extern int SIZE_BUF;
 #include <fcntl.h>
 #include <libgen.h>
 #endif /* HAVE_CAPSICUM */
+#include <pcap.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
 #ifndef WIN32
 #include <sys/wait.h>
 #include <sys/resource.h>
@@ -665,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)
@@ -696,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
@@ -732,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
@@ -752,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 */
        }
@@ -942,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;
@@ -1349,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);
@@ -1384,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) {
@@ -1509,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?
                 */
@@ -1691,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);
 
@@ -2429,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
@@ -2531,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,