1 /* packet-stun.c
2  * Routines for Session Traversal Utilities for NAT (STUN) dissection
3  * Copyright 2003, Shiang-Ming Huang <smhuang@pcs.csie.nctu.edu.tw>
4  * Copyright 2006, Marc Petit-Huguenin <marc@petit-huguenin.org>
5  * Copyright 2007-2008, 8x8 Inc. <petithug@8x8.com>
6  * Copyright 2008, Gael Breard <gael@breard.org>
7  * Copyright 2013, Media5 Corporation, David Bergeron <dbergeron@media5corp.com>
8  *
9  * Wireshark - Network traffic analyzer
10  * By Gerald Combs <gerald@wireshark.org>
11  * Copyright 1998 Gerald Combs
12  *
13  * SPDX-License-Identifier: GPL-2.0-or-later
14  *
15  * Please refer to the following specs for protocol detail:
16  * - RFC 3489 (Addition of deprecated attributes for diagnostics purpose)
17  *             STUN - Simple Traversal of User Datagram Protocol (UDP)
18  *             Through Network Address Translators (NATs) (superseeded by RFC 5389)
19  * - RFC 5389, formerly draft-ietf-behave-rfc3489bis-18
20  *             Session Traversal Utilities for NAT (STUN) (superseeded by RFC 8489)
21  * - RFC 8489  Session Traversal Utilities for NAT (STUN)
22  * - RFC 5780, formerly draft-ietf-behave-nat-behavior-discovery-08
23  *             NAT Behavior Discovery Using Session Traversal Utilities for NAT (STUN)
24  * - RFC 5766, formerly draft-ietf-behave-turn-16
25  *             Traversal Using Relays around NAT (TURN) (superseeded by RFC 8656)
26  * - RFC 8656  Traversal Using Relays around NAT (TURN)
27  * - RFC 6062  Traversal Using Relays around NAT (TURN) Extensions for TCP Allocations
28  * - RFC 6156, formerly draft-ietf-behave-turn-ipv6-11
29  *             Traversal Using Relays around NAT (TURN) Extension for IPv6
30  * - RFC 5245, formerly draft-ietf-mmusic-ice-19
31  *             Interactive Connectivity Establishment (ICE)
32  * - RFC 6544  TCP Candidates with Interactive Connectivity Establishment (ICE)
33  *
34  * Iana registered values:
35  * https://www.iana.org/assignments/stun-parameters/stun-parameters.xhtml
36  *
37  * From MS
38  * MS-TURN: Traversal Using Relay NAT (TURN) Extensions https://docs.microsoft.com/en-us/openspecs/office_protocols/ms-turn
39  * MS-TURNBWM:  Traversal using Relay NAT (TURN) Bandwidth Management Extensions https://docs.microsoft.com/en-us/openspecs/office_protocols/ms-turnbwm
40  * MS-ICE: Interactive Connectivity Establishment (ICE) Extensions https://docs.microsoft.com/en-us/openspecs/office_protocols/ms-ice
41  * MS-ICE2:  Interactive Connectivity Establishment ICE Extensions 2.0 https://docs.microsoft.com/en-us/openspecs/office_protocols/ms-ice2
42  * MS-ICE2BWN: Interactive Connectivity Establishment (ICE) 2.0 Bandwidth Management Extensions https://docs.microsoft.com/en-us/openspecs/office_protocols/ms-ice2bwm
43  */
44 
45 /* TODO
46  * Add information about different versions to table as we find it
47  * Add/Implement missing attributes
48  * Add/Implement missing message classes/methods
49  * Add missing error codes
50  */
51 
52 #include "config.h"
53 
54 #include <epan/packet.h>
55 #include <epan/expert.h>
56 #include <epan/to_str.h>
57 #include <wsutil/ws_roundup.h>
58 #include "packet-tcp.h"
59 
60 void proto_register_stun(void);
61 void proto_reg_handoff_stun(void);
62 
63 /* Dissection relevant differences between STUN/TURN specification documents
64  *
65  *  Aspect   | MS-TURN 15.1       | RFC 3489           | RFC 5389           | RFC 8489 (*1)      |
66  * ===============================================================================================
67  *  Message  | 0b00+14-bit        | 16-bit             | 0b00+14-bit, type= |                    |
68  *  Type     | No class or method | No class or method | class+method       |                    |
69  * -----------------------------------------------------------------------------------------------
70  *  Transac- | 128 bits, seen     | 128 bits           | 32 bit Magic +     |                    |
71  *  tion ID  | with MAGIC as well |                    | 96 bit Trans ID    |                    |
72  * -----------------------------------------------------------------------------------------------
73  *  Padding  | No Attribute Pad   | No Attribute Pad   | Pad to 32 bits     |                    |
74  *           |                    |                    | Att. Len excl. Pad |                    |
75  *           |                    |                    | Msg. Len incl. Pad |                    |
76  *           |                    |                    |  -> MLen & 3 == 0  |                    |
77  *           |                    |                    | Pad value: any     | Pad value: MBZ     |
78  * -----------------------------------------------------------------------------------------------
79  *  (XOR-)   | Write: Any value   | Write: Any value   | Write: MBZ         |                    |
80  *  MAP-ADDR | Read : Ignored     | Read : Ignored     | Read : Ignored     |                    |
81  *  1st byte |                    |                    |                    |                    |
82  * -----------------------------------------------------------------------------------------------
83  *  Username | Opaque             | Opaque             | UTF-8 String       |                    |
84  * -----------------------------------------------------------------------------------------------
85  *  Password | Opaque             | Deprecated         | Deprecated         |                    |
86  * -----------------------------------------------------------------------------------------------
87  *  NONCE &  | 0x0014             | 0x0015             | 0x0015             |                    |
88  *  REALM    | 0x0015             | 0x0014             | 0x0014             |                    |
89  * -----------------------------------------------------------------------------------------------
90  *  TURN     | RFC 5766/8656 or   | N/A                | RFC 5766/8656      |                    |
91  *  Channels | Multiplexed TURN   |                    |                    |                    |
92  *           | Channels           |                    |                    |                    |
93  * -----------------------------------------------------------------------------------------------
94  * *1: Only where different from RFC 5389
95  */
96 
97 enum {
98         NET_VER_AUTO,
99         NET_VER_MS_TURN,
100         NET_VER_3489,
101         NET_VER_5389
102 };
103 
104 /* Auto-tuning. Default: NET_VER_5389; NET_VER_MS_TURN if MAGIC_COOKIE is found */
105 
106 static gint stun_network_version = NET_VER_5389;
107 
108 static const enum_val_t stun_network_version_vals[] = {
109         { "Auto", "Auto",     NET_VER_AUTO},
110         { "MS-TURN",  "MS-TURN", NET_VER_MS_TURN },
111         { "RFC3489 and earlier", "RFC3489 and earlier",     NET_VER_3489},
112         { "RFC5389 and later",  "RFC5389 and later", NET_VER_5389 },
113         { NULL, NULL, 0 }
114 };
115 
116 static const value_string network_versions_vals[] = {
117         {NET_VER_MS_TURN,  "MS-TURN"},
118         {NET_VER_3489,     "RFC-3489 and earlier"},
119         {NET_VER_5389,     "RFC-5389/8489"},
120         {0,   NULL}
121 };
122 
123 /* heuristic subdissectors */
124 static heur_dissector_list_t heur_subdissector_list;
125 
126 /* stun dissector handles */
127 static dissector_handle_t data_handle;
128 static dissector_handle_t stun_tcp_handle;
129 static dissector_handle_t stun_udp_handle;
130 
131 /* Initialize the protocol and registered fields */
132 static int proto_stun = -1;
133 
134 static int hf_stun_channel = -1;
135 
136 
137 static int hf_stun_tcp_frame_length = -1;
138 static int hf_stun_type = -1;
139 static int hf_stun_type_class = -1;
140 static int hf_stun_type_method = -1;
141 static int hf_stun_type_method_assignment = -1;
142 static int hf_stun_length = -1;
143 static int hf_stun_cookie = -1;
144 static int hf_stun_id = -1;
145 static int hf_stun_attributes = -1;
146 static int hf_stun_response_in = -1;
147 static int hf_stun_response_to = -1;
148 static int hf_stun_time = -1;
149 static int hf_stun_duplicate = -1;
150 static int hf_stun_attr = -1;
151 
152 static int hf_stun_att_type = -1; /* STUN attribute fields */
153 static int hf_stun_att_length = -1;
154 static int hf_stun_att_family = -1;
155 static int hf_stun_att_type_comprehension = -1;
156 static int hf_stun_att_type_assignment = -1;
157 static int hf_stun_att_ipv4 = -1;
158 static int hf_stun_att_ipv6 = -1;
159 static int hf_stun_att_port = -1;
160 static int hf_stun_att_username = -1;
161 static int hf_stun_att_username_opaque = -1;
162 static int hf_stun_att_password = -1;
163 static int hf_stun_att_padding = -1;
164 static int hf_stun_att_hmac = -1;
165 static int hf_stun_att_crc32 = -1;
166 static int hf_stun_att_error_class = -1;
167 static int hf_stun_att_error_number = -1;
168 static int hf_stun_att_error_reason = -1;
169 static int hf_stun_att_realm = -1;
170 static int hf_stun_att_nonce = -1;
171 static int hf_stun_att_unknown = -1;
172 static int hf_stun_att_xor_ipv4 = -1;
173 static int hf_stun_att_xor_ipv6 = -1;
174 static int hf_stun_att_xor_port = -1;
175 static int hf_stun_att_icmp_type = -1;
176 static int hf_stun_att_icmp_code = -1;
177 static int hf_stun_att_ms_turn_unknown_8006 = -1;
178 static int hf_stun_att_software = -1;
179 static int hf_stun_att_priority = -1;
180 static int hf_stun_att_tie_breaker = -1;
181 static int hf_stun_att_change_ip = -1;
182 static int hf_stun_att_change_port = -1;
183 static int hf_stun_att_cache_timeout = -1;
184 static int hf_stun_att_token = -1;
185 static int hf_stun_att_pw_alg = -1;
186 static int hf_stun_att_pw_alg_param_len = -1;
187 static int hf_stun_att_pw_alg_param_data = -1;
188 static int hf_stun_att_reserve_next = -1;
189 static int hf_stun_att_reserved = -1;
190 static int hf_stun_att_value = -1;
191 static int hf_stun_att_transp = -1;
192 static int hf_stun_att_magic_cookie = -1;
193 static int hf_stun_att_bandwidth = -1;
194 static int hf_stun_att_lifetime = -1;
195 static int hf_stun_att_channelnum = -1;
196 static int hf_stun_att_ms_version = -1;
197 static int hf_stun_att_ms_connection_id = -1;
198 static int hf_stun_att_ms_sequence_number = -1;
199 static int hf_stun_att_ms_stream_type = -1;
200 static int hf_stun_att_ms_service_quality = -1;
201 static int hf_stun_att_ms_foundation = -1;
202 static int hf_stun_att_ms_multiplexed_turn_session_id = -1;
203 static int hf_stun_att_ms_turn_session_id = -1;
204 static int hf_stun_att_bandwidth_acm_type = -1;
205 static int hf_stun_att_bandwidth_rsv_id = -1;
206 static int hf_stun_att_bandwidth_rsv_amount_misb = -1;
207 static int hf_stun_att_bandwidth_rsv_amount_masb = -1;
208 static int hf_stun_att_bandwidth_rsv_amount_mirb = -1;
209 static int hf_stun_att_bandwidth_rsv_amount_marb = -1;
210 static int hf_stun_att_address_rp_a = -1;
211 static int hf_stun_att_address_rp_b = -1;
212 static int hf_stun_att_address_rp_rsv1 = -1;
213 static int hf_stun_att_address_rp_rsv2 = -1;
214 static int hf_stun_att_address_rp_masb = -1;
215 static int hf_stun_att_address_rp_marb = -1;
216 static int hf_stun_att_sip_dialog_id = -1;
217 static int hf_stun_att_sip_call_id = -1;
218 static int hf_stun_att_lp_peer_location = -1;
219 static int hf_stun_att_lp_self_location = -1;
220 static int hf_stun_att_lp_federation = -1;
221 static int hf_stun_att_google_network_id = -1;
222 static int hf_stun_att_google_network_cost = -1;
223 static int hf_stun_network_version = -1;
224 
225 /* Expert items */
226 static expert_field ei_stun_short_packet = EI_INIT;
227 static expert_field ei_stun_wrong_msglen = EI_INIT;
228 static expert_field ei_stun_long_attribute = EI_INIT;
229 static expert_field ei_stun_unknown_attribute = EI_INIT;
230 
231 /* Structure containing transaction specific information */
232 typedef struct _stun_transaction_t {
233     guint32 req_frame;
234     guint32 rep_frame;
235     nstime_t req_time;
236 } stun_transaction_t;
237 
238 /* Structure containing conversation specific information */
239 typedef struct _stun_conv_info_t {
240     wmem_tree_t *transaction_pdus;
241 } stun_conv_info_t;
242 
243 /* STUN versions RFC5389 and newer split off the leading 32 bits of the
244  * transaction ID into a magic cookie (called message cookie in this
245  * dissector to avoid confusion with the MAGIC_COOKIE attribute) and
246  * shortens the real transaction ID to 96 bits.
247  * This allows to differentiate between the legacy version of RFC3489
248  * and all newer versions.
249  */
250 #define MESSAGE_COOKIE 0x2112A442
251 #define TURN_MAGIC_COOKIE 0x72C64BC6
252 
253 /* Message classes (2 bit) */
254 #define REQUEST          0
255 #define INDICATION       1
256 #define SUCCESS_RESPONSE 2
257 #define ERROR_RESPONSE   3
258 
259 
260 /* Methods */
261 /* 0x000-0x07F IETF Review */
262 #define BINDING                 0x0001 /* RFC8489 */
263 #define SHARED_SECRET           0x0002 /* RFC3489 */
264 #define ALLOCATE                0x0003 /* RFC8489 */
265 #define REFRESH                 0x0004 /* RFC8489 */
266 #define SEND                    0x0006 /* RFC8656 */
267 #define DATA_IND                0x0007 /* RFC8656 */
268 #define CREATE_PERMISSION       0x0008 /* RFC8656 */
269 #define CHANNELBIND             0x0009 /* RFC8656 */
270 /* TCP specific */
271 #define CONNECT                 0x000a /* RFC6062 */
272 #define CONNECTION_BIND         0x000b /* RFC6062 */
273 #define CONNECTION_ATTEMPT      0x000c /* RFC6062 */
274 #define GOOG_PING               0x0080 /* Google undocumented */
275 
276 /* 0x080-0x0FF Expert Review */
277 
278 /* Attribute Types */
279 /* 0x0000-0x3FFF IETF Review comprehension-required range */
280 #define MAPPED_ADDRESS          0x0001 /* RFC8489, MS-TURN */
281 #define RESPONSE_ADDRESS        0x0002 /* Deprecated, RFC3489 */
282 #define CHANGE_REQUEST          0x0003 /* Deprecated, RFC3489 */
283 #define SOURCE_ADDRESS          0x0004 /* Deprecated, RFC3489 */
284 #define CHANGED_ADDRESS         0x0005 /* Deprecated, RFC3489 */
285 #define USERNAME                0x0006 /* RFC8489, MS-TURN */
286 #define PASSWORD                0x0007 /* Deprecated, RFC3489 */
287 #define MESSAGE_INTEGRITY       0x0008 /* RFC8489, MS-TURN */
288 #define ERROR_CODE              0x0009 /* RFC8489, MS-TURN */
289 #define UNKNOWN_ATTRIBUTES      0x000a /* RFC8489, MS-TURN */
290 #define REFLECTED_FROM          0x000b /* Deprecated, RFC3489 */
291 #define CHANNEL_NUMBER          0x000c /* RFC8656 */
292 #define LIFETIME                0x000d /* RFC8656, MS-TURN */
293 #define MS_ALTERNATE_SERVER     0x000e /* MS-TURN */
294 /* 0x000f reserved collision */
295 #define MAGIC_COOKIE            0x000f /* MS-TURN */
296 /* 0x0010 fix reference */
297 #define BANDWIDTH               0x0010 /* MS-TURN */
298 /* 0x0011 reserved collision */
299 #define DESTINATION_ADDRESS     0x0011 /* MS-TURN */
300 #define XOR_PEER_ADDRESS        0x0012 /* RFC8656, MS-TURN */
301 #define DATA                    0x0013 /* RFC8656, MS-TURN */
302 /* Note: REALM and NONCE have swapped attribute numbers in MS-TURN */
303 #define REALM                   0x0014 /* RFC8489, MS-TURN uses 0x0015 */
304 #define NONCE                   0x0015 /* RFC8489, MS-TURN uses 0x0014 */
305 #define XOR_RELAYED_ADDRESS     0x0016 /* RFC8656 */
306 #define REQUESTED_ADDRESS_FAMILY 0x0017 /* RFC8656, MS-TURN */
307 #define EVEN_PORT               0x0018 /* RFC8656 */
308 #define REQUESTED_TRANSPORT     0x0019 /* RFC8656 */
309 #define DONT_FRAGMENT           0x001a /* RFC8656 */
310 #define ACCESS_TOKEN            0x001b /* RFC7635 */
311 #define MESSAGE_INTEGRITY_SHA256 0x001c /* RFC8489 */
312 #define PASSWORD_ALGORITHM      0x001d /* RFC8489 */
313 #define USERHASH                0x001e /* RFC8489 */
314 /* 0x001f Reserved */
315 #define XOR_MAPPED_ADDRESS      0x0020 /* RFC8489 */
316 /* 0x0021 add deprecated TIMER-VAL */
317 #define RESERVATION_TOKEN       0x0022 /* RFC8656 */
318 /* 0x0023 Reserved */
319 #define PRIORITY                0x0024 /* RFC8445 */
320 #define USE_CANDIDATE           0x0025 /* RFC8445 */
321 #define PADDING                 0x0026 /* RFC5780 */
322 /* 0x0027 collision RESPONSE-PORT RFC5780 */
323 #define XOR_RESPONSE_TARGET     0x0027 /* draft-ietf-behave-nat-behavior-discovery-03 */
324 /* 0x0028 Reserved collision */
325 #define XOR_REFLECTED_FROM      0x0028 /* draft-ietf-behave-nat-behavior-discovery-03 */
326 /* 0x0029 Reserved */
327 #define CONNECTION_ID           0x002a /* rfc6062 */
328 /* 0x002b-0x002f unassigned */
329 /* 0x0030 collision reserved */
330 #define LEGACY_ICMP             0x0030 /* Moved from TURN to 0x8004 */
331 /* 0x0031-0x3fff Unassigned */
332 
333 /* 0x4000-0x7FFF Expert Review comprehension-required range */
334 /* 0x4000-0x7fff Unassigned */
335 
336 /* 0x8000-0xBFFF IETF Review comprehension-optional range */
337 #define ADDITIONAL_ADDRESS_FAMILY 0x8000 /* RFC8656 */
338 #define ADDRESS_ERROR_CODE      0x8001 /* RFC8656 */
339 #define PASSWORD_ALGORITHMS     0x8002 /* RFC8489 */
340 #define ALTERNATE_DOMAIN        0x8003 /* RFC8489 */
341 #define ICMP                    0x8004 /* RFC8656 */
342 /* Unknown attribute in MS-TURN packets */
343 #define MS_TURN_UNKNOWN_8006	0x8006
344 /* 0x8005-0x8021 Unassigned collision */
345 #define MS_VERSION              0x8008 /* MS-TURN */
346 /* collision */
347 #define MS_XOR_MAPPED_ADDRESS   0x8020 /* MS-TURN */
348 #define SOFTWARE                0x8022 /* RFC8489 */
349 #define ALTERNATE_SERVER        0x8023 /* RFC8489 */
350 /* 0x8024 Reserved */
351 #define TRANSACTION_TRANSMIT_COUNTER 0x8025 /* RFC7982 */
352 /* 0x8026 Reserved */
353 #define CACHE_TIMEOUT           0x8027 /* RFC5780 */
354 #define FINGERPRINT             0x8028 /* RFC8489 */
355 #define ICE_CONTROLLED          0x8029 /* RFC8445 */
356 #define ICE_CONTROLLING         0x802a /* RFC8445 */
357 #define RESPONSE_ORIGIN         0x802b /* RFC5780 */
358 #define OTHER_ADDRESS           0x802c /* RFC5780 */
359 #define ECN_CHECK_STUN          0x802d /* RFC6679 */
360 #define THIRD_PARTY_AUTHORIZATION 0x802e /* RFC7635 */
361 /* 0x802f Unassigned */
362 #define MOBILITY_TICKET         0x8030 /* RFC8016 */
363 /* 0x8031-0xBFFF Unassigned collision */
364 #define MS_ALTERNATE_HOST_NAME  0x8032 /* MS-TURN */
365 #define MS_APP_ID               0x8037 /* MS-TURN */
366 #define MS_SECURE_TAG           0x8039 /* MS-TURN */
367 #define MS_SEQUENCE_NUMBER      0x8050 /* MS-TURN */
368 #define MS_CANDIDATE_IDENTIFIER 0x8054 /* MS-ICE2 */
369 #define MS_SERVICE_QUALITY      0x8055 /* MS-TURN */
370 #define BANDWIDTH_ACM           0x8056 /* MS-TURNBWM */
371 #define BANDWIDTH_RSV_ID        0x8057 /* MS-TURNBWM */
372 #define BANDWIDTH_RSV_AMOUNT    0x8058 /* MS-TURNBWM */
373 #define REMOTE_SITE_ADDR        0x8059 /* MS-TURNBWM */
374 #define REMOTE_RELAY_SITE       0x805A /* MS-TURNBWM */
375 #define LOCAL_SITE_ADDR         0x805B /* MS-TURNBWM */
376 #define LOCAL_RELAY_SITE        0x805C /* MS-TURNBWM */
377 #define REMOTE_SITE_ADDR_RP     0x805D /* MS-TURNBWM */
378 #define REMOTE_RELAY_SITE_RP    0x805E /* MS-TURNBWM */
379 #define LOCAL_SITE_ADDR_RP      0x805F /* MS-TURNBWM */
380 #define LOCAL_RELAY_SITE_RP     0x8060 /* MS-TURNBWM */
381 #define SIP_DIALOG_ID           0x8061 /* MS-TURNBWM */
382 #define SIP_CALL_ID             0x8062 /* MS-TURNBWM */
383 #define LOCATION_PROFILE        0x8068 /* MS-TURNBWM */
384 #define MS_IMPLEMENTATION_VER   0x8070 /* MS-ICE2 */
385 #define MS_ALT_MAPPED_ADDRESS   0x8090 /* MS-TURN */
386 #define MS_MULTIPLEXED_TURN_SESSION_ID 0x8095 /* MS_TURN */
387 
388 /* 0xC000-0xFFFF Expert Review comprehension-optional range */
389 #define CISCO_STUN_FLOWDATA     0xc000 /* Cisco undocumented */
390 #define ENF_FLOW_DESCRIPTION    0xc001 /* Cisco undocumented */
391 #define ENF_NETWORK_STATUS      0xc002 /* Cisco undocumented */
392 /* 0xc003-0xc056 Unassigned */
393 /* https://webrtc.googlesource.com/src/+/refs/heads/master/api/transport/stun.h */
394 #define GOOG_NETWORK_INFO       0xc057
395 #define GOOG_LAST_ICE_CHECK_RECEIVED 0xc058
396 #define GOOG_MISC_INFO          0xc059
397 #define GOOG_MESSAGE_INTEGRITY_32 0xc060
398 /* 0xc061-0xff03 Unassigned */
399 /* https://webrtc.googlesource.com/src/+/refs/heads/master/p2p/base/turn_port.cc */
400 #define GOOG_MULTI_MAPPING      0xff04
401 #define GOOG_LOGGING_ID         0xff05
402 /* 0xff06-0xffff Unassigned */
403 
404 /* Initialize the subtree pointers */
405 static gint ett_stun = -1;
406 static gint ett_stun_type = -1;
407 static gint ett_stun_att_all= -1;
408 static gint ett_stun_att = -1;
409 static gint ett_stun_att_type = -1;
410 
411 #define UDP_PORT_STUN   3478
412 #define TCP_PORT_STUN   3478
413 
414 #define STUN_HDR_LEN                   20 /* STUN message header length */
415 #define ATTR_HDR_LEN                    4 /* STUN attribute header length */
416 #define CHANNEL_DATA_HDR_LEN            4 /* TURN CHANNEL-DATA Message hdr length */
417 #define MIN_HDR_LEN                     4
418 #define TCP_FRAME_COOKIE_LEN           10 /* min length for cookie with TCP framing */
419 
420 static const value_string transportnames[] = {
421     { 17, "UDP" },
422     {  6, "TCP" },
423     {  0, NULL }
424 };
425 
426 static const value_string classes[] = {
427     {REQUEST         , "Request"},
428     {INDICATION      , "Indication"},
429     {SUCCESS_RESPONSE, "Success Response"},
430     {ERROR_RESPONSE  , "Error Response"},
431     {0x00            , NULL}
432 };
433 
434 static const value_string methods[] = {
435     {BINDING           , "Binding"},
436     {SHARED_SECRET     , "SharedSecret"},
437     {ALLOCATE          , "Allocate"},
438     {REFRESH           , "Refresh"},
439     {SEND              , "Send"},
440     {DATA_IND          , "Data"},
441     {CREATE_PERMISSION , "CreatePermission"},
442     {CHANNELBIND       , "Channel-Bind"},
443     {CONNECT           , "Connect"},
444     {CONNECTION_BIND   , "ConnectionBind"},
445     {CONNECTION_ATTEMPT, "ConnectionAttempt"},
446     {GOOG_PING         , "GooglePing"},
447     {0x00              , NULL}
448 };
449 
450 
451 static const value_string attributes[] = {
452   /* 0x0000-0x3FFF IETF Review comprehension-required range */
453     {MAPPED_ADDRESS        , "MAPPED-ADDRESS"},
454     {RESPONSE_ADDRESS      , "RESPONSE_ADDRESS"},
455     {CHANGE_REQUEST        , "CHANGE_REQUEST"},
456     {SOURCE_ADDRESS        , "SOURCE_ADDRESS"},
457     {CHANGED_ADDRESS       , "CHANGED_ADDRESS"},
458     {USERNAME              , "USERNAME"},
459     {PASSWORD              , "PASSWORD"},
460     {MESSAGE_INTEGRITY     , "MESSAGE-INTEGRITY"},
461     {ERROR_CODE            , "ERROR-CODE"},
462     {UNKNOWN_ATTRIBUTES    , "UNKNOWN-ATTRIBUTES"},
463     {REFLECTED_FROM        , "REFLECTED-FROM"},
464     {CHANNEL_NUMBER        , "CHANNEL-NUMBER"},
465     {LIFETIME              , "LIFETIME"},
466     {MS_ALTERNATE_SERVER   , "MS-ALTERNATE-SERVER"},
467     {MAGIC_COOKIE          , "MAGIC-COOKIE"},
468     {BANDWIDTH             , "BANDWIDTH"},
469     {DESTINATION_ADDRESS   , "DESTINATION-ADDRESS"},
470     {XOR_PEER_ADDRESS      , "XOR-PEER-ADDRESS"},
471     {DATA                  , "DATA"},
472     {REALM                 , "REALM"},
473     {NONCE                 , "NONCE"},
474     {XOR_RELAYED_ADDRESS   , "XOR-RELAYED-ADDRESS"},
475     {REQUESTED_ADDRESS_FAMILY, "REQUESTED-ADDRESS-FAMILY"},
476     {EVEN_PORT             , "EVEN-PORT"},
477     {REQUESTED_TRANSPORT   , "REQUESTED-TRANSPORT"},
478     {DONT_FRAGMENT         , "DONT-FRAGMENT"},
479     {ACCESS_TOKEN          , "ACCESS-TOKEN"},
480     {MESSAGE_INTEGRITY_SHA256, "MESSAGE-INTEGRITY-SHA256"},
481     {PASSWORD_ALGORITHM    , "PASSWORD-ALGORITHM"},
482     {USERHASH              , "USERHASH"},
483     {XOR_MAPPED_ADDRESS    , "XOR-MAPPED-ADDRESS"},
484     {RESERVATION_TOKEN     , "RESERVATION-TOKEN"},
485     {PRIORITY              , "PRIORITY"},
486     {USE_CANDIDATE         , "USE-CANDIDATE"},
487     {PADDING               , "PADDING"},
488     {XOR_RESPONSE_TARGET   , "XOR-RESPONSE-TARGET"},
489     {XOR_REFLECTED_FROM    , "XOR-REFELECTED-FROM"},
490     {CONNECTION_ID         , "CONNECTION-ID"},
491     {LEGACY_ICMP           , "LEGACY-ICMP"},
492 
493   /* 0x4000-0x7FFF Expert Review comprehension-required range */
494 
495   /* 0x8000-0xBFFF IETF Review comprehension-optional range */
496     {ADDITIONAL_ADDRESS_FAMILY, "ADDITIONAL-ADDRESS-FAMILY"},
497     {ADDRESS_ERROR_CODE    , "ADDRESS-ERROR-CODE"},
498     {PASSWORD_ALGORITHMS   , "PASSWORD-ALGORITHMS"},
499     {ALTERNATE_DOMAIN      , "ALTERNATE-DOMAIN"},
500     {ICMP                  , "ICMP"},
501     {MS_TURN_UNKNOWN_8006  , "MS-TURN UNKNOWN 8006"},
502     {MS_VERSION            , "MS-VERSION"},
503     {MS_XOR_MAPPED_ADDRESS , "XOR-MAPPED-ADDRESS"},
504     {SOFTWARE              , "SOFTWARE"},
505     {ALTERNATE_SERVER      , "ALTERNATE-SERVER"},
506     {TRANSACTION_TRANSMIT_COUNTER, "TRANSACTION-TRANSMIT-COUNTER"},
507     {CACHE_TIMEOUT         , "CACHE-TIMEOUT"},
508     {FINGERPRINT           , "FINGERPRINT"},
509     {ICE_CONTROLLED        , "ICE-CONTROLLED"},
510     {ICE_CONTROLLING       , "ICE-CONTROLLING"},
511     {RESPONSE_ORIGIN       , "RESPONSE-ORIGIN"},
512     {OTHER_ADDRESS         , "OTHER-ADDRESS"},
513     {ECN_CHECK_STUN        , "ECN-CHECK-STUN"},
514     {THIRD_PARTY_AUTHORIZATION, "THIRD-PARTY-AUTHORIZATION"},
515     {MOBILITY_TICKET       , "MOBILITY-TICKET"},
516     {MS_ALTERNATE_HOST_NAME, "MS-ALTERNATE-HOST-NAME"},
517     {MS_APP_ID             , "MS-APP-ID"},
518     {MS_SECURE_TAG         , "MS-SECURE-TAG"},
519     {MS_SEQUENCE_NUMBER    , "MS-SEQUENCE-NUMBER"},
520     {MS_CANDIDATE_IDENTIFIER, "MS-CANDIDATE-IDENTIFIER"},
521     {MS_SERVICE_QUALITY    , "MS-SERVICE-QUALITY"},
522     {BANDWIDTH_ACM         , "Bandwidth Admission Control Message"},
523     {BANDWIDTH_RSV_ID      , "Bandwidth Reservation Identifier"},
524     {BANDWIDTH_RSV_AMOUNT  , "Bandwidth Reservation Amount"},
525     {REMOTE_SITE_ADDR      , "Remote Site Address"},
526     {REMOTE_RELAY_SITE     , "Remote Relay Site Address"},
527     {LOCAL_SITE_ADDR       , "Local Site Address"},
528     {LOCAL_RELAY_SITE      , "Local Relay Site Address"},
529     {REMOTE_SITE_ADDR_RP   , "Remote Site Address Response"},
530     {REMOTE_RELAY_SITE_RP  , "Remote Relay Site Address Response"},
531     {LOCAL_SITE_ADDR_RP    , "Local Site Address Response"},
532     {LOCAL_RELAY_SITE_RP   , "Local Relay Site Address Response"},
533     {SIP_DIALOG_ID         , "SIP Dialog Identifier"},
534     {SIP_CALL_ID           , "SIP Call Identifier"},
535     {LOCATION_PROFILE      , "Location Profile"},
536     {MS_IMPLEMENTATION_VER , "MS-IMPLEMENTATION-VERSION"},
537     {MS_ALT_MAPPED_ADDRESS , "MS-ALT-MAPPED-ADDRESS"},
538     {MS_MULTIPLEXED_TURN_SESSION_ID, "MS-MULTIPLEXED-TURN-SESSION-ID"},
539 
540   /* 0xC000-0xFFFF Expert Review comprehension-optional range */
541     {CISCO_STUN_FLOWDATA   , "CISCO-STUN-FLOWDATA"},
542     {ENF_FLOW_DESCRIPTION   , "ENF-FLOW-DESCRIPTION"},
543     {ENF_NETWORK_STATUS    , "ENF-NETWORK-STATUS"},
544     {GOOG_NETWORK_INFO     , "GOOG-NETWORK-INFO"},
545     {GOOG_LAST_ICE_CHECK_RECEIVED, "GOOG-LAST-ICE-CHECK-RECEIVED"},
546     {GOOG_MISC_INFO        , "GOOG-MISC-INFO"},
547     {GOOG_MESSAGE_INTEGRITY_32, "GOOG-MESSAGE_INTEGRITY-32"},
548     {GOOG_MULTI_MAPPING    , "GOOG-MULTI-MAPPING"},
549     {GOOG_LOGGING_ID       , "GOOG-LOGGING-ID"},
550 
551     {0x00                  , NULL}
552 };
553 static value_string_ext attributes_ext = VALUE_STRING_EXT_INIT(attributes);
554 
555 static const value_string assignments[] = {
556     {0x0000, "IETF Review"},
557     {0x0001, "Designated Expert"},
558     {0x00, NULL}
559 };
560 
561 static const value_string comprehensions[] = {
562     {0x0000, "Required"},
563     {0x0001, "Optional"},
564     {0x00  , NULL}
565 };
566 
567 static const value_string attributes_reserve_next[] = {
568     {0, "No reservation"},
569     {1, "Reserve next port number"},
570     {0x00, NULL}
571 };
572 
573 static const value_string attributes_family[] = {
574     {0x0001, "IPv4"},
575     {0x0002, "IPv6"},
576     {0x00, NULL}
577 };
578 /* https://www.iana.org/assignments/stun-parameters/stun-parameters.xhtml#stun-parameters-6 (2020-08-05)*/
579 
580 static const value_string error_code[] = {
581     {274, "Disable Candidate"},               /* MS-ICE2BWN */
582     {275, "Disable Candidate Pair"},          /* MS-ICE2BWN */
583     {300, "Try Alternate"},                   /* RFC8489 */
584     {400, "Bad Request"},                     /* RFC8489 */
585     {401, "Unauthenticated"},                 /* RFC8489, RFC3489+MS-TURN: Unauthorized */
586     {403, "Forbidden"},                       /* RFC8656 */
587     {405, "Mobility Forbidden"},              /* RFC8016 */
588     {420, "Unknown Attribute"},               /* RFC8489 */
589     {430, "Stale Credentials (legacy)"},      /* RFC3489 */
590     {431, "Integrity Check Failure (legacy)"}, /* RFC3489 */
591     {432, "Missing Username (legacy)"},       /* RFC3489 */
592     {433, "Use TLS (legacy)"},                /* RFC3489 */
593     {434, "Missing Realm (legacy)"},          /* MS-TURN */
594     {435, "Missing Nonce (legacy)"},          /* MS-TURN */
595     {436, "Unknown User (legacy)"},           /* MS-TURN */
596     {437, "Allocation Mismatch"},             /* RFC8656 */
597     {438, "Stale Nonce"},                     /* RFC8489 */
598     {439, "Wrong Credentials (legacy)"},      /* turn-07 */
599     {440, "Address Family not Supported"},    /* RFC8656 */
600     {441, "Wrong Credentials"},               /* RFC8656 */
601     {442, "Unsupported Transport Protocol"},  /* RFC8656 */
602     {443, "Peer Address Family Mismatch"},    /* RFC8656 */
603     {446, "Connection Already Exists"},       /* RFC6062 */
604     {447, "Connection Timeout or Failure"},   /* RFC6062 */
605     {481, "Connection does not exist (legacy)"}, /* nat-behavior-discovery-03 */
606     {486, "Allocation Quota Reached"},        /* RFC8656 */
607     {487, "Role Conflict"},                   /* RFC8445 */
608     {500, "Server Error"},                    /* RFC8489 */
609     {503, "Service Unavailable (legacy)"},    /* nat-behavior-discovery-03 */
610     {507, "Insufficient Bandwidth Capacity (legacy)"}, /* turn-07 */
611     {508, "Insufficient Port Capacity"},      /* RFC8656 */
612     {600, "Global Failure"},                  /* RFC8656 */
613     {0x00, NULL}
614 };
615 static value_string_ext error_code_ext = VALUE_STRING_EXT_INIT(error_code);
616 
617 static const value_string ms_version_vals[] = {
618     {0x00000001, "ICE"},
619     {0x00000002, "MS-ICE2"},
620     {0x00000003, "MS-ICE2 with SHA256"},
621     {0x00000004, "MS-ICE2 with SHA256 and IPv6"},
622     {0x00000005, "MULTIPLEXED TURN over UDP only"},
623     {0x00000006, "MULTIPLEXED TURN over UDP and TCP"},
624     {0x00, NULL}
625 };
626 
627 static const value_string ms_stream_type_vals[] = {
628     {0x0001, "Audio"},
629     {0x0002, "Video"},
630     {0x0003, "Supplemental Video"},
631     {0x0004, "Data"},
632     {0x00, NULL}
633 };
634 
635 static const value_string ms_service_quality_vals[] = {
636     {0x0000, "Best effort delivery"},
637     {0x0001, "Reliable delivery"},
638     {0x00, NULL}
639 };
640 
641 static const value_string bandwidth_acm_type_vals[] = {
642     {0x0000, "Reservation Check"},
643     {0x0001, "Reservation Commit"},
644     {0x0002, "Reservation Update"},
645     {0x00, NULL}
646 };
647 
648 static const value_string location_vals[] = {
649     {0x00, "Unknown"},
650     {0x01, "Internet"},
651     {0x02, "Intranet"},
652     {0x00, NULL}
653 };
654 
655 static const value_string federation_vals[] = {
656     {0x00, "No Federation"},
657     {0x01, "Enterprise Federation"},
658     {0x02, "Public Cloud Federation"},
659     {0x00, NULL}
660 };
661 
662 static const value_string password_algorithm_vals[] = {
663     {0x0000, "Reserved"},
664     {0x0001, "MD5"},
665     {0x0002, "SHA-256"},
666     {0x0000, NULL}
667 };
668 
669 /* https://webrtc.googlesource.com/src/+/refs/heads/master/rtc_base/network_constants.h */
670 static const value_string google_network_cost_vals[] = {
671     {0,   "Min"},
672     {10,  "Low"},
673     {50,  "Unknown"},
674     {250, "Cellular5G"},
675     {500, "Cellular4G"},
676     {900, "Cellular"},
677     {910, "Cellular3G"},
678     {980, "Cellular2G"},
679     {999, "Max"},
680     {0,   NULL}
681 };
682 
683 
684 static guint
get_stun_message_len(packet_info * pinfo _U_,tvbuff_t * tvb,int offset,void * data _U_)685 get_stun_message_len(packet_info *pinfo _U_, tvbuff_t *tvb,
686                      int offset, void *data _U_)
687 {
688     guint16 type;
689     guint   length;
690     guint   captured_length = tvb_captured_length(tvb);
691 
692     if ((captured_length >= TCP_FRAME_COOKIE_LEN) &&
693         (tvb_get_ntohl(tvb, 6) == MESSAGE_COOKIE)) {
694         /*
695          * The magic cookie is off by two, so this appears to be
696          * RFC 4571 framing, as per RFC 6544; use the length
697          * field from that framing, rather than the STUN/TURN
698          * ChannelData length field.
699          */
700         return (tvb_get_ntohs(tvb, offset) + 2);
701     }
702 
703     type   = tvb_get_ntohs(tvb, offset);
704     length = tvb_get_ntohs(tvb, offset+2);
705 
706     if (type & 0xC000)
707     {
708         /* two first bits not NULL => should be a channel-data message */
709         /* Note: For TCP the message is padded to a 4 byte boundary    */
710         return (length + CHANNEL_DATA_HDR_LEN +3) & ~0x3;
711     }
712     else
713     {
714         /* Normal STUN message */
715         return length + STUN_HDR_LEN;
716     }
717 }
718 
719 /*
720  * XXX: why is this done in this file by the STUN dissector? Why don't we
721  * re-use the packet-turnchannel.c's dissect_turnchannel_message() function?
722  */
723 static int
dissect_stun_message_channel_data(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,guint16 msg_type,guint msg_length)724 dissect_stun_message_channel_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint16 msg_type, guint msg_length)
725 {
726     tvbuff_t *next_tvb;
727     heur_dtbl_entry_t *hdtbl_entry;
728     gint offset = CHANNEL_DATA_HDR_LEN;
729 
730     /* XXX: a TURN ChannelData message is not actually a STUN message. */
731     col_set_str(pinfo->cinfo, COL_PROTOCOL, "STUN");
732     col_set_str(pinfo->cinfo, COL_INFO, "ChannelData TURN Message");
733 
734     if (tree) {
735         proto_item *ti;
736         proto_tree *stun_tree;
737         ti = proto_tree_add_item(
738             tree, proto_stun, tvb, 0,
739             CHANNEL_DATA_HDR_LEN,
740             ENC_NA);
741         proto_item_append_text(ti, ", TURN ChannelData Message");
742         stun_tree = proto_item_add_subtree(ti, ett_stun);
743         proto_tree_add_item(stun_tree, hf_stun_channel, tvb, 0, 2, ENC_BIG_ENDIAN);
744         proto_tree_add_item(stun_tree, hf_stun_length,  tvb, 2, 2, ENC_BIG_ENDIAN);
745         /* MS-TURN Multiplexed TURN Channel */
746         if (msg_type == 0xFF10 && msg_length >= 8) {
747             proto_tree_add_item(stun_tree, hf_stun_att_ms_turn_session_id, tvb, 4, 8, ENC_NA);
748         }
749     }
750     if (msg_type == 0xFF10 && msg_length >= 8) {
751         msg_length -= 8;
752         offset += 8;
753     }
754 
755     next_tvb = tvb_new_subset_length(tvb, offset, msg_length);
756 
757     if (!dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, tree, &hdtbl_entry, NULL)) {
758         call_dissector_only(data_handle, next_tvb, pinfo, tree, NULL);
759     }
760 
761     return tvb_reported_length(tvb);
762 }
763 
764 
765 static int
dissect_stun_message(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,gboolean heur_check,gboolean is_udp)766 dissect_stun_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gboolean heur_check, gboolean is_udp)
767 {
768     guint       captured_length;
769     guint16     msg_type;
770     guint       msg_length;
771     proto_item *ti;
772     proto_tree *stun_tree;
773     proto_tree *stun_type_tree;
774     proto_tree *att_all_tree;
775     proto_tree *att_type_tree;
776     proto_tree *att_tree = NULL;
777     guint16     msg_type_method;
778     guint16     msg_type_class;
779     const char *msg_class_str;
780     const char *msg_method_str;
781     guint16     att_type, att_type_display;
782     guint16     att_length, att_length_pad, clear_port;
783     guint32     clear_ip[4];
784     address     addr;
785     guint       i;
786     guint       offset;
787     guint       magic_cookie_first_word;
788     guint       tcp_framing_offset;
789     conversation_t     *conversation=NULL;
790     stun_conv_info_t   *stun_info;
791     stun_transaction_t *stun_trans;
792     wmem_tree_key_t     transaction_id_key[2];
793     guint32             transaction_id[3];
794     heur_dtbl_entry_t  *hdtbl_entry;
795     guint               reported_length;
796     gboolean            is_turn = FALSE;
797     gboolean            found_turn_attributes = FALSE;
798     int                 network_version; /* STUN flavour of the current message */
799 
800     /*
801      * Check if the frame is really meant for us.
802      */
803 
804     /* First, make sure we have enough data to do the check. */
805     captured_length = tvb_captured_length(tvb);
806     if (captured_length < MIN_HDR_LEN)
807         return 0;
808     reported_length = tvb_reported_length(tvb);
809 
810     tcp_framing_offset = 0;
811     if ((!is_udp) && (captured_length >= TCP_FRAME_COOKIE_LEN) &&
812        (tvb_get_ntohl(tvb, 6) == MESSAGE_COOKIE)) {
813         /*
814          * The magic cookie is off by two, so this appears to be
815          * RFC 4571 framing, as per RFC 6544; the STUN/TURN
816          * ChannelData header begins after the 2-octet
817          * RFC 4571 length field.
818          */
819         tcp_framing_offset = 2;
820     }
821 
822     msg_type     = tvb_get_ntohs(tvb, tcp_framing_offset + 0);
823     msg_length   = tvb_get_ntohs(tvb, tcp_framing_offset + 2);
824 
825     /* TURN ChannelData message ? */
826     if (msg_type & 0xC000) {
827         /* two first bits not NULL => should be a channel-data message */
828 
829         /*
830          * If the packet is being dissected through heuristics, we never match
831          * TURN ChannelData because the heuristics are otherwise rather weak.
832          * Instead we have to have seen another TURN message type on the same
833          * 5-tuple, and then set that conversation for non-heuristic STUN dissection.
834          */
835         if (heur_check)
836             return 0;
837 
838         if (msg_type == 0xFFFF)
839             return 0;
840 
841         /* note that padding is only mandatory over streaming
842            protocols */
843         if (is_udp) {
844             if (reported_length != msg_length + CHANNEL_DATA_HDR_LEN &&
845                 reported_length != ((msg_length + CHANNEL_DATA_HDR_LEN + 3) & ~0x3))
846                 return 0;
847         } else { /* TCP */
848             if (reported_length != ((msg_length + CHANNEL_DATA_HDR_LEN + 3) & ~0x3))
849                 return 0;
850         }
851 
852         /* XXX: why don't we invoke the turnchannel dissector instead? */
853         return dissect_stun_message_channel_data(tvb, pinfo, tree, msg_type, msg_length);
854     }
855 
856     /* Normal STUN message */
857     if (captured_length < STUN_HDR_LEN)
858         return 0;
859 
860     /* Check if it is really a STUN message */
861     if ( tvb_get_ntohl(tvb, tcp_framing_offset + 4) != MESSAGE_COOKIE)
862         return 0;
863 
864     /* check if payload enough */
865     if (reported_length != (msg_length + STUN_HDR_LEN + tcp_framing_offset))
866         return 0;
867 
868     /* The message seems to be a valid STUN message! */
869 
870     col_set_str(pinfo->cinfo, COL_PROTOCOL, "STUN");
871 
872     /* Create the transaction key which may be used
873        to track the conversation */
874     transaction_id[0] = tvb_get_ntohl(tvb, tcp_framing_offset + 8);
875     transaction_id[1] = tvb_get_ntohl(tvb, tcp_framing_offset + 12);
876     transaction_id[2] = tvb_get_ntohl(tvb, tcp_framing_offset + 16);
877 
878     transaction_id_key[0].length = 3;
879     transaction_id_key[0].key =  transaction_id;
880     transaction_id_key[1].length = 0;
881     transaction_id_key[1].key = NULL;
882 
883     msg_type_class = ((msg_type & 0x0010) >> 4) | ((msg_type & 0x0100) >> 7) ;
884     msg_type_method = (msg_type & 0x000F) | ((msg_type & 0x00E0) >> 1) | ((msg_type & 0x3E00) >> 2);
885 
886     switch (msg_type_method) {
887         /* if it's a TURN method, remember that */
888         case ALLOCATE:
889         case REFRESH:
890         case SEND:
891         case DATA_IND:
892         case CREATE_PERMISSION:
893         case CHANNELBIND:
894         case CONNECT:
895         case CONNECTION_BIND:
896         case CONNECTION_ATTEMPT:
897             is_turn = TRUE;
898             break;
899     }
900 
901     conversation = find_or_create_conversation(pinfo);
902 
903     /*
904      * Do we already have a state structure for this conv
905      */
906     stun_info = (stun_conv_info_t *)conversation_get_proto_data(conversation, proto_stun);
907     if (!stun_info) {
908         /* No.  Attach that information to the conversation, and add
909          * it to the list of information structures.
910          */
911         stun_info = wmem_new(wmem_file_scope(), stun_conv_info_t);
912         stun_info->transaction_pdus=wmem_tree_new(wmem_file_scope());
913         conversation_add_proto_data(conversation, proto_stun, stun_info);
914     }
915 
916     if (!pinfo->fd->visited) {
917         if ((stun_trans = (stun_transaction_t *)
918              wmem_tree_lookup32_array(stun_info->transaction_pdus,
919                                       transaction_id_key)) == NULL) {
920 
921             transaction_id_key[0].length = 3;
922             transaction_id_key[0].key =  transaction_id;
923             transaction_id_key[1].length = 0;
924             transaction_id_key[1].key = NULL;
925 
926             stun_trans=wmem_new(wmem_file_scope(), stun_transaction_t);
927             stun_trans->req_frame=0;
928             stun_trans->rep_frame=0;
929             stun_trans->req_time=pinfo->abs_ts;
930             wmem_tree_insert32_array(stun_info->transaction_pdus,
931                                      transaction_id_key,
932                                      (void *)stun_trans);
933         }
934 
935         if (msg_type_class == REQUEST) {
936             /* This is a request */
937             if (stun_trans->req_frame == 0) {
938                 stun_trans->req_frame=pinfo->num;
939             }
940 
941         } else {
942             /* This is a catch-all for all non-request messages */
943             if (stun_trans->rep_frame == 0) {
944                 stun_trans->rep_frame=pinfo->num;
945             }
946 
947         }
948     } else {
949         stun_trans=(stun_transaction_t *)wmem_tree_lookup32_array(stun_info->transaction_pdus,
950                                                                   transaction_id_key);
951     }
952 
953     if (!stun_trans) {
954         /* create a "fake" pana_trans structure */
955         stun_trans=wmem_new(pinfo->pool, stun_transaction_t);
956         stun_trans->req_frame=0;
957         stun_trans->rep_frame=0;
958         stun_trans->req_time=pinfo->abs_ts;
959     }
960 
961 
962     msg_class_str  = val_to_str_const(msg_type_class, classes, "Unknown");
963     msg_method_str = val_to_str_const(msg_type_method, methods, "Unknown");
964 
965     col_add_lstr(pinfo->cinfo, COL_INFO,
966                  msg_method_str,
967                  " ",
968                  msg_class_str,
969                  COL_ADD_LSTR_TERMINATOR);
970 
971     offset = 0;
972     ti = proto_tree_add_item(tree, proto_stun, tvb, offset, -1, ENC_NA);
973 
974     stun_tree = proto_item_add_subtree(ti, ett_stun);
975 
976     if (msg_type_class == REQUEST) {
977         if (stun_trans->req_frame != pinfo->num) {
978             proto_item *it;
979             it=proto_tree_add_uint(stun_tree, hf_stun_duplicate,
980                                    tvb, offset, 0,
981                                    stun_trans->req_frame);
982             proto_item_set_generated(it);
983         }
984         if (stun_trans->rep_frame) {
985             proto_item *it;
986             it=proto_tree_add_uint(stun_tree, hf_stun_response_in,
987                                    tvb, offset, 0,
988                                    stun_trans->rep_frame);
989             proto_item_set_generated(it);
990         }
991     }
992     else {
993         /* Retransmission control */
994         if (stun_trans->rep_frame != pinfo->num) {
995             proto_item *it;
996             it=proto_tree_add_uint(stun_tree, hf_stun_duplicate,
997                                    tvb, offset, 0,
998                                    stun_trans->rep_frame);
999             proto_item_set_generated(it);
1000         }
1001         if (msg_type_class == SUCCESS_RESPONSE || msg_type_class == ERROR_RESPONSE) {
1002             /* This is a response */
1003             if (stun_trans->req_frame) {
1004                 proto_item *it;
1005                 nstime_t ns;
1006 
1007                 it=proto_tree_add_uint(stun_tree, hf_stun_response_to, tvb,
1008                                        offset, 0,
1009                                        stun_trans->req_frame);
1010                 proto_item_set_generated(it);
1011 
1012                 nstime_delta(&ns, &pinfo->abs_ts, &stun_trans->req_time);
1013                 it=proto_tree_add_time(stun_tree, hf_stun_time, tvb,
1014                                        offset, 0, &ns);
1015                 proto_item_set_generated(it);
1016             }
1017 
1018         }
1019     }
1020 
1021     if (tcp_framing_offset) {
1022         proto_tree_add_item(stun_tree, hf_stun_tcp_frame_length, tvb, offset, 2, ENC_BIG_ENDIAN);
1023         offset += 2;
1024     }
1025     ti = proto_tree_add_uint_format_value(stun_tree, hf_stun_type, tvb, offset, 2,
1026                                           msg_type, "0x%04x (%s %s)", msg_type, msg_method_str, msg_class_str);
1027     stun_type_tree = proto_item_add_subtree(ti, ett_stun_type);
1028     ti = proto_tree_add_uint(stun_type_tree, hf_stun_type_class, tvb, offset, 2, msg_type);
1029     proto_item_append_text(ti, " %s (%d)", msg_class_str, msg_type_class);
1030     ti = proto_tree_add_uint(stun_type_tree, hf_stun_type_method, tvb, offset, 2, msg_type);
1031     proto_item_append_text(ti, " %s (0x%03x)", msg_method_str, msg_type_method);
1032     proto_tree_add_uint(stun_type_tree, hf_stun_type_method_assignment, tvb, offset, 2, msg_type);
1033     offset += 2;
1034 
1035     proto_tree_add_item(stun_tree, hf_stun_length, tvb, offset, 2, ENC_BIG_ENDIAN);
1036     offset += 2;
1037     proto_tree_add_item(stun_tree, hf_stun_cookie, tvb, offset, 4, ENC_NA);
1038     offset += 4;
1039     proto_tree_add_item(stun_tree, hf_stun_id, tvb, offset, 12, ENC_NA);
1040     offset += 12;
1041 
1042     /* Remember this (in host order) so we can show clear xor'd addresses */
1043     magic_cookie_first_word = tvb_get_ntohl(tvb, tcp_framing_offset + 4);
1044 
1045     network_version = stun_network_version != NET_VER_AUTO ? stun_network_version : NET_VER_5389;
1046 
1047     if (msg_length != 0) {
1048         const gchar       *attribute_name_str;
1049 
1050         /* According to [MS-TURN] section 2.2.2.8: "This attribute MUST be the
1051            first attribute following the TURN message header in all TURN messages  */
1052         if (stun_network_version == NET_VER_AUTO &&
1053             offset < (STUN_HDR_LEN + msg_length) &&
1054             tvb_get_ntohs(tvb, offset) == MAGIC_COOKIE) {
1055           network_version = NET_VER_MS_TURN;
1056         }
1057 
1058         ti = proto_tree_add_uint(stun_tree, hf_stun_network_version, tvb, offset, 0, network_version);
1059         proto_item_set_generated(ti);
1060 
1061         /* Starting with RFC 5389 msg_length MUST be multiple of 4 bytes */
1062         if ((network_version >= NET_VER_5389 && msg_length & 3) != 0)
1063             stun_tree = proto_tree_add_expert(stun_tree, pinfo, &ei_stun_wrong_msglen, tvb, offset-18, 2);
1064 
1065         ti = proto_tree_add_item(stun_tree, hf_stun_attributes, tvb, offset, msg_length, ENC_NA);
1066         att_all_tree = proto_item_add_subtree(ti, ett_stun_att_all);
1067 
1068         while (offset < (STUN_HDR_LEN + msg_length)) {
1069             att_type = tvb_get_ntohs(tvb, offset);     /* Attribute type field in attribute header */
1070             att_length = tvb_get_ntohs(tvb, offset+2); /* Attribute length field in attribute header */
1071             if (network_version >= NET_VER_5389)
1072                 att_length_pad = WS_ROUNDUP_4(att_length); /* Attribute length including padding */
1073             else
1074                 att_length_pad = att_length;
1075             att_type_display = att_type;
1076             /* Early drafts and MS-TURN use swapped numbers to later versions */
1077             if ((network_version < NET_VER_3489) && (att_type == 0x0014 || att_type == 0x0015)) {
1078                 att_type_display ^= 1;
1079             }
1080             attribute_name_str = try_val_to_str_ext(att_type_display, &attributes_ext);
1081             if (attribute_name_str){
1082                 ti = proto_tree_add_uint_format(att_all_tree, hf_stun_attr,
1083                                                 tvb, offset, ATTR_HDR_LEN+att_length_pad,
1084                                                 att_type, "%s", attribute_name_str);
1085                 att_tree = proto_item_add_subtree(ti, ett_stun_att);
1086                 ti = proto_tree_add_uint_format_value(att_tree, hf_stun_att_type, tvb,
1087                                          offset, 2, att_type, "%s", attribute_name_str);
1088                 att_type_tree = proto_item_add_subtree(ti, ett_stun_att_type);
1089                 proto_tree_add_uint(att_type_tree, hf_stun_att_type_comprehension, tvb, offset, 2, att_type);
1090                 proto_tree_add_uint(att_type_tree, hf_stun_att_type_assignment, tvb, offset, 2, att_type);
1091 
1092                 if ((offset+ATTR_HDR_LEN+att_length_pad) > (STUN_HDR_LEN+msg_length+tcp_framing_offset)) {
1093                     proto_tree_add_uint_format_value(att_tree,
1094                                                      hf_stun_att_length, tvb, offset+2, 2,
1095                                                      att_length_pad,
1096                                                      "%u (bogus, goes past the end of the message)",
1097                                                      att_length_pad);
1098                     break;
1099                 }
1100             } else {
1101                 att_tree = proto_tree_add_expert_format(att_all_tree, pinfo, &ei_stun_unknown_attribute, tvb,
1102                                                         offset, 2, "Unknown attribute 0x%04x", att_type);
1103             }
1104             offset += 2;
1105 
1106             proto_tree_add_uint(att_tree, hf_stun_att_length, tvb,
1107                                 offset, 2, att_length);
1108             offset += 2;
1109 
1110             /* Zero out address */
1111             clear_address(&addr);
1112 
1113             switch (att_type_display) {
1114 
1115                 /* Deprecated STUN RFC3489 attributes */
1116             case RESPONSE_ADDRESS:
1117             case SOURCE_ADDRESS:
1118             case CHANGED_ADDRESS:
1119             case REFLECTED_FROM:
1120             case DESTINATION_ADDRESS:
1121                 if (att_length < 1)
1122                     break;
1123                 proto_tree_add_item(att_tree, hf_stun_att_reserved, tvb, offset, 1, ENC_NA);
1124                 if (att_length < 2)
1125                     break;
1126                 proto_tree_add_item(att_tree, hf_stun_att_family, tvb, offset+1, 1, ENC_BIG_ENDIAN);
1127                 if (att_length < 4)
1128                     break;
1129                 proto_tree_add_item(att_tree, hf_stun_att_port, tvb, offset+2, 2, ENC_BIG_ENDIAN);
1130                 switch (tvb_get_guint8(tvb, offset+1))
1131                 {
1132                 case 1:
1133                     if (att_length < 8)
1134                         break;
1135                     proto_tree_add_item(att_tree, hf_stun_att_ipv4, tvb, offset+4, 4, ENC_BIG_ENDIAN);
1136                     proto_item_append_text(att_tree, " (Deprecated): %s:%d", tvb_ip_to_str(pinfo->pool, tvb, offset+4),tvb_get_ntohs(tvb,offset+2));
1137 
1138                     break;
1139 
1140                 case 2:
1141                     if (att_length < 20)
1142                         break;
1143                     proto_tree_add_item(att_tree, hf_stun_att_ipv6, tvb, offset+4, 16, ENC_NA);
1144                     break;
1145                 }
1146                 break;
1147 
1148                 /* Deprecated STUN RFC3489 attributes */
1149             case PASSWORD:
1150                 {
1151                 proto_tree_add_item(att_tree, hf_stun_att_password, tvb, offset, att_length, ENC_NA);
1152                 }
1153                 break;
1154 
1155             case MAPPED_ADDRESS:
1156             case ALTERNATE_SERVER:
1157             case RESPONSE_ORIGIN:
1158             case OTHER_ADDRESS:
1159             case MS_ALT_MAPPED_ADDRESS:
1160             case MS_ALTERNATE_SERVER:
1161             {
1162                 const gchar       *addr_str = NULL;
1163                 guint16            att_port;
1164 
1165                 if (att_length < 1)
1166                     break;
1167                 proto_tree_add_item(att_tree, hf_stun_att_reserved, tvb, offset, 1, ENC_NA);
1168                 if (att_length < 2)
1169                     break;
1170                 proto_tree_add_item(att_tree, hf_stun_att_family, tvb, offset+1, 1, ENC_BIG_ENDIAN);
1171                 if (att_length < 4)
1172                     break;
1173                 proto_tree_add_item(att_tree, hf_stun_att_port, tvb, offset+2, 2, ENC_BIG_ENDIAN);
1174                 att_port = tvb_get_ntohs(tvb, offset + 2);
1175 
1176                 switch (tvb_get_guint8(tvb, offset+1)) {
1177                 case 1:
1178                     if (att_length < 8)
1179                         break;
1180                     addr_str = tvb_ip_to_str(pinfo->pool, tvb, offset + 4);
1181                     proto_tree_add_item(att_tree, hf_stun_att_ipv4, tvb, offset+4, 4, ENC_BIG_ENDIAN);
1182                     break;
1183 
1184                 case 2:
1185                     if (att_length < 20)
1186                         break;
1187                     addr_str = tvb_ip6_to_str(pinfo->pool, tvb, offset + 4);
1188                     proto_tree_add_item(att_tree, hf_stun_att_ipv6, tvb, offset+4, 16, ENC_NA);
1189                     break;
1190                 }
1191 
1192                 if (addr_str != NULL) {
1193                     proto_item_append_text(att_tree, ": %s:%d", addr_str, att_port);
1194                     col_append_fstr(pinfo->cinfo, COL_INFO, " %s: %s:%d",
1195                                     attribute_name_str, addr_str, att_port);
1196                 }
1197 
1198                 break;
1199             }
1200             case CHANGE_REQUEST:
1201                 if (att_length < 4)
1202                     break;
1203                 proto_tree_add_item(att_tree, hf_stun_att_change_ip, tvb, offset, 4, ENC_BIG_ENDIAN);
1204                 proto_tree_add_item(att_tree, hf_stun_att_change_port, tvb, offset, 4, ENC_BIG_ENDIAN);
1205                 break;
1206 
1207             case USERNAME:
1208             {
1209                 if (network_version >  NET_VER_3489) {
1210                     const guint8 *user_name_str;
1211 
1212                     proto_tree_add_item_ret_string(att_tree, hf_stun_att_username, tvb, offset, att_length, ENC_UTF_8|ENC_NA, pinfo->pool, &user_name_str);
1213                     proto_item_append_text(att_tree, ": %s", user_name_str);
1214                     col_append_fstr( pinfo->cinfo, COL_INFO, " user: %s", user_name_str);
1215                 } else {
1216                     proto_tree_add_item(att_tree, hf_stun_att_username_opaque, tvb, offset, att_length, ENC_NA);
1217                 }
1218                 break;
1219             }
1220             case MESSAGE_INTEGRITY:
1221                 if (att_length < 20)
1222                     break;
1223                 proto_tree_add_item(att_tree, hf_stun_att_hmac, tvb, offset, att_length, ENC_NA);
1224                 break;
1225 
1226             case ERROR_CODE:
1227                 if (att_length < 2)
1228                     break;
1229                 proto_tree_add_item(att_tree, hf_stun_att_reserved, tvb, offset, 2, ENC_NA);
1230                 if (att_length < 3)
1231                     break;
1232                 proto_tree_add_item(att_tree, hf_stun_att_error_class, tvb, offset+2, 1, ENC_BIG_ENDIAN);
1233                 if (att_length < 4)
1234                     break;
1235                 proto_tree_add_item(att_tree, hf_stun_att_error_number, tvb, offset+3, 1, ENC_BIG_ENDIAN);
1236                 {
1237                     int           human_error_num = tvb_get_guint8(tvb, offset+2) * 100 + tvb_get_guint8(tvb, offset+3);
1238                     const gchar  *error_str = val_to_str_ext_const(human_error_num, &error_code_ext, "*Unknown error code*");
1239                     proto_item_append_text(
1240                         att_tree,
1241                         " %d (%s)",
1242                         human_error_num, /* human readable error code */
1243                         error_str
1244                         );
1245                     col_append_fstr(
1246                         pinfo->cinfo, COL_INFO,
1247                         " error-code: %d (%s)",
1248                         human_error_num,
1249                         error_str
1250                         );
1251                 }
1252                 if (att_length < 5)
1253                     break;
1254                 {
1255                 const guint8 *error_reas_str;
1256                 proto_tree_add_item_ret_string(att_tree, hf_stun_att_error_reason, tvb, offset + 4, att_length - 4, ENC_UTF_8 | ENC_NA, pinfo->pool, &error_reas_str);
1257 
1258                 proto_item_append_text(att_tree, ": %s", error_reas_str);
1259                 col_append_fstr(pinfo->cinfo, COL_INFO, " %s", error_reas_str);
1260                 }
1261                 break;
1262 
1263             case UNKNOWN_ATTRIBUTES:
1264                 for (i = 0; i < att_length; i += 2)
1265                     proto_tree_add_item(att_tree, hf_stun_att_unknown, tvb, offset+i, 2, ENC_BIG_ENDIAN);
1266                 break;
1267 
1268             case REALM:
1269             {
1270                 const guint8 *realm_str;
1271                 proto_tree_add_item_ret_string(att_tree, hf_stun_att_realm, tvb, offset, att_length, ENC_UTF_8|ENC_NA, pinfo->pool, &realm_str);
1272                 proto_item_append_text(att_tree, ": %s", realm_str);
1273                 col_append_fstr(pinfo->cinfo, COL_INFO, " realm: %s", realm_str);
1274                 break;
1275             }
1276             case NONCE:
1277             {
1278                 const guint8 *nonce_str;
1279                 proto_tree_add_item_ret_string(att_tree, hf_stun_att_nonce, tvb, offset, att_length, ENC_UTF_8|ENC_NA, pinfo->pool, &nonce_str);
1280                 proto_item_append_text(att_tree, ": %s", nonce_str);
1281                 col_append_str(pinfo->cinfo, COL_INFO, " with nonce");
1282                 break;
1283             }
1284             case PASSWORD_ALGORITHM:
1285             case PASSWORD_ALGORITHMS:
1286             {
1287                 guint alg, alg_param_len, alg_param_len_pad;
1288                 guint remaining = att_length;
1289                 while (remaining > 0) {
1290                    guint loopoffset = offset + att_length - remaining;
1291                    if (remaining < 4) {
1292                        proto_tree_add_expert_format(att_tree, pinfo, &ei_stun_short_packet, tvb,
1293                            loopoffset, remaining, "Too few bytes left for TLV header (%d < 4)", remaining);
1294                        break;
1295                    }
1296                    proto_tree_add_item_ret_uint(att_tree, hf_stun_att_pw_alg, tvb, loopoffset, 2, ENC_BIG_ENDIAN, &alg);
1297                    proto_tree_add_item_ret_uint(att_tree, hf_stun_att_pw_alg_param_len, tvb, loopoffset+2, 2, ENC_BIG_ENDIAN, &alg_param_len);
1298                    if (alg_param_len > 0) {
1299                        if (alg_param_len+4 >= remaining)
1300                            proto_tree_add_item(att_tree, hf_stun_att_pw_alg_param_data, tvb, loopoffset+4, alg_param_len, ENC_NA);
1301                        else {
1302                            proto_tree_add_expert_format(att_tree, pinfo, &ei_stun_short_packet, tvb,
1303                                 loopoffset, remaining, "Too few bytes left for parameter data (%u < %u)", remaining-4, alg_param_len);
1304                            break;
1305                        }
1306                    }
1307                    /* Hopefully, in case MS-TURN ever gets PASSWORD-ALGORITHM(S) support they will add it with padding */
1308                    alg_param_len_pad = WS_ROUNDUP_4(alg_param_len);
1309 
1310                    if (alg_param_len < alg_param_len_pad)
1311                        proto_tree_add_uint(att_tree, hf_stun_att_padding, tvb, loopoffset+alg_param_len, alg_param_len_pad-alg_param_len, alg_param_len_pad-alg_param_len);
1312                    remaining -= (alg_param_len_pad + 4);
1313                    if ((att_type_display == PASSWORD_ALGORITHM) && (remaining > 0)) {
1314                        proto_tree_add_expert_format(att_tree, pinfo, &ei_stun_long_attribute, tvb,
1315                            loopoffset, remaining, " (PASSWORD-ALGORITHM)");
1316                        /* Continue anyway */
1317                    }
1318                 }
1319                 break;
1320             }
1321             case XOR_PEER_ADDRESS:
1322             case XOR_RELAYED_ADDRESS:
1323                 found_turn_attributes = TRUE;
1324                 /* Fallthrough */
1325             case XOR_MAPPED_ADDRESS:
1326             case XOR_RESPONSE_TARGET:
1327             case XOR_REFLECTED_FROM:
1328             case MS_XOR_MAPPED_ADDRESS:
1329             case REMOTE_SITE_ADDR:
1330             case REMOTE_RELAY_SITE:
1331             case LOCAL_SITE_ADDR:
1332             case LOCAL_RELAY_SITE:
1333                 if (att_length < 1)
1334                     break;
1335                 proto_tree_add_item(att_tree, hf_stun_att_reserved, tvb, offset, 1, ENC_NA);
1336                 if (att_length < 2)
1337                     break;
1338                 proto_tree_add_item(att_tree, hf_stun_att_family, tvb, offset+1, 1, ENC_BIG_ENDIAN);
1339                 if (att_length < 4)
1340                     break;
1341                 proto_tree_add_item(att_tree, hf_stun_att_xor_port, tvb, offset+2, 2, ENC_NA);
1342 
1343                 /* Show the port 'in the clear'
1344                    XOR (host order) transid with (host order) xor-port.
1345                    Add host-order port into tree. */
1346                 clear_port = tvb_get_ntohs(tvb, offset+2) ^ (magic_cookie_first_word >> 16);
1347                 ti = proto_tree_add_uint(att_tree, hf_stun_att_port, tvb, offset+2, 2, clear_port);
1348                 proto_item_set_generated(ti);
1349 
1350                 if (att_length < 8)
1351                     break;
1352 
1353                 switch (tvb_get_guint8(tvb, offset+1)) {
1354                 case 1:
1355                     proto_tree_add_item(att_tree, hf_stun_att_xor_ipv4, tvb, offset+4, 4, ENC_NA);
1356 
1357                     /* Show the address 'in the clear'.
1358                        XOR (host order) transid with (host order) xor-address.
1359                        Add in network order tree. */
1360                     clear_ip[0] = tvb_get_ipv4(tvb, offset+4) ^ g_htonl(magic_cookie_first_word);
1361                     ti = proto_tree_add_ipv4(att_tree, hf_stun_att_ipv4, tvb, offset+4, 4, clear_ip[0]);
1362                     proto_item_set_generated(ti);
1363 
1364                     set_address(&addr, AT_IPv4, 4, clear_ip);
1365                     break;
1366 
1367                 case 2:
1368                     if (att_length < 20)
1369                         break;
1370 
1371                     proto_tree_add_item(att_tree, hf_stun_att_xor_ipv6, tvb, offset+4, 16, ENC_NA);
1372 
1373                     tvb_get_ipv6(tvb, offset+4, (ws_in6_addr *)clear_ip);
1374                     clear_ip[0] ^= g_htonl(magic_cookie_first_word);
1375                     clear_ip[1] ^= g_htonl(transaction_id[0]);
1376                     clear_ip[2] ^= g_htonl(transaction_id[1]);
1377                     clear_ip[3] ^= g_htonl(transaction_id[2]);
1378                     ti = proto_tree_add_ipv6(att_tree, hf_stun_att_ipv6, tvb, offset+4, 16,
1379                                              (const ws_in6_addr *)clear_ip);
1380                     proto_item_set_generated(ti);
1381 
1382                     set_address(&addr, AT_IPv6, 16, &clear_ip);
1383                     break;
1384 
1385                 default:
1386                     clear_address(&addr);
1387                     break;
1388                 }
1389 
1390                 if (addr.type != AT_NONE) {
1391                     const gchar *ipstr = address_to_str(pinfo->pool, &addr);
1392                     proto_item_append_text(att_tree, ": %s:%d", ipstr, clear_port);
1393                     col_append_fstr(pinfo->cinfo, COL_INFO, " %s: %s:%d",
1394                                     attribute_name_str, ipstr, clear_port);
1395                 }
1396 
1397                 break;
1398 
1399             case REQUESTED_ADDRESS_FAMILY:
1400                 if (att_length < 1)
1401                     break;
1402                 proto_tree_add_item(att_tree, hf_stun_att_family, tvb, offset, 1, ENC_BIG_ENDIAN);
1403                 if (att_length < 4)
1404                     break;
1405                 proto_tree_add_item(att_tree, hf_stun_att_reserved, tvb, offset+1, 3, ENC_NA);
1406                 break;
1407             case EVEN_PORT:
1408                 if (att_length < 1)
1409                     break;
1410                 proto_tree_add_item(att_tree, hf_stun_att_reserve_next, tvb, offset, 1, ENC_BIG_ENDIAN);
1411                 found_turn_attributes = TRUE;
1412                 break;
1413 
1414             case RESERVATION_TOKEN:
1415                 if (att_length < 8)
1416                     break;
1417                 proto_tree_add_item(att_tree, hf_stun_att_token, tvb, offset, 8, ENC_NA);
1418                 found_turn_attributes = TRUE;
1419                 break;
1420 
1421             case PRIORITY:
1422                 if (att_length < 4)
1423                     break;
1424                 proto_tree_add_item(att_tree, hf_stun_att_priority, tvb, offset, 4, ENC_BIG_ENDIAN);
1425                 break;
1426 
1427             case PADDING:
1428                 proto_tree_add_uint(att_tree, hf_stun_att_padding, tvb, offset, att_length, att_length);
1429                 break;
1430 
1431             case LEGACY_ICMP:
1432             case ICMP:
1433                 if (att_length < 4)
1434                     break;
1435                 proto_tree_add_item(att_tree, hf_stun_att_icmp_type, tvb, offset, 1, ENC_BIG_ENDIAN);
1436                 proto_tree_add_item(att_tree, hf_stun_att_icmp_code, tvb, offset+1, 1, ENC_BIG_ENDIAN);
1437                 break;
1438 
1439             case MS_TURN_UNKNOWN_8006:
1440                 proto_tree_add_item(att_tree, hf_stun_att_ms_turn_unknown_8006, tvb, offset, att_length, ENC_NA);
1441                 break;
1442 
1443             case SOFTWARE:
1444                 proto_tree_add_item(att_tree, hf_stun_att_software, tvb, offset, att_length, ENC_UTF_8|ENC_NA);
1445                 break;
1446 
1447             case CACHE_TIMEOUT:
1448                 if (att_length < 4)
1449                     break;
1450                 proto_tree_add_item(att_tree, hf_stun_att_cache_timeout, tvb, offset, 4, ENC_BIG_ENDIAN);
1451                 break;
1452 
1453             case FINGERPRINT:
1454                 if (att_length < 4)
1455                     break;
1456                 proto_tree_add_item(att_tree, hf_stun_att_crc32, tvb, offset, att_length, ENC_BIG_ENDIAN);
1457                 break;
1458 
1459             case ICE_CONTROLLED:
1460             case ICE_CONTROLLING:
1461                 if (att_length < 8)
1462                     break;
1463                 proto_tree_add_item(att_tree, hf_stun_att_tie_breaker, tvb, offset, 8, ENC_NA);
1464                 break;
1465 
1466             case DATA:
1467                 if (att_length > 0) {
1468                     tvbuff_t *next_tvb;
1469                     proto_tree_add_item(att_tree, hf_stun_att_value, tvb, offset, att_length, ENC_NA);
1470 
1471                     next_tvb = tvb_new_subset_length(tvb, offset, att_length);
1472 
1473                     if (!dissector_try_heuristic(heur_subdissector_list, next_tvb, pinfo, att_tree, &hdtbl_entry, NULL)) {
1474                         call_dissector_only(data_handle, next_tvb, pinfo, att_tree, NULL);
1475                     }
1476 
1477                 }
1478                 found_turn_attributes = TRUE;
1479                 break;
1480 
1481             case REQUESTED_TRANSPORT:
1482                 if (att_length < 1)
1483                     break;
1484                 proto_tree_add_item(att_tree, hf_stun_att_transp, tvb, offset, 1, ENC_BIG_ENDIAN);
1485                 if (att_length < 4)
1486                     break;
1487 
1488                 {
1489                     guint8  protoCode = tvb_get_guint8(tvb, offset);
1490                     const gchar *protoCode_str = val_to_str(protoCode, transportnames, "Unknown (0x%8x)");
1491 
1492                     proto_item_append_text(att_tree, ": %s", protoCode_str);
1493                     col_append_fstr(
1494                         pinfo->cinfo, COL_INFO,
1495                         " %s",
1496                         protoCode_str
1497                         );
1498                 }
1499                 proto_tree_add_item(att_tree, hf_stun_att_reserved, tvb, offset+1, 3, ENC_NA);
1500                 found_turn_attributes = TRUE;
1501                 break;
1502 
1503             case CHANNEL_NUMBER:
1504                 if (att_length < 4)
1505                     break;
1506                 proto_tree_add_item(att_tree, hf_stun_att_channelnum, tvb, offset, 2, ENC_BIG_ENDIAN);
1507                 {
1508                     guint16 chan = tvb_get_ntohs(tvb, offset);
1509                     proto_item_append_text(att_tree, ": 0x%x", chan);
1510                     col_append_fstr(
1511                         pinfo->cinfo, COL_INFO,
1512                         " ChannelNumber=0x%x",
1513                         chan
1514                         );
1515                 }
1516                 proto_tree_add_item(att_tree, hf_stun_att_reserved, tvb, offset+2, 2, ENC_NA);
1517                 found_turn_attributes = TRUE;
1518                 break;
1519 
1520             case MAGIC_COOKIE:
1521                 if (att_length < 4)
1522                     break;
1523                 proto_tree_add_item(att_tree, hf_stun_att_magic_cookie, tvb, offset, 4, ENC_BIG_ENDIAN);
1524                 break;
1525 
1526             case BANDWIDTH:
1527                 if (att_length < 4)
1528                     break;
1529                 proto_tree_add_item(att_tree, hf_stun_att_bandwidth, tvb, offset, 4, ENC_BIG_ENDIAN);
1530                 proto_item_append_text(att_tree, " %d", tvb_get_ntohl(tvb, offset));
1531                 col_append_fstr(
1532                     pinfo->cinfo, COL_INFO,
1533                     " bandwidth: %d",
1534                     tvb_get_ntohl(tvb, offset)
1535                     );
1536                 found_turn_attributes = TRUE;
1537                 break;
1538             case LIFETIME:
1539                 if (att_length < 4)
1540                     break;
1541                 proto_tree_add_item(att_tree, hf_stun_att_lifetime, tvb, offset, 4, ENC_BIG_ENDIAN);
1542                 proto_item_append_text(att_tree, " %d", tvb_get_ntohl(tvb, offset));
1543                 col_append_fstr(
1544                     pinfo->cinfo, COL_INFO,
1545                     " lifetime: %d",
1546                     tvb_get_ntohl(tvb, offset)
1547                     );
1548                 found_turn_attributes = TRUE;
1549                 break;
1550 
1551             case MS_VERSION:
1552             case MS_IMPLEMENTATION_VER:
1553                 proto_tree_add_item(att_tree, hf_stun_att_ms_version, tvb, offset, 4, ENC_BIG_ENDIAN);
1554                 proto_item_append_text(att_tree, ": %s", val_to_str(tvb_get_ntohl(tvb, offset), ms_version_vals, "Unknown (0x%u)"));
1555                 break;
1556             case MS_SEQUENCE_NUMBER:
1557                 proto_tree_add_item(att_tree, hf_stun_att_ms_connection_id, tvb, offset, 20, ENC_NA);
1558                 proto_tree_add_item(att_tree, hf_stun_att_ms_sequence_number, tvb, offset+20, 4, ENC_BIG_ENDIAN);
1559                 break;
1560             case MS_SERVICE_QUALITY:
1561                 proto_tree_add_item(att_tree, hf_stun_att_ms_stream_type, tvb, offset, 2, ENC_BIG_ENDIAN);
1562                 proto_tree_add_item(att_tree, hf_stun_att_ms_service_quality, tvb, offset+2, 2, ENC_BIG_ENDIAN);
1563                 break;
1564             case BANDWIDTH_ACM:
1565                 proto_tree_add_item(att_tree, hf_stun_att_reserved, tvb, offset, 2, ENC_NA);
1566                 proto_tree_add_item(att_tree, hf_stun_att_bandwidth_acm_type, tvb, offset+2, 2, ENC_BIG_ENDIAN);
1567                 break;
1568             case BANDWIDTH_RSV_ID:
1569                 proto_tree_add_item(att_tree, hf_stun_att_bandwidth_rsv_id, tvb, offset, 16, ENC_NA);
1570                 break;
1571             case BANDWIDTH_RSV_AMOUNT:
1572                 proto_tree_add_item(att_tree, hf_stun_att_bandwidth_rsv_amount_masb, tvb, offset, 4, ENC_BIG_ENDIAN);
1573                 proto_tree_add_item(att_tree, hf_stun_att_bandwidth_rsv_amount_misb, tvb, offset+4, 4, ENC_BIG_ENDIAN);
1574                 proto_tree_add_item(att_tree, hf_stun_att_bandwidth_rsv_amount_marb, tvb, offset+8, 4, ENC_BIG_ENDIAN);
1575                 proto_tree_add_item(att_tree, hf_stun_att_bandwidth_rsv_amount_mirb, tvb, offset+12, 4, ENC_BIG_ENDIAN);
1576                 break;
1577             case REMOTE_SITE_ADDR_RP:
1578             case LOCAL_SITE_ADDR_RP:
1579                 proto_tree_add_item(att_tree, hf_stun_att_address_rp_a, tvb, offset, 4, ENC_BIG_ENDIAN);
1580                 proto_tree_add_item(att_tree, hf_stun_att_address_rp_b, tvb, offset, 4, ENC_BIG_ENDIAN);
1581                 proto_tree_add_item(att_tree, hf_stun_att_address_rp_rsv1, tvb, offset, 4, ENC_BIG_ENDIAN);
1582                 proto_tree_add_item(att_tree, hf_stun_att_address_rp_masb, tvb, offset+4, 4, ENC_BIG_ENDIAN);
1583                 proto_tree_add_item(att_tree, hf_stun_att_address_rp_marb, tvb, offset+8, 4, ENC_BIG_ENDIAN);
1584                 break;
1585             case REMOTE_RELAY_SITE_RP:
1586             case LOCAL_RELAY_SITE_RP:
1587                 proto_tree_add_item(att_tree, hf_stun_att_address_rp_a, tvb, offset, 4, ENC_BIG_ENDIAN);
1588                 proto_tree_add_item(att_tree, hf_stun_att_address_rp_rsv2, tvb, offset, 4, ENC_BIG_ENDIAN);
1589                 proto_tree_add_item(att_tree, hf_stun_att_address_rp_masb, tvb, offset+4, 4, ENC_BIG_ENDIAN);
1590                 proto_tree_add_item(att_tree, hf_stun_att_address_rp_marb, tvb, offset+8, 4, ENC_BIG_ENDIAN);
1591                 break;
1592             case SIP_DIALOG_ID:
1593                 proto_tree_add_item(att_tree, hf_stun_att_sip_dialog_id, tvb, offset, att_length, ENC_NA);
1594                 break;
1595             case SIP_CALL_ID:
1596                 proto_tree_add_item(att_tree, hf_stun_att_sip_call_id, tvb, offset, att_length, ENC_NA);
1597                 break;
1598             case LOCATION_PROFILE:
1599                 proto_tree_add_item(att_tree, hf_stun_att_lp_peer_location, tvb, offset, 1, ENC_BIG_ENDIAN);
1600                 proto_tree_add_item(att_tree, hf_stun_att_lp_self_location, tvb, offset+1, 1, ENC_BIG_ENDIAN);
1601                 proto_tree_add_item(att_tree, hf_stun_att_lp_federation, tvb, offset+2, 1, ENC_BIG_ENDIAN);
1602                 proto_tree_add_item(att_tree, hf_stun_att_reserved, tvb, offset+3, 1, ENC_NA);
1603                 break;
1604             case MS_CANDIDATE_IDENTIFIER:
1605                 proto_tree_add_item(att_tree, hf_stun_att_ms_foundation, tvb, offset, 4, ENC_ASCII|ENC_NA);
1606                 break;
1607             case MS_MULTIPLEXED_TURN_SESSION_ID:
1608                 proto_tree_add_item(att_tree, hf_stun_att_ms_multiplexed_turn_session_id, tvb, offset, 8, ENC_NA);
1609                 /* Trick to force decoding of MS-TURN Multiplexed TURN channels */
1610                 found_turn_attributes = TRUE;
1611                 break;
1612 
1613             case GOOG_NETWORK_INFO:
1614                 proto_tree_add_item(att_tree, hf_stun_att_google_network_id, tvb, offset, 2, ENC_BIG_ENDIAN);
1615                 proto_tree_add_item(att_tree, hf_stun_att_google_network_cost, tvb, offset + 2, 2, ENC_BIG_ENDIAN);
1616                 break;
1617 
1618             default:
1619                 if (att_length > 0)
1620                     proto_tree_add_item(att_tree, hf_stun_att_value, tvb, offset, att_length, ENC_NA);
1621                 break;
1622             }
1623 
1624             if ((network_version >= NET_VER_5389) && (att_length < att_length_pad))
1625                 proto_tree_add_uint(att_tree, hf_stun_att_padding, tvb, offset+att_length, att_length_pad-att_length, att_length_pad-att_length);
1626             offset += att_length_pad;
1627         }
1628     }
1629 
1630     if (found_turn_attributes) {
1631         /* At least one STUN/TURN implementation (Facetime) uses unknown/custom
1632          * TURN methods to setup a Channel Data, so the previous check to set
1633          * "is_turn" variable fails. Fortunately, standard TURN attributes are still
1634          * used in the replies */
1635         is_turn = TRUE;
1636     }
1637     if (heur_check && is_turn && conversation) {
1638         /*
1639          * When in heuristic dissector mode, if this is a TURN message, set
1640          * the 5-tuple conversation to always decode as non-heuristic. The
1641          * odds of incorrectly identifying a random packet as a TURN message
1642          * (other than ChannelData) is incredibly small. A ChannelData message
1643          * won't be matched when in heuristic mode, so heur_check can't be true
1644          * in that case and get to this part of the code.
1645          */
1646         if (pinfo->ptype == PT_TCP) {
1647             conversation_set_dissector(conversation, stun_tcp_handle);
1648         } else if (pinfo->ptype == PT_UDP) {
1649             conversation_set_dissector(conversation, stun_udp_handle);
1650         }
1651     }
1652 
1653     if (!PINFO_FD_VISITED(pinfo) && is_turn && (pinfo->ptype == PT_TCP)
1654         && (msg_type_method == CONNECTION_BIND) && (msg_type_class == SUCCESS_RESPONSE)) {
1655         /* RFC 6062: after the ConnectionBind exchange, the connection is no longer framed as TURN;
1656            instead, it is an unframed pass-through.
1657            Starting from next frame set conversation dissector to data */
1658         conversation_set_dissector_from_frame_number(conversation, pinfo->num+1, data_handle);
1659     }
1660     return reported_length;
1661 }
1662 
1663 static int
dissect_stun_udp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1664 dissect_stun_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1665 {
1666     return dissect_stun_message(tvb, pinfo, tree, FALSE, TRUE);
1667 }
1668 
1669 static int
dissect_stun_tcp_pdu(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1670 dissect_stun_tcp_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1671 {
1672     return dissect_stun_message(tvb, pinfo, tree, FALSE, FALSE);
1673 }
1674 
1675 static int
dissect_stun_tcp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)1676 dissect_stun_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data)
1677 {
1678     tcp_dissect_pdus(tvb, pinfo, tree, TRUE, MIN_HDR_LEN,
1679         get_stun_message_len, dissect_stun_tcp_pdu, data);
1680     return tvb_reported_length(tvb);
1681 }
1682 
1683 static gboolean
dissect_stun_heur_tcp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data)1684 dissect_stun_heur_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
1685 {
1686     conversation_t *conversation;
1687     guint captured_length;
1688     guint16 msg_type;
1689     guint msg_length;
1690     guint tcp_framing_offset;
1691     guint reported_length;
1692 
1693     /* There might be multiple STUN messages in a TCP payload: try finding a valid
1694        message and then switch to non-heuristic TCP dissector which will handle
1695        multiple messages and reassembler stuff correctly */
1696 
1697     captured_length = tvb_captured_length(tvb);
1698     if (captured_length < MIN_HDR_LEN)
1699         return FALSE;
1700     reported_length = tvb_reported_length(tvb);
1701 
1702     tcp_framing_offset = 0;
1703     if ((captured_length >= TCP_FRAME_COOKIE_LEN) &&
1704         (tvb_get_ntohl(tvb, 6) == MESSAGE_COOKIE)) {
1705         /*
1706          * The magic cookie is off by two, so this appears to be
1707          * RFC 4571 framing, as per RFC 6544; the STUN/TURN
1708          * ChannelData header begins after the 2-octet
1709          * RFC 4571 length field.
1710          */
1711         tcp_framing_offset = 2;
1712     }
1713 
1714     msg_type = tvb_get_ntohs(tvb, tcp_framing_offset + 0);
1715     msg_length = tvb_get_ntohs(tvb, tcp_framing_offset + 2);
1716 
1717     /* TURN ChannelData message ? */
1718     if (msg_type & 0xC000) {
1719         /* We don't want to handle TURN ChannelData message in heuristic function
1720            See comment in dissect_stun_message() */
1721         return FALSE;
1722     }
1723 
1724     /* Normal STUN message */
1725     if (captured_length < STUN_HDR_LEN)
1726         return FALSE;
1727 
1728     /* Check if it is really a STUN message */
1729     if (tvb_get_ntohl(tvb, tcp_framing_offset + 4) != MESSAGE_COOKIE)
1730         return FALSE;
1731 
1732     /* We may have more than one STUN message in the TCP payload */
1733     if (reported_length < (msg_length + STUN_HDR_LEN + tcp_framing_offset))
1734         return FALSE;
1735 
1736     conversation = find_or_create_conversation(pinfo);
1737     conversation_set_dissector(conversation, stun_tcp_handle);
1738 
1739     dissect_stun_tcp(tvb, pinfo, tree, data);
1740     return TRUE;
1741 }
1742 static gboolean
dissect_stun_heur_udp(tvbuff_t * tvb,packet_info * pinfo,proto_tree * tree,void * data _U_)1743 dissect_stun_heur_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1744 {
1745     if (dissect_stun_message(tvb, pinfo, tree, TRUE, TRUE) == 0)
1746         return FALSE;
1747     return TRUE;
1748 }
1749 
1750 void
proto_register_stun(void)1751 proto_register_stun(void)
1752 {
1753     static hf_register_info hf[] = {
1754 
1755         { &hf_stun_channel,
1756           { "Channel Number", "stun.channel", FT_UINT16,
1757             BASE_HEX, NULL,  0x0, NULL, HFILL }
1758         },
1759 
1760         /* ////////////////////////////////////// */
1761         { &hf_stun_tcp_frame_length,
1762           { "TCP Frame Length", "stun.tcp_frame_length", FT_UINT16,
1763             BASE_DEC, NULL, 0x0, NULL, HFILL }
1764         },
1765         { &hf_stun_type,
1766           { "Message Type", "stun.type", FT_UINT16,
1767             BASE_HEX, NULL,0, NULL, HFILL }
1768         },
1769         { &hf_stun_type_class,
1770           { "Message Class", "stun.type.class", FT_UINT16,
1771             BASE_HEX, NULL, 0x0110, NULL, HFILL }
1772         },
1773         { &hf_stun_type_method,
1774           { "Message Method", "stun.type.method", FT_UINT16,
1775             BASE_HEX, NULL, 0x3EEF, NULL, HFILL }
1776         },
1777         { &hf_stun_type_method_assignment,
1778           { "Message Method Assignment", "stun.type.method-assignment", FT_UINT16,
1779             BASE_HEX, VALS(assignments), 0x2000, NULL, HFILL }
1780         },
1781         { &hf_stun_length,
1782           { "Message Length", "stun.length", FT_UINT16,
1783             BASE_DEC, NULL, 0x0, "Payload (attributes) length", HFILL }
1784         },
1785         { &hf_stun_cookie,
1786           { "Message Cookie", "stun.cookie", FT_BYTES,
1787             BASE_NONE, NULL, 0x0, NULL, HFILL }
1788         },
1789         { &hf_stun_id,
1790           { "Message Transaction ID", "stun.id", FT_BYTES,
1791             BASE_NONE, NULL, 0x0, NULL, HFILL }
1792         },
1793         { &hf_stun_attributes,
1794           { "Attributes", "stun.attributes", FT_NONE,
1795             BASE_NONE, NULL,  0x0, NULL, HFILL }
1796         },
1797         { &hf_stun_attr,
1798           { "Attribute Type", "stun.attribute", FT_UINT16,
1799             BASE_HEX, NULL, 0, NULL, HFILL }
1800         },
1801         { &hf_stun_response_in,
1802           { "Response In", "stun.response-in", FT_FRAMENUM,
1803             BASE_NONE, NULL, 0x0, "The response to this STUN query is in this frame", HFILL }
1804         },
1805         { &hf_stun_response_to,
1806           { "Request In", "stun.response-to", FT_FRAMENUM,
1807             BASE_NONE, NULL, 0x0, "This is a response to the STUN Request in this frame", HFILL }
1808         },
1809         { &hf_stun_time,
1810           { "Time", "stun.time", FT_RELATIVE_TIME,
1811             BASE_NONE, NULL, 0x0, "The time between the Request and the Response", HFILL }
1812         },
1813         { &hf_stun_duplicate,
1814           { "Duplicated original message in", "stun.reqduplicate", FT_FRAMENUM,
1815             BASE_NONE, NULL, 0x0, "This is a duplicate of STUN message in this frame", HFILL }
1816         },
1817         /* ////////////////////////////////////// */
1818         { &hf_stun_att_type,
1819           { "Attribute Type", "stun.att.type", FT_UINT16,
1820             BASE_HEX, NULL, 0x0, NULL, HFILL }
1821         },
1822         { &hf_stun_att_type_comprehension,
1823           { "Attribute Type Comprehension", "stun.att.type.comprehension", FT_UINT16,
1824             BASE_HEX, VALS(comprehensions), 0x8000, NULL, HFILL }
1825         },
1826         { &hf_stun_att_type_assignment,
1827           { "Attribute Type Assignment", "stun.att.type.assignment", FT_UINT16,
1828             BASE_HEX, VALS(assignments), 0x4000, NULL, HFILL }
1829         },
1830         { &hf_stun_att_length,
1831           { "Attribute Length", "stun.att.length", FT_UINT16,
1832             BASE_DEC, NULL, 0x0, NULL, HFILL }
1833         },
1834         { &hf_stun_att_family,
1835           { "Protocol Family", "stun.att.family", FT_UINT8,
1836             BASE_HEX, VALS(attributes_family), 0x0, NULL, HFILL }
1837         },
1838         { &hf_stun_att_ipv4,
1839           { "IP", "stun.att.ipv4", FT_IPv4,
1840             BASE_NONE, NULL, 0x0, NULL, HFILL }
1841         },
1842         { &hf_stun_att_ipv6,
1843           { "IP", "stun.att.ipv6", FT_IPv6,
1844             BASE_NONE, NULL, 0x0, NULL, HFILL }
1845         },
1846         { &hf_stun_att_port,
1847           { "Port", "stun.att.port", FT_UINT16,
1848             BASE_DEC, NULL, 0x0, NULL, HFILL }
1849         },
1850         { &hf_stun_att_username,
1851           { "Username", "stun.att.username", FT_STRING,
1852             BASE_NONE, NULL, 0x0, NULL, HFILL }
1853         },
1854         { &hf_stun_att_username_opaque,
1855           { "Username", "stun.att.username.opaque", FT_BYTES,
1856             BASE_NONE, NULL, 0x0, NULL, HFILL }
1857         },
1858         { &hf_stun_att_password,
1859           { "Password", "stun.att.password", FT_BYTES,
1860             BASE_NONE, NULL, 0x0, NULL, HFILL }
1861         },
1862         { &hf_stun_att_padding,
1863           { "Padding", "stun.att.padding", FT_UINT16,
1864             BASE_DEC, NULL, 0x0, NULL, HFILL }
1865         },
1866         { &hf_stun_att_hmac,
1867           { "HMAC-SHA1", "stun.att.hmac", FT_BYTES,
1868             BASE_NONE, NULL, 0x0, NULL, HFILL }
1869         },
1870         { &hf_stun_att_crc32,
1871           { "CRC-32", "stun.att.crc32", FT_UINT32,
1872             BASE_HEX, NULL, 0x0, NULL, HFILL }
1873         },
1874         { &hf_stun_att_error_class,
1875           { "Error Class","stun.att.error.class", FT_UINT8,
1876             BASE_DEC, NULL, 0x07, NULL, HFILL}
1877         },
1878         { &hf_stun_att_error_number,
1879           { "Error Code","stun.att.error", FT_UINT8,
1880             BASE_DEC, NULL, 0x0, NULL, HFILL}
1881         },
1882         { &hf_stun_att_error_reason,
1883           { "Error Reason Phrase","stun.att.error.reason", FT_STRING,
1884             BASE_NONE, NULL, 0x0, NULL, HFILL}
1885         },
1886         { &hf_stun_att_realm,
1887           { "Realm", "stun.att.realm", FT_STRING,
1888             BASE_NONE, NULL, 0x0, NULL, HFILL }
1889         },
1890         { &hf_stun_att_nonce,
1891           { "Nonce", "stun.att.nonce", FT_STRING,
1892             BASE_NONE, NULL, 0x0, NULL, HFILL }
1893         },
1894         { &hf_stun_att_unknown,
1895           { "Unknown Attribute","stun.att.unknown", FT_UINT16,
1896             BASE_HEX, NULL, 0x0, NULL, HFILL}
1897         },
1898         { &hf_stun_att_xor_ipv4,
1899           { "IP (XOR-d)", "stun.att.ipv4-xord", FT_BYTES,
1900             BASE_NONE, NULL, 0x0, NULL, HFILL }
1901         },
1902         { &hf_stun_att_xor_ipv6,
1903           { "IP (XOR-d)", "stun.att.ipv6-xord", FT_BYTES,
1904             BASE_NONE, NULL, 0x0, NULL, HFILL }
1905         },
1906         { &hf_stun_att_xor_port,
1907           { "Port (XOR-d)", "stun.att.port-xord", FT_BYTES,
1908             BASE_NONE, NULL, 0x0, NULL, HFILL }
1909         },
1910         { &hf_stun_att_icmp_type,
1911           { "ICMP type", "stun.att.icmp.type", FT_UINT8,
1912             BASE_DEC, NULL, 0x0, NULL, HFILL}
1913          },
1914         { &hf_stun_att_icmp_code,
1915           { "ICMP code", "stun.att.icmp.code", FT_UINT8,
1916             BASE_DEC, NULL, 0x0, NULL, HFILL}
1917          },
1918         { &hf_stun_att_ms_turn_unknown_8006,
1919           { "Unknown8006", "stun.att.unknown8006", FT_BYTES,
1920             BASE_NONE, NULL, 0x0, "MS-TURN Unknown Attribute 0x8006", HFILL }
1921         },
1922         { &hf_stun_att_software,
1923           { "Software","stun.att.software", FT_STRING,
1924             BASE_NONE, NULL, 0x0, NULL, HFILL}
1925         },
1926         { &hf_stun_att_priority,
1927           { "Priority", "stun.att.priority", FT_UINT32,
1928             BASE_DEC, NULL, 0x0, NULL, HFILL}
1929          },
1930         { &hf_stun_att_tie_breaker,
1931           { "Tie breaker", "stun.att.tie-breaker", FT_BYTES,
1932             BASE_NONE, NULL, 0x0, NULL, HFILL }
1933         },
1934         { &hf_stun_att_lifetime,
1935           { "Lifetime", "stun.att.lifetime", FT_UINT32,
1936             BASE_DEC, NULL, 0x0, "Session idle time remaining (seconds)", HFILL}
1937          },
1938         { &hf_stun_att_change_ip,
1939           { "Change IP","stun.att.change-ip", FT_BOOLEAN,
1940             16, TFS(&tfs_set_notset), 0x0004, NULL, HFILL}
1941         },
1942         { &hf_stun_att_change_port,
1943           { "Change Port","stun.att.change-port", FT_BOOLEAN,
1944             16, TFS(&tfs_set_notset), 0x0002, NULL, HFILL}
1945         },
1946         { &hf_stun_att_pw_alg,
1947           { "Password Algorithm", "stun.att.pw_alg", FT_UINT16,
1948             BASE_DEC, VALS(password_algorithm_vals), 0x0, NULL, HFILL }
1949         },
1950         { &hf_stun_att_pw_alg_param_len,
1951           { "Password Algorithm Length", "stun.att.pw_alg_len", FT_UINT16,
1952             BASE_DEC, NULL, 0x0, NULL, HFILL }
1953         },
1954         { &hf_stun_att_pw_alg_param_data,
1955           { "Password Algorithm Data", "stun.att.pw_alg_data", FT_BYTES,
1956             BASE_NONE, NULL, 0x0, NULL, HFILL }
1957         },
1958         { &hf_stun_att_reserve_next,
1959           { "Reserve next","stun.att.even-port.reserve-next", FT_UINT8,
1960             BASE_DEC, VALS(attributes_reserve_next), 0x80, NULL, HFILL}
1961         },
1962         { &hf_stun_att_cache_timeout,
1963           { "Cache timeout", "stun.att.cache-timeout", FT_UINT32,
1964             BASE_DEC, NULL, 0x0, NULL, HFILL}
1965          },
1966         { &hf_stun_att_token,
1967           { "Token", "stun.att.token", FT_BYTES,
1968             BASE_NONE, NULL, 0x0, NULL, HFILL }
1969         },
1970         { &hf_stun_att_value,
1971           { "Value", "stun.value", FT_BYTES,
1972             BASE_NONE, NULL, 0x0, NULL, HFILL }
1973         },
1974         { &hf_stun_att_reserved,
1975           { "Reserved", "stun.att.reserved", FT_BYTES,
1976             BASE_NONE, NULL, 0x0, NULL, HFILL }
1977         },
1978         { &hf_stun_att_transp,
1979           { "Transport", "stun.att.transp", FT_UINT8,
1980             BASE_HEX, VALS(transportnames), 0x0, NULL, HFILL }
1981         },
1982         { &hf_stun_att_channelnum,
1983           { "Channel-Number", "stun.att.channelnum", FT_UINT16,
1984             BASE_HEX, NULL, 0x0, NULL, HFILL }
1985         },
1986         { &hf_stun_att_magic_cookie,
1987           { "Magic Cookie", "stun.att.magic_cookie", FT_UINT32,
1988             BASE_HEX, NULL, 0x0, NULL, HFILL }
1989         },
1990         { &hf_stun_att_bandwidth,
1991           { "Bandwidth", "stun.port.bandwidth", FT_UINT32,
1992             BASE_DEC, NULL, 0x0, "Peak Bandwidth (kBit/s)", HFILL }
1993         },
1994 
1995         { &hf_stun_att_ms_version,
1996           { "MS Version", "stun.att.ms.version", FT_UINT32,
1997             BASE_DEC, VALS(ms_version_vals), 0x0, NULL, HFILL}
1998          },
1999         { &hf_stun_att_ms_connection_id,
2000           { "Connection ID", "stun.att.ms.connection_id", FT_BYTES,
2001             BASE_NONE, NULL, 0x0, NULL, HFILL}
2002          },
2003         { &hf_stun_att_ms_sequence_number,
2004           { "Sequence Number", "stun.att.ms.sequence_number", FT_UINT32,
2005             BASE_DEC, NULL, 0x0, NULL, HFILL}
2006          },
2007         { &hf_stun_att_ms_stream_type,
2008           { "Stream Type", "stun.att.ms.stream_type", FT_UINT16,
2009             BASE_DEC, VALS(ms_stream_type_vals), 0x0, NULL, HFILL}
2010          },
2011         { &hf_stun_att_ms_service_quality,
2012           { "Service Quality", "stun.att.ms.service_quality", FT_UINT16,
2013             BASE_DEC, VALS(ms_service_quality_vals), 0x0, NULL, HFILL}
2014          },
2015          { &hf_stun_att_ms_foundation,
2016            { "Foundation", "stun.att.ms.foundation", FT_STRING,
2017              BASE_NONE, NULL, 0x0, NULL, HFILL}
2018           },
2019         { &hf_stun_att_ms_multiplexed_turn_session_id,
2020           { "MS Multiplexed TURN Session Id", "stun.att.ms.multiplexed_turn_session_id", FT_UINT64,
2021             BASE_HEX, NULL, 0x0, NULL, HFILL}
2022          },
2023         { &hf_stun_att_ms_turn_session_id,
2024           { "MS TURN Session Id", "stun.att.ms.turn_session_id", FT_UINT64,
2025             BASE_HEX, NULL, 0x0, NULL, HFILL}
2026          },
2027         { &hf_stun_att_bandwidth_acm_type,
2028           { "Message Type", "stun.att.bandwidth_acm.type", FT_UINT16,
2029             BASE_DEC, VALS(bandwidth_acm_type_vals), 0x0, NULL, HFILL}
2030          },
2031         { &hf_stun_att_bandwidth_rsv_id,
2032           { "Reservation ID", "stun.att.bandwidth_rsv_id", FT_BYTES,
2033             BASE_NONE, NULL, 0x0, NULL, HFILL}
2034          },
2035         { &hf_stun_att_bandwidth_rsv_amount_misb,
2036           { "Minimum Send Bandwidth", "stun.att.bandwidth_rsv_amount.misb", FT_UINT32,
2037             BASE_DEC, NULL, 0x0, "In kilobits per second", HFILL}
2038          },
2039         { &hf_stun_att_bandwidth_rsv_amount_masb,
2040           { "Maximum Send Bandwidth", "stun.att.bandwidth_rsv_amount.masb", FT_UINT32,
2041             BASE_DEC, NULL, 0x0, "In kilobits per second", HFILL}
2042          },
2043         { &hf_stun_att_bandwidth_rsv_amount_mirb,
2044           { "Minimum Receive Bandwidth", "stun.att.bandwidth_rsv_amount.mirb", FT_UINT32,
2045             BASE_DEC, NULL, 0x0, "In kilobits per second", HFILL}
2046          },
2047         { &hf_stun_att_bandwidth_rsv_amount_marb,
2048           { "Maximum Receive Bandwidth", "stun.att.bandwidth_rsv_amount.marb", FT_UINT32,
2049             BASE_DEC, NULL, 0x0, "In kilobits per second", HFILL}
2050          },
2051         { &hf_stun_att_address_rp_a,
2052           { "Valid", "stun.att.address_rp.valid", FT_BOOLEAN,
2053             32, TFS(&tfs_yes_no), 0x80000000, NULL, HFILL}
2054          },
2055         { &hf_stun_att_address_rp_b,
2056           { "PSTN", "stun.att.address_rp.pstn", FT_BOOLEAN,
2057             32, TFS(&tfs_yes_no), 0x40000000, NULL, HFILL}
2058          },
2059         { &hf_stun_att_address_rp_rsv1,
2060           { "Reserved", "stun.att.address_rp.reserved", FT_UINT32,
2061             BASE_HEX, NULL, 0x3FFFFFFF, NULL, HFILL}
2062          },
2063         { &hf_stun_att_address_rp_rsv2,
2064           { "Reserved", "stun.att.address_rp.reserved", FT_UINT32,
2065             BASE_HEX, NULL, 0x7FFFFFFF, NULL, HFILL}
2066          },
2067         { &hf_stun_att_address_rp_masb,
2068           { "Maximum Send Bandwidth", "stun.att.address_rp.masb", FT_UINT32,
2069             BASE_DEC, NULL, 0x0, "In kilobits per second", HFILL}
2070          },
2071         { &hf_stun_att_address_rp_marb,
2072           { "Maximum Receive Bandwidth", "stun.att.address_rp.marb", FT_UINT32,
2073             BASE_DEC, NULL, 0x0, "In kilobits per second", HFILL}
2074          },
2075         { &hf_stun_att_sip_dialog_id,
2076           { "SIP Dialog ID", "stun.att.sip_dialog_id", FT_BYTES,
2077             BASE_NONE, NULL, 0x0, NULL, HFILL}
2078          },
2079         { &hf_stun_att_sip_call_id,
2080           { "SIP Call ID", "stun.att.sip_call_id", FT_BYTES,
2081             BASE_NONE, NULL, 0x0, NULL, HFILL}
2082          },
2083         { &hf_stun_att_lp_peer_location,
2084           { "Peer Location", "stun.att.lp.peer_location", FT_UINT8,
2085             BASE_DEC, VALS(location_vals), 0x0, NULL, HFILL}
2086          },
2087         { &hf_stun_att_lp_self_location,
2088           { "Self Location", "stun.att.lp.seft_location", FT_UINT8,
2089             BASE_DEC, VALS(location_vals), 0x0, NULL, HFILL}
2090          },
2091         { &hf_stun_att_lp_federation,
2092           { "Federation", "stun.att.lp.federation", FT_UINT8,
2093             BASE_DEC, VALS(federation_vals), 0x0, NULL, HFILL}
2094          },
2095         { &hf_stun_att_google_network_id,
2096           { "Google Network ID", "stun.att.google.network_id", FT_UINT16,
2097             BASE_DEC, NULL, 0x0, NULL, HFILL}
2098          },
2099         { &hf_stun_att_google_network_cost,
2100           { "Google Network Cost", "stun.att.google.network_cost", FT_UINT16,
2101             BASE_DEC, VALS(google_network_cost_vals), 0x0, NULL, HFILL}
2102          },
2103         { &hf_stun_network_version,
2104           { "STUN Network Version", "stun.network_version", FT_UINT8,
2105             BASE_DEC, VALS(network_versions_vals), 0x0, NULL, HFILL }
2106         },
2107     };
2108 
2109     /* Setup protocol subtree array */
2110     static gint *ett[] = {
2111         &ett_stun,
2112         &ett_stun_type,
2113         &ett_stun_att_all,
2114         &ett_stun_att,
2115         &ett_stun_att_type,
2116     };
2117 
2118     static ei_register_info ei[] = {
2119         { &ei_stun_short_packet,
2120         { "stun.short_packet", PI_MALFORMED, PI_ERROR, "Packet is too short", EXPFILL }},
2121 
2122         { &ei_stun_wrong_msglen,
2123         { "stun.wrong_msglen", PI_MALFORMED, PI_ERROR, "Packet length is not multiple of 4 bytes", EXPFILL }},
2124 
2125         { &ei_stun_long_attribute,
2126         { "stun.long_attribute", PI_MALFORMED, PI_WARN, "Attribute has trailing data", EXPFILL }},
2127 
2128         { &ei_stun_unknown_attribute,
2129         { "stun.unknown_attribute", PI_UNDECODED, PI_WARN, "Attribute unknown", EXPFILL }},
2130     };
2131 
2132     module_t *stun_module;
2133     expert_module_t* expert_stun;
2134 
2135     /* Register the protocol name and description */
2136     proto_stun = proto_register_protocol("Session Traversal Utilities for NAT", "STUN", "stun");
2137 
2138     /* Required function calls to register the header fields and subtrees used */
2139     proto_register_field_array(proto_stun, hf, array_length(hf));
2140     proto_register_subtree_array(ett, array_length(ett));
2141 
2142     /* heuristic subdissectors (used for the DATA field) */
2143     heur_subdissector_list = register_heur_dissector_list("stun", proto_stun);
2144 
2145     register_dissector("stun-tcp", dissect_stun_tcp, proto_stun);
2146     register_dissector("stun-udp", dissect_stun_udp, proto_stun);
2147     register_dissector("stun-heur", dissect_stun_heur_udp, proto_stun);
2148 
2149     /* Register preferences */
2150     stun_module = prefs_register_protocol(proto_stun, NULL);
2151     prefs_register_enum_preference(stun_module,
2152         "stunversion", "Stun Version", "Stun Version on the Network",
2153                                        &stun_network_version,
2154                                        stun_network_version_vals,
2155                                        FALSE);
2156 
2157     expert_stun = expert_register_protocol(proto_stun);
2158     expert_register_field_array(expert_stun, ei, array_length(ei));
2159 }
2160 
2161 void
proto_reg_handoff_stun(void)2162 proto_reg_handoff_stun(void)
2163 {
2164     stun_tcp_handle = find_dissector("stun-tcp");
2165     stun_udp_handle = find_dissector("stun-udp");
2166 
2167     dissector_add_uint_with_preference("tcp.port", TCP_PORT_STUN, stun_tcp_handle);
2168     dissector_add_uint_with_preference("udp.port", UDP_PORT_STUN, stun_udp_handle);
2169 
2170     /*
2171      * SSL/TLS and DTLS Application-Layer Protocol Negotiation (ALPN)
2172      * protocol ID.
2173      */
2174     dissector_add_string("tls.alpn", "stun.nat-discovery", stun_tcp_handle);
2175     dissector_add_string("dtls.alpn", "stun.nat-discovery", stun_udp_handle);
2176 
2177     heur_dissector_add("udp", dissect_stun_heur_udp, "STUN over UDP", "stun_udp", proto_stun, HEURISTIC_ENABLE);
2178     heur_dissector_add("tcp", dissect_stun_heur_tcp, "STUN over TCP", "stun_tcp", proto_stun, HEURISTIC_ENABLE);
2179     /* STUN messages may be encapsulated in Send Indication or Channel Data message as DATA payload
2180      * (in TURN and CLASSICSTUN, both)  */
2181     heur_dissector_add("stun", dissect_stun_heur_udp, "STUN over TURN", "stun_turn", proto_stun, HEURISTIC_DISABLE);
2182     heur_dissector_add("classicstun", dissect_stun_heur_udp, "STUN over CLASSICSTUN", "stun_classicstun", proto_stun, HEURISTIC_DISABLE);
2183 
2184     data_handle = find_dissector("data");
2185 }
2186 
2187 /*
2188  * Editor modelines
2189  *
2190  * Local Variables:
2191  * c-basic-offset: 4
2192  * tab-width: 8
2193  * indent-tabs-mode: nil
2194  * End:
2195  *
2196  * ex: set shiftwidth=4 tabstop=8 expandtab:
2197  * :indentSize=4:tabSize=8:noTabs=true:
2198  */
2199