From a57a32c04e0e0a9b709af69fb1e6377e049a14b5 Mon Sep 17 00:00:00 2001 From: Grzegorz Niemirowski Date: Mon, 1 Feb 2021 22:17:54 +0100 Subject: ZVT: Addedd dissection of amount, terminal ID, date and time. Registration fix. --- debian/libwireshark0.symbols | 1 + epan/dissectors/packet-zvt.c | 98 +++++++++++++++++++++++++++++++++++++------- epan/tvbuff.c | 33 +++++++++++---- epan/tvbuff.h | 21 +++++++++- 4 files changed, 127 insertions(+), 26 deletions(-) diff --git a/debian/libwireshark0.symbols b/debian/libwireshark0.symbols index a0b04b1e60..abff9c7cc9 100644 --- a/debian/libwireshark0.symbols +++ b/debian/libwireshark0.symbols @@ -1708,6 +1708,7 @@ libwireshark.so.0 libwireshark0 #MINVER# tvb_address_var_to_str@Base 1.99.2 tvb_ascii_isprint@Base 2.9.0 tvb_bcd_dig_to_wmem_packet_str@Base 1.12.0~rc1 + tvb_bcd_dig_to_wmem_packet_str_be@Base 3.5.0 tvb_bytes_exist@Base 1.9.1 tvb_bytes_to_str@Base 1.99.2 tvb_bytes_to_str_punct@Base 1.99.2 diff --git a/epan/dissectors/packet-zvt.c b/epan/dissectors/packet-zvt.c index 7a023ff5a9..392158b778 100644 --- a/epan/dissectors/packet-zvt.c +++ b/epan/dissectors/packet-zvt.c @@ -153,12 +153,20 @@ typedef struct _bitmap_info_t { #define BMP_PLD_LEN_UNKNOWN 0 /* unknown/variable bitmap payload len */ +static gint dissect_zvt_amount( + tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree); static gint dissect_zvt_tlv_container( tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree); static inline gint dissect_zvt_res_code( tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree); static inline gint dissect_zvt_cc( tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree); +static inline gint dissect_zvt_terminal_id( + tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree); +static inline gint dissect_zvt_time( + tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree); +static inline gint dissect_zvt_date( + tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree); static inline gint dissect_zvt_card_type( tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree); @@ -166,12 +174,12 @@ static const bitmap_info_t bitmap_info[] = { { BMP_TIMEOUT, 1, NULL }, { BMP_MAX_STAT_INFO, 1, NULL }, { BMP_SVC_BYTE, 1, NULL }, - { BMP_AMOUNT, 6, NULL }, + { BMP_AMOUNT, 6, dissect_zvt_amount }, { BMP_PUMP_NR, 1, NULL }, { BMP_TLV_CONTAINER, BMP_PLD_LEN_UNKNOWN, dissect_zvt_tlv_container }, { BMP_TRACE_NUM, 3, NULL }, - { BMP_TIME, 3, NULL }, - { BMP_DATE, 2, NULL }, + { BMP_TIME, 3, dissect_zvt_time }, + { BMP_DATE, 2, dissect_zvt_date }, { BMP_EXP_DATE, 2, NULL }, { BMP_CARD_SEQ_NUM, 2, NULL }, { BMP_PAYMENT_TYPE, 1, NULL }, @@ -179,7 +187,7 @@ static const bitmap_info_t bitmap_info[] = { { BMP_T2_DAT, BMP_PLD_LEN_UNKNOWN, NULL }, { BMP_T3_DAT, BMP_PLD_LEN_UNKNOWN, NULL }, { BMP_RES_CODE, 1, dissect_zvt_res_code }, - { BMP_TID, 4, NULL }, + { BMP_TID, 4, dissect_zvt_terminal_id }, { BMP_T1_DAT, BMP_PLD_LEN_UNKNOWN, NULL }, { BMP_CVV_CVC, 2, NULL }, { BMP_ADD_DATA, BMP_PLD_LEN_UNKNOWN, NULL }, @@ -215,6 +223,10 @@ static int hf_zvt_pwd = -1; static int hf_zvt_reg_cfg = -1; static int hf_zvt_res_code = -1; static int hf_zvt_cc = -1; +static int hf_zvt_amount = -1; +static int hf_zvt_terminal_id = -1; +static int hf_zvt_time = -1; +static int hf_zvt_date = -1; static int hf_zvt_card_type = -1; static int hf_zvt_reg_svc_byte = -1; static int hf_zvt_bmp = -1; @@ -365,7 +377,6 @@ static const value_string tlv_tags[] = { }; static value_string_ext tlv_tags_ext = VALUE_STRING_EXT_INIT(tlv_tags); - static inline gint dissect_zvt_tlv_text_lines( tvbuff_t *tvb, gint offset, gint len, packet_info *pinfo _U_, proto_tree *tree, tlv_seq_info_t *seq_info) @@ -578,6 +589,59 @@ static inline gint dissect_zvt_card_type( } +static inline gint dissect_zvt_terminal_id( + tvbuff_t *tvb, gint offset, packet_info *pinfo _U_, proto_tree *tree) +{ + const gchar *str = tvb_bcd_dig_to_wmem_packet_str_be(tvb, offset, 4, NULL, FALSE); + proto_tree_add_string(tree, hf_zvt_terminal_id, tvb, offset, 4, str); + return 4; +} + + +static inline gint dissect_zvt_amount( + tvbuff_t *tvb, gint offset, packet_info *pinfo _U_, proto_tree *tree) +{ + const gchar *str = tvb_bcd_dig_to_wmem_packet_str_be(tvb, offset, 6, NULL, FALSE); + proto_tree_add_uint64(tree, hf_zvt_amount, tvb, offset, 6, atol(str)); + return 6; +} + + +static inline gint dissect_zvt_time( + tvbuff_t *tvb, gint offset, packet_info *pinfo _U_, proto_tree *tree) +{ + const gchar *str = tvb_bcd_dig_to_wmem_packet_str_be(tvb, offset, 3, NULL, FALSE); + gchar *fstr = (char *)wmem_alloc(wmem_packet_scope(), 9); + fstr[0] = str[0]; + fstr[1] = str[1]; + fstr[2] = ':'; + fstr[3] = str[2]; + fstr[4] = str[3]; + fstr[5] = ':'; + fstr[6] = str[4]; + fstr[7] = str[5]; + fstr[8] = 0; + proto_tree_add_string(tree, hf_zvt_time, tvb, offset, 3, fstr); + return 3; +} + + +static inline gint dissect_zvt_date( + tvbuff_t *tvb, gint offset, packet_info *pinfo _U_, proto_tree *tree) +{ + const gchar *str = tvb_bcd_dig_to_wmem_packet_str_be(tvb, offset, 2, NULL, FALSE); + gchar *fstr = (char *)wmem_alloc(wmem_packet_scope(), 6); + fstr[0] = str[0]; + fstr[1] = str[1]; + fstr[2] = '/'; + fstr[3] = str[2]; + fstr[4] = str[3]; + fstr[5] = 0; + proto_tree_add_string(tree, hf_zvt_date, tvb, offset, 2, fstr); + return 2; +} + + /* dissect one "bitmap", i.e BMP and the corresponding data */ static gint dissect_zvt_bitmap(tvbuff_t *tvb, gint offset, @@ -648,17 +712,9 @@ dissect_zvt_reg(tvbuff_t *tvb, gint offset, guint16 len _U_, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; - /* check for the optional part CC|0x03|service byte */ - if (tvb_captured_length_remaining(tvb, offset)>=4 && - tvb_get_guint8(tvb, offset+2)==0x03) { - + /* check for the optional part CC|0x03|service byte|TLV */ + if (tvb_captured_length_remaining(tvb, offset)>=2) { offset += dissect_zvt_cc(tvb, offset, pinfo, tree); - - offset++; /* 0x03 */ - - proto_tree_add_item(tree, hf_zvt_reg_svc_byte, - tvb, offset, 1, ENC_BIG_ENDIAN); - offset++; } /* it's ok if the remaining len is 0 */ @@ -1043,6 +1099,18 @@ proto_register_zvt(void) { &hf_zvt_card_type, { "Card Type", "zvt.card_type", FT_UINT8, BASE_DEC|BASE_EXT_STRING, &card_type_ext, 0, NULL, HFILL } }, + { &hf_zvt_terminal_id, + { "Terminal ID", "zvt.terminal_id", FT_STRING, + BASE_NONE, NULL, 0, NULL, HFILL } }, + { &hf_zvt_amount, + { "Amount", "zvt.amount", FT_UINT48, + BASE_DEC, NULL, 0, NULL, HFILL } }, + { &hf_zvt_time, + { "Time", "zvt.time", FT_STRING, + BASE_NONE, NULL, 0, NULL, HFILL } }, + { &hf_zvt_date, + { "Date", "zvt.date", FT_STRING, + BASE_NONE, NULL, 0, NULL, HFILL } }, { &hf_zvt_reg_svc_byte, { "Service byte", "zvt.reg.service_byte", FT_UINT8, BASE_HEX, NULL, 0, NULL, HFILL } }, diff --git a/epan/tvbuff.c b/epan/tvbuff.c index 1c80ad79cb..fce3cb8c2d 100644 --- a/epan/tvbuff.c +++ b/epan/tvbuff.c @@ -3056,7 +3056,7 @@ tvb_get_string_enc(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, */ odd = (encoding & ENC_BCD_ODD_NUM_DIG) >> 16; skip_first = (encoding & ENC_BCD_SKIP_FIRST) >> 17; - strptr = tvb_get_bcd_string(scope, tvb, offset, length, &Dgt0_9_bcd, skip_first, odd); + strptr = tvb_get_bcd_string(scope, tvb, offset, length, &Dgt0_9_bcd, skip_first, odd, FALSE); break; case ENC_KEYPAD_ABC_TBCD: @@ -3066,7 +3066,7 @@ tvb_get_string_enc(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, */ odd = (encoding & ENC_BCD_ODD_NUM_DIG) >> 16; skip_first = (encoding & ENC_BCD_SKIP_FIRST) >> 17; - strptr = tvb_get_bcd_string(scope, tvb, offset, length, &Dgt_keypad_abc_tbcd, skip_first, odd); + strptr = tvb_get_bcd_string(scope, tvb, offset, length, &Dgt_keypad_abc_tbcd, skip_first, odd, FALSE); break; case ENC_KEYPAD_BC_TBCD: @@ -3076,7 +3076,7 @@ tvb_get_string_enc(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, */ odd = (encoding & ENC_BCD_ODD_NUM_DIG) >> 16; skip_first = (encoding & ENC_BCD_SKIP_FIRST) >> 17; - strptr = tvb_get_bcd_string(scope, tvb, offset, length, &Dgt_ansi_tbcd, skip_first, odd); + strptr = tvb_get_bcd_string(scope, tvb, offset, length, &Dgt_ansi_tbcd, skip_first, odd, FALSE); break; case ENC_3GPP_TS_23_038_7BITS_UNPACKED: @@ -4137,11 +4137,11 @@ tvb_bytes_to_str_punct(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset * byte), formating the digits into characters according to the * input digit set, and return a pointer to a UTF-8 string, allocated * using the wmem scope. A high-order nibble of 0xf is considered a - * 'filler' and will end the conversion. Similarrily if odd is set thje last + * 'filler' and will end the conversion. Similarrily if odd is set the last * high nibble will be omitted. */ gchar * -tvb_get_bcd_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint len, const dgt_set_t *dgt, gboolean skip_first, gboolean odd) +tvb_get_bcd_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint len, const dgt_set_t *dgt, gboolean skip_first, gboolean odd, gboolean bigendian) { const guint8 *ptr; int i = 0; @@ -4176,7 +4176,11 @@ tvb_get_bcd_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gi while (len > 0) { octet = *ptr; if (!skip_first) { - digit_str[i] = dgt->out[octet & 0x0f]; + if (bigendian) { + digit_str[i] = dgt->out[(octet >> 4) & 0x0f]; + } else { + digit_str[i] = dgt->out[octet & 0x0f]; + } i++; } skip_first = FALSE; @@ -4184,7 +4188,9 @@ tvb_get_bcd_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gi /* * unpack second value in byte */ - octet = octet >> 4; + if (!bigendian) { + octet = octet >> 4; + } if (octet == 0x0f) { /* @@ -4194,7 +4200,7 @@ tvb_get_bcd_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gi break; } if ((len == 1) && (odd == TRUE )){ - /* Last octet, skipp last high nibble incase of odd number digits*/ + /* Last octet, skipp last high nibble incase of odd number of digits*/ break; } digit_str[i] = dgt->out[octet & 0x0f]; @@ -4214,7 +4220,16 @@ tvb_bcd_dig_to_wmem_packet_str(tvbuff_t *tvb, const gint offset, const gint len, if (!dgt) dgt = &Dgt0_9_bcd; - return tvb_get_bcd_string(wmem_packet_scope(), tvb, offset, len, dgt, skip_first, FALSE); + return tvb_get_bcd_string(wmem_packet_scope(), tvb, offset, len, dgt, skip_first, FALSE, FALSE); +} + +const gchar * +tvb_bcd_dig_to_wmem_packet_str_be(tvbuff_t *tvb, const gint offset, const gint len, const dgt_set_t *dgt, gboolean skip_first) +{ + if (!dgt) + dgt = &Dgt0_9_bcd; + + return tvb_get_bcd_string(wmem_packet_scope(), tvb, offset, len, dgt, skip_first, FALSE, TRUE); } /* diff --git a/epan/tvbuff.h b/epan/tvbuff.h index 01ca3fcb24..b8e6cd931c 100644 --- a/epan/tvbuff.h +++ b/epan/tvbuff.h @@ -941,6 +941,21 @@ WS_DLL_PUBLIC const gchar *tvb_bcd_dig_to_wmem_packet_str(tvbuff_t *tvb, const gint offset, const gint len, const dgt_set_t *dgt, gboolean skip_first); +/** + * Given a tvbuff, an offset into the tvbuff, and a length that starts + * at that offset (which may be -1 for "all the way to the end of the + * tvbuff"), fetch BCD encoded digits from a tvbuff starting from either + * the low or high half byte, formatting the digits according to an input digit + * set, if NUL a default digit set of 0-9 returning "?" for overdecadic digits + * will be used. A pointer to the packet-scope (WMEM-allocated) string will + * be returned. Note a tvbuff content of 0xf is considered a 'filler' and will + * end the conversion. Function uses big endian convetion: first digit is based + * on high order nibble, second digit is based on low order nibble. + */ +WS_DLL_PUBLIC const gchar *tvb_bcd_dig_to_wmem_packet_str_be(tvbuff_t *tvb, + const gint offset, const gint len, const dgt_set_t *dgt, + gboolean skip_first); + /** * Given a wmem scope, a tvbuff, an offset, a length, an input digit * set, and a boolean indicator, fetch BCD-encoded digits from a @@ -952,11 +967,13 @@ WS_DLL_PUBLIC const gchar *tvb_bcd_dig_to_wmem_packet_str(tvbuff_t *tvb, * input digit set, and return a pointer to a UTF-8 string, allocated * using the wmem scope. A high-order nibble of 0xf is considered a * 'filler' and will end the conversion. If odd is set the high order - * nibble in the last octet will be skipped + * nibble in the last octet will be skipped. If bigendian is set then + * high order nibble is taken as first digit of a byte and low order + * nibble as second digit. */ WS_DLL_PUBLIC gchar *tvb_get_bcd_string(wmem_allocator_t *scope, tvbuff_t *tvb, const gint offset, gint len, const dgt_set_t *dgt, - gboolean skip_first, gboolean odd); + gboolean skip_first, gboolean odd, gboolean bigendian); /** Locate a sub-tvbuff within another tvbuff, starting at position * 'haystack_offset'. Returns the index of the beginning of 'needle' within -- cgit v1.2.3