summaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-glbp.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-10 20:34:10 +0000
commite4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch)
tree68cb5ef9081156392f1dd62a00c6ccc1451b93df /epan/dissectors/packet-glbp.c
parentInitial commit. (diff)
downloadwireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.tar.xz
wireshark-e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc.zip
Adding upstream version 4.2.2.upstream/4.2.2
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'epan/dissectors/packet-glbp.c')
-rw-r--r--epan/dissectors/packet-glbp.c618
1 files changed, 618 insertions, 0 deletions
diff --git a/epan/dissectors/packet-glbp.c b/epan/dissectors/packet-glbp.c
new file mode 100644
index 00000000..909a7a26
--- /dev/null
+++ b/epan/dissectors/packet-glbp.c
@@ -0,0 +1,618 @@
+/* packet-glbp.c
+ *
+ * Cisco's GLBP: Gateway Load Balancing Protocol
+ *
+ * Copyright 2007 Joerg Mayer (see AUTHORS file)
+ *
+ * Wireshark - Network traffic analyzer
+ * By Gerald Combs <gerald@wireshark.org>
+ * Copyright 1998 Gerald Combs
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+/*
+ * Documentation:
+ * http://www.cisco.com/en/US/docs/ios/12_2t/12_2t15/feature/guide/ft_glbp.pdf
+ *
+ * TODO: This dissector has been written without specs, so much of it is
+ * guesswork. Also, there are still unknown elements in the message.
+ * Some debug output:
+ * GLBP: Fa0/0 Grp 1020 Hello out VG Active pri 100 vIP FE80::C800:8FF:FE64:AAAA
+ * hello 3000, hold 10000 VF 1 Active pri 167 vMAC 0007.b403.fc01
+ * GLBP: Fa0/0 Grp 1021 Hello out VG Active pri 100 vIP 10.20.20.100
+ * hello 3000, hold 10000 VF 1 Active pri 167 vMAC 0007.b403.fd01
+ */
+
+#include "config.h"
+
+#include <epan/packet.h>
+#include <epan/expert.h>
+
+void proto_register_glbp(void);
+void proto_reg_handoff_glbp(void);
+
+static dissector_handle_t glbp_handle;
+
+#define GLBP_UDP_PORT 3222
+
+static int proto_glbp = -1;
+/* glbp header? */
+static gint hf_glbp_version = -1;
+static gint hf_glbp_unknown1 = -1;
+static gint hf_glbp_group = -1;
+static gint hf_glbp_unknown2 = -1;
+static gint hf_glbp_ownerid = -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_unknown10 = -1;
+static gint hf_glbp_hello_vgstate = -1;
+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_addrtype = -1;
+static gint hf_glbp_hello_addrlen = -1;
+static gint hf_glbp_hello_virtualipv4 = -1;
+static gint hf_glbp_hello_virtualipv6 = -1;
+static gint hf_glbp_hello_virtualunk = -1;
+/* glbp type = 2 - Request/Response??? */
+static gint hf_glbp_reqresp_forwarder = -1;
+static gint hf_glbp_reqresp_vfstate = -1;
+static gint hf_glbp_reqresp_unknown21 = -1;
+static gint hf_glbp_reqresp_priority = -1;
+static gint hf_glbp_reqresp_weight = -1;
+static gint hf_glbp_reqresp_unknown22 = -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_unknown_data = -1;
+
+static gint ett_glbp = -1;
+static gint ett_glbp_tlv = -1;
+
+/* filterable expert infos */
+static expert_field ei_glbp_ipv4_wrong_length = EI_INIT;
+static expert_field ei_glbp_ipv6_wrong_length = EI_INIT;
+static expert_field ei_glbp_tlv_length_too_small = EI_INIT;
+static expert_field ei_glbp_tlv_invalid_bytes_used = EI_INIT;
+
+static const value_string glbp_type_vals[] = {
+ { 1, "Hello" },
+ { 2, "Request/Response?" },
+ { 3, "Auth" },
+
+ { 0, NULL }
+};
+
+#if 0
+static const value_string glbp_reqresp_forwarder_vals[] = {
+ { 0, "Request?" },
+ { 2, "Response?" },
+
+ { 0, NULL }
+};
+#endif
+
+static const value_string glbp_addr_type_vals[] = {
+ { 1, "IPv4" },
+ { 2, "IPv6" },
+
+ { 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)" },
+ { x, "Weighted" },
+ { x, "Host dependent" },
+ { x, "Round robin" },
+
+ { 0, NULL }
+};
+#endif
+
+static const value_string glbp_vgstate_vals[] = {
+#if 0
+ { x, "Disabled" },
+ { x, "Initial" },
+#endif
+ { 4, "Listen" },
+ { 8, "Speak" },
+ { 0x10, "Standby" },
+ { 0x20, "Active" },
+
+ { 0, NULL }
+};
+
+static const value_string glbp_vfstate_vals[] = {
+#if 0
+ { x, "Disabled" },
+ { x, "Initial" },
+#endif
+ { 4, "Listen" },
+ { 0x20, "Active" },
+
+ { 0, NULL }
+};
+
+static int
+dissect_glbp_hello(tvbuff_t *tvb, int offset,
+ packet_info *pinfo, proto_tree *tlv_tree)
+{
+ guint8 addrtype;
+ guint8 addrlen;
+
+ proto_tree_add_item(tlv_tree, hf_glbp_hello_unknown10, tvb, offset, 1, ENC_NA);
+ offset ++;
+ proto_tree_add_item(tlv_tree, hf_glbp_hello_vgstate, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset ++;
+ proto_tree_add_item(tlv_tree, hf_glbp_hello_unknown11, tvb, offset, 1, ENC_NA);
+ offset ++;
+ proto_tree_add_item(tlv_tree, hf_glbp_hello_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ proto_tree_add_item(tlv_tree, hf_glbp_hello_unknown12, tvb, offset, 2, ENC_NA);
+ offset += 2;
+ proto_tree_add_item(tlv_tree, hf_glbp_hello_helloint, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(tlv_tree, hf_glbp_hello_holdint, tvb, offset, 4, ENC_BIG_ENDIAN);
+ offset += 4;
+ proto_tree_add_item(tlv_tree, hf_glbp_hello_redirect, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(tlv_tree, hf_glbp_hello_timeout, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(tlv_tree, hf_glbp_hello_unknown13, tvb, offset, 2, ENC_NA);
+ offset += 2;
+ proto_tree_add_item(tlv_tree, hf_glbp_hello_addrtype, tvb, offset, 1, ENC_BIG_ENDIAN);
+ addrtype = tvb_get_guint8( tvb, offset);
+ offset++;
+ proto_tree_add_item(tlv_tree, hf_glbp_hello_addrlen, tvb, offset, 1, ENC_BIG_ENDIAN);
+ addrlen = tvb_get_guint8(tvb, offset);
+ offset++;
+ switch (addrtype) {
+ case 1:
+ if (addrlen != 4) {
+ expert_add_info_format(pinfo, NULL, &ei_glbp_ipv4_wrong_length,
+ "Wrong IPv4 address length: %u", addrlen);
+ return offset + addrlen;
+ }
+ proto_tree_add_item(tlv_tree, hf_glbp_hello_virtualipv4, tvb, offset, addrlen, ENC_BIG_ENDIAN);
+ break;
+ case 2:
+ if (addrlen != 16) {
+ expert_add_info_format(pinfo, NULL, &ei_glbp_ipv6_wrong_length,
+ "Wrong IPv6 address length: %u", addrlen);
+ return offset + addrlen;
+ }
+ proto_tree_add_item(tlv_tree, hf_glbp_hello_virtualipv6, tvb, offset, addrlen, ENC_NA);
+ break;
+ default:
+ proto_tree_add_item(tlv_tree, hf_glbp_hello_virtualunk, tvb, offset, addrlen, ENC_NA);
+ break;
+ }
+ offset += addrlen;
+
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
+ val_to_str(addrtype, glbp_addr_type_vals, "%d"));
+
+ return offset;
+}
+
+
+static int
+dissect_glbp_reqresp(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tlv_tree)
+{
+ proto_tree_add_item(tlv_tree, hf_glbp_reqresp_forwarder, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ proto_tree_add_item(tlv_tree, hf_glbp_reqresp_vfstate, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ proto_tree_add_item(tlv_tree, hf_glbp_reqresp_unknown21, tvb, offset, 1, ENC_NA);
+ offset += 1;
+ proto_tree_add_item(tlv_tree, hf_glbp_reqresp_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ proto_tree_add_item(tlv_tree, hf_glbp_reqresp_weight, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ proto_tree_add_item(tlv_tree, hf_glbp_reqresp_unknown22, tvb, offset, 7, ENC_NA);
+ offset += 7;
+ proto_tree_add_item(tlv_tree, hf_glbp_reqresp_virtualmac, tvb, offset, 6, ENC_NA);
+ offset += 6;
+
+ return offset;
+}
+
+static int
+dissect_glbp_auth(tvbuff_t *tvb, int offset,
+ packet_info *pinfo _U_, proto_tree *tlv_tree)
+{
+ guint8 authtype;
+ guint8 authlength;
+
+ proto_tree_add_item(tlv_tree, hf_glbp_auth_authtype, tvb, offset, 1, ENC_BIG_ENDIAN);
+ authtype = tvb_get_guint8(tvb, offset);
+ offset++;
+ proto_tree_add_item(tlv_tree, hf_glbp_auth_authlength, tvb, offset, 1, ENC_BIG_ENDIAN);
+ authlength = tvb_get_guint8(tvb, offset);
+ offset++;
+ switch(authtype) {
+ case 1:
+ proto_tree_add_item(tlv_tree, hf_glbp_auth_plainpass, tvb, offset, authlength, ENC_ASCII);
+ offset += authlength;
+ break;
+ case 2:
+ proto_tree_add_item(tlv_tree, hf_glbp_auth_md5hash, tvb, offset, authlength, ENC_NA);
+ offset += authlength;
+ break;
+ case 3:
+ proto_tree_add_item(tlv_tree, hf_glbp_auth_md5chainindex, tvb, offset, 4, ENC_BIG_ENDIAN);
+ proto_tree_add_item(tlv_tree, hf_glbp_auth_md5chainhash, tvb, offset+4, authlength-4, ENC_NA);
+ offset += authlength;
+ break;
+ default:
+ proto_tree_add_item(tlv_tree, hf_glbp_auth_authunknown, tvb, offset, authlength, ENC_NA);
+ offset += authlength;
+ break;
+ }
+
+ return offset;
+}
+
+static int
+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, ENC_NA);
+ offset += length;
+
+ return offset;
+}
+
+static int
+dissect_glbp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ proto_tree *glbp_tree;
+ proto_tree *tlv_tree;
+ proto_item *ti;
+ guint8 type;
+ int offset = 0;
+ int lastoffset;
+ guint8 length;
+ guint16 group;
+
+ group = tvb_get_ntohs(tvb, 2);
+
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "GLBP");
+ col_add_fstr(pinfo->cinfo, COL_INFO, "G: %d", group);
+
+ ti = proto_tree_add_item(tree, proto_glbp, tvb, 0, -1, ENC_NA);
+ glbp_tree = proto_item_add_subtree(ti, ett_glbp);
+
+ /* glbp header? */
+ proto_tree_add_item(glbp_tree, hf_glbp_version, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ proto_tree_add_item(glbp_tree, hf_glbp_unknown1, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ proto_tree_add_item(glbp_tree, hf_glbp_group, tvb, offset, 2, ENC_BIG_ENDIAN);
+ offset += 2;
+ proto_tree_add_item(glbp_tree, hf_glbp_unknown2, tvb, offset, 2, ENC_NA);
+ offset += 2;
+ proto_tree_add_item(glbp_tree, hf_glbp_ownerid, tvb, offset, 6, ENC_NA);
+ offset += 6;
+ while (tvb_reported_length_remaining(tvb, offset) > 0) {
+
+ type = tvb_get_guint8(tvb, offset);
+ length = tvb_get_guint8(tvb, offset+1);
+ if (length < 2) {
+ expert_add_info_format(pinfo, NULL, &ei_glbp_tlv_length_too_small,
+ "Length %u too small", length);
+ return offset;
+ }
+ length -= 2;
+
+ ti = proto_tree_add_item(glbp_tree, hf_glbp_tlv, tvb, offset, length+2, ENC_BIG_ENDIAN);
+ 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, ENC_BIG_ENDIAN);
+ offset++;
+ proto_tree_add_item(tlv_tree, hf_glbp_length, tvb, offset, 1, ENC_BIG_ENDIAN);
+ offset++;
+ col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
+ val_to_str(type, glbp_type_vals, "%d"));
+
+ lastoffset = offset;
+ switch(type) {
+ case 1: /* Hello */
+ offset = dissect_glbp_hello(tvb, offset, pinfo, tlv_tree);
+ break;
+ case 2: /* Request/Response */
+ offset = dissect_glbp_reqresp(tvb, offset, pinfo, tlv_tree);
+ break;
+ case 3: /* Plaintext auth */
+ offset = dissect_glbp_auth(tvb, offset, pinfo, tlv_tree);
+ break;
+ default:
+ offset = dissect_glbp_unknown(tvb, offset, length, pinfo, tlv_tree);
+ break;
+ }
+ if (lastoffset >= offset) {
+ expert_add_info(pinfo, NULL, &ei_glbp_tlv_invalid_bytes_used);
+ return lastoffset;
+ }
+ /* Skip over trailing bytes before starting with the next element */
+ if (lastoffset + length > offset)
+ offset = lastoffset + length;
+ }
+ return offset;
+}
+
+static gboolean
+test_glbp(tvbuff_t *tvb, packet_info *pinfo)
+{
+ guint32 unknown1;
+ if ( tvb_captured_length(tvb) < 2)
+ return FALSE;
+ unknown1 = tvb_get_guint8(tvb, 1);
+ if (tvb_get_guint8(tvb, 0) != 1 /* version? */
+ || unknown1 > 4
+ || pinfo->srcport != pinfo->destport
+#if 0 /* XXX */
+ || unknown1 == 0 && pinfo->net_dst != ipv4:224.0.0.102
+ && pinfo->net_dst != ipv6:...
+ || unknown1 == 0 && pinfo->dl_src != ether:c2-00-7c-b8-00-00
+#endif
+ ) {
+ return FALSE;
+ }
+ return TRUE;
+}
+
+static int
+dissect_glbp_static(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
+{
+ if ( !test_glbp(tvb, pinfo) ) {
+ return 0;
+ }
+ return dissect_glbp(tvb, pinfo, tree);
+}
+
+
+void
+proto_register_glbp(void)
+{
+ static hf_register_info hf[] = {
+ /* Header */
+ { &hf_glbp_version,
+ { "Version?", "glbp.version", FT_UINT8, BASE_DEC, NULL,
+ 0x0, NULL, HFILL }},
+
+ { &hf_glbp_unknown1,
+ { "Unknown1", "glbp.unknown1", FT_UINT8, BASE_DEC, NULL,
+ 0x0, NULL, HFILL }},
+
+ { &hf_glbp_group,
+ { "Group", "glbp.group", FT_UINT16, BASE_DEC, NULL,
+ 0x0, NULL, HFILL }},
+
+ { &hf_glbp_unknown2,
+ { "Unknown2", "glbp.unknown2", FT_BYTES, BASE_NONE, NULL,
+ 0x0, NULL, HFILL }},
+
+ { &hf_glbp_ownerid,
+ { "Owner ID", "glbp.ownerid", FT_ETHER, BASE_NONE, NULL,
+ 0x0, NULL, HFILL }},
+
+ { &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_length,
+ { "Length", "glbp.length", FT_UINT8, BASE_DEC, NULL,
+ 0x0, NULL, HFILL }},
+
+ /* type = 1 - hello */
+ { &hf_glbp_hello_unknown10,
+ { "Unknown1-0", "glbp.hello.unknown10", FT_BYTES, BASE_NONE, NULL,
+ 0x0, NULL, HFILL }},
+
+ { &hf_glbp_hello_vgstate,
+ { "VG state?", "glbp.hello.vgstate", FT_UINT8, BASE_DEC, VALS(glbp_vgstate_vals),
+ 0x0, NULL, HFILL }},
+
+ { &hf_glbp_hello_unknown11,
+ { "Unknown1-1", "glbp.hello.unknown11", FT_BYTES, BASE_NONE, NULL,
+ 0x0, NULL, HFILL }},
+
+ { &hf_glbp_hello_priority,
+ { "Priority", "glbp.hello.priority", FT_UINT8, BASE_DEC, NULL,
+ 0x0, NULL, HFILL }},
+
+ { &hf_glbp_hello_unknown12,
+ { "Unknown1-2", "glbp.hello.unknown12", FT_BYTES, BASE_NONE, NULL,
+ 0x0, NULL, HFILL }},
+
+ { &hf_glbp_hello_helloint,
+ { "Helloint", "glbp.hello.helloint", FT_UINT32, BASE_DEC, NULL,
+ 0x0, "Hello interval [msec]", HFILL }},
+
+ { &hf_glbp_hello_holdint,
+ { "Holdint", "glbp.hello.holdint", FT_UINT32, BASE_DEC, NULL,
+ 0x0, "Hold interval [msec]", HFILL }},
+
+ { &hf_glbp_hello_redirect,
+ { "Redirect", "glbp.hello.redirect", FT_UINT16, BASE_DEC, NULL,
+ 0x0, "Redirect interval [sec]", HFILL }},
+
+ { &hf_glbp_hello_timeout,
+ { "Timeout", "glbp.hello.timeout", FT_UINT16, BASE_DEC, NULL,
+ 0x0, "Forwarder timeout interval [sec]", HFILL }},
+
+ { &hf_glbp_hello_unknown13,
+ { "Unknown1-3", "glbp.hello.unknown13", FT_BYTES, BASE_NONE, NULL,
+ 0x0, NULL, HFILL }},
+
+ { &hf_glbp_hello_addrtype,
+ { "Address type", "glbp.hello.addrtype", FT_UINT8, BASE_DEC, VALS(glbp_addr_type_vals),
+ 0x0, NULL, HFILL }},
+
+ { &hf_glbp_hello_addrlen,
+ { "Address length", "glbp.hello.addrlen", FT_UINT8, BASE_DEC, NULL,
+ 0x0, NULL, HFILL }},
+
+ { &hf_glbp_hello_virtualipv4,
+ { "Virtual IPv4", "glbp.hello.virtualipv4", FT_IPv4, BASE_NONE, NULL,
+ 0x0, NULL, HFILL }},
+
+ { &hf_glbp_hello_virtualipv6,
+ { "Virtual IPv6", "glbp.hello.virtualipv6", FT_IPv6, BASE_NONE, NULL,
+ 0x0, NULL, HFILL }},
+
+ { &hf_glbp_hello_virtualunk,
+ { "Virtual Unknown", "glbp.hello.virtualunk", FT_BYTES, BASE_NONE, NULL,
+ 0x0, NULL, HFILL }},
+
+ /* type = 2 - request/response??? */
+ { &hf_glbp_reqresp_forwarder,
+ { "Forwarder?", "glbp.reqresp.forwarder", FT_UINT8, BASE_DEC, NULL,
+ 0x0, NULL, HFILL }},
+
+ { &hf_glbp_reqresp_vfstate,
+ { "VF state?", "glbp.reqresp.vfstate", FT_UINT8, BASE_DEC, VALS(glbp_vfstate_vals),
+ 0x0, NULL, HFILL }},
+
+ { &hf_glbp_reqresp_unknown21,
+ { "Unknown2-1", "glbp.reqresp.unknown21", FT_BYTES, BASE_NONE, NULL,
+ 0x0, NULL, HFILL }},
+
+ { &hf_glbp_reqresp_priority,
+ { "Priority", "glbp.reqresp.priority", FT_UINT8, BASE_DEC, NULL,
+ 0x0, NULL, HFILL }},
+
+ { &hf_glbp_reqresp_weight,
+ { "Weight", "glbp.reqresp.weight", FT_UINT8, BASE_DEC, NULL,
+ 0x0, NULL, HFILL }},
+
+ { &hf_glbp_reqresp_unknown22,
+ { "Unknown2-2", "glbp.reqresp.unknown22", 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_auth_md5chainhash,
+ { "MD5-chain hash", "glbp.auth.md5chainhash", FT_BYTES, BASE_NONE, NULL,
+ 0x0, NULL, HFILL }},
+
+ { &hf_glbp_auth_authunknown,
+ { "Unknown auth value", "glbp.auth.authunknown", FT_BYTES, BASE_NONE, NULL,
+ 0x0, NULL, HFILL }},
+
+ /* type = unknown */
+ { &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,
+ };
+
+ static ei_register_info ei[] = {
+ { &ei_glbp_ipv4_wrong_length,
+ { "glbp.ipv4_wrong_length", PI_MALFORMED, PI_ERROR,
+ "Wrong IPv4 address length: %u",
+ EXPFILL }},
+ { &ei_glbp_ipv6_wrong_length,
+ { "glbp.ipv6_wrong_length", PI_MALFORMED, PI_ERROR,
+ "Wrong IPv6 address length: %u",
+ EXPFILL }},
+ { &ei_glbp_tlv_length_too_small,
+ { "glbp.tlv_length_too_small", PI_MALFORMED, PI_ERROR,
+ "Length %u too small",
+ EXPFILL }},
+ { &ei_glbp_tlv_invalid_bytes_used,
+ { "glbp.tlv_invalid_bytes_used", PI_MALFORMED, PI_ERROR,
+ "Zero or negative length",
+ EXPFILL }},
+ };
+
+ expert_module_t* expert_glbp;
+
+ proto_glbp = proto_register_protocol("Gateway Load Balancing Protocol", "GLBP", "glbp");
+
+ proto_register_field_array(proto_glbp, hf, array_length(hf));
+ proto_register_subtree_array(ett, array_length(ett));
+ expert_glbp = expert_register_protocol(proto_glbp);
+ expert_register_field_array(expert_glbp, ei, array_length(ei));
+
+ glbp_handle = register_dissector("glbp", dissect_glbp_static, proto_glbp);
+}
+
+void
+proto_reg_handoff_glbp(void)
+{
+ dissector_add_uint_with_preference("udp.port", GLBP_UDP_PORT, glbp_handle);
+}
+
+/*
+ * Editor modelines - https://www.wireshark.org/tools/modelines.html
+ *
+ * Local Variables:
+ * c-basic-offset: 2
+ * tab-width: 8
+ * indent-tabs-mode: nil
+ * End:
+ *
+ * ex: set shiftwidth=2 tabstop=8 expandtab:
+ * :indentSize=2:tabSize=8:noTabs=true:
+ */