summaryrefslogtreecommitdiff
path: root/usr.sbin/tcpdump
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2019-03-18 00:09:23 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2019-03-18 00:09:23 +0000
commit2cbcbbc3e54844ec15530ed001236629e4c2403f (patch)
tree433ea045f719470546b3760e945e94b9c7ca3679 /usr.sbin/tcpdump
parent2060f7282849d669e6031b2645625a2cd691b0f7 (diff)
support configuring BIOCSFILDROP with tcpdump.
this allows tcpdump to be used a quick and dirty firewall. it also looks like an amazing foot-gun, so be careful. for example `tcpdump -B drop -i ix1 udp and port 7` lets you completely drop discard packets in the hardware interrupt handler. ok sthen@ mikeb@ claudio@ visa@
Diffstat (limited to 'usr.sbin/tcpdump')
-rw-r--r--usr.sbin/tcpdump/privsep.c9
-rw-r--r--usr.sbin/tcpdump/privsep.h4
-rw-r--r--usr.sbin/tcpdump/privsep_pcap.c10
-rw-r--r--usr.sbin/tcpdump/tcpdump.822
-rw-r--r--usr.sbin/tcpdump/tcpdump.c22
5 files changed, 52 insertions, 15 deletions
diff --git a/usr.sbin/tcpdump/privsep.c b/usr.sbin/tcpdump/privsep.c
index bb2279968df..6e708216e2a 100644
--- a/usr.sbin/tcpdump/privsep.c
+++ b/usr.sbin/tcpdump/privsep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: privsep.c,v 1.52 2018/11/17 16:52:02 brynet Exp $ */
+/* $OpenBSD: privsep.c,v 1.53 2019/03/18 00:09:22 dlg Exp $ */
/*
* Copyright (c) 2003 Can Erkin Acar
@@ -224,7 +224,7 @@ priv_exec(int argc, char *argv[])
/* parse the arguments for required options */
opterr = 0;
while ((i = getopt(argc, argv,
- "ac:D:deE:fF:i:lLnNOopPqr:s:StT:vw:xXy:Y")) != -1) {
+ "aB:c:D:deE:fF:i:lLnNOopPqr:s:StT:vw:xXy:Y")) != -1) {
switch (i) {
case 'n':
nflag++;
@@ -366,7 +366,7 @@ static void
impl_open_bpf(int fd, int *bpfd)
{
int snaplen, promisc, err;
- u_int dlt, dirfilt;
+ u_int dlt, dirfilt, fildrop;
char device[IFNAMSIZ];
size_t iflen;
@@ -376,10 +376,11 @@ impl_open_bpf(int fd, int *bpfd)
must_read(fd, &promisc, sizeof(int));
must_read(fd, &dlt, sizeof(u_int));
must_read(fd, &dirfilt, sizeof(u_int));
+ must_read(fd, &fildrop, sizeof(fildrop));
iflen = read_string(fd, device, sizeof(device), __func__);
if (iflen == 0)
errx(1, "Invalid interface size specified");
- *bpfd = pcap_live(device, snaplen, promisc, dlt, dirfilt);
+ *bpfd = pcap_live(device, snaplen, promisc, dlt, dirfilt, fildrop);
err = errno;
if (*bpfd < 0)
logmsg(LOG_DEBUG,
diff --git a/usr.sbin/tcpdump/privsep.h b/usr.sbin/tcpdump/privsep.h
index 017b100f9f8..e1b565e675e 100644
--- a/usr.sbin/tcpdump/privsep.h
+++ b/usr.sbin/tcpdump/privsep.h
@@ -45,11 +45,11 @@ __dead void priv_exec(int, char **);
void priv_init_done(void);
int setfilter(int, int, char *);
-int pcap_live(const char *, int, int, u_int, u_int);
+int pcap_live(const char *, int, int, u_int, u_int, u_int);
struct bpf_program *priv_pcap_setfilter(pcap_t *, int, u_int32_t);
pcap_t *priv_pcap_live(const char *, int, int, int, char *, u_int,
- u_int);
+ u_int, u_int);
pcap_t *priv_pcap_offline(const char *, char *);
size_t priv_gethostbyaddr(char *, size_t, int, char *, size_t);
diff --git a/usr.sbin/tcpdump/privsep_pcap.c b/usr.sbin/tcpdump/privsep_pcap.c
index 7d9366c79e9..3d248ed1eb7 100644
--- a/usr.sbin/tcpdump/privsep_pcap.c
+++ b/usr.sbin/tcpdump/privsep_pcap.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: privsep_pcap.c,v 1.23 2018/11/17 16:52:02 brynet Exp $ */
+/* $OpenBSD: privsep_pcap.c,v 1.24 2019/03/18 00:09:22 dlg Exp $ */
/*
* Copyright (c) 2004 Can Erkin Acar
@@ -173,7 +173,7 @@ priv_pcap_setfilter(pcap_t *hpcap, int oflag, u_int32_t netmask)
/* privileged part of priv_pcap_live */
int
pcap_live(const char *device, int snaplen, int promisc, u_int dlt,
- u_int dirfilt)
+ u_int dirfilt, u_int fildrop)
{
int fd;
struct ifreq ifr;
@@ -201,6 +201,9 @@ pcap_live(const char *device, int snaplen, int promisc, u_int dlt,
if (ioctl(fd, BIOCSDIRFILT, &dirfilt) < 0)
goto error;
+ if (ioctl(fd, BIOCSFILDROP, &fildrop) < 0)
+ goto error;
+
/* lock the descriptor */
if (ioctl(fd, BIOCLOCK, NULL) < 0)
goto error;
@@ -218,7 +221,7 @@ pcap_live(const char *device, int snaplen, int promisc, u_int dlt,
*/
pcap_t *
priv_pcap_live(const char *dev, int slen, int prom, int to_ms,
- char *ebuf, u_int dlt, u_int dirfilt)
+ char *ebuf, u_int dlt, u_int dirfilt, u_int fildrop)
{
int fd, err;
struct bpf_version bv;
@@ -247,6 +250,7 @@ priv_pcap_live(const char *dev, int slen, int prom, int to_ms,
must_write(priv_fd, &prom, sizeof(int));
must_write(priv_fd, &dlt, sizeof(u_int));
must_write(priv_fd, &dirfilt, sizeof(u_int));
+ must_write(priv_fd, &fildrop, sizeof(fildrop));
write_string(priv_fd, dev);
fd = receive_fd(priv_fd);
diff --git a/usr.sbin/tcpdump/tcpdump.8 b/usr.sbin/tcpdump/tcpdump.8
index 17aadb43116..4b0b2e809df 100644
--- a/usr.sbin/tcpdump/tcpdump.8
+++ b/usr.sbin/tcpdump/tcpdump.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: tcpdump.8,v 1.99 2018/07/06 09:59:12 jmc Exp $
+.\" $OpenBSD: tcpdump.8,v 1.100 2019/03/18 00:09:22 dlg Exp $
.\"
.\" Copyright (c) 1987, 1988, 1989, 1990, 1991, 1992, 1994, 1995, 1996
.\" The Regents of the University of California. All rights reserved.
@@ -19,7 +19,7 @@
.\" WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
.\"
-.Dd $Mdocdate: July 6 2018 $
+.Dd $Mdocdate: March 18 2019 $
.Dt TCPDUMP 8
.Os
.Sh NAME
@@ -29,6 +29,7 @@
.Nm tcpdump
.Op Fl AadefILlNnOopqStvXx
.Op Fl c Ar count
+.Op Fl B Ar fildrop
.Op Fl D Ar direction
.Op Fl E Oo Ar espalg : Oc Ns Ar espkey
.Op Fl F Ar file
@@ -58,6 +59,23 @@ The smaller of the entire packet or
bytes will be printed.
.It Fl a
Attempt to convert network and broadcast addresses to names.
+.It Fl B Ar fildrop
+Configure the drop action specified by
+.A fildrop
+to be used when the filter expression matches a packet.
+The actions are:
+.Pp
+.Bl -tag -width "capture" -offset indent -compact
+.It Cm pass
+Matching packets are accepted and captured.
+.It Cm capture
+Matching packets are dropped and captured.
+.It Cm drop
+Matching packets are dropped and not captured.
+.El
+.Pp
+The default action is
+.Cm pass .
.It Fl c Ar count
Exit after receiving
.Ar count
diff --git a/usr.sbin/tcpdump/tcpdump.c b/usr.sbin/tcpdump/tcpdump.c
index b4818a38491..60552c8c19c 100644
--- a/usr.sbin/tcpdump/tcpdump.c
+++ b/usr.sbin/tcpdump/tcpdump.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tcpdump.c,v 1.88 2018/11/08 14:06:09 brynet Exp $ */
+/* $OpenBSD: tcpdump.c,v 1.89 2019/03/18 00:09:22 dlg Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
@@ -61,6 +61,7 @@
int Aflag; /* dump ascii */
int aflag; /* translate network and broadcast addresses */
+int Bflag; /* BPF fildrop setting */
int dflag; /* print filter code */
int eflag; /* print ethernet header */
int fflag; /* don't translate "foreign" IP address */
@@ -231,7 +232,7 @@ main(int argc, char **argv)
opterr = 0;
while ((op = getopt(argc, argv,
- "Aac:D:deE:fF:i:IlLnNOopqr:s:StT:vw:xXy:Y")) != -1)
+ "AaB:c:D:deE:fF:i:IlLnNOopqr:s:StT:vw:xXy:Y")) != -1)
switch (op) {
case 'A':
@@ -243,6 +244,19 @@ main(int argc, char **argv)
aflag = 1;
break;
+ case 'B':
+ if (strcasecmp(optarg, "pass") == 0)
+ Bflag = BPF_FILDROP_PASS;
+ else if (strcasecmp(optarg, "capture") == 0)
+ Bflag = BPF_FILDROP_CAPTURE;
+ else if (strcasecmp(optarg, "drop") == 0)
+ Bflag = BPF_FILDROP_DROP;
+ else {
+ error("invalid BPF fildrop option: %s",
+ optarg);
+ }
+ break;
+
case 'c':
cnt = strtonum(optarg, 1, INT_MAX, &errstr);
if (errstr)
@@ -440,7 +454,7 @@ main(int argc, char **argv)
error("%s", ebuf);
}
pd = priv_pcap_live(device, snaplen, !pflag, 1000, ebuf,
- dlt, dirfilt);
+ dlt, dirfilt, Bflag);
if (pd == NULL)
error("%s", ebuf);
@@ -700,7 +714,7 @@ __dead void
usage(void)
{
(void)fprintf(stderr,
-"Usage: %s [-AadefILlNnOopqStvXx] [-c count] [-D direction]\n",
+"Usage: %s [-AadefILlNnOopqStvXx] [-B fildrop] [-c count] [-D direction]\n",
program_name);
(void)fprintf(stderr,
"\t [-E [espalg:]espkey] [-F file] [-i interface] [-r file]\n");