Skip to content

Commit 18de787

Browse files
author
Stefan Baranoff
committed
Add support for filtering VNTag frames
Add a "vntag" keyword similar to the existing "vlan" and "mpls" keywords to filter on VNTag frames. VNTag was proposed as 802.1Qbh but has been replaced in the standards by 802.1Qbr although some vendors are still using VNTag. Skips the 6 bytes of the VNTag header similar to the 4 byte skip of VLAN. They both inject themselves between Ethernet dest addr and EtherType. This resolves GitHub issue the-tcpdump-group#770
1 parent c4b4113 commit 18de787

9 files changed

+150
-3
lines changed

CHANGES

+1
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ DayOfTheWeek, Month DD, YYYY / The Tcpdump Group
5151
Require a live capture for all Linux BPF extensions.
5252
Have "outbound" mean Tx only for DLT_SLIP.
5353
Filter Linux SocketCAN frames in userland if necessary.
54+
Add support for filtering VNTag frames (pull request #1480)
5455
rpcap:
5556
Support user names and passwords in rpcap:// and rpcaps:// URLs.
5657
Add a -t flag to rpcapd to specify the data channel port; from

ethertype.h

+3
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,9 @@
115115
#ifndef ETHERTYPE_8021AD
116116
#define ETHERTYPE_8021AD 0x88a8
117117
#endif
118+
#ifndef ETHERTYPE_VNTAG
119+
#define ETHERTYPE_VNTAG 0x8926
120+
#endif
118121
#ifndef ETHERTYPE_LOOPBACK
119122
#define ETHERTYPE_LOOPBACK 0x9000
120123
#endif

gencode.c

+73
Original file line numberDiff line numberDiff line change
@@ -10710,3 +10710,76 @@ gen_atmmulti_abbrev(compiler_state_t *cstate, int type)
1071010710
}
1071110711
return b1;
1071210712
}
10713+
10714+
/*
10715+
* support VNTag (proposed as IEEE 802.1Qbh but never accepted) over Ethernet
10716+
* VNTag headers look like this on their own:
10717+
* 0 1 2 3 4 5
10718+
* 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
10719+
* | | | | | | |
10720+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
10721+
* | EtherType |D|P| vif_list_id/dvif_id |L|R|ver| svif_id |
10722+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
10723+
*
10724+
* In context that looks like this:
10725+
* 0 1 2 3 4 5
10726+
* 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7
10727+
* | | | | | | |
10728+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
10729+
* | Destination Address |
10730+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
10731+
* | Source Address |
10732+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
10733+
* | VNTag |
10734+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
10735+
* | EtherType | Payload... |
10736+
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
10737+
*/
10738+
struct block *
10739+
gen_vntag(compiler_state_t *cstate)
10740+
{
10741+
struct block *b0;
10742+
10743+
/*
10744+
* Catch errors reported by us and routines below us, and return NULL
10745+
* on an error.
10746+
*/
10747+
if (setjmp(cstate->top_ctx))
10748+
return (NULL);
10749+
10750+
/*
10751+
* Check for a VNTag packet, and then change the offsets to point
10752+
* to the type and data fields within the VLAN after the VNTag packet.
10753+
* VNTag always requires VLAN afterwards, and that likely won't be
10754+
* offloaded so handle it just like inline VLAN. Apply the same rules
10755+
* and restrictions as VLAN, too.
10756+
*/
10757+
if (cstate->label_stack_depth > 0)
10758+
bpf_error(cstate, "no VNTag match after MPLS");
10759+
10760+
/* Assume any of the EtherTypes that can have VLAN can also have
10761+
* VNTag as well. With VNTag not being accepted as 802.1Qbh but
10762+
* being replaced in the standads by 802.1Qbr there's not much to go on
10763+
* other than a few vendor proprietary implementations.
10764+
*/
10765+
switch (cstate->linktype) {
10766+
case DLT_EN10MB:
10767+
case DLT_NETANALYZER:
10768+
case DLT_NETANALYZER_TRANSPARENT:
10769+
case DLT_IEEE802_11:
10770+
case DLT_PRISM_HEADER:
10771+
case DLT_IEEE802_11_RADIO_AVS:
10772+
case DLT_IEEE802_11_RADIO:
10773+
/* Make sure we have a VNTag frame, then jump over it. */
10774+
b0 = gen_linktype(cstate, ETHERTYPE_VNTAG);
10775+
cstate->off_linkpl.constant_part += 6;
10776+
cstate->off_linktype.constant_part += 6;
10777+
break;
10778+
default:
10779+
bpf_error(cstate, "no VNTag support for %s",
10780+
pcap_datalink_val_to_description_or_dlt(cstate->linktype));
10781+
/*NOTREACHED*/
10782+
}
10783+
10784+
return (b0);
10785+
}

