MSWSP: fix dissect_mswsp_smb()
[wireshark-wip.git] / epan / dissectors / packet-mint.c
blob53773d93e1076c52a88e8435634d30f46a69a230
1 /* packet-mint.c
2 * Routines for the disassembly of the Chantry/HiPath AP-Controller
3 * tunneling protocol.
5 * $Id$
7 * Copyright 2013 Joerg Mayer (see AUTHORS file)
9 * Wireshark - Network traffic analyzer
10 * By Gerald Combs <gerald@wireshark.org>
11 * Copyright 1998 Gerald Combs
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License
15 * as published by the Free Software Foundation; either version 2
16 * of the License, or (at your option) any later version.
18 * This program is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU General Public License for more details.
23 * You should have received a copy of the GNU General Public License
24 * along with this program; if not, write to the Free Software
25 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
29 * Motorola/Symbol WLAN proprietary protocol
30 * http://www.awimobility.com/s.nl/ctype.KB/it.I/id.7761/KB.81/.f
31 * looks like a mixture of lwapp/capwap and is-is/ospf
34 /* We don't want the tranported data to pollute the output until
35 * we know how to correctly determine the packet type and length
37 #define MINT_DEVELOPMENT 1
39 #define NEW_PROTO_TREE_API 1
41 #include "config.h"
43 #include <glib.h>
45 #include <epan/packet.h>
46 #include <epan/exceptions.h>
47 #include <epan/etypes.h>
48 #include <epan/wmem/wmem.h>
49 #include <epan/expert.h>
50 #include <epan/show_exception.h>
52 #define PROTO_SHORT_NAME "MiNT"
53 #define PROTO_LONG_NAME "Media indepentend Network Transport"
55 /* 0x8783 ETHERTYPE_MINT */
56 /* 0x6000 */
57 #define PORT_MINT_CONTROL_TUNNEL 24576
58 /* 0x6001 */
59 #define PORT_MINT_DATA_TUNNEL 24577
61 static dissector_handle_t eth_handle;
63 /* ett handles */
64 static int ett_mint_ethshim = -1;
65 static int ett_mint = -1;
66 static int ett_mint_header = -1;
67 static int ett_mint_ctrl = -1;
68 static int ett_mint_data = -1;
70 static dissector_handle_t mint_control_handle;
71 static dissector_handle_t mint_data_handle;
72 static dissector_handle_t mint_eth_handle;
74 typedef enum {
75 MINT_TYPE_DATA_UC = 0x01,
76 MINT_TYPE_DATA_BCMC = 0x02,
77 MINT_TYPE_CTRL_0x0c = 0x0c,
78 MINT_TYPE_CTRL_0x0e = 0x0e,
79 MINT_TYPE_CTRL_0x1e = 0x1e,
80 MINT_TYPE_ETH_0x22 = 0x22
81 } mint_packettype_t;
83 static const value_string mint_packettype_vals[] = {
84 { MINT_TYPE_DATA_UC, "Unicast data"},
85 { MINT_TYPE_DATA_BCMC, "BC/MC data"},
86 { MINT_TYPE_CTRL_0x0c, "Ctrl_0x0c"},
87 { MINT_TYPE_CTRL_0x0e, "Ctrl_0x0e"},
88 { MINT_TYPE_CTRL_0x1e, "Ctrl_0x1e"},
89 { MINT_TYPE_ETH_0x22, "Eth_0x22"},
91 { 0, NULL }
95 static const value_string mint_0x0c_csnp_tlv_vals[] = {
97 { 0, NULL }
100 static const value_string mint_0x0c_helo_tlv_vals[] = {
101 { 1, "MiNT ID" },
102 { 8, "IPv4 address" },
104 { 0, NULL }
107 static const value_string mint_0x0c_lsp_tlv_vals[] = {
108 { 8, "MiNT ID" },
110 { 0, NULL }
113 static const value_string mint_0x0c_psnp_tlv_vals[] = {
115 { 0, NULL }
118 static const value_string mint_0x22_tlv_vals[] = {
120 { 0, NULL }
123 /* hfi elements */
124 #define MINT_HF_INIT HFI_INIT(proto_mint)
125 static header_field_info *hfi_mint = NULL;
126 /* MiNT Eth Shim */
127 static header_field_info hfi_mint_ethshim MINT_HF_INIT =
128 { "MiNT Ethernet Shim", "mint.ethshim", FT_PROTOCOL, BASE_NONE, NULL,
129 0x0, NULL, HFILL };
131 static header_field_info hfi_mint_ethshim_unknown MINT_HF_INIT =
132 { "Unknown", "mint.ethshim.unknown", FT_BYTES, BASE_NONE, NULL,
133 0x0, NULL, HFILL };
135 static header_field_info hfi_mint_ethshim_length MINT_HF_INIT =
136 { "Length", "mint.ethshim.length", FT_UINT16, BASE_DEC, NULL,
137 0x0, NULL, HFILL };
139 /* MiNT common */
140 static header_field_info hfi_mint_header MINT_HF_INIT =
141 { "Header", "mint.header", FT_PROTOCOL, BASE_NONE, NULL,
142 0x0, NULL, HFILL };
144 static header_field_info hfi_mint_header_unknown1 MINT_HF_INIT =
145 { "HdrUnk1", "mint.header.unknown1", FT_BYTES, BASE_NONE, NULL,
146 0x0, NULL, HFILL };
148 static header_field_info hfi_mint_header_srcid MINT_HF_INIT =
149 { "Src MiNT ID", "mint.header.srcid", FT_BYTES, BASE_NONE, NULL,
150 0x0, NULL, HFILL };
152 static header_field_info hfi_mint_header_dstid MINT_HF_INIT =
153 { "Dst MiNT ID", "mint.header.dstid", FT_BYTES, BASE_NONE, NULL,
154 0x0, NULL, HFILL };
156 static header_field_info hfi_mint_header_srcdatatype MINT_HF_INIT =
157 { "Src type", "mint.header.srctype", FT_UINT16, BASE_DEC, VALS(mint_packettype_vals),
158 0x0, NULL, HFILL };
160 static header_field_info hfi_mint_header_dstdatatype MINT_HF_INIT =
161 { "Dst type", "mint.header.dsttype", FT_UINT16, BASE_DEC, VALS(mint_packettype_vals),
162 0x0, NULL, HFILL };
164 /* MiNT Data */
165 static header_field_info hfi_mint_data MINT_HF_INIT =
166 { "Data Frame", "mint.data", FT_PROTOCOL, BASE_NONE, NULL,
167 0x0, NULL, HFILL };
169 static header_field_info hfi_mint_data_vlan MINT_HF_INIT =
170 { "Data VLAN", "mint.data.vlan", FT_UINT16, BASE_DEC, NULL,
171 0x0, NULL, HFILL };
173 static header_field_info hfi_mint_data_seqno MINT_HF_INIT =
174 { "Seqence Number", "mint.data.seqno", FT_UINT32, BASE_DEC, NULL,
175 0x0, NULL, HFILL };
177 static header_field_info hfi_mint_data_unknown1 MINT_HF_INIT =
178 { "DataUnk1", "mint.data.unknown1", FT_BYTES, BASE_NONE, NULL,
179 0x0, NULL, HFILL };
181 /* MiNT Control common */
182 static header_field_info hfi_mint_control MINT_HF_INIT =
183 { "Control Frame", "mint.control", FT_PROTOCOL, BASE_NONE, NULL,
184 0x0, NULL, HFILL };
186 static header_field_info hfi_mint_control_32zerobytes MINT_HF_INIT =
187 { "Zero Bytes", "mint.control.32zerobytes", FT_BYTES, BASE_NONE, NULL,
188 0x0, NULL, HFILL };
190 static header_field_info hfi_mint_control_unknown1 MINT_HF_INIT =
191 { "CtrlUnk1", "mint.control.unknown1", FT_BYTES, BASE_NONE, NULL,
192 0x0, NULL, HFILL };
194 /* MiNT Control type 0x0c */
195 static header_field_info hfi_mint_control_0x0c_unknown1 MINT_HF_INIT =
196 { "Unknown1", "mint.control.0x0c.unknown1", FT_UINT8, BASE_HEX, NULL,
197 0x0, NULL, HFILL };
199 static header_field_info hfi_mint_control_0x0c_unknown2 MINT_HF_INIT =
200 { "Unknown2", "mint.control.0x0c.unknown2", FT_UINT8, BASE_DEC, NULL,
201 0x0, NULL, HFILL };
203 static header_field_info hfi_mint_control_0x0c_unknown3 MINT_HF_INIT =
204 { "Unknown3", "mint.control.0x0c.unknown3", FT_UINT8, BASE_HEX, NULL,
205 0x0, NULL, HFILL };
207 static header_field_info hfi_mint_control_0x0c_header_length MINT_HF_INIT =
208 { "Headerlength", "mint.control.0x0c.header.length", FT_UINT8, BASE_HEX, NULL,
209 0x0, NULL, HFILL };
211 static header_field_info hfi_mint_control_0x0c_message_type MINT_HF_INIT =
212 { "Message type", "mint.control.0x0c.message.type", FT_STRING, BASE_NONE, NULL,
213 0x0, NULL, HFILL };
215 static header_field_info hfi_mint_control_0x0c_header_sender MINT_HF_INIT =
216 { "Sender ID", "mint.control.0x0c.header.sender", FT_BYTES, BASE_NONE, NULL,
217 0x0, NULL, HFILL };
219 static header_field_info hfi_mint_control_0x0c_header_unknown MINT_HF_INIT =
220 { "Header unknown", "mint.control.0x0c.header.unknown", FT_BYTES, BASE_NONE, NULL,
221 0x0, NULL, HFILL };
223 static header_field_info hfi_mint_control_0x0c_type_unknown MINT_HF_INIT =
224 { "TLV Type", "mint.control.0x0c.tlvtype", FT_UINT8, BASE_DEC, NULL,
225 0x0, NULL, HFILL };
227 static header_field_info hfi_mint_control_0x0c_type_csnp MINT_HF_INIT =
228 { "TLV Type", "mint.control.0x0c.tlvtype", FT_UINT8, BASE_DEC, VALS(mint_0x0c_csnp_tlv_vals),
229 0x0, NULL, HFILL };
231 static header_field_info hfi_mint_control_0x0c_type_helo MINT_HF_INIT =
232 { "TLV Type", "mint.control.0x0c.tlvtype", FT_UINT8, BASE_DEC, VALS(mint_0x0c_helo_tlv_vals),
233 0x0, NULL, HFILL };
235 static header_field_info hfi_mint_control_0x0c_type_lsp MINT_HF_INIT =
236 { "TLV Type", "mint.control.0x0c.tlvtype", FT_UINT8, BASE_DEC, VALS(mint_0x0c_lsp_tlv_vals),
237 0x0, NULL, HFILL };
239 static header_field_info hfi_mint_control_0x0c_type_psnp MINT_HF_INIT =
240 { "TLV Type", "mint.control.0x0c.tlvtype", FT_UINT8, BASE_DEC, VALS(mint_0x0c_psnp_tlv_vals),
241 0x0, NULL, HFILL };
243 static header_field_info hfi_mint_control_0x0c_length MINT_HF_INIT =
244 { "TLV Length", "mint.control.0x0c.tlvlength", FT_UINT8, BASE_DEC, NULL,
245 0x0, NULL, HFILL };
247 static header_field_info hfi_mint_control_0x0c_array MINT_HF_INIT =
248 { "Array indicator", "mint.control.0x0c.array", FT_UINT8, BASE_DEC, NULL,
249 0x0, NULL, HFILL };
251 static header_field_info hfi_mint_control_0x0c_element MINT_HF_INIT =
252 { "Array element", "mint.control.0x0c.element", FT_BYTES, BASE_NONE, NULL,
253 0x0, NULL, HFILL };
255 static header_field_info hfi_mint_control_0x0c_value MINT_HF_INIT =
256 { "TLV Value", "mint.control.0x0c.tlvvalue", FT_BYTES, BASE_NONE, NULL,
257 0x0, NULL, HFILL };
259 /* MiNT Control type 0x1e */
260 static header_field_info hfi_mint_control_0x1e_unknown MINT_HF_INIT =
261 { "Unknown", "mint.control.0x22.unknown", FT_BYTES, BASE_NONE, NULL,
262 0x0, NULL, HFILL };
264 /* MiNT Control type 0x22 */
265 static header_field_info hfi_mint_control_0x22_message MINT_HF_INIT =
266 { "Message", "mint.control.0x22.message", FT_UINT16, BASE_HEX, NULL,
267 0x0, NULL, HFILL };
269 static header_field_info hfi_mint_control_0x22_type MINT_HF_INIT =
270 { "TLV Type", "mint.control.0x22.tlvtype", FT_UINT8, BASE_DEC, VALS(mint_0x22_tlv_vals),
271 0x0, NULL, HFILL };
273 static header_field_info hfi_mint_control_0x22_length MINT_HF_INIT =
274 { "TLV Length", "mint.control.0x22.tlvlength", FT_UINT8, BASE_DEC, NULL,
275 0x0, NULL, HFILL };
277 static header_field_info hfi_mint_control_0x22_value MINT_HF_INIT =
278 { "TLV Value", "mint.control.0x22.tlvvalue", FT_BYTES, BASE_NONE, NULL,
279 0x0, NULL, HFILL };
281 /* End hfi elements */
283 static int
284 dissect_eth_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *mint_tree,
285 volatile guint32 offset, guint32 length)
287 tvbuff_t *eth_tvb;
289 #ifdef MINT_DEVELOPMENT
290 col_set_writable(pinfo->cinfo, FALSE);
291 #endif
293 eth_tvb = tvb_new_subset(tvb, offset, length, length);
294 /* Continue after Ethernet dissection errors */
295 TRY {
296 call_dissector(eth_handle, eth_tvb, pinfo, mint_tree);
297 } CATCH_NONFATAL_ERRORS {
298 show_exception(eth_tvb, pinfo, mint_tree, EXCEPT_CODE, GET_MESSAGE);
299 } ENDTRY;
300 offset += length;
302 #ifdef MINT_DEVELOPMENT
303 col_set_writable(pinfo->cinfo, TRUE);
304 #endif
305 return offset;
308 static int
309 dissect_mint_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
310 guint32 offset, guint32 packet_length, guint received_via)
312 proto_item *ti;
313 proto_tree *mint_tree = NULL;
314 proto_tree *mint_header_tree = NULL;
315 proto_tree *mint_data_tree = NULL;
316 proto_tree *mint_ctrl_tree = NULL;
317 guint16 bytes_remaining;
318 guint16 packet_type;
319 guint8 type, length, header_length;
320 guint32 message_type;
321 guint8 element_length;
322 static header_field_info *display_hfi_tlv_vals;
324 if (!tree)
325 return packet_length;
327 packet_type = tvb_get_ntohs(tvb, offset + 12);
329 col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_SHORT_NAME);
330 col_add_str(pinfo->cinfo, COL_INFO, val_to_str(packet_type,
331 mint_packettype_vals, "Type 0x%02x"));
333 ti = proto_tree_add_item(tree, hfi_mint, tvb,
334 offset, packet_length, ENC_NA);
335 mint_tree = proto_item_add_subtree(ti, ett_mint);
337 ti = proto_tree_add_item(mint_tree, &hfi_mint_header, tvb,
338 offset, 16, ENC_NA);
339 mint_header_tree = proto_item_add_subtree(ti, ett_mint_header);
341 /* MiNT header */
342 proto_tree_add_item(mint_header_tree, &hfi_mint_header_unknown1, tvb,
343 offset, 4, ENC_NA);
344 offset += 4;
345 proto_tree_add_item(mint_header_tree, &hfi_mint_header_dstid, tvb,
346 offset, 4, ENC_NA);
347 offset += 4;
348 proto_tree_add_item(mint_header_tree, &hfi_mint_header_srcid, tvb,
349 offset, 4, ENC_NA);
350 offset += 4;
351 proto_tree_add_item(mint_header_tree, &hfi_mint_header_dstdatatype, tvb,
352 offset, 2, ENC_BIG_ENDIAN);
353 offset += 2;
354 proto_tree_add_item(mint_header_tree, &hfi_mint_header_srcdatatype, tvb,
355 offset, 2, ENC_BIG_ENDIAN);
356 offset += 2;
357 /* FIXME: This is probably not the right way to determine the packet type.
358 * It's more likely something in mint_header_unknown1 but I haven't
359 * found out what. */
360 switch(packet_type) {
361 case MINT_TYPE_DATA_UC:
362 ti = proto_tree_add_item(mint_tree, &hfi_mint_data, tvb,
363 offset, packet_length - 16, ENC_NA);
364 mint_data_tree = proto_item_add_subtree(ti, ett_mint_data);
365 proto_tree_add_item(mint_data_tree, &hfi_mint_data_unknown1, tvb,
366 offset, 2, ENC_NA);
367 offset += 2;
368 /* Transported user frame */
369 if (offset < packet_length)
370 offset += dissect_eth_frame(tvb, pinfo, tree,
371 offset, packet_length - offset);
372 break;
373 case MINT_TYPE_DATA_BCMC:
374 ti = proto_tree_add_item(mint_tree, &hfi_mint_data, tvb,
375 offset, packet_length - 16, ENC_NA);
376 mint_data_tree = proto_item_add_subtree(ti, ett_mint_data);
377 /* Decode as vlan only for now. To be verified against a capture
378 * with CoS != 0 */
379 proto_tree_add_item(mint_data_tree, &hfi_mint_data_vlan, tvb,
380 offset, 2, ENC_BIG_ENDIAN);
381 offset += 2;
382 proto_tree_add_item(mint_data_tree, &hfi_mint_data_seqno, tvb,
383 offset, 4, ENC_NA);
384 offset += 4;
385 proto_tree_add_item(mint_data_tree, &hfi_mint_data_unknown1, tvb,
386 offset, 4, ENC_NA);
387 offset += 4;
388 /* Transported user frame */
389 if (offset < packet_length)
390 offset += dissect_eth_frame(tvb, pinfo, tree,
391 offset, packet_length - offset);
392 break;
393 case MINT_TYPE_CTRL_0x0c:
394 ti = proto_tree_add_item(mint_tree, &hfi_mint_control, tvb,
395 offset, packet_length - 16, ENC_NA);
396 mint_ctrl_tree = proto_item_add_subtree(ti, ett_mint_ctrl);
397 proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_32zerobytes, tvb,
398 offset, 32, ENC_NA);
399 offset += 32;
401 proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x0c_unknown1, tvb,
402 offset, 1, ENC_NA);
403 offset += 1;
404 proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x0c_unknown2, tvb,
405 offset, 1, ENC_NA);
406 offset += 1;
407 proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x0c_unknown3, tvb,
408 offset, 1, ENC_NA);
409 offset += 1;
410 header_length = tvb_get_guint8(tvb, offset);
411 proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x0c_header_length, tvb,
412 offset, 1, ENC_NA);
413 offset += 1;
414 message_type = tvb_get_ntohl(tvb, offset);
415 proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x0c_message_type, tvb,
416 offset, 4, ENC_NA);
417 offset += 4;
418 proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x0c_header_sender, tvb,
419 offset, 4, ENC_NA);
420 offset += 4;
421 switch (message_type) {
422 case 0x43534E50: /* CSNP */
423 element_length = 12;
424 display_hfi_tlv_vals = &hfi_mint_control_0x0c_type_csnp;
425 break;
426 case 0x48454C4F: /* HELO */
427 element_length = 0;
428 display_hfi_tlv_vals = &hfi_mint_control_0x0c_type_helo;
429 break;
430 case 0x4C535000: /* LSP */
431 element_length = 8;
432 display_hfi_tlv_vals = &hfi_mint_control_0x0c_type_lsp;
433 break;
434 case 0x50534E50: /* PSNP */
435 element_length = 4;
436 display_hfi_tlv_vals = &hfi_mint_control_0x0c_type_psnp;
437 break;
438 default:
439 element_length = 0;
440 display_hfi_tlv_vals = &hfi_mint_control_0x0c_type_unknown;
442 /* FIXME: This should go into the per message_type switch above */
443 if (header_length > 12) {
444 proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x0c_header_unknown, tvb,
445 offset, header_length - 12, ENC_NA);
446 offset += header_length - 12;
448 while (offset < packet_length - 2) {
449 type = tvb_get_guint8(tvb, offset);
450 proto_tree_add_item(mint_ctrl_tree, display_hfi_tlv_vals, tvb,
451 offset, 1, ENC_NA);
452 offset += 1;
453 length = tvb_get_guint8(tvb, offset);
454 /* FIXME: This is a hack - reliable array detection missing */
455 if (type == 1 && length == 128) {
456 proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x0c_array, tvb,
457 offset, 1, ENC_NA);
458 offset += 1;
459 length = tvb_get_guint8(tvb, offset);
461 proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x0c_length, tvb,
462 offset, 1, ENC_NA);
463 offset += 1;
464 if (offset + length > packet_length) {
465 /* FIXME: print expert information */
466 break;
468 if (type == 1 && element_length) {
469 guint32 end_offset = offset + length;
470 for (; offset < end_offset; offset += element_length) {
471 proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x0c_element, tvb,
472 offset, element_length, ENC_NA);
474 } else {
475 proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x0c_value, tvb,
476 offset, length, ENC_NA);
477 offset += length;
480 break;
481 case MINT_TYPE_CTRL_0x1e:
482 ti = proto_tree_add_item(mint_tree, &hfi_mint_control, tvb,
483 offset, packet_length - 16, ENC_NA);
484 mint_ctrl_tree = proto_item_add_subtree(ti, ett_mint_ctrl);
485 proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_32zerobytes, tvb,
486 offset, 32, ENC_NA);
487 offset += 32;
488 bytes_remaining = packet_length - offset;
489 proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x1e_unknown, tvb,
490 offset, bytes_remaining, ENC_NA);
491 offset += bytes_remaining;
492 break;
493 case MINT_TYPE_ETH_0x22:
494 ti = proto_tree_add_item(mint_tree, &hfi_mint_control, tvb,
495 offset, packet_length - 16, ENC_NA);
496 mint_ctrl_tree = proto_item_add_subtree(ti, ett_mint_ctrl);
497 proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_32zerobytes, tvb,
498 offset, 32, ENC_NA);
499 offset += 32;
500 proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x22_message, tvb,
501 offset, 2, ENC_BIG_ENDIAN);
502 offset += 2;
503 while (offset < packet_length - 2) {
504 proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x22_type, tvb,
505 offset, 1, ENC_NA);
506 offset += 1;
507 length = tvb_get_guint8(tvb, offset);
508 proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x22_length, tvb,
509 offset, 1, ENC_NA);
510 offset += 1;
511 if (offset + length > packet_length) {
512 /* print expert information */
513 break;
515 proto_tree_add_item(mint_ctrl_tree, &hfi_mint_control_0x22_value, tvb,
516 offset, length, ENC_NA);
517 offset += length;
519 break;
520 default:
521 bytes_remaining = packet_length - offset;
522 switch(received_via) {
523 case PORT_MINT_CONTROL_TUNNEL:
524 case ETHERTYPE_MINT:
525 proto_tree_add_item(mint_tree, &hfi_mint_control_unknown1, tvb,
526 offset, bytes_remaining, ENC_NA);
527 break;
528 case PORT_MINT_DATA_TUNNEL:
529 proto_tree_add_item(mint_tree, &hfi_mint_data_unknown1, tvb,
530 offset, bytes_remaining, ENC_NA);
531 break;
532 default:
533 DISSECTOR_ASSERT_NOT_REACHED();
535 offset += bytes_remaining;
536 break;
538 #if defined MINT_DEVELOPMENT
539 tree_expanded_set(ett_mint, TRUE);
540 tree_expanded_set(ett_mint_ethshim, TRUE);
541 tree_expanded_set(ett_mint_header, TRUE);
542 tree_expanded_set(ett_mint_ctrl, TRUE);
543 tree_expanded_set(ett_mint_data, TRUE);
544 #endif
545 return offset;
548 static int
549 dissect_mint_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
551 guint32 offset = 0;
552 guint32 packet_length = tvb_length_remaining(tvb, 0);
554 offset += dissect_mint_common(tvb, pinfo, tree, 0, packet_length,
555 PORT_MINT_CONTROL_TUNNEL);
557 return offset;
560 static int
561 dissect_mint_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
563 guint32 offset = 0;
564 guint32 packet_length = tvb_length_remaining(tvb, 0);
566 offset += dissect_mint_common(tvb, pinfo, tree, 0, packet_length,
567 PORT_MINT_DATA_TUNNEL);
569 return offset;
572 static int
573 dissect_mint_ethshim(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
575 proto_item *ti;
576 proto_tree *mint_ethshim_tree = NULL;
577 guint32 offset = 0;
578 guint32 packet_length;
580 ti = proto_tree_add_item(tree, &hfi_mint_ethshim, tvb,
581 offset, 4, ENC_NA);
582 mint_ethshim_tree = proto_item_add_subtree(ti, ett_mint_ethshim);
584 proto_tree_add_item(mint_ethshim_tree, &hfi_mint_ethshim_unknown, tvb,
585 offset, 2, ENC_NA);
586 offset += 2;
587 proto_tree_add_item(mint_ethshim_tree, &hfi_mint_ethshim_length, tvb,
588 offset, 2, ENC_BIG_ENDIAN);
589 packet_length = tvb_get_ntohs(tvb, offset) + 4;
590 offset += 2;
592 offset += dissect_mint_common(tvb, pinfo, tree, 4, packet_length, ETHERTYPE_MINT);
594 return offset;
597 static gboolean
598 test_mint_control(tvbuff_t *tvb _U_)
600 #if 0
601 /* Minimum of 8 bytes, first byte (version) has value of 3 */
602 if ( tvb_length(tvb) < 8
603 || tvb_get_guint8(tvb, 0) != 3
604 /* || tvb_get_guint8(tvb, 2) != 0
605 || tvb_get_ntohs(tvb, 6) > tvb_reported_length(tvb) */
607 return FALSE;
609 #endif
610 return TRUE;
613 static gboolean
614 test_mint_data(tvbuff_t *tvb _U_)
616 #if 0
617 /* Minimum of 8 bytes, first byte (version) has value of 3 */
618 if ( tvb_length(tvb) < 8
619 || tvb_get_guint8(tvb, 0) != 3
620 /* || tvb_get_guint8(tvb, 2) != 0
621 || tvb_get_ntohs(tvb, 6) > tvb_reported_length(tvb) */
623 return FALSE;
625 #endif
626 return TRUE;
629 static gboolean
630 test_mint_eth(tvbuff_t *tvb _U_)
632 #if 0
633 /* Minimum of 8 bytes, first byte (version) has value of 3 */
634 if ( tvb_length(tvb) < 8
635 || tvb_get_guint8(tvb, 0) != 3
636 /* || tvb_get_guint8(tvb, 2) != 0
637 || tvb_get_ntohs(tvb, 6) > tvb_reported_length(tvb) */
639 return FALSE;
641 #endif
642 return TRUE;
645 static int
646 dissect_mint_control_static(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
648 if ( !test_mint_control(tvb) ) {
649 return 0;
651 return dissect_mint_control(tvb, pinfo, tree);
654 static int
655 dissect_mint_data_static(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
657 if ( !test_mint_data(tvb) ) {
658 return 0;
660 return dissect_mint_data(tvb, pinfo, tree);
663 static int
664 dissect_mint_ethshim_static(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
666 if ( !test_mint_eth(tvb) ) {
667 return 0;
669 return dissect_mint_ethshim(tvb, pinfo, tree);
672 void
673 proto_register_mint(void)
675 #ifndef HAVE_HFI_SECTION_INIT
676 static header_field_info *hfi[] = {
678 /* MiNT Eth Shim */
679 &hfi_mint_ethshim,
680 &hfi_mint_ethshim_unknown,
681 &hfi_mint_ethshim_length,
682 /* MiNT common */
683 &hfi_mint_header,
684 &hfi_mint_header_unknown1,
685 &hfi_mint_header_srcid,
686 &hfi_mint_header_dstid,
687 &hfi_mint_header_srcdatatype,
688 &hfi_mint_header_dstdatatype,
689 /* MiNT Data */
690 &hfi_mint_data,
691 &hfi_mint_data_vlan,
692 &hfi_mint_data_seqno,
693 &hfi_mint_data_unknown1,
694 /* MiNT Control */
695 &hfi_mint_control,
696 &hfi_mint_control_32zerobytes,
697 &hfi_mint_control_unknown1,
698 /* MiNT Control 0x0c */
699 &hfi_mint_control_0x0c_message_type,
700 &hfi_mint_control_0x0c_header_sender,
701 &hfi_mint_control_0x0c_unknown1,
702 &hfi_mint_control_0x0c_unknown2,
703 &hfi_mint_control_0x0c_unknown3,
704 &hfi_mint_control_0x0c_header_length,
705 &hfi_mint_control_0x0c_header_unknown,
706 &hfi_mint_control_0x0c_type_unknown,
707 &hfi_mint_control_0x0c_type_csnp,
708 &hfi_mint_control_0x0c_type_helo,
709 &hfi_mint_control_0x0c_type_lsp,
710 &hfi_mint_control_0x0c_type_psnp,
711 &hfi_mint_control_0x0c_length,
712 &hfi_mint_control_0x0c_array,
713 &hfi_mint_control_0x0c_element,
714 &hfi_mint_control_0x0c_value,
715 /* MiNT Control 0x1e */
716 &hfi_mint_control_0x1e_unknown,
717 /* MiNT Control 0x22 */
718 &hfi_mint_control_0x22_message,
719 &hfi_mint_control_0x22_type,
720 &hfi_mint_control_0x22_length,
721 &hfi_mint_control_0x22_value,
723 #endif
725 static gint *ett[] = {
726 &ett_mint_ethshim,
727 &ett_mint,
728 &ett_mint_header,
729 &ett_mint_ctrl,
730 &ett_mint_data,
733 int proto_mint;
735 proto_mint = proto_register_protocol(PROTO_LONG_NAME, PROTO_SHORT_NAME, "mint");
736 hfi_mint = proto_registrar_get_nth(proto_mint);
737 proto_register_fields(proto_mint, hfi, array_length(hfi));
738 proto_register_subtree_array(ett, array_length(ett));
740 mint_control_handle = new_create_dissector_handle(dissect_mint_control_static, proto_mint);
741 mint_data_handle = new_create_dissector_handle(dissect_mint_data_static, proto_mint);
742 mint_eth_handle = new_create_dissector_handle(dissect_mint_ethshim_static, proto_mint);
745 void
746 proto_reg_handoff_mint(void)
748 dissector_add_uint("udp.port", PORT_MINT_CONTROL_TUNNEL, mint_control_handle);
749 dissector_add_uint("udp.port", PORT_MINT_DATA_TUNNEL, mint_data_handle);
750 dissector_add_uint("ethertype", ETHERTYPE_MINT, mint_eth_handle);
752 eth_handle = find_dissector("eth_withoutfcs");