Coverage Report

Created: 2026-08-14 06:45

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-glbp.c
Line
Count
Source
1
/* packet-glbp.c
2
 *
3
 * Cisco's GLBP:  Gateway Load Balancing Protocol
4
 *
5
 * Copyright 2007 Joerg Mayer (see AUTHORS file)
6
 *
7
 * Wireshark - Network traffic analyzer
8
 * By Gerald Combs <gerald@wireshark.org>
9
 * Copyright 1998 Gerald Combs
10
 *
11
 * SPDX-License-Identifier: GPL-2.0-or-later
12
 */
13
14
/*
15
 * Documentation:
16
 * http://www.cisco.com/en/US/docs/ios/12_2t/12_2t15/feature/guide/ft_glbp.pdf
17
 *
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
25
 */
26
27
#include "config.h"
28
29
#include <epan/packet.h>
30
#include <epan/expert.h>
31
32
void proto_register_glbp(void);
33
void proto_reg_handoff_glbp(void);
34
35
static dissector_handle_t glbp_handle;
36
37
16
#define GLBP_UDP_PORT 3222
38
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;
83
84
static int ett_glbp;
85
static int ett_glbp_tlv;
86
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;
92
93
static const value_string glbp_type_vals[] = {
94
  { 1,  "Hello" },
95
  { 2,  "Request/Response?" },
96
  { 3,  "Auth" },
97
98
  { 0, NULL }
99
};
100
101
#if 0
102
static const value_string glbp_reqresp_forwarder_vals[] = {
103
  { 0,  "Request?" },
104
  { 2,  "Response?" },
105
106
  { 0, NULL }
107
};
108
#endif
109
110
static const value_string glbp_addr_type_vals[] = {
111
  { 1,  "IPv4" },
112
  { 2,  "IPv6" },
113
114
  { 0, NULL }
115
};
116
117
static const value_string glbp_auth_type_vals[] = {
118
  { 0,  "None" },
119
  { 1,  "Plain text" },
120
  { 2,  "MD5 string" },
121
  { 3,  "MD5 chain" },
122
123
  { 0, NULL }
124
};
125
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" },
132
133
  { 0, NULL }
134
};
135
#endif
136
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" },
146
147
  { 0, NULL }
148
};
149
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" },
157
158
  { 0, NULL }
159
};
160
161
static int
162
dissect_glbp_hello(tvbuff_t *tvb, int offset,
163
        packet_info *pinfo, proto_tree *tlv_tree)
