Wireshark-dev: [Wireshark-dev] [PATCH] draft-ietf-behave-rfc3489bis-07
From: Marc Petit-Huguenin <marc@xxxxxxxxxxxxxxxxxx>
Date: Mon, 09 Jul 2007 14:05:45 -0700
-----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1 Hi, This is an update to the STUN2 dissector using the last draft, draft-ietf-behave-rfc3489bis-07. Here is the changelog: * My employer is now sponsoring this work, so added a copyright line. * Added a comment for each method/attribute with the RFC/I-D where is it defined, so it will be easier to add new STUN usages. * Removed the SHARED-SECRET method. * Removed the PASSWORD and REFRESH-INTERVAL attributes. * Changed "Response" to "Success Response". * Changed "Error Reason Phase" to "Error Reason Phrase". * Added reassembly for TCP segments on STUN2. * Updated STUN acronym expansion. * Renamed STUN2_ERROR to ERROR_RESPONSE. * Changed the value of attribute FINGERPRINT from 0x8025 to 0x8028. * Display if an unknown attribute is comprehension-optional or comprehension-required. * Reorganized order of attributes in the dissector code. * The message length is now displayed in decimal. I will update the Wiki page accordingly. - -- Marc Petit-Huguenin [ ] Home: marc@xxxxxxxxxxxxxxxxxx [RFC1855-compliant space for rent ] Work: marc@xxxxxxx [ ] -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.6 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org iD8DBQFGkqMp9RoMZyVa61cRAqVfAJ0RoNN8GDFXW/KlNqOcA0ncbRhdxACgjfAJ QknuNq6Sc35RDLj6AJLlFKs= =3qRQ -----END PGP SIGNATURE-----
Index: epan/dissectors/packet-stun2.c
===================================================================
--- epan/dissectors/packet-stun2.c (revision 22276)
+++ epan/dissectors/packet-stun2.c (working copy)
@@ -1,7 +1,8 @@
/* packet-stun2.c
- * Routines for Simple Traversal Underneath NAT dissection
+ * Routines for Session Traversal Utilities for NAT (STUN) dissection
* Copyright 2003, Shiang-Ming Huang <smhuang@xxxxxxxxxxxxxxxxxxxx>
* Copyright 2006, Marc Petit-Huguenin <marc@xxxxxxxxxxxxxxxxxx>
+ * Copyright 2007, 8x8 Inc. <petithug@xxxxxxx>
*
* $Id$
*
@@ -23,7 +24,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
- * Please refer to draft-ietf-behave-rfc3489bis-05 for protocol detail.
+ * Please refer to draft-ietf-behave-rfc3489bis-07 for protocol detail.
*/
#ifdef HAVE_CONFIG_H
@@ -77,27 +78,24 @@
#define REQUEST 0x0000
#define INDICATION 0x0001
#define RESPONSE 0x0010
-#define STUN2_ERROR 0x0011 /* use prefix to prevent redefinition from wingdi.h */
+#define ERROR_RESPONSE 0x0011
-/* Message methods */
-#define METHOD_MASK 0xCEEF
-#define BINDING 0x0001
-#define SHARED_SECRET 0x0002
+/* Request/Response Transactions */
+#define METHOD_MASK 0xCEEF
+#define BINDING 0x0001 /* draft-ietf-behave-rfc3489bis-07 */
/* Attribute Types */
-#define MAPPED_ADDRESS 0x0001
-#define USERNAME 0x0006
-#define PASSWORD 0x0007
-#define MESSAGE_INTEGRITY 0x0008
-#define ERROR_CODE 0x0009
-#define UNKNOWN_ATTRIBUTES 0x000a
-#define REALM 0x0014
-#define NONCE 0x0015
-#define XOR_MAPPED_ADDRESS 0x0020
-#define SERVER 0x8022
-#define ALTERNATE_SERVER 0x8023
-#define REFRESH_INTERVAL 0x8024
-#define FINGERPRINT 0x8025
+#define MAPPED_ADDRESS 0x0001 /* draft-ietf-behave-rfc3489bis-07 */
+#define USERNAME 0x0006 /* draft-ietf-behave-rfc3489bis-07 */
+#define MESSAGE_INTEGRITY 0x0008 /* draft-ietf-behave-rfc3489bis-07 */
+#define ERROR_CODE 0x0009 /* draft-ietf-behave-rfc3489bis-07 */
+#define UNKNOWN_ATTRIBUTES 0x000a /* draft-ietf-behave-rfc3489bis-07 */
+#define REALM 0x0014 /* draft-ietf-behave-rfc3489bis-07 */
+#define NONCE 0x0015 /* draft-ietf-behave-rfc3489bis-07 */
+#define XOR_MAPPED_ADDRESS 0x0020 /* draft-ietf-behave-rfc3489bis-07 */
+#define SERVER 0x8022 /* draft-ietf-behave-rfc3489bis-07 */
+#define ALTERNATE_SERVER 0x8023 /* draft-ietf-behave-rfc3489bis-07 */
+#define FINGERPRINT 0x8028 /* draft-ietf-behave-rfc3489bis-07 */
/* Initialize the subtree pointers */
static gint ett_stun2 = -1;
@@ -114,21 +112,19 @@
static const value_string classes[] = {
{REQUEST, "Request"},
{INDICATION, "Indication"},
- {RESPONSE, "Response"},
- {STUN2_ERROR, "Error Response"},
+ {RESPONSE, "Success Response"},
+ {ERROR_RESPONSE, "Error Response"},
{0x00, NULL}
};
static const value_string methods[] = {
{BINDING, "Binding"},
- {SHARED_SECRET, "Shared Secret"},
{0x00, NULL}
};
static const value_string attributes[] = {
{MAPPED_ADDRESS, "MAPPED-ADDRESS"},
{USERNAME, "USERNAME"},
- {PASSWORD, "PASSWORD"},
{MESSAGE_INTEGRITY, "MESSAGE-INTEGRITY"},
{ERROR_CODE, "ERROR-CODE"},
{UNKNOWN_ATTRIBUTES, "UNKNOWN-ATTRIBUTES"},
@@ -137,7 +133,6 @@
{XOR_MAPPED_ADDRESS, "XOR-MAPPED-ADDRESS"},
{SERVER, "SERVER"},
{ALTERNATE_SERVER, "ALTERNATE-SERVER"},
- {REFRESH_INTERVAL, "REFRESH-INTERVAL"},
{FINGERPRINT, "FINGERPRINT"},
{0x00, NULL}
};
@@ -148,8 +143,13 @@
{0x00, NULL}
};
+static guint get_stun2_message_len(packet_info *pinfo, tvbuff_t *tvb, int offset)
+{
+ return (guint)tvb_get_ntohs(tvb, offset+2) + 20;
+}
+
static int
-dissect_stun2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+dissect_stun2_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
proto_item *ti;
proto_item *ta;
@@ -231,7 +231,7 @@
ta = proto_tree_add_text(att_type_tree, tvb, offset,
ATTR_HDR_LEN+att_length,
"Attribute: %s",
- val_to_str(att_type, attributes, "Unknown (0x%04x)"));
+ val_to_str(att_type, attributes, att_type & 0x8000 ? "Unknown (0x%4x) - Comprehension-optional" : "Unknown (0x%04x)- Comprehension-required"));
att_tree = proto_item_add_subtree(ta, ett_stun2_att);
proto_tree_add_uint(att_tree, stun2_att_type, tvb,
@@ -278,36 +278,12 @@
proto_tree_add_uint(att_tree, stun2_att_padding, tvb, offset+att_length, 4-(att_length % 4), 4-(att_length % 4));
break;
- case PASSWORD:
- proto_tree_add_item(att_tree, stun2_att_password, tvb, offset, att_length, FALSE);
- if (att_length % 4 != 0)
- proto_tree_add_uint(att_tree, stun2_att_padding, tvb, offset+att_length, 4-(att_length % 4), 4-(att_length % 4));
- break;
-
- case NONCE:
- proto_tree_add_item(att_tree, stun2_att_nonce, tvb, offset, att_length, FALSE);
- if (att_length % 4 != 0)
- proto_tree_add_uint(att_tree, stun2_att_padding, tvb, offset+att_length, 4-(att_length % 4), 4-(att_length % 4));
- break;
-
- case REALM:
- proto_tree_add_item(att_tree, stun2_att_realm, tvb, offset, att_length, FALSE);
- if (att_length % 4 != 0)
- proto_tree_add_uint(att_tree, stun2_att_padding, tvb, offset+att_length, 4-(att_length % 4), 4-(att_length % 4));
- break;
-
case MESSAGE_INTEGRITY:
if (att_length < 20)
break;
proto_tree_add_item(att_tree, stun2_att_hmac, tvb, offset, att_length, FALSE);
break;
- case FINGERPRINT:
- if (att_length < 4)
- break;
- proto_tree_add_item(att_tree, stun2_att_crc32, tvb, offset, att_length, FALSE);
- break;
-
case ERROR_CODE:
if (att_length < 3)
break;
@@ -329,12 +305,18 @@
proto_tree_add_uint(att_tree, stun2_att_padding, tvb, offset+att_length, 4-(att_length % 4), 4-(att_length % 4));
break;
- case SERVER:
- proto_tree_add_item(att_tree, stun2_att_server, tvb, offset, att_length, FALSE);
+ case REALM:
+ proto_tree_add_item(att_tree, stun2_att_realm, tvb, offset, att_length, FALSE);
if (att_length % 4 != 0)
proto_tree_add_uint(att_tree, stun2_att_padding, tvb, offset+att_length, 4-(att_length % 4), 4-(att_length % 4));
break;
+ case NONCE:
+ proto_tree_add_item(att_tree, stun2_att_nonce, tvb, offset, att_length, FALSE);
+ if (att_length % 4 != 0)
+ proto_tree_add_uint(att_tree, stun2_att_padding, tvb, offset+att_length, 4-(att_length % 4), 4-(att_length % 4));
+ break;
+
case XOR_MAPPED_ADDRESS:
if (att_length < 2)
break;
@@ -377,10 +359,16 @@
}
break;
- case REFRESH_INTERVAL:
+ case SERVER:
+ proto_tree_add_item(att_tree, stun2_att_server, tvb, offset, att_length, FALSE);
+ if (att_length % 4 != 0)
+ proto_tree_add_uint(att_tree, stun2_att_padding, tvb, offset+att_length, 4-(att_length % 4), 4-(att_length % 4));
+ break;
+
+ case FINGERPRINT:
if (att_length < 4)
break;
- proto_tree_add_item(att_tree, stun2_att_refresh_interval, tvb, offset, 4, FALSE);
+ proto_tree_add_item(att_tree, stun2_att_crc32, tvb, offset, att_length, FALSE);
break;
default:
@@ -398,11 +386,23 @@
return tvb_length(tvb);
}
+static int
+dissect_stun2_udp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ dissect_stun2_message(tvb, pinfo, tree);
+}
+static int
+dissect_stun2_tcp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
+{
+ tcp_dissect_pdus(tvb, pinfo, tree, TRUE, STUN2_HDR_LEN,
+ get_stun2_message_len, dissect_stun2_message);
+}
+
static gboolean
dissect_stun2_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
{
- if (dissect_stun2(tvb, pinfo, tree) == 0)
+ if (dissect_stun2_message(tvb, pinfo, tree) == 0)
return FALSE;
return TRUE;
@@ -422,7 +422,7 @@
},
{ &hf_stun2_length,
{ "Message Length", "stun2.length", FT_UINT16,
- BASE_HEX, NULL, 0x0, "", HFILL }
+ BASE_DEC, NULL, 0x0, "", HFILL }
},
{ &hf_stun2_cookie,
{ "Message Cookie", "stun2.cookie", FT_BYTES,
@@ -469,10 +469,6 @@
{ "Padding", "stun2.att.padding", FT_UINT16,
BASE_DEC, NULL, 0x0, "", HFILL }
},
- { &stun2_att_password,
- { "Password", "stun2.att.password", FT_STRING,
- BASE_NONE, NULL, 0x0, "", HFILL }
- },
{ &stun2_att_hmac,
{ "HMAC-SHA1", "stun2.att.hmac", FT_BYTES,
BASE_HEX, NULL, 0x0, "", HFILL }
@@ -490,7 +486,7 @@
BASE_DEC, NULL, 0x0, "", HFILL}
},
{ &stun2_att_error_reason,
- { "Error Reason Phase","stun2.att.error.reason", FT_STRING,
+ { "Error Reason Phrase","stun2.att.error.reason", FT_STRING,
BASE_NONE, NULL, 0x0, "", HFILL}
},
{ &stun2_att_realm,
@@ -521,10 +517,6 @@
{ "Server software","stun2.att.server", FT_STRING,
BASE_NONE, NULL, 0x0, "", HFILL}
},
- { &stun2_att_refresh_interval,
- { "Refresh Interval","stun2.att.refresh-interval", FT_UINT16,
- BASE_DEC, NULL, 0x0, "", HFILL}
- },
{ &stun2_att_value,
{ "Value", "stun2.value", FT_BYTES,
BASE_HEX, NULL, 0x0, "", HFILL }
@@ -539,26 +531,25 @@
};
/* Register the protocol name and description */
- proto_stun2 = proto_register_protocol("Simple Traversal Underneath NAT",
+ proto_stun2 = proto_register_protocol("Session Traversal Utilities for NAT",
"STUN2", "stun2");
/* Required function calls to register the header fields and subtrees used */
proto_register_field_array(proto_stun2, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
-
- new_register_dissector("stun2", dissect_stun2, proto_stun2);
}
-
void
proto_reg_handoff_stun2(void)
{
- dissector_handle_t stun2_handle;
+ dissector_handle_t stun2_tcp_handle;
+ dissector_handle_t stun2_udp_handle;
- stun2_handle = find_dissector("stun2");
+ stun2_tcp_handle = create_dissector_handle(dissect_stun2_tcp, proto_stun2);
+ stun2_udp_handle = create_dissector_handle(dissect_stun2_udp, proto_stun2);
- dissector_add("tcp.port", TCP_PORT_STUN2, stun2_handle);
- dissector_add("udp.port", UDP_PORT_STUN2, stun2_handle);
+ dissector_add("tcp.port", TCP_PORT_STUN2, stun2_tcp_handle);
+ dissector_add("udp.port", UDP_PORT_STUN2, stun2_udp_handle);
heur_dissector_add("udp", dissect_stun2_heur, proto_stun2);
heur_dissector_add("tcp", dissect_stun2_heur, proto_stun2);
- Follow-Ups:
- Re: [Wireshark-dev] [PATCH] draft-ietf-behave-rfc3489bis-07
- From: Jeff Morriss
- Re: [Wireshark-dev] [PATCH] draft-ietf-behave-rfc3489bis-07
- Prev by Date: Re: [Wireshark-dev] [Wireshark-users] Lua compile problems
- Next by Date: [Wireshark-dev] Wireshark Windows installer updated to 0.99.6a
- Previous by thread: Re: [Wireshark-dev] [Wireshark-users] Lua compile problems
- Next by thread: Re: [Wireshark-dev] [PATCH] draft-ietf-behave-rfc3489bis-07
- Index(es):