From Martin Mathieson:

stun -  add support for 3 extra Message Attributes as described in draft-ietf-behave-rfc3489bis-00

ymsg 
 - avoid looking beyond the tvb while looking for content item delimiters (causing most frames to be shown as malformed packet)
- makes content items (and their keys and values) filterable  (includes fix to bug 415)


svn path=/trunk/; revision=16005
This commit is contained in:
Anders Broman 2005-09-26 05:43:25 +00:00
parent fa1647d9a6
commit 25fe588f9f
2 changed files with 122 additions and 34 deletions

View File

@ -23,6 +23,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* Please refer to RFC 3489 for protocol detail.
* (supports extra message attributes described in draft-ietf-behave-rfc3489bis-00)
*/
#ifdef HAVE_CONFIG_H
@ -57,6 +58,9 @@ static int stun_att_unknown = -1;
static int stun_att_error_class = -1;
static int stun_att_error_number = -1;
static int stun_att_error_reason = -1;
static int stun_att_server_string = -1;
static int stun_att_xor_ip = -1;
static int stun_att_xor_port = -1;
@ -80,6 +84,9 @@ static int stun_att_error_reason = -1;
#define ERROR_CODE 0x0009
#define UNKNOWN_ATTRIBUTES 0x000a
#define REFLECTED_FROM 0x000b
#define XOR_MAPPED_ADDRESS 0x0020
#define XOR_ONLY 0x0021
#define SERVER 0x0022
@ -123,6 +130,9 @@ static const value_string attributes[] = {
{MESSAGE_INTEGRITY, "MESSAGE-INTEGRITY"},
{ERROR_CODE, "ERROR-CODE"},
{REFLECTED_FROM, "REFLECTED-FROM"},
{XOR_MAPPED_ADDRESS, "XOR-MAPPED-ADDRESS"},
{XOR_ONLY, "XOR_ONLY"},
{SERVER, "SERVER"},
{0x00, NULL}
};
@ -273,6 +283,22 @@ dissect_stun(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
break;
case SERVER:
proto_tree_add_item(att_tree, stun_att_server_string, tvb, offset, att_length, FALSE);
break;
case XOR_MAPPED_ADDRESS:
if (att_length < 2)
break;
proto_tree_add_item(att_tree, stun_att_family, tvb, offset+1, 1, FALSE);
if (att_length < 4)
break;
proto_tree_add_item(att_tree, stun_att_xor_port, tvb, offset+2, 2, FALSE);
if (att_length < 8)
break;
proto_tree_add_item(att_tree, stun_att_xor_ip, tvb, offset+4, 4, FALSE);
break;
default:
break;
}
@ -366,6 +392,18 @@ proto_register_stun(void)
{ "Error Reason Phase","stun.att.error.reason", FT_STRING,
BASE_NONE, NULL, 0x0, "", HFILL}
},
{ &stun_att_xor_ip,
{ "IP (XOR-d)", "stun.att.ip-xord", FT_IPv4,
BASE_NONE, NULL, 0x0, "", HFILL }
},
{ &stun_att_xor_port,
{ "Port (XOR-d)", "stun.att.port-xord", FT_UINT16,
BASE_DEC, NULL, 0x0, "", HFILL }
},
{ &stun_att_server_string,
{ "Server version","stun.att.server", FT_STRING,
BASE_NONE, NULL, 0x0, "", HFILL}
},
};
/* Setup protocol subtree array */

View File