gencode.h

+1
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@ struct block *gen_llc_u_subtype(compiler_state_t *, bpf_u_int32);
352352

353353
struct block *gen_vlan(compiler_state_t *, bpf_u_int32, int);
354354
struct block *gen_mpls(compiler_state_t *, bpf_u_int32, int);
355+
struct block *gen_vntag(compiler_state_t *);
355356

356357
struct block *gen_pppoed(compiler_state_t *);
357358
struct block *gen_pppoes(compiler_state_t *, bpf_u_int32, int);

grammar.y.in

+2-1
Original file line numberDiff line numberDiff line change
@@ -389,7 +389,7 @@ DIAG_OFF_BISON_BYACC
389389
%token LSH RSH
390390
%token LEN
391391
%token IPV6 ICMPV6 AH ESP
392-
%token VLAN MPLS
392+
%token VLAN MPLS VNTAG
393393
%token PPPOED PPPOES GENEVE VXLAN
394394
%token ISO ESIS CLNP ISIS L1 L2 IIH LSP SNP CSNP PSNP
395395
%token STP
@@ -682,6 +682,7 @@ other: pqual TK_BROADCAST { CHECK_PTR_VAL(($$ = gen_broadcast(cstate, $1))); }
682682
| VLAN { CHECK_PTR_VAL(($$ = gen_vlan(cstate, 0, 0))); }
683683
| MPLS pnum { CHECK_PTR_VAL(($$ = gen_mpls(cstate, $2, 1))); }
684684
| MPLS { CHECK_PTR_VAL(($$ = gen_mpls(cstate, 0, 0))); }
685+
| VNTAG { CHECK_PTR_VAL(($$ = gen_vntag(cstate))); }
685686
| PPPOED { CHECK_PTR_VAL(($$ = gen_pppoed(cstate))); }
686687
| PPPOES pnum { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, $2, 1))); }
687688
| PPPOES { CHECK_PTR_VAL(($$ = gen_pppoes(cstate, 0, 0))); }

pcap-filter.manmisc.in

+22-2
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,24 @@ filters packets with an outer label of 100000 and an inner label of
10111011
.in -.5i
10121012
filters packets to or from 192.9.200.1 with an inner label of 1024 and
10131013
any outer label.
1014+
.IP "\fBvntag\fR"
1015+
True if the packet is a VNTag packet (identified by EtherType 0x8926).
1016+
Each use of that keyword increments the filter link header and payload offsets by 6.
1017+
.IP
1018+
For example:
1019+
.in +.5i
1020+
.nf
1021+
\fBvntag\fR
1022+
.fi
1023+
.in -.5i
1024+
filters on VNTag as the next EtherType and skips the VNTag header
1025+
.in +.5i
1026+
.nf
1027+
\fBvntag\fR and \fBvlan\fR and \fBip src host\fR 192.0.2.0
1028+
.fi
1029+
.in -.5i
1030+
filters on VNTag followed by any VLAN followed by an IPv4 packet from 192.0.2.0
1031+
skipping over the VNTag header, then VLAN header, to allow finding the IPv4
10141032
.IP \fBpppoed\fP
10151033
True if the packet is a PPP-over-Ethernet Discovery packet (Ethernet
10161034
type 0x8863).
@@ -1636,8 +1654,10 @@ The
16361654
keyword became available in libpcap 1.10.0.
16371655
.PP
16381656
The
1639-
.B vxlan
1640-
keyword became available in libpcap 1.11.0.
1657+
.BR vxlan
1658+
and
1659+
.B vntag
1660+
keywords became available in libpcap 1.11.0.
16411661
.SH SEE ALSO
16421662
.BR pcap (3PCAP)
16431663
.SH BUGS

