]> The Tcpdump Group git mirrors - tcpdump/blobdiff - tcpdump.c
Added options to gitattributes
[tcpdump] / tcpdump.c
index 10b6239d5793d3c39c14f31c9aca007bce244a7e..f21ec355943c8b0d817a801365bfd1ef1aedb037 100644 (file)
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -74,6 +74,10 @@ extern int SIZE_BUF;
 #include <errno.h>
 #endif /* WIN32 */
 
+/* capabilities convinience library */
+#ifdef HAVE_CAP_NG_H
+#include <cap-ng.h>
+#endif /* HAVE_CAP_NG_H */
 
 #include "netdissect.h"
 #include "interface.h"
@@ -87,6 +91,12 @@ extern int SIZE_BUF;
 #define NAME_MAX 255
 #endif
 
+#ifdef SIGINFO
+#define SIGNAL_REQ_INFO SIGINFO
+#elif SIGUSR1
+#define SIGNAL_REQ_INFO SIGUSR1
+#endif
+
 netdissect_options Gndo;
 netdissect_options *gndo = &Gndo;
 
@@ -115,10 +125,11 @@ static void ndo_default_print(netdissect_options *, const u_char *, u_int);
 static void dump_packet_and_trunc(u_char *, const struct pcap_pkthdr *, const u_char *);
 static void dump_packet(u_char *, const struct pcap_pkthdr *, const u_char *);
 static void droproot(const char *, const char *);
-static void ndo_error(netdissect_options *ndo, const char *fmt, ...);
+static void ndo_error(netdissect_options *ndo, const char *fmt, ...)
+     __attribute__ ((noreturn, format (printf, 2, 3)));
 static void ndo_warning(netdissect_options *ndo, const char *fmt, ...);
 
-#ifdef SIGINFO
+#ifdef SIGNAL_REQ_INFO
 RETSIGTYPE requestinfo(int);
 #endif
 
@@ -313,6 +324,12 @@ static struct ndo_printer ndo_printers[] = {
 #endif
 #ifdef DLT_PPI
        { ppi_if_print,         DLT_PPI },
+#endif
+#ifdef DLT_NETANALYZER
+       { netanalyzer_if_print, DLT_NETANALYZER },
+#endif
+#ifdef DLT_NETANALYZER_TRANSPARENT
+       { netanalyzer_transparent_if_print, DLT_NETANALYZER_TRANSPARENT },
 #endif
        { NULL,                 0 },
 };
@@ -448,7 +465,9 @@ show_dlts_and_exit(const char *device, pcap_t *pd)
                            dlts[n_dlts]);
                }
        }
+#ifdef HAVE_PCAP_FREE_DATALINKS
        pcap_free_datalinks(dlts);
+#endif
        exit(0);
 }
 
@@ -519,6 +538,19 @@ droproot(const char *username, const char *chroot_dir)
                                exit(1);
                        }
                }
