diff --git a/CHANGES b/CHANGES index 26b45a1f3f..2809b30da0 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,8 @@ +2.5-773 | 2018-07-24 15:04:41 +0000 + + * BIT-1950: Support PPPoE over QinQ (Jon Siwek, Corelight) + 2.5-771 | 2018-07-24 02:26:17 +0000 * Support building plugins from Bro installation prefix so that it diff --git a/NEWS b/NEWS index 9b5d00943f..3cb0fd79b3 100644 --- a/NEWS +++ b/NEWS @@ -275,6 +275,8 @@ New Functionality creating "bro-devel" packages providing all files necessary to build plugins. +- Bro now supports PPPoE over QinQ. + Changed Functionality --------------------- diff --git a/VERSION b/VERSION index 2fb81e9be3..cc077245e0 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.5-771 +2.5-773 diff --git a/src/iosource/Packet.cc b/src/iosource/Packet.cc index fedb795885..5199765f51 100644 --- a/src/iosource/Packet.cc +++ b/src/iosource/Packet.cc @@ -149,36 +149,17 @@ void Packet::ProcessLayer2() pdata += GetLinkHeaderSize(link_type); - switch ( protocol ) + bool saw_vlan = false; + + while ( protocol == 0x8100 || protocol == 0x9100 || + protocol == 0x8864 ) { - // MPLS carried over the ethernet frame. - case 0x8847: - have_mpls = true; - break; - - // VLAN carried over the ethernet frame. - // 802.1q / 802.1ad - case 0x8100: - case 0x9100: - if ( pdata + 4 >= end_of_data ) - { - Weird("truncated_link_header"); - return; - } - - vlan = ((pdata[0] << 8) + pdata[1]) & 0xfff; - protocol = ((pdata[2] << 8) + pdata[3]); - pdata += 4; // Skip the vlan header - - // Check for MPLS in VLAN. - if ( protocol == 0x8847 ) - { - have_mpls = true; - break; - } - - // Check for double-tagged (802.1ad) - if ( protocol == 0x8100 || protocol == 0x9100 ) + switch ( protocol ) + { + // VLAN carried over the ethernet frame. + // 802.1q / 802.1ad + case 0x8100: + case 0x9100: { if ( pdata + 4 >= end_of_data ) { @@ -186,39 +167,46 @@ void Packet::ProcessLayer2() return; } - inner_vlan = ((pdata[0] << 8) + pdata[1]) & 0xfff; + auto& vlan_ref = saw_vlan ? inner_vlan : vlan; + vlan_ref = ((pdata[0] << 8) + pdata[1]) & 0xfff; protocol = ((pdata[2] << 8) + pdata[3]); pdata += 4; // Skip the vlan header + saw_vlan = true; + eth_type = protocol; } + break; - eth_type = protocol; - break; - - // PPPoE carried over the ethernet frame. - case 0x8864: - if ( pdata + 8 >= end_of_data ) + // PPPoE carried over the ethernet frame. + case 0x8864: { - Weird("truncated_link_header"); - return; + if ( pdata + 8 >= end_of_data ) + { + Weird("truncated_link_header"); + return; + } + + protocol = (pdata[6] << 8) + pdata[7]; + pdata += 8; // Skip the PPPoE session and PPP header + + if ( protocol == 0x0021 ) + l3_proto = L3_IPV4; + else if ( protocol == 0x0057 ) + l3_proto = L3_IPV6; + else + { + // Neither IPv4 nor IPv6. + Weird("non_ip_packet_in_pppoe_encapsulation"); + return; + } } - - protocol = (pdata[6] << 8) + pdata[7]; - pdata += 8; // Skip the PPPoE session and PPP header - - if ( protocol == 0x0021 ) - l3_proto = L3_IPV4; - else if ( protocol == 0x0057 ) - l3_proto = L3_IPV6; - else - { - // Neither IPv4 nor IPv6. - Weird("non_ip_packet_in_pppoe_encapsulation"); - return; - } - - break; + break; + } } + // Check for MPLS in VLAN. + if ( protocol == 0x8847 ) + have_mpls = true; + // Normal path to determine Layer 3 protocol. if ( ! have_mpls && l3_proto == L3_UNKNOWN ) { diff --git a/testing/btest/Baseline/core.pppoe-over-qinq/conn.log b/testing/btest/Baseline/core.pppoe-over-qinq/conn.log new file mode 100644 index 0000000000..6450d8f2f7 --- /dev/null +++ b/testing/btest/Baseline/core.pppoe-over-qinq/conn.log @@ -0,0 +1,10 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open 2018-07-06-12-25-54 +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p proto service duration orig_bytes resp_bytes conn_state local_orig local_resp missed_bytes history orig_pkts orig_ip_bytes resp_pkts resp_ip_bytes tunnel_parents +#types time string addr port addr port enum string interval count count string bool bool count string count count count count set[string] +1523351398.449222 CHhAvVGS1DHFjwGM9 1.1.1.1 20394 2.2.2.2 443 tcp - 273.626833 11352 4984 SF - - 0 ShADdtaTFf 44 25283 42 13001 - +#close 2018-07-06-12-25-54 diff --git a/testing/btest/Traces/pppoe-over-qinq.pcap b/testing/btest/Traces/pppoe-over-qinq.pcap new file mode 100644 index 0000000000..10e1429d0c Binary files /dev/null and b/testing/btest/Traces/pppoe-over-qinq.pcap differ diff --git a/testing/btest/core/pppoe-over-qinq.bro b/testing/btest/core/pppoe-over-qinq.bro new file mode 100644 index 0000000000..cdfd4607ae --- /dev/null +++ b/testing/btest/core/pppoe-over-qinq.bro @@ -0,0 +1,2 @@ +# @TEST-EXEC: bro -C -r $TRACES/pppoe-over-qinq.pcap +# @TEST-EXEC: btest-diff conn.log