zvt: use a hash table for the bitmaps

table entries contain the length (if known and constant) and a function
to dissect the payload

this should clean up the code for bitmap dissection and make it easier
to add new entries

Change-Id: Id0ef5ff9e53c82171789c8a3352e56d3997d82b9
Reviewed-on: https://code.wireshark.org/review/16632
Petri-Dish: Martin Kaiser <wireshark@kaiser.cx>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Martin Kaiser <wireshark@kaiser.cx>
This commit is contained in:
Martin Kaiser 2016-07-24 18:43:14 +02:00
parent 363617ffed
commit 688d055acd
1 changed files with 81 additions and 68 deletions

View File

@ -59,7 +59,7 @@
#define ZVT_APDU_MIN_LEN 3
static GHashTable *apdu_table = NULL;
static GHashTable *apdu_table = NULL, *bitmap_table = NULL;
static wmem_tree_t *transactions = NULL;
@ -126,6 +126,51 @@ static const apdu_info_t apdu_info[] = {
{ CTRL_PRINT_LINE, 0, DIRECTION_PT_TO_ECR, NULL }
};
typedef struct _bitmap_info_t {
guint8 bmp;
guint16 payload_len;
gint (*dissect_payload)(tvbuff_t *, gint, packet_info *, proto_tree *);
} bitmap_info_t;
#define BMP_TIMEOUT 0x01
#define BMP_MAX_STAT_INFO 0x02
#define BMP_AMOUNT 0x04
#define BMP_PUMP_NR 0x05
#define BMP_TLV_CONTAINER 0x06
#define BMP_EXP_DATE 0x0E
#define BMP_PAYMENT_TYPE 0x19
#define BMP_CARD_NUM 0x22
#define BMP_T2_DAT 0x23
#define BMP_T3_DAT 0x24
#define BMP_T1_DAT 0x2D
#define BMP_CVV_CVC 0x3A
#define BMP_ADD_DATA 0x3C
#define BMP_CC 0x49
#define BMP_PLD_LEN_UNKNOWN 0 /* unknown/variable bitmap payload len */
static gint dissect_zvt_tlv_container(
tvbuff_t *tvb, gint offset, packet_info *pinfo, proto_tree *tree);
static const bitmap_info_t bitmap_info[] = {
{ BMP_TIMEOUT, 1, NULL },
{ BMP_MAX_STAT_INFO, 1, NULL },
{ BMP_AMOUNT, 6, NULL },
{ BMP_PUMP_NR, 1, NULL },
{ BMP_TLV_CONTAINER, BMP_PLD_LEN_UNKNOWN, dissect_zvt_tlv_container },
{ BMP_EXP_DATE, 2, NULL },
{ BMP_PAYMENT_TYPE, 1, NULL },
{ BMP_CARD_NUM, BMP_PLD_LEN_UNKNOWN, NULL },
{ BMP_T2_DAT, BMP_PLD_LEN_UNKNOWN, NULL },
{ BMP_T3_DAT, BMP_PLD_LEN_UNKNOWN, NULL },
{ BMP_T1_DAT, BMP_PLD_LEN_UNKNOWN, NULL },
{ BMP_CVV_CVC, 2, NULL },
{ BMP_ADD_DATA, BMP_PLD_LEN_UNKNOWN, NULL },
{ BMP_CC, 2, NULL }
};
void proto_register_zvt(void);
void proto_reg_handoff_zvt(void);
@ -137,6 +182,7 @@ static int proto_zvt = -1;
static int ett_zvt = -1;
static int ett_zvt_apdu = -1;
static int ett_zvt_bitmap = -1;
static int ett_zvt_tlv_dat_obj = -1;
static int ett_zvt_tlv_tag = -1;
@ -189,21 +235,6 @@ static const value_string ctrl_field[] = {
};
static value_string_ext ctrl_field_ext = VALUE_STRING_EXT_INIT(ctrl_field);
#define BMP_TIMEOUT 0x01
#define BMP_MAX_STAT_INFO 0x02
#define BMP_AMOUNT 0x04
#define BMP_PUMP_NR 0x05
#define BMP_TLV_CONTAINER 0x06
#define BMP_EXP_DATE 0x0E
#define BMP_PAYMENT_TYPE 0x19
#define BMP_CARD_NUM 0x22
#define BMP_T2_DAT 0x23
#define BMP_T3_DAT 0x24
#define BMP_T1_DAT 0x2D
#define BMP_CVV_CVC 0x3A
#define BMP_ADD_DATA 0x3C
#define BMP_CC 0x49
static const value_string bitmap[] = {
{ BMP_TIMEOUT, "Timeout" },
{ BMP_MAX_STAT_INFO, "max. status info" },
@ -363,9 +394,12 @@ static gint
dissect_zvt_bitmap(tvbuff_t *tvb, gint offset,
packet_info *pinfo, proto_tree *tree)
{
gint offset_start;
guint8 bmp;
gint ret;
gint offset_start;
guint8 bmp;
proto_item *bitmap_it;
proto_tree *bitmap_tree;
bitmap_info_t *bi;
gint ret;
offset_start = offset;
@ -373,61 +407,32 @@ dissect_zvt_bitmap(tvbuff_t *tvb, gint offset,
if (try_val_to_str(bmp, bitmap) == NULL)
return -1;
proto_tree_add_item(tree, hf_zvt_bmp, tvb, offset, 1, ENC_BIG_ENDIAN);
bitmap_tree = proto_tree_add_subtree(tree,
tvb, offset, -1, ett_zvt_bitmap, &bitmap_it, "Bitmap");
proto_tree_add_item(bitmap_tree, hf_zvt_bmp,
tvb, offset, 1, ENC_BIG_ENDIAN);
proto_item_append_text(bitmap_it, ": %s",
val_to_str(bmp, bitmap, "unknown"));
offset++;
switch (bmp) {
case BMP_TIMEOUT:
offset++;
break;
case BMP_MAX_STAT_INFO:
offset++;
break;
case BMP_AMOUNT:
offset += 6;
break;
case BMP_PUMP_NR:
offset++;
break;
case BMP_EXP_DATE:
offset += 2;
break;
case BMP_PAYMENT_TYPE:
offset++;
break;
case BMP_CVV_CVC:
offset += 2;
break;
case BMP_CC:
offset += 2;
break;
case BMP_TLV_CONTAINER:
ret = dissect_zvt_tlv_container(tvb, offset, pinfo, tree);
if (ret<0)
return -1;
offset += ret;
break;
case BMP_CARD_NUM:
case BMP_T2_DAT:
case BMP_T3_DAT:
case BMP_T1_DAT:
case BMP_ADD_DATA:
/* the bitmaps are not TLV but only TV, there's no length field
the tags listed above have variable length
-> if we see one of those tags, we have to stop the
dissection and report an error to the caller */
return -1;
default:
g_assert_not_reached();
break;
};
bi = (bitmap_info_t *)g_hash_table_lookup(
bitmap_table, GUINT_TO_POINTER((guint)bmp));
if (bi) {
if (bi->dissect_payload) {
ret = bi->dissect_payload(tvb, offset, pinfo, bitmap_tree);
if (ret >= 0)
offset += ret;
}
else if (bi->payload_len != BMP_PLD_LEN_UNKNOWN)
offset += bi->payload_len;
}
proto_item_set_len(bitmap_it, offset - offset_start);
return offset - offset_start;
}
static void
dissect_zvt_reg(tvbuff_t *tvb, gint offset, guint16 len _U_,
packet_info *pinfo, proto_tree *tree, zvt_transaction_t *zvt_trans)
@ -802,6 +807,7 @@ proto_register_zvt(void)
static gint *ett[] = {
&ett_zvt,
&ett_zvt_apdu,
&ett_zvt_bitmap,
&ett_zvt_tlv_dat_obj,
&ett_zvt_tlv_tag
};
@ -882,6 +888,13 @@ proto_register_zvt(void)
(gpointer)(&apdu_info[i]));
}
bitmap_table = g_hash_table_new(g_direct_hash, g_direct_equal);
for(i=0; i<array_length(bitmap_info); i++) {
g_hash_table_insert(bitmap_table,
GUINT_TO_POINTER((guint)bitmap_info[i].bmp),
(gpointer)(&bitmap_info[i]));
}
proto_zvt = proto_register_protocol(
"ZVT Kassenschnittstelle", "ZVT", "zvt");
proto_register_field_array(proto_zvt, hf, array_length(hf));