]> The Tcpdump Group git mirrors - tcpdump/blobdiff - tcpdump.c
Give more details for --time-stamp-precision.
[tcpdump] / tcpdump.c
index b08e00f1d90943cb7b1449841592a20fed76b7fd..d9f3e0fa96761fa993b0360fca4c53585c254d90 100644 (file)
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -57,6 +57,10 @@ extern int SIZE_BUF;
 #include <smi.h>
 #endif
 
+#ifdef HAVE_LIBCRYPTO
+#include <openssl/crypto.h>
+#endif
+
 #ifdef HAVE_GETOPT_LONG
 #include <getopt.h>
 #else
@@ -122,7 +126,8 @@ int32_t thiszone;           /* seconds offset from gmt to local time */
 /* Forwards */
 static RETSIGTYPE cleanup(int);
 static RETSIGTYPE child_cleanup(int);
-static void usage(void) __attribute__((noreturn));
+static void print_version(void);
+static void print_usage(void);
 static void show_dlts_and_exit(const char *device, pcap_t *pd) __attribute__((noreturn));
 
 static void print_packet(u_char *, const struct pcap_pkthdr *, const u_char *);
@@ -638,13 +643,16 @@ show_devices_and_exit (void)
  * doesn't make sense; it should be --verbosity={N} or something such
  * as that.
  *
- * We do not currently have long options with no corresponding short
- * options; for those, we should define values outside the range of
- * ASCII graphic characters, make that the last component of the
- * entry for the long option, and have a case for that option in the
- * switch statement.
+ * For long options with no corresponding short options, we define values
+ * outside the range of ASCII graphic characters, make that the last
+ * component of the entry for the long option, and have a case for that
+ * option in the switch statement.
  */
-static struct option longopts[] = {
+#define OPTION_NUMBER  128
+#define OPTION_VERSION 129
+#define OPTION_TSTAMP_PRECISION 130
+
+static const struct option longopts[] = {
 #if defined(HAVE_PCAP_CREATE) || defined(WIN32)
        { "buffer-size", required_argument, NULL, 'B' },
 #endif
@@ -658,6 +666,7 @@ static struct option longopts[] = {
        { "time-stamp-type", required_argument, NULL, 'j' },
        { "list-time-stamp-types", no_argument, NULL, 'J' },
 #endif
+       { "time-stamp-precision", required_argument, NULL, OPTION_TSTAMP_PRECISION},
        { "dont-verify-checksums", no_argument, NULL, 'K' },
        { "list-data-link-types", no_argument, NULL, 'L' },
        { "no-optimize", no_argument, NULL, 'O' },
@@ -675,7 +684,8 @@ static struct option longopts[] = {
        { "debug-filter-parser", no_argument, NULL, 'Y' },
 #endif
        { "relinquish-privileges", required_argument, NULL, 'Z' },
-       { "number", no_argument, NULL, 'z' + 1},
+       { "number", no_argument, NULL, OPTION_NUMBER },
+       { "version", no_argument, NULL, OPTION_VERSION },
        { NULL, 0, NULL, 0 }
 };
 
@@ -703,7 +713,10 @@ droproot(const char *username, const char *chroot_dir)
 #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);
+                       fprintf(stderr, "error : ret %d\n", ret);
+               }
+               else {
+                       printf("dropped privs to %s\n", username);
                }
                /* We don't need CAP_SETUID and CAP_SETGID */
                capng_update(CAPNG_DROP, CAPNG_EFFECTIVE, CAP_SETUID);
@@ -722,6 +735,9 @@ droproot(const char *username, const char *chroot_dir)
                            pcap_strerror(errno));
                        exit(1);
                }
+               else {
+                       printf("dropped privs to %s\n", username);
+               }
 #endif /* HAVE_CAP_NG_H */
        }
        else {
@@ -832,6 +848,18 @@ get_next_file(FILE *VFile, char *ptr)
        return ret;
 }
 
