aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-iapp.c
diff options
context:
space:
mode:
Diffstat (limited to 'epan/dissectors/packet-iapp.c')
-rw-r--r--epan/dissectors/packet-iapp.c279
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));
}