]> The Tcpdump Group git mirrors - tcpdump/blobdiff - tcpdump.c
bgp: Parse BGP extended message support capability
[tcpdump] / tcpdump.c
index 4c56faf49d06a743d6eb6fab2384720d02a44d30..a4403370e715b4c5b91e90bcd750f5a9565724a0 100644 (file)
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -78,7 +78,9 @@ The Regents of the University of California.  All rights reserved.\n";
 #endif
 /* 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.
+ * in the opposite order works fine. For the most part anyway, because in
+ * FreeBSD <pcap/pcap.h> declares bpf_dump() instead of <net/bpf.h>. Thus
+ * interface.h takes care of it later to avoid a compiler warning.
  */
 #ifdef HAVE_CAPSICUM
 #include <sys/capsicum.h>
@@ -161,6 +163,8 @@ The Regents of the University of California.  All rights reserved.\n";
 
 #include "print.h"
 
+#include "diag-control.h"
+
 #include "fptype.h"
 
 #ifndef PATH_MAX
@@ -238,10 +242,6 @@ static int infoprint;
 
 char *program_name;
 
-#ifdef HAVE_CASPER
-cap_channel_t *capdns;
-#endif
-
 /* Forwards */
 static void (*setsignal (int sig, void (*func)(int)))(int);
 static void cleanup(int);
@@ -795,7 +795,7 @@ droproot(const char *username, const char *chroot_dir)
                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. */
-DIAG_OFF_CLANG(assign-enum)
+DIAG_OFF_ASSIGN_ENUM
        capng_updatev(
                CAPNG_DROP,
                CAPNG_EFFECTIVE | CAPNG_PERMITTED,
@@ -803,7 +803,7 @@ DIAG_OFF_CLANG(assign-enum)
                CAP_SETGID,
                CAP_SYS_CHROOT,
                -1);
-DIAG_ON_CLANG(assign-enum)
+DIAG_ON_ASSIGN_ENUM
        capng_apply(CAPNG_SELECT_BOTH);
 #endif /* HAVE_LIBCAP_NG */
 
@@ -1484,6 +1484,7 @@ main(int argc, char **argv)
        int yflag_dlt = -1;
        const char *yflag_dlt_name = NULL;
        int print = 0;
+       long Cflagmult;
 
        netdissect_options Ndo;
        netdissect_options *ndo = &Ndo;
@@ -1565,19 +1566,77 @@ main(int argc, char **argv)
 #else
                        Cflag = strtol(optarg, &endp, 10);
 #endif
-                       if (endp == optarg || *endp != '\0' || errno != 0
-                           || Cflag <= 0)
+                       if (endp == optarg || errno != 0 || Cflag <= 0)
                                error("invalid file size %s", optarg);
+
+                       if (*endp == '\0') {
+                               /*
+                                * There's nothing after the file size,
+                                * so the size is in units of 1 MB
+                                * (1,000,000 bytes).
+                                */
+                               Cflagmult = 1000000;
+                       } else {
+                               /*
+                                * There's something after the file
+                                * size.
+                                *
+                                * If it's a single letter, then:
+                                *
+                                *   if the letter is k or K, the size
+                                *   is in units of 1 KiB (1024 bytes);
+                                *
+                                *   if the letter is m or M, the size
+                                *   is in units of 1 MiB (1,048,576 bytes);
+                                *
+                                *   if the letter is g or G, the size
+                                *   is in units of 1 GiB (1,073,741,824 bytes).
+                                *
+                                * Otherwise, it's an error.
+                                */
+                               switch (*endp) {
+
+                               case 'k':
+                               case 'K':
+                                       Cflagmult = 1024;
+                                       break;
+
+                               case 'm':
+                               case 'M':
+                                       Cflagmult = 1024*1024;
+                                       break;
+
+                               case 'g':
+                               case 'G':
+                                       Cflagmult = 1024*1024*1024;
+                                       break;
+
+                               default:
+                                       error("invalid file size %s", optarg);
+                               }
+
+                               /*
+                                * OK, there was a letter that we treat
+                                * as a units indication; was there
+                                * anything after it?
+                                */
+                               endp++;
+                               if (*endp != '\0') {
+                                       /* Yes - error */
+                                       error("invalid file size %s", optarg);
+                               }
+                       }
+
                        /*
-                        * Will multiplying it by 1000000 overflow?
+                        * Will multiplying it by multiplier overflow?
                         */
 #ifdef HAVE_PCAP_DUMP_FTELL64
-                       if (Cflag > INT64_T_CONSTANT(0x7fffffffffffffff) / 1000000)
+                       if (Cflag > INT64_T_CONSTANT(0x7fffffffffffffff) / Cflagmult)
 #else
-                       if (Cflag > LONG_MAX / 1000000)
+                       if (Cflag > LONG_MAX / Cflagmult)
 #endif
                                error("file size %s is too large", optarg);
