X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/2f63616362063fc8a34b1bb7eaeddae7d395b8d3..2d0270b827db5c1eaa6af8ca85bd07aca1ef90df:/tcpdump.c diff --git a/tcpdump.c b/tcpdump.c index b1f88cf3..207908a5 100644 --- a/tcpdump.c +++ b/tcpdump.c @@ -58,7 +58,6 @@ The Regents of the University of California. All rights reserved.\n"; #ifdef WIN32 #include "w32_fzs.h" -extern int strcasecmp (const char *__s1, const char *__s2); extern int SIZE_BUF; #define off_t long #define uint UINT @@ -121,6 +120,9 @@ extern int SIZE_BUF; #include "setsignal.h" #include "gmt2local.h" #include "pcap-missing.h" +#include "ascii_strcasecmp.h" + +#include "print.h" #ifndef PATH_MAX #define PATH_MAX 1024 @@ -132,18 +134,24 @@ extern int SIZE_BUF; #define SIGNAL_REQ_INFO SIGUSR1 #endif -netdissect_options Gndo; -netdissect_options *gndo = &Gndo; - +static int Cflag; /* rotate dump files after this many bytes */ +static int Cflag_count; /* Keep track of which file number we're writing */ static int Dflag; /* list available devices and exit */ static int dflag; /* print filter code */ +static int Gflag; /* rotate dump files after this many seconds */ +static int Gflag_count; /* number of files created with Gflag rotation */ +static time_t Gflag_time; /* The last time_t the dump file was rotated. */ static int Lflag; /* list available data link types and exit */ +static int Iflag; /* rfmon (monitor) mode */ #ifdef HAVE_PCAP_SET_TSTAMP_TYPE static int Jflag; /* list available time stamp types */ #endif #ifdef HAVE_PCAP_SETDIRECTION int Qflag = -1; /* restrict captured packet by send/receive direction */ #endif +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 infodelay; @@ -151,31 +159,18 @@ static int infoprint; char *program_name; -int32_t thiszone; /* seconds offset from gmt to local time */ - /* Forwards */ static RETSIGTYPE cleanup(int); static RETSIGTYPE child_cleanup(int); 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 show_tstamp_types_and_exit(const char *device) __attribute__((noreturn)); +static void show_dlts_and_exit(const char *device) __attribute__((noreturn)); static void print_packet(u_char *, const struct pcap_pkthdr *, const u_char *); -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, ...) - __attribute__((noreturn)) -#ifdef __ATTRIBUTE___FORMAT_OK - __attribute__((format (printf, 2, 3))) -#endif /* __ATTRIBUTE___FORMAT_OK */ - ; -static void ndo_warning(netdissect_options *ndo, const char *fmt, ...) -#ifdef __ATTRIBUTE___FORMAT_OK - __attribute__((format (printf, 2, 3))) -#endif /* __ATTRIBUTE___FORMAT_OK */ - ; #ifdef SIGNAL_REQ_INFO RETSIGTYPE requestinfo(int); @@ -192,202 +187,6 @@ RETSIGTYPE requestinfo(int); static void info(int); static u_int packets_captured; -struct printer { - if_printer f; - int type; -}; - - -struct ndo_printer { - if_ndo_printer f; - int type; -}; - - -static const struct printer printers[] = { - { NULL, 0 }, -}; - -static const struct ndo_printer ndo_printers[] = { - { ether_if_print, DLT_EN10MB }, -#ifdef DLT_IPNET - { ipnet_if_print, DLT_IPNET }, -#endif -#ifdef DLT_IEEE802_15_4 - { ieee802_15_4_if_print, DLT_IEEE802_15_4 }, -#endif -#ifdef DLT_IEEE802_15_4_NOFCS - { ieee802_15_4_if_print, DLT_IEEE802_15_4_NOFCS }, -#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 -#if defined(DLT_NFLOG) && defined(HAVE_PCAP_NFLOG_H) - { nflog_if_print, DLT_NFLOG}, -#endif -#ifdef DLT_CIP - { cip_if_print, DLT_CIP }, -#endif -#ifdef DLT_ATM_CLIP - { cip_if_print, DLT_ATM_CLIP }, -#endif -#ifdef DLT_IP_OVER_FC - { ipfc_if_print, DLT_IP_OVER_FC }, -#endif - { null_if_print, DLT_NULL }, -#ifdef DLT_LOOP - { null_if_print, DLT_LOOP }, -#endif -#ifdef DLT_APPLE_IP_OVER_IEEE1394 - { ap1394_if_print, DLT_APPLE_IP_OVER_IEEE1394 }, -#endif -#if defined(DLT_BLUETOOTH_HCI_H4_WITH_PHDR) && defined(HAVE_PCAP_BLUETOOTH_H) - { bt_if_print, DLT_BLUETOOTH_HCI_H4_WITH_PHDR}, -#endif -#ifdef DLT_LANE8023 - { lane_if_print, DLT_LANE8023 }, -#endif - { arcnet_if_print, DLT_ARCNET }, -#ifdef DLT_ARCNET_LINUX - { arcnet_linux_if_print, DLT_ARCNET_LINUX }, -#endif - { raw_if_print, DLT_RAW }, -#ifdef DLT_IPV4 - { raw_if_print, DLT_IPV4 }, -#endif -#ifdef DLT_IPV6 - { raw_if_print, DLT_IPV6 }, -#endif -#ifdef HAVE_PCAP_USB_H -#ifdef DLT_USB_LINUX - { usb_linux_48_byte_print, DLT_USB_LINUX}, -#endif /* DLT_USB_LINUX */ -#ifdef DLT_USB_LINUX_MMAPPED - { usb_linux_64_byte_print, DLT_USB_LINUX_MMAPPED}, -#endif /* DLT_USB_LINUX_MMAPPED */ -#endif /* HAVE_PCAP_USB_H */ -#ifdef DLT_SYMANTEC_FIREWALL - { symantec_if_print, DLT_SYMANTEC_FIREWALL }, -#endif -#ifdef DLT_C_HDLC - { chdlc_if_print, DLT_C_HDLC }, -#endif -#ifdef DLT_HDLC - { chdlc_if_print, DLT_HDLC }, -#endif -#ifdef DLT_PPP_ETHER - { pppoe_if_print, DLT_PPP_ETHER }, -#endif -#if defined(DLT_PFLOG) && defined(HAVE_NET_PFVAR_H) - { pflog_if_print, DLT_PFLOG }, -#endif - { token_if_print, DLT_IEEE802 }, - { fddi_if_print, DLT_FDDI }, -#ifdef DLT_LINUX_SLL - { sll_if_print, DLT_LINUX_SLL }, -#endif -#ifdef DLT_FR - { fr_if_print, DLT_FR }, -#endif -#ifdef DLT_FRELAY - { fr_if_print, DLT_FRELAY }, -#endif -#ifdef DLT_MFR - { mfr_if_print, DLT_MFR }, -#endif - { atm_if_print, DLT_ATM_RFC1483 }, -#ifdef DLT_SUNATM - { sunatm_if_print, DLT_SUNATM }, -#endif -#ifdef DLT_ENC - { enc_if_print, DLT_ENC }, -#endif - { sl_if_print, DLT_SLIP }, -#ifdef DLT_SLIP_BSDOS - { sl_bsdos_if_print, DLT_SLIP_BSDOS }, -#endif -#ifdef DLT_LTALK - { ltalk_if_print, DLT_LTALK }, -#endif -#ifdef DLT_JUNIPER_ATM1 - { juniper_atm1_print, DLT_JUNIPER_ATM1 }, -#endif -#ifdef DLT_JUNIPER_ATM2 - { juniper_atm2_print, DLT_JUNIPER_ATM2 }, -#endif -#ifdef DLT_JUNIPER_MFR - { juniper_mfr_print, DLT_JUNIPER_MFR }, -#endif -#ifdef DLT_JUNIPER_MLFR - { juniper_mlfr_print, DLT_JUNIPER_MLFR }, -#endif -#ifdef DLT_JUNIPER_MLPPP - { juniper_mlppp_print, DLT_JUNIPER_MLPPP }, -#endif -#ifdef DLT_JUNIPER_PPPOE - { juniper_pppoe_print, DLT_JUNIPER_PPPOE }, -#endif -#ifdef DLT_JUNIPER_PPPOE_ATM - { juniper_pppoe_atm_print, DLT_JUNIPER_PPPOE_ATM }, -#endif -#ifdef DLT_JUNIPER_GGSN - { juniper_ggsn_print, DLT_JUNIPER_GGSN }, -#endif -#ifdef DLT_JUNIPER_ES - { juniper_es_print, DLT_JUNIPER_ES }, -#endif -#ifdef DLT_JUNIPER_MONITOR - { juniper_monitor_print, DLT_JUNIPER_MONITOR }, -#endif -#ifdef DLT_JUNIPER_SERVICES - { juniper_services_print, DLT_JUNIPER_SERVICES }, -#endif -#ifdef DLT_JUNIPER_ETHER - { juniper_ether_print, DLT_JUNIPER_ETHER }, -#endif -#ifdef DLT_JUNIPER_PPP - { juniper_ppp_print, DLT_JUNIPER_PPP }, -#endif -#ifdef DLT_JUNIPER_FRELAY - { juniper_frelay_print, DLT_JUNIPER_FRELAY }, -#endif -#ifdef DLT_JUNIPER_CHDLC - { juniper_chdlc_print, DLT_JUNIPER_CHDLC }, -#endif -#ifdef DLT_PKTAP - { pktap_if_print, DLT_PKTAP }, -#endif -#ifdef DLT_IEEE802_11_RADIO - { ieee802_11_radio_if_print, DLT_IEEE802_11_RADIO }, -#endif -#ifdef DLT_IEEE802_11 - { ieee802_11_if_print, DLT_IEEE802_11}, -#endif -#ifdef DLT_IEEE802_11_RADIO_AVS - { ieee802_11_radio_avs_if_print, DLT_IEEE802_11_RADIO_AVS }, -#endif -#ifdef DLT_PRISM_HEADER - { prism_if_print, DLT_PRISM_HEADER }, -#endif - { ppp_if_print, DLT_PPP }, -#ifdef DLT_PPP_WITHDIRECTION - { ppp_if_print, DLT_PPP_WITHDIRECTION }, -#endif -#ifdef DLT_PPP_BSDOS - { ppp_bsdos_if_print, DLT_PPP_BSDOS }, -#endif -#ifdef DLT_PPP_SERIAL - { ppp_hdlc_if_print, DLT_PPP_SERIAL }, -#endif - { NULL, 0 }, -}; - static const struct tok status_flags[] = { #ifdef PCAP_IF_UP { PCAP_IF_UP, "Up" }, @@ -399,56 +198,6 @@ static const struct tok status_flags[] = { { 0, NULL } }; -if_printer -lookup_printer(int type) -{ - const struct printer *p; - - for (p = printers; p->f; ++p) - if (type == p->type) - return p->f; - - return NULL; - /* NOTREACHED */ -} - -if_ndo_printer -lookup_ndo_printer(int type) -{ - const struct ndo_printer *p; - - for (p = ndo_printers; p->f; ++p) - if (type == p->type) - return p->f; - -#if defined(DLT_USER2) && defined(DLT_PKTAP) - /* - * Apple incorrectly chose to use DLT_USER2 for their PKTAP - * header. - * - * We map DLT_PKTAP, whether it's DLT_USER2 as it is on Darwin- - * based OSes or the same value as LINKTYPE_PKTAP as it is on - * other OSes, to LINKTYPE_PKTAP, so files written with - * this version of libpcap for a DLT_PKTAP capture have a link- - * layer header type of LINKTYPE_PKTAP. - * - * However, files written on OS X Mavericks for a DLT_PKTAP - * capture have a link-layer header type of LINKTYPE_USER2. - * If we don't have a printer for DLT_USER2, and type is - * DLT_USER2, we look up the printer for DLT_PKTAP and use - * that. - */ - if (type == DLT_USER2) { - for (p = ndo_printers; p->f; ++p) - if (DLT_PKTAP == p->type) - return p->f; - } -#endif - - return NULL; - /* NOTREACHED */ -} - static pcap_t *pd; static int supports_monitor_mode; @@ -457,15 +206,6 @@ extern int optind; extern int opterr; extern char *optarg; -struct print_info { - netdissect_options *ndo; - union { - if_printer printer; - if_ndo_printer ndo_printer; - } p; - int ndo_type; -}; - struct dump_info { char *WFileName; char *CurrentFileName; @@ -478,7 +218,7 @@ struct dump_info { #ifdef HAVE_PCAP_SET_TSTAMP_TYPE static void -show_tstamp_types_and_exit(const char *device, pcap_t *pd) +show_tstamp_types_and_exit(const char *device) { int n_tstamp_types; int *tstamp_types = 0; @@ -511,9 +251,9 @@ show_tstamp_types_and_exit(const char *device, pcap_t *pd) #endif static void -show_dlts_and_exit(const char *device, pcap_t *pd) +show_dlts_and_exit(const char *device) { - int n_dlts; + int n_dlts, i; int *dlts = 0; const char *dlt_name; @@ -539,22 +279,21 @@ show_dlts_and_exit(const char *device, pcap_t *pd) (void) fprintf(stderr, "Data link types for %s (use option -y to set):\n", device); - while (--n_dlts >= 0) { - dlt_name = pcap_datalink_val_to_name(dlts[n_dlts]); + for (i = 0; i < n_dlts; i++) { + dlt_name = pcap_datalink_val_to_name(dlts[i]); if (dlt_name != NULL) { (void) fprintf(stderr, " %s (%s)", dlt_name, - pcap_datalink_val_to_description(dlts[n_dlts])); + pcap_datalink_val_to_description(dlts[i])); /* * OK, does tcpdump handle that type? */ - if (lookup_printer(dlts[n_dlts]) == NULL - && lookup_ndo_printer(dlts[n_dlts]) == NULL) + if (!has_printer(dlts[i])) (void) fprintf(stderr, " (printing not supported)"); fprintf(stderr, "\n"); } else { (void) fprintf(stderr, " DLT %d (printing not supported)\n", - dlts[n_dlts]); + dlts[i]); } } #ifdef HAVE_PCAP_FREE_DATALINKS @@ -754,12 +493,13 @@ droproot(const char *username, const char *chroot_dir) } } #ifdef HAVE_LIBCAP_NG - int ret = capng_change_id(pw->pw_uid, pw->pw_gid, CAPNG_NO_FLAG); - if (ret < 0) { - fprintf(stderr, "error : ret %d\n", ret); - } - else { - fprintf(stderr, "dropped privs to %s\n", username); + { + int ret = capng_change_id(pw->pw_uid, pw->pw_gid, CAPNG_NO_FLAG); + if (ret < 0) { + fprintf(stderr, "error : ret %d\n", ret); + } else { + fprintf(stderr, "dropped privs to %s\n", username); + } } #else if (initgroups(pw->pw_name, pw->pw_gid) != 0 || @@ -843,43 +583,6 @@ MakeFilename(char *buffer, char *orig_name, int cnt, int max_chars) free(filename); } -static int tcpdump_printf(netdissect_options *ndo _U_, - const char *fmt, ...) -{ - - va_list args; - int ret; - - va_start(args, fmt); - ret=vfprintf(stdout, fmt, args); - va_end(args); - - return ret; -} - -static struct print_info -get_print_info(int type) -{ - struct print_info printinfo; - - printinfo.ndo_type = 1; - printinfo.ndo = gndo; - printinfo.p.ndo_printer = lookup_ndo_printer(type); - if (printinfo.p.ndo_printer == NULL) { - printinfo.p.printer = lookup_printer(type); - printinfo.ndo_type = 0; - if (printinfo.p.printer == NULL) { - gndo->ndo_dltname = pcap_datalink_val_to_name(type); - if (gndo->ndo_dltname != NULL) - error("packet printing is not supported for link type %s: use -w", - gndo->ndo_dltname); - else - error("packet printing is not supported for link type %d: use -w", type); - } - } - return (printinfo); -} - static char * get_next_file(FILE *VFile, char *ptr) { @@ -980,8 +683,9 @@ tstamp_precision_to_string(int precision) * what the standard I/O library happens to require this week. */ static void -set_dump_fd_capsicum_rights(int fd) +set_dumper_capsicum_rights(pcap_dumper_t *p) { + int fd = fileno(pcap_dump_file(p)); cap_rights_t rights; cap_rights_init(&rights, CAP_SEEK, CAP_WRITE, CAP_FCNTL); @@ -999,6 +703,7 @@ main(int argc, char **argv) { register int cnt, op, i; bpf_u_int32 localnet =0 , netmask = 0; + int timezone_offset = 0; register char *cp, *infile, *cmdbuf, *device, *RFileName, *VFileName, *WFileName; pcap_handler callback; int type; @@ -1028,21 +733,23 @@ main(int argc, char **argv) cap_rights_t rights; int cansandbox; #endif /* HAVE_CAPSICUM */ + int Bflag=0; /* buffer size */ + int jflag=-1; /* packet time stamp source */ + int Oflag=1; /* run filter code optimizer */ + int pflag=0; /* don't go promiscuous */ + netdissect_options Ndo; + netdissect_options *ndo = &Ndo; #ifdef WIN32 if(wsockinit() != 0) return 1; #endif /* WIN32 */ - jflag=-1; /* not set */ - gndo->ndo_Oflag=1; - gndo->ndo_Rflag=1; - gndo->ndo_dlt=-1; - gndo->ndo_default_print=ndo_default_print; - gndo->ndo_printf=tcpdump_printf; - gndo->ndo_error=ndo_error; - gndo->ndo_warning=ndo_warning; - gndo->ndo_snaplen = DEFAULT_SNAPLEN; - gndo->ndo_immediate = 0; + memset(ndo, 0, sizeof(*ndo)); + ndo->ndo_Rflag=1; + ndo->ndo_dlt=-1; + ndo_set_function_pointers(ndo); + ndo->ndo_snaplen = DEFAULT_SNAPLEN; + ndo->ndo_immediate = 0; cnt = -1; device = NULL; @@ -1080,11 +787,11 @@ main(int argc, char **argv) break; case 'A': - ++Aflag; + ++ndo->ndo_Aflag; break; case 'b': - ++bflag; + ++ndo->ndo_bflag; break; #if defined(HAVE_PCAP_CREATE) || defined(WIN32) @@ -1120,18 +827,18 @@ main(int argc, char **argv) break; case 'e': - ++eflag; + ++ndo->ndo_eflag; break; case 'E': #ifndef HAVE_LIBCRYPTO warning("crypto code not compiled in"); #endif - gndo->ndo_espsecret = optarg; + ndo->ndo_espsecret = optarg; break; case 'f': - ++fflag; + ++ndo->ndo_fflag; break; case 'F': @@ -1159,7 +866,7 @@ main(int argc, char **argv) break; case 'H': - ++Hflag; + ++ndo->ndo_Hflag; break; case 'i': @@ -1244,7 +951,7 @@ main(int argc, char **argv) break; case 'K': - ++Kflag; + ++ndo->ndo_Kflag; break; case 'm': @@ -1252,7 +959,7 @@ main(int argc, char **argv) if (smiLoadModule(optarg) == 0) { error("could not load MIB module %s", optarg); } - sflag = 1; + ndo->ndo_sflag = 1; #else (void)fprintf(stderr, "%s: ignoring option `-m %s' ", program_name, optarg); @@ -1265,15 +972,15 @@ main(int argc, char **argv) #ifndef HAVE_LIBCRYPTO warning("crypto code not compiled in"); #endif - sigsecret = optarg; + ndo->ndo_sigsecret = optarg; break; case 'n': - ++nflag; + ++ndo->ndo_nflag; break; case 'N': - ++Nflag; + ++ndo->ndo_Nflag; break; case 'O': @@ -1285,17 +992,17 @@ main(int argc, char **argv) break; case 'q': - ++qflag; - ++suppress_default_print; + ++ndo->ndo_qflag; + ++ndo->ndo_suppress_default_print; break; #ifdef HAVE_PCAP_SETDIRECTION case 'Q': - if (strcasecmp(optarg, "in") == 0) + if (ascii_strcasecmp(optarg, "in") == 0) Qflag = PCAP_D_IN; - else if (strcasecmp(optarg, "out") == 0) + else if (ascii_strcasecmp(optarg, "out") == 0) Qflag = PCAP_D_OUT; - else if (strcasecmp(optarg, "inout") == 0) + else if (ascii_strcasecmp(optarg, "inout") == 0) Qflag = PCAP_D_INOUT; else error("unknown capture direction `%s'", optarg); @@ -1307,65 +1014,65 @@ main(int argc, char **argv) break; case 'R': - Rflag = 0; + ndo->ndo_Rflag = 0; break; case 's': - snaplen = strtol(optarg, &end, 0); + ndo->ndo_snaplen = strtol(optarg, &end, 0); if (optarg == end || *end != '\0' - || snaplen < 0 || snaplen > MAXIMUM_SNAPLEN) + || ndo->ndo_snaplen < 0 || ndo->ndo_snaplen > MAXIMUM_SNAPLEN) error("invalid snaplen %s", optarg); - else if (snaplen == 0) - snaplen = MAXIMUM_SNAPLEN; + else if (ndo->ndo_snaplen == 0) + ndo->ndo_snaplen = MAXIMUM_SNAPLEN; break; case 'S': - ++Sflag; + ++ndo->ndo_Sflag; break; case 't': - ++tflag; + ++ndo->ndo_tflag; break; case 'T': - if (strcasecmp(optarg, "vat") == 0) - packettype = PT_VAT; - else if (strcasecmp(optarg, "wb") == 0) - packettype = PT_WB; - else if (strcasecmp(optarg, "rpc") == 0) - packettype = PT_RPC; - else if (strcasecmp(optarg, "rtp") == 0) - packettype = PT_RTP; - else if (strcasecmp(optarg, "rtcp") == 0) - packettype = PT_RTCP; - else if (strcasecmp(optarg, "snmp") == 0) - packettype = PT_SNMP; - else if (strcasecmp(optarg, "cnfp") == 0) - packettype = PT_CNFP; - else if (strcasecmp(optarg, "tftp") == 0) - 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 if (strcasecmp(optarg, "zmtp1") == 0) - packettype = PT_ZMTP1; - else if (strcasecmp(optarg, "vxlan") == 0) - packettype = PT_VXLAN; - else if (strcasecmp(optarg, "pgm") == 0) - packettype = PT_PGM; - else if (strcasecmp(optarg, "pgm_zmtp1") == 0) - packettype = PT_PGM_ZMTP1; - else if (strcasecmp(optarg, "lmp") == 0) - packettype = PT_LMP; + if (ascii_strcasecmp(optarg, "vat") == 0) + ndo->ndo_packettype = PT_VAT; + else if (ascii_strcasecmp(optarg, "wb") == 0) + ndo->ndo_packettype = PT_WB; + else if (ascii_strcasecmp(optarg, "rpc") == 0) + ndo->ndo_packettype = PT_RPC; + else if (ascii_strcasecmp(optarg, "rtp") == 0) + ndo->ndo_packettype = PT_RTP; + else if (ascii_strcasecmp(optarg, "rtcp") == 0) + ndo->ndo_packettype = PT_RTCP; + else if (ascii_strcasecmp(optarg, "snmp") == 0) + ndo->ndo_packettype = PT_SNMP; + else if (ascii_strcasecmp(optarg, "cnfp") == 0) + ndo->ndo_packettype = PT_CNFP; + else if (ascii_strcasecmp(optarg, "tftp") == 0) + ndo->ndo_packettype = PT_TFTP; + else if (ascii_strcasecmp(optarg, "aodv") == 0) + ndo->ndo_packettype = PT_AODV; + else if (ascii_strcasecmp(optarg, "carp") == 0) + ndo->ndo_packettype = PT_CARP; + else if (ascii_strcasecmp(optarg, "radius") == 0) + ndo->ndo_packettype = PT_RADIUS; + else if (ascii_strcasecmp(optarg, "zmtp1") == 0) + ndo->ndo_packettype = PT_ZMTP1; + else if (ascii_strcasecmp(optarg, "vxlan") == 0) + ndo->ndo_packettype = PT_VXLAN; + else if (ascii_strcasecmp(optarg, "pgm") == 0) + ndo->ndo_packettype = PT_PGM; + else if (ascii_strcasecmp(optarg, "pgm_zmtp1") == 0) + ndo->ndo_packettype = PT_PGM_ZMTP1; + else if (ascii_strcasecmp(optarg, "lmp") == 0) + ndo->ndo_packettype = PT_LMP; else error("unknown packet type `%s'", optarg); break; case 'u': - ++uflag; + ++ndo->ndo_uflag; break; #ifdef HAVE_PCAP_DUMP_FLUSH @@ -1375,7 +1082,7 @@ main(int argc, char **argv) #endif case 'v': - ++vflag; + ++ndo->ndo_vflag; break; case 'V': @@ -1394,21 +1101,21 @@ main(int argc, char **argv) break; case 'x': - ++xflag; - ++suppress_default_print; + ++ndo->ndo_xflag; + ++ndo->ndo_suppress_default_print; break; case 'X': - ++Xflag; - ++suppress_default_print; + ++ndo->ndo_Xflag; + ++ndo->ndo_suppress_default_print; break; case 'y': - gndo->ndo_dltname = optarg; - gndo->ndo_dlt = - pcap_datalink_name_to_val(gndo->ndo_dltname); - if (gndo->ndo_dlt < 0) - error("invalid data link type %s", gndo->ndo_dltname); + ndo->ndo_dltname = optarg; + ndo->ndo_dlt = + pcap_datalink_name_to_val(ndo->ndo_dltname); + if (ndo->ndo_dlt < 0) + error("invalid data link type %s", ndo->ndo_dltname); break; #if defined(HAVE_PCAP_DEBUG) || defined(HAVE_YYDEBUG) @@ -1427,14 +1134,18 @@ main(int argc, char **argv) #endif case 'z': zflag = strdup(optarg); + if (zflag == NULL) + error("Unable to allocate memory for -z argument"); break; case 'Z': username = strdup(optarg); + if (username == NULL) + error("Unable to allocate memory for -Z argument"); break; case '#': - gndo->ndo_packet_number = 1; + ndo->ndo_packet_number = 1; break; case OPTION_VERSION: @@ -1444,15 +1155,15 @@ main(int argc, char **argv) #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION case OPTION_TSTAMP_PRECISION: - gndo->ndo_tstamp_precision = tstamp_precision_from_string(optarg); - if (gndo->ndo_tstamp_precision < 0) + ndo->ndo_tstamp_precision = tstamp_precision_from_string(optarg); + if (ndo->ndo_tstamp_precision < 0) error("unsupported time stamp precision"); break; #endif #ifdef HAVE_PCAP_SET_IMMEDIATE_MODE case OPTION_IMMEDIATE_MODE: - gndo->ndo_immediate = 1; + ndo->ndo_immediate = 1; break; #endif @@ -1467,11 +1178,11 @@ main(int argc, char **argv) show_devices_and_exit(); #endif - switch (tflag) { + switch (ndo->ndo_tflag) { case 0: /* Default */ case 4: /* Default + Date*/ - thiszone = gmt2local(0); + timezone_offset = gmt2local(0); break; case 1: /* No time stamp */ @@ -1485,7 +1196,7 @@ main(int argc, char **argv) break; } - if (fflag != 0 && (VFileName != NULL || RFileName != NULL)) + if (ndo->ndo_fflag != 0 && (VFileName != NULL || RFileName != NULL)) error("-f can not be used with -V or -r"); if (VFileName != NULL && RFileName != NULL) @@ -1499,7 +1210,7 @@ main(int argc, char **argv) * probably expecting to see packets pop up immediately. */ if (WFileName == NULL && isatty(1)) - gndo->ndo_immediate = 1; + ndo->ndo_immediate = 1; #endif #ifdef WITH_CHROOT @@ -1560,7 +1271,7 @@ main(int argc, char **argv) #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION pd = pcap_open_offline_with_tstamp_precision(RFileName, - gndo->ndo_tstamp_precision, ebuf); + ndo->ndo_tstamp_precision, ebuf); #else pd = pcap_open_offline(RFileName, ebuf); #endif @@ -1616,19 +1327,19 @@ main(int argc, char **argv) error("%s", ebuf); #ifdef HAVE_PCAP_SET_TSTAMP_TYPE if (Jflag) - show_tstamp_types_and_exit(device, pd); + show_tstamp_types_and_exit(device); #endif #ifdef HAVE_PCAP_SET_TSTAMP_PRECISION - status = pcap_set_tstamp_precision(pd, gndo->ndo_tstamp_precision); + status = pcap_set_tstamp_precision(pd, ndo->ndo_tstamp_precision); if (status != 0) error("%s: Can't set %ssecond time stamp precision: %s", device, - tstamp_precision_to_string(gndo->ndo_tstamp_precision), + tstamp_precision_to_string(ndo->ndo_tstamp_precision), pcap_statustostr(status)); #endif #ifdef HAVE_PCAP_SET_IMMEDIATE_MODE - if (gndo->ndo_immediate) { + if (ndo->ndo_immediate) { status = pcap_set_immediate_mode(pd, 1); if (status != 0) error("%s: Can't set immediate mode: %s", @@ -1643,7 +1354,7 @@ main(int argc, char **argv) supports_monitor_mode = 1; else supports_monitor_mode = 0; - status = pcap_set_snaplen(pd, snaplen); + status = pcap_set_snaplen(pd, ndo->ndo_snaplen); if (status != 0) error("%s: Can't set snapshot length: %s", device, pcap_statustostr(status)); @@ -1737,10 +1448,10 @@ main(int argc, char **argv) } #endif /* !defined(HAVE_PCAP_CREATE) && defined(WIN32) */ if (Lflag) - show_dlts_and_exit(device, pd); - if (gndo->ndo_dlt >= 0) { + show_dlts_and_exit(device); + if (ndo->ndo_dlt >= 0) { #ifdef HAVE_PCAP_SET_DATALINK - if (pcap_set_datalink(pd, gndo->ndo_dlt) < 0) + if (pcap_set_datalink(pd, ndo->ndo_dlt) < 0) error("%s", pcap_geterr(pd)); #else /* @@ -1748,21 +1459,21 @@ main(int argc, char **argv) * data link type, so we only let them * set it to what it already is. */ - if (gndo->ndo_dlt != pcap_datalink(pd)) { + if (ndo->ndo_dlt != pcap_datalink(pd)) { error("%s is not one of the DLTs supported by this device\n", - gndo->ndo_dltname); + ndo->ndo_dltname); } #endif (void)fprintf(stderr, "%s: data link type %s\n", - program_name, gndo->ndo_dltname); + program_name, ndo->ndo_dltname); (void)fflush(stderr); } i = pcap_snapshot(pd); - if (snaplen < i) { - warning("snaplen raised from %d to %d", snaplen, i); - snaplen = i; + if (ndo->ndo_snaplen < i) { + warning("snaplen raised from %d to %d", ndo->ndo_snaplen, i); + ndo->ndo_snaplen = i; } - if(fflag != 0) { + if(ndo->ndo_fflag != 0) { if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) { warning("foreign (-f) flag used but: %s", ebuf); } @@ -1782,8 +1493,7 @@ main(int argc, char **argv) free(cmdbuf); exit(0); } - init_addrtoname(gndo, localnet, netmask); - init_checksum(); + init_print(ndo, localnet, netmask, timezone_offset); #ifndef WIN32 (void)setsignal(SIGPIPE, cleanup); @@ -1894,11 +1604,15 @@ main(int argc, char **argv) if (p == NULL) error("%s", pcap_geterr(pd)); #ifdef HAVE_CAPSICUM - set_dump_fd_capsicum_rights(fileno(pcap_dump_file(p))); + set_dumper_capsicum_rights(p); #endif if (Cflag != 0 || Gflag != 0) { #ifdef HAVE_CAPSICUM dumpinfo.WFileName = strdup(basename(WFileName)); + if (dumpinfo.WFileName == NULL) { + error("Unable to allocate memory for file %s", + WFileName); + } dumpinfo.dirfd = open(dirname(WFileName), O_DIRECTORY | O_RDONLY); if (dumpinfo.dirfd < 0) { @@ -1932,7 +1646,7 @@ main(int argc, char **argv) #endif } else { type = pcap_datalink(pd); - printinfo = get_print_info(type); + printinfo = get_print_info(ndo, type); callback = print_packet; pcap_userdata = (u_char *)&printinfo; } @@ -1946,10 +1660,10 @@ main(int argc, char **argv) (void)setsignal(SIGNAL_REQ_INFO, requestinfo); #endif - if (vflag > 0 && WFileName) { + if (ndo->ndo_vflag > 0 && WFileName) { /* * When capturing to a file, "-v" means tcpdump should, - * every 10 secodns, "v"erbosely report the number of + * every 10 seconds, "v"erbosely report the number of * packets captured. */ #ifdef USE_WIN32_MM_TIMER @@ -1969,7 +1683,7 @@ main(int argc, char **argv) * to a file from the -V file). Print a message to * the standard error on UN*X. */ - if (!vflag && !WFileName) { + if (!ndo->ndo_vflag && !WFileName) { (void)fprintf(stderr, "%s: verbose output suppressed, use -v or -vv for full protocol decode\n", program_name); @@ -1979,22 +1693,20 @@ main(int argc, char **argv) dlt_name = pcap_datalink_val_to_name(dlt); if (dlt_name == NULL) { (void)fprintf(stderr, "listening on %s, link-type %u, capture size %u bytes\n", - device, dlt, snaplen); + device, dlt, ndo->ndo_snaplen); } else { (void)fprintf(stderr, "listening on %s, link-type %s (%s), capture size %u bytes\n", device, dlt_name, - pcap_datalink_val_to_description(dlt), snaplen); + pcap_datalink_val_to_description(dlt), ndo->ndo_snaplen); } (void)fflush(stderr); } #endif /* WIN32 */ #ifdef HAVE_CAPSICUM - cansandbox = (nflag && VFileName == NULL && zflag == NULL); + cansandbox = (ndo->ndo_nflag && VFileName == NULL && zflag == NULL); if (cansandbox && cap_enter() < 0 && errno != ENOSYS) error("unable to enter the capability mode"); - if (cap_sandboxed()) - fprintf(stderr, "capability mode sandbox enabled\n"); #endif /* HAVE_CAPSICUM */ do { @@ -2054,7 +1766,7 @@ main(int argc, char **argv) new_dlt = pcap_datalink(pd); if (WFileName && new_dlt != dlt) error("%s: new dlt does not match original", RFileName); - printinfo = get_print_info(new_dlt); + printinfo = get_print_info(ndo, new_dlt); dlt_name = pcap_datalink_val_to_name(new_dlt); if (dlt_name == NULL) { fprintf(stderr, "reading from file %s, link-type %u\n", @@ -2219,9 +1931,6 @@ static void dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) { struct dump_info *dump_info; -#ifdef HAVE_CAPSICUM - cap_rights_t rights; -#endif ++packets_captured; @@ -2332,7 +2041,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s if (dump_info->p == NULL) error("%s", pcap_geterr(pd)); #ifdef HAVE_CAPSICUM - set_dump_fd_capsicum_rights(pcap_dump_file(dump_info->p))); + set_dumper_capsicum_rights(dump_info->p); #endif } } @@ -2403,7 +2112,7 @@ dump_packet_and_trunc(u_char *user, const struct pcap_pkthdr *h, const u_char *s if (dump_info->p == NULL) error("%s", pcap_geterr(pd)); #ifdef HAVE_CAPSICUM - set_dump_fd_capsicum_rights(fileno(pcap_dump_file(dump_info->p))); + set_dumper_capsicum_rights(dump_info->p); #endif } } @@ -2441,99 +2150,14 @@ static void print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) { struct print_info *print_info; - u_int hdrlen; - netdissect_options *ndo; ++packets_captured; ++infodelay; 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); - - /* - * Some printers want to check that they're not walking off the - * end of the packet. - * Rather than pass it all the way down, we set this member - * of the netdissect_options structure. - */ - ndo->ndo_snapend = sp + h->caplen; - - if(print_info->ndo_type) { - hdrlen = (*print_info->p.ndo_printer)(print_info->ndo, h, sp); - } else { - hdrlen = (*print_info->p.printer)(h, sp); - } - - /* - * Restore the original snapend, as a printer might have - * changed it. - */ - ndo->ndo_snapend = sp + h->caplen; - if (ndo->ndo_Xflag) { - /* - * Print the raw packet data in hex and ASCII. - */ - if (ndo->ndo_Xflag > 1) { - /* - * Include the link-layer header. - */ - hex_and_ascii_print(ndo, "\n\t", sp, h->caplen); - } else { - /* - * Don't include the link-layer header - and if - * we have nothing past the link-layer header, - * print nothing. - */ - if (h->caplen > hdrlen) - hex_and_ascii_print(ndo, "\n\t", sp + hdrlen, - h->caplen - hdrlen); - } - } else if (ndo->ndo_xflag) { - /* - * Print the raw packet data in hex. - */ - if (ndo->ndo_xflag > 1) { - /* - * Include the link-layer header. - */ - hex_print(ndo, "\n\t", sp, h->caplen); - } else { - /* - * Don't include the link-layer header - and if - * we have nothing past the link-layer header, - * print nothing. - */ - if (h->caplen > hdrlen) - hex_print(ndo, "\n\t", sp + hdrlen, - h->caplen - hdrlen); - } - } else if (ndo->ndo_Aflag) { - /* - * Print the raw packet data in ASCII. - */ - if (ndo->ndo_Aflag > 1) { - /* - * Include the link-layer header. - */ - ascii_print(ndo, sp, h->caplen); - } else { - /* - * Don't include the link-layer header - and if - * we have nothing past the link-layer header, - * print nothing. - */ - if (h->caplen > hdrlen) - ascii_print(ndo, sp + hdrlen, h->caplen - hdrlen); - } - } - putchar('\n'); + pretty_print_packet(print_info, h, sp, packets_captured); --infodelay; if (infoprint) @@ -2567,21 +2191,6 @@ print_packet(u_char *user, const struct pcap_pkthdr *h, const u_char *sp) char Wpcap_version[]="3.1"; #endif -/* - * By default, print the specified data out in hex and ASCII. - */ -static void -ndo_default_print(netdissect_options *ndo, const u_char *bp, u_int length) -{ - hex_and_ascii_print(ndo, "\n\t", bp, length); /* pass on lf and indentation string */ -} - -void -default_print(const u_char *bp, u_int length) -{ - ndo_default_print(gndo, bp, length); -} - #ifdef SIGNAL_REQ_INFO RETSIGTYPE requestinfo(int signo _U_) { @@ -2685,44 +2294,6 @@ print_usage(void) (void)fprintf(stderr, "\t\t[ -Z user ] [ expression ]\n"); } - - - -/* VARARGS */ -static void -ndo_error(netdissect_options *ndo _U_, const char *fmt, ...) -{ - va_list ap; - - (void)fprintf(stderr, "%s: ", program_name); - va_start(ap, fmt); - (void)vfprintf(stderr, fmt, ap); - va_end(ap); - if (*fmt) { - fmt += strlen(fmt); - if (fmt[-1] != '\n') - (void)fputc('\n', stderr); - } - exit(1); - /* NOTREACHED */ -} - -/* VARARGS */ -static void -ndo_warning(netdissect_options *ndo _U_, const char *fmt, ...) -{ - va_list ap; - - (void)fprintf(stderr, "%s: WARNING: ", program_name); - va_start(ap, fmt); - (void)vfprintf(stderr, fmt, ap); - va_end(ap); - if (*fmt) { - fmt += strlen(fmt); - if (fmt[-1] != '\n') - (void)fputc('\n', stderr); - } -} /* * Local Variables: * c-style: whitesmith