9

Я пытаюсь выполнить обратное проектирование устройства usb (HID) и не могу понять, как то, что я вижу на wireshark (usbmon + wireshark на Linux или Windows), связано с протоколом usb ?. Я посмотрел протокол USB от www.usb.org.

Что показывает wireshark?

1) Одна строка на пакет? (токен, данные, рукопожатие)

2) Одна строка на транзакцию? (токен + [данные] + рукопожатие) (мое предположение)

3) Одна строка на контрольную передачу?

Направление сделки также очень странное (в / из полей). По крайней мере, это не соответствует моим ожиданиям :-) ... И часть данных перечисления, скрытого отчета и т.д. ... иногда отображается с установочными данными (8 байт), а иногда нет ... Я действительно не знаю, что такое URB ... в протоколе usb нет упоминаний об этом, насколько я мог видеть ... Мне кажется, что wireshark / usbmon отслеживает на более высоком уровне стека и пытается определить, что будет на проводе из этого ...

Пример того, что я вижу, приведен ниже, что нам здесь увидеть?

а) Я не мог даже найти bmtype = 0x20 (из установки, кадр № = 599) в спецификации.

б) Поскольку у меня есть устройство HID, я предположил, что это может быть конфигурация отчета / функции (перечисление передается на данном этапе). Поэтому я мог согласиться с направлением (хост-> устройство). а где данные? Или здесь нет фазы данных? Что такое кадр 600?

в) что такое кадр 600? данные?

г) что такое кадр 601? ACK статуса? ... но тогда данные и ACK имеют один и тот же источник?

No.     Time        Source                Destination           Protocol Length Info
    599 67.996889   host                  2.0                   USB      36     URB_CONTROL out

Frame 599: 36 bytes on wire (288 bits), 36 bytes captured (288 bits)
USB URB
    USBPcap pseudoheader length: 28
    IRP ID: 0xfffffa800a1e2610
    IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000)
    URB Function: URB_FUNCTION_CLASS_DEVICE (0x001a)
    IRP information: 0x00, Direction: FDO -> PDO
    URB bus id: 1
    Device address: 2
    Endpoint: 0x00, Direction: OUT
    URB transfer type: URB_CONTROL (0x02)
    Packet Data Length: 8
    Control transfer stage: Setup (0)
    [Response in: 601]
    [bInterfaceClass: Unknown (0xffff)]
URB setup
    bmRequestType: 0x20
        0... .... = Direction: Host-to-device
        .01. .... = Type: Class (0x01)
        ...0 0000 = Recipient: Device (0x00)
    bRequest: 0
    wValue: 0x0000
    wIndex: 0
    wLength: 16

0000  1c 00 10 26 1e 0a 80 fa ff ff 00 00 00 00 1a 00   ...&............
0010  00 01 00 02 00 00 02 08 00 00 00 00 20 00 00 00   ............ ...
0020  00 00 10 00                                       ....

No.     Time        Source                Destination           Protocol Length Info
    600 67.997889   2.0                   host                  USB      44     URB_CONTROL out

Frame 600: 44 bytes on wire (352 bits), 44 bytes captured (352 bits)
USB URB
    USBPcap pseudoheader length: 28
    IRP ID: 0xfffffa800a1e2610
    IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000)
    URB Function: URB_FUNCTION_CONTROL_TRANSFER (0x0008)
    IRP information: 0x01, Direction: PDO -> FDO
    URB bus id: 1
    Device address: 2
    Endpoint: 0x00, Direction: OUT
    URB transfer type: URB_CONTROL (0x02)
    Packet Data Length: 16
    Control transfer stage: Data (1)
    [Request in: 599]
    [Time from request: 0.001000000 seconds]
    [bInterfaceClass: Unknown (0xffff)]
CONTROL response data

0000  1c 00 10 26 1e 0a 80 fa ff ff 00 00 00 00 08 00   ...&............
0010  01 01 00 02 00 00 02 10 00 00 00 01 05 04 0d 56   ...............V
0020  fb 82 c0 1d 10 18 cc 02 00 00 00 01               ............

No.     Time        Source                Destination           Protocol Length Info
    601 67.997889   2.0                   host                  USB      28     GET STATUS Status

Frame 601: 28 bytes on wire (224 bits), 28 bytes captured (224 bits)
USB URB
    USBPcap pseudoheader length: 28
    IRP ID: 0xfffffa800a1e2610
    IRP USBD_STATUS: USBD_STATUS_SUCCESS (0x00000000)
    URB Function: URB_FUNCTION_CONTROL_TRANSFER (0x0008)
    IRP information: 0x01, Direction: PDO -> FDO
    URB bus id: 1
    Device address: 2
    Endpoint: 0x00, Direction: OUT
    URB transfer type: URB_CONTROL (0x02)
    Packet Data Length: 0
    Control transfer stage: Status (2)
    [Request in: 599]
    [Time from request: 0.001000000 seconds]

