Coverage Report

Created: 2026-11-12 07:01

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
16
#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
0
{
131
0
  int i;
132
0
  uint8_t buf;
133
134
0
  for (i = 0; i < length; i++) {
135
0
    buf = tvb_get_uint8(tvb, offset+i);
136
0
    if (buf < 0x20 || buf >= 0x80) {
137
0
      return false;
138
0
    }
139
0
  }
140
0
  return true;
141
0
}
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
0
{
146
0
  proto_tree_add_item(tapa_discover_tree, hf_tapa_discover_reply_switchip, tvb, offset, 4,
147
0
    ENC_BIG_ENDIAN);
148
149
0
  col_append_fstr(pinfo->cinfo, COL_INFO, ", Switch: %s",
150
0
      tvb_ip_to_str(pinfo->pool, tvb, offset));
151
152
0
  offset += 4;
153
154
0
  proto_tree_add_item(tapa_discover_tree, hf_tapa_discover_reply_unused, tvb, offset, 1,
155
0
    ENC_BIG_ENDIAN);
156
0
  offset += 1;
157
158
0
  proto_tree_add_item(tapa_discover_tree, hf_tapa_discover_reply_bias, tvb, offset, 1,
159
0
    ENC_BIG_ENDIAN);
160
0
  offset += 1;
161
162
0
  remaining -= 6;
163
0
  proto_tree_add_item(tapa_discover_tree, hf_tapa_discover_reply_pad, tvb, offset, remaining,
164
0
    ENC_NA);
165
0
  offset += remaining;
166
167
0
  return offset;
168
0
}
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
0
{
215
0
  proto_tree  *tapa_discover_item_tree;
216
0
  proto_item  *item, *discover_item;
217
0
  uint8_t    item_type;
218
0
  int    item_length;
219
0
  const char  *item_text;
220
  /*const char  *item_type_text;*/
221
0
  bool   is_ascii;
222
223
0
  while (remaining > 3) {  /* type(1) + flags(1) + length(2) */
224
0
    item_type = tvb_get_uint8(tvb, offset);
225
    /*item_type_text = val_to_str(pinfo->pool, item_type, tapa_discover_unknown_vals, "%d");*/
226
0
    item_length = tvb_get_ntohs(tvb, offset + 2) - 4;
227
228
0
    tapa_discover_item_tree = proto_tree_add_subtree_format(tapa_discover_tree, tvb, offset, 4 + item_length,
229
0
      ett_tapa_discover_req, &discover_item, "Type %d, length %d", item_type, item_length);
230
231
0
    proto_tree_add_item(tapa_discover_item_tree, hf_tapa_discover_newtlv_type, tvb, offset, 1,
232
0
      ENC_BIG_ENDIAN);
233
0
    offset += 1;
234
235
0
    proto_tree_add_item(tapa_discover_item_tree, hf_tapa_discover_newtlv_pad, tvb, offset, 1,
236
0
      ENC_BIG_ENDIAN);
237
0
    offset += 1;
238
239
0
    item = proto_tree_add_item(tapa_discover_item_tree, hf_tapa_discover_newtlv_length, tvb, offset, 2,
240
0
      ENC_BIG_ENDIAN);
241
0
    offset += 2;
242
243
0
    if (item_length <= 0) {
244
0
      expert_add_info(pinfo, item, &ei_tapa_length_too_short);
245
0
      return offset;
246
0
    }
247
248
0
    is_ascii = check_ascii(tvb, offset, item_length);
249
0
    if (is_ascii)
250
0
      item_text = tvb_format_text(pinfo->pool, tvb, offset, item_length);
251
0
    else
252
0
      item_text = "BINARY-DATA";
253
254
0
    col_append_fstr(pinfo->cinfo, COL_INFO, ", T=%d L=%d",
255
0
        item_type, item_length);
256
0
    proto_item_append_text(discover_item, ", value %s", item_text);
257
258
0
    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
0
    else
262
0
      proto_tree_add_item(tapa_discover_item_tree, hf_tapa_discover_newtlv_valuehex,
263
0
        tvb, offset, item_length, ENC_NA);
264
0
    offset += item_length;
265
266
0
    remaining -= (item_length + 4);
267
0
  }
268
0
  return offset;
269
0
}
270
271
static int
272
dissect_tapa_discover(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
273
0
{
274
0
  proto_item *ti;
275
0
  proto_tree *tapa_discover_tree = NULL;
276
0
  unsigned offset = 0;
277
0
  uint8_t packet_type;
278
0
  int remaining;
279
280
0
  packet_type = tvb_get_uint8(tvb, 0);
281
0
  remaining = tvb_get_ntohs(tvb, 2) - 4;
282
283
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "TAPA");
284
0
  col_add_fstr(pinfo->cinfo, COL_INFO, "Discover - %s",
285
0
      val_to_str(pinfo->pool, packet_type, tapa_discover_type_vals, "Unknown (%d)"));
286
287
0
  if (tree) {
288
0
    ti = proto_tree_add_item(tree, proto_tapa, tvb, offset, -1,
289
0
      ENC_NA);
290
0
    tapa_discover_tree = proto_item_add_subtree(ti, ett_tapa_discover);
291
292
0
    proto_tree_add_item(tapa_discover_tree, hf_tapa_discover_type, tvb, offset, 1,
293
0
      ENC_BIG_ENDIAN);
294
0
    offset += 1;
295
296
0
    proto_tree_add_item(tapa_discover_tree, hf_tapa_discover_flags, tvb, offset, 1,
297
0
      ENC_BIG_ENDIAN);
298
0
    offset += 1;
299
300
0
    ti = proto_tree_add_item(tapa_discover_tree, hf_tapa_discover_length, tvb, offset, 2,
301
0
      ENC_BIG_ENDIAN);
302
0
    offset += 2;
303
304
0
    if (remaining <= 0) {
305
0
      expert_add_info(pinfo, ti, &ei_tapa_length_too_short);
306
0
      return offset;
307
0
    }
308
309
0
    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
0
    case TAPA_TYPE_REPLY:
314
0
      offset = dissect_tapa_discover_reply(tvb, pinfo, tapa_discover_tree, offset, remaining);
315
0
      break;
316
0
    case TAPA_TYPE_REQUEST_NEW:
317
0
    case TAPA_TYPE_REPLY_NEW:
318
0
      offset = dissect_tapa_discover_unknown_new_tlv(tvb, pinfo, tapa_discover_tree,
319
0
          offset, remaining);
320
0
      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
0
    }
328
0
  }
