aboutsummaryrefslogtreecommitdiffstats
path: root/packet-sip.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2003-12-08 20:25:31 +0000
committerGuy Harris <guy@alum.mit.edu>2003-12-08 20:25:31 +0000
commitd5ba7b40ebcb73d2e15597c96b88f2bf0e49679f (patch)
tree59d818f54ab7e89985f6583f6750c6d7dd62f0c0 /packet-sip.c
parent26ac41f3dd3f70eac3850b5697db950d0e24aeb1 (diff)
From Anders Broman:
Call subdissectors regardless of whether we're building a protocol tree or not. Use the "media_type" dissector table to hand off to subdissectors, rather than wiring in SDP. Put the message body into a subtree of the SIP tree rather than at the top level. svn path=/trunk/; revision=9200
Diffstat (limited to 'packet-sip.c')
-rw-r--r--packet-sip.c392
1 files changed, 223 insertions, 169 deletions
diff --git a/packet-sip.c b/packet-sip.c
index 79c3076c3c..843717d676 100644
--- a/packet-sip.c
+++ b/packet-sip.c
@@ -3,6 +3,7 @@
* RFCs 3261-3264
*
* TODO: Pay attention to Content-Type: It might not always be SDP.
+ * Content-Type is fixed, mixed/mode is not handled though.
* hf_ display filters for headers of SIP extension RFCs:
* Done for RFC 3265, RFC 3262
* Use hash table for list of headers
@@ -17,7 +18,7 @@
* Copyright 2000, Heikki Vatiainen <hessu@cs.tut.fi>
* Copyright 2001, Jean-Francois Mule <jfm@cablelabs.com>
*
- * $Id: packet-sip.c,v 1.49 2003/11/25 18:02:57 guy Exp $
+ * $Id: packet-sip.c,v 1.50 2003/12/08 20:25:31 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
@@ -68,11 +69,12 @@ static gint hf_sip_from_addr = -1;
static gint hf_sip_tag = -1;
/* Initialize the subtree pointers */
-static gint ett_sip = -1;
-static gint ett_sip_reqresp = -1;
-static gint ett_sip_hdr = -1;
-static gint ett_raw_text = -1;
-static gint ett_sip_element = -1;
+static gint ett_sip = -1;
+static gint ett_sip_reqresp = -1;
+static gint ett_sip_hdr = -1;
+static gint ett_raw_text = -1;
+static gint ett_sip_element = -1;
+static gint ett_sip_message_body = -1;
/* PUBLISH method added as per http://www.ietf.org/internet-drafts/draft-ietf-sip-publish-01.txt */
static const char *sip_methods[] = {
@@ -354,7 +356,9 @@ static void dfilter_sip_request_line(tvbuff_t *tvb, proto_tree *tree,
static void dfilter_sip_status_line(tvbuff_t *tvb, proto_tree *tree);
static void tvb_raw_text_add(tvbuff_t *tvb, proto_tree *tree);
-static dissector_handle_t sdp_handle;
+/* SIP content type and internet media type used by other dissectors are the same */
+/* List of nmediatypes from IANA at: http://www.iana.org/assignments/media-types/index.html */
+static dissector_table_t media_type_dissector_table;
#define SIP2_HDR "SIP/2.0"
#define SIP2_HDR_LEN (strlen (SIP2_HDR))
@@ -389,13 +393,16 @@ dissect_sip_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
line_type_t line_type;
tvbuff_t *next_tvb;
gboolean is_known_request;
+ gboolean found_match = FALSE;
char *descr;
guint token_1_len;
guint current_method_idx = 0;
proto_item *ts = NULL, *ti, *th = NULL, *sip_element_item;
- proto_tree *sip_tree, *reqresp_tree, *hdr_tree = NULL, *sip_element_tree;
+ proto_tree *sip_tree = NULL, *reqresp_tree, *hdr_tree = NULL, *sip_element_tree, *message_body_tree;
guchar contacts = 0, contact_is_star = 0, expires_is_0 = 0;
char csec_method[16] = "";
+ char *media_type_str = NULL;
+ char *boundary_str = NULL;
/*
* Note that "tvb_find_line_end()" will return a value that
@@ -454,7 +461,6 @@ dissect_sip_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
col_set_str(pinfo->cinfo, COL_INFO, "Continuation");
break;
}
-
if (tree) {
ts = proto_tree_add_item(tree, proto_sip, tvb, 0, -1, FALSE);
sip_tree = proto_item_add_subtree(ts, ett_sip);
@@ -495,9 +501,11 @@ dissect_sip_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
while (tvb_reported_length_remaining(tvb, offset) > 0) {
gint line_end_offset;
gint colon_offset;
+ gint semicolon_offset;
+ gint content_type_len;
gint header_len;
gint hf_index;
- gint value_offset,tag_offset;
+ gint value_offset,tag_offset,left_quote_offset,right_quote_offset,boundary_str_len;
guchar c;
size_t value_len;
char *value;
@@ -511,176 +519,203 @@ dissect_sip_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
*/
break;
}
- if (tree) {
- line_end_offset = offset + linelen;
- colon_offset = tvb_find_guint8(tvb, offset, linelen,
- ':');
- if (colon_offset == -1) {
- /*
- * Malformed header - no colon after the
- * name.
- */
- proto_tree_add_text(hdr_tree, tvb, offset,
- next_offset - offset, "%s",
+ line_end_offset = offset + linelen;
+ colon_offset = tvb_find_guint8(tvb, offset, linelen, ':');
+ if (colon_offset == -1) {
+ /*
+ * Malformed header - no colon after the name.
+ */
+ proto_tree_add_text(hdr_tree, tvb, offset,
+ next_offset - offset, "%s",
+ tvb_format_text(tvb, offset, linelen));
+ } else {
+ header_len = colon_offset - offset;
+ hf_index = sip_is_known_sip_header(tvb,
+ offset, header_len);
+
+ if (hf_index == -1) {
+ proto_tree_add_text(hdr_tree, tvb,
+ offset, next_offset - offset, "%s",
tvb_format_text(tvb, offset, linelen));
} else {
- header_len = colon_offset - offset;
- hf_index = sip_is_known_sip_header(tvb,
- offset, header_len);
+ /*
+ * Skip whitespace after the colon.
+ */
+ value_offset = colon_offset + 1;
+ while (value_offset < line_end_offset
+ && ((c = tvb_get_guint8(tvb,
+ value_offset)) == ' '
+ || c == '\t'))
+ value_offset++;
+ /*
+ * Fetch the value.
+ */
+ value_len = line_end_offset - value_offset;
+ value = tvb_get_string(tvb, value_offset,
+ value_len);
- if (hf_index == -1) {
- proto_tree_add_text(hdr_tree, tvb,
- offset, next_offset - offset, "%s",
+ /*
+ * Add it to the protocol tree,
+ * but display the line as is.
+ */
+ switch ( hf_index ) {
+ case POS_TO :
+ sip_element_item = proto_tree_add_string_format(hdr_tree,
+ hf_header_array[hf_index], tvb,
+ offset, next_offset - offset,
+ value, "%s",
tvb_format_text(tvb, offset, linelen));
- } else {
- /*
- * Skip whitespace after the colon.
- */
- value_offset = colon_offset + 1;
- while (value_offset < line_end_offset
- && ((c = tvb_get_guint8(tvb,
- value_offset)) == ' '
- || c == '\t'))
- value_offset++;
- /*
- * Fetch the value.
- */
- value_len = line_end_offset - value_offset;
- value = tvb_get_string(tvb, value_offset,
- value_len);
-
- /*
- * Add it to the protocol tree,
- * but display the line as is.
- */
-
- switch ( hf_index ) {
- case POS_TO :
- sip_element_item = proto_tree_add_string_format(hdr_tree,
- hf_header_array[hf_index], tvb,
- offset, next_offset - offset,
- value, "%s",
- tvb_format_text(tvb, offset, linelen));
- sip_element_tree = proto_item_add_subtree( sip_element_item, ett_sip_element);
- tag_offset = tvb_find_guint8(tvb, offset,linelen, ';');
- if ( tag_offset != -1){
- tag_offset = tag_offset + 1;
- c = tvb_get_guint8(tvb,tag_offset);
- if ( c == 't' ){/* tag found */
- proto_tree_add_string(sip_element_tree,
- hf_sip_to_addr, tvb,
- value_offset, (tag_offset - value_offset - 1),
- tvb_format_text(tvb, value_offset, ( tag_offset - value_offset - 1)));
- tag_offset = tvb_find_guint8(tvb, tag_offset,linelen, '=') + 1;
- proto_tree_add_string(sip_element_tree,
- hf_sip_tag, tvb,
- tag_offset, (line_end_offset - tag_offset),
- tvb_format_text(tvb, tag_offset, (line_end_offset - tag_offset)));
-
- }
- else {
- proto_tree_add_string_format(sip_element_tree,
- hf_sip_to_addr, tvb,
- offset, line_end_offset - offset,
- value, "%s",
- tvb_format_text(tvb, offset, linelen));
- }/* if c= t */
- } /* if tag offset */
+ sip_element_tree = proto_item_add_subtree( sip_element_item,
+ ett_sip_element);
+ tag_offset = tvb_find_guint8(tvb, offset,linelen, ';');
+ if ( tag_offset != -1){
+ tag_offset = tag_offset + 1;
+ c = tvb_get_guint8(tvb,tag_offset);
+ if ( c == 't' ){/* tag found */
+ proto_tree_add_string(sip_element_tree,
+ hf_sip_to_addr, tvb,
+ value_offset, (tag_offset - value_offset - 1),
+ tvb_format_text(tvb, value_offset,
+ ( tag_offset - value_offset - 1)));
+ tag_offset = tvb_find_guint8(tvb, tag_offset,linelen, '=') + 1;
+ proto_tree_add_string(sip_element_tree,
+ hf_sip_tag, tvb,
+ tag_offset, (line_end_offset - tag_offset),
+ tvb_format_text(tvb, tag_offset, (line_end_offset - tag_offset)));
+
+ }
+ else {
+ proto_tree_add_string_format(sip_element_tree,
+ hf_sip_to_addr, tvb,
+ offset, line_end_offset - offset,
+ value, "%s",
+ tvb_format_text(tvb, offset, linelen));
+ }/* if c= t */
+ } /* if tag offset */
break;
- case POS_FROM :
- sip_element_item = proto_tree_add_string_format(hdr_tree,
- hf_header_array[hf_index], tvb,
- offset, next_offset - offset,
- value, "%s",
- tvb_format_text(tvb, offset, linelen));
- sip_element_tree = proto_item_add_subtree( sip_element_item, ett_sip_element);
- tag_offset = tvb_find_guint8(tvb, offset,linelen, ';');
- if ( tag_offset != -1){
- tag_offset = tag_offset + 1;
- c = tvb_get_guint8(tvb,tag_offset);
- if ( c == 't' ){/* tag found */
- proto_tree_add_string(sip_element_tree,
- hf_sip_from_addr, tvb,
- value_offset, (tag_offset - value_offset - 1),
- tvb_format_text(tvb, value_offset, ( tag_offset - value_offset - 1)));
- tag_offset = tvb_find_guint8(tvb, offset,linelen, '=') + 1;
- proto_tree_add_string(sip_element_tree,
- hf_sip_tag, tvb,
- tag_offset, (line_end_offset - tag_offset),
- tvb_format_text(tvb, tag_offset, (line_end_offset - tag_offset)));
- }
- else {
- tag_offset = tvb_find_guint8(tvb, tag_offset,linelen, ';');
- if ( tag_offset != -1){
- tag_offset = tag_offset + 1;
- c = tvb_get_guint8(tvb,tag_offset);
- if ( c == 't' ){/* tag found */
- proto_tree_add_string(sip_element_tree,
- hf_sip_from_addr, tvb,
- value_offset, (tag_offset - value_offset - 1),
- tvb_format_text(tvb, value_offset, ( tag_offset - value_offset - 1)));
- tag_offset = tvb_find_guint8(tvb, tag_offset,linelen, '=') + 1;
- proto_tree_add_string(sip_element_tree,
- hf_sip_tag, tvb,
- tag_offset, (line_end_offset - tag_offset),
- tvb_format_text(tvb, tag_offset, (line_end_offset - tag_offset)));
- }
+ case POS_FROM :
+ sip_element_item = proto_tree_add_string_format(hdr_tree,
+ hf_header_array[hf_index], tvb,
+ offset, next_offset - offset,
+ value, "%s",
+ tvb_format_text(tvb, offset, linelen));
+ sip_element_tree = proto_item_add_subtree( sip_element_item, ett_sip_element);
+ tag_offset = tvb_find_guint8(tvb, offset,linelen, ';');
+ if ( tag_offset != -1){
+ tag_offset = tag_offset + 1;
+ c = tvb_get_guint8(tvb,tag_offset);
+ if ( c == 't' ){/* tag found */
+ proto_tree_add_string(sip_element_tree,
+ hf_sip_from_addr, tvb,
+ value_offset, (tag_offset - value_offset - 1),
+ tvb_format_text(tvb, value_offset, ( tag_offset - value_offset - 1)));
+ tag_offset = tvb_find_guint8(tvb, offset,linelen, '=') + 1;
+ proto_tree_add_string(sip_element_tree,
+ hf_sip_tag, tvb,
+ tag_offset, (line_end_offset - tag_offset),
+ tvb_format_text(tvb, tag_offset, (line_end_offset - tag_offset)));
+ }
+ else {
+ tag_offset = tvb_find_guint8(tvb, tag_offset,linelen, ';');
+ if ( tag_offset != -1){
+ tag_offset = tag_offset + 1;
+ c = tvb_get_guint8(tvb,tag_offset);
+ if ( c == 't' ){/* tag found */
+ proto_tree_add_string(sip_element_tree,
+ hf_sip_from_addr, tvb,
+ value_offset, (tag_offset - value_offset - 1),
+ tvb_format_text(tvb, value_offset, ( tag_offset - value_offset - 1)));
+ tag_offset = tvb_find_guint8(tvb, tag_offset,linelen, '=') + 1;
+ proto_tree_add_string(sip_element_tree,
+ hf_sip_tag, tvb,
+ tag_offset, (line_end_offset - tag_offset),
+ tvb_format_text(tvb, tag_offset, (line_end_offset - tag_offset)));
}
- }/* if c= t */
- } /* if tag offset */
- break;
- case POS_CSEQ :
- /* Extract method name from value */
- for (value_offset = 0; value_offset < (gint)strlen(value); value_offset++)
- {
- if (isalpha(value[value_offset]))
- {
- strcpy(csec_method,value+value_offset);
- break;
}
- }
- /* Add 'CSeq' string item to tree */
- proto_tree_add_string_format(hdr_tree,
- hf_header_array[hf_index], tvb,
- offset, next_offset - offset,
- value, "%s",
- tvb_format_text(tvb, offset, linelen));
+ }/* if c= t */
+ } /* if tag offset */
break;
- case POS_EXPIRES :
- if (strcmp(value, "0") == 0)
+ case POS_CSEQ :
+ /* Extract method name from value */
+ for (value_offset = 0; value_offset < (gint)strlen(value); value_offset++)
+ {
+ if (isalpha(value[value_offset]))
{
- expires_is_0 = 1;
+ strcpy(csec_method,value+value_offset);
+ break;
}
- /* Add 'Expires' string item to tree */
- proto_tree_add_string_format(hdr_tree,
- hf_header_array[hf_index], tvb,
- offset, next_offset - offset,
- value, "%s",
- tvb_format_text(tvb, offset, linelen));
+ }
+ /* Add 'CSeq' string item to tree */
+ proto_tree_add_string_format(hdr_tree,
+ hf_header_array[hf_index], tvb,
+ offset, next_offset - offset,
+ value, "%s",
+ tvb_format_text(tvb, offset, linelen));
break;
- case POS_CONTACT :
- contacts++;
- if (strcmp(value, "*") == 0)
- {
- contact_is_star = 1;
+ case POS_EXPIRES :
+ if (strcmp(value, "0") == 0)
+ {
+ expires_is_0 = 1;
+ }
+ /* Add 'Expires' string item to tree */
+ proto_tree_add_string_format(hdr_tree,
+ hf_header_array[hf_index], tvb,
+ offset, next_offset - offset,
+ value, "%s",
+ tvb_format_text(tvb, offset, linelen));
+ break;
+
+ /*
+ * Content-Type is the same as Internet
+ * media type used by other dissectors,
+ * appropriate dissector found by
+ * lookup in "media_type" dissector table.
+ */
+ case POS_CONTENT_TYPE :
+ proto_tree_add_string_format(hdr_tree,
+ hf_header_array[hf_index], tvb,
+ offset, next_offset - offset,
+ value, "%s",
+ tvb_format_text(tvb, offset, linelen));
+ content_type_len = value_len;
+ semicolon_offset = tvb_find_guint8(tvb, value_offset,linelen, ';');
+ if ( semicolon_offset != -1) {
+ content_type_len = semicolon_offset - value_offset;
+ }
+ media_type_str = tvb_get_string(tvb, value_offset, content_type_len);
+ if (strcmp(media_type_str, "multipart/mixed") == 0)
+ {
+ left_quote_offset = tvb_find_guint8(tvb, value_offset,linelen, '"');
+ if ( left_quote_offset !=-1 ){
+ right_quote_offset = tvb_find_guint8(tvb, left_quote_offset + 1,linelen, '"');
+ boundary_str_len = right_quote_offset - left_quote_offset - 1;
+ boundary_str = tvb_get_string(tvb, left_quote_offset + 1, boundary_str_len);
}
- /* Fall through to default case to add string to tree */
- default :
- proto_tree_add_string_format(hdr_tree,
- hf_header_array[hf_index], tvb,
- offset, next_offset - offset,
- value, "%s",
- tvb_format_text(tvb, offset, linelen));
+ }
break;
- }/* end switch */
- g_free(value);
- }/*if HF_index */
- }/* if colon_offset */
- }/* if tree */
+ case POS_CONTACT :
+ contacts++;
+ if (strcmp(value, "*") == 0)
+ {
+ contact_is_star = 1;
+ }
+ /* Fall through to default case to add string to tree */
+ default :
+ proto_tree_add_string_format(hdr_tree,
+ hf_header_array[hf_index], tvb,
+ offset, next_offset - offset,
+ value, "%s",
+ tvb_format_text(tvb, offset, linelen));
+ break;
+ }/* end switch */
+ g_free(value);
+ }/*if HF_index */
+ }/* if colon_offset */
offset = next_offset;
}/* End while */
if (tvb_offset_exists(tvb, next_offset)) {
+
/*
* There's a message body starting at "next_offset".
* Set the length of the SIP portion and of the
@@ -689,7 +724,25 @@ dissect_sip_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
proto_item_set_end(ts, tvb, next_offset);
proto_item_set_end(th, tvb, next_offset);
next_tvb = tvb_new_subset(tvb, next_offset, -1, -1);
- call_dissector(sdp_handle, next_tvb, pinfo, tree);
+ ti = proto_tree_add_text(sip_tree, next_tvb, 0, -1,
+ "Message body");
+ message_body_tree = proto_item_add_subtree(ti, ett_sip_message_body);
+ found_match = dissector_try_string(media_type_dissector_table,
+ media_type_str , next_tvb, pinfo, message_body_tree);
+ g_free(media_type_str);
+ g_free(boundary_str);
+ /* If no match dump as text */
+ if ( found_match != TRUE )
+ {
+ offset = 0;
+ while (tvb_offset_exists(next_tvb, offset)) {
+ tvb_find_line_end(next_tvb, offset, -1, &next_offset, FALSE);
+ linelen = next_offset - offset;
+ proto_tree_add_text(message_body_tree, next_tvb, offset, linelen,
+ "%s", tvb_format_text(next_tvb, offset, linelen));
+ offset = next_offset;
+ }/* end while */
+ }
}
@@ -1343,8 +1396,8 @@ void proto_register_sip(void)
&ett_sip_reqresp,
&ett_sip_hdr,
&ett_sip_element,
+ &ett_sip_message_body,
};
-
static gint *ett_raw[] = {
&ett_raw_text,
};
@@ -1362,6 +1415,11 @@ void proto_register_sip(void)
proto_register_subtree_array(ett, array_length(ett));
proto_register_subtree_array(ett_raw, array_length(ett_raw));
+ /* SIP content type and internet media type used by other dissectors are the same */
+
+ media_type_dissector_table = find_dissector_table("media_type");
+
+
sip_module = prefs_register_protocol(proto_sip, NULL);
prefs_register_bool_preference(sip_module, "display_raw_text",
@@ -1387,8 +1445,4 @@ proto_reg_handoff_sip(void)
heur_dissector_add("tcp", dissect_sip_heur, proto_sip);
heur_dissector_add("sctp", dissect_sip_heur, proto_sip);
- /*
- * Get a handle for the SDP dissector.
- */
- sdp_handle = find_dissector("sdp");
}