OSDN Git Service

Merge "packet: Add Packet classes and tests" am: a275910a49 am: 257ed53ca9
[android-x86/system-bt.git] / hci / src / btsnoop.cc
1 /******************************************************************************
2  *
3  *  Copyright 2014 Google, Inc.
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18
19 #define LOG_TAG "bt_snoop"
20
21 #include <mutex>
22
23 #include <arpa/inet.h>
24 #include <base/logging.h>
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <inttypes.h>
28 #include <limits.h>
29 #include <netinet/in.h>
30 #include <stdbool.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <string.h>
34 #include <sys/stat.h>
35 #include <sys/time.h>
36 #include <sys/uio.h>
37 #include <unistd.h>
38 #include <mutex>
39 #include <unordered_map>
40 #include <unordered_set>
41
42 #include "bt_types.h"
43 #include "common/time_util.h"
44 #include "hci/include/btsnoop.h"
45 #include "hci/include/btsnoop_mem.h"
46 #include "hci_layer.h"
47 #include "internal_include/bt_trace.h"
48 #include "osi/include/log.h"
49 #include "osi/include/properties.h"
50 #include "stack/include/hcimsgs.h"
51 #include "stack/include/rfcdefs.h"
52 #include "stack/l2cap/l2c_int.h"
53 #include "stack_config.h"
54
55 // The number of of packets per btsnoop file before we rotate to the next
56 // file. As of right now there are two snoop files that are rotated through.
57 // The size can be dynamically configured by seting the relevant system
58 // property
59 #define DEFAULT_BTSNOOP_SIZE 0xffff
60
61 #define IS_DEBUGGABLE_PROPERTY "ro.debuggable"
62
63 #define BTSNOOP_LOG_MODE_PROPERTY "persist.bluetooth.btsnooplogmode"
64 #define BTSNOOP_DEFAULT_MODE_PROPERTY "persist.bluetooth.btsnoopdefaultmode"
65 #define BTSNOOP_MODE_DISABLED "disabled"
66 #define BTSNOOP_MODE_FILTERED "filtered"
67 #define BTSNOOP_MODE_FULL "full"
68
69 #define BTSNOOP_PATH_PROPERTY "persist.bluetooth.btsnooppath"
70 #define DEFAULT_BTSNOOP_PATH "/data/misc/bluetooth/logs/btsnoop_hci.log"
71 #define BTSNOOP_MAX_PACKETS_PROPERTY "persist.bluetooth.btsnoopsize"
72
73 typedef enum {
74   kCommandPacket = 1,
75   kAclPacket = 2,
76   kScoPacket = 3,
77   kEventPacket = 4
78 } packet_type_t;
79
80 // Epoch in microseconds since 01/01/0000.
81 static const uint64_t BTSNOOP_EPOCH_DELTA = 0x00dcddb30f2f8000ULL;
82
83 // Number of bytes into a packet where you can find the value for a channel.
84 static const size_t ACL_CHANNEL_OFFSET = 0;
85 static const size_t L2C_CHANNEL_OFFSET = 6;
86 static const size_t RFC_CHANNEL_OFFSET = 8;
87 static const size_t RFC_EVENT_OFFSET = 9;
88
89 // The size of the L2CAP header. All information past this point is removed from
90 // a filtered packet.
91 static const uint32_t L2C_HEADER_SIZE = 9;
92
93 static int logfile_fd = INVALID_FD;
94 static std::mutex btsnoop_mutex;
95
96 static int32_t packets_per_file;
97 static int32_t packet_counter;
98
99 // Channel tracking variables for filtering.
100
101 // Keeps track of L2CAP channels that need to be filtered out of the snoop
102 // logs.
103 class FilterTracker {
104  public:
105   // NOTE: 1 is used as a static CID for L2CAP signaling
106   std::unordered_set<uint16_t> l2c_local_cid = {1};
107   std::unordered_set<uint16_t> l2c_remote_cid = {1};
108   uint16_t rfc_local_cid = 0;
109   uint16_t rfc_remote_cid = 0;
110   std::unordered_set<uint16_t> rfc_channels = {0};
111
112   // Adds L2C channel to whitelist.
113   void addL2cCid(uint16_t local_cid, uint16_t remote_cid) {
114     l2c_local_cid.insert(local_cid);
115     l2c_remote_cid.insert(remote_cid);
116   }
117
118   // Sets L2CAP channel that RFCOMM uses.
119   void setRfcCid(uint16_t local_cid, uint16_t remote_cid) {
120     rfc_local_cid = local_cid;
121     rfc_remote_cid = remote_cid;
122   }
123
124   // Remove L2C channel from whitelist.
125   void removeL2cCid(uint16_t local_cid, uint16_t remote_cid) {
126     if (rfc_local_cid == local_cid) {
127       rfc_channels.clear();
128       rfc_channels.insert(0);
129       rfc_local_cid = 0;
130       rfc_remote_cid = 0;
131     }
132
133     l2c_local_cid.erase(local_cid);
134     l2c_remote_cid.erase(remote_cid);
135   }
136
137   void addRfcDlci(uint8_t channel) { rfc_channels.insert(channel); }
138
139   bool isWhitelistedL2c(bool local, uint16_t cid) {
140     const auto& set = local ? l2c_local_cid : l2c_remote_cid;
141     return (set.find(cid) != set.end());
142   }
143
144   bool isRfcChannel(bool local, uint16_t cid) {
145     const auto& channel = local ? rfc_local_cid : rfc_remote_cid;
146     return cid == channel;
147   }
148
149   bool isWhitelistedDlci(uint8_t dlci) {
150     return rfc_channels.find(dlci) != rfc_channels.end();
151   }
152 };
153
154 std::mutex filter_list_mutex;
155 std::unordered_map<uint16_t, FilterTracker> filter_list;
156 std::unordered_map<uint16_t, uint16_t> local_cid_to_acl;
157
158 // Cached value for whether full snoop logs are enabled. So the property isn't
159 // checked for every packet.
160 static bool is_btsnoop_enabled;
161 static bool is_btsnoop_filtered;
162
163 // TODO(zachoverflow): merge btsnoop and btsnoop_net together
164 void btsnoop_net_open();
165 void btsnoop_net_close();
166 void btsnoop_net_write(const void* data, size_t length);
167
168 static void delete_btsnoop_files(bool filtered);
169 static std::string get_btsnoop_log_path(bool filtered);
170 static std::string get_btsnoop_last_log_path(std::string log_path);
171 static void open_next_snoop_file();
172 static void btsnoop_write_packet(packet_type_t type, uint8_t* packet,
173                                  bool is_received, uint64_t timestamp_us);
174
175 // Module lifecycle functions
176
177 static future_t* start_up() {
178   std::array<char, PROPERTY_VALUE_MAX> property = {};
179   std::lock_guard<std::mutex> lock(btsnoop_mutex);
180
181   // Default mode is FILTERED on userdebug/eng build, DISABLED on user build.
182   // It can also be overwritten by modifying the global setting.
183   int is_debuggable = osi_property_get_int32(IS_DEBUGGABLE_PROPERTY, 0);
184   std::string default_mode = BTSNOOP_MODE_DISABLED;
185   if (is_debuggable) {
186     int len = osi_property_get(BTSNOOP_DEFAULT_MODE_PROPERTY, property.data(),
187                                BTSNOOP_MODE_DISABLED);
188     default_mode = std::string(property.data(), len);
189   }
190
191   // Get the actual mode
192   int len = osi_property_get(BTSNOOP_LOG_MODE_PROPERTY, property.data(),
193                              default_mode.c_str());
194   std::string btsnoop_mode(property.data(), len);
195
196   if (btsnoop_mode == BTSNOOP_MODE_FILTERED) {
197     LOG(INFO) << __func__ << ": Filtered Snoop Logs enabled";
198     is_btsnoop_enabled = true;
199     is_btsnoop_filtered = true;
200     delete_btsnoop_files(false);
201   } else if (btsnoop_mode == BTSNOOP_MODE_FULL) {
202     LOG(INFO) << __func__ << ": Snoop Logs fully enabled";
203     is_btsnoop_enabled = true;
204     is_btsnoop_filtered = false;
205     delete_btsnoop_files(true);
206   } else {
207     LOG(INFO) << __func__ << ": Snoop Logs disabled";
208     is_btsnoop_enabled = false;
209     is_btsnoop_filtered = false;
210     delete_btsnoop_files(true);
211     delete_btsnoop_files(false);
212   }
213
214   if (is_btsnoop_enabled) {
215     open_next_snoop_file();
216     packets_per_file = osi_property_get_int32(BTSNOOP_MAX_PACKETS_PROPERTY,
217                                               DEFAULT_BTSNOOP_SIZE);
218     btsnoop_net_open();
219   }
220
221   return NULL;
222 }
223
224 static future_t* shut_down(void) {
225   std::lock_guard<std::mutex> lock(btsnoop_mutex);
226
227   if (is_btsnoop_enabled) {
228     if (is_btsnoop_filtered) {
229       delete_btsnoop_files(false);
230     } else {
231       delete_btsnoop_files(true);
232     }
233   } else {
234     delete_btsnoop_files(true);
235     delete_btsnoop_files(false);
236   }
237
238   if (logfile_fd != INVALID_FD) close(logfile_fd);
239   logfile_fd = INVALID_FD;
240
241   if (is_btsnoop_enabled) btsnoop_net_close();
242
243   return NULL;
244 }
245
246 EXPORT_SYMBOL extern const module_t btsnoop_module = {
247     .name = BTSNOOP_MODULE,
248     .init = NULL,
249     .start_up = start_up,
250     .shut_down = shut_down,
251     .clean_up = NULL,
252     .dependencies = {STACK_CONFIG_MODULE, NULL}};
253
254 // Interface functions
255 static void capture(const BT_HDR* buffer, bool is_received) {
256   uint8_t* p = const_cast<uint8_t*>(buffer->data + buffer->offset);
257
258   std::lock_guard<std::mutex> lock(btsnoop_mutex);
259
260   struct timespec ts_now = {};
261   clock_gettime(CLOCK_REALTIME, &ts_now);
262   uint64_t timestamp_us =
263       ((uint64_t)ts_now.tv_sec * 1000000L) + ((uint64_t)ts_now.tv_nsec / 1000);
264
265   btsnoop_mem_capture(buffer, timestamp_us);
266
267   if (logfile_fd == INVALID_FD) return;
268
269   switch (buffer->event & MSG_EVT_MASK) {
270     case MSG_HC_TO_STACK_HCI_EVT:
271       btsnoop_write_packet(kEventPacket, p, false, timestamp_us);
272       break;
273     case MSG_HC_TO_STACK_HCI_ACL:
274     case MSG_STACK_TO_HC_HCI_ACL:
275       btsnoop_write_packet(kAclPacket, p, is_received, timestamp_us);
276       break;
277     case MSG_HC_TO_STACK_HCI_SCO:
278     case MSG_STACK_TO_HC_HCI_SCO:
279       btsnoop_write_packet(kScoPacket, p, is_received, timestamp_us);
280       break;
281     case MSG_STACK_TO_HC_HCI_CMD:
282       btsnoop_write_packet(kCommandPacket, p, true, timestamp_us);
283       break;
284   }
285 }
286
287 static void whitelist_l2c_channel(uint16_t conn_handle, uint16_t local_cid,
288                                   uint16_t remote_cid) {
289   LOG(INFO) << __func__
290             << ": Whitelisting l2cap channel. conn_handle=" << conn_handle
291             << " cid=" << loghex(local_cid) << ":" << loghex(remote_cid);
292   std::lock_guard lock(filter_list_mutex);
293
294   // This will create the entry if there is no associated filter with the
295   // connection.
296   filter_list[conn_handle].addL2cCid(local_cid, remote_cid);
297 }
298
299 static void whitelist_rfc_dlci(uint16_t local_cid, uint8_t dlci) {
300   LOG(INFO) << __func__
301             << ": Whitelisting rfcomm channel. L2CAP CID=" << loghex(local_cid)
302             << " DLCI=" << loghex(dlci);
303   std::lock_guard lock(filter_list_mutex);
304
305   tL2C_CCB* p_ccb = l2cu_find_ccb_by_cid(nullptr, local_cid);
306   filter_list[p_ccb->p_lcb->handle].addRfcDlci(dlci);
307 }
308
309 static void add_rfc_l2c_channel(uint16_t conn_handle, uint16_t local_cid,
310                                 uint16_t remote_cid) {
311   LOG(INFO) << __func__
312             << ": rfcomm data going over l2cap channel. conn_handle="
313             << conn_handle << " cid=" << loghex(local_cid) << ":"
314             << loghex(remote_cid);
315   std::lock_guard lock(filter_list_mutex);
316
317   filter_list[conn_handle].setRfcCid(local_cid, remote_cid);
318   local_cid_to_acl.insert({local_cid, conn_handle});
319 }
320
321 static void clear_l2cap_whitelist(uint16_t conn_handle, uint16_t local_cid,
322                                   uint16_t remote_cid) {
323   LOG(INFO) << __func__
324             << ": Clearing whitelist from l2cap channel. conn_handle="
325             << conn_handle << " cid=" << local_cid << ":" << remote_cid;
326
327   std::lock_guard lock(filter_list_mutex);
328   filter_list[conn_handle].removeL2cCid(local_cid, remote_cid);
329 }
330
331 static const btsnoop_t interface = {capture, whitelist_l2c_channel,
332                                     whitelist_rfc_dlci, add_rfc_l2c_channel,
333                                     clear_l2cap_whitelist};
334
335 const btsnoop_t* btsnoop_get_interface() { return &interface; }
336
337 static void delete_btsnoop_files(bool filtered) {
338   LOG(INFO) << __func__
339             << ": Deleting snoop logs if they exist. filtered = " << filtered;
340   auto log_path = get_btsnoop_log_path(filtered);
341   remove(log_path.c_str());
342   remove(get_btsnoop_last_log_path(log_path).c_str());
343 }
344
345 std::string get_btsnoop_log_path(bool filtered) {
346   char btsnoop_path[PROPERTY_VALUE_MAX];
347   osi_property_get(BTSNOOP_PATH_PROPERTY, btsnoop_path, DEFAULT_BTSNOOP_PATH);
348   std::string result(btsnoop_path);
349   if (filtered) result = result.append(".filtered");
350
351   return result;
352 }
353
354 std::string get_btsnoop_last_log_path(std::string btsnoop_path) {
355   return btsnoop_path.append(".last");
356 }
357
358 static void open_next_snoop_file() {
359   packet_counter = 0;
360
361   if (logfile_fd != INVALID_FD) {
362     close(logfile_fd);
363     logfile_fd = INVALID_FD;
364   }
365
366   auto log_path = get_btsnoop_log_path(is_btsnoop_filtered);
367   auto last_log_path = get_btsnoop_last_log_path(log_path);
368
369   if (rename(log_path.c_str(), last_log_path.c_str()) != 0 && errno != ENOENT)
370     LOG(ERROR) << __func__ << ": unable to rename '" << log_path << "' to '"
371                << last_log_path << "' : " << strerror(errno);
372
373   mode_t prevmask = umask(0);
374   logfile_fd = open(log_path.c_str(), O_WRONLY | O_CREAT | O_TRUNC,
375                     S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH);
376   umask(prevmask);
377   if (logfile_fd == INVALID_FD) {
378     LOG(ERROR) << __func__ << ": unable to open '" << log_path
379                << "' : " << strerror(errno);
380     return;
381   }
382
383   write(logfile_fd, "btsnoop\0\0\0\0\1\0\0\x3\xea", 16);
384 }
385
386 typedef struct {
387   uint32_t length_original;
388   uint32_t length_captured;
389   uint32_t flags;
390   uint32_t dropped_packets;
391   uint64_t timestamp;
392   uint8_t type;
393 } __attribute__((__packed__)) btsnoop_header_t;
394
395 static uint64_t htonll(uint64_t ll) {
396   const uint32_t l = 1;
397   if (*(reinterpret_cast<const uint8_t*>(&l)) == 1)
398     return static_cast<uint64_t>(htonl(ll & 0xffffffff)) << 32 |
399            htonl(ll >> 32);
400
401   return ll;
402 }
403
404 static bool should_filter_log(bool is_received, uint8_t* packet) {
405   uint16_t acl_handle =
406       HCID_GET_HANDLE((((uint16_t)packet[ACL_CHANNEL_OFFSET + 1]) << 8) +
407                       packet[ACL_CHANNEL_OFFSET]);
408
409   std::lock_guard lock(filter_list_mutex);
410   auto& filters = filter_list[acl_handle];
411   uint16_t l2c_channel =
412       (packet[L2C_CHANNEL_OFFSET + 1] << 8) + packet[L2C_CHANNEL_OFFSET];
413   if (filters.isRfcChannel(is_received, l2c_channel)) {
414     uint8_t rfc_event = packet[RFC_EVENT_OFFSET] & 0b11101111;
415     if (rfc_event == RFCOMM_SABME || rfc_event == RFCOMM_UA) {
416       return false;
417     }
418
419     uint8_t rfc_dlci = packet[RFC_CHANNEL_OFFSET] >> 2;
420     if (!filters.isWhitelistedDlci(rfc_dlci)) {
421       return true;
422     }
423   } else if (!filters.isWhitelistedL2c(is_received, l2c_channel)) {
424     return true;
425   }
426
427   return false;
428 }
429
430 static void btsnoop_write_packet(packet_type_t type, uint8_t* packet,
431                                  bool is_received, uint64_t timestamp_us) {
432   uint32_t length_he = 0;
433   uint32_t flags = 0;
434
435   switch (type) {
436     case kCommandPacket:
437       length_he = packet[2] + 4;
438       flags = 2;
439       break;
440     case kAclPacket:
441       length_he = (packet[3] << 8) + packet[2] + 5;
442       flags = is_received;
443       break;
444     case kScoPacket:
445       length_he = packet[2] + 4;
446       flags = is_received;
447       break;
448     case kEventPacket:
449       length_he = packet[1] + 3;
450       flags = 3;
451       break;
452   }
453
454   btsnoop_header_t header;
455   header.length_original = htonl(length_he);
456
457   bool blacklisted = false;
458   if (is_btsnoop_filtered && type == kAclPacket) {
459     blacklisted = should_filter_log(is_received, packet);
460   }
461
462   header.length_captured =
463       blacklisted ? htonl(L2C_HEADER_SIZE) : header.length_original;
464   if (blacklisted) length_he = L2C_HEADER_SIZE;
465   header.flags = htonl(flags);
466   header.dropped_packets = 0;
467   header.timestamp = htonll(timestamp_us + BTSNOOP_EPOCH_DELTA);
468   header.type = type;
469
470   btsnoop_net_write(&header, sizeof(btsnoop_header_t));
471   btsnoop_net_write(packet, length_he - 1);
472
473   if (logfile_fd != INVALID_FD) {
474     packet_counter++;
475     if (packet_counter > packets_per_file) {
476       open_next_snoop_file();
477     }
478
479     iovec iov[] = {{&header, sizeof(btsnoop_header_t)},
480                    {reinterpret_cast<void*>(packet), length_he - 1}};
481     TEMP_FAILURE_RETRY(writev(logfile_fd, iov, 2));
482   }
483 }