+static int
+tstamp_precision_from_string(const char *precision)
+{
+       if (strncmp(precision, "nano", strlen("nano")) == 0)
+               return PCAP_TSTAMP_PRECISION_NANO;
+
+       if (strncmp(precision, "micro", strlen("micro")) == 0)
+               return PCAP_TSTAMP_PRECISION_MICRO;
+
+       return -EINVAL;
+}
+
 int
 main(int argc, char **argv)
 {
@@ -979,7 +1007,8 @@ main(int argc, char **argv)
                        break;
 
                case 'h':
-                       usage();
+                       print_usage();
+                       exit(0);
                        break;
 
                case 'H':
@@ -1257,12 +1286,24 @@ main(int argc, char **argv)
                        username = strdup(optarg);
                        break;
 
-               case 'z' + 1:
+               case OPTION_NUMBER:
                        gndo->ndo_packet_number = 1;
                        break;
 
+               case OPTION_VERSION:
+                       print_version();
+                       exit(0);
+                       break;
+
+               case OPTION_TSTAMP_PRECISION:
+                       gndo->ndo_tstamp_precision = tstamp_precision_from_string(optarg);
+                       if (gndo->ndo_tstamp_precision < 0)
+                               error("unsupported time stamp precision");
+                       break;
+
                default:
-                       usage();
+                       print_usage();
+                       exit(1);
                        /* NOTREACHED */
                }
 
@@ -1351,7 +1392,11 @@ main(int argc, char **argv)
                        RFileName = VFileLine;
                }
 
-               pd = pcap_open_offline(RFileName, ebuf);
+               if (gndo->ndo_tstamp_precision == PCAP_TSTAMP_PRECISION_NANO)
+                       pd = pcap_open_offline_with_tstamp_precision(RFileName, PCAP_TSTAMP_PRECISION_NANO, ebuf);
+               else
+                       pd = pcap_open_offline_with_tstamp_precision(RFileName, PCAP_TSTAMP_PRECISION_MICRO, ebuf);
+
                if (pd == NULL)
                        error("%s", ebuf);
                dlt = pcap_datalink(pd);
@@ -1398,6 +1443,13 @@ main(int argc, char **argv)
                if (Jflag)
                        show_tstamp_types_and_exit(device, pd);
 #endif
+               if (gndo->ndo_tstamp_precision == PCAP_TSTAMP_PRECISION_NANO) {
+                       status = pcap_set_tstamp_precision(pd, PCAP_TSTAMP_PRECISION_NANO);
+                       if (status != 0)
+                               error("%s: Can't set nanosecond time stamp precision: %s",
+                                       device, pcap_statustostr(status));
+                }
+
                /*
                 * Is this an interface that supports monitor mode?
                 */
@@ -2242,8 +2294,9 @@ static void verbose_stats_dump(int sig _U_)
 }
 #endif
 
+USES_APPLE_DEPRECATED_API
 static void
-usage(void)
+print_version(void)
 {
        extern char version[];
 #ifndef HAVE_PCAP_LIB_VERSION
@@ -2270,6 +2323,21 @@ usage(void)
        (void)fprintf(stderr, "libpcap version %s\n", pcap_version);
 #endif /* WIN32 */
 #endif /* HAVE_PCAP_LIB_VERSION */
+
+#if defined(HAVE_LIBCRYPTO) && defined(SSLEAY_VERSION)
+       (void)fprintf (stderr, "%s\n", SSLeay_version(SSLEAY_VERSION));
+#endif
+
+#if defined(HAVE_SMI_H)
+       (void)fprintf (stderr, "SMI-library: %s\n", smi_version_string);
+#endif
+}
+USES_APPLE_RST
+
+static void
+print_usage(void)
+{
+       print_version();
        (void)fprintf(stderr,
 "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,
@@ -2281,12 +2349,11 @@ usage(void)
 "\t\t[ -Q in|out|inout ]\n");
 #endif
        (void)fprintf(stderr,
-"\t\t[ -r file ] [ -s snaplen ] [ -T type ] [ -V file ] [ -w file ]\n");
+"\t\t[ -r file ] [ -s snaplen ] [ -T type ] [ --version ] [ -V file ]\n");
        (void)fprintf(stderr,
-"\t\t[ -W filecount ] [ -y datalinktype ] [ -z command ]\n");
+"\t\t[ -w file ] [ -W filecount ] [ -y datalinktype ] [ -z command ]\n");
        (void)fprintf(stderr,
 "\t\t[ -Z user ] [ expression ]\n");
-       exit(1);
 }