diff --git a/CHANGES b/CHANGES index e3ebc76476..4ebc9364ce 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,12 @@ +2.4-253 | 2016-01-20 17:41:20 -0800 + + * Support of RadioTap encapsulation for 802.11 (Seth Hall) + + Radiotap support should be fully functional with Radiotap + packets that include IPv4 and IPv6. Other radiotap packets are + silently ignored. + 2.4-247 | 2016-01-19 10:19:48 -0800 * Fixing C++11 compiler warnings. (Seth Hall) diff --git a/NEWS b/NEWS index 5348826e04..e8c0268644 100644 --- a/NEWS +++ b/NEWS @@ -23,6 +23,8 @@ New Dependencies New Functionality ----------------- +- Bro now supports the Radiotap header for 802.11 frames. + - Bro now tracks VLAN IDs. To record them inside the connection log, load protocols/conn/vlan-logging.bro. diff --git a/VERSION b/VERSION index 1582f62cd4..943e3a2081 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -2.4-247 +2.4-253 diff --git a/src/iosource/Packet.cc b/src/iosource/Packet.cc index fbefd9c5d2..2aa7fa58c7 100644 --- a/src/iosource/Packet.cc +++ b/src/iosource/Packet.cc @@ -83,6 +83,9 @@ int Packet::GetLinkHeaderSize(int link_type) case DLT_PPP_SERIAL: // PPP_SERIAL return 4; + case DLT_IEEE802_11_RADIO: // 802.11 plus RadioTap + return 59; + case DLT_RAW: return 0; } @@ -251,6 +254,80 @@ void Packet::ProcessLayer2() break; } + case DLT_IEEE802_11_RADIO: + { + if ( pdata + 3 >= end_of_data ) + { + Weird("truncated_radiotap_header"); + return; + } + // Skip over the RadioTap header + int rtheader_len = (pdata[3] << 8) + pdata[2]; + if ( pdata + rtheader_len >= end_of_data ) + { + Weird("truncated_radiotap_header"); + return; + } + pdata += rtheader_len; + + int type_80211 = pdata[0]; + int len_80211 = 0; + if ( (type_80211 >> 4) & 0x04 ) + { + //identified a null frame (we ignore for now). no weird. + return; + } + // Look for the QoS indicator bit. + if ( (type_80211 >> 4) & 0x08 ) + len_80211 = 26; + else + len_80211 = 24; + + if ( pdata + len_80211 >= end_of_data ) + { + Weird("truncated_radiotap_header"); + return; + } + // skip 802.11 data header + pdata += len_80211; + + if ( pdata + 8 >= end_of_data ) + { + Weird("truncated_radiotap_header"); + return; + } + // Check that the DSAP and SSAP are both SNAP and that the control + // field indicates that this is an unnumbered frame. + // The organization code (24bits) needs to also be zero to + // indicate that this is encapsulated ethernet. + if ( pdata[0] == 0xAA && pdata[1] == 0xAA && pdata[2] == 0x03 && + pdata[3] == 0 && pdata[4] == 0 && pdata[5] == 0 ) + { + pdata += 6; + } + else + { + // If this is a logical link control frame without the + // possibility of having a protocol we care about, we'll + // just skip it for now. + return; + } + + int protocol = (pdata[0] << 8) + pdata[1]; + if ( protocol == 0x0800 ) + l3_proto = L3_IPV4; + else if ( protocol == 0x86DD ) + l3_proto = L3_IPV6; + else + { + Weird("non_ip_packet_in_ieee802_11_radio_encapsulation"); + return; + } + pdata += 2; + + break; + } + default: { // Assume we're pointing at IP. Just figure out which version. diff --git a/testing/btest/Baseline/core.radiotap/conn.log b/testing/btest/Baseline/core.radiotap/conn.log new file mode 100644 index 0000000000..24b94f77f4 --- /dev/null +++ b/testing/btest/Baseline/core.radiotap/conn.log @@ -0,0 +1,11 @@ +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path conn +#open 2016-01-19-09-01-31 +#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] +1439902891.705224 CXWv6p3arKYeMETxOg 172.17.156.76 61738 208.67.220.220 53 udp dns 0.041654 35 128 SF - - 0 Dd 1 63 1 156 (empty) +1439903050.580632 CjhGID4nQcgTWjvg4c fe80::a667:6ff:fef7:ec54 5353 ff02::fb 5353 udp dns - - - S0 - - 0 D 1 328 0 0 (empty) +#close 2016-01-19-09-01-31 diff --git a/testing/btest/Traces/radiotap.pcap b/testing/btest/Traces/radiotap.pcap new file mode 100644 index 0000000000..1f500f2ed7 Binary files /dev/null and b/testing/btest/Traces/radiotap.pcap differ diff --git a/testing/btest/core/radiotap.bro b/testing/btest/core/radiotap.bro new file mode 100644 index 0000000000..27513990f0 --- /dev/null +++ b/testing/btest/core/radiotap.bro @@ -0,0 +1,2 @@ +# @TEST-EXEC: bro -C -r $TRACES/radiotap.pcap +# @TEST-EXEC: btest-diff conn.log