您的位置:

使用Wireshark监控USB通信流量:全面分析USB设备通信

一、Wireshark是什么

Wireshark是一款流行的网络协议分析工具,它能够捕获网络数据包并对数据包进行深入分析。Wireshark最早是一个开源软件项目Ethereal,后来改名为Wireshark,并在全球得到广泛应用。它能够解析众多的网络协议,帮助用户分析出网络流量中的各项指标,洞悉网络传输的详细过程。

二、Wireshark能够监控USB通信流量吗

Wireshark最初是一个局限于网络协议的分析工具,但随着其功能的逐步完善,早已可以监控USB通信流量并对USB设备的通讯进行全面分析。为了实现监控USB通信流量,Wireshark提供了一种USB协议分析方法:

  1. 建立USB数据包捕获环境
  2. 进行USB通信流量捕获
  3. 对捕获到的USB数据包进行解码和分析

通过这种方法,Wireshark可以抓取USB数据包并对USB设备的通讯流程进行深入分析,从而帮助用户找出USB设备通讯中的瓶颈,解决问题。

三、建立USB数据包捕获环境

在进行USB通信流量的捕获前,首先需要建立一个合适的USB数据包捕获环境。具体的步骤如下:

  1. 在Wireshark主界面中,单击捕获选项卡
  2. 在界面中选取网络适配器
  3. 选中“usbmon”适配器
  4. 点击“Start”按钮,开始USB数据包的捕获和监控
如下代码片段即为建立USB数据包捕获环境的详细过程:

1. //在Wireshark主界面中,单击捕获选项卡
2. Capture -> Options -> 网络适配器
3. 选中USBmon适配器
4. 点击Start按钮,开始USB数据包的捕获和监控

四、捕获USB通信流量

USB设备的通讯一般是通过USB控制传输(ep0)和USB批量传输(bulk)管道来实现的。因此,要抓取USB通讯流量,需要对这两个管道的数据进行打包捕获。具体步骤如下:

  1. 在Wireshark主界面中单击捕获选项卡
  2. 选择“usbmon”适配器
  3. 在“Capture Filter”栏目中输入过滤条件“usb.transfer_type==0x03 || usb.transfer_type==0x02”(过滤批量传输和控制传输数据包)
  4. 单击“Start”按钮开始捕获USB通讯流量
如下代码片段即为捕获USB通讯流量的详细过程:

1. //在Wireshark主界面中单击捕获选项卡
2. Capture -> Options -> 选择“usbmon”适配器
3. 在“Capture Filter”栏目中输入过滤条件“usb.transfer_type==0x03 || usb.transfer_type==0x02”(过滤批量传输和控制传输数据包)
4. 单击“Start”按钮开始捕获USB通讯流量

五、对捕获到的USB数据包进行解码和分析

在对USB通讯流量进行捕获后,Wireshark会将捕获到的USB数据包进行解码和分析。为了更好地进行USB通讯流量的分析,Wireshark会对捕获到的USB数据包进行解包,得到如下几个要素:

  1. Endpoint(端点):USB设备中应用程序与主机之间建立的通讯通道
  2. Transfer Type(传输类型):指数据包在USB物理层的传输方式(批量传输、控制传输、中断传输、异步传输)
  3. Direction(传输方向):指USB通讯流量的方向(host->device or device->host)
  4. Data Length(数据长度):指USB数据包中的数据长度
  5. Data(数据):指USB数据包中的数据载荷

根据这些要素,Wireshark可以清晰地呈现USB设备通讯的全过程,从而进一步帮助用户分析出USB设备的工作流程,找出通讯瓶颈。

六、代码示例

#include 
#include 
   
#include 
    
#include 
     
#include 
      
#include 
       
        #include 
        
         #include 
         
          #define MAXBYTES2CAPTURE 2048 int main() { int i, c_amt; struct pcap_pkthdr *header; const unsigned char *pkt_data; char errbuf[PCAP_ERRBUF_SIZE]; pcap_t *handle; bpf_u_int32 mask; /* Our netmask */ bpf_u_int32 net; /* Our IP */ struct bpf_program filter; char filter_app[] = "usb.transfer_type==0x03 || usb.transfer_type==0x02"; /* Open the session in non-promiscuous mode */ handle = pcap_open_live("usbmon1", MAXBYTES2CAPTURE, 0, 512, errbuf); if (handle == NULL) { printf("pcap_open_live error: %s\n", errbuf); exit(1); } /* Compile and apply the filter */ if (pcap_lookupnet("usbmon1", &net, &mask, errbuf) == -1) { printf("pcap_lookupnet error: %s\n", errbuf); exit(1); } if (pcap_compile(handle, &filter, filter_app, 0, net) == -1) { printf("pcap_compile error: %s\n", pcap_geterr(handle)); exit(1); } if (pcap_setfilter(handle, &filter) == -1) { printf("pcap_setfilter error: %s\n", pcap_geterr(handle)); exit(1); } printf("start capturing USB transfer packets...\n"); /* Keep capturing USB packets */ for (c_amt = 0; c_amt < 20; c_amt++) { if (pcap_next_ex(handle, &header, &pkt_data) == 1) { printf("Packet #%d\n", c_amt); /* Print the USB data */ printf("len:%d, ", header->len); printf("data:"); for (i = 0; i < header->len; i++) { printf("%02x", *(pkt_data+i)); if ((i+1) % 16 == 0) { printf("\n "); } else if ((i+1) % 8 == 0) { printf(" "); } else if ((i+1) % 4 == 0) { printf(" "); } } printf("\n\n"); } } /* Close the session */ pcap_close(handle); return 0; }