From 756882f568169ee247463370307c4b2b297deed5 Mon Sep 17 00:00:00 2001 From: jmayer Date: Sat, 20 Jun 2009 16:07:01 +0000 Subject: Lots of improvements to GLPB dissector - still lot of stuff missing. git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@28781 f5534014-38df-0310-8fa8-9805f1628bb7 --- epan/dissectors/packet-glbp.c | 370 ++++++++++++++++++++++++++++-------------- 1 file changed, 252 insertions(+), 118 deletions(-) (limited to 'epan/dissectors/packet-glbp.c') diff --git a/epan/dissectors/packet-glbp.c b/epan/dissectors/packet-glbp.c index 596d1bf781..2a3e2d355e 100644 --- a/epan/dissectors/packet-glbp.c +++ b/epan/dissectors/packet-glbp.c @@ -54,47 +54,67 @@ static int proto_glbp = -1; /* glbp header? */ static gint hf_glbp_version = -1; -static gint hf_glbp_type1 = -1; -static gint hf_glbp_unknown1 = -1; +static gint hf_glbp_forwarder = -1; +static gint hf_glbp_group = -1; static gint hf_glbp_unknown2 = -1; static gint hf_glbp_somemac = -1; -static gint hf_glbp_type2 = -1; -static gint hf_glbp_length2 = -1; -/* glbp type2 = 1 - hello */ -static gint hf_glbp_unknown11 = -1; -static gint hf_glbp_priority = -1; -static gint hf_glbp_unknown12 = -1; -static gint hf_glbp_helloint = -1; -static gint hf_glbp_holdint = -1; -static gint hf_glbp_redirect = -1; -static gint hf_glbp_timeout = -1; -static gint hf_glbp_unknown13 = -1; -static gint hf_glbp_numips = -1; -static gint hf_glbp_lenip = -1; -static gint hf_glbp_virtualip = -1; -/* glbp type2 = 2 - Request/Response??? */ -static gint hf_glbp_subtype = -1; -static gint hf_glbp_unknown21 = -1; -static gint hf_glbp_virtualmac = -1; +static gint hf_glbp_tlv = -1; +static gint hf_glbp_type = -1; +static gint hf_glbp_length = -1; +/* glbp type = 1 - hello */ +static gint hf_glbp_hello_unknown11 = -1; +static gint hf_glbp_hello_priority = -1; +static gint hf_glbp_hello_unknown12 = -1; +static gint hf_glbp_hello_helloint = -1; +static gint hf_glbp_hello_holdint = -1; +static gint hf_glbp_hello_redirect = -1; +static gint hf_glbp_hello_timeout = -1; +static gint hf_glbp_hello_unknown13 = -1; +static gint hf_glbp_hello_numips = -1; +static gint hf_glbp_hello_lenip = -1; +static gint hf_glbp_hello_virtualip = -1; +/* glbp type = 2 - Request/Response??? */ +static gint hf_glbp_reqresp_type = -1; +static gint hf_glbp_reqresp_unknown21 = -1; +static gint hf_glbp_reqresp_virtualmac = -1; +/* glbp type = 3 - Auth */ +static gint hf_glbp_auth_authtype = -1; +static gint hf_glbp_auth_authlength = -1; +static gint hf_glbp_auth_plainpass = -1; +static gint hf_glbp_auth_md5hash = -1; +static gint hf_glbp_auth_md5chainindex = -1; +static gint hf_glbp_auth_md5chainhash = -1; +static gint hf_glbp_auth_authunknown = -1; /* unknown type */ -static gint hf_glbp_unknown6 = -1; +static gint hf_glbp_unknown_data = -1; static gint ett_glbp = -1; +static gint ett_glbp_tlv = -1; -static const value_string glbp_type2_vals[] = { +static const value_string glbp_type_vals[] = { { 1, "Hello" }, { 2, "Request/Response?" }, + { 3, "Auth" }, { 0, NULL } }; -static const value_string glbp_subtype_vals[] = { +static const value_string glbp_reqresp_type_vals[] = { { 0, "Request?" }, { 2, "Response?" }, { 0, NULL } }; +static const value_string glbp_auth_type_vals[] = { + { 0, "None" }, + { 1, "Plain text" }, + { 2, "MD5 string" }, + { 3, "MD5 chain" }, + + { 0, NULL } +}; + #if 0 static const value_string glbp_loadbalancing_vals[] = { { x, "None (AVG only)" }, @@ -105,15 +125,6 @@ static const value_string glbp_loadbalancing_vals[] = { { 0, NULL } }; - -static const value_string glbp_authentication_vals[] = { - { x, "None" }, - { x, "Plain text" }, - { x, "MD5" }, - - { 0, NULL } -}; - static const value_string glbp_vgstate_vals[] = { { x, "Active" }, { x, "Standby" }, @@ -135,78 +146,167 @@ static const value_string glbp_vfstate_vals[] = { }; #endif +static void +dissect_glbp_hello(tvbuff_t *tvb, int offset, guint32 length _U_, + packet_info *pinfo _U_, proto_tree *tlv_tree) +{ + proto_tree_add_item(tlv_tree, hf_glbp_hello_unknown11, tvb, offset, 3, FALSE); + offset += 3; + proto_tree_add_item(tlv_tree, hf_glbp_hello_priority, tvb, offset, 1, FALSE); + offset++; + proto_tree_add_item(tlv_tree, hf_glbp_hello_unknown12, tvb, offset, 2, FALSE); + offset += 2; + proto_tree_add_item(tlv_tree, hf_glbp_hello_helloint, tvb, offset, 4, FALSE); + offset += 4; + proto_tree_add_item(tlv_tree, hf_glbp_hello_holdint, tvb, offset, 4, FALSE); + offset += 4; + proto_tree_add_item(tlv_tree, hf_glbp_hello_redirect, tvb, offset, 2, FALSE); + offset += 2; + proto_tree_add_item(tlv_tree, hf_glbp_hello_timeout, tvb, offset, 2, FALSE); + offset += 2; + proto_tree_add_item(tlv_tree, hf_glbp_hello_unknown13, tvb, offset, 2, FALSE); + offset += 2; + proto_tree_add_item(tlv_tree, hf_glbp_hello_numips, tvb, offset, 1, FALSE); + offset++; + proto_tree_add_item(tlv_tree, hf_glbp_hello_lenip, tvb, offset, 1, FALSE); + offset++; + proto_tree_add_item(tlv_tree, hf_glbp_hello_virtualip, tvb, offset, 4, FALSE); + offset += 4; +} + + +static void +dissect_glbp_reqresp(tvbuff_t *tvb, int offset, guint32 length _U_, + packet_info *pinfo _U_, proto_tree *tlv_tree) +{ + proto_tree_add_item(tlv_tree, hf_glbp_reqresp_type, tvb, offset, 1, FALSE); + offset++; + proto_tree_add_item(tlv_tree, hf_glbp_reqresp_unknown21, tvb, offset, 11, FALSE); + offset += 11; + proto_tree_add_item(tlv_tree, hf_glbp_reqresp_virtualmac, tvb, offset, 6, FALSE); + offset += 6 ; +} + +static void +dissect_glbp_auth(tvbuff_t *tvb, int offset, guint32 length, + packet_info *pinfo _U_, proto_tree *tlv_tree) +{ + guint32 authtype; + guint32 authlength; + + proto_tree_add_item(tlv_tree, hf_glbp_auth_authtype, tvb, offset, 1, FALSE); + authtype = tvb_get_guint8(tvb, offset); + offset++; + proto_tree_add_item(tlv_tree, hf_glbp_auth_authlength, tvb, offset, 1, FALSE); + authlength = tvb_get_guint8(tvb, offset); + offset++; + switch(authtype) { + case 1: + proto_tree_add_item(tlv_tree, hf_glbp_auth_plainpass, tvb, offset, authlength, FALSE); + break; + case 2: + proto_tree_add_item(tlv_tree, hf_glbp_auth_md5hash, tvb, offset, authlength, FALSE); + break; + case 3: + proto_tree_add_item(tlv_tree, hf_glbp_auth_md5chainindex, tvb, offset, 4, FALSE); + proto_tree_add_item(tlv_tree, hf_glbp_auth_md5chainhash, tvb, offset+4, authlength-4, FALSE); + break; + default: + proto_tree_add_item(tlv_tree, hf_glbp_auth_authunknown, tvb, offset, authlength, FALSE); + break; + } + offset += length; +} + +static void +dissect_glbp_unknown(tvbuff_t *tvb, int offset, guint32 length, + packet_info *pinfo _U_, proto_tree *tlv_tree) +{ + proto_tree_add_item(tlv_tree, hf_glbp_unknown_data, tvb, offset, length, FALSE); + offset += length; +} + static int dissect_glbp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { proto_tree *glbp_tree = NULL; + proto_tree *tlv_tree = NULL; proto_item *ti = NULL; - guint32 type2; - guint32 length2; - - type2 = tvb_get_guint8(tvb, 12); + guint32 type; + int offset = 0; + guint32 length; + guint32 group; - if (check_col(pinfo->cinfo, COL_PROTOCOL)) - col_set_str(pinfo->cinfo, COL_PROTOCOL, "GLBP"); - if (check_col(pinfo->cinfo, COL_INFO)) - col_add_str(pinfo->cinfo, COL_INFO, val_to_str(type2, - glbp_type2_vals, "Type 0x%02x")); + group = tvb_get_ntohs(tvb, 2); - length2 = tvb_get_guint8(tvb, 13); + col_set_str(pinfo->cinfo, COL_PROTOCOL, "GLBP"); + col_add_fstr(pinfo->cinfo, COL_INFO, "G: %d", group); if (tree) { ti = proto_tree_add_item(tree, proto_glbp, tvb, 0, -1, FALSE); glbp_tree = proto_item_add_subtree(ti, ett_glbp); /* glbp header? */ - proto_tree_add_item(glbp_tree, hf_glbp_version, tvb, 0, 1, FALSE); - proto_tree_add_item(glbp_tree, hf_glbp_type1, tvb, 1, 1, FALSE); - proto_tree_add_item(glbp_tree, hf_glbp_unknown1, tvb, 2, 2, FALSE); - proto_tree_add_item(glbp_tree, hf_glbp_unknown2, tvb, 4, 2, FALSE); - proto_tree_add_item(glbp_tree, hf_glbp_somemac, tvb, 6, 6, FALSE); - proto_tree_add_item(glbp_tree, hf_glbp_type2, tvb, 12, 1, FALSE); - proto_tree_add_item(glbp_tree, hf_glbp_length2, tvb, 13, 1, FALSE); - - switch(type2) { - case 1: /* Hello */ - proto_tree_add_item(glbp_tree, hf_glbp_unknown11, tvb, 14, 3, FALSE); - proto_tree_add_item(glbp_tree, hf_glbp_priority, tvb, 17, 1, FALSE); - proto_tree_add_item(glbp_tree, hf_glbp_unknown12, tvb, 18, 2, FALSE); - proto_tree_add_item(glbp_tree, hf_glbp_helloint, tvb, 20, 4, FALSE); - proto_tree_add_item(glbp_tree, hf_glbp_holdint, tvb, 24, 4, FALSE); - proto_tree_add_item(glbp_tree, hf_glbp_redirect, tvb, 28, 2, FALSE); - proto_tree_add_item(glbp_tree, hf_glbp_timeout, tvb, 30, 2, FALSE); - proto_tree_add_item(glbp_tree, hf_glbp_unknown13, tvb, 32, 2, FALSE); - proto_tree_add_item(glbp_tree, hf_glbp_numips, tvb, 34, 1, FALSE); - proto_tree_add_item(glbp_tree, hf_glbp_lenip, tvb, 35, 1, FALSE); - proto_tree_add_item(glbp_tree, hf_glbp_virtualip, tvb, 36, 4, FALSE); - break; - case 2: - proto_tree_add_item(glbp_tree, hf_glbp_subtype, tvb, 14, 1, FALSE); - proto_tree_add_item(glbp_tree, hf_glbp_unknown21, tvb, 15, 11, FALSE); - proto_tree_add_item(glbp_tree, hf_glbp_virtualmac, tvb, 26, 6, FALSE); - break; - default: - proto_tree_add_item(glbp_tree, hf_glbp_unknown6, tvb, 14, length2-2, FALSE); - break; + proto_tree_add_item(glbp_tree, hf_glbp_version, tvb, offset, 1, FALSE); + offset++; + proto_tree_add_item(glbp_tree, hf_glbp_forwarder, tvb, offset, 1, FALSE); + offset++; + proto_tree_add_item(glbp_tree, hf_glbp_group, tvb, offset, 2, FALSE); + offset += 2; + proto_tree_add_item(glbp_tree, hf_glbp_unknown2, tvb, offset, 2, FALSE); + offset += 2; + proto_tree_add_item(glbp_tree, hf_glbp_somemac, tvb, offset, 6, FALSE); + offset += 6; + while (tvb_length_remaining(tvb, offset) > 0) { + + type = tvb_get_guint8(tvb, offset); + length = tvb_get_guint8(tvb, offset+1) - 2; + + ti = proto_tree_add_item(glbp_tree, hf_glbp_tlv, tvb, offset, length+2, FALSE); + tlv_tree = proto_item_add_subtree(ti, ett_glbp_tlv); + proto_item_append_text(ti, " l=%d, t=%s", length+2, + val_to_str(type, glbp_type_vals, "%d")); + + proto_tree_add_item(tlv_tree, hf_glbp_type, tvb, offset, 1, FALSE); + offset++; + proto_tree_add_item(tlv_tree, hf_glbp_length, tvb, offset, 1, FALSE); + offset++; + col_append_fstr(pinfo->cinfo, COL_INFO, ", %s", + val_to_str(type, glbp_type_vals, "%d")); + + switch(type) { + case 1: /* Hello */ + dissect_glbp_hello(tvb, offset, length, pinfo, tlv_tree); + break; + case 2: /* Request/Response */ + dissect_glbp_reqresp(tvb, offset, length, pinfo, tlv_tree); + break; + case 3: /* Plaintext auth */ + dissect_glbp_auth(tvb, offset, length, pinfo, tlv_tree); + break; + default: + dissect_glbp_unknown(tvb, offset, length, pinfo, tlv_tree); + break; + } + offset += length; } - } - return 12 + length2; + return offset; } static gboolean test_glbp(tvbuff_t *tvb, packet_info *pinfo) { - guint32 type1; + guint32 forwarder; if ( tvb_length(tvb) < 2) return FALSE; - type1 = tvb_get_guint8(tvb, 1); + forwarder = tvb_get_guint8(tvb, 1); if (tvb_get_guint8(tvb, 0) != 1 /* version? */ - || type1 > 2 + || forwarder > 4 || pinfo->srcport != pinfo->destport #if 0 /* XXX */ - || type1 == 0 && pinfo->net_dst != ipv4:224.0.0.102 - || type1 == 0 && pinfo->dl_src != ether:c2-00-7c-b8-00-00 + || forwarder == 0 && pinfo->net_dst != ipv4:224.0.0.102 + || forwarder == 0 && pinfo->dl_src != ether:c2-00-7c-b8-00-00 #endif ) { return FALSE; @@ -230,15 +330,15 @@ proto_register_glbp(void) static hf_register_info hf[] = { /* Header */ { &hf_glbp_version, - { "Version?", "glbp.version", FT_UINT8, BASE_DEC, NULL, + { "Version?", "glbp.version", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, - { &hf_glbp_type1, - { "Type1???", "glbp.type1", FT_UINT8, BASE_DEC, NULL, + { &hf_glbp_forwarder, + { "Forwarder???", "glbp.forwarder", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, - { &hf_glbp_unknown1, - { "Unknown1", "glbp.unknown1", FT_BYTES, BASE_NONE, NULL, + { &hf_glbp_group, + { "Group", "glbp.group", FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL }}, { &hf_glbp_unknown2, @@ -249,80 +349,114 @@ proto_register_glbp(void) { "Somemac?", "glbp.somemac", FT_ETHER, BASE_NONE, NULL, 0x0, NULL, HFILL }}, - { &hf_glbp_type2, - { "Type2???", "glbp.type2", FT_UINT8, BASE_DEC, VALS(glbp_type2_vals), + { &hf_glbp_tlv, + { "TLV", "glbp.tlv", FT_PROTOCOL, BASE_NONE, NULL, + 0x0, NULL, HFILL }}, + + { &hf_glbp_type, + { "Type", "glbp.type", FT_UINT8, BASE_DEC, VALS(glbp_type_vals), 0x0, NULL, HFILL }}, - { &hf_glbp_length2, - { "Length2?", "glbp.length2", FT_UINT8, BASE_DEC, NULL, + { &hf_glbp_length, + { "Length", "glbp.length", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, /* type = 1 - hello */ - { &hf_glbp_unknown11, - { "Unknown1-1", "glbp.unknown11", FT_BYTES, BASE_NONE, NULL, + { &hf_glbp_hello_unknown11, + { "Unknown1-1", "glbp.hello.unknown11", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, - { &hf_glbp_priority, - { "Priority", "glbp.priority", FT_UINT8, BASE_DEC, NULL, + { &hf_glbp_hello_priority, + { "Priority", "glbp.hello.priority", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, - { &hf_glbp_unknown12, - { "Unknown1-2", "glbp.unknown12", FT_BYTES, BASE_NONE, NULL, + { &hf_glbp_hello_unknown12, + { "Unknown1-2", "glbp.hello.unknown12", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, - { &hf_glbp_helloint, - { "Helloint", "glbp.helloint", FT_UINT32, BASE_DEC, NULL, + { &hf_glbp_hello_helloint, + { "Helloint", "glbp.hello.helloint", FT_UINT32, BASE_DEC, NULL, 0x0, "Hello interval [msec]", HFILL }}, - { &hf_glbp_holdint, - { "Holdint", "glbp.holdint", FT_UINT32, BASE_DEC, NULL, + { &hf_glbp_hello_holdint, + { "Holdint", "glbp.hello.holdint", FT_UINT32, BASE_DEC, NULL, 0x0, "Hold interval [msec]", HFILL }}, - { &hf_glbp_redirect, - { "Redirect", "glbp.redirect", FT_UINT16, BASE_DEC, NULL, + { &hf_glbp_hello_redirect, + { "Redirect", "glbp.hello.redirect", FT_UINT16, BASE_DEC, NULL, 0x0, "Redirect interval [sec]", HFILL }}, - { &hf_glbp_timeout, - { "Timeout", "glbp.timeout", FT_UINT16, BASE_DEC, NULL, + { &hf_glbp_hello_timeout, + { "Timeout", "glbp.hello.timeout", FT_UINT16, BASE_DEC, NULL, 0x0, "Forwarder timeout interval [sec]", HFILL }}, - { &hf_glbp_unknown13, - { "Unknown1-3", "glbp.unknown13", FT_BYTES, BASE_NONE, NULL, + { &hf_glbp_hello_unknown13, + { "Unknown1-3", "glbp.hello.unknown13", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, - { &hf_glbp_numips, - { "Number IPs???", "glbp.numips", FT_UINT8, BASE_DEC, NULL, + { &hf_glbp_hello_numips, + { "Number IPs???", "glbp.hello.numips", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, - { &hf_glbp_lenip, - { "Length IP???", "glbp.lenip", FT_UINT8, BASE_DEC, NULL, + { &hf_glbp_hello_lenip, + { "Length IP???", "glbp.hello.lenip", FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL }}, - { &hf_glbp_virtualip, - { "Virtual IP", "glbp.virtualip", FT_IPv4, BASE_NONE, NULL, + { &hf_glbp_hello_virtualip, + { "Virtual IP", "glbp.hello.virtualip", FT_IPv4, BASE_NONE, NULL, 0x0, NULL, HFILL }}, /* type = 2 - request/response??? */ - { &hf_glbp_subtype, - { "Subtype???", "glbp.subtype", FT_UINT8, BASE_DEC, VALS(glbp_subtype_vals), + { &hf_glbp_reqresp_type, + { "Type???", "glbp.reqresp.type", FT_UINT8, BASE_DEC, VALS(glbp_reqresp_type_vals), + 0x0, NULL, HFILL }}, + + { &hf_glbp_reqresp_unknown21, + { "Unknown2-1", "glbp.reqresp.unknown21", FT_BYTES, BASE_NONE, NULL, + 0x0, NULL, HFILL }}, + + { &hf_glbp_reqresp_virtualmac, + { "Virtualmac", "glbp.reqresp.virtualmac", FT_ETHER, BASE_NONE, NULL, + 0x0, NULL, HFILL }}, + + /* type = 3 - auth */ + { &hf_glbp_auth_authtype, + { "Authtype", "glbp.auth.authtype", FT_UINT8, BASE_DEC, VALS(glbp_auth_type_vals), + 0x0, NULL, HFILL }}, + + { &hf_glbp_auth_authlength, + { "Authlength", "glbp.auth.authlength", FT_UINT8, BASE_DEC, NULL, + 0x0, NULL, HFILL }}, + + { &hf_glbp_auth_plainpass, + { "Plain pass", "glbp.auth.plainpass", FT_STRING, BASE_NONE, NULL, + 0x0, NULL, HFILL }}, + + { &hf_glbp_auth_md5hash, + { "MD5-string hash", "glbp.auth.md5hash", FT_BYTES, BASE_NONE, NULL, + 0x0, NULL, HFILL }}, + + { &hf_glbp_auth_md5chainindex, + { "MD5-chain index", "glbp.auth.md5chainindex", FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL }}, - { &hf_glbp_unknown21, - { "Unknown2-1", "glbp.unknown21", FT_BYTES, BASE_NONE, NULL, + { &hf_glbp_auth_md5chainhash, + { "MD5-chain hash", "glbp.auth.md5chainhash", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, - { &hf_glbp_virtualmac, - { "Virtualmac", "glbp.virtualmac", FT_ETHER, BASE_NONE, NULL, + { &hf_glbp_auth_authunknown, + { "Unknown auth value", "glbp.auth.authunknown", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, /* type = unknown */ - { &hf_glbp_unknown6, - { "Unknown6", "glbp.unknown6", FT_BYTES, BASE_NONE, NULL, + { &hf_glbp_unknown_data, + { "Unknown TLV data", "glbp.unknown.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL }}, }; static gint *ett[] = { &ett_glbp, + &ett_glbp_tlv, }; proto_glbp = proto_register_protocol( -- cgit v1.2.3