From fbdb88dda33f366d2c14f0d3140bc66fc68b6117 Mon Sep 17 00:00:00 2001 From: Patrik Flykt Date: Fri, 12 Dec 2014 15:51:35 +0200 Subject: [PATCH] monitor: Create table for IE decoding Create a table for IE decoding and modify vendor IE printing to use this new implementation. Unconditionally print out hexdumps of the IEs in order to be able to verify the decoded IEs and its byte representation. --- monitor/nlmon.c | 100 +++++++++++++++++++++++++++--------------------- 1 file changed, 56 insertions(+), 44 deletions(-) diff --git a/monitor/nlmon.c b/monitor/nlmon.c index 0d25a6bc..42f5e04a 100644 --- a/monitor/nlmon.c +++ b/monitor/nlmon.c @@ -79,6 +79,37 @@ struct nlmon_req { uint8_t version; }; +typedef void (*attr_func_t) (unsigned int level, const char *label, + const void *data, uint16_t size); +enum attr_type { + ATTR_UNSPEC, + ATTR_FLAG, + ATTR_U8, + ATTR_U16, + ATTR_U32, + ATTR_U64, + ATTR_S32, + ATTR_S64, + ATTR_STRING, + ATTR_ADDRESS, + ATTR_BINARY, + ATTR_NESTED, + ATTR_ARRAY, + ATTR_FLAG_OR_U16, + ATTR_CUSTOM, +}; + +struct attr_entry { + uint16_t attr; + const char *str; + enum attr_type type; + union { + const struct attr_entry *nested; + enum attr_type array_type; + attr_func_t function; + }; +}; + static void nlmon_req_free(void *data) { struct nlmon_req *req = data; @@ -258,14 +289,14 @@ static const struct { { } }; -static void print_ie_vendor(unsigned int level, - const void *data, uint16_t size) +static void print_ie_vendor(unsigned int level, const char *label, + const void *data, uint16_t size) { const uint8_t *oui = data; const char *str = NULL; unsigned int i; - print_attr(level, "Vendor specific: len %u", size); + print_attr(level, "%s: len %u", label, size); if (size < 3) { print_hexdump(level + 1, data, size); @@ -285,14 +316,19 @@ static void print_ie_vendor(unsigned int level, else print_attr(level + 1, "%02x:%02x:%02x", oui[0], oui[1], oui[2]); - - print_hexdump(level + 1, data + 3, size - 3); } +static struct attr_entry ie_entry[] = { + {IE_TYPE_VENDOR_SPECIFIC, "Vendor specific", + ATTR_CUSTOM, { .function = print_ie_vendor } }, + { }, +}; + static void print_ie(unsigned int level, const char *label, const void *data, uint16_t size) { struct ie_tlv_iter iter; + int i; print_attr(level, "%s: len %u", label, size); @@ -300,16 +336,23 @@ static void print_ie(unsigned int level, const char *label, while (ie_tlv_iter_next(&iter)) { uint8_t tag = ie_tlv_iter_get_tag(&iter); + struct attr_entry *entry = NULL; - switch (tag) { - case IE_TYPE_VENDOR_SPECIFIC: - print_ie_vendor(level + 1, iter.data, iter.len); - break; - default: - print_attr(level + 1, "Tag %u: len %u", tag, iter.len); - print_hexdump(level + 2, iter.data, iter.len); - break; + for (i = 0; ie_entry[i].str; i++) { + if (ie_entry[i].attr == tag) { + entry = &ie_entry[i]; + break; + } } + + if (entry && entry->function) + entry->function(level + 1, entry->str, + iter.data, iter.len); + else + print_attr(level + 1, "Tag %u: len %u", tag, + iter.len); + + print_hexdump(level + 2, iter.data, iter.len); } } @@ -440,37 +483,6 @@ static void print_cipher_suites(unsigned int level, const char *label, } } -typedef void (*attr_func_t) (unsigned int level, const char *label, - const void *data, uint16_t size); -enum attr_type { - ATTR_UNSPEC, - ATTR_FLAG, - ATTR_U8, - ATTR_U16, - ATTR_U32, - ATTR_U64, - ATTR_S32, - ATTR_S64, - ATTR_STRING, - ATTR_ADDRESS, - ATTR_BINARY, - ATTR_NESTED, - ATTR_ARRAY, - ATTR_FLAG_OR_U16, - ATTR_CUSTOM, -}; - -struct attr_entry { - uint16_t attr; - const char *str; - enum attr_type type; - union { - const struct attr_entry *nested; - enum attr_type array_type; - attr_func_t function; - }; -}; - static const struct attr_entry iftype_table[] = { { NL80211_IFTYPE_ADHOC, "Ad-hoc", ATTR_FLAG }, { NL80211_IFTYPE_STATION, "Station", ATTR_FLAG },