Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-glbp.c
blobdde61e399bc9da5454cbdff48a7cc6ba32c53b99
1 /* packet-glbp.c
3 * Cisco's GLBP: Gateway Load Balancing Protocol
5 * Copyright 2007 Joerg Mayer (see AUTHORS file)
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * SPDX-License-Identifier: GPL-2.0-or-later
15 * Documentation:
16 * http://www.cisco.com/en/US/docs/ios/12_2t/12_2t15/feature/guide/ft_glbp.pdf
18 * TODO: This dissector has been written without specs, so much of it is
19 * guesswork. Also, there are still unknown elements in the message.
20 * Some debug output:
21 * GLBP: Fa0/0 Grp 1020 Hello out VG Active pri 100 vIP FE80::C800:8FF:FE64:AAAA
22 * hello 3000, hold 10000 VF 1 Active pri 167 vMAC 0007.b403.fc01
23 * GLBP: Fa0/0 Grp 1021 Hello out VG Active pri 100 vIP 10.20.20.100
24 * hello 3000, hold 10000 VF 1 Active pri 167 vMAC 0007.b403.fd01
27 #include "config.h"
29 #include <epan/packet.h>
30 #include <epan/expert.h>
32 void proto_register_glbp(void);
33 void proto_reg_handoff_glbp(void);
35 static dissector_handle_t glbp_handle;
37 #define GLBP_UDP_PORT 3222
39 static int proto_glbp;
40 /* glbp header? */
41 static int hf_glbp_version;
42 static int hf_glbp_unknown1;
43 static int hf_glbp_group;
44 static int hf_glbp_unknown2;
45 static int hf_glbp_ownerid;
46 static int hf_glbp_tlv;
47 static int hf_glbp_type;
48 static int hf_glbp_length;
49 /* glbp type = 1 - hello */
50 static int hf_glbp_hello_unknown10;
51 static int hf_glbp_hello_vgstate;
52 static int hf_glbp_hello_unknown11;
53 static int hf_glbp_hello_priority;
54 static int hf_glbp_hello_unknown12;
55 static int hf_glbp_hello_helloint;
56 static int hf_glbp_hello_holdint;
57 static int hf_glbp_hello_redirect;
58 static int hf_glbp_hello_timeout;
59 static int hf_glbp_hello_unknown13;
60 static int hf_glbp_hello_addrtype;
61 static int hf_glbp_hello_addrlen;
62 static int hf_glbp_hello_virtualipv4;
63 static int hf_glbp_hello_virtualipv6;
64 static int hf_glbp_hello_virtualunk;
65 /* glbp type = 2 - Request/Response??? */
66 static int hf_glbp_reqresp_forwarder;
67 static int hf_glbp_reqresp_vfstate;
68 static int hf_glbp_reqresp_unknown21;
69 static int hf_glbp_reqresp_priority;
70 static int hf_glbp_reqresp_weight;
71 static int hf_glbp_reqresp_unknown22;
72 static int hf_glbp_reqresp_virtualmac;
73 /* glbp type = 3 - Auth */
74 static int hf_glbp_auth_authtype;
75 static int hf_glbp_auth_authlength;
76 static int hf_glbp_auth_plainpass;
77 static int hf_glbp_auth_md5hash;
78 static int hf_glbp_auth_md5chainindex;
79 static int hf_glbp_auth_md5chainhash;
80 static int hf_glbp_auth_authunknown;
81 /* unknown type */
82 static int hf_glbp_unknown_data;
84 static int ett_glbp;
85 static int ett_glbp_tlv;
87 /* filterable expert infos */
88 static expert_field ei_glbp_ipv4_wrong_length;
89 static expert_field ei_glbp_ipv6_wrong_length;
90 static expert_field ei_glbp_tlv_length_too_small;
91 static expert_field ei_glbp_tlv_invalid_bytes_used;
93 static const value_string glbp_type_vals[] = {
94 { 1, "Hello" },
95 { 2, "Request/Response?" },
96 { 3, "Auth" },
98 { 0, NULL }
101 #if 0
102 static const value_string glbp_reqresp_forwarder_vals[] = {
103 { 0, "Request?" },
104 { 2, "Response?" },
106 { 0, NULL }
108 #endif
110 static const value_string glbp_addr_type_vals[] = {
111 { 1, "IPv4" },
112 { 2, "IPv6" },
114 { 0, NULL }
117 static const value_string glbp_auth_type_vals[] = {
118 { 0, "None" },
119 { 1, "Plain text" },
120 { 2, "MD5 string" },
121 { 3, "MD5 chain" },
123 { 0, NULL }
126 #if 0
127 static const value_string glbp_loadbalancing_vals[] = {
128 { x, "None (AVG only)" },
129 { x, "Weighted" },
130 { x, "Host dependent" },
131 { x, "Round robin" },
133 { 0, NULL }
135 #endif
137 static const value_string glbp_vgstate_vals[] = {
138 #if 0
139 { x, "Disabled" },
140 { x, "Initial" },
141 #endif
142 { 4, "Listen" },
143 { 8, "Speak" },
144 { 0x10, "Standby" },
145 { 0x20, "Active" },
147 { 0, NULL }
150 static const value_string glbp_vfstate_vals[] = {
151 #if 0
152 { x, "Disabled" },
153 { x, "Initial" },
154 #endif
155 { 4, "Listen" },
156 { 0x20, "Active" },
158 { 0, NULL }
161 static int
162 dissect_glbp_hello(tvbuff_t *tvb, int offset,
163 packet_info *pinfo, proto_tree *tlv_tree)
165 uint8_t addrtype;
166 uint8_t addrlen;
168 proto_tree_add_item(tlv_tree, hf_glbp_hello_unknown10, tvb, offset, 1, ENC_NA);
169 offset ++;
170 proto_tree_add_item(tlv_tree, hf_glbp_hello_vgstate, tvb, offset, 1, ENC_BIG_ENDIAN);
171 offset ++;
172 proto_tree_add_item(tlv_tree, hf_glbp_hello_unknown11, tvb, offset, 1, ENC_NA);
173 offset ++;
174 proto_tree_add_item(tlv_tree, hf_glbp_hello_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
175 offset++;
176 proto_tree_add_item(tlv_tree, hf_glbp_hello_unknown12, tvb, offset, 2, ENC_NA);
177 offset += 2;
178 proto_tree_add_item(tlv_tree, hf_glbp_hello_helloint, tvb, offset, 4, ENC_BIG_ENDIAN);
179 offset += 4;
180 proto_tree_add_item(tlv_tree, hf_glbp_hello_holdint, tvb, offset, 4, ENC_BIG_ENDIAN);
181 offset += 4;
182 proto_tree_add_item(tlv_tree, hf_glbp_hello_redirect, tvb, offset, 2, ENC_BIG_ENDIAN);
183 offset += 2;
184 proto_tree_add_item(tlv_tree, hf_glbp_hello_timeout, tvb, offset, 2, ENC_BIG_ENDIAN);
185 offset += 2;
186 proto_tree_add_item(tlv_tree, hf_glbp_hello_unknown13, tvb, offset, 2, ENC_NA);
187 offset += 2;
188 proto_tree_add_item(tlv_tree, hf_glbp_hello_addrtype, tvb, offset, 1, ENC_BIG_ENDIAN);
189 addrtype = tvb_get_uint8( tvb, offset);
190 offset++;
191 proto_tree_add_item(tlv_tree, hf_glbp_hello_addrlen, tvb, offset, 1, ENC_BIG_ENDIAN);
192 addrlen = tvb_get_uint8(tvb, offset);
193 offset++;
194 switch (addrtype) {
195 case 1:
196 if (addrlen != 4) {
197 expert_add_info_format(pinfo, NULL, &ei_glbp_ipv4_wrong_length,
198 "Wrong IPv4 address length: %u", addrlen);
199 return offset + addrlen;
201 proto_tree_add_item(tlv_tree, hf_glbp_hello_virtualipv4, tvb, offset, addrlen, ENC_BIG_ENDIAN);
202 break;
203 case 2:
204 if (addrlen != 16) {
205 expert_add_info_format(pinfo, NULL, &ei_glbp_ipv6_wrong_length,
206 "Wrong IPv6 address length: %u", addrlen);
207 return offset + addrlen;
209 proto_tree_add_item(tlv_tree, hf_glbp_hello_virtualipv6, tvb, offset, addrlen, ENC_NA);
210 break;
211 default:
212 proto_tree_add_item(tlv_tree, hf_glbp_hello_virtualunk, tvb, offset, addrlen, ENC_NA);
213 break;
215 offset += addrlen;
217 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
218 val_to_str(addrtype, glbp_addr_type_vals, "%d"));
220 return offset;
224 static int
225 dissect_glbp_reqresp(tvbuff_t *tvb, int offset,
226 packet_info *pinfo _U_, proto_tree *tlv_tree)
228 proto_tree_add_item(tlv_tree, hf_glbp_reqresp_forwarder, tvb, offset, 1, ENC_BIG_ENDIAN);
229 offset++;
230 proto_tree_add_item(tlv_tree, hf_glbp_reqresp_vfstate, tvb, offset, 1, ENC_BIG_ENDIAN);
231 offset++;
232 proto_tree_add_item(tlv_tree, hf_glbp_reqresp_unknown21, tvb, offset, 1, ENC_NA);
233 offset += 1;
234 proto_tree_add_item(tlv_tree, hf_glbp_reqresp_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
235 offset++;
236 proto_tree_add_item(tlv_tree, hf_glbp_reqresp_weight, tvb, offset, 1, ENC_BIG_ENDIAN);
237 offset++;
238 proto_tree_add_item(tlv_tree, hf_glbp_reqresp_unknown22, tvb, offset, 7, ENC_NA);
239 offset += 7;
240 proto_tree_add_item(tlv_tree, hf_glbp_reqresp_virtualmac, tvb, offset, 6, ENC_NA);
241 offset += 6;
243 return offset;
246 static int
247 dissect_glbp_auth(tvbuff_t *tvb, int offset,
248 packet_info *pinfo _U_, proto_tree *tlv_tree)
250 uint8_t authtype;
251 uint8_t authlength;
253 proto_tree_add_item(tlv_tree, hf_glbp_auth_authtype, tvb, offset, 1, ENC_BIG_ENDIAN);
254 authtype = tvb_get_uint8(tvb, offset);
255 offset++;
256 proto_tree_add_item(tlv_tree, hf_glbp_auth_authlength, tvb, offset, 1, ENC_BIG_ENDIAN);
257 authlength = tvb_get_uint8(tvb, offset);
258 offset++;
259 switch(authtype) {
260 case 1:
261 proto_tree_add_item(tlv_tree, hf_glbp_auth_plainpass, tvb, offset, authlength, ENC_ASCII);
262 offset += authlength;
263 break;
264 case 2:
265 proto_tree_add_item(tlv_tree, hf_glbp_auth_md5hash, tvb, offset, authlength, ENC_NA);
266 offset += authlength;
267 break;
268 case 3:
269 proto_tree_add_item(tlv_tree, hf_glbp_auth_md5chainindex, tvb, offset, 4, ENC_BIG_ENDIAN);
270 proto_tree_add_item(tlv_tree, hf_glbp_auth_md5chainhash, tvb, offset+4, authlength-4, ENC_NA);
271 offset += authlength;
272 break;
273 default:
274 proto_tree_add_item(tlv_tree, hf_glbp_auth_authunknown, tvb, offset, authlength, ENC_NA);
275 offset += authlength;
276 break;
279 return offset;
282 static int
283 dissect_glbp_unknown(tvbuff_t *tvb, int offset, uint32_t length,
284 packet_info *pinfo _U_, proto_tree *tlv_tree)
286 proto_tree_add_item(tlv_tree, hf_glbp_unknown_data, tvb, offset, length, ENC_NA);
287 offset += length;
289 return offset;
292 static int
293 dissect_glbp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
295 proto_tree *glbp_tree;
296 proto_tree *tlv_tree;
297 proto_item *ti;
298 uint8_t type;
299 int offset = 0;
300 int lastoffset;
301 uint8_t length;
302 uint16_t group;
304 group = tvb_get_ntohs(tvb, 2);
306 col_set_str(pinfo->cinfo, COL_PROTOCOL, "GLBP");
307 col_add_fstr(pinfo->cinfo, COL_INFO, "G: %d", group);
309 ti = proto_tree_add_item(tree, proto_glbp, tvb, 0, -1, ENC_NA);
310 glbp_tree = proto_item_add_subtree(ti, ett_glbp);
312 /* glbp header? */
313 proto_tree_add_item(glbp_tree, hf_glbp_version, tvb, offset, 1, ENC_BIG_ENDIAN);
314 offset++;
315 proto_tree_add_item(glbp_tree, hf_glbp_unknown1, tvb, offset, 1, ENC_BIG_ENDIAN);
316 offset++;
317 proto_tree_add_item(glbp_tree, hf_glbp_group, tvb, offset, 2, ENC_BIG_ENDIAN);
318 offset += 2;
319 proto_tree_add_item(glbp_tree, hf_glbp_unknown2, tvb, offset, 2, ENC_NA);
320 offset += 2;
321 proto_tree_add_item(glbp_tree, hf_glbp_ownerid, tvb, offset, 6, ENC_NA);
322 offset += 6;
323 while (tvb_reported_length_remaining(tvb, offset) > 0) {
325 type = tvb_get_uint8(tvb, offset);
326 length = tvb_get_uint8(tvb, offset+1);
327 if (length < 2) {
328 expert_add_info_format(pinfo, NULL, &ei_glbp_tlv_length_too_small,
329 "Length %u too small", length);
330 return offset;
332 length -= 2;
334 ti = proto_tree_add_item(glbp_tree, hf_glbp_tlv, tvb, offset, length+2, ENC_BIG_ENDIAN);
335 tlv_tree = proto_item_add_subtree(ti, ett_glbp_tlv);
336 proto_item_append_text(ti, " l=%d, t=%s", length+2,
337 val_to_str(type, glbp_type_vals, "%d"));
339 proto_tree_add_item(tlv_tree, hf_glbp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
340 offset++;
341 proto_tree_add_item(tlv_tree, hf_glbp_length, tvb, offset, 1, ENC_BIG_ENDIAN);
342 offset++;
343 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
344 val_to_str(type, glbp_type_vals, "%d"));
346 lastoffset = offset;
347 switch(type) {
348 case 1: /* Hello */
349 offset = dissect_glbp_hello(tvb, offset, pinfo, tlv_tree);
350 break;
351 case 2: /* Request/Response */
352 offset = dissect_glbp_reqresp(tvb, offset, pinfo, tlv_tree);
353 break;
354 case 3: /* Plaintext auth */
355 offset = dissect_glbp_auth(tvb, offset, pinfo, tlv_tree);
356 break;
357 default:
358 offset = dissect_glbp_unknown(tvb, offset, length, pinfo, tlv_tree);
359 break;
361 if (lastoffset >= offset) {
362 expert_add_info(pinfo, NULL, &ei_glbp_tlv_invalid_bytes_used);
363 return lastoffset;
365 /* Skip over trailing bytes before starting with the next element */
366 if (lastoffset + length > offset)
367 offset = lastoffset + length;
369 return offset;
372 static bool
373 test_glbp(tvbuff_t *tvb, packet_info *pinfo)
375 uint32_t unknown1;
376 if ( tvb_captured_length(tvb) < 2)
377 return false;
378 unknown1 = tvb_get_uint8(tvb, 1);
379 if (tvb_get_uint8(tvb, 0) != 1 /* version? */
380 || unknown1 > 4
381 || pinfo->srcport != pinfo->destport
382 #if 0 /* XXX */
383 || unknown1 == 0 && pinfo->net_dst != ipv4:224.0.0.102
384 && pinfo->net_dst != ipv6:...
385 || unknown1 == 0 && pinfo->dl_src != ether:c2-00-7c-b8-00-00
386 #endif
388 return false;
390 return true;
393 static int
394 dissect_glbp_static(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
396 if ( !test_glbp(tvb, pinfo) ) {
397 return 0;
399 return dissect_glbp(tvb, pinfo, tree);
403 void
404 proto_register_glbp(void)
406 static hf_register_info hf[] = {
407 /* Header */
408 { &hf_glbp_version,
409 { "Version?", "glbp.version", FT_UINT8, BASE_DEC, NULL,
410 0x0, NULL, HFILL }},
412 { &hf_glbp_unknown1,
413 { "Unknown1", "glbp.unknown1", FT_UINT8, BASE_DEC, NULL,
414 0x0, NULL, HFILL }},
416 { &hf_glbp_group,
417 { "Group", "glbp.group", FT_UINT16, BASE_DEC, NULL,
418 0x0, NULL, HFILL }},
420 { &hf_glbp_unknown2,
421 { "Unknown2", "glbp.unknown2", FT_BYTES, BASE_NONE, NULL,
422 0x0, NULL, HFILL }},
424 { &hf_glbp_ownerid,
425 { "Owner ID", "glbp.ownerid", FT_ETHER, BASE_NONE, NULL,
426 0x0, NULL, HFILL }},
428 { &hf_glbp_tlv,
429 { "TLV", "glbp.tlv", FT_PROTOCOL, BASE_NONE, NULL,
430 0x0, NULL, HFILL }},
432 { &hf_glbp_type,
433 { "Type", "glbp.type", FT_UINT8, BASE_DEC, VALS(glbp_type_vals),
434 0x0, NULL, HFILL }},
436 { &hf_glbp_length,
437 { "Length", "glbp.length", FT_UINT8, BASE_DEC, NULL,
438 0x0, NULL, HFILL }},
440 /* type = 1 - hello */
441 { &hf_glbp_hello_unknown10,
442 { "Unknown1-0", "glbp.hello.unknown10", FT_BYTES, BASE_NONE, NULL,
443 0x0, NULL, HFILL }},
445 { &hf_glbp_hello_vgstate,
446 { "VG state?", "glbp.hello.vgstate", FT_UINT8, BASE_DEC, VALS(glbp_vgstate_vals),
447 0x0, NULL, HFILL }},
449 { &hf_glbp_hello_unknown11,
450 { "Unknown1-1", "glbp.hello.unknown11", FT_BYTES, BASE_NONE, NULL,
451 0x0, NULL, HFILL }},
453 { &hf_glbp_hello_priority,
454 { "Priority", "glbp.hello.priority", FT_UINT8, BASE_DEC, NULL,
455 0x0, NULL, HFILL }},
457 { &hf_glbp_hello_unknown12,
458 { "Unknown1-2", "glbp.hello.unknown12", FT_BYTES, BASE_NONE, NULL,
459 0x0, NULL, HFILL }},
461 { &hf_glbp_hello_helloint,
462 { "Helloint", "glbp.hello.helloint", FT_UINT32, BASE_DEC, NULL,
463 0x0, "Hello interval [msec]", HFILL }},
465 { &hf_glbp_hello_holdint,
466 { "Holdint", "glbp.hello.holdint", FT_UINT32, BASE_DEC, NULL,
467 0x0, "Hold interval [msec]", HFILL }},
469 { &hf_glbp_hello_redirect,
470 { "Redirect", "glbp.hello.redirect", FT_UINT16, BASE_DEC, NULL,
471 0x0, "Redirect interval [sec]", HFILL }},
473 { &hf_glbp_hello_timeout,
474 { "Timeout", "glbp.hello.timeout", FT_UINT16, BASE_DEC, NULL,
475 0x0, "Forwarder timeout interval [sec]", HFILL }},
477 { &hf_glbp_hello_unknown13,
478 { "Unknown1-3", "glbp.hello.unknown13", FT_BYTES, BASE_NONE, NULL,
479 0x0, NULL, HFILL }},
481 { &hf_glbp_hello_addrtype,
482 { "Address type", "glbp.hello.addrtype", FT_UINT8, BASE_DEC, VALS(glbp_addr_type_vals),
483 0x0, NULL, HFILL }},
485 { &hf_glbp_hello_addrlen,
486 { "Address length", "glbp.hello.addrlen", FT_UINT8, BASE_DEC, NULL,
487 0x0, NULL, HFILL }},
489 { &hf_glbp_hello_virtualipv4,
490 { "Virtual IPv4", "glbp.hello.virtualipv4", FT_IPv4, BASE_NONE, NULL,
491 0x0, NULL, HFILL }},
493 { &hf_glbp_hello_virtualipv6,
494 { "Virtual IPv6", "glbp.hello.virtualipv6", FT_IPv6, BASE_NONE, NULL,
495 0x0, NULL, HFILL }},
497 { &hf_glbp_hello_virtualunk,
498 { "Virtual Unknown", "glbp.hello.virtualunk", FT_BYTES, BASE_NONE, NULL,
499 0x0, NULL, HFILL }},
501 /* type = 2 - request/response??? */
502 { &hf_glbp_reqresp_forwarder,
503 { "Forwarder?", "glbp.reqresp.forwarder", FT_UINT8, BASE_DEC, NULL,
504 0x0, NULL, HFILL }},
506 { &hf_glbp_reqresp_vfstate,
507 { "VF state?", "glbp.reqresp.vfstate", FT_UINT8, BASE_DEC, VALS(glbp_vfstate_vals),
508 0x0, NULL, HFILL }},
510 { &hf_glbp_reqresp_unknown21,
511 { "Unknown2-1", "glbp.reqresp.unknown21", FT_BYTES, BASE_NONE, NULL,
512 0x0, NULL, HFILL }},
514 { &hf_glbp_reqresp_priority,
515 { "Priority", "glbp.reqresp.priority", FT_UINT8, BASE_DEC, NULL,
516 0x0, NULL, HFILL }},
518 { &hf_glbp_reqresp_weight,
519 { "Weight", "glbp.reqresp.weight", FT_UINT8, BASE_DEC, NULL,
520 0x0, NULL, HFILL }},
522 { &hf_glbp_reqresp_unknown22,
523 { "Unknown2-2", "glbp.reqresp.unknown22", FT_BYTES, BASE_NONE, NULL,
524 0x0, NULL, HFILL }},
526 { &hf_glbp_reqresp_virtualmac,
527 { "Virtualmac", "glbp.reqresp.virtualmac", FT_ETHER, BASE_NONE, NULL,
528 0x0, NULL, HFILL }},
530 /* type = 3 - auth */
531 { &hf_glbp_auth_authtype,
532 { "Authtype", "glbp.auth.authtype", FT_UINT8, BASE_DEC, VALS(glbp_auth_type_vals),
533 0x0, NULL, HFILL }},
535 { &hf_glbp_auth_authlength,
536 { "Authlength", "glbp.auth.authlength", FT_UINT8, BASE_DEC, NULL,
537 0x0, NULL, HFILL }},
539 { &hf_glbp_auth_plainpass,
540 { "Plain pass", "glbp.auth.plainpass", FT_STRING, BASE_NONE, NULL,
541 0x0, NULL, HFILL }},
543 { &hf_glbp_auth_md5hash,
544 { "MD5-string hash", "glbp.auth.md5hash", FT_BYTES, BASE_NONE, NULL,
545 0x0, NULL, HFILL }},
547 { &hf_glbp_auth_md5chainindex,
548 { "MD5-chain index", "glbp.auth.md5chainindex", FT_UINT32, BASE_DEC, NULL,
549 0x0, NULL, HFILL }},
551 { &hf_glbp_auth_md5chainhash,
552 { "MD5-chain hash", "glbp.auth.md5chainhash", FT_BYTES, BASE_NONE, NULL,
553 0x0, NULL, HFILL }},
555 { &hf_glbp_auth_authunknown,
556 { "Unknown auth value", "glbp.auth.authunknown", FT_BYTES, BASE_NONE, NULL,
557 0x0, NULL, HFILL }},
559 /* type = unknown */
560 { &hf_glbp_unknown_data,
561 { "Unknown TLV data", "glbp.unknown.data", FT_BYTES, BASE_NONE, NULL,
562 0x0, NULL, HFILL }},
565 static int *ett[] = {
566 &ett_glbp,
567 &ett_glbp_tlv,
570 static ei_register_info ei[] = {
571 { &ei_glbp_ipv4_wrong_length,
572 { "glbp.ipv4_wrong_length", PI_MALFORMED, PI_ERROR,
573 "Wrong IPv4 address length",
574 EXPFILL }},
575 { &ei_glbp_ipv6_wrong_length,
576 { "glbp.ipv6_wrong_length", PI_MALFORMED, PI_ERROR,
577 "Wrong IPv6 address length",
578 EXPFILL }},
579 { &ei_glbp_tlv_length_too_small,
580 { "glbp.tlv_length_too_small", PI_MALFORMED, PI_ERROR,
581 "TLV Length too small",
582 EXPFILL }},
583 { &ei_glbp_tlv_invalid_bytes_used,
584 { "glbp.tlv_invalid_bytes_used", PI_MALFORMED, PI_ERROR,
585 "Zero or negative length",
586 EXPFILL }},
589 expert_module_t* expert_glbp;
591 proto_glbp = proto_register_protocol("Gateway Load Balancing Protocol", "GLBP", "glbp");
593 proto_register_field_array(proto_glbp, hf, array_length(hf));
594 proto_register_subtree_array(ett, array_length(ett));
595 expert_glbp = expert_register_protocol(proto_glbp);
596 expert_register_field_array(expert_glbp, ei, array_length(ei));
598 glbp_handle = register_dissector("glbp", dissect_glbp_static, proto_glbp);
601 void
602 proto_reg_handoff_glbp(void)
604 dissector_add_uint_with_preference("udp.port", GLBP_UDP_PORT, glbp_handle);
608 * Editor modelines - https://www.wireshark.org/tools/modelines.html
610 * Local Variables:
611 * c-basic-offset: 2
612 * tab-width: 8
613 * indent-tabs-mode: nil
614 * End:
616 * ex: set shiftwidth=2 tabstop=8 expandtab:
617 * :indentSize=2:tabSize=8:noTabs=true: