diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:34:10 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-10 20:34:10 +0000 |
commit | e4ba6dbc3f1e76890b22773807ea37fe8fa2b1bc (patch) | |
tree | 68cb5ef9081156392f1dd62a00c6ccc1451b93df /epan/dissectors/packet-glbp.c | |
parent | Initial commit. (diff) | |
download | wireshark-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.c | 618 |
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: + */ |