USBLL: Verify Token/Split packets CRC-5
Ping-Bug: 15908 Change-Id: I25aaf772d3d0af2f459a1ad78d8253344ed13f05 Reviewed-on: https://code.wireshark.org/review/34025 Petri-Dish: Peter Wu <peter@lekensteyn.nl> Tested-by: Petri Dish Buildbot Reviewed-by: Peter Wu <peter@lekensteyn.nl>
This commit is contained in:
parent
d89eb91eaf
commit
53ecc16079
|
@ -40,6 +40,8 @@ libwsutil.so.0 libwsutil0 #MINVER#
|
|||
crc32c_calculate@Base 1.10.0
|
||||
crc32c_calculate_no_swap@Base 1.10.0
|
||||
crc32c_table_lookup@Base 1.10.0
|
||||
crc5_usb_11bit_input@Base 3.1.1
|
||||
crc5_usb_19bit_input@Base 3.1.1
|
||||
crc6_0X6F@Base 1.12.0~rc1
|
||||
crc7update@Base 1.10.0
|
||||
crc8_0x2F@Base 1.10.0
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <epan/packet.h>
|
||||
#include <epan/expert.h>
|
||||
#include <epan/crc16-tvb.h>
|
||||
#include <wsutil/crc5.h>
|
||||
|
||||
static int proto_usbll = -1;
|
||||
|
||||
|
@ -25,6 +26,7 @@ static int hf_usbll_pid = -1;
|
|||
static int hf_usbll_addr = -1;
|
||||
static int hf_usbll_endp = -1;
|
||||
static int hf_usbll_crc5 = -1;
|
||||
static int hf_usbll_crc5_status = -1;
|
||||
static int hf_usbll_data = -1;
|
||||
static int hf_usbll_data_crc = -1;
|
||||
static int hf_usbll_data_crc_status = -1;
|
||||
|
@ -37,11 +39,14 @@ static int hf_usbll_split_e = -1;
|
|||
static int hf_usbll_split_iso_se = -1;
|
||||
static int hf_usbll_split_et = -1;
|
||||
static int hf_usbll_split_crc5 = -1;
|
||||
static int hf_usbll_split_crc5_status = -1;
|
||||
|
||||
static int ett_usbll = -1;
|
||||
|
||||
static expert_field ei_invalid_pid = EI_INIT;
|
||||
static expert_field ei_undecoded = EI_INIT;
|
||||
static expert_field ei_wrong_crc5 = EI_INIT;
|
||||
static expert_field ei_wrong_split_crc5 = EI_INIT;
|
||||
static expert_field ei_wrong_crc16 = EI_INIT;
|
||||
|
||||
static dissector_handle_t usbll_handle;
|
||||
|
@ -154,14 +159,19 @@ dissect_usbll_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
|
|||
case USB_PID_TOKEN_IN:
|
||||
case USB_PID_SPECIAL_PING:
|
||||
{
|
||||
guint16 address_bits;
|
||||
static const int *address_fields[] = {
|
||||
&hf_usbll_addr,
|
||||
&hf_usbll_endp,
|
||||
&hf_usbll_crc5,
|
||||
NULL
|
||||
};
|
||||
|
||||
proto_tree_add_bitmask_list(tree, tvb, offset, 2, address_fields, ENC_LITTLE_ENDIAN);
|
||||
address_bits = tvb_get_letohs(tvb, offset);
|
||||
proto_tree_add_bitmask_list_value(tree, tvb, offset, 2, address_fields, address_bits);
|
||||
proto_tree_add_checksum(tree, tvb, offset,
|
||||
hf_usbll_crc5, hf_usbll_crc5_status, &ei_wrong_crc5, pinfo,
|
||||
crc5_usb_11bit_input(address_bits),
|
||||
ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
|
||||
offset += 2;
|
||||
break;
|
||||
}
|
||||
|
@ -191,13 +201,12 @@ dissect_usbll_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
|
|||
break;
|
||||
case USB_PID_TOKEN_SOF:
|
||||
{
|
||||
static const int *sof_fields[] = {
|
||||
&hf_usbll_sof_framenum,
|
||||
&hf_usbll_crc5,
|
||||
NULL
|
||||
};
|
||||
|
||||
proto_tree_add_bitmask_list(tree, tvb, offset, 2, sof_fields, ENC_LITTLE_ENDIAN);
|
||||
guint32 frame;
|
||||
proto_tree_add_item_ret_uint(tree, hf_usbll_sof_framenum, tvb, offset, 2, ENC_LITTLE_ENDIAN, &frame);
|
||||
proto_tree_add_checksum(tree, tvb, offset,
|
||||
hf_usbll_crc5, hf_usbll_crc5_status, &ei_wrong_crc5, pinfo,
|
||||
crc5_usb_11bit_input(frame),
|
||||
ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
|
||||
offset += 2;
|
||||
break;
|
||||
}
|
||||
|
@ -212,7 +221,6 @@ dissect_usbll_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
|
|||
&hf_usbll_split_s,
|
||||
&hf_usbll_split_e,
|
||||
&hf_usbll_split_et,
|
||||
&hf_usbll_split_crc5,
|
||||
NULL
|
||||
};
|
||||
static const int *split_iso_fields[] = {
|
||||
|
@ -221,7 +229,6 @@ dissect_usbll_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
|
|||
&hf_usbll_split_port,
|
||||
&hf_usbll_split_iso_se,
|
||||
&hf_usbll_split_et,
|
||||
&hf_usbll_split_crc5,
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@ -233,6 +240,10 @@ dissect_usbll_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
|
|||
{
|
||||
proto_tree_add_bitmask_list(tree, tvb, offset, 3, split_fields, ENC_LITTLE_ENDIAN);
|
||||
}
|
||||
proto_tree_add_checksum(tree, tvb, offset,
|
||||
hf_usbll_split_crc5, hf_usbll_split_crc5_status, &ei_wrong_split_crc5, pinfo,
|
||||
crc5_usb_19bit_input(tmp),
|
||||
ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
|
||||
offset += 3;
|
||||
break;
|
||||
}
|
||||
|
@ -276,6 +287,10 @@ proto_register_usbll(void)
|
|||
{ "CRC5", "usbll.crc5",
|
||||
FT_UINT16, BASE_HEX, NULL, 0xF800,
|
||||
NULL, HFILL }},
|
||||
{ &hf_usbll_crc5_status,
|
||||
{ "CRC5 Status", "usbll.crc5.status",
|
||||
FT_UINT8, BASE_NONE, VALS(proto_checksum_vals), 0,
|
||||
NULL, HFILL }},
|
||||
{ &hf_usbll_data,
|
||||
{ "Data", "usbll.data",
|
||||
FT_BYTES, BASE_NONE, NULL, 0,
|
||||
|
@ -325,11 +340,17 @@ proto_register_usbll(void)
|
|||
{ "CRC5", "usbll.split_crc5",
|
||||
FT_UINT24, BASE_HEX, NULL, 0xF80000,
|
||||
NULL, HFILL }},
|
||||
{ &hf_usbll_split_crc5_status,
|
||||
{ "CRC5 Status", "usbll.split_crc5.status",
|
||||
FT_UINT8, BASE_NONE, VALS(proto_checksum_vals), 0,
|
||||
NULL, HFILL }},
|
||||
};
|
||||
|
||||
static ei_register_info ei[] = {
|
||||
{ &ei_invalid_pid, { "usbll.invalid_pid", PI_MALFORMED, PI_ERROR, "Invalid USB Packet ID", EXPFILL }},
|
||||
{ &ei_undecoded, { "usbll.undecoded", PI_UNDECODED, PI_WARN, "Not dissected yet (report to wireshark.org)", EXPFILL }},
|
||||
{ &ei_wrong_crc5, { "usbll.crc5.wrong", PI_PROTOCOL, PI_WARN, "Wrong CRC", EXPFILL }},
|
||||
{ &ei_wrong_split_crc5, { "usbll.split_crc5.wrong", PI_PROTOCOL, PI_WARN, "Wrong CRC", EXPFILL }},
|
||||
{ &ei_wrong_crc16, { "usbll.crc16.wrong", PI_PROTOCOL, PI_WARN, "Wrong CRC", EXPFILL }},
|
||||
};
|
||||
|
||||
|
|
|
@ -23,6 +23,7 @@ set(WSUTIL_PUBLIC_HEADERS
|
|||
copyright_info.h
|
||||
cpu_info.h
|
||||
crash_info.h
|
||||
crc5.h
|
||||
crc6.h
|
||||
crc7.h
|
||||
crc8.h
|
||||
|
@ -85,6 +86,7 @@ set(WSUTIL_COMMON_FILES
|
|||
crc16.c
|
||||
crc16-plain.c
|
||||
crc32.c
|
||||
crc5.c
|
||||
crc6.c
|
||||
crc7.c
|
||||
crc8.c
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/* crc5.c
|
||||
* CRC-5 routine
|
||||
*
|
||||
* 2019 Tomasz Mon <desowin@gmail.com>
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <wsutil/crc5.h>
|
||||
|
||||
static guint8 crc5_usb_bits(guint32 v, int vl, guint8 ival)
|
||||
{
|
||||
/* This function is based on code posted by John Sullivan to Wireshark-dev
|
||||
* mailing list on Jul 21, 2019.
|
||||
*
|
||||
* "One of the properties of LFSRs is that a 1 bit in the input toggles a
|
||||
* completely predictable set of register bits *at any point in the
|
||||
* future*. This isn't often useful for most CRC caculations on variable
|
||||
* sized input, as the cost of working out which those bits are vastly
|
||||
* outweighs most other methods."
|
||||
*
|
||||
* In USB 2.0, the CRC5 is calculated on either 11 or 19 bits inputs,
|
||||
* and thus this approach is viable.
|
||||
*/
|
||||
guint8 rv = ival;
|
||||
static const guint8 bvals[19] = {
|
||||
0x1e, 0x15, 0x03, 0x06, 0x0c, 0x18, 0x19, 0x1b,
|
||||
0x1f, 0x17, 0x07, 0x0e, 0x1c, 0x11, 0x0b, 0x16,
|
||||
0x05, 0x0a, 0x14
|
||||
};
|
||||
|
||||
for (int i = 0; i < vl; i++) {
|
||||
if (v & (1 << i)) {
|
||||
rv ^= bvals[19 - vl + i];
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
guint8 crc5_usb_11bit_input(guint16 input)
|
||||
{
|
||||
return crc5_usb_bits(input, 11, 0x02);
|
||||
}
|
||||
|
||||
guint8 crc5_usb_19bit_input(guint32 input)
|
||||
{
|
||||
return crc5_usb_bits(input, 19, 0x1d);
|
||||
}
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
* Local variables:
|
||||
* c-basic-offset: 4
|
||||
* tab-width: 8
|
||||
* indent-tabs-mode: nil
|
||||
* End:
|
||||
*
|
||||
* vi: set shiftwidth=4 tabstop=8 expandtab:
|
||||
* :indentSize=4:tabSize=8:noTabs=true:
|
||||
*/
|
|
@ -0,0 +1,40 @@
|
|||
/* crc5.h
|
||||
* Declaration of CRC-5 routines and table
|
||||
*
|
||||
* 2019 Tomasz Mon <desowin@gmail.com>
|
||||
*
|
||||
* Wireshark - Network traffic analyzer
|
||||
* By Gerald Combs <gerald@wireshark.org>
|
||||
* Copyright 1998 Gerald Combs
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||
*/
|
||||
|
||||
#ifndef __CRC5_H__
|
||||
#define __CRC5_H__
|
||||
|
||||
#include "ws_symbol_export.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/** Compute the 5-bit CRC value of a input value matching the CRC-5
|
||||
defined in USB 2.0 Specification. This function calculates the CRC
|
||||
on low 11 bits of the input value. High bits are ignored.
|
||||
@param input Source data for which the CRC-5 should be calculated.
|
||||
@return the CRC5 checksum for input value */
|
||||
WS_DLL_PUBLIC guint8 crc5_usb_11bit_input(guint16 input);
|
||||
|
||||
/** Compute the 5-bit CRC value of a input value matching the CRC-5
|
||||
defined in USB 2.0 Specification. This function calculates the CRC
|
||||
on low 19 bits of the input value. High bits are ignored.
|
||||
@param input Source data for which the CRC-5 should be calculated.
|
||||
@return the CRC5 checksum for input value */
|
||||
WS_DLL_PUBLIC guint8 crc5_usb_19bit_input(guint32 input);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __CRC5_H__ */
|
Loading…
Reference in New Issue