164
0
{
165
0
  uint8_t addrtype;
166
0
  uint8_t addrlen;
167
168
0
  proto_tree_add_item(tlv_tree, hf_glbp_hello_unknown10, tvb, offset, 1, ENC_NA);
169
0
  offset ++;
170
0
  proto_tree_add_item(tlv_tree, hf_glbp_hello_vgstate,   tvb, offset, 1, ENC_BIG_ENDIAN);
171
0
  offset ++;
172
0
  proto_tree_add_item(tlv_tree, hf_glbp_hello_unknown11, tvb, offset, 1, ENC_NA);
173
0
  offset ++;
174
0
  proto_tree_add_item(tlv_tree, hf_glbp_hello_priority,  tvb, offset, 1, ENC_BIG_ENDIAN);
175
0
  offset++;
176
0
  proto_tree_add_item(tlv_tree, hf_glbp_hello_unknown12, tvb, offset, 2, ENC_NA);
177
0
  offset += 2;
178
0
  proto_tree_add_item(tlv_tree, hf_glbp_hello_helloint,  tvb, offset, 4, ENC_BIG_ENDIAN);
179
0
  offset += 4;
180
0
  proto_tree_add_item(tlv_tree, hf_glbp_hello_holdint,   tvb, offset, 4, ENC_BIG_ENDIAN);
181
0
  offset += 4;
182
0
  proto_tree_add_item(tlv_tree, hf_glbp_hello_redirect,  tvb, offset, 2, ENC_BIG_ENDIAN);
183
0
  offset += 2;
184
0
  proto_tree_add_item(tlv_tree, hf_glbp_hello_timeout,   tvb, offset, 2, ENC_BIG_ENDIAN);
185
0
  offset += 2;
186
0
  proto_tree_add_item(tlv_tree, hf_glbp_hello_unknown13, tvb, offset, 2, ENC_NA);
187
0
  offset += 2;
188
0
  proto_tree_add_item_ret_uint8(tlv_tree, hf_glbp_hello_addrtype,  tvb, offset, 1, ENC_BIG_ENDIAN, &addrtype);
189
0
  offset++;
190
0
  proto_tree_add_item_ret_uint8(tlv_tree, hf_glbp_hello_addrlen,   tvb, offset, 1, ENC_BIG_ENDIAN, &addrlen);
191
0
  offset++;
192
0
  switch (addrtype) {
193
0
    case 1:
194
0
    if (addrlen != 4) {
195
0
      expert_add_info_format(pinfo, NULL, &ei_glbp_ipv4_wrong_length,
196
0
        "Wrong IPv4 address length: %u", addrlen);
197
0
      return offset + addrlen;
198
0
    }
199
0
    proto_tree_add_item(tlv_tree, hf_glbp_hello_virtualipv4, tvb, offset, addrlen, ENC_BIG_ENDIAN);
200
0
    break;
201
0
  case 2:
202
0
    if (addrlen != 16) {
203
0
      expert_add_info_format(pinfo, NULL, &ei_glbp_ipv6_wrong_length,
204
0
        "Wrong IPv6 address length: %u", addrlen);
205
0
      return offset + addrlen;
206
0
    }
207
0
    proto_tree_add_item(tlv_tree, hf_glbp_hello_virtualipv6, tvb, offset, addrlen, ENC_NA);
208
0
    break;
209
0
  default:
210
0
    proto_tree_add_item(tlv_tree, hf_glbp_hello_virtualunk, tvb, offset, addrlen, ENC_NA);
211
0
    break;
212
0
  }
213
0
  offset += addrlen;
214
215
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
216
0
    val_to_str(pinfo->pool, addrtype, glbp_addr_type_vals, "%d"));
217
218
0
  return offset;
219
0
}
220
221
222
static int
223
dissect_glbp_reqresp(tvbuff_t *tvb, int offset,
224
        packet_info *pinfo _U_, proto_tree *tlv_tree)
225
0
{
226
0
  proto_tree_add_item(tlv_tree, hf_glbp_reqresp_forwarder,  tvb, offset, 1, ENC_BIG_ENDIAN);
227
0
  offset++;
228
0
  proto_tree_add_item(tlv_tree, hf_glbp_reqresp_vfstate,    tvb, offset, 1, ENC_BIG_ENDIAN);
229
0
  offset++;
230
0
  proto_tree_add_item(tlv_tree, hf_glbp_reqresp_unknown21,  tvb, offset, 1, ENC_NA);
231
0
  offset += 1;
232
0
  proto_tree_add_item(tlv_tree, hf_glbp_reqresp_priority,   tvb, offset, 1, ENC_BIG_ENDIAN);
233
0
  offset++;
234
0
  proto_tree_add_item(tlv_tree, hf_glbp_reqresp_weight,     tvb, offset, 1, ENC_BIG_ENDIAN);
235
0
  offset++;
236
0
  proto_tree_add_item(tlv_tree, hf_glbp_reqresp_unknown22,  tvb, offset, 7, ENC_NA);
237
0
  offset += 7;
238
0
  proto_tree_add_item(tlv_tree, hf_glbp_reqresp_virtualmac, tvb, offset, 6, ENC_NA);
239
0
  offset += 6;
240
241
0
  return offset;
242
0
}
243
244
static int
245
dissect_glbp_auth(tvbuff_t *tvb, int offset,
246
        packet_info *pinfo _U_, proto_tree *tlv_tree)
