epan/dissectors/pidl/samr/samr.cnf cnf_dissect_lsa_BinaryString => lsarpc_dissect_str...
[wireshark-sm.git] / epan / dissectors / packet-mint.c
blob56dceca0acd9812a6a0f5588fb5b21920a9ba7f6
1 /* packet-mint.c
2 * Routines for the disassembly of the Media Independent Network Transport
3 * protocol used between wireless controllers and APs
5 * Copyright 2013 Joerg Mayer (see AUTHORS file)
7 * Wireshark - Network traffic analyzer
8 * By Gerald Combs <gerald@wireshark.org>
9 * Copyright 1998 Gerald Combs
11 * SPDX-License-Identifier: GPL-2.0-or-later
15 * Extremenetworks/Zebra/Motorola/Symbol WLAN proprietary protocol
16 * http://www.awimobility.com/s.nl/ctype.KB/it.I/id.7761/KB.81/.f
17 * and
18 * http://www.michaelfmcnamara.com/files/motorola/WiNG_5X_How_To_NOC.pdf
19 * looks like a mixture of lwapp/capwap and is-is/ospf
21 * MLCP: MINT Link Creation Protocol
24 /* We don't want the tranported data to pollute the output until
25 * we know how to correctly determine the packet type and length
27 #define MINT_DEVELOPMENT 1
29 #include "config.h"
31 #include <epan/packet.h>
32 #include <epan/exceptions.h>
33 #include <epan/etypes.h>
34 #include <epan/show_exception.h>
36 void proto_register_mint(void);
37 void proto_reg_handoff_mint(void);
39 #define PROTO_SHORT_NAME "MINT"
40 #define PROTO_LONG_NAME "Media Independent Network Transport"
42 /* 0x8783 ETHERTYPE_MINT */
43 /* Destmac: 01-a0-f8-00-00-00: Hello packets in multicast mode */
44 /* Mint overhead: 86 bytes */
45 /* 24576 = 0x6000 */
46 #define PORT_MINT_CONTROL_TUNNEL 24576
47 /* 24577 = 0x6001 */
48 #define PORT_MINT_DATA_TUNNEL 24577
49 #define PORT_MINT_RANGE "24576-24577"
50 /* MLCP: VLAN or IP-based */
52 static dissector_handle_t eth_handle;
54 static int proto_mint;
56 static int hf_mint_control;
57 static int hf_mint_control_32zerobytes;
58 static int hf_mint_control_unknown1;
59 static int hf_mint_data;
60 static int hf_mint_data_seqno;
61 static int hf_mint_data_unknown1;
62 static int hf_mint_data_vlan;
63 static int hf_mint_ethshim;
64 static int hf_mint_ethshim_length;
65 static int hf_mint_ethshim_unknown;
66 static int hf_mint_header;
67 static int hf_mint_header_dstdataport;
68 static int hf_mint_header_dstid;
69 static int hf_mint_header_srcdataport;
70 static int hf_mint_header_srcid;
71 static int hf_mint_header_ttl;
72 static int hf_mint_header_unknown1;
73 static int hf_mint_header_unknown2;
74 static int hf_mint_mlcp_length;
75 static int hf_mint_mlcp_message;
76 static int hf_mint_mlcp_type;
77 static int hf_mint_mlcp_value;
78 static int hf_mint_neighbor_unknown;
79 static int hf_mint_router_array;
80 static int hf_mint_router_element;
81 static int hf_mint_router_header_length;
82 static int hf_mint_router_header_sender;
83 static int hf_mint_router_header_unknown;
84 static int hf_mint_router_length;
85 static int hf_mint_router_message_type;
86 static int hf_mint_router_type_csnp;
87 static int hf_mint_router_type_helo;
88 static int hf_mint_router_type_lsp;
89 static int hf_mint_router_type_psnp;
90 static int hf_mint_router_type_unknown;
91 static int hf_mint_router_unknown1;
92 static int hf_mint_router_unknown2;
93 static int hf_mint_router_unknown3;
94 static int hf_mint_router_value;
96 /* ett handles */
97 static int ett_mint_ethshim;
98 static int ett_mint;
99 static int ett_mint_header;
100 static int ett_mint_ctrl;
101 static int ett_mint_data;
103 static dissector_handle_t mint_control_handle;
104 static dissector_handle_t mint_data_handle;
105 static dissector_handle_t mint_eth_handle;
107 /* Output of "service show mint ports" on controller */
109 typedef enum {
110 MINT_PORT_0 = 0,
111 MINT_PORT_DATA = 1,
112 MINT_PORT_DATA_FLOOD = 2,
113 MINT_PORT_FDB_UPDATE = 3,
114 MINT_PORT_MDD = 8,
115 MINT_PORT_RIM = 9,
116 MINT_PORT_SMARTRF = 10,
117 MINT_PORT_CONFIG = 11,
118 MINT_PORT_ROUTER = 12,
119 MINT_PORT_REDUNDANCY = 13,
120 MINT_PORT_HOTSPOT = 14,
121 MINT_PORT_PING = 15,
122 MINT_PORT_STATS = 16,
123 MINT_PORT_JOIN = 18,
124 MINT_PORT_FILEXFR = 19,
125 MINT_PORT_SECURITY = 20,
126 MINT_PORT_BOOTSTRAP = 21,
127 MINT_PORT_XPATH = 22,
128 MINT_PORT_MCAST_RP = 23,
129 MINT_PORT_MCAST_CTRL = 24,
130 MINT_PORT_MCAST_DATA = 25,
131 MINT_PORT_RADPROXY = 26,
132 MINT_PORT_CLUSTER = 27,
133 MINT_PORT_MIGRATION = 28,
134 MINT_PORT_CLUSTER_SYNC = 29,
135 MINT_PORT_NEIGHBOR = 30,
136 MINT_PORT_GKEY = 31,
137 MINT_PORT_MARP = 32,
138 MINT_PORT_MPROXY = 33,
139 MINT_PORT_MLCP = 34,
140 MINT_PORT_TELNET = 35,
141 MINT_PORT_RDBG_REQ = 36,
142 MINT_PORT_RDBG_SRV0 = 37,
143 MINT_PORT_RDBG_SRV1 = 38,
144 MINT_PORT_RDBG_SRV2 = 39,
145 MINT_PORT_RDBG_SRV3 = 40,
146 MINT_PORT_RDBG_SRV4 = 41,
147 MINT_PORT_RDBG_SRV5 = 42,
148 MINT_PORT_RDBG_SRV6 = 43,
149 MINT_PORT_RDBG_SRV7 = 44,
150 MINT_PORT_TRACEROUTE = 45,
151 MINT_PORT_STATS_LISTEN = 46,
152 MINT_PORT_NOC_CONTROLLER = 47,
153 MINT_PORT_NOC_CLIENT = 48,
154 MINT_PORT_STATS_SERVER = 49,
155 MINT_PORT_EXTVLAN = 50,
156 MINT_PORT_RAD_DYNAMIC = 51,
157 MINT_PORT_RFD_CLIENT = 52,
158 MINT_PORT_RFD_SERVER = 53,
159 MINT_PORT_NOC_SERVER = 54,
160 MINT_PORT_NOC__CLIENT = 55,
161 MINT_PORT_CP_STATS_CLIENT = 56,
162 MINT_PORT_NX_URLINFO_SRVR = 57,
163 MINT_PORT_NX_URLINFO_PRXY = 58,
164 MINT_PORT_LDAP_PROXY = 59,
165 MINT_PORT_ANALYTICS = 60,
166 MINT_PORT_ADOPTION = 61,
167 MINT_PORT_CLUSTER_ADOPT = 62,
168 MINT_PORT_NOC_SITE = 63,
169 MINT_PORT_DAD = 64,
170 MINT_PORT_CCACHE = 65,
171 MINT_PORT_GLB_ASSOC_LIST = 66,
172 MINT_PORT_BONJOUR = 131,
173 MINT_PORT_DPD2_EXTIF = 132,
174 MINT_PORT_TROUBLE = 133,
175 MINT_PORT_URLF_CLASSIFIER = 134,
176 MINT_PORT_NF_PROXY = 135,
177 MINT_PORT_WING_EXPRESS = 136,
178 MINT_PORT_NSM_STAT_CLIENT = 138,
179 MINT_PORT_DPD2_STATS_CLIENT = 140,
180 MINT_PORT_BTIM_STATS_CLIENT = 142
181 } mint_packettype_t;
183 static const value_string mint_port_vals[] = {
184 { MINT_PORT_0, "0 port" },
185 { MINT_PORT_DATA, "data/dgram" },
186 { MINT_PORT_DATA_FLOOD, "data-flood/dgram" },
187 { MINT_PORT_FDB_UPDATE, "fdb-update/dgram" },
188 { MINT_PORT_MDD, "mdd/dgram" },
189 { MINT_PORT_RIM, "rim/dgram" },
190 { MINT_PORT_SMARTRF, "smartrf/seqpkt" },
191 { MINT_PORT_CONFIG, "config/stream" },
192 { MINT_PORT_ROUTER, "router/dgram" },
193 { MINT_PORT_REDUNDANCY, "redundancy/seqpkt" },
194 { MINT_PORT_HOTSPOT, "hotspot/seqpkt" },
195 { MINT_PORT_PING, "ping/dgram" },
196 { MINT_PORT_STATS, "stats/dgram" },
197 { MINT_PORT_JOIN, "join/seqpkt" },
198 { MINT_PORT_FILEXFR, "filexfr/stream" },
199 { MINT_PORT_SECURITY, "security/seqpkt" },
200 { MINT_PORT_BOOTSTRAP, "bootstrap/seqpkt" },
201 { MINT_PORT_XPATH, "xpath/stream" },
202 { MINT_PORT_MCAST_RP, "mcast-rp/dgram" },
203 { MINT_PORT_MCAST_CTRL, "mcast-ctrl/seqpkt" },
204 { MINT_PORT_MCAST_DATA, "mcast-data/seqpkt" },
205 { MINT_PORT_RADPROXY, "radproxy/dgram" },
206 { MINT_PORT_CLUSTER, "cluster/seqpkt" },
207 { MINT_PORT_MIGRATION, "migration/stream" },
208 { MINT_PORT_CLUSTER_SYNC, "cluster-sync/stream" },
209 { MINT_PORT_NEIGHBOR, "neighbor/seqpkt" },
210 { MINT_PORT_GKEY, "gkey/dgram" },
211 { MINT_PORT_MARP, "marp/dgram" },
212 { MINT_PORT_MPROXY, "mproxy/seqpkt" },
213 { MINT_PORT_MLCP, "mlcp/dgram" },
214 { MINT_PORT_TELNET, "telnet/stream" },
215 { MINT_PORT_RDBG_REQ, "rdbg-req/seqpkt" },
216 { MINT_PORT_RDBG_SRV0, "rdbg-srv0/seqpkt" },
217 { MINT_PORT_RDBG_SRV1, "rdbg-srv1/seqpkt" },
218 { MINT_PORT_RDBG_SRV2, "rdbg-srv2/seqpkt" },
219 { MINT_PORT_RDBG_SRV3, "rdbg-srv3/seqpkt" },
220 { MINT_PORT_RDBG_SRV4, "rdbg-srv4/seqpkt" },
221 { MINT_PORT_RDBG_SRV5, "rdbg-srv5/seqpkt" },
222 { MINT_PORT_RDBG_SRV6, "rdbg-srv6/seqpkt" },
223 { MINT_PORT_RDBG_SRV7, "rdbg-srv7/seqpkt" },
224 { MINT_PORT_TRACEROUTE, "traceroute/seqpkt" },
225 { MINT_PORT_STATS_LISTEN, "stats-listen/seqpkt" },
226 { MINT_PORT_NOC_CONTROLLER, "noc-controller/seqpkt" },
227 { MINT_PORT_NOC_CLIENT, "noc-client/seqpkt" },
228 { MINT_PORT_STATS_SERVER, "stats-server/seqpkt" },
229 { MINT_PORT_EXTVLAN, "extvlan/dgram" },
230 { MINT_PORT_RAD_DYNAMIC, "rad-dynamic/seqpkt" },
231 { MINT_PORT_RFD_CLIENT, "rfd_client/stream" },
232 { MINT_PORT_RFD_SERVER, "rfd_server/stream" },
233 { MINT_PORT_NOC_SERVER, "noc_server/stream" },
234 { MINT_PORT_NOC__CLIENT, "noc_client/stream" },
235 { MINT_PORT_CP_STATS_CLIENT, "cp_stats_client/stream" },
236 { MINT_PORT_NX_URLINFO_SRVR, "nx_urlinfo_srvr/dgram" },
237 { MINT_PORT_NX_URLINFO_PRXY, "nx_urlinfo_prxy/dgram" },
238 { MINT_PORT_LDAP_PROXY, "ldap_proxy/stream" },
239 { MINT_PORT_ANALYTICS, "analytics/dgram" },
240 { MINT_PORT_ADOPTION, "adoption/seqpkt" },
241 { MINT_PORT_CLUSTER_ADOPT, "cluster-adopt/seqpkt" },
242 { MINT_PORT_NOC_SITE, "noc-site/stream" },
243 { MINT_PORT_DAD, "dad/stream" },
244 { MINT_PORT_CCACHE, "ccache/dgram" },
245 { MINT_PORT_GLB_ASSOC_LIST, "glb_assoc_list/dgram" },
246 { MINT_PORT_BONJOUR, "bonjour/dgram" },
247 { MINT_PORT_DPD2_EXTIF, "dpd2-extif/dgram" },
248 { MINT_PORT_TROUBLE, "trouble/dgram" },
249 { MINT_PORT_URLF_CLASSIFIER, "urlf_classifier/dgram" },
250 { MINT_PORT_NF_PROXY, "nf-proxy/dgram" },
251 { MINT_PORT_WING_EXPRESS, "wing_express/dgram" },
252 { MINT_PORT_NSM_STAT_CLIENT, "nsm-stat-client/stream" },
253 { MINT_PORT_DPD2_STATS_CLIENT, "dpd2-stats-client/stream" },
254 { MINT_PORT_BTIM_STATS_CLIENT, "btim-stats-client/stream" },
256 { 0, NULL }
259 static const value_string mint_router_csnp_tlv_vals[] = {
261 { 0, NULL }
264 static const value_string mint_router_helo_tlv_vals[] = {
265 { 1, "MINT ID" },
266 { 8, "IPv4 address" },
268 { 0, NULL }
271 static const value_string mint_router_lsp_tlv_vals[] = {
272 { 8, "MINT ID" },
274 { 0, NULL }
277 static const value_string mint_router_psnp_tlv_vals[] = {
279 { 0, NULL }
282 static const value_string mint_0x22_tlv_vals[] = {
284 { 0, NULL }
287 static int
288 dissect_eth_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *mint_tree,
289 volatile uint32_t offset, uint32_t length)
291 tvbuff_t *eth_tvb;
293 #ifdef MINT_DEVELOPMENT
294 col_set_writable(pinfo->cinfo, -1, false);
295 #endif
297 eth_tvb = tvb_new_subset_length(tvb, offset, length);
298 /* Continue after Ethernet dissection errors */
299 TRY {
300 call_dissector(eth_handle, eth_tvb, pinfo, mint_tree);
301 } CATCH_NONFATAL_ERRORS {
302 show_exception(eth_tvb, pinfo, mint_tree, EXCEPT_CODE, GET_MESSAGE);
303 } ENDTRY;
304 offset += length;
306 #ifdef MINT_DEVELOPMENT
307 col_set_writable(pinfo->cinfo, -1, true);
308 #endif
309 return offset;
312 static int
313 dissect_mint_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
314 uint32_t offset, uint32_t packet_length, unsigned received_via)
316 proto_item *ti;
317 proto_tree *mint_tree = NULL;
318 proto_tree *mint_header_tree = NULL;
319 proto_tree *mint_data_tree = NULL;
320 proto_tree *mint_ctrl_tree = NULL;
321 uint16_t bytes_remaining;
322 uint16_t mint_port;
323 uint8_t type, length, header_length;
324 uint32_t message_type;
325 uint8_t element_length;
326 int hf_tlv_vals;
328 mint_port = tvb_get_ntohs(tvb, offset + 12);
330 col_set_str(pinfo->cinfo, COL_PROTOCOL, PROTO_SHORT_NAME);
331 col_add_str(pinfo->cinfo, COL_INFO, val_to_str(mint_port,
332 mint_port_vals, "Type %03d"));
334 ti = proto_tree_add_item(tree, proto_mint, tvb,
335 offset, packet_length, ENC_NA);
336 mint_tree = proto_item_add_subtree(ti, ett_mint);
338 ti = proto_tree_add_item(mint_tree, hf_mint_header, tvb,
339 offset, 16, ENC_NA);
340 mint_header_tree = proto_item_add_subtree(ti, ett_mint_header);
342 /* MINT header */
343 proto_tree_add_item(mint_header_tree, hf_mint_header_unknown1, tvb,
344 offset, 1, ENC_NA);
345 offset += 1;
346 proto_tree_add_item(mint_header_tree, hf_mint_header_ttl, tvb,
347 offset, 1, ENC_NA);
348 offset += 1;
349 proto_tree_add_item(mint_header_tree, hf_mint_header_unknown2, tvb,
350 offset, 2, ENC_NA);
351 offset += 2;
352 proto_tree_add_item(mint_header_tree, hf_mint_header_dstid, tvb,
353 offset, 4, ENC_NA);
354 offset += 4;
355 proto_tree_add_item(mint_header_tree, hf_mint_header_srcid, tvb,
356 offset, 4, ENC_NA);
357 offset += 4;
358 proto_tree_add_item(mint_header_tree, hf_mint_header_dstdataport, tvb,
359 offset, 2, ENC_BIG_ENDIAN);
360 offset += 2;
361 proto_tree_add_item(mint_header_tree, hf_mint_header_srcdataport, tvb,
362 offset, 2, ENC_BIG_ENDIAN);
363 offset += 2;
364 /* FIXME: This is probably not the right way to determine the packet type.
365 * It's more likely something in mint_header_unknown1 but I haven't
366 * found out what. */
367 switch(mint_port) {
368 case MINT_PORT_DATA:
369 ti = proto_tree_add_item(mint_tree, hf_mint_data, tvb,
370 offset, packet_length - 16, ENC_NA);
371 mint_data_tree = proto_item_add_subtree(ti, ett_mint_data);
372 proto_tree_add_item(mint_data_tree, hf_mint_data_unknown1, tvb,
373 offset, 2, ENC_NA);
374 offset += 2;
375 /* Transported user frame */
376 if (offset < packet_length)
377 offset += dissect_eth_frame(tvb, pinfo, tree,
378 offset, packet_length - offset);
379 break;
380 case MINT_PORT_DATA_FLOOD:
381 ti = proto_tree_add_item(mint_tree, hf_mint_data, tvb,
382 offset, packet_length - 16, ENC_NA);
383 mint_data_tree = proto_item_add_subtree(ti, ett_mint_data);
384 /* Decode as vlan only for now. To be verified against a capture
385 * with CoS != 0 */
386 proto_tree_add_item(mint_data_tree, hf_mint_data_vlan, tvb,
387 offset, 2, ENC_BIG_ENDIAN);
388 offset += 2;
389 proto_tree_add_item(mint_data_tree, hf_mint_data_seqno, tvb,
390 offset, 4, ENC_NA);
391 offset += 4;
392 proto_tree_add_item(mint_data_tree, hf_mint_data_unknown1, tvb,
393 offset, 4, ENC_NA);
394 offset += 4;
395 /* Transported user frame */
396 if (offset < packet_length)
397 offset += dissect_eth_frame(tvb, pinfo, tree,
398 offset, packet_length - offset);
399 break;
400 case MINT_PORT_ROUTER:
401 ti = proto_tree_add_item(mint_tree, hf_mint_control, tvb,
402 offset, packet_length - 16, ENC_NA);
403 mint_ctrl_tree = proto_item_add_subtree(ti, ett_mint_ctrl);
404 proto_tree_add_item(mint_ctrl_tree, hf_mint_control_32zerobytes, tvb,
405 offset, 32, ENC_NA);
406 offset += 32;
408 proto_tree_add_item(mint_ctrl_tree, hf_mint_router_unknown1, tvb,
409 offset, 1, ENC_NA);
410 offset += 1;
411 proto_tree_add_item(mint_ctrl_tree, hf_mint_router_unknown2, tvb,
412 offset, 1, ENC_NA);
413 offset += 1;
414 proto_tree_add_item(mint_ctrl_tree, hf_mint_router_unknown3, tvb,
415 offset, 1, ENC_NA);
416 offset += 1;
417 header_length = tvb_get_uint8(tvb, offset);
418 proto_tree_add_item(mint_ctrl_tree, hf_mint_router_header_length, tvb,
419 offset, 1, ENC_NA);
420 offset += 1;
421 message_type = tvb_get_ntohl(tvb, offset);
422 proto_tree_add_item(mint_ctrl_tree, hf_mint_router_message_type, tvb,
423 offset, 4, ENC_ASCII);
424 offset += 4;
425 proto_tree_add_item(mint_ctrl_tree, hf_mint_router_header_sender, tvb,
426 offset, 4, ENC_NA);
427 offset += 4;
428 switch (message_type) {
429 case 0x43534E50: /* CSNP */
430 element_length = 12;
431 hf_tlv_vals = hf_mint_router_type_csnp;
432 break;
433 case 0x48454C4F: /* HELO */
434 element_length = 0;
435 hf_tlv_vals = hf_mint_router_type_helo;
436 break;
437 case 0x4C535000: /* LSP */
438 element_length = 8;
439 hf_tlv_vals = hf_mint_router_type_lsp;
440 break;
441 case 0x50534E50: /* PSNP */
442 element_length = 4;
443 hf_tlv_vals = hf_mint_router_type_psnp;
444 break;
445 default:
446 element_length = 0;
447 hf_tlv_vals = hf_mint_router_type_unknown;
449 /* FIXME: This should go into the per message_type switch above */
450 if (header_length > 12) {
451 proto_tree_add_item(mint_ctrl_tree, hf_mint_router_header_unknown, tvb,
452 offset, header_length - 12, ENC_NA);
453 offset += header_length - 12;
455 while (offset < packet_length - 2) {
456 type = tvb_get_uint8(tvb, offset);
457 proto_tree_add_item(mint_ctrl_tree, hf_tlv_vals, tvb,
458 offset, 1, ENC_NA);
459 offset += 1;
460 length = tvb_get_uint8(tvb, offset);
461 /* FIXME: This is a hack - reliable array detection missing */
462 if (type == 1 && length == 128) {
463 proto_tree_add_item(mint_ctrl_tree, hf_mint_router_array, tvb,
464 offset, 1, ENC_NA);
465 offset += 1;
466 length = tvb_get_uint8(tvb, offset);
468 proto_tree_add_item(mint_ctrl_tree, hf_mint_router_length, tvb,
469 offset, 1, ENC_NA);
470 offset += 1;
471 if (offset + length > packet_length) {
472 /* FIXME: print expert information */
473 break;
475 if (type == 1 && element_length) {
476 uint32_t end_offset = offset + length;
477 for (; offset < end_offset; offset += element_length) {
478 proto_tree_add_item(mint_ctrl_tree, hf_mint_router_element, tvb,
479 offset, element_length, ENC_NA);
481 } else {
482 proto_tree_add_item(mint_ctrl_tree, hf_mint_router_value, tvb,
483 offset, length, ENC_NA);
484 offset += length;
487 break;
488 case MINT_PORT_NEIGHBOR:
489 ti = proto_tree_add_item(mint_tree, hf_mint_control, tvb,
490 offset, packet_length - 16, ENC_NA);
491 mint_ctrl_tree = proto_item_add_subtree(ti, ett_mint_ctrl);
492 proto_tree_add_item(mint_ctrl_tree, hf_mint_control_32zerobytes, tvb,
493 offset, 32, ENC_NA);
494 offset += 32;
495 bytes_remaining = packet_length - offset;
496 proto_tree_add_item(mint_ctrl_tree, hf_mint_neighbor_unknown, tvb,
497 offset, bytes_remaining, ENC_NA);
498 offset += bytes_remaining;
499 break;
500 case MINT_PORT_MLCP:
501 ti = proto_tree_add_item(mint_tree, hf_mint_control, tvb,
502 offset, packet_length - 16, ENC_NA);
503 mint_ctrl_tree = proto_item_add_subtree(ti, ett_mint_ctrl);
504 proto_tree_add_item(mint_ctrl_tree, hf_mint_control_32zerobytes, tvb,
505 offset, 32, ENC_NA);
506 offset += 32;
507 proto_tree_add_item(mint_ctrl_tree, hf_mint_mlcp_message, tvb,
508 offset, 2, ENC_BIG_ENDIAN);
509 offset += 2;
510 while (offset < packet_length - 2) {
511 proto_tree_add_item(mint_ctrl_tree, hf_mint_mlcp_type, tvb,
512 offset, 1, ENC_NA);
513 offset += 1;
514 length = tvb_get_uint8(tvb, offset);
515 proto_tree_add_item(mint_ctrl_tree, hf_mint_mlcp_length, tvb,
516 offset, 1, ENC_NA);
517 offset += 1;
518 if (offset + length > packet_length) {
519 /* print expert information */
520 break;
522 proto_tree_add_item(mint_ctrl_tree, hf_mint_mlcp_value, tvb,
523 offset, length, ENC_NA);
524 offset += length;
526 break;
527 default:
528 bytes_remaining = packet_length - offset;
529 switch(received_via) {
530 case PORT_MINT_CONTROL_TUNNEL:
531 case ETHERTYPE_MINT:
532 proto_tree_add_item(mint_tree, hf_mint_control_unknown1, tvb,
533 offset, bytes_remaining, ENC_NA);
534 break;
535 case PORT_MINT_DATA_TUNNEL:
536 proto_tree_add_item(mint_tree, hf_mint_data_unknown1, tvb,
537 offset, bytes_remaining, ENC_NA);
538 break;
539 default:
540 DISSECTOR_ASSERT_NOT_REACHED();
542 offset += bytes_remaining;
543 break;
545 #if defined MINT_DEVELOPMENT
546 tree_expanded_set(ett_mint, true);
547 tree_expanded_set(ett_mint_ethshim, true);
548 tree_expanded_set(ett_mint_header, true);
549 tree_expanded_set(ett_mint_ctrl, true);
550 tree_expanded_set(ett_mint_data, true);
551 #endif
552 return offset;
555 static int
556 dissect_mint_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
558 uint32_t packet_length = tvb_captured_length(tvb);
560 return dissect_mint_common(tvb, pinfo, tree, 0, packet_length,
561 PORT_MINT_CONTROL_TUNNEL);
564 static int
565 dissect_mint_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
567 uint32_t packet_length = tvb_captured_length(tvb);
569 return dissect_mint_common(tvb, pinfo, tree, 0, packet_length,
570 PORT_MINT_DATA_TUNNEL);
573 static int
574 dissect_mint_ethshim(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
576 proto_item *ti;
577 proto_tree *mint_ethshim_tree = NULL;
578 uint32_t offset = 0;
579 uint32_t packet_length;
581 ti = proto_tree_add_item(tree, hf_mint_ethshim, tvb,
582 offset, 4, ENC_NA);
583 mint_ethshim_tree = proto_item_add_subtree(ti, ett_mint_ethshim);
585 proto_tree_add_item(mint_ethshim_tree, hf_mint_ethshim_unknown, tvb,
586 offset, 2, ENC_NA);
587 offset += 2;
588 proto_tree_add_item(mint_ethshim_tree, hf_mint_ethshim_length, tvb,
589 offset, 2, ENC_BIG_ENDIAN);
590 packet_length = tvb_get_ntohs(tvb, offset) + 4;
591 offset += 2;
593 offset += dissect_mint_common(tvb, pinfo, tree, 4, packet_length, ETHERTYPE_MINT);
595 return offset;
598 static bool
599 test_mint_control(tvbuff_t *tvb _U_)
601 #if 0
602 /* Minimum of 8 bytes, first byte (version) has value of 3 */
603 if ( tvb_length(tvb) < 8
604 || tvb_get_uint8(tvb, 0) != 3
605 /* || tvb_get_uint8(tvb, 2) != 0
606 || tvb_get_ntohs(tvb, 6) > tvb_reported_length(tvb) */
608 return false;
610 #endif
611 return true;
614 static bool
615 test_mint_data(tvbuff_t *tvb _U_)
617 #if 0
618 /* Minimum of 8 bytes, first byte (version) has value of 3 */
619 if ( tvb_length(tvb) < 8
620 || tvb_get_uint8(tvb, 0) != 3
621 /* || tvb_get_uint8(tvb, 2) != 0
622 || tvb_get_ntohs(tvb, 6) > tvb_reported_length(tvb) */
624 return false;
626 #endif
627 return true;
630 static bool
631 test_mint_eth(tvbuff_t *tvb _U_)
633 #if 0
634 /* Minimum of 8 bytes, first byte (version) has value of 3 */
635 if ( tvb_length(tvb) < 8
636 || tvb_get_uint8(tvb, 0) != 3
637 /* || tvb_get_uint8(tvb, 2) != 0
638 || tvb_get_ntohs(tvb, 6) > tvb_reported_length(tvb) */
640 return false;
642 #endif
643 return true;
646 static int
647 dissect_mint_control_static(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
649 if ( !test_mint_control(tvb) ) {
650 return 0;
652 return dissect_mint_control(tvb, pinfo, tree);
655 static int
656 dissect_mint_data_static(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
658 if ( !test_mint_data(tvb) ) {
659 return 0;
661 return dissect_mint_data(tvb, pinfo, tree);
664 static int
665 dissect_mint_ethshim_static(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
667 if ( !test_mint_eth(tvb) ) {
668 return 0;
670 return dissect_mint_ethshim(tvb, pinfo, tree);
673 void
674 proto_register_mint(void)
676 static hf_register_info hf[] = {
677 { &hf_mint_ethshim,
678 { "MINT Ethernet Shim", "mint.ethshim",
679 FT_PROTOCOL, BASE_NONE, NULL, 0x0,
680 NULL, HFILL }
682 { &hf_mint_ethshim_unknown,
683 { "Unknown", "mint.ethshim.unknown",
684 FT_BYTES, BASE_NONE, NULL, 0x0,
685 NULL, HFILL }
687 { &hf_mint_ethshim_length,
688 { "Length", "mint.ethshim.length",
689 FT_UINT16, BASE_DEC, NULL, 0x0,
690 NULL, HFILL }
692 { &hf_mint_header,
693 { "Header", "mint.header",
694 FT_PROTOCOL, BASE_NONE, NULL, 0x0,
695 NULL, HFILL }
697 { &hf_mint_header_unknown1,
698 { "HdrUnk1", "mint.header.unknown1",
699 FT_BYTES, BASE_NONE, NULL, 0x0,
700 NULL, HFILL }
702 { &hf_mint_header_ttl,
703 { "TTL", "mint.header.ttl",
704 FT_UINT8, BASE_DEC, NULL, 0x0,
705 NULL, HFILL }
707 { &hf_mint_header_unknown2,
708 { "HdrUnk2", "mint.header.unknown2",
709 FT_BYTES, BASE_NONE, NULL, 0x0,
710 NULL, HFILL }
712 { &hf_mint_header_srcid,
713 { "Src MINT ID", "mint.header.srcid",
714 FT_BYTES, BASE_NONE, NULL, 0x0,
715 NULL, HFILL }
717 { &hf_mint_header_dstid,
718 { "Dst MINT ID", "mint.header.dstid",
719 FT_BYTES, BASE_NONE, NULL, 0x0,
720 NULL, HFILL }
722 { &hf_mint_header_srcdataport,
723 { "Src port", "mint.header.srcport",
724 FT_UINT16, BASE_DEC, VALS(mint_port_vals), 0x0,
725 NULL, HFILL }
727 { &hf_mint_header_dstdataport,
728 { "Dst port", "mint.header.dstport",
729 FT_UINT16, BASE_DEC, VALS(mint_port_vals), 0x0,
730 NULL, HFILL }
732 { &hf_mint_data,
733 { "Data Frame", "mint.data",
734 FT_PROTOCOL, BASE_NONE, NULL, 0x0,
735 NULL, HFILL }
737 { &hf_mint_data_vlan,
738 { "Data VLAN", "mint.data.vlan",
739 FT_UINT16, BASE_DEC, NULL, 0x0,
740 NULL, HFILL }
742 { &hf_mint_data_seqno,
743 { "Sequence Number", "mint.data.seqno",
744 FT_UINT32, BASE_DEC, NULL, 0x0,
745 NULL, HFILL }
747 { &hf_mint_data_unknown1,
748 { "DataUnk1", "mint.data.unknown1",
749 FT_BYTES, BASE_NONE, NULL, 0x0,
750 NULL, HFILL }
752 { &hf_mint_control,
753 { "Control Frame", "mint.control",
754 FT_PROTOCOL, BASE_NONE, NULL, 0x0,
755 NULL, HFILL }
757 { &hf_mint_control_32zerobytes,
758 { "Zero Bytes", "mint.control.32zerobytes",
759 FT_BYTES, BASE_NONE, NULL, 0x0,
760 NULL, HFILL }
762 { &hf_mint_control_unknown1,
763 { "CtrlUnk1", "mint.control.unknown1",
764 FT_BYTES, BASE_NONE, NULL, 0x0,
765 NULL, HFILL }
767 { &hf_mint_router_unknown1,
768 { "Unknown1", "mint.control.router.unknown1",
769 FT_UINT8, BASE_HEX, NULL, 0x0,
770 NULL, HFILL }
772 { &hf_mint_router_unknown2,
773 { "Unknown2", "mint.control.router.unknown2",
774 FT_UINT8, BASE_DEC, NULL, 0x0,
775 NULL, HFILL }
777 { &hf_mint_router_unknown3,
778 { "Unknown3", "mint.control.router.unknown3",
779 FT_UINT8, BASE_HEX, NULL, 0x0,
780 NULL, HFILL }
782 { &hf_mint_router_header_length,
783 { "Headerlength", "mint.control.router.header.length",
784 FT_UINT8, BASE_HEX, NULL, 0x0,
785 NULL, HFILL }
787 { &hf_mint_router_message_type,
788 { "Message type", "mint.control.router.message.type",
789 FT_STRING, BASE_NONE, NULL, 0x0,
790 NULL, HFILL }
792 { &hf_mint_router_header_sender,
793 { "Sender ID", "mint.control.router.header.sender",
794 FT_BYTES, BASE_NONE, NULL, 0x0,
795 NULL, HFILL }
797 { &hf_mint_router_header_unknown,
798 { "Header unknown", "mint.control.router.header.unknown",
799 FT_BYTES, BASE_NONE, NULL, 0x0,
800 NULL, HFILL }
802 { &hf_mint_router_type_unknown,
803 { "TLV Type", "mint.control.router.tlvtype",
804 FT_UINT8, BASE_DEC, NULL, 0x0,
805 NULL, HFILL }
807 { &hf_mint_router_type_csnp,
808 { "TLV Type", "mint.control.router.tlvtype",
809 FT_UINT8, BASE_DEC, VALS(mint_router_csnp_tlv_vals), 0x0,
810 NULL, HFILL }
812 { &hf_mint_router_type_helo,
813 { "TLV Type", "mint.control.router.tlvtype",
814 FT_UINT8, BASE_DEC, VALS(mint_router_helo_tlv_vals), 0x0,
815 NULL, HFILL }
817 { &hf_mint_router_type_lsp,
818 { "TLV Type", "mint.control.router.tlvtype",
819 FT_UINT8, BASE_DEC, VALS(mint_router_lsp_tlv_vals), 0x0,
820 NULL, HFILL }
822 { &hf_mint_router_type_psnp,
823 { "TLV Type", "mint.control.router.tlvtype",
824 FT_UINT8, BASE_DEC, VALS(mint_router_psnp_tlv_vals), 0x0,
825 NULL, HFILL }
827 { &hf_mint_router_length,
828 { "TLV Length", "mint.control.router.tlvlength",
829 FT_UINT8, BASE_DEC, NULL, 0x0,
830 NULL, HFILL }
832 { &hf_mint_router_array,
833 { "Array indicator", "mint.control.router.array",
834 FT_UINT8, BASE_DEC, NULL, 0x0,
835 NULL, HFILL }
837 { &hf_mint_router_element,
838 { "Array element", "mint.control.router.element",
839 FT_BYTES, BASE_NONE, NULL, 0x0,
840 NULL, HFILL }
842 { &hf_mint_router_value,
843 { "TLV Value", "mint.control.router.tlvvalue",
844 FT_BYTES, BASE_NONE, NULL, 0x0,
845 NULL, HFILL }
847 { &hf_mint_neighbor_unknown,
848 { "Unknown", "mint.control.neighbor.unknown",
849 FT_BYTES, BASE_NONE, NULL, 0x0,
850 NULL, HFILL }
852 { &hf_mint_mlcp_message,
853 { "Message", "mint.control.mlcp.message",
854 FT_UINT16, BASE_HEX, NULL, 0x0,
855 NULL, HFILL }
857 { &hf_mint_mlcp_type,
858 { "TLV Type", "mint.control.mlcp.tlvtype",
859 FT_UINT8, BASE_DEC, VALS(mint_0x22_tlv_vals), 0x0,
860 NULL, HFILL }
862 { &hf_mint_mlcp_length,
863 { "TLV Length", "mint.control.mlcp.tlvlength",
864 FT_UINT8, BASE_DEC, NULL, 0x0,
865 NULL, HFILL }
867 { &hf_mint_mlcp_value,
868 { "TLV Value", "mint.control.mlcp.tlvvalue",
869 FT_BYTES, BASE_NONE, NULL, 0x0,
870 NULL, HFILL }
874 static int *ett[] = {
875 &ett_mint_ethshim,
876 &ett_mint,
877 &ett_mint_header,
878 &ett_mint_ctrl,
879 &ett_mint_data,
882 proto_mint = proto_register_protocol(PROTO_LONG_NAME, PROTO_SHORT_NAME, "mint");
883 /* Created to remove Decode As confusion */
884 int proto_mint_data = proto_register_protocol_in_name_only("Media Independent Network Transport Data", "MINT (Data)", "mint_data", proto_mint, FT_PROTOCOL);
886 proto_register_field_array(proto_mint, hf, array_length(hf));
887 proto_register_subtree_array(ett, array_length(ett));
889 mint_control_handle = register_dissector("mint_control", dissect_mint_control_static, proto_mint);
890 mint_data_handle = register_dissector("mint_data", dissect_mint_data_static, proto_mint_data);
891 mint_eth_handle = register_dissector("mint_eth", dissect_mint_ethshim_static, proto_mint);
894 void
895 proto_reg_handoff_mint(void)
897 dissector_add_uint_range_with_preference("udp.port", PORT_MINT_RANGE, mint_control_handle);
898 dissector_add_uint("ethertype", ETHERTYPE_MINT, mint_eth_handle);
900 eth_handle = find_dissector_add_dependency("eth_withoutfcs", proto_mint);
904 * Editor modelines - https://www.wireshark.org/tools/modelines.html
906 * Local variables:
907 * c-basic-offset: 8
908 * tab-width: 8
909 * indent-tabs-mode: t
910 * End:
912 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
913 * :indentSize=8:tabSize=8:noTabs=false: