1 | initial version |
No particular encoding is necessary to make Wireshark display the value nicely. A binary-coded-decimal is like a plain integer, except that the value needs to be translated as if it were decimal.
So 56 (decimal value) for example will be transmitted (assuming big-endian / network-byte-order on the wire) as 0000 0000 0101 0110
or 0056
(hex). All that is needed is to register the field as a FT_UINTX (e.g. UINT32 for 4 byte Packed BCD, UINT40 for 5 byte, etc.) with BASE_HEX representation.
static hf_register_info field_array[] = {
{ &fields.foo, { "Foo Field", "protocol.foo", FT_UINT48, BASE_HEX } },
// etc. other fields
}; // works for 6-byte packed BCD
And in the dissecting function itself, add the item:
proto_tree_add_item(body, fields.foo, tvb, offset, length, ENC_NA);
As for actually turning the BCD bytes into an integer, we can just write a function to transform BCDs to unsigned, e.g.:
#include <cstdint>
uint64_t bcd_to_uint(const char* start, const size_t bytes)
{
uint64_t value = 0;
for (size_t i = 0; i < bytes; ++i)
{
uint8_t data = start[i] - '0';
value += ((data >> 4) * 10 + (data & 0x0f)) * ipow(100, bytes - i - 1);
// right-shift unsigned will fill with 0s
// integer promotion will prevent overflow up to UINT_MAX
// ipow(base, exp) returns base to the power of exp, returns uint64
}
return value;
}
2 | No.2 Revision |
No particular encoding is necessary to make Wireshark display the value nicely. A binary-coded-decimal is like a plain integer, except that the value needs to be translated as if it were decimal.
So 56 (decimal value) for example will be transmitted (assuming big-endian / network-byte-order on the wire) as 0000 0000 0101 0110
or 0056
(hex). All that is needed is to register the field as a FT_UINTX FT_UINTX
(e.g. UINT32 for 4 byte Packed BCD, UINT40 for 5 byte, etc.) with BASE_HEX representation.
static hf_register_info field_array[] = {
{ &fields.foo, { "Foo Field", "protocol.foo", FT_UINT48, BASE_HEX } },
// etc. other fields
}; // works for 6-byte packed BCD
And in the dissecting function itself, add the item:
proto_tree_add_item(body, fields.foo, tvb, offset, length, ENC_NA);
As for actually turning the BCD bytes into an integer, we can just write a function to transform BCDs to unsigned, e.g.:
#include <cstdint>
uint64_t bcd_to_uint(const char* start, const size_t bytes)
{
uint64_t value = 0;
for (size_t i = 0; i < bytes; ++i)
{
uint8_t data = start[i] - '0';
value += ((data >> 4) * 10 + (data & 0x0f)) * ipow(100, bytes - i - 1);
// right-shift unsigned will fill with 0s
// integer promotion will prevent overflow up to UINT_MAX
// ipow(base, exp) returns base to the power of exp, returns uint64
}
return value;
}