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