forked from osmocom/wireshark
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@Base 1.10.0
|
||||||
crc32c_calculate_no_swap@Base 1.10.0
|
crc32c_calculate_no_swap@Base 1.10.0
|
||||||
crc32c_table_lookup@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
|
crc6_0X6F@Base 1.12.0~rc1
|
||||||
crc7update@Base 1.10.0
|
crc7update@Base 1.10.0
|
||||||
crc8_0x2F@Base 1.10.0
|
crc8_0x2F@Base 1.10.0
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <epan/packet.h>
|
#include <epan/packet.h>
|
||||||
#include <epan/expert.h>
|
#include <epan/expert.h>
|
||||||
#include <epan/crc16-tvb.h>
|
#include <epan/crc16-tvb.h>
|
||||||
|
#include <wsutil/crc5.h>
|
||||||
|
|
||||||
static int proto_usbll = -1;
|
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_addr = -1;
|
||||||
static int hf_usbll_endp = -1;
|
static int hf_usbll_endp = -1;
|
||||||
static int hf_usbll_crc5 = -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 = -1;
|
||||||
static int hf_usbll_data_crc = -1;
|
static int hf_usbll_data_crc = -1;
|
||||||
static int hf_usbll_data_crc_status = -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_iso_se = -1;
|
||||||
static int hf_usbll_split_et = -1;
|
static int hf_usbll_split_et = -1;
|
||||||
static int hf_usbll_split_crc5 = -1;
|
static int hf_usbll_split_crc5 = -1;
|
||||||
|
static int hf_usbll_split_crc5_status = -1;
|
||||||
|
|
||||||
static int ett_usbll = -1;
|
static int ett_usbll = -1;
|
||||||
|
|
||||||
static expert_field ei_invalid_pid = EI_INIT;
|
static expert_field ei_invalid_pid = EI_INIT;
|
||||||
static expert_field ei_undecoded = 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 expert_field ei_wrong_crc16 = EI_INIT;
|
||||||
|
|
||||||
static dissector_handle_t usbll_handle;
|
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_TOKEN_IN:
|
||||||
case USB_PID_SPECIAL_PING:
|
case USB_PID_SPECIAL_PING:
|
||||||
{
|
{
|
||||||
|
guint16 address_bits;
|
||||||
static const int *address_fields[] = {
|
static const int *address_fields[] = {
|
||||||
&hf_usbll_addr,
|
&hf_usbll_addr,
|
||||||
&hf_usbll_endp,
|
&hf_usbll_endp,
|
||||||
&hf_usbll_crc5,
|
|
||||||
NULL
|
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;
|
offset += 2;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -191,13 +201,12 @@ dissect_usbll_packet(tvbuff_t *tvb, packet_info *pinfo, proto_tree *parent_tree,
|
||||||
break;
|
break;
|
||||||
case USB_PID_TOKEN_SOF:
|
case USB_PID_TOKEN_SOF:
|
||||||
{
|
{
|
||||||
static const int *sof_fields[] = {
|
guint32 frame;
|
||||||
&hf_usbll_sof_framenum,
|
proto_tree_add_item_ret_uint(tree, hf_usbll_sof_framenum, tvb, offset, 2, ENC_LITTLE_ENDIAN, &frame);
|
||||||
&hf_usbll_crc5,
|
proto_tree_add_checksum(tree, tvb, offset,
|
||||||
NULL
|
hf_usbll_crc5, hf_usbll_crc5_status, &ei_wrong_crc5, pinfo,
|
||||||
};
|
crc5_usb_11bit_input(frame),
|
||||||
|
ENC_LITTLE_ENDIAN, PROTO_CHECKSUM_VERIFY);
|
||||||
proto_tree_add_bitmask_list(tree, tvb, offset, 2, sof_fields, ENC_LITTLE_ENDIAN);
|
|
||||||
offset += 2;
|
offset += 2;
|
||||||
break;
|
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_s,
|
||||||
&hf_usbll_split_e,
|
&hf_usbll_split_e,
|
||||||
&hf_usbll_split_et,
|
&hf_usbll_split_et,
|
||||||
&hf_usbll_split_crc5,
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
static const int *split_iso_fields[] = {
|
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_port,
|
||||||
&hf_usbll_split_iso_se,
|
&hf_usbll_split_iso_se,
|
||||||
&hf_usbll_split_et,
|
&hf_usbll_split_et,
|
||||||
&hf_usbll_split_crc5,
|
|
||||||
NULL
|
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_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;
|
offset += 3;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -276,6 +287,10 @@ proto_register_usbll(void)
|
||||||
{ "CRC5", "usbll.crc5",
|
{ "CRC5", "usbll.crc5",
|
||||||
FT_UINT16, BASE_HEX, NULL, 0xF800,
|
FT_UINT16, BASE_HEX, NULL, 0xF800,
|
||||||
NULL, HFILL }},
|
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,
|
{ &hf_usbll_data,
|
||||||
{ "Data", "usbll.data",
|
{ "Data", "usbll.data",
|
||||||
FT_BYTES, BASE_NONE, NULL, 0,
|
FT_BYTES, BASE_NONE, NULL, 0,
|
||||||
|
@ -325,11 +340,17 @@ proto_register_usbll(void)
|
||||||
{ "CRC5", "usbll.split_crc5",
|
{ "CRC5", "usbll.split_crc5",
|
||||||
FT_UINT24, BASE_HEX, NULL, 0xF80000,
|
FT_UINT24, BASE_HEX, NULL, 0xF80000,
|
||||||
NULL, HFILL }},
|
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[] = {
|
static ei_register_info ei[] = {
|
||||||
{ &ei_invalid_pid, { "usbll.invalid_pid", PI_MALFORMED, PI_ERROR, "Invalid USB Packet ID", EXPFILL }},
|
{ &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_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 }},
|
{ &ei_wrong_crc16, { "usbll.crc16.wrong", PI_PROTOCOL, PI_WARN, "Wrong CRC", EXPFILL }},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ set(WSUTIL_PUBLIC_HEADERS
|
||||||
copyright_info.h
|
copyright_info.h
|
||||||
cpu_info.h
|
cpu_info.h
|
||||||
crash_info.h
|
crash_info.h
|
||||||
|
crc5.h
|
||||||
crc6.h
|
crc6.h
|
||||||
crc7.h
|
crc7.h
|
||||||
crc8.h
|
crc8.h
|
||||||
|
@ -85,6 +86,7 @@ set(WSUTIL_COMMON_FILES
|
||||||
crc16.c
|
crc16.c
|
||||||
crc16-plain.c
|
crc16-plain.c
|
||||||
crc32.c
|
crc32.c
|
||||||
|
crc5.c
|
||||||
crc6.c
|
crc6.c
|
||||||
crc7.c
|
crc7.c
|
||||||
crc8.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