beagle 480 抓包数据转成pcap文件

使用beagle 480抓到的usb ncm数据直接分析比较困难, 这里将beagle 480抓到的包导出成csv文件(注意要勾选data数据栏) 下面脚本将每包ncm数据,去掉nth16头和ndp头,然后将同一包ncm数据里的所有ndp entry 提取出来,合并到一起,然后形成一个以太帧 最后将所有以太帧一起写到pcap文件,再用wireshark打开

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import re
from construct import *
from csv import reader
import scapy.all as scapy

def ncm_extract_payload(data):
    payload = bytearray()
    nth_format = Struct(
        "magic" / Bytes(4),
        "header_length" / Int16ul,
        "seq" / Int16ul,
        "block_length" / Int16ul,
        "fp_index" / Int16ul,
    )
    
    ndp_format = Struct(
        "magic" / Bytes(4),
        "length" / Int16ul,
        "next_ndp_index" / Int16ul
    )
    
    entry_format = Struct(
        "index" / Int16ul,
        "length" / Int16ul
    )
    
    nth16 = nth_format.parse(data)
    offset = nth16.fp_index
    if len(data) == 116:
        print('====> %d' % offset)
    
    while True:
        ndp16 = ndp_format.parse(data[offset:])
        num_entries = int((ndp16.length - 8) / 4)
        offset += 8
        for i in range(0, num_entries):
            entry = entry_format.parse(data[offset:])
            offset += 4
            if entry.length > 0 and entry.index > 0:
                payload += data[entry.index: entry.index + entry.length]
        
        offset = ndp16.next_ndp_index
        if offset == 0:
            break
    
    print('%d %d %d' % (len(data), len(payload), num_entries))
    return payload
    
    
def parse_ts(str):
    m = re.match(r'(\d+):(\d+)\.(\d+)\.(\d+)', str)
    if m == None:
        return 0
    
    groups = m.groups()
    if len(groups) != 4:
        return 0
    
    return round(float(groups[0]) * 60 + float(groups[1]) + \
        float(groups[2]) / 1000.0 + float(groups[3]) / 1000000.0, 6)
        
packets = []

count = 0
with open('out.csv', 'r') as fp:
    csvr = reader(fp)
    for row in csvr:
        if row[0][0] == '#':
            continue
        err = row[6]
        if err != '':
            continue
        dev = row[7]
        if dev != '02':
            continue
            
        ep = row[8]
        if ep == '02' or ep == '02':
            data = row[10]
            ts = parse_ts(row[3])
            data = bytes.fromhex(data.strip())
            if len(data) == 0:
                continue
            payload = ncm_extract_payload(data)
            packets.append(scapy.Ether(payload))
            #count += 1
            #if count == 10:
            #    break

scapy.wrpcap("output.pcap", packets)