-                       Cflag *= 1000000;
+                       Cflag *= Cflagmult;
                        break;
 
                case 'd':
@@ -1805,6 +1864,8 @@ main(int argc, char **argv)
                                ndo->ndo_packettype = PT_SOMEIP;
                        else if (ascii_strcasecmp(optarg, "domain") == 0)
                                ndo->ndo_packettype = PT_DOMAIN;
+                       else if (ascii_strcasecmp(optarg, "quic") == 0)
+                               ndo->ndo_packettype = PT_QUIC;
                        else
                                error("unknown packet type `%s'", optarg);
                        break;
@@ -2278,33 +2339,33 @@ main(int argc, char **argv)
                /* Initialize capng */
                capng_clear(CAPNG_SELECT_BOTH);
                if (username) {
-DIAG_OFF_CLANG(assign-enum)
+DIAG_OFF_ASSIGN_ENUM
                        capng_updatev(
                                CAPNG_ADD,
                                CAPNG_PERMITTED | CAPNG_EFFECTIVE,
                                CAP_SETUID,
                                CAP_SETGID,
                                -1);
-DIAG_ON_CLANG(assign-enum)
+DIAG_ON_ASSIGN_ENUM
                }
                if (chroot_dir) {
-DIAG_OFF_CLANG(assign-enum)
+DIAG_OFF_ASSIGN_ENUM
                        capng_update(
                                CAPNG_ADD,
                                CAPNG_PERMITTED | CAPNG_EFFECTIVE,
                                CAP_SYS_CHROOT
                                );
-DIAG_ON_CLANG(assign-enum)
+DIAG_ON_ASSIGN_ENUM
                }
 
                if (WFileName) {
-DIAG_OFF_CLANG(assign-enum)
+DIAG_OFF_ASSIGN_ENUM
                        capng_update(
                                CAPNG_ADD,
                                CAPNG_PERMITTED | CAPNG_EFFECTIVE,
                                CAP_DAC_OVERRIDE
                                );
-DIAG_ON_CLANG(assign-enum)
+DIAG_ON_ASSIGN_ENUM
                }
                capng_apply(CAPNG_SELECT_BOTH);
 #endif /* HAVE_LIBCAP_NG */
@@ -2370,17 +2431,44 @@ DIAG_ON_CLANG(assign-enum)
 #endif
                if (Cflag != 0 || Gflag != 0) {
 #ifdef HAVE_CAPSICUM
-                       dumpinfo.WFileName = strdup(basename(WFileName));
+                       /*
+                        * basename() and dirname() may modify their input buffer
+                        * and they do since FreeBSD 12.0, but they didn't before.
+                        * Hence use the return value only, but always assume the
+                        * input buffer has been modified and would need to be
+                        * reset before the next use.
+                        */
+                       char *WFileName_copy;
+
+                       if ((WFileName_copy = strdup(WFileName)) == NULL) {
+                               error("Unable to allocate memory for file %s",
+                                   WFileName);
+                       }
+                       DIAG_OFF_C11_EXTENSIONS
+                       dumpinfo.WFileName = strdup(basename(WFileName_copy));
+                       DIAG_ON_C11_EXTENSIONS
                        if (dumpinfo.WFileName == NULL) {
                                error("Unable to allocate memory for file %s",
                                    WFileName);
                        }
-                       dumpinfo.dirfd = open(dirname(WFileName),
+                       free(WFileName_copy);
+
+                       if ((WFileName_copy = strdup(WFileName)) == NULL) {
+                               error("Unable to allocate memory for file %s",
+                                   WFileName);
+                       }
+                       DIAG_OFF_C11_EXTENSIONS
+                       char *WFileName_dirname = dirname(WFileName_copy);
+                       DIAG_ON_C11_EXTENSIONS
+                       dumpinfo.dirfd = open(WFileName_dirname,
                            O_DIRECTORY | O_RDONLY);
                        if (dumpinfo.dirfd < 0) {
                                error("unable to open directory %s",
-                                   dirname(WFileName));
+                                   WFileName_dirname);
                        }
+                       free(WFileName_dirname);
+                       free(WFileName_copy);
+
                        cap_rights_init(&rights, CAP_CREATE, CAP_FCNTL,
                            CAP_FTRUNCATE, CAP_LOOKUP, CAP_SEEK, CAP_WRITE);
                        if (cap_rights_limit(dumpinfo.dirfd, &rights) < 0 &&
@@ -3115,7 +3203,7 @@ static void verbose_stats_dump(int sig _U_)
 }
 #endif /* _WIN32 */
 
-USES_APPLE_DEPRECATED_API
+DIAG_OFF_DEPRECATION
 static void
 print_version(FILE *f)
 {
@@ -3153,7 +3241,7 @@ print_version(FILE *f)
 #  endif
 #endif /* __SANITIZE_ADDRESS__ or __has_feature */
 }
-USES_APPLE_RST
+DIAG_ON_DEPRECATION
 
 static void
 print_usage(FILE *f)