static const char copyright[] _U_ =
"@(#) 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.283 2008-09-25 21:45:50 guy Exp $ (LBL)";
#endif
/*
#include <tcpdump-stdinc.h>
#ifdef WIN32
-#include "getopt.h"
#include "w32_fzs.h"
extern int strcasecmp (const char *__s1, const char *__s2);
extern int SIZE_BUF;
#include <smi.h>
#endif
+#ifdef HAVE_LIBCRYPTO
+#include <openssl/crypto.h>
+#endif
+
+#ifdef HAVE_GETOPT_LONG
+#include <getopt.h>
+#else
+#include "getopt_long.h"
+#endif
#include <pcap.h>
#include <signal.h>
#include <stdio.h>
#include <sys/resource.h>
#include <pwd.h>
#include <grp.h>
-#include <errno.h>
#endif /* WIN32 */
/* capabilities convinience library */
netdissect_options Gndo;
netdissect_options *gndo = &Gndo;
+static int Dflag; /* list available devices and exit */
static int dflag; /* print filter code */
static int Lflag; /* list available data link types and exit */
#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 char *zflag = NULL; /* compress each savefile using a specified command (like gzip or bzip2) */
static int infodelay;
/* Forwards */
static RETSIGTYPE cleanup(int);
static RETSIGTYPE child_cleanup(int);
-static void usage(void) __attribute__((noreturn));
+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 print_packet(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, format (printf, 2, 3)));
-static void ndo_warning(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);
};
-static struct printer printers[] = {
- { arcnet_if_print, DLT_ARCNET },
-#ifdef DLT_ARCNET_LINUX
- { arcnet_linux_if_print, DLT_ARCNET_LINUX },
+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
- { token_if_print, DLT_IEEE802 },
-#ifdef DLT_LANE8023
- { lane_if_print, DLT_LANE8023 },
+#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 },
#ifdef DLT_ATM_CLIP
{ cip_if_print, DLT_ATM_CLIP },
#endif
- { sl_if_print, DLT_SLIP },
-#ifdef DLT_SLIP_BSDOS
- { sl_bsdos_if_print, DLT_SLIP_BSDOS },
-#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 },
+#ifdef DLT_IP_OVER_FC
+ { ipfc_if_print, DLT_IP_OVER_FC },
#endif
- { fddi_if_print, DLT_FDDI },
{ 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 },
- { atm_if_print, DLT_ATM_RFC1483 },
+#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_SERIAL
- { ppp_hdlc_if_print, DLT_PPP_SERIAL },
-#endif
#ifdef DLT_PPP_ETHER
{ pppoe_if_print, DLT_PPP_ETHER },
#endif
-#ifdef DLT_LINUX_SLL
- { sll_if_print, DLT_LINUX_SLL },
-#endif
-#ifdef DLT_IEEE802_11
- { ieee802_11_if_print, DLT_IEEE802_11},
-#endif
-#ifdef DLT_LTALK
- { ltalk_if_print, DLT_LTALK },
-#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 },
#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_IP_OVER_FC
- { ipfc_if_print, DLT_IP_OVER_FC },
-#endif
-#ifdef DLT_PRISM_HEADER
- { prism_if_print, DLT_PRISM_HEADER },
-#endif
-#ifdef DLT_IEEE802_11_RADIO
- { ieee802_11_radio_if_print, DLT_IEEE802_11_RADIO },
-#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 },
+ { sl_if_print, DLT_SLIP },
+#ifdef DLT_SLIP_BSDOS
+ { sl_bsdos_if_print, DLT_SLIP_BSDOS },
#endif
-#ifdef DLT_IEEE802_11_RADIO_AVS
- { ieee802_11_radio_avs_if_print, DLT_IEEE802_11_RADIO_AVS },
+#ifdef DLT_LTALK
+ { ltalk_if_print, DLT_LTALK },
#endif
#ifdef DLT_JUNIPER_ATM1
{ juniper_atm1_print, DLT_JUNIPER_ATM1 },
#ifdef DLT_JUNIPER_CHDLC
{ juniper_chdlc_print, DLT_JUNIPER_CHDLC },
#endif
-#ifdef DLT_MFR
- { mfr_if_print, DLT_MFR },
+#ifdef DLT_PKTAP
+ { pktap_if_print, DLT_PKTAP },
#endif
-#if defined(DLT_BLUETOOTH_HCI_H4_WITH_PHDR) && defined(HAVE_PCAP_BLUETOOTH_H)
- { bt_if_print, DLT_BLUETOOTH_HCI_H4_WITH_PHDR},
+#ifdef DLT_IEEE802_11_RADIO
+ { ieee802_11_radio_if_print, DLT_IEEE802_11_RADIO },
#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_IPV4
- { raw_if_print, DLT_IPV4 },
+#ifdef DLT_IEEE802_11
+ { ieee802_11_if_print, DLT_IEEE802_11},
#endif
-#ifdef DLT_IPV6
- { raw_if_print, DLT_IPV6 },
+#ifdef DLT_IEEE802_11_RADIO_AVS
+ { ieee802_11_radio_avs_if_print, DLT_IEEE802_11_RADIO_AVS },
#endif
- { NULL, 0 },
-};
-
-static struct ndo_printer ndo_printers[] = {
- { ether_if_print, DLT_EN10MB },
-#ifdef DLT_IPNET
- { ipnet_if_print, DLT_IPNET },
+#ifdef DLT_PRISM_HEADER
+ { prism_if_print, DLT_PRISM_HEADER },
#endif
-#ifdef DLT_IEEE802_15_4
- { ieee802_15_4_if_print, DLT_IEEE802_15_4 },
+ { ppp_if_print, DLT_PPP },
+#ifdef DLT_PPP_WITHDIRECTION
+ { ppp_if_print, DLT_PPP_WITHDIRECTION },
#endif
-#ifdef DLT_IEEE802_15_4_NOFCS
- { ieee802_15_4_if_print, DLT_IEEE802_15_4_NOFCS },
+#ifdef DLT_PPP_BSDOS
+ { ppp_bsdos_if_print, DLT_PPP_BSDOS },
#endif
-#ifdef DLT_PPI
- { ppi_if_print, DLT_PPI },
+#ifdef DLT_PPP_SERIAL
+ { ppp_hdlc_if_print, DLT_PPP_SERIAL },
#endif
-#ifdef DLT_NETANALYZER
- { netanalyzer_if_print, DLT_NETANALYZER },
+ { NULL, 0 },
+};
+
+static const struct tok status_flags[] = {
+#ifdef PCAP_IF_UP
+ { PCAP_IF_UP, "Up" },
#endif
-#ifdef DLT_NETANALYZER_TRANSPARENT
- { netanalyzer_transparent_if_print, DLT_NETANALYZER_TRANSPARENT },
+#ifdef PCAP_IF_RUNNING
+ { PCAP_IF_RUNNING, "Running" },
#endif
- { NULL, 0 },
+ { PCAP_IF_LOOPBACK, "Loopback" },
+ { 0, NULL }
};
if_printer
lookup_printer(int type)
{
- struct printer *p;
+ const struct printer *p;
for (p = printers; p->f; ++p)
if (type == p->type)
if_ndo_printer
lookup_ndo_printer(int type)
{
- struct ndo_printer *p;
+ 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 */
}
exit(0);
}
+#ifdef HAVE_PCAP_FINDALLDEVS
+static void
+show_devices_and_exit (void)
+{
+ pcap_if_t *devpointer;
+ char ebuf[PCAP_ERRBUF_SIZE];
+ int i;
+
+ if (pcap_findalldevs(&devpointer, ebuf) < 0)
+ error("%s", ebuf);
+ else {
+ for (i = 0; devpointer != NULL; i++) {
+ printf("%d.%s", i+1, devpointer->name);
+ if (devpointer->description != NULL)
+ printf(" (%s)", devpointer->description);
+ if (devpointer->flags != 0)
+ printf(" [%s]", bittok2str(status_flags, "none", devpointer->flags));
+ printf("\n");
+ devpointer = devpointer->next;
+ }
+ }
+ exit(0);
+}
+#endif /* HAVE_PCAP_FINDALLDEVS */
+
+/*
+ * Short options.
+ *
+ * Note that there we use all letters for short options except for g, k,
+ * o, and P, and those are used by other versions of tcpdump, and we should
+ * only use them for the same purposes that the other versions of tcpdump
+ * use them:
+ *
+ * OS X tcpdump uses -g to force non--v output for IP to be on one
+ * line, making it more "g"repable;
+ *
+ * OS X tcpdump uses -k tospecify that packet comments in pcap-ng files
+ * should be printed;
+ *
+ * OpenBSD tcpdump uses -o to indicate that OS fingerprinting should be done
+ * for hosts sending TCP SYN packets;
+ *
+ * OS X tcpdump uses -P to indicate that -w should write pcap-ng rather
+ * than pcap files.
+ */
+
/*
* Set up flags that might or might not be supported depending on the
* version of libpcap we're using.
#define U_FLAG
#endif
+#ifdef HAVE_PCAP_SETDIRECTION
+#define Q_FLAG "Q:"
+#else
+#define Q_FLAG
+#endif
+
+/*
+ * Long options.
+ *
+ * We do not currently have long options corresponding to all short
+ * options; we should probably pick appropriate option names for them.
+ *
+ * However, the short options where the number of times the option is
+ * specified matters, such as -v and -d and -t, should probably not
+ * just map to a long option, as saying
+ *
+ * tcpdump --verbose --verbose
+ *
+ * doesn't make sense; it should be --verbosity={N} or something such
+ * as that.
+ *
+ * For long options with no corresponding short options, we define values
+ * outside the range of ASCII graphic characters, make that the last
+ * component of the entry for the long option, and have a case for that
+ * option in the switch statement.
+ */
+#define OPTION_NUMBER 128
+#define OPTION_VERSION 129
+
+static struct option longopts[] = {
+#if defined(HAVE_PCAP_CREATE) || defined(WIN32)
+ { "buffer-size", required_argument, NULL, 'B' },
+#endif
+ { "list-interfaces", no_argument, NULL, 'D' },
+ { "help", no_argument, NULL, 'h' },
+ { "interface", required_argument, NULL, 'i' },
+#ifdef HAVE_PCAP_CREATE
+ { "monitor-mode", no_argument, NULL, 'I' },
+#endif
+#ifdef HAVE_PCAP_SET_TSTAMP_TYPE
+ { "time-stamp-type", required_argument, NULL, 'j' },
+ { "list-time-stamp-types", no_argument, NULL, 'J' },
+#endif
+ { "dont-verify-checksums", no_argument, NULL, 'K' },
+ { "list-data-link-types", no_argument, NULL, 'L' },
+ { "no-optimize", no_argument, NULL, 'O' },
+ { "no-promiscuous-mode", no_argument, NULL, 'p' },
+#ifdef HAVE_PCAP_SETDIRECTION
+ { "direction", required_argument, NULL, 'Q' },
+#endif
+ { "snapshot-length", required_argument, NULL, 's' },
+ { "absolute-tcp-sequence-numbers", no_argument, NULL, 'S' },
+#ifdef HAVE_PCAP_DUMP_FLUSH
+ { "packet-buffered", no_argument, NULL, 'U' },
+#endif
+ { "linktype", required_argument, NULL, 'y' },
+#if defined(HAVE_PCAP_DEBUG) || defined(HAVE_YYDEBUG)
+ { "debug-filter-parser", no_argument, NULL, 'Y' },
+#endif
+ { "relinquish-privileges", required_argument, NULL, 'Z' },
+ { "number", no_argument, NULL, OPTION_NUMBER },
+ { "version", no_argument, NULL, OPTION_VERSION },
+ { NULL, 0, NULL, 0 }
+};
+
#ifndef WIN32
/* Drop root privileges and chroot if necessary */
static void
fprintf(stderr, "tcpdump: Chroot without dropping root is insecure\n");
exit(1);
}
-
+
pw = getpwnam(username);
if (pw) {
if (chroot_dir) {
if (initgroups(pw->pw_name, pw->pw_gid) != 0 ||
setgid(pw->pw_gid) != 0 || setuid(pw->pw_uid) != 0) {
fprintf(stderr, "tcpdump: Couldn't change to '%.32s' uid=%lu gid=%lu: %s\n",
- username,
+ username,
(unsigned long)pw->pw_uid,
(unsigned long)pw->pw_gid,
pcap_strerror(errno));
static int tcpdump_printf(netdissect_options *ndo _U_,
const char *fmt, ...)
{
-
+
va_list args;
int ret;
main(int argc, char **argv)
{
register int cnt, op, i;
- bpf_u_int32 localnet, netmask;
+ bpf_u_int32 localnet =0 , netmask = 0;
register char *cp, *infile, *cmdbuf, *device, *RFileName, *VFileName, *WFileName;
pcap_handler callback;
int type;
gndo->ndo_error=ndo_error;
gndo->ndo_warning=ndo_warning;
gndo->ndo_snaplen = DEFAULT_SNAPLEN;
-
+
cnt = -1;
device = NULL;
infile = NULL;
#endif
while (
- (op = getopt(argc, argv, "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:hHi:" I_FLAG j_FLAG J_FLAG "KlLm:M:nNOpqr:Rs:StT:u" U_FLAG "V:vw:W:xXy:Yz:Z:")) != -1)
+ (op = getopt_long(argc, argv, "aAb" B_FLAG "c:C:d" D_FLAG "eE:fF:G:hHi:" I_FLAG j_FLAG J_FLAG "KlLm:M:nNOpq" Q_FLAG "r:Rs:StT:u" U_FLAG "vV:w:W:xXy:Yz:Z:", longopts, NULL)) != -1)
switch (op) {
case 'a':
++dflag;
break;
-#ifdef HAVE_PCAP_FINDALLDEVS
case 'D':
- if (pcap_findalldevs(&devpointer, ebuf) < 0)
- error("%s", ebuf);
- else {
- for (i = 0; devpointer != 0; i++) {
- printf("%d.%s", i+1, devpointer->name);
- if (devpointer->description != NULL)
- printf(" (%s)", devpointer->description);
- printf("\n");
- devpointer = devpointer->next;
- }
- }
- return 0;
-#endif /* HAVE_PCAP_FINDALLDEVS */
+ Dflag++;
+ break;
case 'L':
Lflag++;
break;
case 'h':
- usage();
+ print_usage();
+ exit(0);
break;
case 'H':
case 'i':
if (optarg[0] == '0' && optarg[1] == 0)
error("Invalid adapter index");
-
+
#ifdef HAVE_PCAP_FINDALLDEVS
/*
* If the argument is a number, treat it as
++suppress_default_print;
break;
+#ifdef HAVE_PCAP_SETDIRECTION
+ case 'Q':
+ if (strcasecmp(optarg, "in") == 0)
+ Qflag = PCAP_D_IN;
+ else if (strcasecmp(optarg, "out") == 0)
+ Qflag = PCAP_D_OUT;
+ else if (strcasecmp(optarg, "inout") == 0)
+ Qflag = PCAP_D_INOUT;
+ else
+ error("unknown capture direction `%s'", optarg);
+ break;
+#endif /* HAVE_PCAP_SETDIRECTION */
+
case 'r':
RFileName = optarg;
break;
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;
else
error("unknown packet type `%s'", optarg);
break;
case 'W':
Wflag = atoi(optarg);
- if (Wflag < 0)
+ if (Wflag < 0)
error("invalid number of output files %s", optarg);
WflagChars = getWflagChars(Wflag);
break;
break;
#endif
case 'z':
- if (optarg) {
- zflag = strdup(optarg);
- } else {
- usage();
- /* NOTREACHED */
- }
+ zflag = strdup(optarg);
break;
case 'Z':
- if (optarg) {
- username = strdup(optarg);
- }
- else {
- usage();
- /* NOTREACHED */
- }
+ username = strdup(optarg);
+ break;
+
+ case OPTION_NUMBER:
+ gndo->ndo_packet_number = 1;
+ break;
+
+ case OPTION_VERSION:
+ print_version();
+ exit(0);
break;
default:
- usage();
+ print_usage();
+ exit(1);
/* NOTREACHED */
}
+#ifdef HAVE_PCAP_FINDALLDEVS
+ if (Dflag)
+ show_devices_and_exit();
+#endif
+
switch (tflag) {
case 0: /* Default */
#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 */
+ /* Run with '-Z root' to restore old behaviour */
if (!username)
username = WITH_USER;
}
RFileName, dlt_name,
pcap_datalink_val_to_description(dlt));
}
- localnet = 0;
- netmask = 0;
} else {
/*
* We're doing a live capture.
* Print a message to the standard error on Windows.
* XXX - why do it here, with a different message?
*/
- if(strlen(device) == 1) //we assume that an ASCII string is always longer than 1 char
- { //a Unicode string has a \0 as second byte (so strlen() is 1)
+ if(strlen(device) == 1) /* we assume that an ASCII string is always longer than 1 char */
+ { /* a Unicode string has a \0 as second byte (so strlen() is 1) */
fprintf(stderr, "%s: listening on %ws\n", program_name, device);
}
else
fprintf(stderr, "%s: listening on %s\n", program_name, device);
}
- fflush(stderr);
+ fflush(stderr);
#endif /* WIN32 */
#ifdef HAVE_PCAP_CREATE
pd = pcap_create(device, ebuf);
warning("%s: %s", device,
pcap_statustostr(status));
}
+#ifdef HAVE_PCAP_SETDIRECTION
+ if (Qflag != -1) {
+ status = pcap_setdirection(pd, Qflag);
+ if (status != 0)
+ error("%s: pcap_setdirection() failed: %s",
+ device, pcap_geterr(pd));
+ }
+#endif /* HAVE_PCAP_SETDIRECTION */
#else
*ebuf = '\0';
pd = pcap_open_live(device, snaplen, !pflag, 1000, ebuf);
warning("snaplen raised from %d to %d", snaplen, i);
snaplen = i;
}
- if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) {
- localnet = 0;
- netmask = 0;
- warning("%s", ebuf);
- }
+ if(fflag != 0) {
+ if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) {
+ warning("foreign (-f) flag used but: %s", ebuf);
+ }
+ }
+
}
if (infile)
cmdbuf = read_infile(infile);
free(cmdbuf);
exit(0);
}
- init_addrtoname(localnet, netmask);
+ init_addrtoname(gndo, localnet, netmask);
init_checksum();
-#ifndef WIN32
+#ifndef WIN32
(void)setsignal(SIGPIPE, cleanup);
(void)setsignal(SIGTERM, cleanup);
(void)setsignal(SIGINT, cleanup);
(void)setsignal(SIGCHLD, child_cleanup);
#endif
/* Cooperate with nohup(1) */
-#ifndef WIN32
+#ifndef WIN32
if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL)
(void)setsignal(SIGHUP, oldhandler);
#endif /* WIN32 */
}
(void)fflush(stdout);
}
+ if (status == -2) {
+ /*
+ * We got interrupted. If we are reading multiple
+ * files (via -V) set these so that we stop.
+ */
+ VFileName = NULL;
+ ret = NULL;
+ }
if (status == -1) {
/*
* Error. Report it.
dump_info->CurrentFileName = (char *)malloc(PATH_MAX + 1);
if (dump_info->CurrentFileName == NULL)
error("dump_packet_and_trunc: malloc");
+ /*
+ * Gflag was set otherwise we wouldn't be here. Reset the count
+ * so multiple files would end with 1,2,3 in the filename.
+ * The counting is handled with the -C flow after this.
+ */
+ Cflag_count = 0;
+
/*
* This is always the first file in the Cflag
* rotation: e.g. 0
{
struct print_info *print_info;
u_int hdrlen;
+ netdissect_options *ndo;
++packets_captured;
++infodelay;
- ts_print(&h->ts);
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 global.
*/
- snapend = sp + h->caplen;
+ 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);
}
-
- if (Xflag) {
+
+ if (ndo->ndo_Xflag) {
/*
* Print the raw packet data in hex and ASCII.
*/
- if (Xflag > 1) {
+ if (ndo->ndo_Xflag > 1) {
/*
* Include the link-layer header.
*/
- hex_and_ascii_print("\n\t", sp, h->caplen);
+ hex_and_ascii_print(ndo, "\n\t", sp, h->caplen);
} else {
/*
* Don't include the link-layer header - and if
* print nothing.
*/
if (h->caplen > hdrlen)
- hex_and_ascii_print("\n\t", sp + hdrlen,
+ hex_and_ascii_print(ndo, "\n\t", sp + hdrlen,
h->caplen - hdrlen);
}
- } else if (xflag) {
+ } else if (ndo->ndo_xflag) {
/*
* Print the raw packet data in hex.
*/
- if (xflag > 1) {
+ if (ndo->ndo_xflag > 1) {
/*
* Include the link-layer header.
*/
- hex_print("\n\t", sp, h->caplen);
+ hex_print(ndo, "\n\t", sp, h->caplen);
} else {
/*
* Don't include the link-layer header - and if
* print nothing.
*/
if (h->caplen > hdrlen)
- hex_print("\n\t", sp + hdrlen,
- h->caplen - hdrlen);
+ hex_print(ndo, "\n\t", sp + hdrlen,
+ h->caplen - hdrlen);
}
- } else if (Aflag) {
+ } else if (ndo->ndo_Aflag) {
/*
* Print the raw packet data in ASCII.
*/
- if (Aflag > 1) {
+ if (ndo->ndo_Aflag > 1) {
/*
* Include the link-layer header.
*/
- ascii_print(sp, h->caplen);
+ ascii_print(ndo, sp, h->caplen);
} else {
/*
* Don't include the link-layer header - and if
* print nothing.
*/
if (h->caplen > hdrlen)
- ascii_print(sp + hdrlen, h->caplen - hdrlen);
+ ascii_print(ndo, sp + hdrlen, h->caplen - hdrlen);
}
}
* version number of the Packet.dll code, to supply the
* "Wpcap_version" information on Windows.
*/
- char WDversion[]="current-cvs.tcpdump.org";
+ char WDversion[]="current-git.tcpdump.org";
#if !defined(HAVE_GENERATED_VERSION)
- char version[]="current-cvs.tcpdump.org";
+ char version[]="current-git.tcpdump.org";
#endif
- char pcap_version[]="current-cvs.tcpdump.org";
+ char pcap_version[]="current-git.tcpdump.org";
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 _U_, const u_char *bp, u_int length)
+ndo_default_print(netdissect_options *ndo, const u_char *bp, u_int length)
{
- hex_and_ascii_print("\n\t", bp, length); /* pass on lf and identation string */
+ hex_and_ascii_print(ndo, "\n\t", bp, length); /* pass on lf and identation string */
}
void
#endif
static void
-usage(void)
+print_version(void)
{
extern char version[];
#ifndef HAVE_PCAP_LIB_VERSION
(void)fprintf(stderr, "libpcap version %s\n", pcap_version);
#endif /* WIN32 */
#endif /* HAVE_PCAP_LIB_VERSION */
+
+#if defined(HAVE_LIBCRYPTO) && defined(SSLEAY_VERSION)
+ (void)fprintf (stderr, "%s\n", SSLeay_version(SSLEAY_VERSION));
+#endif
+
+#if defined(HAVE_SMI_H)
+ (void)fprintf (stderr, "SMI-library: %s\n", smi_version_string);
+#endif
+}
+
+static void
+print_usage(void)
+{
+ print_version();
(void)fprintf(stderr,
"Usage: %s [-aAbd" D_FLAG "efhH" I_FLAG J_FLAG "KlLnNOpqRStu" U_FLAG "vxX]" B_FLAG_USAGE " [ -c count ]\n", program_name);
(void)fprintf(stderr,
"\t\t[ -C file_size ] [ -E algo:secret ] [ -F file ] [ -G seconds ]\n");
(void)fprintf(stderr,
-"\t\t[ -i interface ]" j_FLAG_USAGE " [ -M secret ]\n");
+"\t\t[ -i interface ]" j_FLAG_USAGE " [ -M secret ] [ --number ]\n");
+#ifdef HAVE_PCAP_SETDIRECTION
+ (void)fprintf(stderr,
+"\t\t[ -Q in|out|inout ]\n");
+#endif
(void)fprintf(stderr,
-"\t\t[ -r file ] [ -s snaplen ] [ -T type ] [ -V file ] [ -w file ]\n");
+"\t\t[ -r file ] [ -s snaplen ] [ -T type ] [ --version ] [ -V file ]\n");
(void)fprintf(stderr,
-"\t\t[ -W filecount ] [ -y datalinktype ] [ -z command ]\n");
+"\t\t[ -w file ] [ -W filecount ] [ -y datalinktype ] [ -z command ]\n");
(void)fprintf(stderr,
"\t\t[ -Z user ] [ expression ]\n");
- exit(1);
}
(void)fputc('\n', stderr);
}
}
+/*
+ * Local Variables:
+ * c-style: whitesmith
+ * c-basic-offset: 8
+ * End:
+ */