• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "baseband_sniffer.h"
18 
19 #include "log.h"
20 #include "packet/raw_builder.h"
21 #include "pcap.h"
22 
23 using std::vector;
24 
25 namespace rootcanal {
26 
27 #include "bredr_bb.h"
28 
BaseBandSniffer(const std::string & filename)29 BaseBandSniffer::BaseBandSniffer(const std::string& filename) {
30   output_.open(filename, std::ios::binary);
31 
32   uint32_t linktype = 255;  // http://www.tcpdump.org/linktypes.html
33                             // LINKTYPE_BLUETOOTH_BREDR_BB
34 
35   pcap::WriteHeader(output_, linktype);
36   output_.flush();
37 }
38 
AppendRecord(std::unique_ptr<bredr_bb::BaseBandPacketBuilder> packet)39 void BaseBandSniffer::AppendRecord(
40     std::unique_ptr<bredr_bb::BaseBandPacketBuilder> packet) {
41   auto bytes = std::vector<uint8_t>();
42   bytes.reserve(packet->size());
43   bluetooth::packet::BitInserter i(bytes);
44   packet->Serialize(i);
45 
46   pcap::WriteRecordHeader(output_, bytes.size());
47   output_.write((char*)bytes.data(), bytes.size());
48   output_.flush();
49 }
50 
ReverseByte(uint8_t b)51 static uint8_t ReverseByte(uint8_t b) {
52   static uint8_t lookup[16] = {
53       [0b0000] = 0b0000, [0b0001] = 0b1000, [0b0010] = 0b0100,
54       [0b0011] = 0b1100, [0b0100] = 0b0010, [0b0101] = 0b1010,
55       [0b0110] = 0b0110, [0b0111] = 0b1110, [0b1000] = 0b0001,
56       [0b1001] = 0b1001, [0b1010] = 0b0101, [0b1011] = 0b1101,
57       [0b1100] = 0b0011, [0b1101] = 0b1011, [0b1110] = 0b0111,
58       [0b1111] = 0b1111,
59   };
60 
61   return (lookup[b & 0xF] << 4) | lookup[b >> 4];
62 }
63 
HeaderErrorCheck(uint8_t uap,uint32_t data)64 static uint8_t HeaderErrorCheck(uint8_t uap, uint32_t data) {
65   // See Bluetooth Core, Vol 2, Part B, 7.1.1
66 
67   uint8_t value = ReverseByte(uap);
68 
69   for (auto i = 0; i < 10; i++) {
70     bool bit = (value ^ data) & 1;
71     data >>= 1;
72     value >>= 1;
73     if (bit) {
74       value ^= 0xe5;
75     }
76   }
77 
78   return value;
79 }
80 
BuildBtPacketHeader(uint8_t uap,uint8_t lt_addr,uint8_t packet_type,bool flow,bool arqn,bool seqn)81 static uint32_t BuildBtPacketHeader(uint8_t uap, uint8_t lt_addr,
82                                     uint8_t packet_type, bool flow, bool arqn,
83                                     bool seqn) {
84   // See Bluetooth Core, Vol2, Part B, 6.4
85 
86   uint32_t header = (lt_addr & 0x7) | ((packet_type & 0xF) << 3) | (flow << 7) |
87                     (arqn << 8) | (seqn << 9);
88 
89   header |= (HeaderErrorCheck(uap, header) << 10);
90 
91   return header;
92 }
93 
ReceiveLinkLayerPacket(model::packets::LinkLayerPacketView packet,Phy::Type,int8_t)94 void BaseBandSniffer::ReceiveLinkLayerPacket(
95     model::packets::LinkLayerPacketView packet, Phy::Type /*type*/,
96     int8_t /*rssi*/) {
97   auto packet_type = packet.GetType();
98   auto address = packet.GetSourceAddress();
99 
100   // Bluetooth Core, Vol2, Part B, 1.2, Figure 1.5
101   uint32_t lap =
102       address.data()[0] | (address.data()[1] << 8) | (address.data()[2] << 16);
103   uint8_t uap = address.data()[3];
104   uint16_t nap = address.data()[4] | (address.data()[5] << 8);
105 
106   // http://www.whiterocker.com/bt/LINKTYPE_BLUETOOTH_BREDR_BB.html
107   uint16_t flags =
108       /* BT Packet Header and BR or EDR Payload are de-whitened */ 0x0001 |
109       /* BR or EDR Payload is decrypted */ 0x0008 |
110       /* Reference LAP is valid and led to this packet being captured */
111       0x0010 |
112       /* BR or EDR Payload is present and follows this field */ 0x0020 |
113       /* Reference UAP field is valid for HEC and CRC checking */ 0x0080 |
114       /* CRC portion of the BR or EDR Payload was checked */ 0x0400 |
115       /* CRC portion of the BR or EDR Payload passed its check */ 0x0800;
116 
117   uint8_t lt_addr = 0;
118 
119   uint8_t rf_channel = 0;
120   uint8_t signal_power = 0;
121   uint8_t noise_power = 0;
122   uint8_t access_code_offenses = 0;
123   uint8_t corrected_header_bits = 0;
124   uint16_t corrected_payload_bits = 0;
125   uint8_t lower_address_part = lap;
126   uint8_t reference_lap = lap;
127   uint8_t reference_uap = uap;
128 
129   if (packet_type == model::packets::PacketType::PAGE) {
130     auto page_view = model::packets::PageView::Create(packet);
131     ASSERT(page_view.IsValid());
132 
133     uint8_t bt_packet_type = 0b0010;  // FHS
134 
135     AppendRecord(bredr_bb::FHSAclPacketBuilder::Create(
136         rf_channel, signal_power, noise_power, access_code_offenses,
137         corrected_header_bits, corrected_payload_bits, lower_address_part,
138         reference_lap, reference_uap,
139         BuildBtPacketHeader(uap, lt_addr, bt_packet_type, true, true, true),
140         flags,
141         0,  // parity_bits
142         lap,
143         0,  // eir
144         0,  // sr
145         0,  // sp
146         uap, nap, page_view.GetClassOfDevice().ToUint32(),
147         1,  // lt_addr
148         0,  // clk
149         0,  // page_scan_mode
150         0   // crc
151         ));
152   } else if (packet_type == model::packets::PacketType::LMP) {
153     auto lmp_view = model::packets::LmpView::Create(packet);
154     ASSERT(lmp_view.IsValid());
155     auto lmp_bytes = std::vector<uint8_t>(lmp_view.GetPayload().begin(),
156                                           lmp_view.GetPayload().end());
157 
158     uint8_t bt_packet_type = 0b0011;  // DM1
159 
160     AppendRecord(bredr_bb::DM1AclPacketBuilder::Create(
161         rf_channel, signal_power, noise_power, access_code_offenses,
162         corrected_header_bits, corrected_payload_bits, lower_address_part,
163         reference_lap, reference_uap,
164         BuildBtPacketHeader(uap, lt_addr, bt_packet_type, true, true, true),
165         flags,
166         0x3,  // llid
167         1,    // flow
168         std::make_unique<bluetooth::packet::RawBuilder>(lmp_bytes),
169         0  // crc
170         ));
171   }
172 }
173 
174 }  // namespace rootcanal
175