247
0
{
248
0
  uint8_t authtype;
249
0
  uint8_t authlength;
250
251
0
  proto_tree_add_item_ret_uint8(tlv_tree, hf_glbp_auth_authtype,   tvb, offset, 1, ENC_BIG_ENDIAN, &authtype);
252
0
  offset++;
253
0
  proto_tree_add_item_ret_uint8(tlv_tree, hf_glbp_auth_authlength, tvb, offset, 1, ENC_BIG_ENDIAN, &authlength);
254
0
  offset++;
255
0
  switch(authtype) {
256
0
  case 1:
257
0
    proto_tree_add_item(tlv_tree, hf_glbp_auth_plainpass, tvb, offset, authlength, ENC_ASCII);
258
0
    offset += authlength;
259
0
    break;
260
0
  case 2:
261
0
    proto_tree_add_item(tlv_tree, hf_glbp_auth_md5hash,   tvb, offset, authlength, ENC_NA);
262
0
    offset += authlength;
263
0
    break;
264
0
  case 3:
265
0
    proto_tree_add_item(tlv_tree, hf_glbp_auth_md5chainindex, tvb, offset, 4, ENC_BIG_ENDIAN);
266
0
    proto_tree_add_item(tlv_tree, hf_glbp_auth_md5chainhash,  tvb, offset+4, authlength-4, ENC_NA);
267
0
    offset += authlength;
268
0
    break;
269
0
  default:
270
0
    proto_tree_add_item(tlv_tree, hf_glbp_auth_authunknown, tvb, offset, authlength, ENC_NA);
271
0
    offset += authlength;
272
0
    break;
273
0
  }
274
275
0
  return offset;
276
0
}
277
278
static int
279
dissect_glbp_unknown(tvbuff_t *tvb, int offset, uint32_t length,
280
        packet_info *pinfo _U_, proto_tree *tlv_tree)
281
0
{
282
0
  proto_tree_add_item(tlv_tree, hf_glbp_unknown_data, tvb, offset, length, ENC_NA);
283
0
  offset += length;
284
285
0
  return offset;
286
0
}
287
288
static int
289
dissect_glbp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
290
0
{
291
0
  proto_tree *glbp_tree;
292
0
  proto_tree *tlv_tree;
293
0
  proto_item *ti;
294
0
  uint8_t     type;
295
0
  int         offset    = 0;
296
0
  int         lastoffset;
297
0
  uint8_t     length;
298
0
  uint16_t    group;
299
300
0
  group = tvb_get_ntohs(tvb, 2);
301
302
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "GLBP");
303
0
  col_add_fstr(pinfo->cinfo, COL_INFO, "G: %d", group);
304
305
0
  ti = proto_tree_add_item(tree, proto_glbp, tvb, 0, -1, ENC_NA);
306
0
  glbp_tree = proto_item_add_subtree(ti, ett_glbp);
307
308
  /* glbp header? */
309
0
  proto_tree_add_item(glbp_tree, hf_glbp_version, tvb, offset, 1,  ENC_BIG_ENDIAN);
310
0
  offset++;
311
0
  proto_tree_add_item(glbp_tree, hf_glbp_unknown1, tvb, offset, 1,  ENC_BIG_ENDIAN);
312
0
  offset++;
313
0
  proto_tree_add_item(glbp_tree, hf_glbp_group, tvb, offset, 2,  ENC_BIG_ENDIAN);
314
0
  offset += 2;
315
0
  proto_tree_add_item(glbp_tree, hf_glbp_unknown2, tvb, offset, 2,  ENC_NA);
316
0
  offset += 2;
317
0
  proto_tree_add_item(glbp_tree, hf_glbp_ownerid, tvb, offset, 6, ENC_NA);