+#ifdef HAVE_CAP_NG_H
+               int ret = capng_change_id(pw->pw_uid, pw->pw_gid, CAPNG_NO_FLAG);
+               if (ret < 0) {
+                       printf("error : ret %d\n", ret);
+               }
+               /* 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_apply(CAPNG_SELECT_BOTH);
+
+#else
                if (initgroups(pw->pw_name, pw->pw_gid) != 0 ||
                    setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) {
                        fprintf(stderr, "tcpdump: Couldn't change to '%.32s' uid=%lu gid=%lu: %s\n",
@@ -528,6 +560,7 @@ droproot(const char *username, const char *chroot_dir)
                            pcap_strerror(errno));
                        exit(1);
                }
+#endif /* HAVE_CAP_NG_H */
        }
        else {
                fprintf(stderr, "tcpdump: Couldn't find user '%.32s'\n",
@@ -651,9 +684,8 @@ main(int argc, char **argv)
        smiInit("tcpdump");
 #endif
 
-       opterr = 0;
        while (
-           (op = getopt(argc, argv, "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:hi:" I_FLAG j_FLAG J_FLAG "KlLm:M:nNOpqr:Rs:StT:u" U_FLAG "vw:W:xXy:Yz:Z:")) != -1)
+           (op = getopt(argc, argv, "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:hHi:" I_FLAG j_FLAG J_FLAG "KlLm:M:nNOpqr:Rs:StT:u" U_FLAG "vw:W:xXy:Yz:Z:")) != -1)
                switch (op) {
 
                case 'a':
@@ -747,7 +779,11 @@ main(int argc, char **argv)
                        break;
 
                case 'h':
-                       ++hflag;
+                       usage();
+                       break;
+
+               case 'H':
+                       ++Hflag;
                        break;
 
                case 'i':
@@ -923,6 +959,10 @@ main(int argc, char **argv)
                                packettype = PT_TFTP;
                        else if (strcasecmp(optarg, "aodv") == 0)
                                packettype = PT_AODV;
+                       else if (strcasecmp(optarg, "carp") == 0)
+                               packettype = PT_CARP;
+                       else if (strcasecmp(optarg, "radius") == 0)
+                               packettype = PT_RADIUS;
                        else
                                error("unknown packet type `%s'", optarg);
                        break;
@@ -1277,9 +1317,31 @@ main(int argc, char **argv)
         * Switching to the -Z user ID only after opening the first
         * savefile doesn't handle the general case.
         */
+
+#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);
+                       /* 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_apply(CAPNG_SELECT_BOTH);
+               }
+       }
+#endif /* HAVE_CAP_NG_H */
+
        if (getuid() == 0 || geteuid() == 0) {
                if (username || chroot_dir)
                        droproot(username, chroot_dir);
+
        }
 #endif /* WIN32 */
 
@@ -1300,6 +1362,10 @@ main(int argc, char **argv)
                  MakeFilename(dumpinfo.CurrentFileName, WFileName, 0, 0);
 
                p = pcap_dump_open(pd, dumpinfo.CurrentFileName);
+#ifdef HAVE_CAP_NG_H
+        /* Give up capabilities, clear Effective set */
+        capng_clear(CAPNG_EFFECTIVE);
+#endif
                if (p == NULL)
                        error("%s", pcap_geterr(pd));
                if (Cflag != 0 || Gflag != 0) {
@@ -1337,13 +1403,13 @@ main(int argc, char **argv)
                pcap_userdata = (u_char *)&printinfo;
        }
 
-#ifdef SIGINFO
+#ifdef SIGNAL_REQ_INFO
        /*
         * We can't get statistics when reading from a file rather
         * than capturing from a device.
         */
        if (RFileName == NULL)
-               (void)setsignal(SIGINFO, requestinfo);
+               (void)setsignal(SIGNAL_REQ_INFO, requestinfo);
 #endif
 
        if (vflag > 0 && WFileName) {
@@ -1631,7 +1697,15 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s
                        else
                                MakeFilename(dump_info->CurrentFileName, dump_info->WFileName, 0, 0);
 
+#ifdef HAVE_CAP_NG_H
+                       capng_update(CAPNG_ADD, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE);
+                       capng_apply(CAPNG_EFFECTIVE);
+#endif /* HAVE_CAP_NG_H */
                        dump_info->p = pcap_dump_open(dump_info->pd, dump_info->CurrentFileName);
+#ifdef HAVE_CAP_NG_H
+                       capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, CAP_DAC_OVERRIDE);
+                       capng_apply(CAPNG_EFFECTIVE);
+#endif /* HAVE_CAP_NG_H */
                        if (dump_info->p == NULL)
                                error("%s", pcap_geterr(pd));
                }
@@ -1832,7 +1906,7 @@ default_print(const u_char *bp, u_int length)
        ndo_default_print(gndo, bp, length);
 }
 
-#ifdef SIGINFO
+#ifdef SIGNAL_REQ_INFO
 RETSIGTYPE requestinfo(int signo _U_)
 {
        if (infodelay)
@@ -1894,7 +1968,7 @@ usage(void)
 #endif /* WIN32 */
 #endif /* HAVE_PCAP_LIB_VERSION */
        (void)fprintf(stderr,
-"Usage: %s [-aAbd" D_FLAG "efh" I_FLAG J_FLAG "KlLnNOpqRStu" U_FLAG "vxX]" B_FLAG_USAGE " [ -c count ]\n", program_name);
+"Usage: %s [-aAbd" D_FLAG "efhH" I_FLAG J_FLAG "KlLnNOpqRStu" U_FLAG "vxX]" B_FLAG_USAGE " [ -c count ]\n", program_name);
        (void)fprintf(stderr,
 "\t\t[ -C file_size ] [ -E algo:secret ] [ -F file ] [ -G seconds ]\n");
        (void)fprintf(stderr,