summaryrefslogtreecommitdiff
path: root/lib/libpcap
diff options
context:
space:
mode:
authordenis <denis@cvs.openbsd.org>2018-12-09 15:07:07 +0000
committerdenis <denis@cvs.openbsd.org>2018-12-09 15:07:07 +0000
commita9f3c72a8b559572937319c305be64c04dcb838b (patch)
tree3108094b9faaaf3067fd92c1cbe0fa06602c9736 /lib/libpcap
parenta0b49f0de769daa3c267dca4b0c02fde8329f6dd (diff)
add basic MPLS filtering support
OK claudio@ jca@
Diffstat (limited to 'lib/libpcap')
-rw-r--r--lib/libpcap/gencode.c37
-rw-r--r--lib/libpcap/gencode.h3
-rw-r--r--lib/libpcap/grammar.y6
-rw-r--r--lib/libpcap/pcap-filter.326
-rw-r--r--lib/libpcap/scanner.l3
5 files changed, 67 insertions, 8 deletions
diff --git a/lib/libpcap/gencode.c b/lib/libpcap/gencode.c
index e0e97aa4994..44d791b0644 100644
--- a/lib/libpcap/gencode.c
+++ b/lib/libpcap/gencode.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: gencode.c,v 1.51 2018/11/10 10:17:37 denis Exp $ */
+/* $OpenBSD: gencode.c,v 1.52 2018/12/09 15:07:06 denis Exp $ */
/*
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998
@@ -37,6 +37,8 @@ struct rtentry;
#include <net/if_pflog.h>
#include <net/pfvar.h>
+#include <netmpls/mpls.h>
+
#include <net80211/ieee80211.h>
#include <net80211/ieee80211_radiotap.h>
@@ -69,6 +71,7 @@ static pcap_t *bpf_pcap;
/* Hack for updating VLAN offsets. */
static u_int orig_linktype = -1, orig_nl = -1, orig_nl_nosnap = -1;
+static u_int mpls_stack = 0;
/* XXX */
#ifdef PCAP_FDDIPAD
@@ -837,11 +840,11 @@ gen_linktype(proto)
struct block *b0, *b1;
/* If we're not using encapsulation and checking for IP, we're done */
- if (off_linktype == -1 && proto == ETHERTYPE_IP)
+ if ((off_linktype == -1 || mpls_stack > 0) && proto == ETHERTYPE_IP)
return gen_true();
#ifdef INET6
/* this isn't the right thing to do, but sometimes necessary */
- if (off_linktype == -1 && proto == ETHERTYPE_IPV6)
+ if ((off_linktype == -1 || mpls_stack > 0) && proto == ETHERTYPE_IPV6)
return gen_true();
#endif
@@ -3350,6 +3353,34 @@ gen_acode(eaddr, q)
/* NOTREACHED */
}
+struct block *
+gen_mpls(label)
+ int label;
+{
+ struct block *b0;
+
+ if (label > MPLS_LABEL_MAX)
+ bpf_error("invalid MPLS label : %d", label);
+
+ if (mpls_stack > 0) /* Bottom-Of-Label-Stack bit ? */
+ b0 = gen_mcmp(off_nl-2, BPF_B, (bpf_int32)0, 0x1);
+ else
+ b0 = gen_linktype(ETHERTYPE_MPLS);
+
+ if (label >= 0) {
+ struct block *b1;
+
+ b1 = gen_mcmp(off_nl, BPF_W, (bpf_int32)(label << 12),
+ MPLS_LABEL_MASK);
+ gen_and(b0, b1);
+ b0 = b1;
+ }
+ off_nl += 4;
+ off_linktype += 4;
+ mpls_stack++;
+ return (b0);
+}
+
/*
* support IEEE 802.1Q VLAN trunk over ethernet
*/
diff --git a/lib/libpcap/gencode.h b/lib/libpcap/gencode.h
index fc8a8499c21..d04ea6d90ff 100644
--- a/lib/libpcap/gencode.h
+++ b/lib/libpcap/gencode.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: gencode.h,v 1.18 2018/06/03 10:29:28 sthen Exp $ */
+/* $OpenBSD: gencode.h,v 1.19 2018/12/09 15:07:06 denis Exp $ */
/*
* Copyright (c) 1990, 1991, 1992, 1993, 1994, 1995, 1996
@@ -179,6 +179,7 @@ struct block *gen_multicast(int);
struct block *gen_inbound(int);
struct block *gen_vlan(int);
+struct block *gen_mpls(int);
struct block *gen_pf_ifname(char *);
struct block *gen_pf_rnr(int);
diff --git a/lib/libpcap/grammar.y b/lib/libpcap/grammar.y
index d784d84f8a7..12177ed03d6 100644
--- a/lib/libpcap/grammar.y
+++ b/lib/libpcap/grammar.y
@@ -1,5 +1,5 @@
%{
-/* $OpenBSD: grammar.y,v 1.19 2009/10/27 23:59:30 deraadt Exp $ */
+/* $OpenBSD: grammar.y,v 1.20 2018/12/09 15:07:06 denis Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996
@@ -115,7 +115,7 @@ pcap_parse()
%token LSH RSH
%token LEN
%token IPV6 ICMPV6 AH ESP
-%token VLAN
+%token VLAN MPLS
%type <s> ID
%type <e> EID
@@ -279,6 +279,8 @@ other: pqual TK_BROADCAST { $$ = gen_broadcast($1); }
| OUTBOUND { $$ = gen_inbound(1); }
| VLAN pnum { $$ = gen_vlan($2); }
| VLAN { $$ = gen_vlan(-1); }
+ | MPLS pnum { $$ = gen_mpls($2); }
+ | MPLS { $$ = gen_mpls(-1); }
| pfvar { $$ = $1; }
| pqual p80211 { $$ = $2; }
;
diff --git a/lib/libpcap/pcap-filter.3 b/lib/libpcap/pcap-filter.3
index d2579c27e72..4c0da989f2c 100644
--- a/lib/libpcap/pcap-filter.3
+++ b/lib/libpcap/pcap-filter.3
@@ -1,4 +1,4 @@
-.\" $OpenBSD: pcap-filter.3,v 1.2 2014/02/19 04:51:32 lteo Exp $
+.\" $OpenBSD: pcap-filter.3,v 1.3 2018/12/09 15:07:06 denis Exp $
.\"
.\" Copyright (c) 1987, 1988, 1989, 1990, 1991, 1992, 1994, 1995, 1996, 1997
.\" The Regents of the University of California. All rights reserved.
@@ -522,6 +522,30 @@ filters on VLAN 200 encapsulated within VLAN 100, and
.in -.5i
filters IPv4 protocols encapsulated in VLAN 300 encapsulated within any
higher order VLAN.
+.IP "\fBmpls \fI[label]\fR"
+True if the packet is an MPLS (Multi-Protocol Label Switching) packet.
+If \fIlabel\fR is specified, only true if the packet has the specified
+\fIlabel\fR.
+Note that the first \fBmpls\fR keyword encountered in \fIexpression\fR
+changes the decoding offsets for the remainder of \fIexpression\fR on
+the assumption that the packet is an MPLS packet. The \fBmpls
+\fI[label]\fR expression may be used more than once, to filter on MPLS
+labels stack. Each use of that expression increments the filter offsets
+by 4.
+.IP
+For example:
+.in +.5i
+.nf
+\fBmpls 42 && mpls 12\fR
+.fi
+.in -.5i
+filters on MPLS label 42 first and requires the next label to be 12 and
+.in +.5i
+.nf
+\fBmpls 42 && net 192.0.2.0/24\fR
+.fi
+.in -.5i
+filters on network 192.0.2.0/24 transported inside packets with label 42.
.IP "\fBtcp\fR, \fBudp\fR, \fBicmp\fR"
Abbreviations for:
.in +.5i
diff --git a/lib/libpcap/scanner.l b/lib/libpcap/scanner.l
index 895fe8d9198..714662cf8e2 100644
--- a/lib/libpcap/scanner.l
+++ b/lib/libpcap/scanner.l
@@ -1,5 +1,5 @@
%{
-/* $OpenBSD: scanner.l,v 1.25 2018/06/03 10:29:28 sthen Exp $ */
+/* $OpenBSD: scanner.l,v 1.26 2018/12/09 15:07:06 denis Exp $ */
/*
* Copyright (c) 1988, 1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997
@@ -224,6 +224,7 @@ inbound return INBOUND;
outbound return OUTBOUND;
vlan return VLAN;
+mpls return MPLS;
on|ifname return PF_IFNAME;
rset|ruleset return PF_RSET;