Makefile.in | 8 ++++---- addrtoname.c | 4 ++-- configure.in | 16 +++++++++------- print-ether.c | 2 +- print-ip6opts.c | 2 +- tcpdump.1 | 30 +++++++++++++++++++----------- tcpdump.c | 29 +++++++++++++++++++++++------ 7 files changed, 59 insertions(+), 32 deletions(-) diff --git a/Makefile.in b/Makefile.in index e62e5e6..72e7fa6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -160,13 +160,13 @@ install: [ -d $(DESTDIR)$(sbindir) ] || \ (mkdir -p $(DESTDIR)$(sbindir); chmod 755 $(DESTDIR)$(sbindir)) $(INSTALL_PROGRAM) $(PROG) $(DESTDIR)$(sbindir)/$(PROG) - [ -d $(DESTDIR)$(mandir)/man1 ] || \ - (mkdir -p $(DESTDIR)$(mandir)/man1; chmod 755 $(DESTDIR)$(mandir)/man1) - $(INSTALL_DATA) $(srcdir)/$(PROG).1 $(DESTDIR)$(mandir)/man1/$(PROG).1 + [ -d $(DESTDIR)$(mandir)/man8 ] || \ + (mkdir -p $(DESTDIR)$(mandir)/man8; chmod 755 $(DESTDIR)$(mandir)/man8) + $(INSTALL_DATA) $(srcdir)/$(PROG).1 $(DESTDIR)$(mandir)/man8/$(PROG).8 uninstall: rm -f $(DESTDIR)$(sbindir)/$(PROG) - rm -f $(DESTDIR)$(mandir)/man1/$(PROG).1 + rm -f $(DESTDIR)$(mandir)/man8/$(PROG).8 lint: $(GENSRC) lint -hbxn $(SRC) | \ diff --git a/addrtoname.c b/addrtoname.c index bef9ad2..f964b00 100644 --- a/addrtoname.c +++ b/addrtoname.c @@ -704,7 +704,7 @@ init_servarray(void) while (table->name) table = table->nxt; - if (nflag) { + if (nflag > 1) { (void)snprintf(buf, sizeof(buf), "%d", port); table->name = strdup(buf); } else @@ -1104,7 +1104,7 @@ init_addrtoname(u_int32_t localnet, u_int32_t mask) f_localnet = localnet; f_netmask = mask; } - if (nflag) + if (nflag > 1) /* * Simplest way to suppress names. */ diff --git a/configure.in b/configure.in index 7a331c5..8273331 100644 --- a/configure.in +++ b/configure.in @@ -12,6 +12,8 @@ AC_INIT(tcpdump.c) AC_CANONICAL_HOST +AC_GNU_SOURCE +AC_SYS_LARGEFILE AC_LBL_C_INIT(V_CCOPT, V_INCLS) AC_LBL_C_INLINE AC_C___ATTRIBUTE__ @@ -273,7 +275,7 @@ yes fi if test "$ipv6" = "yes" -a "$ipv6lib" != "none"; then - if test -d $ipv6libdir -a -f $ipv6libdir/lib$ipv6lib.a; then + if test -d $ipv6libdir -a -f $ipv6libdir/lib$ipv6lib.so; then LIBS="-L$ipv6libdir -l$ipv6lib $LIBS" echo "You have $ipv6lib library, using it" else @@ -281,7 +283,7 @@ if test "$ipv6" = "yes" -a "$ipv6lib" != "none"; then echo "You do not have $ipv6lib library, using libc" else echo 'Fatal: no $ipv6lib library found. cannot continue.' - echo "You need to fetch lib$ipv6lib.a from appropriate" + echo "You need to fetch lib$ipv6lib.so from appropriate" echo 'ipv6 kit and compile beforehand.' exit 1 fi @@ -929,10 +931,10 @@ for dir in $Xprefix /usr/${host_alias} /usr /usr/local /usr/local/ssl /usr/pkg; # # Or should we just look for "libcrypto.*"? # - if test -d $dir/lib -a \( -f $dir/lib/libcrypto.a -o \ - -f $dir/lib/libcrypto.so -o \ + if test -d $dir/lib -a \( -f $dir/lib/libcrypto.so -o \ -f $dir/lib/libcrypto.sl -o \ - -f $dir/lib/libcrypto.dylib \); then + -f $dir/lib/libcrypto.dylib -o \ + -f $dir/lib/libcrypto.a \); then ac_cv_ssleay_path=$dir fi if test -d $dir/include/openssl -a -f $dir/include/openssl/des.h; then @@ -949,10 +951,10 @@ AC_MSG_RESULT($ac_cv_ssleay_path) if test "$ac_cv_ssleay_path" != no; then V_INCLS="$V_INCLS $incdir" LDFLAGS="-L$dir/lib $LDFLAGS" - if test -f $ac_cv_ssleay_path/lib/libRSAglue.a; then + if test -f $ac_cv_ssleay_path/lib/libRSAglue.so; then LIBS="$LIBS -lRSAglue" fi - if test -f $ac_cv_ssleay_path/lib/librsaref.a; then + if test -f $ac_cv_ssleay_path/lib/librsaref.so; then LIBS="$LIBS -lrsaref" fi AC_CHECK_LIB(crypto, DES_cbc_encrypt) diff --git a/print-ether.c b/print-ether.c index f71a7cc..e0da4ed 100644 --- a/print-ether.c +++ b/print-ether.c @@ -220,7 +220,7 @@ ether_encap_print(u_short ether_type, const u_char *p, return (1); case ETHERTYPE_8021Q: - if (eflag) + if (!eflag) printf("vlan %u, p %u%s, ", ntohs(*(u_int16_t *)p) & 0xfff, ntohs(*(u_int16_t *)p) >> 13, diff --git a/print-ip6opts.c b/print-ip6opts.c index 82163a2..7515199 100644 --- a/print-ip6opts.c +++ b/print-ip6opts.c @@ -74,7 +74,7 @@ static void ip6_sopt_print(const u_char *bp, int len) { int i; - int optlen; + int optlen = 0; for (i = 0; i < len; i += optlen) { if (bp[i] == IP6OPT_PAD1) diff --git a/tcpdump.1 b/tcpdump.1 index d13b4de..a0a8a06 100644 --- a/tcpdump.1 +++ b/tcpdump.1 @@ -22,7 +22,7 @@ .\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF .\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. .\" -.TH TCPDUMP 1 "18 April 2005" +.TH TCPDUMP 8 "18 April 2005" .SH NAME tcpdump \- dump traffic on a network .SH SYNOPSIS @@ -264,6 +264,9 @@ have the name specified with the flag, with a number after it, starting at 1 and continuing upward. The units of \fIfile_size\fP are millions of bytes (1,000,000 bytes, not 1,048,576 bytes). + +Note that when used with \fB\-Z\fR option (enabled by default), +privileges are dropped before opening first savefile. .TP .B \-d Dump the compiled packet-matching code in a human readable form to @@ -310,7 +313,7 @@ Print the link-level header on each dump line. .B \-E Use \fIspi@ipaddr algo:secret\fP for decrypting IPsec ESP packets that are addressed to \fIaddr\fP and contain Security Parameter Index value -\fIspi\fP. This combination may be repeated with comma or newline seperation. +\fIspi\fP. This combination may be repeated with comma or newline separation. .IP Note that setting the secret for IPv4 ESP packets is supported at this time. .IP @@ -326,7 +329,7 @@ The ability to decrypt packets is only present if \fItcpdump\fP was compiled with cryptography enabled. .IP \fIsecret\fP is the ASCII text for ESP secret key. -If preceeded by 0x, then a hex value will be read. +If preceded by 0x, then a hex value will be read. .IP The option assumes RFC2406 ESP, not RFC1827 ESP. The option is only for debugging purposes, and @@ -400,7 +403,11 @@ Use \fIsecret\fP as a shared secret for validating the digests found in TCP segments with the TCP-MD5 option (RFC 2385), if present. .TP .B \-n -Don't convert addresses (i.e., host addresses, port numbers, etc.) to names. +Don't convert host addresses to names. This can be used to avoid +DNS lookups. +.TP +.B \-nn +Don't convert protocol and port numbers etc. to names either. .TP .B \-N Don't print domain name qualification of host names. @@ -588,7 +595,8 @@ Drops privileges (if root) and changes user ID to and the group ID to the primary group of .IR user . .IP -This behavior can also be enabled by default at compile time. +This behavior is enabled by default (\fB\-Z tcpdump\fR), +and can be disabled by \fB\-Z root\fR. .IP "\fI expression\fP" .RS selects which packets will be dumped. @@ -727,7 +735,7 @@ be checked for a match. True if the Ethernet destination address is \fIehost\fP. \fIEhost\fP may be either a name from /etc/ethers or a number (see -.IR ethers (3N) +.IR ethers (5) for numeric format). .IP "\fBether src \fIehost\fP True if the Ethernet source address is \fIehost\fP. @@ -781,9 +789,9 @@ May be qualified with \fBsrc\fR or \fBdst\fR. True if the packet is ip/tcp, ip/udp, ip6/tcp or ip6/udp and has a destination port value of \fIport\fP. The \fIport\fP can be a number or a name used in /etc/services (see -.IR tcp (4P) +.IR tcp (7) and -.IR udp (4P)). +.IR udp (7)). If a name is used, both the port number and protocol are checked. If a number or ambiguous name is used, @@ -974,7 +982,7 @@ True if the packet was logged as matching the specified PF rule number (applies only to packets logged by OpenBSD's .BR pf (4)). .IP "\fBrulenum \fInum\fR" -Synonomous with the +Synonymous with the .B rnr modifier. .IP "\fBreason \fIcode\fR" @@ -994,7 +1002,7 @@ True if the packet was logged as matching the specified PF ruleset name of an anchored ruleset (applies only to packets logged by .BR pf (4)). .IP "\fBruleset \fIname\fR" -Synonomous with the +Synonymous with the .B rset modifier. .IP "\fBsrnr \fInum\fR" @@ -1002,7 +1010,7 @@ True if the packet was logged as matching the specified PF rule number of an anchored ruleset (applies only to packets logged by .BR pf (4)). .IP "\fBsubrulenum \fInum\fR" -Synonomous with the +Synonymous with the .B srnr modifier. .IP "\fBaction \fIact\fR" diff --git a/tcpdump.c b/tcpdump.c index 9d87e3a..96c64a3 100644 --- a/tcpdump.c +++ b/tcpdump.c @@ -380,19 +380,28 @@ droproot(const char *username, const char *chroot_dir) pw = getpwnam(username); if (pw) { + uid_t uid = pw->pw_uid; + gid_t gid = pw->pw_gid; + + if (initgroups(pw->pw_name, gid) != 0) { + fprintf(stderr, + "tcpdump: Couldn't initialize the supplementary group list: %s\n", + pcap_strerror(errno)); + exit(1); + } + endpwent(); if (chroot_dir) { - if (chroot(chroot_dir) != 0 || chdir ("/") != 0) { + if (chdir(chroot_dir) != 0 || chroot(".") != 0) { fprintf(stderr, "tcpdump: Couldn't chroot/chdir to '%.64s': %s\n", chroot_dir, pcap_strerror(errno)); exit(1); } } - if (initgroups(pw->pw_name, pw->pw_gid) != 0 || - setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) { + if (setgid(gid) != 0 || setuid(uid) != 0) { fprintf(stderr, "tcpdump: Couldn't change to '%.32s' uid=%lu gid=%lu: %s\n", username, - (unsigned long)pw->pw_uid, - (unsigned long)pw->pw_gid, + (unsigned long)uid, + (unsigned long)gid, pcap_strerror(errno)); exit(1); } @@ -956,6 +965,10 @@ main(int argc, char **argv) #ifndef WIN32 if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL) (void)setsignal(SIGHUP, oldhandler); + if (Cflag && (getuid() == 0 || geteuid() == 0)) { + if (username || chroot_dir) + droproot(username, chroot_dir); + } #endif /* WIN32 */ if (pcap_setfilter(pd, &fcode) < 0) @@ -976,6 +989,10 @@ main(int argc, char **argv) dumpinfo.pd = pd; dumpinfo.p = p; pcap_userdata = (u_char *)&dumpinfo; + if (chroot_dir) { + warning("chroot to %s disabled", chroot_dir); + chroot_dir = NULL; + } } else { callback = dump_packet; pcap_userdata = (u_char *)p; @@ -999,7 +1016,7 @@ main(int argc, char **argv) * We cannot do this earlier, because we want to be able to open * the file (if done) for writing before giving up permissions. */ - if (getuid() == 0 || geteuid() == 0) { + if (!Cflag && (getuid() == 0 || geteuid() == 0)) { if (username || chroot_dir) droproot(username, chroot_dir); }