HACK: 2nd try to match RowsetProperties
[wireshark-wip.git] / epan / dissectors / packet-glbp.c
blob054cdbf795b35e211ebe5674c7a383a9ea9a02f1
1 /* packet-glbp.c
3 * Cisco's GLBP: Gateway Load Balancing Protocol
5 * $Id$
7 * Copyright 2007 Joerg Mayer (see AUTHORS file)
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 * Documentation:
30 * http://www.cisco.com/en/US/docs/ios/12_2t/12_2t15/feature/guide/ft_glbp.pdf
32 * TODO: This dissector has been written without specs, so much of it is
33 * guesswork. Also, there are still unknown elements in the message.
34 * Some debug output:
35 * GLBP: Fa0/0 Grp 1020 Hello out VG Active pri 100 vIP FE80::C800:8FF:FE64:AAAA
36 * hello 3000, hold 10000 VF 1 Active pri 167 vMAC 0007.b403.fc01
37 * GLBP: Fa0/0 Grp 1021 Hello out VG Active pri 100 vIP 10.20.20.100
38 * hello 3000, hold 10000 VF 1 Active pri 167 vMAC 0007.b403.fd01
41 #include "config.h"
43 #include <glib.h>
44 #include <epan/packet.h>
45 #include <epan/expert.h>
47 static int proto_glbp = -1;
48 /* glbp header? */
49 static gint hf_glbp_version = -1;
50 static gint hf_glbp_unknown1 = -1;
51 static gint hf_glbp_group = -1;
52 static gint hf_glbp_unknown2 = -1;
53 static gint hf_glbp_ownerid = -1;
54 static gint hf_glbp_tlv = -1;
55 static gint hf_glbp_type = -1;
56 static gint hf_glbp_length = -1;
57 /* glbp type = 1 - hello */
58 static gint hf_glbp_hello_unknown10 = -1;
59 static gint hf_glbp_hello_vgstate = -1;
60 static gint hf_glbp_hello_unknown11 = -1;
61 static gint hf_glbp_hello_priority = -1;
62 static gint hf_glbp_hello_unknown12 = -1;
63 static gint hf_glbp_hello_helloint = -1;
64 static gint hf_glbp_hello_holdint = -1;
65 static gint hf_glbp_hello_redirect = -1;
66 static gint hf_glbp_hello_timeout = -1;
67 static gint hf_glbp_hello_unknown13 = -1;
68 static gint hf_glbp_hello_addrtype = -1;
69 static gint hf_glbp_hello_addrlen = -1;
70 static gint hf_glbp_hello_virtualipv4 = -1;
71 static gint hf_glbp_hello_virtualipv6 = -1;
72 static gint hf_glbp_hello_virtualunk = -1;
73 /* glbp type = 2 - Request/Response??? */
74 static gint hf_glbp_reqresp_forwarder = -1;
75 static gint hf_glbp_reqresp_vfstate = -1;
76 static gint hf_glbp_reqresp_unknown21 = -1;
77 static gint hf_glbp_reqresp_priority = -1;
78 static gint hf_glbp_reqresp_weight = -1;
79 static gint hf_glbp_reqresp_unknown22 = -1;
80 static gint hf_glbp_reqresp_virtualmac = -1;
81 /* glbp type = 3 - Auth */
82 static gint hf_glbp_auth_authtype = -1;
83 static gint hf_glbp_auth_authlength = -1;
84 static gint hf_glbp_auth_plainpass = -1;
85 static gint hf_glbp_auth_md5hash = -1;
86 static gint hf_glbp_auth_md5chainindex = -1;
87 static gint hf_glbp_auth_md5chainhash = -1;
88 static gint hf_glbp_auth_authunknown = -1;
89 /* unknown type */
90 static gint hf_glbp_unknown_data = -1;
92 static gint ett_glbp = -1;
93 static gint ett_glbp_tlv = -1;
95 /* filterable expert infos */
96 static expert_field ei_glbp_ipv4_wrong_length = EI_INIT;
97 static expert_field ei_glbp_ipv6_wrong_length = EI_INIT;
98 static expert_field ei_glbp_tlv_length_too_small = EI_INIT;
99 static expert_field ei_glbp_tlv_invalid_bytes_used = EI_INIT;
101 static const value_string glbp_type_vals[] = {
102 { 1, "Hello" },
103 { 2, "Request/Response?" },
104 { 3, "Auth" },
106 { 0, NULL }
109 #if 0
110 static const value_string glbp_reqresp_forwarder_vals[] = {
111 { 0, "Request?" },
112 { 2, "Response?" },
114 { 0, NULL }
116 #endif
118 static const value_string glbp_addr_type_vals[] = {
119 { 1, "IPv4" },
120 { 2, "IPv6" },
122 { 0, NULL }
125 static const value_string glbp_auth_type_vals[] = {
126 { 0, "None" },
127 { 1, "Plain text" },
128 { 2, "MD5 string" },
129 { 3, "MD5 chain" },
131 { 0, NULL }
134 #if 0
135 static const value_string glbp_loadbalancing_vals[] = {
136 { x, "None (AVG only)" },
137 { x, "Weighted" },
138 { x, "Host dependent" },
139 { x, "Round robin" },
141 { 0, NULL }
143 #endif
145 static const value_string glbp_vgstate_vals[] = {
146 #if 0
147 { x, "Disabled" },
148 { x, "Initial" },
149 #endif
150 { 4, "Listen" },
151 { 8, "Speak" },
152 { 0x10, "Standby" },
153 { 0x20, "Active" },
155 { 0, NULL }
158 static const value_string glbp_vfstate_vals[] = {
159 #if 0
160 { x, "Disabled" },
161 { x, "Initial" },
162 #endif
163 { 4, "Listen" },
164 { 0x20, "Active" },
166 { 0, NULL }
169 static int
170 dissect_glbp_hello(tvbuff_t *tvb, int offset,
171 packet_info *pinfo, proto_tree *tlv_tree)
173 guint8 addrtype;
174 guint8 addrlen;
176 proto_tree_add_item(tlv_tree, hf_glbp_hello_unknown10, tvb, offset, 1, ENC_NA);
177 offset ++;
178 proto_tree_add_item(tlv_tree, hf_glbp_hello_vgstate, tvb, offset, 1, ENC_BIG_ENDIAN);
179 offset ++;
180 proto_tree_add_item(tlv_tree, hf_glbp_hello_unknown11, tvb, offset, 1, ENC_NA);
181 offset ++;
182 proto_tree_add_item(tlv_tree, hf_glbp_hello_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
183 offset++;
184 proto_tree_add_item(tlv_tree, hf_glbp_hello_unknown12, tvb, offset, 2, ENC_NA);
185 offset += 2;
186 proto_tree_add_item(tlv_tree, hf_glbp_hello_helloint, tvb, offset, 4, ENC_BIG_ENDIAN);
187 offset += 4;
188 proto_tree_add_item(tlv_tree, hf_glbp_hello_holdint, tvb, offset, 4, ENC_BIG_ENDIAN);
189 offset += 4;
190 proto_tree_add_item(tlv_tree, hf_glbp_hello_redirect, tvb, offset, 2, ENC_BIG_ENDIAN);
191 offset += 2;
192 proto_tree_add_item(tlv_tree, hf_glbp_hello_timeout, tvb, offset, 2, ENC_BIG_ENDIAN);
193 offset += 2;
194 proto_tree_add_item(tlv_tree, hf_glbp_hello_unknown13, tvb, offset, 2, ENC_NA);
195 offset += 2;
196 proto_tree_add_item(tlv_tree, hf_glbp_hello_addrtype, tvb, offset, 1, ENC_BIG_ENDIAN);
197 addrtype = tvb_get_guint8( tvb, offset);
198 offset++;
199 proto_tree_add_item(tlv_tree, hf_glbp_hello_addrlen, tvb, offset, 1, ENC_BIG_ENDIAN);
200 addrlen = tvb_get_guint8(tvb, offset);
201 offset++;
202 switch (addrtype) {
203 case 1:
204 if (addrlen != 4) {
205 expert_add_info_format(pinfo, NULL, &ei_glbp_ipv4_wrong_length,
206 "Wrong IPv4 address length: %u", addrlen);
207 return offset + addrlen;
209 proto_tree_add_item(tlv_tree, hf_glbp_hello_virtualipv4, tvb, offset, addrlen, ENC_BIG_ENDIAN);
210 break;
211 case 2:
212 if (addrlen != 16) {
213 expert_add_info_format(pinfo, NULL, &ei_glbp_ipv6_wrong_length,
214 "Wrong IPv6 address length: %u", addrlen);
215 return offset + addrlen;
217 proto_tree_add_item(tlv_tree, hf_glbp_hello_virtualipv6, tvb, offset, addrlen, ENC_NA);
218 break;
219 default:
220 proto_tree_add_item(tlv_tree, hf_glbp_hello_virtualunk, tvb, offset, addrlen, ENC_NA);
221 break;
223 offset += addrlen;
225 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
226 val_to_str(addrtype, glbp_addr_type_vals, "%d"));
228 return offset;
232 static int
233 dissect_glbp_reqresp(tvbuff_t *tvb, int offset,
234 packet_info *pinfo _U_, proto_tree *tlv_tree)
236 proto_tree_add_item(tlv_tree, hf_glbp_reqresp_forwarder, tvb, offset, 1, ENC_BIG_ENDIAN);
237 offset++;
238 proto_tree_add_item(tlv_tree, hf_glbp_reqresp_vfstate, tvb, offset, 1, ENC_BIG_ENDIAN);
239 offset++;
240 proto_tree_add_item(tlv_tree, hf_glbp_reqresp_unknown21, tvb, offset, 1, ENC_NA);
241 offset += 1;
242 proto_tree_add_item(tlv_tree, hf_glbp_reqresp_priority, tvb, offset, 1, ENC_BIG_ENDIAN);
243 offset++;
244 proto_tree_add_item(tlv_tree, hf_glbp_reqresp_weight, tvb, offset, 1, ENC_BIG_ENDIAN);
245 offset++;
246 proto_tree_add_item(tlv_tree, hf_glbp_reqresp_unknown22, tvb, offset, 7, ENC_NA);
247 offset += 7;
248 proto_tree_add_item(tlv_tree, hf_glbp_reqresp_virtualmac, tvb, offset, 6, ENC_NA);
249 offset += 6;
251 return offset;
254 static int
255 dissect_glbp_auth(tvbuff_t *tvb, int offset,
256 packet_info *pinfo _U_, proto_tree *tlv_tree)
258 guint8 authtype;
259 guint8 authlength;
261 proto_tree_add_item(tlv_tree, hf_glbp_auth_authtype, tvb, offset, 1, ENC_BIG_ENDIAN);
262 authtype = tvb_get_guint8(tvb, offset);
263 offset++;
264 proto_tree_add_item(tlv_tree, hf_glbp_auth_authlength, tvb, offset, 1, ENC_BIG_ENDIAN);
265 authlength = tvb_get_guint8(tvb, offset);
266 offset++;
267 switch(authtype) {
268 case 1:
269 proto_tree_add_item(tlv_tree, hf_glbp_auth_plainpass, tvb, offset, authlength, ENC_ASCII|ENC_NA);
270 offset += authlength;
271 break;
272 case 2:
273 proto_tree_add_item(tlv_tree, hf_glbp_auth_md5hash, tvb, offset, authlength, ENC_NA);
274 offset += authlength;
275 break;
276 case 3:
277 proto_tree_add_item(tlv_tree, hf_glbp_auth_md5chainindex, tvb, offset, 4, ENC_BIG_ENDIAN);
278 proto_tree_add_item(tlv_tree, hf_glbp_auth_md5chainhash, tvb, offset+4, authlength-4, ENC_NA);
279 offset += authlength;
280 break;
281 default:
282 proto_tree_add_item(tlv_tree, hf_glbp_auth_authunknown, tvb, offset, authlength, ENC_NA);
283 offset += authlength;
284 break;
287 return offset;
290 static int
291 dissect_glbp_unknown(tvbuff_t *tvb, int offset, guint32 length,
292 packet_info *pinfo _U_, proto_tree *tlv_tree)
294 proto_tree_add_item(tlv_tree, hf_glbp_unknown_data, tvb, offset, length, ENC_NA);
295 offset += length;
297 return offset;
300 static int
301 dissect_glbp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
303 proto_tree *glbp_tree;
304 proto_tree *tlv_tree;
305 proto_item *ti;
306 guint8 type;
307 int offset = 0;
308 int lastoffset;
309 guint8 length;
310 guint16 group;
312 group = tvb_get_ntohs(tvb, 2);
314 col_set_str(pinfo->cinfo, COL_PROTOCOL, "GLBP");
315 col_add_fstr(pinfo->cinfo, COL_INFO, "G: %d", group);
317 ti = proto_tree_add_item(tree, proto_glbp, tvb, 0, -1, ENC_NA);
318 glbp_tree = proto_item_add_subtree(ti, ett_glbp);
320 /* glbp header? */
321 proto_tree_add_item(glbp_tree, hf_glbp_version, tvb, offset, 1, ENC_BIG_ENDIAN);
322 offset++;
323 proto_tree_add_item(glbp_tree, hf_glbp_unknown1, tvb, offset, 1, ENC_BIG_ENDIAN);
324 offset++;
325 proto_tree_add_item(glbp_tree, hf_glbp_group, tvb, offset, 2, ENC_BIG_ENDIAN);
326 offset += 2;
327 proto_tree_add_item(glbp_tree, hf_glbp_unknown2, tvb, offset, 2, ENC_NA);
328 offset += 2;
329 proto_tree_add_item(glbp_tree, hf_glbp_ownerid, tvb, offset, 6, ENC_NA);
330 offset += 6;
331 while (tvb_length_remaining(tvb, offset) > 0) {
333 type = tvb_get_guint8(tvb, offset);
334 length = tvb_get_guint8(tvb, offset+1);
335 if (length < 2) {
336 expert_add_info_format(pinfo, NULL, &ei_glbp_tlv_length_too_small,
337 "Length %u too small", length);
338 return offset;
340 length -= 2;
342 ti = proto_tree_add_item(glbp_tree, hf_glbp_tlv, tvb, offset, length+2, ENC_BIG_ENDIAN);
343 tlv_tree = proto_item_add_subtree(ti, ett_glbp_tlv);
344 proto_item_append_text(ti, " l=%d, t=%s", length+2,
345 val_to_str(type, glbp_type_vals, "%d"));
347 proto_tree_add_item(tlv_tree, hf_glbp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
348 offset++;
349 proto_tree_add_item(tlv_tree, hf_glbp_length, tvb, offset, 1, ENC_BIG_ENDIAN);
350 offset++;
351 col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
352 val_to_str(type, glbp_type_vals, "%d"));
354 lastoffset = offset;
355 switch(type) {
356 case 1: /* Hello */
357 offset = dissect_glbp_hello(tvb, offset, pinfo, tlv_tree);
358 break;
359 case 2: /* Request/Response */
360 offset = dissect_glbp_reqresp(tvb, offset, pinfo, tlv_tree);
361 break;
362 case 3: /* Plaintext auth */
363 offset = dissect_glbp_auth(tvb, offset, pinfo, tlv_tree);
364 break;
365 default:
366 offset = dissect_glbp_unknown(tvb, offset, length, pinfo, tlv_tree);
367 break;
369 if (lastoffset >= offset) {
370 expert_add_info(pinfo, NULL, &ei_glbp_tlv_invalid_bytes_used);
371 return lastoffset;
373 /* Skip over trailing bytes before starting with the next element */
374 if (lastoffset + length > offset)
375 offset = lastoffset + length;
377 return offset;
380 static gboolean
381 test_glbp(tvbuff_t *tvb, packet_info *pinfo)
383 guint32 unknown1;
384 if ( tvb_length(tvb) < 2)
385 return FALSE;
386 unknown1 = tvb_get_guint8(tvb, 1);
387 if (tvb_get_guint8(tvb, 0) != 1 /* version? */
388 || unknown1 > 4
389 || pinfo->srcport != pinfo->destport
390 #if 0 /* XXX */
391 || unknown1 == 0 && pinfo->net_dst != ipv4:224.0.0.102
392 && pinfo->net_dst != ipv6:...
393 || unknown1 == 0 && pinfo->dl_src != ether:c2-00-7c-b8-00-00
394 #endif
396 return FALSE;
398 return TRUE;
401 static int
402 dissect_glbp_static(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
404 if ( !test_glbp(tvb, pinfo) ) {
405 return 0;
407 return dissect_glbp(tvb, pinfo, tree);
411 void
412 proto_register_glbp(void)
414 static hf_register_info hf[] = {
415 /* Header */
416 { &hf_glbp_version,
417 { "Version?", "glbp.version", FT_UINT8, BASE_DEC, NULL,
418 0x0, NULL, HFILL }},
420 { &hf_glbp_unknown1,
421 { "Unknown1", "glbp.unknown1", FT_UINT8, BASE_DEC, NULL,
422 0x0, NULL, HFILL }},
424 { &hf_glbp_group,
425 { "Group", "glbp.group", FT_UINT16, BASE_DEC, NULL,
426 0x0, NULL, HFILL }},
428 { &hf_glbp_unknown2,
429 { "Unknown2", "glbp.unknown2", FT_BYTES, BASE_NONE, NULL,
430 0x0, NULL, HFILL }},
432 { &hf_glbp_ownerid,
433 { "Owner ID", "glbp.ownerid", FT_ETHER, BASE_NONE, NULL,
434 0x0, NULL, HFILL }},
436 { &hf_glbp_tlv,
437 { "TLV", "glbp.tlv", FT_PROTOCOL, BASE_NONE, NULL,
438 0x0, NULL, HFILL }},
440 { &hf_glbp_type,
441 { "Type", "glbp.type", FT_UINT8, BASE_DEC, VALS(glbp_type_vals),
442 0x0, NULL, HFILL }},
444 { &hf_glbp_length,
445 { "Length", "glbp.length", FT_UINT8, BASE_DEC, NULL,
446 0x0, NULL, HFILL }},
448 /* type = 1 - hello */
449 { &hf_glbp_hello_unknown10,
450 { "Unknown1-0", "glbp.hello.unknown10", FT_BYTES, BASE_NONE, NULL,
451 0x0, NULL, HFILL }},
453 { &hf_glbp_hello_vgstate,
454 { "VG state?", "glbp.hello.vgstate", FT_UINT8, BASE_DEC, VALS(glbp_vgstate_vals),
455 0x0, NULL, HFILL }},
457 { &hf_glbp_hello_unknown11,
458 { "Unknown1-1", "glbp.hello.unknown11", FT_BYTES, BASE_NONE, NULL,
459 0x0, NULL, HFILL }},
461 { &hf_glbp_hello_priority,
462 { "Priority", "glbp.hello.priority", FT_UINT8, BASE_DEC, NULL,
463 0x0, NULL, HFILL }},
465 { &hf_glbp_hello_unknown12,
466 { "Unknown1-2", "glbp.hello.unknown12", FT_BYTES, BASE_NONE, NULL,
467 0x0, NULL, HFILL }},
469 { &hf_glbp_hello_helloint,
470 { "Helloint", "glbp.hello.helloint", FT_UINT32, BASE_DEC, NULL,
471 0x0, "Hello interval [msec]", HFILL }},
473 { &hf_glbp_hello_holdint,
474 { "Holdint", "glbp.hello.holdint", FT_UINT32, BASE_DEC, NULL,
475 0x0, "Hold interval [msec]", HFILL }},
477 { &hf_glbp_hello_redirect,
478 { "Redirect", "glbp.hello.redirect", FT_UINT16, BASE_DEC, NULL,
479 0x0, "Redirect interval [sec]", HFILL }},
481 { &hf_glbp_hello_timeout,
482 { "Timeout", "glbp.hello.timeout", FT_UINT16, BASE_DEC, NULL,
483 0x0, "Forwarder timeout interval [sec]", HFILL }},
485 { &hf_glbp_hello_unknown13,
486 { "Unknown1-3", "glbp.hello.unknown13", FT_BYTES, BASE_NONE, NULL,
487 0x0, NULL, HFILL }},
489 { &hf_glbp_hello_addrtype,
490 { "Address type", "glbp.hello.addrtype", FT_UINT8, BASE_DEC, VALS(glbp_addr_type_vals),
491 0x0, NULL, HFILL }},
493 { &hf_glbp_hello_addrlen,
494 { "Address length", "glbp.hello.addrlen", FT_UINT8, BASE_DEC, NULL,
495 0x0, NULL, HFILL }},
497 { &hf_glbp_hello_virtualipv4,
498 { "Virtual IPv4", "glbp.hello.virtualipv4", FT_IPv4, BASE_NONE, NULL,
499 0x0, NULL, HFILL }},
501 { &hf_glbp_hello_virtualipv6,
502 { "Virtual IPv6", "glbp.hello.virtualipv6", FT_IPv6, BASE_NONE, NULL,
503 0x0, NULL, HFILL }},
505 { &hf_glbp_hello_virtualunk,
506 { "Virtual Unknown", "glbp.hello.virtualunk", FT_BYTES, BASE_NONE, NULL,
507 0x0, NULL, HFILL }},
509 /* type = 2 - request/response??? */
510 { &hf_glbp_reqresp_forwarder,
511 { "Forwarder?", "glbp.reqresp.forwarder", FT_UINT8, BASE_DEC, NULL,
512 0x0, NULL, HFILL }},
514 { &hf_glbp_reqresp_vfstate,
515 { "VF state?", "glbp.reqresp.vfstate", FT_UINT8, BASE_DEC, VALS(glbp_vfstate_vals),
516 0x0, NULL, HFILL }},
518 { &hf_glbp_reqresp_unknown21,
519 { "Unknown2-1", "glbp.reqresp.unknown21", FT_BYTES, BASE_NONE, NULL,
520 0x0, NULL, HFILL }},
522 { &hf_glbp_reqresp_priority,
523 { "Priority", "glbp.reqresp.priority", FT_UINT8, BASE_DEC, NULL,
524 0x0, NULL, HFILL }},
526 { &hf_glbp_reqresp_weight,
527 { "Weight", "glbp.reqresp.weight", FT_UINT8, BASE_DEC, NULL,
528 0x0, NULL, HFILL }},
530 { &hf_glbp_reqresp_unknown22,
531 { "Unknown2-2", "glbp.reqresp.unknown22", FT_BYTES, BASE_NONE, NULL,
532 0x0, NULL, HFILL }},
534 { &hf_glbp_reqresp_virtualmac,
535 { "Virtualmac", "glbp.reqresp.virtualmac", FT_ETHER, BASE_NONE, NULL,
536 0x0, NULL, HFILL }},
538 /* type = 3 - auth */
539 { &hf_glbp_auth_authtype,
540 { "Authtype", "glbp.auth.authtype", FT_UINT8, BASE_DEC, VALS(glbp_auth_type_vals),
541 0x0, NULL, HFILL }},
543 { &hf_glbp_auth_authlength,
544 { "Authlength", "glbp.auth.authlength", FT_UINT8, BASE_DEC, NULL,
545 0x0, NULL, HFILL }},
547 { &hf_glbp_auth_plainpass,
548 { "Plain pass", "glbp.auth.plainpass", FT_STRING, BASE_NONE, NULL,
549 0x0, NULL, HFILL }},
551 { &hf_glbp_auth_md5hash,
552 { "MD5-string hash", "glbp.auth.md5hash", FT_BYTES, BASE_NONE, NULL,
553 0x0, NULL, HFILL }},
555 { &hf_glbp_auth_md5chainindex,
556 { "MD5-chain index", "glbp.auth.md5chainindex", FT_UINT32, BASE_DEC, NULL,
557 0x0, NULL, HFILL }},
559 { &hf_glbp_auth_md5chainhash,
560 { "MD5-chain hash", "glbp.auth.md5chainhash", FT_BYTES, BASE_NONE, NULL,
561 0x0, NULL, HFILL }},
563 { &hf_glbp_auth_authunknown,
564 { "Unknown auth value", "glbp.auth.authunknown", FT_BYTES, BASE_NONE, NULL,
565 0x0, NULL, HFILL }},
567 /* type = unknown */
568 { &hf_glbp_unknown_data,
569 { "Unknown TLV data", "glbp.unknown.data", FT_BYTES, BASE_NONE, NULL,
570 0x0, NULL, HFILL }},
573 static gint *ett[] = {
574 &ett_glbp,
575 &ett_glbp_tlv,
578 static ei_register_info ei[] = {
579 { &ei_glbp_ipv4_wrong_length,
580 { "glbp.ipv4_wrong_length", PI_MALFORMED, PI_ERROR,
581 "Wrong IPv4 address length: %u",
582 EXPFILL }},
583 { &ei_glbp_ipv6_wrong_length,
584 { "glbp.ipv6_wrong_length", PI_MALFORMED, PI_ERROR,
585 "Wrong IPv6 address length: %u",
586 EXPFILL }},
587 { &ei_glbp_tlv_length_too_small,
588 { "glbp.tlv_length_too_small", PI_MALFORMED, PI_ERROR,
589 "Length %u too small",
590 EXPFILL }},
591 { &ei_glbp_tlv_invalid_bytes_used,
592 { "glbp.tlv_invalid_bytes_used", PI_MALFORMED, PI_ERROR,
593 "Zero or negative length",
594 EXPFILL }},
597 expert_module_t* expert_glbp;
599 proto_glbp = proto_register_protocol(
600 "Gateway Load Balancing Protocol", "GLBP", "glbp");
601 proto_register_field_array(proto_glbp, hf, array_length(hf));
602 proto_register_subtree_array(ett, array_length(ett));
603 expert_glbp = expert_register_protocol(proto_glbp);
604 expert_register_field_array(expert_glbp, ei, array_length(ei));
607 void
608 proto_reg_handoff_glbp(void)
610 dissector_handle_t glbp_handle;
612 glbp_handle = new_create_dissector_handle(dissect_glbp_static, proto_glbp);
613 dissector_add_uint("udp.port", 3222, glbp_handle);