BTSnoop File Format

BTSnoop File Format

Overview

The BTSnoop file format is suitable for storing Bluetooth® HCI traffic. It closely resembles the snoop format, as documented in RFC 1761.

File Format

The snoop packet capture file is an array of octets structured as follows:

The File Header is a fixed-length field containing general information about the packet file and the format of the packet records it contains. One or more variable-length Packet Record fields follow the File Header field. Each Packet Record field holds the data of one captured packet.

File Header

The structure of the File Header is as follows:

Identification Pattern:

A 64-bit (8 octet) pattern used to identify the file as a snoop packet capture file. The Identification Pattern consists of the 8 hexadecimal octets:

62 74 73 6E 6F 6F 70 00

This is the ASCII string "btsnoop" followed by one null octets.

Version Number:

A 32-bit (4 octet) unsigned integer value representing the version of the packet capture file being used. This document describes version number 1.

Datalink Type:

A 32-bit (4 octet) field identifying the type of datalink header used in the packet records that follow. The datalink type codes are listed in the table below. Values 0 - 1000 are reserved, to maximize compatibility with the RFC1761 snoop version 2 format.

Datalink Codes
Datalink TypeCode
Reserved0 - 1000
Un-encapsulated HCI (H1)1001
HCI UART (H4)1002
HCI BSCP1003
HCI Serial (H5)1004
Unassigned1005 - 4294967295

Packet Record Format

Each packet record holds a partial or complete copy of one packet as well as some descriptive information about that packet. The packet may be truncated in order to limit the amount of data to be stored in the packet file.

Each packet record holds 24 octets of descriptive information about the packet, followed by the packet data, which is variable-length, and an optional pad field. The descriptive information is structured as six 32-bit (4-octet) integer values.

The structure of the packet record is as follows:

Original Length

A 32-bit unsigned integer representing the length in octets of the captured packet as received via a network.

Included Length

A 32-bit unsigned integer representing the length of the Packet Data field. This is the number of octets of the captured packet that are included in this packet record. If the received packet was truncated, the Included Length field is less than the Original Length field.

Packet Flags

Flags specific to this packet. Currently the following flags are defined:

Packet Flag Description
Bit No.Definition
0Direction flag 0 = Sent, 1 = Received
1Command flag 0 = Data, 1 = Command/Event
2 - 31Reserved

Bit 0 is the least significant bit of the 32-bit word.

Direction is relative to host / DTE. i.e. for Bluetooth controllers, Send is Host->Controller, Receive is Controller->Host.

Note: Some Datalink Types already encode some or all of this information within the Packet Data. With these Datalink Types, these flags should be treated as informational only, and the value in the Packet Data should take precedence.

Cumulative Drops

A 32-bit unsigned integer representing the number of packets that were lost by the system that created the packet file between the first packet record in the file and this one. Packets may be lost because of insufficient resources in the capturing system, or for other reasons.

Note: some implementations lack the ability to count dropped packets. Those implementations may set the cumulative drops value to zero.

Timestamp Microseconds

A 64-bit signed integer representing the time of packet arrival, in microseconds since midnight, January 1st, 0 AD nominal Gregorian.

In order to avoid leap-day ambiguity in calculations, note that an equivalent epoch may be used of midnight, January 1st 2000 AD, which is represented in this field as 0x00E03AB44A676000.

从公元元年1月1日到公元1970年1月1日的微妙数为:0x00DCDDB30F2F8000

Packet Data

Variable-length field holding the packet that was captured, beginning with its datalink header. The Datalink Type field of the file header can be used to determine how to decode the datalink header. The length of the Packet Data field is given in the Included Length field.

Note that the length of this field in not necessarily rounded to any particular multi-octet boundary, as might otherwise be suggested by the diagram.

Data Format

All integer values are stored in "big-endian" order, with the high-order bits first.

使用python解析BTSnoop文件:

import os
import struct
import datetime

LOG_FILE_EXTENSION = ".cfaa"

btsnoop_flag = [0x62, 0x74, 0x73, 0x6E, 0x6F, 0x6F, 0x70, 00]

def parse_packet_data(packet_data):
    pass

def parse_btsnoop_file(root, file):
    file_name = os.path.join(root, file)
    print("file_name:", file_name)
    file_ob = open(file_name, 'rb')
    file_data = file_ob.read()
    print("type(file_data):", type(file_data))
    file_len = len(file_data)
    print("file_len:", file_len)

    offset = 0

    header_len = 8 + 4 + 4
    offset += header_len

    while offset < file_len:

        # 以大端的形式读取4个字节
        origin_length = struct.unpack('>I', file_data[offset: offset + 4])[0]
        offset += 4

        included_length = struct.unpack('>I', file_data[offset: offset + 4])[0]
        offset += 4

        packet_flags = struct.unpack('>I', file_data[offset: offset + 4])[0]
        offset += 4

        cumulative_drops = struct.unpack('>I', file_data[offset: offset + 4])[0]
        offset += 4

        # 以大端形式读取8个字节
        timestamp_us = struct.unpack('>Q', file_data[offset: offset + 8])[0]
        offset += 8

        unix_timpstamp_us = timestamp_us - 0x00DCDDB30F2F8000
        unix_seconds = unix_timpstamp_us // 1000000
        microseconds_remainder = unix_timpstamp_us % 1000000
        # 将时间戳转换为UTC时间
        utc_time = datetime.datetime.utcfromtimestamp(unix_seconds)

        # 将UTC时间转换为本地时间
        local_time = utc_time.replace(tzinfo=datetime.timezone.utc).astimezone(tz=None)
        print(local_time.strftime("%Y-%m-%d %H:%M:%S") + ' ' + str(int(microseconds_remainder / 1000)))

        offset += origin_length


    file_ob.close()

if __name__ == '__main__':
    print("Program Start")

    for root, dirs, files in os.walk(".", topdown=False):
        # print("root:{}, dirs:{}, files:{}".format(root, dirs, files))
        for file in files:
            if file.endswith(LOG_FILE_EXTENSION):
                parse_btsnoop_file(root, file)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值