diff options
author | denis <denis@cvs.openbsd.org> | 2018-12-09 15:07:07 +0000 |
---|---|---|
committer | denis <denis@cvs.openbsd.org> | 2018-12-09 15:07:07 +0000 |
commit | a9f3c72a8b559572937319c305be64c04dcb838b (patch) | |
tree | 3108094b9faaaf3067fd92c1cbe0fa06602c9736 /lib/libpcap | |
parent | a0b49f0de769daa3c267dca4b0c02fde8329f6dd (diff) |
add basic MPLS filtering support
OK claudio@ jca@
Diffstat (limited to 'lib/libpcap')
-rw-r--r-- | lib/libpcap/gencode.c | 37 | ||||
-rw-r--r-- | lib/libpcap/gencode.h | 3 | ||||
-rw-r--r-- | lib/libpcap/grammar.y | 6 | ||||
-rw-r--r-- | lib/libpcap/pcap-filter.3 | 26 | ||||
-rw-r--r-- | lib/libpcap/scanner.l | 3 |
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; |