Coverage Report

Created: 2026-07-12 07:10

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/wireshark/epan/dissectors/packet-tapa.c
Line
Count
Source
1
/* packet-tapa.c
2
 * Routines for the disassembly of the Trapeze TAPA protocol
3
 *
4
 * Copyright 2007 Joerg Mayer (see AUTHORS file)
5
 *
6
 * Wireshark - Network traffic analyzer
7
 * By Gerald Combs <gerald@wireshark.org>
8
 * Copyright 1998 Gerald Combs
9
 *
10
 * SPDX-License-Identifier: GPL-2.0-or-later
11
 */
12
13
/*
14
  TODO:
15
16
Specs:
17
18
  No specs available.
19
 */
20
21
#include "config.h"
22
23
#include <epan/packet.h>
24
#include <epan/to_str.h>
25
#include <epan/expert.h>
26
#include <epan/iana-info.h>
27
#include "packet-ip.h"
28
29
void proto_reg_handoff_tapa(void);
30
void proto_register_tapa(void);
31
32
/* protocol handles */
33
static int proto_tapa;
34
35
/* ett handles */
36
static int ett_tapa_discover;
37
static int ett_tapa_discover_req;
38
static int ett_tapa_tunnel;
39
40
/* hf elements */
41
static int hf_tapa_discover_type;
42
static int hf_tapa_discover_flags;
43
static int hf_tapa_discover_length;
44
static int hf_tapa_discover_unknown;
45
46
static int hf_tapa_discover_req_type;
47
static int hf_tapa_discover_req_pad;
48
static int hf_tapa_discover_req_length;
49
static int hf_tapa_discover_req_value;
50
51
static int hf_tapa_discover_newtlv_type;
52
static int hf_tapa_discover_newtlv_pad;
53
static int hf_tapa_discover_newtlv_length;
54
static int hf_tapa_discover_newtlv_valuetext;
55
static int hf_tapa_discover_newtlv_valuehex;
56
57
static int hf_tapa_discover_reply_switchip;
58
static int hf_tapa_discover_reply_unused;
59
static int hf_tapa_discover_reply_bias;
60
static int hf_tapa_discover_reply_pad;
61
62
static int hf_tapa_tunnel_version;
63
static int hf_tapa_tunnel_five;
64
static int hf_tapa_tunnel_type;
65
static int hf_tapa_tunnel_zero;
66
static int hf_tapa_tunnel_dmac;
67
static int hf_tapa_tunnel_smac;
68
static int hf_tapa_tunnel_seqno;
69
static int hf_tapa_tunnel_length;
70
static int hf_tapa_tunnel_0804;
71
static int hf_tapa_tunnel_tagsetc;
72
73
static int hf_tapa_tunnel_remaining;
74
75
static expert_field ei_tapa_length_too_short;
76
77
static dissector_handle_t tapa_handle;
78
79
15
#define PORT_TAPA 5000 /* Not IANA registered */
80
81
typedef enum {
82
  TAPA_TYPE_REQUEST = 0x01,
83
  TAPA_TYPE_REPLY   = 0x02,
84
  TAPA_TYPE_REQUEST_NEW = 0x04,
85
  TAPA_TYPE_REPLY_NEW = 0x05
86
} tapa_discover_type_t;
87
88
static const value_string tapa_discover_type_vals[] = {
89
  { TAPA_TYPE_REQUEST,    "Request" },
90
  { TAPA_TYPE_REPLY,    "Reply" },
91
  { TAPA_TYPE_REQUEST_NEW,  "NewRequest" },
92
  { TAPA_TYPE_REPLY_NEW,    "NewReply" },
93
94
  { 0,  NULL }
95
};
96
97
typedef enum {
98
  TAPA_TUNNEL_TYPE_0  = 0x00,
99
  TAPA_TUNNEL_TYPE_1  = 0x01
100
} tapa_tunnel_type_t;
101
102
static const value_string tapa_tunnel_type_vals[] = {
103
  { TAPA_TUNNEL_TYPE_0, "Type 0" },
104
  { TAPA_TUNNEL_TYPE_1, "Type 1" },
105
106
  { 0,  NULL }
107
};
108
109
typedef enum {
110
  TAPA_REQUEST_SERIAL = 0x01,
111
  TAPA_REQUEST_MODEL  = 0x02
112
} tapa_discover_request_t;
113
114
static const value_string tapa_discover_request_vals[] = {
115
  { TAPA_REQUEST_SERIAL,  "SerialNo" },
116
  { TAPA_REQUEST_MODEL, "Model" },
117
118
  { 0,  NULL }
119
};
120
121
#if 0
122
static const value_string tapa_discover_unknown_vals[] = {
123
124
  { 0,  NULL }
125
};
126
#endif
127
128
static bool
129
check_ascii(tvbuff_t *tvb, int offset, int length)
130
4
{
131
4
  int i;
132
4
  uint8_t buf;
133
134
43
  for (i = 0; i < length; i++) {
135
43
    buf = tvb_get_uint8(tvb, offset+i);
136
43
    if (buf < 0x20 || buf >= 0x80) {
137
4
      return false;
138
4
    }
139
43
  }
140
0
  return true;
141
4
}
142
143
static int
144
dissect_tapa_discover_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tapa_discover_tree, uint32_t offset, int remaining)
145
1
{
146
1
  proto_tree_add_item(tapa_discover_tree, hf_tapa_discover_reply_switchip, tvb, offset, 4,
147
1
    ENC_BIG_ENDIAN);
148
149
1
  col_append_fstr(pinfo->cinfo, COL_INFO, ", Switch: %s",
150
1
      tvb_ip_to_str(pinfo->pool, tvb, offset));
151
152
1
  offset += 4;
153
154
1
  proto_tree_add_item(tapa_discover_tree, hf_tapa_discover_reply_unused, tvb, offset, 1,
155
1
    ENC_BIG_ENDIAN);
156
1
  offset += 1;
157
158
1
  proto_tree_add_item(tapa_discover_tree, hf_tapa_discover_reply_bias, tvb, offset, 1,
159
1
    ENC_BIG_ENDIAN);
160
1
  offset += 1;
161
162
1
  remaining -= 6;
163
1
  proto_tree_add_item(tapa_discover_tree, hf_tapa_discover_reply_pad, tvb, offset, remaining,
164
1
    ENC_NA);
165
1
  offset += remaining;
166
167
1
  return offset;
168
1
}
169
170
static int
171
dissect_tapa_discover_req(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tapa_discover_tree, uint32_t offset, int remaining)
172
0
{
173
0
  proto_tree  *tapa_discover_item_tree;
174
0
  uint8_t    item_type;
175
0
  int    item_length;
176
0
  char    *item_text;
177
0
  const char  *item_type_text;
178
179
0
  while (remaining > 0) {
180
0
    item_type = tvb_get_uint8(tvb, offset);
181
0
    item_type_text = val_to_str(pinfo->pool, item_type, tapa_discover_request_vals, "%d");
182
0
    item_length = tvb_get_ntohs(tvb, offset + 2);
183
0
    item_text = tvb_format_text(pinfo->pool, tvb, offset + 4, item_length);
184
185
0
    col_append_fstr(pinfo->cinfo, COL_INFO, ", %s: %s",
186
0
        item_type_text, item_text);
187
188
0
    tapa_discover_item_tree = proto_tree_add_subtree_format(tapa_discover_tree, tvb, offset, 4 + item_length,
189
0
      ett_tapa_discover_req, NULL, "Type %d = %s, length %d, value %s",
190
0
      item_type, item_type_text, item_length, item_text);
191
192
0
    proto_tree_add_item(tapa_discover_item_tree, hf_tapa_discover_req_type, tvb, offset, 1,
193
0
      ENC_BIG_ENDIAN);
194
0
    offset += 1;
195
196
0
    proto_tree_add_item(tapa_discover_item_tree, hf_tapa_discover_req_pad, tvb, offset, 1,
197
0
      ENC_BIG_ENDIAN);
198
0
    offset += 1;
199
200
0
    proto_tree_add_item(tapa_discover_item_tree, hf_tapa_discover_req_length, tvb, offset, 2,
201
0
      ENC_BIG_ENDIAN);
202
0
    offset += 2;
203
0
    proto_tree_add_item(tapa_discover_item_tree, hf_tapa_discover_req_value, tvb, offset, item_length,
204
0
      ENC_NA);
205
0
    offset += item_length;
206
207
0
    remaining -= (item_length + 4);
208
0
  }
209
0
  return offset;
210
0
}
211
212
static int
213
dissect_tapa_discover_unknown_new_tlv(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tapa_discover_tree, uint32_t offset, int remaining)
214
6
{
215
6
  proto_tree  *tapa_discover_item_tree;
216
6
  proto_item  *item, *discover_item;
217
6
  uint8_t    item_type;
218
6
  int    item_length;
219
6
  const char  *item_text;
220
  /*const char  *item_type_text;*/
221
6
  bool   is_ascii;
222
223
11
  while (remaining > 3) {  /* type(1) + flags(1) + length(2) */
224
6
    item_type = tvb_get_uint8(tvb, offset);
225
    /*item_type_text = val_to_str(pinfo->pool, item_type, tapa_discover_unknown_vals, "%d");*/
226
6
    item_length = tvb_get_ntohs(tvb, offset + 2) - 4;
227
228
6
    tapa_discover_item_tree = proto_tree_add_subtree_format(tapa_discover_tree, tvb, offset, 4 + item_length,
229
6
      ett_tapa_discover_req, &discover_item, "Type %d, length %d", item_type, item_length);
230
231
6
    proto_tree_add_item(tapa_discover_item_tree, hf_tapa_discover_newtlv_type, tvb, offset, 1,
232
6
      ENC_BIG_ENDIAN);
233
6
    offset += 1;
234
235
6
    proto_tree_add_item(tapa_discover_item_tree, hf_tapa_discover_newtlv_pad, tvb, offset, 1,
236
6
      ENC_BIG_ENDIAN);
237
6
    offset += 1;
238
239
6
    item = proto_tree_add_item(tapa_discover_item_tree, hf_tapa_discover_newtlv_length, tvb, offset, 2,
240
6
      ENC_BIG_ENDIAN);
241
6
    offset += 2;
242
243
6
    if (item_length <= 0) {
244
1
      expert_add_info(pinfo, item, &ei_tapa_length_too_short);
245
1
      return offset;
246
1
    }
247
248
5
    is_ascii = check_ascii(tvb, offset + 4, item_length);
249
5
    if (is_ascii)
250
0
      item_text = tvb_format_text(pinfo->pool, tvb, offset + 4, item_length);
251
5
    else
252
5
      item_text = "BINARY-DATA";
253
254
5
    col_append_fstr(pinfo->cinfo, COL_INFO, ", T=%d L=%d",
255
5
        item_type, item_length);
256
5
    proto_item_append_text(discover_item, ", value %s", item_text);
257
258
5
    if (is_ascii)
259
0
      proto_tree_add_item(tapa_discover_item_tree, hf_tapa_discover_newtlv_valuetext,
260
0
        tvb, offset, item_length, ENC_ASCII);
261
5
    else
262
5
      proto_tree_add_item(tapa_discover_item_tree, hf_tapa_discover_newtlv_valuehex,
263
5
        tvb, offset, item_length, ENC_NA);
264
5
    offset += item_length;
265
266
5
    remaining -= (item_length + 4);
267
5
  }
268
5
  return offset;
269
6
}
270
271
static int
272
dissect_tapa_discover(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
273
7
{
274
7
  proto_item *ti;
275
7
  proto_tree *tapa_discover_tree = NULL;
276
7
  unsigned offset = 0;
277
7
  uint8_t packet_type;
278
7
  int remaining;
279
280
7
  packet_type = tvb_get_uint8(tvb, 0);
281
7
  remaining = tvb_get_ntohs(tvb, 2) - 4;
282
283
7
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "TAPA");
284
7
  col_add_fstr(pinfo->cinfo, COL_INFO, "Discover - %s",
285
7
      val_to_str(pinfo->pool, packet_type, tapa_discover_type_vals, "Unknown (%d)"));
286
287
7
  if (tree) {
288
7
    ti = proto_tree_add_item(tree, proto_tapa, tvb, offset, -1,
289
7
      ENC_NA);
290
7
    tapa_discover_tree = proto_item_add_subtree(ti, ett_tapa_discover);
291
292
7
    proto_tree_add_item(tapa_discover_tree, hf_tapa_discover_type, tvb, offset, 1,
293
7
      ENC_BIG_ENDIAN);
294
7
    offset += 1;
295
296
7
    proto_tree_add_item(tapa_discover_tree, hf_tapa_discover_flags, tvb, offset, 1,
297
7
      ENC_BIG_ENDIAN);
298
7
    offset += 1;
299
300
7
    ti = proto_tree_add_item(tapa_discover_tree, hf_tapa_discover_length, tvb, offset, 2,
301
7
      ENC_BIG_ENDIAN);
302
7
    offset += 2;
303
304
7
    if (remaining <= 0) {
305
0
      expert_add_info(pinfo, ti, &ei_tapa_length_too_short);
306
0
      return offset;
307
0
    }
308
309
7
    switch (packet_type) {
310
0
    case TAPA_TYPE_REQUEST:
311
0
      offset = dissect_tapa_discover_req(tvb, pinfo, tapa_discover_tree, offset, remaining);
312
0
      break;
313
1
    case TAPA_TYPE_REPLY:
314
1
      offset = dissect_tapa_discover_reply(tvb, pinfo, tapa_discover_tree, offset, remaining);
315
1
      break;
316
0
    case TAPA_TYPE_REQUEST_NEW:
317
6
    case TAPA_TYPE_REPLY_NEW:
318
6
      offset = dissect_tapa_discover_unknown_new_tlv(tvb, pinfo, tapa_discover_tree,
319
6
          offset, remaining);
320
6
      break;
321
0
    default:
322
0
      proto_tree_add_item(tapa_discover_tree, hf_tapa_discover_unknown, tvb, offset,
323
0
          remaining, ENC_NA);
324
0
    offset += 1;
325
326
0
      break;
327
7
    }
328
7
  }
329
1
  return offset;
330
7
}
331
332
static int
333
dissect_tapa_tunnel(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
334
7
{
335
7
  proto_item *ti;
336
7
  proto_tree *tapa_tunnel_tree = NULL;
337
7
  uint32_t offset = 0;
338
7
  uint8_t version;
339
7
  uint8_t type;
340
7
  unsigned remaining;
341
342
7
  version = tvb_get_uint8(tvb, 0) & 0xF0;
343
7
  type = tvb_get_uint8(tvb, 1);
344
7
  remaining = tvb_reported_length(tvb);
345
346
7
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "TAPA");
347
7
  col_add_fstr(pinfo->cinfo, COL_INFO, "Tunnel - V=%d, T=%s", version >> 4,
348
7
      val_to_str(pinfo->pool, type, tapa_tunnel_type_vals, "Unknown (%d)"));
349
350
7
  if (tree) {
351
7
    ti = proto_tree_add_item(tree, proto_tapa, tvb, offset, -1,
352
7
      ENC_NA);
353
7
    tapa_tunnel_tree = proto_item_add_subtree(ti, ett_tapa_tunnel);
354
355
7
    proto_tree_add_item(tapa_tunnel_tree, hf_tapa_tunnel_version, tvb, offset, 1,
356
7
      ENC_BIG_ENDIAN);
357
7
    proto_tree_add_item(tapa_tunnel_tree, hf_tapa_tunnel_five, tvb, offset, 1,
358
7
      ENC_BIG_ENDIAN);
359
7
    offset += 1;
360
361
7
    proto_tree_add_item(tapa_tunnel_tree, hf_tapa_tunnel_type, tvb, offset, 1,
362
7
      ENC_BIG_ENDIAN);
363
7
    offset += 1;
364
365
7
    proto_tree_add_item(tapa_tunnel_tree, hf_tapa_tunnel_zero, tvb, offset, 8,
366
7
      ENC_NA);
367
7
    offset += 8;
368
369
7
    proto_tree_add_item(tapa_tunnel_tree, hf_tapa_tunnel_dmac, tvb, offset, 6,
370
7
      ENC_NA);
371
7
    offset += 6;
372
373
7
    proto_tree_add_item(tapa_tunnel_tree, hf_tapa_tunnel_smac, tvb, offset, 6,
374
7
      ENC_NA);
375
7
    offset += 6;
376
377
7
    switch (type) {
378
4
    case TAPA_TUNNEL_TYPE_0:
379
4
      proto_tree_add_item(tapa_tunnel_tree, hf_tapa_tunnel_0804, tvb, offset, 2,
380
4
        ENC_BIG_ENDIAN);
381
4
      offset += 2;
382
383
4
      proto_tree_add_item(tapa_tunnel_tree, hf_tapa_tunnel_tagsetc, tvb, offset, 6,
384
4
        ENC_NA);
385
4
      offset += 6;
386
387
4
      break;
388
1
    case TAPA_TUNNEL_TYPE_1:
389
1
      proto_tree_add_item(tapa_tunnel_tree, hf_tapa_tunnel_seqno, tvb, offset, 2,
390
1
        ENC_BIG_ENDIAN);
391
1
      offset += 2;
392
393
1
      proto_tree_add_item(tapa_tunnel_tree, hf_tapa_tunnel_length, tvb, offset, 2,
394
1
        ENC_BIG_ENDIAN);
395
1
      offset += 2;
396
1
      break;
397
0
    default:
398
0
      break;
399
7
    }
400
401
402
    /* FIXME: This is just to help figuring out what the bytes mean */
403
3
    proto_tree_add_item(tapa_tunnel_tree, hf_tapa_tunnel_remaining, tvb,
404
3
      offset, remaining - offset, ENC_NA);
405
3
    offset = remaining;
406
407
3
  }
408
3
  return offset;
409
7
}
410
411
static bool
412
test_tapa_discover(tvbuff_t *tvb)
413
24
{
414
24
  uint8_t type, req_type;
415
24
  uint16_t length;
416
417
24
  if (tvb_captured_length(tvb) < 4)
418
3
    return false;
419
420
  /* Type(1 byte) <= 5, unknown(1 byte), length(2 bytes) */
421
21
  type = tvb_get_uint8(tvb, 0);
422
  /* unknown = tvb_get_uint8(tvb, 1); */
423
21
  length = tvb_get_ntohs(tvb, 2);
424
21
  req_type = tvb_get_uint8(tvb, 4);
425
426
21
  if (type < TAPA_TYPE_REQUEST    ||
427
18
      type > TAPA_TYPE_REPLY_NEW    ||
428
10
      length < 12        ||
429
9
      length > 1472      ||
430
14
      (type == TAPA_TYPE_REQUEST && (req_type < TAPA_REQUEST_SERIAL || req_type > TAPA_REQUEST_MODEL))) {
431
14
    return false;
432
14
  }
433
434
7
  return true;
435
21
}
436
437
static bool
438
test_tapa_tunnel(tvbuff_t *tvb)
439
17
{
440
  /* If it isn't IPv4, it's TAPA. IPv4: Version(1 byte) = 4,
441
    length(2 bytes) >= 20 */
442
17
  if (tvb_captured_length(tvb) < 4 ||
443
14
      (tvb_get_uint8(tvb, 0) & 0xF0) >= 0x40 ||
444
12
      tvb_get_ntohs(tvb, 2) > 0 ||
445
10
      tvb_get_uint8(tvb, 1) > 1) { /* Is tunnel type known? */
446
10
    return false;
447
10
  }
448
7
  return true;
449
17
}
450
451
static int
452
dissect_tapa_static(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
453
24
{
454
24
  if (test_tapa_discover(tvb)) {
455
7
    return dissect_tapa_discover(tvb, pinfo, tree);
456
17
  } else if (test_tapa_tunnel(tvb)) {
457
7
    return dissect_tapa_tunnel(tvb, pinfo, tree);
458
7
  } else
459
10
    return 0;
460
24
}
461
462
/* heuristic dissector */
463
static bool
464
dissect_tapa_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *iph)
465
590
{
466
  /* The TAPA protocol also uses IP protocol number 4 but it isn't really IPIP */
467
590
  if ((ws_ip_protocol(iph) == IP_PROTO_IPV4) && ((tvb_get_uint8(tvb, 0) & 0xF0) != 0x40) &&
468
16
      (tvb_get_ntohs(tvb, 2)) < 20) {
469
8
    dissect_tapa_static(tvb, pinfo, tree, iph);
470
8
    return true;
471
8
  }
472
473
582
  return false;
474
590
}
475
476
void
477
proto_register_tapa(void)
478
15
{
479
15
  expert_module_t* expert_tapa;
480
481
15
  static hf_register_info hf[] = {
482
483
    /* TAPA discover header */
484
15
    { &hf_tapa_discover_type,
485
15
      { "Type", "tapa.discover.type", FT_UINT8, BASE_DEC, VALS(tapa_discover_type_vals),
486
15
        0x0, NULL, HFILL }},
487
488
15
    { &hf_tapa_discover_flags,
489
15
      { "Flags",  "tapa.discover.flags", FT_UINT8, BASE_HEX, NULL,
490
15
        0x0, NULL, HFILL }},
491
492
15
    { &hf_tapa_discover_length,
493
15
      { "Length", "tapa.discover.length", FT_UINT16, BASE_DEC, NULL,
494
15
        0x0, NULL, HFILL }},
495
496
    /* TAPA discover request */
497
15
    { &hf_tapa_discover_req_type,
498
15
      { "Req type", "tapa.discover.req.type", FT_UINT8, BASE_DEC, VALS(tapa_discover_request_vals),
499
15
        0x0, NULL, HFILL }},
500
501
15
    { &hf_tapa_discover_req_pad,
502
15
      { "Req padding",  "tapa.discover.req.pad", FT_UINT8, BASE_DEC, NULL,
503
15
        0x0, NULL, HFILL }},
504
505
15
    { &hf_tapa_discover_req_length,
506
15
      { "Req length", "tapa.discover.req.length", FT_UINT16, BASE_DEC, NULL,
507
15
        0x0, NULL, HFILL }},
508
509
15
    { &hf_tapa_discover_req_value,
510
15
      { "Req value",   "tapa.discover.req.value", FT_BYTES, BASE_NONE, NULL,
511
15
        0x0, NULL, HFILL }},
512
513
    /* TAPA discover reply */
514
15
    { &hf_tapa_discover_reply_switchip,
515
15
      { "Switch Ip",   "tapa.discover.reply.switchip", FT_IPv4, BASE_NONE, NULL,
516
15
        0x0, NULL, HFILL }},
517
518
15
    { &hf_tapa_discover_reply_unused,
519
15
      { "Reply unused", "tapa.discover.reply.unused", FT_UINT8, BASE_DEC, NULL,
520
15
        0x0, NULL, HFILL }},
521
522
15
    { &hf_tapa_discover_reply_bias,
523
15
      { "Reply bias", "tapa.discover.reply.bias", FT_UINT8, BASE_DEC, NULL,
524
15
        0x0, NULL, HFILL }},
525
526
15
    { &hf_tapa_discover_reply_pad,
527
15
      { "Reply pad",   "tapa.discover.reply.pad", FT_BYTES, BASE_NONE, NULL,
528
15
        0x0, NULL, HFILL }},
529
530
    /* TAPA discover new request/reply tlv */
531
15
    { &hf_tapa_discover_newtlv_type,
532
15
      { "New tlv type", "tapa.discover.newtlv.type", FT_UINT8, BASE_DEC, VALS(tapa_discover_request_vals),
533
15
        0x0, NULL, HFILL }},
534
535
15
    { &hf_tapa_discover_newtlv_pad,
536
15
      { "New tlv padding",  "tapa.discover.newtlv.pad", FT_UINT8, BASE_DEC, NULL,
537
15
        0x0, NULL, HFILL }},
538
539
15
    { &hf_tapa_discover_newtlv_length,
540
15
      { "New tlv length", "tapa.discover.newtlv.length", FT_UINT16, BASE_DEC, NULL,
541
15
        0x0, NULL, HFILL }},
542
543
15
    { &hf_tapa_discover_newtlv_valuetext,
544
15
      { "New tlv value",   "tapa.discover.newtlv.valuetext", FT_STRING, BASE_NONE, NULL,
545
15
        0x0, NULL, HFILL }},
546
547
15
    { &hf_tapa_discover_newtlv_valuehex,
548
15
      { "New tlv value",   "tapa.discover.newtlv.valuehex", FT_BYTES, BASE_NONE, NULL,
549
15
        0x0, NULL, HFILL }},
550
551
    /* TAPA discover unknown packet */
552
15
    { &hf_tapa_discover_unknown,
553
15
      { "Tapa unknown packet",   "tapa.discover.unknown", FT_BYTES, BASE_NONE, NULL,
554
15
        0x0, NULL, HFILL }},
555
556
    /* TAPA tunnel */
557
15
    { &hf_tapa_tunnel_version,
558
15
      { "Tapa tunnel version",   "tapa.tunnel.version", FT_UINT8, BASE_HEX, NULL,
559
15
        0xF0, NULL, HFILL }},
560
561
15
    { &hf_tapa_tunnel_five,
562
15
      { "Tapa tunnel five",   "tapa.tunnel.five", FT_UINT8, BASE_HEX, NULL,
563
15
        0x0F, NULL, HFILL }},
564
565
15
    { &hf_tapa_tunnel_type,
566
15
      { "Tapa tunnel type",   "tapa.tunnel.type", FT_UINT8, BASE_HEX, VALS(tapa_tunnel_type_vals),
567
15
        0x0, NULL, HFILL }},
568
569
15
    { &hf_tapa_tunnel_zero,
570
15
      { "Tapa tunnel zeroes",   "tapa.tunnel.zero", FT_BYTES, BASE_NONE, NULL,
571
15
        0x0, NULL, HFILL }},
572
573
15
    { &hf_tapa_tunnel_dmac,
574
15
      { "Tapa tunnel dest mac",   "tapa.tunnel.dmac", FT_ETHER, BASE_NONE, NULL,
575
15
        0x0, NULL, HFILL }},
576
577
15
    { &hf_tapa_tunnel_smac,
578
15
      { "Tapa tunnel src mac",   "tapa.tunnel.smac", FT_ETHER, BASE_NONE, NULL,
579
15
        0x0, NULL, HFILL }},
580
581
    /* TAPA tunnel type 0 */
582
15
    { &hf_tapa_tunnel_0804,
583
15
      { "Tapa tunnel 0804",   "tapa.tunnel.0804", FT_UINT16, BASE_HEX, NULL,
584
15
        0x0, NULL, HFILL }},
585
586
15
    { &hf_tapa_tunnel_tagsetc,
587
15
      { "Tapa tunnel tags, seqno, pad",   "tapa.tunnel.tags", FT_BYTES, BASE_NONE, NULL,
588
15
        0x0, NULL, HFILL }},
589
590
    /* TAPA tunnel type 1 */
591
15
    { &hf_tapa_tunnel_seqno,
592
15
      { "Tapa tunnel seqno",   "tapa.tunnel.seqno", FT_UINT16, BASE_DEC, NULL,
593
15
        0x0, NULL, HFILL }},
594
595
15
    { &hf_tapa_tunnel_length,
596
15
      { "Tapa tunnel length",   "tapa.tunnel.length", FT_UINT16, BASE_DEC, NULL,
597
15
        0x0, NULL, HFILL }},
598
599
600
    /* TAPA tunnel remaining stuff */
601
15
    { &hf_tapa_tunnel_remaining,
602
15
      { "Tapa tunnel all data",   "tapa.tunnel.remaining", FT_BYTES, BASE_NONE, NULL,
603
15
        0x0, NULL, HFILL }},
604
605
15
  };
606
15
  static int *ett[] = {
607
15
    &ett_tapa_discover,
608
15
    &ett_tapa_discover_req,
609
15
    &ett_tapa_tunnel,
610
15
  };
611
612
15
  static ei_register_info ei[] = {
613
15
    { &ei_tapa_length_too_short,
614
15
      { "tapa.length_too_short", PI_MALFORMED, PI_ERROR,
615
15
              "Length is too short (<= 4)", EXPFILL }}
616
15
  };
617
618
15
  proto_tapa = proto_register_protocol("Trapeze Access Point Access Protocol", "TAPA", "tapa");
619
15
  proto_register_field_array(proto_tapa, hf, array_length(hf));
620
15
  proto_register_subtree_array(ett, array_length(ett));
621
15
  expert_tapa = expert_register_protocol(proto_tapa);
622
15
  expert_register_field_array(expert_tapa, ei, array_length(ei));
623
624
15
  tapa_handle = register_dissector("tapa", dissect_tapa_static, proto_tapa);
625
626
15
}
627
628
void
629
proto_reg_handoff_tapa(void)
630
15
{
631
15
  dissector_add_uint_with_preference("udp.port", PORT_TAPA, tapa_handle);
632
15
  heur_dissector_add( "ip", dissect_tapa_heur, "TAPA over IP", "tapa_ip", proto_tapa, HEURISTIC_ENABLE);
633
15
}
634
635
/*
636
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
637
 *
638
 * Local variables:
639
 * c-basic-offset: 8
640
 * tab-width: 8
641
 * indent-tabs-mode: t
642
 * End:
643
 *
644
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
645
 * :indentSize=8:tabSize=8:noTabs=false:
646
 */