318
0
  offset += 6;
319
0
  while (tvb_reported_length_remaining(tvb, offset) > 0) {
320
321
0
    type = tvb_get_uint8(tvb, offset);
322
0
    length = tvb_get_uint8(tvb, offset+1);
323
0
    if (length < 2) {
324
0
      expert_add_info_format(pinfo, NULL, &ei_glbp_tlv_length_too_small,
325
0
        "Length %u too small", length);
326
0
      return offset;
327
0
    }
328
0
    length -= 2;
329
330
0
    ti = proto_tree_add_item(glbp_tree, hf_glbp_tlv, tvb, offset, length+2, ENC_BIG_ENDIAN);
331
0
    tlv_tree = proto_item_add_subtree(ti, ett_glbp_tlv);
332
0
    proto_item_append_text(ti, " l=%d, t=%s", length+2,
333
0
                           val_to_str(pinfo->pool, type, glbp_type_vals, "%d"));
334
335
0
    proto_tree_add_item(tlv_tree, hf_glbp_type, tvb, offset, 1,  ENC_BIG_ENDIAN);
336
0
    offset++;
337
0
    proto_tree_add_item(tlv_tree, hf_glbp_length, tvb, offset, 1,  ENC_BIG_ENDIAN);
338
0
    offset++;
339
0
    col_append_fstr(pinfo->cinfo, COL_INFO, ", %s",
340
0
                    val_to_str(pinfo->pool, type, glbp_type_vals, "%d"));
341
342
0
    lastoffset = offset;
343
0
    switch(type) {
344
0
    case 1: /* Hello */
345
0
      offset = dissect_glbp_hello(tvb, offset, pinfo, tlv_tree);
346
0
      break;
347
0
    case 2: /* Request/Response */
348
0
      offset = dissect_glbp_reqresp(tvb, offset, pinfo, tlv_tree);
349
0
      break;
350
0
    case 3: /* Plaintext auth */
351
0
      offset = dissect_glbp_auth(tvb, offset, pinfo, tlv_tree);
352
0
      break;
353
0
    default:
354
0
      offset = dissect_glbp_unknown(tvb, offset, length, pinfo, tlv_tree);
355
0
      break;
356
0
    }
357
0
    if (lastoffset >= offset) {
358
0
      expert_add_info(pinfo, NULL, &ei_glbp_tlv_invalid_bytes_used);
359
0
      return lastoffset;
360
0
    }
361
    /* Skip over trailing bytes before starting with the next element */
362
0
    if (lastoffset + length > offset)
363
0
      offset = lastoffset + length;
364
0
  }
365
0
  return offset;