329
0
  return tree ? (int)offset : (int)tvb_captured_length(tvb);
330
0
}
331
332
static int
333
dissect_tapa_tunnel(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
334
0
{
335
0
  proto_item *ti;
336
0
  proto_tree *tapa_tunnel_tree = NULL;
337
0
  uint32_t offset = 0;
338
0
  uint8_t version;
339
0
  uint8_t type;
340
0
  unsigned remaining;
341
342
0
  version = tvb_get_uint8(tvb, 0) & 0xF0;
343
0
  type = tvb_get_uint8(tvb, 1);
344
0
  remaining = tvb_reported_length(tvb);
345
346
0
  col_set_str(pinfo->cinfo, COL_PROTOCOL, "TAPA");
347
0
  col_add_fstr(pinfo->cinfo, COL_INFO, "Tunnel - V=%d, T=%s", version >> 4,
348
0
      val_to_str(pinfo->pool, type, tapa_tunnel_type_vals, "Unknown (%d)"));
349
350
0
  if (tree) {
351
0
    ti = proto_tree_add_item(tree, proto_tapa, tvb, offset, -1,
352
0
      ENC_NA);
353
0
    tapa_tunnel_tree = proto_item_add_subtree(ti, ett_tapa_tunnel);
354
355
0
    proto_tree_add_item(tapa_tunnel_tree, hf_tapa_tunnel_version, tvb, offset, 1,
356
0
      ENC_BIG_ENDIAN);
357
0
    proto_tree_add_item(tapa_tunnel_tree, hf_tapa_tunnel_five, tvb, offset, 1,
358
0
      ENC_BIG_ENDIAN);
359
0
    offset += 1;
360
361
0
    proto_tree_add_item(tapa_tunnel_tree, hf_tapa_tunnel_type, tvb, offset, 1,
362
0
      ENC_BIG_ENDIAN);
363
0
    offset += 1;
364
365
0
    proto_tree_add_item(tapa_tunnel_tree, hf_tapa_tunnel_zero, tvb, offset, 8,
366
0
      ENC_NA);
367
0
    offset += 8;
368
369
0
    proto_tree_add_item(tapa_tunnel_tree, hf_tapa_tunnel_dmac, tvb, offset, 6,
370
0
      ENC_NA);
371
0
    offset += 6;
372
373
0
    proto_tree_add_item(tapa_tunnel_tree, hf_tapa_tunnel_smac, tvb, offset, 6,
374
0
      ENC_NA);
375
0
    offset += 6;
376
377
0
    switch (type) {
378
0
    case TAPA_TUNNEL_TYPE_0:
379
0
      proto_tree_add_item(tapa_tunnel_tree, hf_tapa_tunnel_0804, tvb, offset, 2,
380
0
        ENC_BIG_ENDIAN);
381
0
      offset += 2;
382
383
0
      proto_tree_add_item(tapa_tunnel_tree, hf_tapa_tunnel_tagsetc, tvb, offset, 6,
384
0
        ENC_NA);
385
0
      offset += 6;
386
387
0
      break;
388
0
    case TAPA_TUNNEL_TYPE_1:
389
0
      proto_tree_add_item(tapa_tunnel_tree, hf_tapa_tunnel_seqno, tvb, offset, 2,
390
0
        ENC_BIG_ENDIAN);
391
0
      offset += 2;
392
393
0
      proto_tree_add_item(tapa_tunnel_tree, hf_tapa_tunnel_length, tvb, offset, 2,
394
0
        ENC_BIG_ENDIAN);
395
0
      offset += 2;
396
0
      break;
397
0
    default:
398
0
      break;
399
0
    }
400
401
402
    /* FIXME: This is just to help figuring out what the bytes mean */
403
0
    proto_tree_add_item(tapa_tunnel_tree, hf_tapa_tunnel_remaining, tvb,
404
0
      offset, remaining - offset, ENC_NA);
405
0
    offset = remaining;
406
407
0
  }
408
0
  return tree ? (int)offset : (int)tvb_captured_length(tvb);
409
0
}
410
411
static bool
412
test_tapa_discover(tvbuff_t *tvb)
413
0
{
414
0
  uint8_t type, req_type;
415
0
  uint16_t length;
416
417
0
  if (tvb_captured_length(tvb) < 5)
418
0
    return false;
419
420
  /* Type(1 byte) <= 5, unknown(1 byte), length(2 bytes) */
421
0
  type = tvb_get_uint8(tvb, 0);
422
  /* unknown = tvb_get_uint8(tvb, 1); */
423
0
  length = tvb_get_ntohs(tvb, 2);
424
0
  req_type = tvb_get_uint8(tvb, 4);
425
426
0
  if (type < TAPA_TYPE_REQUEST    ||
427
0
      type > TAPA_TYPE_REPLY_NEW    ||
428
0
      length < 12        ||
429
0
      length > 1472      ||
430
0
      (type == TAPA_TYPE_REQUEST && (req_type < TAPA_REQUEST_SERIAL || req_type > TAPA_REQUEST_MODEL))) {
431
0
    return false;
432
0
  }
433
434
0
  return true;
435
0
}
436
437
static bool
438
test_tapa_tunnel(tvbuff_t *tvb)
439
0
{
440
  /* If it isn't IPv4, it's TAPA. IPv4: Version(1 byte) = 4,
441
    length(2 bytes) >= 20 */
442
0
  if (tvb_captured_length(tvb) < 4 ||
443
0
      (tvb_get_uint8(tvb, 0) & 0xF0) >= 0x40 ||
444
0
      tvb_get_ntohs(tvb, 2) > 0 ||
445
0
      tvb_get_uint8(tvb, 1) > 1) { /* Is tunnel type known? */
446
0
    return false;
447
0
  }
448
0
  return true;
449
0
}
450
451
static int
452
dissect_tapa_static(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
453
0
{
454
0
  if (test_tapa_discover(tvb)) {
455
0
    return dissect_tapa_discover(tvb, pinfo, tree);
456
0
  } else if (test_tapa_tunnel(tvb)) {
457
0
    return dissect_tapa_tunnel(tvb, pinfo, tree);
458
0
  } else
459
0
    return 0;
460
0
}
461
462
/* heuristic dissector */
463
static bool
464
dissect_tapa_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *iph)
465
448
{
466
  /* The TAPA protocol also uses IP protocol number 4 but it isn't really IPIP */
467
448
  if (tvb_captured_length(tvb) < 4)
468
80
    return false;
469
368
  if ((ws_ip_protocol(iph) == IP_PROTO_IPV4) && ((tvb_get_uint8(tvb, 0) & 0xF0) != 0x40) &&
470
2
      (tvb_get_ntohs(tvb, 2)) < 20) {
471
0
    dissect_tapa_static(tvb, pinfo, tree, iph);
472
0
    return true;
473
0
  }
474
475
368
  return false;
476
368
}
477
478
void
479
proto_register_tapa(void)
480
16
{
481
16
  expert_module_t* expert_tapa;
482
483
16
  static hf_register_info hf[] = {
484
485
    /* TAPA discover header */
486
16
    { &hf_tapa_discover_type,
487
16
      { "Type", "tapa.discover.type", FT_UINT8, BASE_DEC, VALS(tapa_discover_type_vals),
488
16
        0x0, NULL, HFILL }},
489
490
16
    { &hf_tapa_discover_flags,
491
16
      { "Flags",  "tapa.discover.flags", FT_UINT8, BASE_HEX, NULL,
492
16
        0x0, NULL, HFILL }},
493
494
16
    { &hf_tapa_discover_length,
495
16
      { "Length", "tapa.discover.length", FT_UINT16, BASE_DEC, NULL,
496
16
        0x0, NULL, HFILL }},
497
498
    /* TAPA discover request */
499
16
    { &hf_tapa_discover_req_type,
500
16
      { "Req type", "tapa.discover.req.type", FT_UINT8, BASE_DEC, VALS(tapa_discover_request_vals),
501
16
        0x0, NULL, HFILL }},
502
503
16
    { &hf_tapa_discover_req_pad,
504
16
      { "Req padding",  "tapa.discover.req.pad", FT_UINT8, BASE_DEC, NULL,
505
16
        0x0, NULL, HFILL }},
506
507
16
    { &hf_tapa_discover_req_length,
508
16
      { "Req length", "tapa.discover.req.length", FT_UINT16, BASE_DEC, NULL,
509
16
        0x0, NULL, HFILL }},
510
511
16
    { &hf_tapa_discover_req_value,
512
16
      { "Req value",   "tapa.discover.req.value", FT_BYTES, BASE_NONE, NULL,
513
16
        0x0, NULL, HFILL }},
514
515
    /* TAPA discover reply */
516
16
    { &hf_tapa_discover_reply_switchip,
517
16
      { "Switch Ip",   "tapa.discover.reply.switchip", FT_IPv4, BASE_NONE, NULL,
518
16
        0x0, NULL, HFILL }},
519
520
16
    { &hf_tapa_discover_reply_unused,
521
16
      { "Reply unused", "tapa.discover.reply.unused", FT_UINT8, BASE_DEC, NULL,
522
16
        0x0, NULL, HFILL }},
523
524
16
    { &hf_tapa_discover_reply_bias,
525
16
      { "Reply bias", "tapa.discover.reply.bias", FT_UINT8, BASE_DEC, NULL,
526
16
        0x0, NULL, HFILL }},
527
528
16
    { &hf_tapa_discover_reply_pad,
529
16
      { "Reply pad",   "tapa.discover.reply.pad", FT_BYTES, BASE_NONE, NULL,
530
16
        0x0, NULL, HFILL }},
531
532
    /* TAPA discover new request/reply tlv */
533
16
    { &hf_tapa_discover_newtlv_type,
534
16
      { "New tlv type", "tapa.discover.newtlv.type", FT_UINT8, BASE_DEC, VALS(tapa_discover_request_vals),
535
16
        0x0, NULL, HFILL }},
536
537
16
    { &hf_tapa_discover_newtlv_pad,
538
16
      { "New tlv padding",  "tapa.discover.newtlv.pad", FT_UINT8, BASE_DEC, NULL,
539
16
        0x0, NULL, HFILL }},
540
541
16
    { &hf_tapa_discover_newtlv_length,
542
16
      { "New tlv length", "tapa.discover.newtlv.length", FT_UINT16, BASE_DEC, NULL,
543
16
        0x0, NULL, HFILL }},
544
545
16
    { &hf_tapa_discover_newtlv_valuetext,
546
16
      { "New tlv value",   "tapa.discover.newtlv.valuetext", FT_STRING, BASE_NONE, NULL,
547
16
        0x0, NULL, HFILL }},
548
549
16
    { &hf_tapa_discover_newtlv_valuehex,
550
16
      { "New tlv value",   "tapa.discover.newtlv.valuehex", FT_BYTES, BASE_NONE, NULL,
551
16
        0x0, NULL, HFILL }},
552
553
    /* TAPA discover unknown packet */
554
16
    { &hf_tapa_discover_unknown,
555
16
      { "Tapa unknown packet",   "tapa.discover.unknown", FT_BYTES, BASE_NONE, NULL,
556
16
        0x0, NULL, HFILL }},
557
558
    /* TAPA tunnel */
559
16
    { &hf_tapa_tunnel_version,
560
16
      { "Tapa tunnel version",   "tapa.tunnel.version", FT_UINT8, BASE_HEX, NULL,
561
16
        0xF0, NULL, HFILL }},
562
563
16
    { &hf_tapa_tunnel_five,
564
16
      { "Tapa tunnel five",   "tapa.tunnel.five", FT_UINT8, BASE_HEX, NULL,
565
16
        0x0F, NULL, HFILL }},
566
567
16
    { &hf_tapa_tunnel_type,
568
16
      { "Tapa tunnel type",   "tapa.tunnel.type", FT_UINT8, BASE_HEX, VALS(tapa_tunnel_type_vals),
569
16
        0x0, NULL, HFILL }},
570
571
16
    { &hf_tapa_tunnel_zero,
572
16
      { "Tapa tunnel zeroes",   "tapa.tunnel.zero", FT_BYTES, BASE_NONE, NULL,
573
16
        0x0, NULL, HFILL }},
574
575
16
    { &hf_tapa_tunnel_dmac,
576
16
      { "Tapa tunnel dest mac",   "tapa.tunnel.dmac", FT_ETHER, BASE_NONE, NULL,
577
16
        0x0, NULL, HFILL }},
578
579
16
    { &hf_tapa_tunnel_smac,
580
16
      { "Tapa tunnel src mac",   "tapa.tunnel.smac", FT_ETHER, BASE_NONE, NULL,
581
16
        0x0, NULL, HFILL }},
582
583
    /* TAPA tunnel type 0 */
584
16
    { &hf_tapa_tunnel_0804,
585
16
      { "Tapa tunnel 0804",   "tapa.tunnel.0804", FT_UINT16, BASE_HEX, NULL,
586
16
        0x0, NULL, HFILL }},
587
588
16
    { &hf_tapa_tunnel_tagsetc,
589
16
      { "Tapa tunnel tags, seqno, pad",   "tapa.tunnel.tags", FT_BYTES, BASE_NONE, NULL,
590
16
        0x0, NULL, HFILL }},
591
592
    /* TAPA tunnel type 1 */
593
16
    { &hf_tapa_tunnel_seqno,
594
16
      { "Tapa tunnel seqno",   "tapa.tunnel.seqno", FT_UINT16, BASE_DEC, NULL,
595
16
        0x0, NULL, HFILL }},
596
597
16
    { &hf_tapa_tunnel_length,
598
16
      { "Tapa tunnel length",   "tapa.tunnel.length", FT_UINT16, BASE_DEC, NULL,
599
16
        0x0, NULL, HFILL }},
600
601
602
    /* TAPA tunnel remaining stuff */
603
16
    { &hf_tapa_tunnel_remaining,
604
16
      { "Tapa tunnel all data",   "tapa.tunnel.remaining", FT_BYTES, BASE_NONE, NULL,
605
16
        0x0, NULL, HFILL }},
606
607
16
  };
608
16
  static int *ett[] = {
609
16
    &ett_tapa_discover,
610
16
    &ett_tapa_discover_req,
611
16
    &ett_tapa_tunnel,
612
16
  };
613
614
16
  static ei_register_info ei[] = {
615
16
    { &ei_tapa_length_too_short,
616
16
      { "tapa.length_too_short", PI_MALFORMED, PI_ERROR,
617
16
              "Length is too short (<= 4)", EXPFILL }}
618
16
  };
619
620
16
  proto_tapa = proto_register_protocol("Trapeze Access Point Access Protocol", "TAPA", "tapa");
621
16
  proto_register_field_array(proto_tapa, hf, array_length(hf));
622
16
  proto_register_subtree_array(ett, array_length(ett));
623
16
  expert_tapa = expert_register_protocol(proto_tapa);
624
16
  expert_register_field_array(expert_tapa, ei, array_length(ei));
625
626
16
  tapa_handle = register_dissector("tapa", dissect_tapa_static, proto_tapa);
627
628
16
}
629
630
void
631
proto_reg_handoff_tapa(void)
632
16
{
633
16
  dissector_add_uint_with_preference("udp.port", PORT_TAPA, tapa_handle);
634
16
  heur_dissector_add( "ip", dissect_tapa_heur, "TAPA over IP", "tapa_ip", proto_tapa, HEURISTIC_ENABLE);
635
16
}
636
637
/*
638
 * Editor modelines  -  https://www.wireshark.org/tools/modelines.html
639
 *
640
 * Local variables:
641
 * c-basic-offset: 8
642
 * tab-width: 8
643
 * indent-tabs-mode: t
644
 * End:
645
 *
646
 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
647
 * :indentSize=8:tabSize=8:noTabs=false:
648
 */