X-Git-Url: https://git.tcpdump.org/tcpdump/blobdiff_plain/46b34a84c5c6c63cccb44d66521b0cb97a55ec87..2d0270b827db5c1eaa6af8ca85bd07aca1ef90df:/tcpdump.c diff --git a/tcpdump.c b/tcpdump.c index c9f62a51..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,7 @@ extern int SIZE_BUF; #include "setsignal.h" #include "gmt2local.h" #include "pcap-missing.h" +#include "ascii_strcasecmp.h" #include "print.h" @@ -134,9 +134,6 @@ 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 */ @@ -167,7 +164,8 @@ 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 dump_packet_and_trunc(u_char *, const struct pcap_pkthdr *, const u_char *); @@ -220,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; @@ -253,7 +251,7 @@ 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, i; int *dlts = 0; @@ -495,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 || @@ -738,16 +737,19 @@ main(int argc, char **argv) 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 */ - gndo->ndo_Rflag=1; - gndo->ndo_dlt=-1; - ndo_set_function_pointers(gndo); - 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; @@ -785,11 +787,11 @@ main(int argc, char **argv) break; case 'A': - ++gndo->ndo_Aflag; + ++ndo->ndo_Aflag; break; case 'b': - ++gndo->ndo_bflag; + ++ndo->ndo_bflag; break; #if defined(HAVE_PCAP_CREATE) || defined(WIN32) @@ -825,18 +827,18 @@ main(int argc, char **argv) break; case 'e': - ++gndo->ndo_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': - ++gndo->ndo_fflag; + ++ndo->ndo_fflag; break; case 'F': @@ -864,7 +866,7 @@ main(int argc, char **argv) break; case 'H': - ++gndo->ndo_Hflag; + ++ndo->ndo_Hflag; break; case 'i': @@ -949,7 +951,7 @@ main(int argc, char **argv) break; case 'K': - ++gndo->ndo_Kflag; + ++ndo->ndo_Kflag; break; case 'm': @@ -957,7 +959,7 @@ main(int argc, char **argv) if (smiLoadModule(optarg) == 0) { error("could not load MIB module %s", optarg); } - gndo->ndo_sflag = 1; + ndo->ndo_sflag = 1; #else (void)fprintf(stderr, "%s: ignoring option `-m %s' ", program_name, optarg); @@ -970,15 +972,15 @@ main(int argc, char **argv) #ifndef HAVE_LIBCRYPTO warning("crypto code not compiled in"); #endif - gndo->ndo_sigsecret = optarg; + ndo->ndo_sigsecret = optarg; break; case 'n': - ++gndo->ndo_nflag; + ++ndo->ndo_nflag; break; case 'N': - ++gndo->ndo_Nflag; + ++ndo->ndo_Nflag; break; case 'O': @@ -990,17 +992,17 @@ main(int argc, char **argv) break; case 'q': - ++gndo->ndo_qflag; - ++gndo->ndo_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); @@ -1012,65 +1014,65 @@ main(int argc, char **argv) break; case 'R': - gndo->ndo_Rflag = 0; + ndo->ndo_Rflag = 0; break; case 's': - gndo->ndo_snaplen = strtol(optarg, &end, 0); + ndo->ndo_snaplen = strtol(optarg, &end, 0); if (optarg == end || *end != '\0' - || gndo->ndo_snaplen < 0 || gndo->ndo_snaplen > MAXIMUM_SNAPLEN) + || ndo->ndo_snaplen < 0 || ndo->ndo_snaplen > MAXIMUM_SNAPLEN) error("invalid snaplen %s", optarg); - else if (gndo->ndo_snaplen == 0) - gndo->ndo_snaplen = MAXIMUM_SNAPLEN; + else if (ndo->ndo_snaplen == 0) + ndo->ndo_snaplen = MAXIMUM_SNAPLEN; break; case 'S': - ++gndo->ndo_Sflag; + ++ndo->ndo_Sflag; break; case 't': - ++gndo->ndo_tflag; + ++ndo->ndo_tflag; break; case 'T': - if (strcasecmp(optarg, "vat") == 0) - gndo->ndo_packettype = PT_VAT; - else if (strcasecmp(optarg, "wb") == 0) - gndo->ndo_packettype = PT_WB; - else if (strcasecmp(optarg, "rpc") == 0) - gndo->ndo_packettype = PT_RPC; - else if (strcasecmp(optarg, "rtp") == 0) - gndo->ndo_packettype = PT_RTP; - else if (strcasecmp(optarg, "rtcp") == 0) - gndo->ndo_packettype = PT_RTCP; - else if (strcasecmp(optarg, "snmp") == 0) - gndo->ndo_packettype = PT_SNMP; - else if (strcasecmp(optarg, "cnfp") == 0) - gndo->ndo_packettype = PT_CNFP; - else if (strcasecmp(optarg, "tftp") == 0) - gndo->ndo_packettype = PT_TFTP; - else if (strcasecmp(optarg, "aodv") == 0) - gndo->ndo_packettype = PT_AODV; - else if (strcasecmp(optarg, "carp") == 0) - gndo->ndo_packettype = PT_CARP; - else if (strcasecmp(optarg, "radius") == 0) - gndo->ndo_packettype = PT_RADIUS; - else if (strcasecmp(optarg, "zmtp1") == 0) - gndo->ndo_packettype = PT_ZMTP1; - else if (strcasecmp(optarg, "vxlan") == 0) - gndo->ndo_packettype = PT_VXLAN; - else if (strcasecmp(optarg, "pgm") == 0) - gndo->ndo_packettype = PT_PGM; - else if (strcasecmp(optarg, "pgm_zmtp1") == 0) - gndo->ndo_packettype = PT_PGM_ZMTP1; - else if (strcasecmp(optarg, "lmp") == 0) - gndo->ndo_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': - ++gndo->ndo_uflag; + ++ndo->ndo_uflag; break; #ifdef HAVE_PCAP_DUMP_FLUSH @@ -1080,7 +1082,7 @@ main(int argc, char **argv) #endif case 'v': - ++gndo->ndo_vflag; + ++ndo->ndo_vflag; break; case 'V': @@ -1099,21 +1101,21 @@ main(int argc, char **argv) break; case 'x': - ++gndo->ndo_xflag; - ++gndo->ndo_suppress_default_print; + ++ndo->ndo_xflag; + ++ndo->ndo_suppress_default_print; break; case 'X': - ++gndo->ndo_Xflag; - ++gndo->ndo_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) @@ -1132,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: @@ -1149,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 @@ -1172,7 +1178,7 @@ main(int argc, char **argv) show_devices_and_exit(); #endif - switch (gndo->ndo_tflag) { + switch (ndo->ndo_tflag) { case 0: /* Default */ case 4: /* Default + Date*/ @@ -1190,7 +1196,7 @@ main(int argc, char **argv) break; } - if (gndo->ndo_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) @@ -1204,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 @@ -1265,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 @@ -1321,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", @@ -1348,7 +1354,7 @@ main(int argc, char **argv) supports_monitor_mode = 1; else supports_monitor_mode = 0; - status = pcap_set_snaplen(pd, gndo->ndo_snaplen); + status = pcap_set_snaplen(pd, ndo->ndo_snaplen); if (status != 0) error("%s: Can't set snapshot length: %s", device, pcap_statustostr(status)); @@ -1442,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 /* @@ -1453,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 (gndo->ndo_snaplen < i) { - warning("snaplen raised from %d to %d", gndo->ndo_snaplen, i); - gndo->ndo_snaplen = i; + if (ndo->ndo_snaplen < i) { + warning("snaplen raised from %d to %d", ndo->ndo_snaplen, i); + ndo->ndo_snaplen = i; } - if(gndo->ndo_fflag != 0) { + if(ndo->ndo_fflag != 0) { if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) { warning("foreign (-f) flag used but: %s", ebuf); } @@ -1487,7 +1493,7 @@ main(int argc, char **argv) free(cmdbuf); exit(0); } - init_print(localnet, netmask, timezone_offset); + init_print(ndo, localnet, netmask, timezone_offset); #ifndef WIN32 (void)setsignal(SIGPIPE, cleanup); @@ -1603,6 +1609,10 @@ main(int argc, char **argv) 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) { @@ -1636,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; } @@ -1650,10 +1660,10 @@ main(int argc, char **argv) (void)setsignal(SIGNAL_REQ_INFO, requestinfo); #endif - if (gndo->ndo_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 @@ -1673,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 (!gndo->ndo_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); @@ -1683,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, gndo->ndo_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), gndo->ndo_snaplen); + pcap_datalink_val_to_description(dlt), ndo->ndo_snaplen); } (void)fflush(stderr); } #endif /* WIN32 */ #ifdef HAVE_CAPSICUM - cansandbox = (gndo->ndo_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 { @@ -1758,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",