Revert "TODO epan/dissectors/asn1/kerberos/packet-kerberos-template.c new GSS flags"
[wireshark-sm.git] / epan / dissectors / packet-uaudp.c
blob409463075551ebf2b21863f04ec1d44d317634c2
1 /* packet-uaudp.c
2 * Routines for UA/UDP (Universal Alcatel over UDP) packet dissection.
3 * Copyright 2012, Alcatel-Lucent Enterprise <lars.ruoff@alcatel-lucent.com>
4 * Copyright 2018, Alcatel-Lucent Enterprise <nicolas.bertin@al-enterprise.com>
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 #include "config.h"
15 #include <epan/packet.h>
16 #include <epan/prefs.h>
17 #include <epan/expert.h>
18 #include <wsutil/report_message.h>
19 #include <wsutil/inet_addr.h>
21 #include "packet-uaudp.h"
23 void proto_register_uaudp(void);
24 void proto_reg_handoff_uaudp(void);
26 /* GLOBALS */
28 static dissector_handle_t uaudp_handle;
30 static int proto_uaudp;
32 static int hf_uaudp_opcode;
33 static int hf_uaudp_version;
34 static int hf_uaudp_window_size;
35 static int hf_uaudp_mtu;
36 static int hf_uaudp_udp_lost;
37 static int hf_uaudp_udp_lost_reinit;
38 static int hf_uaudp_keepalive;
39 static int hf_uaudp_qos_ip_tos;
40 static int hf_uaudp_qos_8021_vlid;
41 static int hf_uaudp_qos_8021_pri;
42 static int hf_uaudp_superfast_connect;
43 static int hf_uaudp_expseq;
44 static int hf_uaudp_sntseq;
45 static int hf_uaudp_type;
46 static int hf_uaudp_length;
47 static int hf_uaudp_startsig_reserved;
48 static int hf_uaudp_startsig_filename;
50 static int ett_uaudp;
51 static int ett_uaudp_tlv;
53 static expert_field ei_uaudp_tlv_length;
55 /* pref */
56 #define UAUDP_PORT_RANGE "32000,32512" /* Not IANA registered */
57 static range_t *ua_udp_range;
58 static address cs_address = ADDRESS_INIT_NONE;
59 static ws_in4_addr cs_ipv4;
60 static ws_in6_addr cs_ipv6;
61 static const char* pref_sys_ip_s = "";
63 static bool use_sys_ip;
65 static const value_string uaudp_opcode_str[] =
67 { UAUDP_CONNECT, "Connect" },
68 { UAUDP_CONNECT_ACK, "Connect ACK" },
69 { UAUDP_RELEASE, "Release" },
70 { UAUDP_RELEASE_ACK, "Release ACK" },
71 { UAUDP_KEEPALIVE, "Keepalive" },
72 { UAUDP_KEEPALIVE_ACK, "Keepalive ACK" },
73 { UAUDP_NACK, "NACK" },
74 { UAUDP_DATA, "Data" },
75 { UAUDP_START_SIG, "StartSig" },
76 { UAUDP_START_SIG_ACK, "StartSig ACK" },
77 { 0, NULL }
79 value_string_ext uaudp_opcode_str_ext = VALUE_STRING_EXT_INIT(uaudp_opcode_str);
81 static const value_string uaudp_connect_vals[] =
83 { UAUDP_CONNECT_VERSION, "Version" },
84 { UAUDP_CONNECT_WINDOW_SIZE, "Window Size" },
85 { UAUDP_CONNECT_MTU, "MTU" },
86 { UAUDP_CONNECT_UDP_LOST, "UDP lost" },
87 { UAUDP_CONNECT_UDP_LOST_REINIT,"UDP lost reinit" },
88 { UAUDP_CONNECT_KEEPALIVE, "Keepalive" },
89 { UAUDP_CONNECT_QOS_IP_TOS, "QoS IP TOS" },
90 { UAUDP_CONNECT_QOS_8021_VLID, "QoS 802.1 VLID" },
91 { UAUDP_CONNECT_QOS_8021_PRI, "QoS 802.1 PRI"},
92 { UAUDP_CONNECT_SUPERFAST_CONNECT, "SuperFast Connect"},
93 { 0, NULL }
95 value_string_ext uaudp_connect_vals_ext = VALUE_STRING_EXT_INIT(uaudp_connect_vals);
97 static dissector_handle_t ua_sys_to_term_handle;
98 static dissector_handle_t ua_term_to_sys_handle;
100 /* UA/UDP DISSECTOR */
101 static void _dissect_uaudp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
102 e_ua_direction direction)
104 int offset = 0;
105 uint32_t type, length;
106 uint8_t opcode;
107 proto_item *uaudp_item, *tlv_item, *tlv_len_item;
108 proto_tree *uaudp_tree, *connect_tree;
110 col_set_str(pinfo->cinfo, COL_PROTOCOL, "UAUDP");
112 /* get the identifier; it means operation code */
113 opcode = tvb_get_uint8(tvb, offset);
114 offset += 1;
116 /* print in "INFO" column the type of UAUDP message */
117 col_add_str(pinfo->cinfo,
118 COL_INFO,
119 val_to_str_ext(opcode, &uaudp_opcode_str_ext, "unknown (0x%02x)"));
121 uaudp_item = proto_tree_add_protocol_format(tree, proto_uaudp, tvb, 0, tvb_reported_length(tvb),
122 "Universal Alcatel/UDP Encapsulation Protocol, %s",
123 val_to_str_ext(opcode, &uaudp_opcode_str_ext, "unknown (0x%02x)"));
125 uaudp_tree = proto_item_add_subtree(uaudp_item, ett_uaudp);
127 /* print the identifier */
128 proto_tree_add_uint(uaudp_tree, hf_uaudp_opcode, tvb, 0, 1, opcode);
130 switch(opcode)
132 case UAUDP_CONNECT:
134 while(tvb_reported_length_remaining(tvb, offset) > 0)
136 type = tvb_get_uint8(tvb, offset+0);
137 connect_tree = proto_tree_add_subtree(uaudp_tree, tvb, offset, 0, ett_uaudp_tlv, &tlv_item,
138 val_to_str_ext(type, &uaudp_connect_vals_ext, "Unknown %d"));
139 proto_tree_add_uint(connect_tree, hf_uaudp_type, tvb, offset, 1, type);
140 offset++;
141 tlv_len_item = proto_tree_add_item_ret_uint(connect_tree, hf_uaudp_length, tvb, offset, 1, ENC_NA, &length);
142 proto_item_set_len(tlv_item, length+2);
143 offset++;
145 if ((length >= 1) && (length <= 4))
147 switch(type)
149 case UAUDP_CONNECT_VERSION:
150 proto_tree_add_item(connect_tree, hf_uaudp_version, tvb, offset, length, ENC_BIG_ENDIAN);
151 break;
152 case UAUDP_CONNECT_WINDOW_SIZE:
153 proto_tree_add_item(connect_tree, hf_uaudp_window_size, tvb, offset, length, ENC_BIG_ENDIAN);
154 break;
155 case UAUDP_CONNECT_MTU:
156 proto_tree_add_item(connect_tree, hf_uaudp_mtu, tvb, offset, length, ENC_BIG_ENDIAN);
157 break;
158 case UAUDP_CONNECT_UDP_LOST:
159 proto_tree_add_item(connect_tree, hf_uaudp_udp_lost, tvb, offset, length, ENC_BIG_ENDIAN);
160 break;
161 case UAUDP_CONNECT_UDP_LOST_REINIT:
162 proto_tree_add_item(connect_tree, hf_uaudp_udp_lost_reinit, tvb, offset, length, ENC_BIG_ENDIAN);
163 break;
164 case UAUDP_CONNECT_KEEPALIVE:
165 proto_tree_add_item(connect_tree, hf_uaudp_keepalive, tvb, offset, length, ENC_BIG_ENDIAN);
166 break;
167 case UAUDP_CONNECT_QOS_IP_TOS:
168 proto_tree_add_item(connect_tree, hf_uaudp_qos_ip_tos, tvb, offset, length, ENC_BIG_ENDIAN);
169 break;
170 case UAUDP_CONNECT_QOS_8021_VLID:
171 proto_tree_add_item(connect_tree, hf_uaudp_qos_8021_vlid, tvb, offset, length, ENC_BIG_ENDIAN);
172 break;
173 case UAUDP_CONNECT_QOS_8021_PRI:
174 proto_tree_add_item(connect_tree, hf_uaudp_qos_8021_pri, tvb, offset, length, ENC_BIG_ENDIAN);
175 break;
176 case UAUDP_CONNECT_SUPERFAST_CONNECT:
177 proto_tree_add_item(connect_tree, hf_uaudp_superfast_connect, tvb, offset, length, ENC_BIG_ENDIAN);
178 break;
181 else
183 expert_add_info_format(pinfo, tlv_len_item, &ei_uaudp_tlv_length, "Invalid length %d", length);
185 offset += length;
187 break;
190 case UAUDP_NACK:
192 proto_tree_add_item(uaudp_tree,
193 hf_uaudp_expseq,
194 tvb,
195 offset,
197 ENC_BIG_ENDIAN);
198 break;
201 case UAUDP_DATA:
203 int datalen;
205 proto_tree_add_item(uaudp_tree,
206 hf_uaudp_expseq,
207 tvb,
208 offset+0,
210 ENC_BIG_ENDIAN);
212 proto_tree_add_item(uaudp_tree,
213 hf_uaudp_sntseq,
214 tvb,
215 offset+2,
217 ENC_BIG_ENDIAN);
219 offset += 4;
220 datalen = tvb_reported_length(tvb) - offset;
222 /* if there is remaining data, call the UA dissector */
223 if (datalen > 0)
225 if (direction == SYS_TO_TERM)
226 call_dissector(ua_sys_to_term_handle,
227 tvb_new_subset_length(tvb, offset, datalen),
228 pinfo,
229 tree);
230 else if (direction == TERM_TO_SYS)
231 call_dissector(ua_term_to_sys_handle,
232 tvb_new_subset_length(tvb, offset, datalen),
233 pinfo,
234 tree);
235 else {
236 /* XXX: expert ?? */
237 col_set_str(pinfo->cinfo,
238 COL_INFO,
239 "Data - Couldn't resolve direction. Check UAUDP Preferences.");
242 else {
243 /* print in "INFO" column */
244 col_set_str(pinfo->cinfo,
245 COL_INFO,
246 "Data ACK");
248 break;
251 case UAUDP_START_SIG:
253 proto_tree_add_item(uaudp_tree, hf_uaudp_startsig_reserved, tvb, offset, 6, ENC_NA);
254 offset += 6;
255 proto_tree_add_item(uaudp_tree, hf_uaudp_startsig_filename, tvb, offset, tvb_strsize(tvb, offset)-1, ENC_ASCII);
256 break;
259 default:
260 break;
265 * UA/UDP DISSECTOR
266 Wireshark packet dissector entry point
268 static int dissect_uaudp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_)
270 /* server address, if present, has precedence on ports */
271 if (use_sys_ip) {
272 /* use server address to find direction*/
273 if (addresses_equal((address *)&pinfo->src, (address *)&cs_address))
275 _dissect_uaudp(tvb, pinfo, tree, SYS_TO_TERM);
276 return tvb_captured_length(tvb);
278 else if (addresses_equal((address *)&pinfo->dst, (address *)&cs_address))
280 _dissect_uaudp(tvb, pinfo, tree, TERM_TO_SYS);
281 return tvb_captured_length(tvb);
285 /* use ports to find direction */
286 if (value_is_in_range(ua_udp_range, pinfo->srcport))
288 _dissect_uaudp(tvb, pinfo, tree, TERM_TO_SYS);
289 return tvb_captured_length(tvb);
291 else if (value_is_in_range(ua_udp_range, pinfo->destport))
293 _dissect_uaudp(tvb, pinfo, tree, SYS_TO_TERM);
294 return tvb_captured_length(tvb);
297 _dissect_uaudp(tvb, pinfo, tree, DIR_UNKNOWN);
298 return tvb_captured_length(tvb);
301 static void
302 apply_uaudp_prefs(void) {
303 ua_udp_range = prefs_get_range_value("uaudp", "udp.port");
305 use_sys_ip = false;
306 if (*pref_sys_ip_s) {
307 use_sys_ip = ws_inet_pton4(pref_sys_ip_s, &cs_ipv4);
308 if (use_sys_ip) {
309 set_address((address *)&cs_address, AT_IPv4, sizeof(ws_in4_addr), &cs_ipv4);
310 return;
312 use_sys_ip = ws_inet_pton6(pref_sys_ip_s, &cs_ipv6);
313 if (use_sys_ip) {
314 set_address((address *)&cs_address, AT_IPv6, sizeof(ws_in6_addr), &cs_ipv6);
315 return;
317 report_failure("Invalid value for pref uaudp.system_ip: %s", pref_sys_ip_s);
321 void proto_register_uaudp(void)
323 module_t *uaudp_module;
325 /* Setup list of header fields. See Section 1.6.1 for details */
326 static hf_register_info hf_uaudp[] = {
328 &hf_uaudp_opcode,
330 "Opcode",
331 "uaudp.opcode",
332 FT_UINT8,
333 BASE_DEC | BASE_EXT_STRING,
334 &uaudp_opcode_str_ext,
335 0x0,
336 "UA/UDP Opcode",
337 HFILL
341 &hf_uaudp_version,
343 "Version",
344 "uaudp.version",
345 FT_UINT8,
346 BASE_DEC,
347 NULL, 0x0,
348 "UA/UDP Version",
349 HFILL
353 &hf_uaudp_window_size,
355 "Window Size",
356 "uaudp.window_size",
357 FT_UINT8,
358 BASE_DEC,
359 NULL,
360 0x0,
361 "UA/UDP Window Size",
362 HFILL
366 &hf_uaudp_mtu,
368 "MTU",
369 "uaudp.mtu",
370 FT_UINT8,
371 BASE_DEC,
372 NULL,
373 0x0,
374 "UA/UDP MTU",
375 HFILL
379 &hf_uaudp_udp_lost,
381 "UDP Lost",
382 "uaudp.udp_lost",
383 FT_UINT8,
384 BASE_DEC,
385 NULL,
386 0x0,
387 "UA/UDP Lost",
388 HFILL
392 &hf_uaudp_udp_lost_reinit,
394 "UDP lost reinit",
395 "uaudp.udp_lost_reinit",
396 FT_UINT8,
397 BASE_DEC,
398 NULL, 0x0,
399 "UA/UDP Lost Re-Init",
400 HFILL
404 &hf_uaudp_keepalive,
406 "Keepalive",
407 "uaudp.keepalive",
408 FT_UINT8,
409 BASE_DEC,
410 NULL,
411 0x0,
412 "UA/UDP Keepalive",
413 HFILL
417 &hf_uaudp_qos_ip_tos,
419 "QoS IP TOS",
420 "uaudp.qos_ip_tos",
421 FT_UINT8,
422 BASE_DEC,
423 NULL,
424 0x0,
425 "UA/UDP QoS IP TOS",
426 HFILL
430 &hf_uaudp_qos_8021_vlid,
432 "QoS 802.1 VLID",
433 "uaudp.qos_8021_vlid",
434 FT_UINT8,
435 BASE_DEC,
436 NULL,
437 0x0,
438 "UA/UDP QoS 802.1 VLID",
439 HFILL
443 &hf_uaudp_qos_8021_pri,
445 "QoS 802.1 PRI",
446 "uaudp.qos_8021_pri",
447 FT_UINT8,
448 BASE_DEC,
449 NULL,
450 0x0,
451 "UA/UDP QoS 802.1 PRI",
452 HFILL
456 &hf_uaudp_superfast_connect,
458 "SuperFast Connect",
459 "uaudp.superfast_connect",
460 FT_UINT8,
461 BASE_DEC,
462 NULL,
463 0x0,
464 "UA/UDP SuperFast Connect",
465 HFILL
469 &hf_uaudp_expseq,
471 "Sequence Number (expected)",
472 "uaudp.expseq",
473 FT_UINT16,
474 BASE_DEC,
475 NULL,
476 0x0,
477 "UA/UDP Expected Sequence Number",
478 HFILL
482 &hf_uaudp_sntseq,
484 "Sequence Number (sent)",
485 "uaudp.sntseq",
486 FT_UINT16,
487 BASE_DEC,
488 NULL,
489 0x0,
490 "UA/UDP Sent Sequence Number",
491 HFILL
495 &hf_uaudp_type,
497 "Type",
498 "uaudp.type",
499 FT_UINT8,
500 BASE_DEC|BASE_EXT_STRING,
501 &uaudp_connect_vals_ext,
502 0x0,
503 NULL,
504 HFILL
508 &hf_uaudp_length,
510 "Length",
511 "uaudp.length",
512 FT_UINT8,
513 BASE_DEC,
514 NULL,
515 0x0,
516 NULL,
517 HFILL
521 &hf_uaudp_startsig_reserved,
523 "Reserved",
524 "uaudp.startsig.reserved",
525 FT_BYTES,
526 BASE_NONE,
527 NULL,
528 0x0,
529 NULL,
530 HFILL
534 &hf_uaudp_startsig_filename,
536 "Filename",
537 "uaudp.startsig.filename",
538 FT_STRING,
539 BASE_NONE,
540 NULL,
541 0x0,
542 NULL,
543 HFILL
549 /* Setup protocol subtree array */
550 static int *ett[] =
552 &ett_uaudp,
553 &ett_uaudp_tlv,
556 static ei_register_info ei[] = {
557 { &ei_uaudp_tlv_length, { "uaudp.tlv_length_invalid", PI_PROTOCOL, PI_WARN, "Invalid length", EXPFILL }},
559 expert_module_t* expert_uaudp;
561 /* Register the protocol name and description */
562 proto_uaudp = proto_register_protocol("UA/UDP Encapsulation Protocol", "UAUDP", "uaudp");
564 uaudp_handle = register_dissector("uaudp", dissect_uaudp, proto_uaudp);
566 proto_register_field_array(proto_uaudp, hf_uaudp, array_length(hf_uaudp));
567 proto_register_subtree_array(ett, array_length(ett));
568 expert_uaudp = expert_register_protocol(proto_uaudp);
569 expert_register_field_array(expert_uaudp, ei, array_length(ei));
571 /* Register preferences */
572 uaudp_module = prefs_register_protocol(proto_uaudp, apply_uaudp_prefs);
574 prefs_register_string_preference(uaudp_module, "system_ip",
575 "Call Server IP Address (optional)",
576 "IPv4 (or IPv6) address of the call server."
577 " (Used only in case of identical source and destination ports)",
578 &pref_sys_ip_s);
581 void proto_reg_handoff_uaudp(void)
583 ua_sys_to_term_handle = find_dissector_add_dependency("ua_sys_to_term", proto_uaudp);
584 ua_term_to_sys_handle = find_dissector_add_dependency("ua_term_to_sys", proto_uaudp);
586 dissector_add_uint_range_with_preference("udp.port", UAUDP_PORT_RANGE, uaudp_handle);
587 apply_uaudp_prefs();
591 * Editor modelines - https://www.wireshark.org/tools/modelines.html
593 * Local variables:
594 * c-basic-offset: 4
595 * tab-width: 8
596 * indent-tabs-mode: nil
597 * End:
599 * vi: set shiftwidth=4 tabstop=8 expandtab:
600 * :indentSize=4:tabSize=8:noTabs=true: