X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/a98167e7c9f2431319ee9f223b22bd495c2ca162..246ca110d152b6483fd8c1c176a570858307f76b:/tcpdump.c diff --git a/tcpdump.c b/tcpdump.c index 9e6a2995..cd277042 100644 --- a/tcpdump.c +++ b/tcpdump.c @@ -150,6 +150,8 @@ The Regents of the University of California. All rights reserved.\n"; #include "print.h" +#include "fptype.h" + #ifndef PATH_MAX #define PATH_MAX 1024 #endif @@ -203,6 +205,7 @@ static int Iflag; /* rfmon (monitor) mode */ static int Jflag; /* list available time stamp types */ static int jflag = -1; /* packet time stamp source */ #endif +static int lflag; /* line-buffered output */ static int pflag; /* don't go promiscuous */ #ifdef HAVE_PCAP_SETDIRECTION static int Qflag = -1; /* restrict captured packet by send/receive direction */ @@ -213,6 +216,7 @@ static int Uflag; /* "unbuffered" output of dump files */ static int Wflag; /* recycle output files after this number of files */ static int WflagChars; static char *zflag = NULL; /* compress each savefile using a specified command (like gzip or bzip2) */ +static int timeout = 1000; /* default timeout = 1000 ms = 1 s */ #ifdef HAVE_PCAP_SET_IMMEDIATE_MODE static int immediate_mode; #endif @@ -685,6 +689,7 @@ show_remote_devices_and_exit(void) #define OPTION_LIST_REMOTE_INTERFACES 132 #define OPTION_TSTAMP_MICRO 133 #define OPTION_TSTAMP_NANO 134 +#define OPTION_FP_TYPE 135 static const struct option longopts[] = { #if defined(HAVE_PCAP_CREATE) || defined(_WIN32) @@ -728,6 +733,7 @@ static const struct option longopts[] = { { "debug-filter-parser", no_argument, NULL, 'Y' }, #endif { "relinquish-privileges", required_argument, NULL, 'Z' }, + { "fp-type", no_argument, NULL, OPTION_FP_TYPE }, { "number", no_argument, NULL, '#' }, { "print", no_argument, NULL, OPTION_PRINT }, { "version", no_argument, NULL, OPTION_VERSION }, @@ -844,7 +850,7 @@ MakeFilename(char *buffer, char *orig_name, int cnt, int max_chars) if (cnt == 0 && max_chars == 0) strncpy(buffer, filename, PATH_MAX + 1); else - if (nd_snprintf(buffer, PATH_MAX + 1, "%s%0*d", filename, max_chars, cnt) > PATH_MAX) + if (snprintf(buffer, PATH_MAX + 1, "%s%0*d", filename, max_chars, cnt) > PATH_MAX) /* Report an error if the filename is too large */ error("too many output files or filename is too long (> %d)", PATH_MAX); free(filename); @@ -854,13 +860,15 @@ static char * get_next_file(FILE *VFile, char *ptr) { char *ret; + size_t len; ret = fgets(ptr, PATH_MAX, VFile); if (!ret) return NULL; - if (ptr[strlen(ptr) - 1] == '\n') - ptr[strlen(ptr) - 1] = '\0'; + len = strlen (ptr); + if (len > 0 && ptr[len - 1] == '\n') + ptr[len - 1] = '\0'; return ret; } @@ -1227,7 +1235,7 @@ open_interface(const char *device, netdissect_options *ndo, char *ebuf) */ *ebuf = '\0'; pc = pcap_open(device, ndo->ndo_snaplen, - pflag ? 0 : PCAP_OPENFLAG_PROMISCUOUS, 1000, NULL, + pflag ? 0 : PCAP_OPENFLAG_PROMISCUOUS, timeout, NULL, ebuf); if (pc == NULL) { /* @@ -1309,7 +1317,7 @@ open_interface(const char *device, netdissect_options *ndo, char *ebuf) error("%s: Can't set monitor mode: %s", device, pcap_statustostr(status)); } - status = pcap_set_timeout(pc, 1000); + status = pcap_set_timeout(pc, timeout); if (status != 0) error("%s: pcap_set_timeout failed: %s", device, pcap_statustostr(status)); @@ -1343,10 +1351,8 @@ open_interface(const char *device, netdissect_options *ndo, char *ebuf) /* * Return an error for our caller to handle. */ - nd_snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s\n(%s)", + snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s: %s\n(%s)", device, pcap_statustostr(status), cp); - pcap_close(pc); - return (NULL); } else if (status == PCAP_ERROR_PERM_DENIED && *cp != '\0') error("%s: %s\n(%s)", device, pcap_statustostr(status), cp); @@ -1357,7 +1363,7 @@ open_interface(const char *device, netdissect_options *ndo, char *ebuf) char sysctl[32]; size_t s = sizeof(parent); - nd_snprintf(sysctl, sizeof(sysctl), + snprintf(sysctl, sizeof(sysctl), "net.wlan.%d.%%parent", atoi(device + 4)); sysctlbyname(sysctl, parent, &s, NULL, 0); strlcpy(newdev, device, sizeof(newdev)); @@ -1377,6 +1383,8 @@ open_interface(const char *device, netdissect_options *ndo, char *ebuf) else error("%s: %s", device, pcap_statustostr(status)); + pcap_close(pc); + return (NULL); } else if (status > 0) { /* * pcap_activate() succeeded, but it's warning us @@ -1408,8 +1416,8 @@ open_interface(const char *device, netdissect_options *ndo, char *ebuf) * specified, default to 256KB. */ if (ndo->ndo_snaplen == 0) - ndo->ndo_snaplen = 262144; - pc = pcap_open_live(device, ndo->ndo_snaplen, !pflag, 1000, ebuf); + ndo->ndo_snaplen = MAXIMUM_SNAPLEN; + pc = pcap_open_live(device, ndo->ndo_snaplen, !pflag, timeout, ebuf); if (pc == NULL) { /* * If this failed with "No such device", that means @@ -1446,7 +1454,7 @@ main(int argc, char **argv) u_char *pcap_userdata; char ebuf[PCAP_ERRBUF_SIZE]; char VFileLine[PATH_MAX + 1]; - char *username = NULL; + const char *username = NULL; #ifndef _WIN32 const char *chroot_dir = NULL; #endif @@ -1666,6 +1674,7 @@ main(int argc, char **argv) setvbuf(stdout, NULL, _IOLBF, 0); #endif #endif /* _WIN32 */ + lflag = 1; break; case 'K': @@ -1780,6 +1789,10 @@ main(int argc, char **argv) ndo->ndo_packettype = PT_LMP; else if (ascii_strcasecmp(optarg, "resp") == 0) ndo->ndo_packettype = PT_RESP; + else if (ascii_strcasecmp(optarg, "ptp") == 0) + ndo->ndo_packettype = PT_PTP; + else if (ascii_strcasecmp(optarg, "someip") == 0) + ndo->ndo_packettype = PT_SOMEIP; else error("unknown packet type `%s'", optarg); break; @@ -1884,6 +1897,17 @@ main(int argc, char **argv) break; #endif + case OPTION_FP_TYPE: + /* + * Print out the type of floating-point arithmetic + * we're doing; it's probably IEEE, unless somebody + * tries to run this on a VAX, but the precision + * may differ (e.g., it might be 32-bit, 64-bit, + * or 80-bit). + */ + float_type_check(0x4e93312d); + return 0; + default: print_usage(); exit_tcpdump(S_ERR_HOST_PROGRAM); @@ -1920,19 +1944,18 @@ 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 - * and the standard output is a terminal, use immediate mode, - * as the user's probably expecting to see packets pop up - * immediately. + * If we're printing dissected packets to the standard output, + * and either the standard output is a terminal or we're doing + * "line" buffering, set the capture timeout to .1 second rather + * than 1 second, as the user's probably expecting to see packets + * pop up immediately shortly after they arrive. * - * XXX - set the timeout to a lower value, instead? If so, - * what value would be appropriate? + * XXX - would there be some value appropriate for all cases, + * based on, say, the buffer size and packet input rate? */ - if ((WFileName == NULL || print) && isatty(1)) - immediate_mode = 1; -#endif + if ((WFileName == NULL || print) && (isatty(1) || lflag)) + timeout = 100; #ifdef WITH_CHROOT /* if run as root, prepare for chrooting */ @@ -2020,6 +2043,29 @@ main(int argc, char **argv) if (dlt == DLT_LINUX_SLL2) fprintf(stderr, "Warning: interface names might be incorrect\n"); #endif + } else if (dflag && !device) { + int dump_dlt = DLT_EN10MB; + /* + * We're dumping the compiled code without an explicit + * device specification. (If a device is specified, we + * definitely want to open it to use the DLT of that device.) + * Either default to DLT_EN10MB with a warning, or use + * the user-specified value if supplied. + */ + /* + * If no snapshot length was specified, or a length of 0 was + * specified, default to 256KB. + */ + if (ndo->ndo_snaplen == 0) + ndo->ndo_snaplen = MAXIMUM_SNAPLEN; + /* + * If a DLT was specified with the -y flag, use that instead. + */ + if (yflag_dlt != -1) + dump_dlt = yflag_dlt; + else + fprintf(stderr, "Warning: assuming Ethernet\n"); + pd = pcap_open_dead(dump_dlt, ndo->ndo_snaplen); } else { /* * We're doing a live capture. @@ -3063,9 +3109,6 @@ print_version(void) smi_version_string = nd_smi_version_string(); if (smi_version_string != NULL) (void)fprintf (stderr, "SMI-library: %s\n", smi_version_string); -#ifdef HAVE_DNET_HTOA - (void)fprintf(stderr, "libdnet unknown version\n"); -#endif #if defined(__SANITIZE_ADDRESS__) (void)fprintf (stderr, "Compiled with AddressSanitizer/GCC.\n");