add: proper indentation when printing TLV objects
authorpwpiwi <pwpiwi@users.noreply.github.com>
Fri, 10 Nov 2017 20:39:10 +0000 (21:39 +0100)
committerpwpiwi <pwpiwi@users.noreply.github.com>
Fri, 10 Nov 2017 20:54:07 +0000 (21:54 +0100)
client/emv/dump.c
client/emv/dump.h
client/emv/emv_tags.c
client/emv/emv_tags.h
client/emv/emvcore.c
client/emv/tlv.c
client/emv/tlv.h

index 9915ad737c17823fc9c776b4c2d025deb10126a2..41d7c9fd68c3a3e01b3ab854e3f27998fae6aa3e 100644 (file)
@@ -21,6 +21,8 @@
 
 #include <stdio.h>
 
+#define PRINT_INDENT(level)    {for (int i = 0; i < (level); i++) fprintf(f, "\t");}
+
 void dump_buffer_simple(const unsigned char *ptr, size_t len, FILE *f)
 {
        int i;
@@ -32,7 +34,7 @@ void dump_buffer_simple(const unsigned char *ptr, size_t len, FILE *f)
                fprintf(f, "%s%02hhX", i ? " " : "", ptr[i]);
 }
 
-void dump_buffer(const unsigned char *ptr, size_t len, FILE *f)
+void dump_buffer(const unsigned char *ptr, size_t len, FILE *f, int level)
 {
        int i, j;
 
@@ -40,6 +42,7 @@ void dump_buffer(const unsigned char *ptr, size_t len, FILE *f)
                f = stdout;
 
        for (i = 0; i < len; i += 16) {
+               PRINT_INDENT(level);
                fprintf(f, "\t%02x:", i);
                for (j = 0; j < 16; j++) {
                        if (i + j < len)
index 5976da445aadd5223ff85655460e894a0026c6e8..ad69ea834e63a3c73323cedd69efa3f325546709 100644 (file)
@@ -19,6 +19,6 @@
 #include <stdio.h>
 
 void dump_buffer_simple(const unsigned char *ptr, size_t len, FILE *f);
-void dump_buffer(const unsigned char *ptr, size_t len, FILE *f);
+void dump_buffer(const unsigned char *ptr, size_t len, FILE *f, int level);
 
 #endif
index 1aae847af2f668d17b4ba98326e2342c0cc4f4ca..d91685c44a572553763f38c671a911637e81282c 100644 (file)
@@ -22,6 +22,8 @@
 
 #include <stdlib.h>
 
+#define PRINT_INDENT(level)    {for (int i = 0; i < (level); i++) fprintf(f, "\t");}
+
 enum emv_tag_t {
        EMV_TAG_GENERIC,
        EMV_TAG_BITMASK,
@@ -230,16 +232,18 @@ static const char *bitstrings[] = {
        "1.......",
 };
 
-static void emv_tag_dump_bitmask(const struct tlv *tlv, const struct emv_tag *tag, FILE *f)
+static void emv_tag_dump_bitmask(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level)
 {
        const struct emv_tag_bit *bits = tag->data;
        unsigned bit, byte;
 
        for (byte = 1; byte <= tlv->len; byte ++) {
                unsigned char val = tlv->value[byte - 1];
+               PRINT_INDENT(level);
                fprintf(f, "\tByte %u (%02x)\n", byte, val);
                for (bit = 8; bit > 0; bit--, val <<= 1) {
                        if (val & 0x80)
+                               PRINT_INDENT(level);
                                fprintf(f, "\t\t%s - '%s'\n", bitstrings[bit - 1],
                                                bits->bit == EMV_BIT(byte, bit) ? bits->name : "Unknown");
                        if (bits->bit == EMV_BIT(byte, bit))
@@ -248,7 +252,7 @@ static void emv_tag_dump_bitmask(const struct tlv *tlv, const struct emv_tag *ta
        }
 }
 
-static void emv_tag_dump_dol(const struct tlv *tlv, const struct emv_tag *tag, FILE *f)
+static void emv_tag_dump_dol(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level)
 {
        const unsigned char *buf = tlv->value;
        size_t left = tlv->len;
@@ -258,20 +262,24 @@ static void emv_tag_dump_dol(const struct tlv *tlv, const struct emv_tag *tag, F
                const struct emv_tag *doltag;
 
                if (!tlv_parse_tl(&buf, &left, &doltlv)) {
+                       PRINT_INDENT(level);
                        fprintf(f, "Invalid Tag-Len\n");
                        continue;
                }
 
                doltag = emv_get_tag(&doltlv);
 
+               PRINT_INDENT(level);
                fprintf(f, "\tTag %4hx len %02zx ('%s')\n", doltlv.tag, doltlv.len, doltag->name);
        }
 }
 
-static void emv_tag_dump_string(const struct tlv *tlv, const struct emv_tag *tag, FILE *f)
+static void emv_tag_dump_string(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level)
 {
+       PRINT_INDENT(level);
        fprintf(f, "\tString value '");
        fwrite(tlv->value, 1, tlv->len, f);
+       PRINT_INDENT(level);
        fprintf(f, "'\n");
 }
 
@@ -306,13 +314,15 @@ static unsigned long emv_value_numeric(const struct tlv *tlv, unsigned start, un
        return ret;
 }
 
-static void emv_tag_dump_numeric(const struct tlv *tlv, const struct emv_tag *tag, FILE *f)
+static void emv_tag_dump_numeric(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level)
 {
+       PRINT_INDENT(level);
        fprintf(f, "\tNumeric value %lu\n", emv_value_numeric(tlv, 0, tlv->len * 2));
 }
 
-static void emv_tag_dump_yymmdd(const struct tlv *tlv, const struct emv_tag *tag, FILE *f)
+static void emv_tag_dump_yymmdd(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level)
 {
+       PRINT_INDENT(level);
        fprintf(f, "\tDate: 20%02ld.%ld.%ld\n",
                        emv_value_numeric(tlv, 0, 2),
                        emv_value_numeric(tlv, 2, 4),
@@ -324,12 +334,13 @@ static uint32_t emv_get_binary(const unsigned char *S)
        return (S[0] << 24) | (S[1] << 16) | (S[2] << 8) | (S[3] << 0);
 }
 
-static void emv_tag_dump_cvm_list(const struct tlv *tlv, const struct emv_tag *tag, FILE *f)
+static void emv_tag_dump_cvm_list(const struct tlv *tlv, const struct emv_tag *tag, FILE *f, int level)
 {
        uint32_t X, Y;
        int i;
 
        if (tlv->len < 10 || tlv->len % 2) {
+               PRINT_INDENT(level);
                fprintf(f, "\tINVALID!\n");
                return;
        }
@@ -337,7 +348,9 @@ static void emv_tag_dump_cvm_list(const struct tlv *tlv, const struct emv_tag *t
        X = emv_get_binary(tlv->value);
        Y = emv_get_binary(tlv->value + 4);
 
+       PRINT_INDENT(level);
        fprintf(f, "\tX: %d\n", X);
+       PRINT_INDENT(level);
        fprintf(f, "\tY: %d\n", Y);
 
        for (i = 8; i < tlv->len; i+= 2) {
@@ -413,13 +426,14 @@ static void emv_tag_dump_cvm_list(const struct tlv *tlv, const struct emv_tag *t
                        break;
                }
 
+               PRINT_INDENT(level);
                fprintf(f, "\t%02x %02x: '%s' '%s' and '%s' if this CVM is unsuccessful\n",
                                tlv->value[i], tlv->value[i+1],
                                method, condition, (tlv->value[i] & 0x40) ? "continue" : "fail");
        }
 }
 
-bool emv_tag_dump(const struct tlv *tlv, FILE *f)
+bool emv_tag_dump(const struct tlv *tlv, FILE *f, int level)
 {
        if (!tlv) {
                fprintf(f, "NULL\n");
@@ -428,28 +442,29 @@ bool emv_tag_dump(const struct tlv *tlv, FILE *f)
 
        const struct emv_tag *tag = emv_get_tag(tlv);
 
+       PRINT_INDENT(level);
        fprintf(f, "--%2hx[%02zx] '%s':\n", tlv->tag, tlv->len, tag->name);
 
        switch (tag->type) {
        case EMV_TAG_GENERIC:
                break;
        case EMV_TAG_BITMASK:
-               emv_tag_dump_bitmask(tlv, tag, f);
+               emv_tag_dump_bitmask(tlv, tag, f, level);
                break;
        case EMV_TAG_DOL:
-               emv_tag_dump_dol(tlv, tag, f);
+               emv_tag_dump_dol(tlv, tag, f, level);
                break;
        case EMV_TAG_CVM_LIST:
-               emv_tag_dump_cvm_list(tlv, tag, f);
+               emv_tag_dump_cvm_list(tlv, tag, f, level);
                break;
        case EMV_TAG_STRING:
-               emv_tag_dump_string(tlv, tag, f);
+               emv_tag_dump_string(tlv, tag, f, level);
                break;
        case EMV_TAG_NUMERIC:
-               emv_tag_dump_numeric(tlv, tag, f);
+               emv_tag_dump_numeric(tlv, tag, f, level);
                break;
        case EMV_TAG_YYMMDD:
-               emv_tag_dump_yymmdd(tlv, tag, f);
+               emv_tag_dump_yymmdd(tlv, tag, f, level);
                break;
        };
 
index de6d9d1e73e1082d646ad11ed94649fa689dedce..8dbd9e00a92cb29e1266260dde1ca8835f8466a6 100644 (file)
@@ -19,6 +19,6 @@
 #include "tlv.h"
 #include <stdio.h>
 
-bool emv_tag_dump(const struct tlv *tlv, FILE *f);
+bool emv_tag_dump(const struct tlv *tlv, FILE *f, int level);
 
 #endif
index 9264b11068c4a9b00f73baa2954a0d62c78b5a70..8dc9325964142dedc24d6633c4838e7db0bfba61 100644 (file)
@@ -10,9 +10,9 @@
 
 #include "emvcore.h"
 
-static bool print_cb(void *data, const struct tlv *tlv) {
-       emv_tag_dump(tlv, stdout);
-       dump_buffer(tlv->value, tlv->len, stdout);
+static bool print_cb(void *data, const struct tlv *tlv, int level) {
+       emv_tag_dump(tlv, stdout, level);
+       dump_buffer(tlv->value, tlv->len, stdout, level);
 
        return true;
 }
@@ -23,7 +23,7 @@ void TLVPrintFromBuffer(uint8_t *data, int datalen) {
        if (t) {
                PrintAndLog("TLV decoded:");
                
-               tlvdb_visit(t, print_cb, NULL);
+               tlvdb_visit(t, print_cb, NULL, 0);
                tlvdb_free(t);
        } else {
                PrintAndLog("TLV ERROR: Can't parse response as TLV tree.");
index d78f049e07bb7577cf7265fc0d12707420e01926..7feaa9aa9377d794418bde7c3cdaeb5ea33e2c37 100644 (file)
@@ -308,7 +308,7 @@ void tlvdb_add(struct tlvdb *tlvdb, struct tlvdb *other)
        tlvdb->next = other;
 }
 
-void tlvdb_visit(const struct tlvdb *tlvdb, tlv_cb cb, void *data)
+void tlvdb_visit(const struct tlvdb *tlvdb, tlv_cb cb, void *data, int level)
 {
        struct tlvdb *next = NULL;
 
@@ -317,8 +317,8 @@ void tlvdb_visit(const struct tlvdb *tlvdb, tlv_cb cb, void *data)
 
        for (; tlvdb; tlvdb = next) {
                next = tlvdb->next;
-               cb(data, &tlvdb->tag);
-               tlvdb_visit(tlvdb->children, cb, data);
+               cb(data, &tlvdb->tag, level);
+               tlvdb_visit(tlvdb->children, cb, data, level+1);
        }
 }
 
index 3fd3f34776c6154e65afb5679e9576842246b4cc..187781f88767fc6b1f5338fc381abdb71772f720 100644 (file)
@@ -31,7 +31,7 @@ struct tlv {
 };
 
 struct tlvdb;
-typedef bool (*tlv_cb)(void *data, const struct tlv *tlv);
+typedef bool (*tlv_cb)(void *data, const struct tlv *tlv, int level);
 
 struct tlvdb *tlvdb_fixed(tlv_tag_t tag, size_t len, const unsigned char *value);
 struct tlvdb *tlvdb_external(tlv_tag_t tag, size_t len, const unsigned char *value);
@@ -41,7 +41,7 @@ void tlvdb_free(struct tlvdb *tlvdb);
 
 void tlvdb_add(struct tlvdb *tlvdb, struct tlvdb *other);
 
-void tlvdb_visit(const struct tlvdb *tlvdb, tlv_cb cb, void *data);
+void tlvdb_visit(const struct tlvdb *tlvdb, tlv_cb cb, void *data, int level);
 const struct tlv *tlvdb_get(const struct tlvdb *tlvdb, tlv_tag_t tag, const struct tlv *prev);
 
 bool tlv_parse_tl(const unsigned char **buf, size_t *len, struct tlv *tlv);
Impressum, Datenschutz