[英]Wireshark dissector encoding for packed BCD
用C ++編寫Wireshark Dissector插件。 我嘗試解析的協議的所有整數都使用了不常見的打包二進制編碼十進制格式。
通常,當我想增加長度的項目length
在offset offset
,我寫的:
proto_tree_add_item(body, fields.foo, tvb, offset, length, ENC_LITTLE_ENDIAN);
proto_tree_add_item(body, fields.foo, tvb, offset, length, ENC_NA); // big-endian int
proto_tree_add_item(body, fields.foo, tvb, offset, length, ENC_ASCII); // string
...等。我還需要向以下字段注冊字段數組:
proto_register_field_array(handle, field_array, array_length(field_array));
...其中field_array
是陣列hf_register_info
,如下所示:
static hf_register_info field_array[] = {
{ &fields.foo, { "Foo Field", "protocol.foo", FT_UINT48, BASE_DEC } },
// etc. other fields
};
……假設我的示例是一個6字節的壓縮BCD(能夠容納12個十進制數字)。
當我解析通過有線發送uint32,ASCII,int64等的明智協議時,所有這些都很好地工作。 但是似乎沒有用於打包BCD的內置Wireshark編碼。
我可以看到一個棘手的變通辦法,將其解析為原始數據,然后編寫一個函數將原始數據轉換為正確的值,然后使用proto_item_set_text
將proto_item_set_text
設置為所需的表示形式。
有沒有更好的辦法?
也許tvb_bcd_dig_to_wmem_packet_str()
對您有用嗎? 有很多使用它的解剖器,它們應該作為如何使用它的很好的例子:
$ grep -l tvb_bcd_dig_to_wmem_packet_str packet-*.c
packet-ansi_683.c
packet-ansi_a.c
packet-ansi_map.c
packet-bssap.c
packet-e164.c
packet-e212.c
packet-gsm_a_common.c
packet-gsm_a_dtap.c
packet-gsm_map.c
packet-gtp.c
packet-gtpv2.c
packet-ilp.c
packet-isup.c
packet-lte-rrc.c
packet-meta.c
packet-mip6.c
packet-nas_eps.c
packet-sgsap.c
packet-ulp.c
不需要特殊的編碼即可使Wireshark很好地顯示該值。 二進制編碼的十進制類似於普通整數,不同之處在於該值需要像十進制一樣進行轉換。
因此,例如將傳輸56
(十進制值)(假定線路上的字節序/網絡字節序)為0000 0000 0101 0110
或0056
(十六進制)。 需要做的就是用BASE_HEX表示形式將字段注冊為FT_UINTX(例如,UINT32用於4字節壓縮BCD,UINT40用於5字節,等等)。
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
然后在解剖函數本身中添加以下項:
proto_tree_add_item(body, fields.foo, tvb, offset, length, ENC_NA);
至於實際上將BCD字節轉換為整數,我們可以編寫一個函數將BCD轉換為無符號,例如:
#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;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.