366
0
}
367
368
static bool
369
test_glbp(tvbuff_t *tvb, packet_info *pinfo)
370
2
{
371
2
  uint32_t unknown1;
372
2
  if ( tvb_captured_length(tvb) < 2)
373
1
    return false;
374
1
  unknown1 = tvb_get_uint8(tvb, 1);
375
1
  if (tvb_get_uint8(tvb, 0) != 1 /* version? */
376
0
      || unknown1 > 4
377
0
      || pinfo->srcport != pinfo->destport
378
#if 0 /* XXX */
379
      || unknown1 == 0 && pinfo->net_dst != ipv4:224.0.0.102
380
      && pinfo->net_dst != ipv6:...
381
      || unknown1 == 0 && pinfo->dl_src != ether:c2-00-7c-b8-00-00
382
#endif
383
1
    ) {
384
1
    return false;
385
1
  }
386
0
  return true;
387
1
}
388
389
static int
390
dissect_glbp_static(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
391
2
{
392
2
  if ( !test_glbp(tvb, pinfo) ) {
393
2
    return 0;
394
2
  }
395
0
  return dissect_glbp(tvb, pinfo, tree);
396
2
}
397
398
399
void
400
proto_register_glbp(void)
401
16
{
402
16
  static hf_register_info hf[] = {
403
    /* Header */
404
16
    { &hf_glbp_version,
405
16
      { "Version?",           "glbp.version", FT_UINT8, BASE_DEC, NULL,
406
16
        0x0, NULL, HFILL }},
407
408
16
    { &hf_glbp_unknown1,
409
16
      { "Unknown1",           "glbp.unknown1", FT_UINT8, BASE_DEC, NULL,
410
16
        0x0, NULL, HFILL }},
411
412
16
    { &hf_glbp_group,
413
16
      { "Group",              "glbp.group", FT_UINT16, BASE_DEC, NULL,
414
16
        0x0, NULL, HFILL }},
415
416
16
    { &hf_glbp_unknown2,
417
16
      { "Unknown2",           "glbp.unknown2", FT_BYTES, BASE_NONE, NULL,
418
16
        0x0, NULL, HFILL }},
419
420
16
    { &hf_glbp_ownerid,
421
16
      { "Owner ID",           "glbp.ownerid", FT_ETHER, BASE_NONE, NULL,
422
16
        0x0, NULL, HFILL }},
423
424
16
    { &hf_glbp_tlv,
425
16
      { "TLV",                "glbp.tlv", FT_PROTOCOL, BASE_NONE, NULL,
426
16
        0x0, NULL, HFILL }},
427
428
16
    { &hf_glbp_type,
429
16
      { "Type",               "glbp.type", FT_UINT8, BASE_DEC, VALS(glbp_type_vals),
430
16
        0x0, NULL, HFILL }},
431
432
16
    { &hf_glbp_length,
433
16
      { "Length",             "glbp.length", FT_UINT8, BASE_DEC, NULL,
434
16
        0x0, NULL, HFILL }},
435
436
    /* type = 1 - hello */
437
16
    { &hf_glbp_hello_unknown10,
438
16
      { "Unknown1-0",         "glbp.hello.unknown10", FT_BYTES, BASE_NONE, NULL,
439
16
        0x0, NULL, HFILL }},
440
441
16
    { &hf_glbp_hello_vgstate,
442
16
      { "VG state?",          "glbp.hello.vgstate", FT_UINT8, BASE_DEC, VALS(glbp_vgstate_vals),
443
16
        0x0, NULL, HFILL }},
444
445
16
    { &hf_glbp_hello_unknown11,
446
16
      { "Unknown1-1",         "glbp.hello.unknown11", FT_BYTES, BASE_NONE, NULL,
447
16
        0x0, NULL, HFILL }},
448
449
16
    { &hf_glbp_hello_priority,
450
16
      { "Priority",           "glbp.hello.priority", FT_UINT8, BASE_DEC, NULL,
451
16
        0x0, NULL, HFILL }},
452
453
16
    { &hf_glbp_hello_unknown12,
454
16
      { "Unknown1-2",         "glbp.hello.unknown12", FT_BYTES, BASE_NONE, NULL,
455
16
        0x0, NULL, HFILL }},
456
457
16
    { &hf_glbp_hello_helloint,
458
16
      { "Helloint",           "glbp.hello.helloint", FT_UINT32, BASE_DEC, NULL,
459
16
        0x0, "Hello interval [msec]", HFILL }},
460
461
16
    { &hf_glbp_hello_holdint,
462
16
      { "Holdint",            "glbp.hello.holdint", FT_UINT32, BASE_DEC, NULL,
463
16
        0x0, "Hold interval [msec]", HFILL }},
464
465
16
    { &hf_glbp_hello_redirect,
466
16
      { "Redirect",           "glbp.hello.redirect", FT_UINT16, BASE_DEC, NULL,
467
16
        0x0, "Redirect interval [sec]", HFILL }},
468
469
16
    { &hf_glbp_hello_timeout,
470
16
      { "Timeout",            "glbp.hello.timeout", FT_UINT16, BASE_DEC, NULL,
471
16
        0x0, "Forwarder timeout interval [sec]", HFILL }},
472
473
16
    { &hf_glbp_hello_unknown13,
474
16
      { "Unknown1-3",         "glbp.hello.unknown13", FT_BYTES, BASE_NONE, NULL,
475
16
        0x0, NULL, HFILL }},
476
477
16
    { &hf_glbp_hello_addrtype,
478
16
      { "Address type",       "glbp.hello.addrtype", FT_UINT8, BASE_DEC, VALS(glbp_addr_type_vals),
479
16
        0x0, NULL, HFILL }},
480
481
16
    { &hf_glbp_hello_addrlen,
482
16
      { "Address length",     "glbp.hello.addrlen", FT_UINT8, BASE_DEC, NULL,
483
16
        0x0, NULL, HFILL }},
484
485
16
    { &hf_glbp_hello_virtualipv4,
486
16
      { "Virtual IPv4",       "glbp.hello.virtualipv4", FT_IPv4, BASE_NONE, NULL,
487
16
        0x0, NULL, HFILL }},
488
489
16
    { &hf_glbp_hello_virtualipv6,
490
16
      { "Virtual IPv6",       "glbp.hello.virtualipv6", FT_IPv6, BASE_NONE, NULL,
491
16
        0x0, NULL, HFILL }},
492
493
16
    { &hf_glbp_hello_virtualunk,
494
16
      { "Virtual Unknown",    "glbp.hello.virtualunk", FT_BYTES, BASE_NONE, NULL,
495
16
        0x0, NULL, HFILL }},
496
497
    /* type = 2 - request/response??? */
498
16
    { &hf_glbp_reqresp_forwarder,
499
16
      { "Forwarder?",         "glbp.reqresp.forwarder", FT_UINT8, BASE_DEC, NULL,
500
16
        0x0, NULL, HFILL }},
501
502
16
    { &hf_glbp_reqresp_vfstate,
503
16
      { "VF state?",          "glbp.reqresp.vfstate", FT_UINT8, BASE_DEC, VALS(glbp_vfstate_vals),
504
16
        0x0, NULL, HFILL }},
505
506
16
    { &hf_glbp_reqresp_unknown21,
507
16
      { "Unknown2-1",         "glbp.reqresp.unknown21", FT_BYTES, BASE_NONE, NULL,
508
16
        0x0, NULL, HFILL }},
509
510
16
    { &hf_glbp_reqresp_priority,
511
16
      { "Priority",           "glbp.reqresp.priority", FT_UINT8, BASE_DEC, NULL,
512
16
        0x0, NULL, HFILL }},
513
514
16
    { &hf_glbp_reqresp_weight,
515
16
      { "Weight",             "glbp.reqresp.weight", FT_UINT8, BASE_DEC, NULL,
516
16
        0x0, NULL, HFILL }},
517
518
16
    { &hf_glbp_reqresp_unknown22,
519
16
      { "Unknown2-2",         "glbp.reqresp.unknown22", FT_BYTES, BASE_NONE, NULL,
520
16
        0x0, NULL, HFILL }},
521
522
16
    { &hf_glbp_reqresp_virtualmac,
523
16
      { "Virtualmac",         "glbp.reqresp.virtualmac", FT_ETHER, BASE_NONE, NULL,
524
16
        0x0, NULL, HFILL }},
525
526
    /* type = 3 - auth */
527
16
    { &hf_glbp_auth_authtype,
528
16
      { "Authtype",           "glbp.auth.authtype", FT_UINT8, BASE_DEC, VALS(glbp_auth_type_vals),
529
16
        0x0, NULL, HFILL }},
530
531
16
    { &hf_glbp_auth_authlength,
532
16
      { "Authlength",         "glbp.auth.authlength", FT_UINT8, BASE_DEC, NULL,
533
16
        0x0, NULL, HFILL }},
534
535
16
    { &hf_glbp_auth_plainpass,
536
16
      { "Plain pass",         "glbp.auth.plainpass", FT_STRING, BASE_NONE, NULL,
537
16
        0x0, NULL, HFILL }},
538
539
16
    { &hf_glbp_auth_md5hash,
540
16
      { "MD5-string hash",    "glbp.auth.md5hash", FT_BYTES, BASE_NONE, NULL,
541
16
        0x0, NULL, HFILL }},
542
543
16
    { &hf_glbp_auth_md5chainindex,
544
16
      { "MD5-chain index",    "glbp.auth.md5chainindex", FT_UINT32, BASE_DEC, NULL,
545
16
        0x0, NULL, HFILL }},
546
547
16
    { &hf_glbp_auth_md5chainhash,
548
16
      { "MD5-chain hash",     "glbp.auth.md5chainhash", FT_BYTES, BASE_NONE, NULL,
549
16
        0x0, NULL, HFILL }},
550
551
16
    { &hf_glbp_auth_authunknown,
552
16
      { "Unknown auth value", "glbp.auth.authunknown", FT_BYTES, BASE_NONE, NULL,
553
16
        0x0, NULL, HFILL }},
554
555
    /* type = unknown */
556
16
    { &hf_glbp_unknown_data,
557
16
      { "Unknown TLV data",   "glbp.unknown.data", FT_BYTES, BASE_NONE, NULL,
558
16
        0x0, NULL, HFILL }},
559
560
16
  };
561
16
  static int *ett[] = {
562
16
    &ett_glbp,
563
16
    &ett_glbp_tlv,
564
16
  };
565
566
16
  static ei_register_info ei[] = {
567
16
    { &ei_glbp_ipv4_wrong_length,
568
16
      { "glbp.ipv4_wrong_length", PI_MALFORMED, PI_ERROR,
569
16
        "Wrong IPv4 address length",
570
16
        EXPFILL }},
571
16
    { &ei_glbp_ipv6_wrong_length,
572
16
      { "glbp.ipv6_wrong_length", PI_MALFORMED, PI_ERROR,
573
16
        "Wrong IPv6 address length",
574
16
        EXPFILL }},
575
16
    { &ei_glbp_tlv_length_too_small,
576
16
      { "glbp.tlv_length_too_small", PI_MALFORMED, PI_ERROR,
577
16
        "TLV Length too small",
578
16
        EXPFILL }},
579
16
    { &ei_glbp_tlv_invalid_bytes_used,
580
16
      { "glbp.tlv_invalid_bytes_used", PI_MALFORMED, PI_ERROR,
581
16
        "Zero or negative length",
582
16
        EXPFILL }},
583
16
  };
584
585
16
  expert_module_t* expert_glbp;
586
587
16
  proto_glbp = proto_register_protocol("Gateway Load Balancing Protocol", "GLBP", "glbp");
588
589
16
  proto_register_field_array(proto_glbp, hf, array_length(hf));
590
16
  proto_register_subtree_array(ett, array_length(ett));
591
16
  expert_glbp = expert_register_protocol(proto_glbp);
592
16
  expert_register_field_array(expert_glbp, ei, array_length(ei));
593
594
16
  glbp_handle = register_dissector("glbp", dissect_glbp_static, proto_glbp);
595
16
}
596
597
void
598
proto_reg_handoff_glbp(void)
599
16
{
600
16
  dissector_add_uint_with_preference("udp.port", GLBP_UDP_PORT, glbp_handle);
601
16
}
602
603
/*
604
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
605
 *
606
 * Local Variables:
607
 * c-basic-offset: 2
608
 * tab-width: 8
609
 * indent-tabs-mode: nil
610
 * End:
611
 *
612
 * ex: set shiftwidth=2 tabstop=8 expandtab:
613
 * :indentSize=2:tabSize=8:noTabs=true:
614
 */