scanner.l

+1
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,7 @@ pppoed return PPPOED;
339339
pppoes return PPPOES;
340340
geneve return GENEVE;
341341
vxlan return VXLAN;
342+
vntag return VNTAG;
342343

343344
lane return LANE;
344345
llc return LLC;

testprogs/TESTrun

+47
Original file line numberDiff line numberDiff line change
@@ -9657,6 +9657,34 @@ my %accept_blocks = (
96579657
(020) ret #0
96589658
',
96599659
}, # dst_portrange_degenerate
9660+
vntag_eth => {
9661+
DLT => 'EN10MB',
9662+
aliases => ['vntag'],
9663+
opt => '
9664+
(000) ldh [12]
9665+
(001) jeq #0x8926 jt 2 jf 3
9666+
(002) ret #262144
9667+
(003) ret #0
9668+
',
9669+
}, # vntag_eth
9670+
vntag_eth_vlan_vntag_vlan => {
9671+
DLT => 'EN10MB',
9672+
aliases => ['vlan and vntag and vlan'],
9673+
opt => '
9674+
(000) ldh [12]
9675+
(001) jeq #0x8100 jt 4 jf 2
9676+
(002) jeq #0x88a8 jt 4 jf 3
9677+
(003) jeq #0x9100 jt 4 jf 11
9678+
(004) ldh [16]
9679+
(005) jeq #0x8926 jt 6 jf 11
9680+
(006) ldh [22]
9681+
(007) jeq #0x8100 jt 10 jf 8
9682+
(008) jeq #0x88a8 jt 10 jf 9
9683+
(009) jeq #0x9100 jt 10 jf 11
9684+
(010) ret #262144
9685+
(011) ret #0
9686+
',
9687+
}, # vntag_eth
96609688
);
96619689

96629690
# In apply_blocks the top-level keys are test block names. Each test block
@@ -10067,6 +10095,21 @@ my %apply_blocks = (
1006710095
expr => 'outbound',
1006810096
results => [46],
1006910097
},
10098+
vntag => {
10099+
savefile => 'vntag-novntag-mixed.pcap',
10100+
expr => 'vntag',
10101+
results => [262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
10102+
},
10103+
vntag_vlan_ip => {
10104+
savefile => 'vntag-novntag-mixed.pcap',
10105+
expr => 'vntag and vlan 100 and ip',
10106+
results => [262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 262144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
10107+
},
10108+
vntag_vlan_dest_ip => {
10109+
savefile => 'vntag-novntag-mixed.pcap',
10110+
expr => 'vntag and vlan 100 and ip dst 192.168.20.102',
10111+
results => [0, 262144, 0, 0, 262144, 262144, 0, 0, 262144, 262144, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
10112+
},
1007010113
);
1007110114

1007210115
# * DLT, expr, netmask and skip: same as in accept_blocks above
@@ -10698,6 +10741,10 @@ my %reject_tests = (
1069810741
DLT => 'EN10MB',
1069910742
expr => 'gateway $af',
1070010743
errstr => 'aid supported only on ARCnet',
10744+
vntag_not_supported => {
10745+
DLT => 'RAW',
10746+
expr => 'vntag',
10747+
errstr => 'no VNTag support',
1070110748
},
1070210749
);
1070310750

tests/filter/vntag-novntag-mixed.pcap

3.23 KB
Binary file not shown.

0 commit comments

Comments
 (0)