"@(#) Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 2000\n\
The Regents of the University of California. All rights reserved.\n";
static const char rcsid[] _U_ =
- "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.229 2004-01-26 02:09:23 guy Exp $ (LBL)";
+ "@(#) $Header: /tcpdump/master/tcpdump/tcpdump.c,v 1.238 2004-03-23 18:57:33 fenner Exp $ (LBL)";
#endif
/*
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
+#ifndef WIN32
#include <pwd.h>
#include <grp.h>
+#endif /* WIN32 */
#include "interface.h"
#include "addrtoname.h"
#include "gmt2local.h"
#include "pcap-missing.h"
-static int dflag; /* print filter code */
+int dflag; /* print filter code */
int eflag; /* print ethernet header */
int fflag; /* don't translate "foreign" IP address */
static int Lflag; /* list available data link types and exit */
const char *dlt_name = NULL;
char *espsecret = NULL; /* ESP secret key */
+char *tcpmd5secret = NULL; /* TCP-MD5 secret key */
int packettype;
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 *);
static void dump_packet(u_char *, const struct pcap_pkthdr *, const u_char *);
-static void droproot(const char *);
+static void droproot(const char *, const char *);
#ifdef SIGINFO
RETSIGTYPE requestinfo(int);
#endif
#ifdef DLT_ENC
{ enc_if_print, DLT_ENC },
+#endif
+#ifdef DLT_SYMANTEC_FIREWALL
+ { symantec_if_print, DLT_SYMANTEC_FIREWALL },
+#endif
+#ifdef DLT_APPLE_IP_OVER_IEEE1394
+ { ap1394_if_print, DLT_APPLE_IP_OVER_IEEE1394 },
#endif
{ NULL, 0 },
};
#define B_FLAG_USAGE
#endif /* WIN32 */
+#ifdef HAVE_PCAP_FINDALLDEVS
+#ifndef HAVE_PCAP_IF_T
+#undef HAVE_PCAP_FINDALLDEVS
+#endif
+#endif
+
#ifdef HAVE_PCAP_FINDALLDEVS
#define D_FLAG "D"
#else
#define U_FLAG
#endif
-/* Drop root privileges */
+#ifndef WIN32
+/* Drop root privileges and chroot if necessary */
static void
-droproot(const char *username)
+droproot(const char *username, const char *chroot_dir)
{
struct passwd *pw = NULL;
+ if (chroot_dir && !username) {
+ fprintf(stderr, "Chroot without dropping root is insecure\n");
+ exit(1);
+ }
+
pw = getpwnam(username);
if (pw) {
- if (initgroups(pw->pw_name, 0) != 0 || setgid(pw->pw_gid) != 0 ||
+ if (chroot_dir) {
+ if (chroot(chroot_dir) != 0 || chdir ("/") != 0) {
+ fprintf(stderr, "Couldn't chroot/chdir to '%.64s'\n", chroot_dir);
+ exit(1);
+ }
+ }
+ if (initgroups(pw->pw_name, pw->pw_gid) != 0 || setgid(pw->pw_gid) != 0 ||
setuid(pw->pw_uid) != 0) {
fprintf(stderr, "Couldn't change to '%.32s' uid=%d gid=%d\n", username,
pw->pw_uid, pw->pw_gid);
exit(1);
}
}
+#endif /* WIN32 */
static int
getWflagChars(int x)
u_char *pcap_userdata;
char ebuf[PCAP_ERRBUF_SIZE];
char *username = NULL;
+ char *chroot_dir = NULL;
#ifdef HAVE_PCAP_FINDALLDEVS
pcap_if_t *devpointer;
int devnum;
opterr = 0;
while (
- (op = getopt(argc, argv, "aA" B_FLAG "c:C:d" D_FLAG "eE:fF:i:lLm:nNOpqr:Rs:StT:u" U_FLAG "vw:W:xXy:YZ:")) != -1)
+ (op = getopt(argc, argv, "aA" B_FLAG "c:C:d" D_FLAG "eE:fF:i:lLm:M:nNOpqr:Rs:StT:u" U_FLAG "vw:W:xXy:YZ:")) != -1)
switch (op) {
case 'a':
#endif
break;
+ case 'M':
+ /* TCP-MD5 shared secret */
+#ifndef HAVE_LIBCRYPTO
+ warning("crypto code not compiled in");
+#endif
+ tcpmd5secret = optarg;
+ break;
+
case 'O':
Oflag = 0;
break;
if (tflag > 0)
thiszone = gmt2local(0);
+#ifdef WITH_CHROOT
+ /* if run as root, prepare for chrooting */
+ if (getuid() == 0 || geteuid() == 0) {
+ /* future extensibility for cmd-line arguments */
+ if (!chroot_dir)
+ chroot_dir = WITH_CHROOT;
+ }
+#endif
+
+#ifdef WITH_USER
+ /* if run as root, prepare for dropping root privileges */
+ if (getuid() == 0 || geteuid() == 0) {
+ /* Run with '-Z root' to restore old behaviour */
+ if (!username)
+ username = WITH_USER;
+ }
+#endif
+
if (RFileName != NULL) {
int dlt;
const char *dlt_name;
* people's trace files (especially if we're set-UID
* root).
*/
- if (username) {
- droproot(username);
- }
- else {
- if (setgid(getgid()) != 0 || setuid(getuid()) != 0 )
- fprintf(stderr, "Warning: setgid/setuid failed !\n");
- }
+ if (setgid(getgid()) != 0 || setuid(getuid()) != 0 )
+ fprintf(stderr, "Warning: setgid/setuid failed !\n");
#endif /* WIN32 */
pd = pcap_open_offline(RFileName, ebuf);
if (pd == NULL)
error("%s", ebuf);
else if (*ebuf)
warning("%s", ebuf);
+ /*
+ * Let user own process after socket has been opened.
+ */
+#ifndef WIN32
+ if (setgid(getgid()) != 0 || setuid(getuid()) != 0)
+ fprintf(stderr, "Warning: setgid/setuid failed !\n");
+#endif /* WIN32 */
#ifdef WIN32
if(UserBufferSize != 1000000)
if(pcap_setbuff(pd, UserBufferSize)==-1){
netmask = 0;
warning("%s", ebuf);
}
- /*
- * Let user own process after socket has been opened.
- */
-#ifndef WIN32
- if (username) {
- droproot(username);
- }
- else {
- if (setgid(getgid()) != 0 || setuid(getuid()) != 0)
- fprintf(stderr, "Warning: setgid/setuid failed !\n");
- }
-#endif /* WIN32 */
}
if (infile)
cmdbuf = read_infile(infile);
callback = print_packet;
pcap_userdata = (u_char *)&printinfo;
}
+#ifndef WIN32
+ /*
+ * 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 (username || chroot_dir)
+ droproot(username, chroot_dir);
+ }
+#endif /* WIN32 */
#ifdef SIGINFO
(void)setsignal(SIGINFO, requestinfo);
#endif
(void)fprintf(stderr, "%s: pcap_loop: %s\n",
program_name, pcap_geterr(pd));
}
-#ifdef WITH_USER
- /* if run as root, drop root; protect against remote sec problems */
- if (getuid() == 0 || geteuid() == 0) {
- /* Run with '-Z root' to restore old behaviour */
- if (!username) {
- droproot(WITH_USER);
- /* does not return if fails */
- }
- }
-#endif
if (RFileName == NULL) {
/*
* We're doing a live capture. Report the capture
(void)fprintf(stderr,
"Usage: %s [-aAd" D_FLAG "eflLnNOpqRStu" U_FLAG "vxX]" B_FLAG_USAGE " [-c count] [ -C file_size ]\n", program_name);
(void)fprintf(stderr,
-"\t\t[ -E algo:secret ] [ -F file ] [ -i interface ] [ -r file ]\n");
+"\t\t[ -E algo:secret ] [ -F file ] [ -i interface ] [ -M secret ]\n");
(void)fprintf(stderr,
-"\t\t[ -s snaplen ] [ -T type ] [ -w file ] [ -W filecount ]\n");
+"\t\t[ -r file ] [ -s snaplen ] [ -T type ] [ -w file ] [ -W filecount ]\n");
(void)fprintf(stderr,
"\t\t[ -y datalinktype ] [ -Z user ]\n");
(void)fprintf(stderr,