@ -43,10 +43,15 @@ static int hf_ymsg_len = -1;
static int hf_ymsg_service = -1;
static int hf_ymsg_status = -1;
static int hf_ymsg_session_id = -1;
static int hf_ymsg_content = -1;
static int hf_ymsg_content_line = -1;
static int hf_ymsg_content_line_key = -1;
static int hf_ymsg_content_line_value = -1;
static gint ett_ymsg = -1;
static gint ett_ymsg_content = -1;
static gint ett_ymsg_content_line = -1;
#define TCP_PORT_YMSG 23 /* XXX - this is Telnet! */
#define TCP_PORT_YMSG_2 25 /* And this is SMTP! */
@ -166,7 +171,7 @@ enum yahoo_status {
YAHOO_STATUS_INVISIBLE = 12,
YAHOO_STATUS_CUSTOM = 99,
YAHOO_STATUS_IDLE = 999,
YAHOO_STATUS_WEBLOGIN = 0x5a55aa55,
YAHOO_STATUS_WEBLOGIN = 0x5a55aa55,
YAHOO_STATUS_OFFLINE = 0x5a55aa56, /* don't ask */
YAHOO_STATUS_TYPING = 0x16
};
@ -277,13 +282,14 @@ static const value_string ymsg_status_vals[] = {
static guint get_ymsg_pdu_len(tvbuff_t *tvb, int offset);
static void dissect_ymsg_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree);
static int
get_content_item_length(tvbuff_t *tvb, int offset) {
/* Find the end of the current content line and return its length */
static int get_content_item_length(tvbuff_t *tvb, int offset)
{
int origoffset = offset;
guint16 curdata;
for (;;) {
curdata = tvb_get_ntohs(tvb, offset);
if (curdata == 0xc080) {
/* Keep reading until the magic delimiter (or end of tvb) is found */
while (tvb_length_remaining(tvb, offset) >= 2) {
if (tvb_get_ntohs(tvb, offset) == 0xc080) {
break;
}
offset++;
@ -302,7 +308,7 @@ dissect_ymsg(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
tcp_dissect_pdus(tvb, pinfo, tree, ymsg_desegment, 8, get_ymsg_pdu_len,
dissect_ymsg_pdu);
dissect_ymsg_pdu);
return TRUE;
}
@ -351,50 +357,83 @@ dissect_ymsg_pdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
}
if (tree) {
ti = proto_tree_add_item(tree, proto_ymsg, tvb, offset, -1,
FALSE);
ti = proto_tree_add_item(tree, proto_ymsg, tvb, offset, -1, FALSE);
ymsg_tree = proto_item_add_subtree(ti, ett_ymsg);
offset += 4; /* skip the YMSG string */
proto_tree_add_item(ymsg_tree, hf_ymsg_version, tvb,
offset, 2, FALSE);
/* Version */
proto_tree_add_item(ymsg_tree, hf_ymsg_version, tvb, offset, 2, FALSE);
offset += 2;
offset += 2; /* XXX - padding? */
/* Length */
content_len = tvb_get_ntohs(tvb, offset);
proto_tree_add_item(ymsg_tree, hf_ymsg_len, tvb,
offset, 2, FALSE);
proto_tree_add_item(ymsg_tree, hf_ymsg_len, tvb, offset, 2, FALSE);
offset += 2;
proto_tree_add_item(ymsg_tree, hf_ymsg_service, tvb,
offset, 2, FALSE);
/* Service */
proto_tree_add_item(ymsg_tree, hf_ymsg_service, tvb, offset, 2, FALSE);
offset += 2;
proto_tree_add_item(ymsg_tree, hf_ymsg_status, tvb,
offset, 4, FALSE);
/* Status */
proto_tree_add_item(ymsg_tree, hf_ymsg_status, tvb, offset, 4, FALSE);
offset += 4;
proto_tree_add_item(ymsg_tree, hf_ymsg_session_id, tvb,
offset, 4, TRUE);
/* Session id */
proto_tree_add_item(ymsg_tree, hf_ymsg_session_id, tvb, offset, 4, TRUE);
offset += 4;
content_item = proto_tree_add_item(ymsg_tree, hf_ymsg_content, tvb,
offset, -1, TRUE);
content_tree = proto_item_add_subtree(content_item, ett_ymsg_content);
/* Contents */
if (content_len) {
/* Create content subtree */
content_item = proto_tree_add_item(ymsg_tree, hf_ymsg_content, tvb,
offset, -1, TRUE);
content_tree = proto_item_add_subtree(content_item, ett_ymsg_content);
for (;;) {
if (offset >= headersize+content_len) {
break;
/* Each entry consists of:
<key string> <delimiter> <value string> <delimiter>
*/
/* Parse and show each line of the contents */
for (;;)
{
proto_item *ti = NULL;
proto_tree *content_line_tree = NULL;
/* Don't continue unless there is room for another whole item.
(including 2 2-byte delimiters */
if (offset >= (headersize+content_len-4))
{
break;
}
/* Get the length of the key */
keylen = get_content_item_length(tvb, offset);
/* Extract the key */
keybuf = tvb_format_text(tvb, offset, keylen);
/* Get the length of the value */
vallen = get_content_item_length(tvb, offset+keylen+2);
/* Extract the value */
valbuf = tvb_format_text(tvb, offset+keylen+2, vallen);
/* Add a text item with the key... */
ti = proto_tree_add_string_format(content_tree, hf_ymsg_content_line, tvb,
offset, keylen+2+vallen+2,
"", "%s:%s", keybuf, valbuf);
content_line_tree = proto_item_add_subtree(ti, ett_ymsg_content_line);
/* And add the key and value separately inside */
proto_tree_add_item(content_line_tree, hf_ymsg_content_line_key, tvb,
offset, keylen, FALSE);
proto_tree_add_item(content_line_tree, hf_ymsg_content_line_value, tvb,
offset+keylen+2, vallen, FALSE);
/* Move beyone key and value lines */
offset += keylen+2+vallen+2;
}
keylen = get_content_item_length (tvb, offset);
keybuf = tvb_format_text(tvb, offset, keylen);
vallen = get_content_item_length (tvb, offset+keylen+2);
content_item = proto_tree_add_text(content_tree, tvb, offset, keylen+vallen+4, "%s: ", keybuf);
valbuf = tvb_format_text(tvb, offset+keylen+2, vallen);
proto_item_append_text(content_item, "%s", valbuf);
offset += keylen+vallen+4;
}
}
@ -420,13 +459,24 @@ proto_register_ymsg(void)
{ &hf_ymsg_session_id, {
"Session ID", "ymsg.session_id", FT_UINT32, BASE_HEX,
NULL, 0, "Connection ID", HFILL }},
{ &hf_ymsg_content, {
"Content", "ymsg.content", FT_STRING, 0,
"Content", "ymsg.content", FT_STRING, BASE_NONE,
NULL, 0, "Data portion of the packet", HFILL }},
{ &hf_ymsg_content_line, {
"Content-line", "ymsg.content-line", FT_STRING, BASE_NONE,
NULL, 0, "Data portion of the packet", HFILL }},
{ &hf_ymsg_content_line_key, {
"Key", "ymsg.content-line.key", FT_STRING, BASE_NONE,
NULL, 0, "Content line key", HFILL }},
{ &hf_ymsg_content_line_value, {
"Value", "ymsg.content-line.value", FT_STRING, BASE_NONE,
NULL, 0, "Content line value", HFILL }},
};
static gint *ett[] = {
&ett_ymsg,
&ett_ymsg_content,
&ett_ymsg_content_line
};
module_t *ymsg_module;