start dissecting the ZVT authentication apdu
authorMartin Kaiser <wireshark@kaiser.cx>
Sun, 11 Jan 2015 14:14:21 +0000 (15:14 +0100)
committerMartin Kaiser <wireshark@kaiser.cx>
Mon, 19 Jan 2015 20:59:06 +0000 (20:59 +0000)
add a length paramenter to the body dissection functions in the apdu table

Change-Id: I4abbd9078fd36385a816963ab042f443e3c26b60
Reviewed-on: https://code.wireshark.org/review/6669
Reviewed-by: Martin Kaiser <wireshark@kaiser.cx>
epan/dissectors/packet-zvt.c

index be6a233692c4db8278cddcee17941a916a0d6a4e..0201c1b4bcdb2cec6477d9b5f5b716cbf0d47d27 100644 (file)
@@ -74,7 +74,7 @@ typedef struct _apdu_info_t {
     guint16          ctrl;
     guint32          min_len_field;
     zvt_direction_t  direction;
-    void (*dissect_payload)(tvbuff_t *, gint, packet_info *, proto_tree *);
+    void (*dissect_payload)(tvbuff_t *, gint, guint16, packet_info *, proto_tree *);
 } apdu_info_t;
 
 /* control code 0 is not defined in the specification */
@@ -85,12 +85,14 @@ typedef struct _apdu_info_t {
 #define CTRL_COMPLETION    0x060F
 #define CTRL_PRINT_LINE    0x06D1
 
+static void dissect_zvt_auth(
+        tvbuff_t *tvb, gint offset, guint16 len, packet_info *pinfo, proto_tree *tree);
 
 static const apdu_info_t apdu_info[] = {
     { CTRL_STATUS, 0, DIRECTION_PT_TO_ECR, NULL },
     { CTRL_INT_STATUS, 0, DIRECTION_PT_TO_ECR, NULL },
     /* authorisation has at least a 0x04 tag and 6 bytes for the amount */
-    { CTRL_AUTHORISATION, 7, DIRECTION_ECR_TO_PT, NULL },
+    { CTRL_AUTHORISATION, 7, DIRECTION_ECR_TO_PT, dissect_zvt_auth },
     { CTRL_COMPLETION, 0, DIRECTION_PT_TO_ECR, NULL },
     { CTRL_PRINT_LINE, 0, DIRECTION_PT_TO_ECR, NULL }
 };
@@ -114,6 +116,7 @@ static int hf_zvt_ccrc = -1;
 static int hf_zvt_aprc = -1;
 static int hf_zvt_len = -1;
 static int hf_zvt_data = -1;
+static int hf_zvt_auth_tag = -1;
 
 static const value_string serial_char[] = {
     { STX, "Start of text (STX)" },
@@ -142,6 +145,101 @@ static const value_string ctrl_field[] = {
 };
 static value_string_ext ctrl_field_ext = VALUE_STRING_EXT_INIT(ctrl_field);
 
+#define AUTH_TAG_TIMEOUT       0x01
+#define AUTH_TAG_MAX_STAT_INFO 0x02
+#define AUTH_TAG_AMOUNT        0x04
+#define AUTH_TAG_PUMP_NR       0x05
+#define AUTH_TAG_TLV_CONTAINER 0x06
+#define AUTH_TAG_EXP_DATE      0x0E
+#define AUTH_TAG_PAYMENT_TYPE  0x19
+#define AUTH_TAG_CARD_NUM      0x22
+#define AUTH_TAG_T2_DAT        0x23
+#define AUTH_TAG_T3_DAT        0x24
+#define AUTH_TAG_T1_DAT        0x2D
+#define AUTH_TAG_CVV_CVC       0x3A
+#define AUTH_TAG_ADD_DATA      0x3C
+#define AUTH_TAG_CC            0x49
+
+static const value_string auth_tag[] = {
+    { AUTH_TAG_TIMEOUT,       "Timeout" },
+    { AUTH_TAG_MAX_STAT_INFO, "max. status info" },
+    { AUTH_TAG_AMOUNT,        "Amount" },
+    { AUTH_TAG_PUMP_NR,       "Pump number" },
+    { AUTH_TAG_TLV_CONTAINER, "TLV container" },
+    { AUTH_TAG_EXP_DATE,      "Exipry date" },
+    { AUTH_TAG_PAYMENT_TYPE,  "Payment type" },
+    { AUTH_TAG_CARD_NUM,      "Card number" },
+    { AUTH_TAG_T2_DAT,        "Track 2 data" },
+    { AUTH_TAG_T3_DAT,        "Track 3 data" },
+    { AUTH_TAG_T1_DAT,        "Track 1 data" },
+    { AUTH_TAG_CVV_CVC,       "CVV / CVC" },
+    { AUTH_TAG_ADD_DATA,      "Additional data" },
+    { AUTH_TAG_CC,            "Currency code (CC)" },
+    { 0, NULL }
+};
+static value_string_ext auth_tag_ext = VALUE_STRING_EXT_INIT(auth_tag);
+
+
+static void
+dissect_zvt_auth(tvbuff_t *tvb, gint offset, guint16 len,
+        packet_info *pinfo _U_, proto_tree *tree)
+{
+    gint    offset_start;
+    guint8  auth_tag_byte;
+
+    offset_start = offset;
+
+    while (offset - offset_start < len) {
+        auth_tag_byte = tvb_get_guint8(tvb, offset);
+        proto_tree_add_item(tree, hf_zvt_auth_tag, tvb, offset, 1, ENC_BIG_ENDIAN);
+        offset++;
+
+        switch (auth_tag_byte) {
+            case AUTH_TAG_TIMEOUT:
+                offset++;
+                break;
+            case AUTH_TAG_MAX_STAT_INFO:
+                offset++;
+                break;
+            case AUTH_TAG_AMOUNT:
+                offset += 6;
+                break;
+            case AUTH_TAG_PUMP_NR:
+                offset++;
+                break;
+            case AUTH_TAG_EXP_DATE:
+                offset += 2;
+                break;
+            case AUTH_TAG_PAYMENT_TYPE:
+                offset++;
+                break;
+            case AUTH_TAG_CVV_CVC:
+                offset += 2;
+                break;
+            case AUTH_TAG_CC:
+                offset += 2;
+                break;
+            case AUTH_TAG_CARD_NUM:
+            case AUTH_TAG_T2_DAT:
+            case AUTH_TAG_T3_DAT:
+            case AUTH_TAG_T1_DAT:
+            case AUTH_TAG_TLV_CONTAINER:
+            case AUTH_TAG_ADD_DATA:
+                /* the data items in the authentication apdu consist of
+                   a tag and the item data - there's no length field
+                   the tag listed above have a variable length
+                   -> if we see one of those tags, we have to stop the
+                      dissection (or we have to parse the corresponding
+                      data) */
+                return;
+            default:
+                /* since there's no length field, we can't skip
+                   unknown data items - if we see an unknown data item,
+                   we have to stop */
+                return;
+        };
+    }
+}
 
 static void
 zvt_set_addresses(packet_info *pinfo _U_, zvt_direction_t dir)
@@ -420,7 +518,10 @@ proto_register_zvt(void)
                 FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
         { &hf_zvt_data,
           { "APDU data", "zvt.data",
-            FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } }
+            FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } },
+        { &hf_zvt_auth_tag,
+            { "Tag", "zvt.auth.tag", FT_UINT8,
+                BASE_HEX|BASE_EXT_STRING, &auth_tag_ext, 0, NULL, HFILL } }
     };