0000  1c 00 10 26 1e 0a 80 fa ff ff 00 00 00 00 08 00   ...&............
0010  01 01 00 02 00 00 02 00 00 00 00 02               ............

Очевидно, я что-то упустил. Общее объяснение того, как отображение wireshark относится к протоколу и (на его основе), значение вышеупомянутого следа приветствуется!

Первоначально я разместил это в Stack Overflow, но мне сказали, что это не был напрямую вопрос программирования. Надеюсь, это подходит лучше здесь.

2 ответа2

10

USB URB - это как IP-пакет, а конечная точка USB - как IP-порт. Конечные точки USB 0x00-0x7F находятся на хосте, а конечные точки 0x80-0xFF находятся на устройстве (я думаю). Следовательно, конечная точка кодирует направление передачи. lsusb покажет вам, какие конечные точки и какие типы передачи поддерживает устройство.

Я буду использовать "пакеты" в кавычках, чтобы обозначить единицу активности, которую захватывает wireshark. Это не буквально то, что посылают по проводам. Например, "пакеты" будут иметь временные метки, когда начались передачи, даже если они не передаются по шине USB.

Я думаю, что наиболее запутанным аспектом перехвата протокола USB является то, что вы видите два "пакета" Wireshark для каждого USB URB. Когда хост инициирует некоторую передачу, это URB_SUBMIT (фильтр отображения Wireshark usb.urb_type == URB_SUBMIT). Когда передача завершается, это URB_COMPLETE (фильтр отображения Wireshark usb.urb_type == URB_COMPLETE)

Из того, что я могу сказать, когда есть передача от хоста к устройству, "пакет" SUBMIT содержит фактические данные USB, переданные. Когда происходит передача с устройства на хост (инициируемая хостом, как всегда), COMPLETE "пакет" содержит фактические передаваемые данные USB.

С точки зрения анализа протокола, все остальные "пакеты" отвлекают ИЛИ ошибку URB. Чтобы отфильтровать отвлечения, я использую следующий фильтр отображения !(usb.urb_type == URB_SUBMIT && usb.endpoint_number.direction == IN) && !(usb.urb_type == URB_COMPLETE && usb.endpoint_number.direction == OUT)

Я полагаю, что протокол USB включает в себя некоторые рукопожатия, ACK и повторные передачи, но все это обрабатывается хост-контроллером, и ОС не задействована. Я не думаю, например, что ОС отслеживает подтверждения или повторные передачи.

Кстати, я использую следующую команду для анализа протокола. В дополнение к выполнению фильтрации выше, он отображает только номер конечной точки (в десятичной форме) и данные USB. Это на машине GNU/Linux, использующей устройство usbmon1 для прослушивания и предполагающей, что USB-устройство, которое я хочу отслеживать, находится на шине 1 и имеет адрес 11.

tshark -i usbmon1 -Y "usb.device_address == 11 && !(usb.urb_type == URB_SUBMIT && usb.endpoint_number.direction == IN) && !(usb.urb_type == URB_COMPLETE && usb.endpoint_number.direction == OUT)" -Tfields -e usb.endpoint_number -e usb.capdata

3

Журналы WireShark USB сделаны на уровне операционной системы. В Linux он основан на данных, которые генерирует usbmon, который основан на внутренней структуре URB Linux, описанной здесь. Таким образом, просмотр комментариев и документов ядра и WireShark позволяет лучше понять, что это такое.

Из документации по ядру я обнаружил, что пакеты представляют собой структуры usbmon, за которыми следуют отправленные и полученные данные. Это структура (скопированная отсюда):

struct usbmon_packet {
    u64 id;         /*  0: URB ID - from submission to callback */
    unsigned char type; /*  8: Same as text; extensible. */
    unsigned char xfer_type; /*    ISO (0), Intr, Control, Bulk (3) */
    unsigned char epnum;    /*     Endpoint number and transfer direction */
    unsigned char devnum;   /*     Device address */
    u16 busnum;     /* 12: Bus number */
    char flag_setup;    /* 14: Same as text */
    char flag_data;     /* 15: Same as text; Binary zero is OK. */
    s64 ts_sec;     /* 16: gettimeofday */
    s32 ts_usec;        /* 24: gettimeofday */
    int status;     /* 28: */
    unsigned int length;    /* 32: Length of data (submitted or actual) */
    unsigned int len_cap;   /* 36: Delivered length */
    union {         /* 40: */
        unsigned char setup[SETUP_LEN]; /* Only for Control S-type */
        struct iso_rec {        /* Only for ISO */
            int error_count;
            int numdesc;
        } iso;
    } s;
    int interval;       /* 48: Only for Interrupt and ISO */
    int start_frame;    /* 52: For ISO */
    unsigned int xfer_flags; /* 56: copy of URB's transfer_flags */
    unsigned int ndesc; /* 60: Actual number of ISO descriptors */
};

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .