X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/bbedebc666a341d8e14922dce37a92766400c798..e1e0824e40f4bfaaec7636f1e452911a6b8f7eca:/tcpdump.c diff --git a/tcpdump.c b/tcpdump.c index 2bc87924..2e9a5055 100644 --- a/tcpdump.c +++ b/tcpdump.c @@ -46,7 +46,6 @@ The Regents of the University of California. All rights reserved.\n"; #include #ifdef WIN32 -#include "getopt.h" #include "w32_fzs.h" extern int strcasecmp (const char *__s1, const char *__s2); extern int SIZE_BUF; @@ -58,6 +57,15 @@ extern int SIZE_BUF; #include #endif +#ifdef HAVE_LIBCRYPTO +#include +#endif + +#ifdef HAVE_GETOPT_LONG +#include +#else +#include "getopt_long.h" +#endif #include #include #include @@ -69,7 +77,6 @@ extern int SIZE_BUF; #include #include #include -#include #endif /* WIN32 */ /* capabilities convinience library */ @@ -119,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 *); @@ -547,6 +555,27 @@ show_devices_and_exit (void) } #endif /* HAVE_PCAP_FINDALLDEVS */ +/* + * Short options. + * + * Note that there we use all letters for short options except for g, k, + * o, and P, and those are used by other versions of tcpdump, and we should + * only use them for the same purposes that the other versions of tcpdump + * use them: + * + * OS X tcpdump uses -g to force non--v output for IP to be on one + * line, making it more "g"repable; + * + * OS X tcpdump uses -k tospecify that packet comments in pcap-ng files + * should be printed; + * + * OpenBSD tcpdump uses -o to indicate that OS fingerprinting should be done + * for hosts sending TCP SYN packets; + * + * OS X tcpdump uses -P to indicate that -w should write pcap-ng rather + * than pcap files. + */ + /* * Set up flags that might or might not be supported depending on the * version of libpcap we're using. @@ -599,6 +628,65 @@ show_devices_and_exit (void) #define Q_FLAG #endif +/* + * Long options. + * + * We do not currently have long options corresponding to all short + * options; we should probably pick appropriate option names for them. + * + * However, the short options where the number of times the option is + * specified matters, such as -v and -d and -t, should probably not + * just map to a long option, as saying + * + * tcpdump --verbose --verbose + * + * doesn't make sense; it should be --verbosity={N} or something such + * as that. + * + * 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. + */ +#define OPTION_NUMBER 128 +#define OPTION_VERSION 129 + +static struct option longopts[] = { +#if defined(HAVE_PCAP_CREATE) || defined(WIN32) + { "buffer-size", required_argument, NULL, 'B' }, +#endif + { "list-interfaces", no_argument, NULL, 'D' }, + { "help", no_argument, NULL, 'h' }, + { "interface", required_argument, NULL, 'i' }, +#ifdef HAVE_PCAP_CREATE + { "monitor-mode", no_argument, NULL, 'I' }, +#endif +#ifdef HAVE_PCAP_SET_TSTAMP_TYPE + { "time-stamp-type", required_argument, NULL, 'j' }, + { "list-time-stamp-types", no_argument, NULL, 'J' }, +#endif + { "dont-verify-checksums", no_argument, NULL, 'K' }, + { "list-data-link-types", no_argument, NULL, 'L' }, + { "no-optimize", no_argument, NULL, 'O' }, + { "no-promiscuous-mode", no_argument, NULL, 'p' }, +#ifdef HAVE_PCAP_SETDIRECTION + { "direction", required_argument, NULL, 'Q' }, +#endif + { "snapshot-length", required_argument, NULL, 's' }, + { "absolute-tcp-sequence-numbers", no_argument, NULL, 'S' }, +#ifdef HAVE_PCAP_DUMP_FLUSH + { "packet-buffered", no_argument, NULL, 'U' }, +#endif + { "linktype", required_argument, NULL, 'y' }, +#if defined(HAVE_PCAP_DEBUG) || defined(HAVE_YYDEBUG) + { "debug-filter-parser", no_argument, NULL, 'Y' }, +#endif + { "relinquish-privileges", required_argument, NULL, 'Z' }, + { "number", no_argument, NULL, OPTION_NUMBER }, + { "version", no_argument, NULL, OPTION_VERSION }, + { NULL, 0, NULL, 0 } +}; + #ifndef WIN32 /* Drop root privileges and chroot if necessary */ static void @@ -817,7 +905,7 @@ main(int argc, char **argv) #endif while ( - (op = getopt(argc, argv, "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:hHi:" I_FLAG j_FLAG J_FLAG "KlLm:M:nNOpq" Q_FLAG "r:Rs:StT:u" U_FLAG "vV:w:W:xXy:Yz:Z:")) != -1) + (op = getopt_long(argc, argv, "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:hHi:" I_FLAG j_FLAG J_FLAG "KlLm:M:nNOpq" Q_FLAG "r:Rs:StT:u" U_FLAG "vV:w:W:xXy:Yz:Z:", longopts, NULL)) != -1) switch (op) { case 'a': @@ -899,7 +987,8 @@ main(int argc, char **argv) break; case 'h': - usage(); + print_usage(); + exit(0); break; case 'H': @@ -1177,8 +1266,18 @@ main(int argc, char **argv) username = strdup(optarg); break; + case OPTION_NUMBER: + gndo->ndo_packet_number = 1; + break; + + case OPTION_VERSION: + print_version(); + exit(0); + break; + default: - usage(); + print_usage(); + exit(1); /* NOTREACHED */ } @@ -1999,6 +2098,10 @@ print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) print_info = (struct print_info *)user; ndo = print_info->ndo; + + if(ndo->ndo_packet_number) + ND_PRINT((ndo, "%5u ", packets_captured)); + ts_print(ndo, &h->ts); /* @@ -2155,7 +2258,7 @@ static void verbose_stats_dump(int sig _U_) #endif static void -usage(void) +print_version(void) { extern char version[]; #ifndef HAVE_PCAP_LIB_VERSION @@ -2182,23 +2285,36 @@ 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 +} + +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, "\t\t[ -C file_size ] [ -E algo:secret ] [ -F file ] [ -G seconds ]\n"); (void)fprintf(stderr, -"\t\t[ -i interface ]" j_FLAG_USAGE " [ -M secret ]\n"); +"\t\t[ -i interface ]" j_FLAG_USAGE " [ -M secret ] [ --number ]\n"); #ifdef HAVE_PCAP_SETDIRECTION (void)fprintf(stderr, "\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); }