diff options
Diffstat (limited to 'epan/dissectors/packet-iapp.c')
-rw-r--r-- | epan/dissectors/packet-iapp.c | 279 |
1 files changed, 137 insertions, 142 deletions
diff --git a/epan/dissectors/packet-iapp.c b/epan/dissectors/packet-iapp.c index ac95ba5c21..3608e6580a 100644 --- a/epan/dissectors/packet-iapp.c +++ b/epan/dissectors/packet-iapp.c @@ -24,6 +24,7 @@ #include "config.h" #include <epan/packet.h> +#include <epan/expert.h> #include <epan/to_str.h> #include <epan/oui.h> @@ -34,12 +35,29 @@ void proto_reg_handoff_iapp(void); static int proto_iapp = -1; static int hf_iapp_version = -1; static int hf_iapp_type = -1; +static int hf_iapp_cap_forwarding = -1; +static int hf_iapp_cap_wep = -1; +static int hf_iapp_auth_status = -1; +static int hf_iapp_auth_string = -1; +static int hf_iapp_auth_uint = -1; +static int hf_iapp_auth_ipaddr = -1; +static int hf_iapp_auth_trailer = -1; +static int hf_iapp_pdu_ssid = -1; +static int hf_iapp_pdu_bytes = -1; +static int hf_iapp_pdu_uint = -1; +static int hf_iapp_pdu_phytype = -1; +static int hf_iapp_pdu_regdomain = -1; +static int hf_iapp_pdu_oui_ident = -1; /* Initialize the subtree pointers */ static gint ett_iapp = -1; static gint ett_iapp_pdu = -1; +static gint ett_iapp_subpdu = -1; static gint ett_iapp_cap = -1; static gint ett_iapp_auth = -1; +static gint ett_iapp_authinfo = -1; + +static expert_field ei_iapp_no_pdus = EI_INIT; #define UDP_PORT_IAPP 2313 @@ -95,18 +113,6 @@ static gint ett_iapp_auth = -1; #define IAPP_AUTH_IPADDR 0x0e #define IAPP_AUTH_TRAILER 0xff - -typedef struct _e_iapphdr { - guint8 ia_version; - guint8 ia_type; -} e_iapphdr; - -typedef struct _e_pduhdr { - guint8 pdu_type; - guint8 pdu_len_h; - guint8 pdu_len_l; -} e_pduhdr; - static const value_string iapp_vals[] = { {IAPP_ANNOUNCE_REQUEST, "Announce Request"}, {IAPP_ANNOUNCE_RESPONSE, "Announce Response"}, @@ -180,45 +186,29 @@ static const value_string iapp_auth_type_vals[] = { /* dissect a capability bit field */ -static void dissect_caps(proto_item *pitem, tvbuff_t *tvb, int offset) +static void dissect_caps(proto_tree *tree, tvbuff_t *tvb, int offset) { proto_tree *captree; - int bit, val, thisbit; - const gchar *strval; - gchar bitval[4+1+4+1]; /* "xxxx xxxx\0" */ - captree = proto_item_add_subtree(pitem, ett_iapp_cap); - val = tvb_get_guint8(tvb, offset + 3); - - for (bit = 7; bit >= 0; bit--) - { - thisbit = 1 << bit; - strval = try_val_to_str(thisbit, iapp_cap_vals); - if (strval) - { - other_decode_bitfield_value(bitval, val, thisbit, 8); - proto_tree_add_text(captree, tvb, offset + 3, 1, "%s %s: %s", - bitval, strval, val & thisbit ? "Yes" : "No"); - } - } + captree = proto_tree_add_subtree(tree, tvb, offset, 1, ett_iapp_cap, NULL, "Capabilities"); + proto_tree_add_item(captree, hf_iapp_cap_forwarding, tvb, offset, 1, ENC_NA); + proto_tree_add_item(captree, hf_iapp_cap_wep, tvb, offset, 1, ENC_NA); } static void -append_authval_str(proto_item *ti, int type, int len, tvbuff_t *tvb, int offset) +add_authval_str(proto_tree *tree, int type, int len, tvbuff_t *tvb, int offset) { - int z, val; - - proto_item_append_text(ti, " Value: "); + int val; switch (type) { case IAPP_AUTH_STATUS: - proto_item_append_text(ti, "%s", tvb_get_guint8(tvb, offset + 3) ? "Authenticated" : "Not authenticated"); + val = tvb_get_guint8(tvb, offset); + proto_tree_add_uint_format_value(tree, hf_iapp_auth_status, tvb, offset, 1, val, "%s", val ? "Authenticated" : "Not authenticated"); break; case IAPP_AUTH_USERNAME: case IAPP_AUTH_PROVNAME: - proto_item_append_text(ti, "\"%s\"", - tvb_format_text(tvb, offset + 3, len)); + proto_tree_add_item(tree, hf_iapp_auth_string, tvb, offset, 1, ENC_ASCII|ENC_NA); break; case IAPP_AUTH_RXPKTS: case IAPP_AUTH_TXPKTS: @@ -227,22 +217,19 @@ append_authval_str(proto_item *ti, int type, int len, tvbuff_t *tvb, int offset) case IAPP_AUTH_RXGWORDS: case IAPP_AUTH_TXGWORDS: case IAPP_AUTH_VOLLIMIT: - val = tvb_get_ntohl(tvb, offset + 3); - proto_item_append_text(ti, "%d", val); + proto_tree_add_item(tree, hf_iapp_auth_uint, tvb, offset, 4, ENC_BIG_ENDIAN); break; case IAPP_AUTH_LOGINTIME: case IAPP_AUTH_TIMELIMIT: case IAPP_AUTH_ACCCYCLE: - val = tvb_get_ntohl(tvb, offset + 3); - proto_item_append_text(ti, "%d seconds", val); + val = tvb_get_ntohl(tvb, offset); + proto_tree_add_uint_format_value(tree, hf_iapp_auth_uint, tvb, offset, 4, val, "%d seconds", val); break; case IAPP_AUTH_IPADDR: - proto_item_append_text(ti, "%s", tvb_ip_to_str(tvb, offset + 3)); + proto_tree_add_item(tree, hf_iapp_auth_ipaddr, tvb, offset, 4, ENC_BIG_ENDIAN); break; case IAPP_AUTH_TRAILER: - for (z = 0; z < len; z++) - proto_item_append_text(ti, "%s%02x", z ? " " : "", - tvb_get_guint8(tvb, offset + 3 + z)); + proto_tree_add_item(tree, hf_iapp_auth_trailer, tvb, offset, len, ENC_NA); break; } } @@ -251,23 +238,22 @@ append_authval_str(proto_item *ti, int type, int len, tvbuff_t *tvb, int offset) static void dissect_authinfo(proto_item *pitem, tvbuff_t *tvb, int offset, int sumlen) { - proto_tree *authtree; - proto_item *ti; - e_pduhdr pduhdr; - int len; + proto_tree *authtree, *value_tree; + guint8 pdu_type; + guint16 len; authtree = proto_item_add_subtree(pitem, ett_iapp_auth); while (sumlen > 0) { - tvb_memcpy(tvb, (guint8 *)&pduhdr, offset, sizeof(e_pduhdr)); - len = (((int)pduhdr.pdu_len_h) << 8) + pduhdr.pdu_len_l; + pdu_type = tvb_get_guint8(tvb, offset); + len = tvb_get_ntohs(tvb, offset+1); - ti = proto_tree_add_text(authtree, tvb, offset, len + 3, - "%s(%d)", - val_to_str_const(pduhdr.pdu_type, iapp_auth_type_vals, "Unknown PDU Type"), - pduhdr.pdu_type); - append_authval_str(ti, pduhdr.pdu_type, len, tvb, offset); + value_tree = proto_tree_add_subtree_format(authtree, tvb, offset, len + 3, + ett_iapp_authinfo, NULL, "%s (%d)", + val_to_str_const(pdu_type, iapp_auth_type_vals, "Unknown PDU Type"), + pdu_type); + add_authval_str(value_tree, pdu_type, len, tvb, offset+3); sumlen -= (len + 3); offset += (len + 3); @@ -277,85 +263,55 @@ static void dissect_authinfo(proto_item *pitem, tvbuff_t *tvb, int offset, int s /* get displayable values of PDU contents */ static gboolean -append_pduval_str(proto_item *ti, int type, int len, tvbuff_t *tvb, int offset, +append_pduval_str(proto_tree *tree, int type, int len, tvbuff_t *tvb, int offset, gboolean is_fhss) { - int z, val; - const gchar *strval; - - proto_item_append_text(ti, " Value: "); + int val; switch (type) { case IAPP_PDU_SSID: - proto_item_append_text(ti, "\"%s\"", - tvb_format_text(tvb, offset + 3, len)); + proto_tree_add_item(tree, hf_iapp_pdu_ssid, tvb, offset, len, ENC_ASCII|ENC_NA); break; case IAPP_PDU_BSSID: case IAPP_PDU_OLDBSSID: case IAPP_PDU_MSADDR: - for (z = 0; z < len; z++) - proto_item_append_text(ti, "%s%02x", z ? ":" : "", - tvb_get_guint8(tvb, offset + 3 + z)); + proto_tree_add_item(tree, hf_iapp_pdu_bytes, tvb, offset, len, ENC_NA); break; case IAPP_PDU_CAPABILITY: - { - int mask, first = 1; - - val = tvb_get_guint8(tvb, offset + 3); - proto_item_append_text(ti, "%02x (", val); - for (mask = 0x80; mask; mask >>= 1) - if (val & mask) - { - strval = try_val_to_str(mask, iapp_cap_vals); - if (strval) - { - if (!first) - proto_item_append_text(ti, " "); - proto_item_append_text(ti, "%s", strval); - first=0; - } - } - proto_item_append_text(ti, ")"); + dissect_caps(tree, tvb, offset); break; - } case IAPP_PDU_ANNOUNCEINT: - val = tvb_get_ntohs(tvb, offset + 3); - proto_item_append_text(ti, "%d seconds", val); + val = tvb_get_ntohs(tvb, offset); + proto_tree_add_uint_format_value(tree, hf_iapp_pdu_uint, tvb, offset, 2, val, "%d seconds", val); break; case IAPP_PDU_HOTIMEOUT: case IAPP_PDU_BEACONINT: - val = tvb_get_ntohs(tvb, offset + 3); - proto_item_append_text(ti, "%d Kus", val); + val = tvb_get_ntohs(tvb, offset); + proto_tree_add_uint_format_value(tree, hf_iapp_pdu_uint, tvb, offset, 2, val, "%d Kus", val); break; case IAPP_PDU_MESSAGEID: - val = tvb_get_ntohs(tvb, offset + 3); - proto_item_append_text(ti, "%d", val); + proto_tree_add_item(tree, hf_iapp_pdu_uint, tvb, offset, 2, ENC_BIG_ENDIAN); break; case IAPP_PDU_PHYTYPE: - val = tvb_get_guint8(tvb, offset + 3); - strval = val_to_str_const(val, iapp_phy_vals, "Unknown"); - proto_item_append_text(ti, "%s", strval); - is_fhss = (val == IAPP_PHY_FHSS); + proto_tree_add_item(tree, hf_iapp_pdu_phytype, tvb, offset, 1, ENC_BIG_ENDIAN); + is_fhss = (tvb_get_guint8(tvb, offset) == IAPP_PHY_FHSS); break; case IAPP_PDU_REGDOMAIN: - val = tvb_get_guint8(tvb, offset + 3); - strval = val_to_str_const(val, iapp_dom_vals, "Unknown"); - proto_item_append_text(ti, "%s", strval); + proto_tree_add_item(tree, hf_iapp_pdu_regdomain, tvb, offset, 1, ENC_BIG_ENDIAN); break; case IAPP_PDU_CHANNEL: - val = tvb_get_guint8(tvb, offset + 3); if (is_fhss) - proto_item_append_text(ti, "Pattern set %d, sequence %d", - ((val >> 6) & 3) + 1, (val & 31) + 1); + { + val = tvb_get_guint8(tvb, offset); + proto_tree_add_uint_format(tree, hf_iapp_pdu_uint, tvb, offset, 1, val, + "Pattern set %d, sequence %d", ((val >> 6) & 3) + 1, (val & 31) + 1); + } else - proto_item_append_text(ti, "%d", val); + proto_tree_add_item(tree, hf_iapp_pdu_uint, tvb, offset, 1, ENC_NA); break; case IAPP_PDU_OUIIDENT: - for (val = z = 0; z < 3; z++) - val = (val << 8) | tvb_get_guint8(tvb, offset + 3 + z); - strval = val_to_str_const(val, oui_vals, "Unknown"); - proto_item_append_text(ti, "%s", strval); + proto_tree_add_item(tree, hf_iapp_pdu_oui_ident, tvb, offset, 3, ENC_BIG_ENDIAN); break; } return is_fhss; @@ -364,36 +320,34 @@ append_pduval_str(proto_item *ti, int type, int len, tvbuff_t *tvb, int offset, /* code to dissect a list of PDUs */ static void -dissect_pdus(tvbuff_t *tvb, int offset, proto_tree *pdutree, int pdulen) +dissect_pdus(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *pdutree, proto_item *pduitem, int pdulen) { - e_pduhdr pduhdr; - int len; + guint8 pdu_type; + guint16 len; proto_item *ti; gboolean is_fhss; + proto_tree *subtree; if (!pdulen) { - proto_tree_add_text(pdutree, tvb, offset, 0, "No PDUs found"); + expert_add_info(pinfo, pduitem, &ei_iapp_no_pdus); return; } is_fhss = FALSE; while (pdulen > 0) { - tvb_memcpy(tvb, (guint8 *)&pduhdr, offset, sizeof(e_pduhdr)); - len = (((int)pduhdr.pdu_len_h) << 8) + pduhdr.pdu_len_l; - - ti = proto_tree_add_text(pdutree, tvb, offset, len + 3, - "%s(%d)", - val_to_str_const(pduhdr.pdu_type, iapp_pdu_type_vals, "Unknown PDU Type"), - pduhdr.pdu_type); - is_fhss = append_pduval_str(ti, pduhdr.pdu_type, len, tvb, - offset, is_fhss); + pdu_type = tvb_get_guint8(tvb, offset); + len = tvb_get_ntohs(tvb, offset+1); - if (pduhdr.pdu_type == IAPP_PDU_CAPABILITY) - dissect_caps(ti, tvb, offset); + subtree = proto_tree_add_subtree_format(pdutree, tvb, offset, len + 3, + ett_iapp_subpdu, &ti, "%s (%d)", + val_to_str_const(pdu_type, iapp_pdu_type_vals, "Unknown PDU Type"), + pdu_type); + is_fhss = append_pduval_str(subtree, pdu_type, len, tvb, + offset+3, is_fhss); - if (pduhdr.pdu_type == IAPP_PDU_AUTHINFO) + if (pdu_type == IAPP_PDU_AUTHINFO) dissect_authinfo(ti, tvb, offset + 3, len); pdulen -= (len + 3); @@ -405,21 +359,19 @@ dissect_pdus(tvbuff_t *tvb, int offset, proto_tree *pdutree, int pdulen) static void dissect_iapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { - proto_item *ti; + proto_item *ti, *pduitem; proto_tree *iapp_tree, *pdutree; - e_iapphdr ih; - int ia_version; - int ia_type; + guint8 ia_version; + guint8 ia_type; const gchar *codestrval; col_set_str(pinfo->cinfo, COL_PROTOCOL, "IAPP"); col_clear(pinfo->cinfo, COL_INFO); - tvb_memcpy(tvb, (guint8 *)&ih, 0, sizeof(e_iapphdr)); + ia_version = tvb_get_guint8(tvb, 0); + ia_type = tvb_get_guint8(tvb, 1); - ia_version = (int)ih.ia_version; - ia_type = (int)ih.ia_type; codestrval = val_to_str_const(ia_type, iapp_vals, "Unknown Packet"); col_add_fstr(pinfo->cinfo, COL_INFO, "%s(%d) (version=%d)", codestrval, ia_type, ia_version); @@ -430,19 +382,14 @@ dissect_iapp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) /* common header for all IAPP frames */ - proto_tree_add_uint(iapp_tree, hf_iapp_version, tvb, 0, 1, - ih.ia_version); - proto_tree_add_uint_format_value(iapp_tree, hf_iapp_type, tvb, 1, 1, - ih.ia_type, "%s(%d)", codestrval, ia_type); + proto_tree_add_item(iapp_tree, hf_iapp_version, tvb, 0, 1, ENC_NA); + proto_tree_add_item(iapp_tree, hf_iapp_type, tvb, 1, 1, ENC_NA); pdutree = proto_tree_add_subtree(iapp_tree, tvb, 2, -1, - ett_iapp_pdu, NULL, "Protocol data units"); + ett_iapp_pdu, &pduitem, "Protocol data units"); - if (pdutree) - { - dissect_pdus(tvb, 2, pdutree, + dissect_pdus(tvb, pinfo, 2, pdutree, pduitem, tvb_length_remaining(tvb, 2)); - } } } @@ -462,24 +409,72 @@ proto_register_iapp(void) { "Version", "iapp.version", FT_UINT8, BASE_DEC, NULL, 0x00, NULL, HFILL } }, { &hf_iapp_type, - { "Type", "iapp.type", FT_UINT8, BASE_DEC, NULL, 0x00, NULL, HFILL } + { "Type", "iapp.type", FT_UINT8, BASE_DEC, VALS(iapp_vals), 0x00, NULL, HFILL } + }, + { &hf_iapp_cap_forwarding, + { "Forwarding", "iapp.cap.forwarding", FT_BOOLEAN, 8, TFS(&tfs_yes_no), IAPP_CAP_FORWARDING, NULL, HFILL } + }, + { &hf_iapp_cap_wep, + { "WEP", "iapp.cap.wep", FT_BOOLEAN, 8, TFS(&tfs_yes_no), IAPP_CAP_WEP, NULL, HFILL } + }, + { &hf_iapp_auth_status, + { "Status", "iapp.auth.status", FT_UINT8, BASE_DEC, NULL, 0x00, NULL, HFILL } + }, + { &hf_iapp_auth_uint, + { "Value", "iapp.auth.uint", FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } + }, + { &hf_iapp_auth_string, + { "Value", "iapp.auth.string", FT_STRING, BASE_NONE, NULL, 0x00, NULL, HFILL } + }, + { &hf_iapp_auth_ipaddr, + { "IP Address", "iapp.auth.ipaddr", FT_IPv4, BASE_NONE, NULL, 0x00, NULL, HFILL } + }, + { &hf_iapp_auth_trailer, + { "Trailer", "iapp.auth.trailer", FT_BYTES, BASE_NONE, NULL, 0x00, NULL, HFILL } + }, + { &hf_iapp_pdu_ssid, + { "SSID", "iapp.pdu.ssid", FT_STRING, BASE_NONE, NULL, 0x00, NULL, HFILL } + }, + { &hf_iapp_pdu_bytes, + { "Value", "iapp.pdu.bytes", FT_BYTES, BASE_NONE, NULL, 0x00, NULL, HFILL } + }, + { &hf_iapp_pdu_uint, + { "Value", "iapp.pdu.uint", FT_UINT32, BASE_DEC, NULL, 0x00, NULL, HFILL } + }, + { &hf_iapp_pdu_phytype, + { "PHY Type", "iapp.pdu.phytype", FT_UINT8, BASE_DEC, VALS(iapp_phy_vals), 0x00, NULL, HFILL } + }, + { &hf_iapp_pdu_regdomain, + { "Reg domain", "iapp.pdu.regdomain", FT_UINT8, BASE_DEC, VALS(iapp_dom_vals), 0x00, NULL, HFILL } + }, + { &hf_iapp_pdu_oui_ident, + { "OUI", "iapp.pdu.oui_ident", FT_UINT24, BASE_DEC, VALS(oui_vals), 0x00, NULL, HFILL } }, }; static gint *ett[] = { &ett_iapp, &ett_iapp_pdu, + &ett_iapp_subpdu, &ett_iapp_cap, - &ett_iapp_auth + &ett_iapp_auth, + &ett_iapp_authinfo + }; + + static ei_register_info ei[] = { + { &ei_iapp_no_pdus, { "iapp.no_pdus", PI_PROTOCOL, PI_NOTE, "No PDUs found", EXPFILL }}, }; + expert_module_t* expert_iapp; + /* Register the protocol name and description */ - proto_iapp = proto_register_protocol("Inter-Access-Point Protocol", - "IAPP", "iapp"); + proto_iapp = proto_register_protocol("Inter-Access-Point Protocol", "IAPP", "iapp"); /* Required function calls to register the header fields and subtrees used */ proto_register_field_array(proto_iapp, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); + expert_iapp = expert_register_protocol(proto_iapp); + expert_register_field_array(expert_iapp, ei, array_length(ei)); } |