diff options
Diffstat (limited to 'epan')
-rw-r--r-- | epan/CMakeLists.txt | 1 | ||||
-rw-r--r-- | epan/Makefile.am | 2 | ||||
-rw-r--r-- | epan/dissectors/packet-http-urlencoded.c | 15 | ||||
-rw-r--r-- | epan/dissectors/packet-http.c | 25 | ||||
-rw-r--r-- | epan/dissectors/packet-http.h | 13 | ||||
-rw-r--r-- | epan/dissectors/packet-imf.c | 7 | ||||
-rw-r--r-- | epan/dissectors/packet-ipp.c | 24 | ||||
-rw-r--r-- | epan/dissectors/packet-isup.c | 59 | ||||
-rw-r--r-- | epan/dissectors/packet-json.c | 15 | ||||
-rw-r--r-- | epan/dissectors/packet-jxta.c | 9 | ||||
-rw-r--r-- | epan/dissectors/packet-media.c | 8 | ||||
-rw-r--r-- | epan/dissectors/packet-msrp.c | 7 | ||||
-rw-r--r-- | epan/dissectors/packet-multipart.c | 143 | ||||
-rw-r--r-- | epan/dissectors/packet-sip.c | 10 | ||||
-rw-r--r-- | epan/dissectors/packet-spdy.c | 16 | ||||
-rw-r--r-- | epan/dissectors/packet-text-media.c | 14 | ||||
-rw-r--r-- | epan/media_params.c | 133 | ||||
-rw-r--r-- | epan/media_params.h | 52 |
18 files changed, 379 insertions, 174 deletions
diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt index 540b480fac..5b31d8a838 100644 --- a/epan/CMakeLists.txt +++ b/epan/CMakeLists.txt @@ -127,6 +127,7 @@ set(LIBWIRESHARK_FILES in_cksum.c ipproto.c ipv4.c + media_params.c next_tvb.c oids.c osi-utils.c diff --git a/epan/Makefile.am b/epan/Makefile.am index 49a8e7cb4c..11a2300614 100644 --- a/epan/Makefile.am +++ b/epan/Makefile.am @@ -89,6 +89,7 @@ LIBWIRESHARK_SRC = \ in_cksum.c \ ipproto.c \ ipv4.c \ + media_params.c \ next_tvb.c \ oids.c \ osi-utils.c \ @@ -237,6 +238,7 @@ LIBWIRESHARK_INCLUDES = \ ipv6.h \ lapd_sapi.h \ llcsaps.h \ + media_params.h \ next_tvb.h \ nlpid.h \ oids.h \ diff --git a/epan/dissectors/packet-http-urlencoded.c b/epan/dissectors/packet-http-urlencoded.c index aca2185aaa..46f49e624b 100644 --- a/epan/dissectors/packet-http-urlencoded.c +++ b/epan/dissectors/packet-http-urlencoded.c @@ -27,6 +27,8 @@ #include <epan/packet.h> #include <wsutil/str_util.h> +#include "packet-http.h" + void proto_register_http_urlencoded(void); void proto_reg_handoff_http_urlencoded(void); @@ -123,18 +125,27 @@ dissect_form_urlencoded(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, voi proto_item *ti; gint offset = 0, next_offset; const char *data_name; + http_message_info_t *message_info; data_name = pinfo->match_string; if (! (data_name && data_name[0])) { /* * No information from "match_string" */ - data_name = (char *)data; - if (! (data_name && data_name[0])) { + message_info = (http_message_info_t *)data; + if (message_info == NULL) { /* * No information from dissector data */ data_name = NULL; + } else { + data_name = message_info->media_str; + if (! (data_name && data_name[0])) { + /* + * No information from dissector data + */ + data_name = NULL; + } } } diff --git a/epan/dissectors/packet-http.c b/epan/dissectors/packet-http.c index edde7974fa..e38224f9fc 100644 --- a/epan/dissectors/packet-http.c +++ b/epan/dissectors/packet-http.c @@ -49,14 +49,6 @@ #include "packet-tcp.h" #include "packet-ssl.h" -typedef enum _http_type { - HTTP_REQUEST, - HTTP_RESPONSE, - HTTP_NOTIFICATION, - HTTP_OTHERS -} http_type_t; - - void proto_register_http(void); void proto_reg_handoff_http(void); void proto_register_message_http(void); @@ -764,6 +756,7 @@ dissect_http_message(tvbuff_t *tvb, int offset, packet_info *pinfo, int reported_length; guint16 word; gboolean leading_crlf = FALSE; + http_message_info_t message_info; reported_length = tvb_reported_length_remaining(tvb, offset); if (reported_length < 1) { @@ -1428,13 +1421,13 @@ dissect_http_message(tvbuff_t *tvb, int offset, packet_info *pinfo, if (headers.content_encoding != NULL && g_ascii_strcasecmp(headers.content_encoding, "identity") != 0) { /* - * We currently can't handle, for example, "compress"; + * We currently don't handle, for example, "compress"; * just handle them as data for now. * - * After July 7, 2004 the LZW patent expires, so support - * might be added then. However, I don't think that - * anybody ever really implemented "compress", due to - * the aforementioned patent. + * After July 7, 2004 the LZW patent expired, so + * support could be added. However, I don't think + * that anybody ever really implemented "compress", + * due to the aforementioned patent. */ tvbuff_t *uncomp_tvb = NULL; proto_item *e_ti = NULL; @@ -1559,11 +1552,13 @@ dissect_http_message(tvbuff_t *tvb, int offset, packet_info *pinfo, pinfo->match_uint); } + message_info.type = http_type; + message_info.media_str = media_str; if (handle != NULL) { /* * We have a subdissector - call it. */ - dissected = call_dissector_only(handle, next_tvb, pinfo, tree, media_str); + dissected = call_dissector_only(handle, next_tvb, pinfo, tree, &message_info); if (!dissected) expert_add_info(pinfo, http_tree, &ei_http_subdissector_failed); } @@ -1591,7 +1586,7 @@ dissect_http_message(tvbuff_t *tvb, int offset, packet_info *pinfo, * Calling the default media handle if there is a content-type that * wasn't handled above. */ - call_dissector_with_data(media_handle, next_tvb, pinfo, tree, media_str); + call_dissector_with_data(media_handle, next_tvb, pinfo, tree, &message_info); } else { /* Call the default data dissector */ call_data_dissector(next_tvb, pinfo, http_tree); diff --git a/epan/dissectors/packet-http.h b/epan/dissectors/packet-http.h index 179ca200a0..2ff906ca57 100644 --- a/epan/dissectors/packet-http.h +++ b/epan/dissectors/packet-http.h @@ -85,4 +85,17 @@ typedef struct _http_conv_t { http_req_res_t *req_res_tail; } http_conv_t; +typedef enum _http_type { + HTTP_REQUEST, + HTTP_RESPONSE, + HTTP_NOTIFICATION, + HTTP_OTHERS +} http_type_t; + +/** Passed to dissectors called by the HTTP dissector. */ +typedef struct _http_message_info_t { + http_type_t type; /* Message type; may be HTTP_OTHERS if not called by HTTP */ + const char *media_str; /* Content-Type parameters */ +} http_message_info_t; + #endif /* __PACKET_HTTP_H__ */ diff --git a/epan/dissectors/packet-imf.c b/epan/dissectors/packet-imf.c index b84ae91c3d..66a335c6de 100644 --- a/epan/dissectors/packet-imf.c +++ b/epan/dissectors/packet-imf.c @@ -31,6 +31,7 @@ #include <wsutil/str_util.h> #include "packet-ber.h" +#include "packet-http.h" #include "packet-imf.h" #include "packet-ess.h" #include "packet-p1.h" @@ -813,6 +814,8 @@ dissect_imf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) /* now dissect the MIME based upon the content type */ if(content_type_str && media_type_dissector_table) { + http_message_info_t message_info; + col_set_fence(pinfo->cinfo, COL_INFO); if(content_encoding_str && !g_ascii_strncasecmp(content_encoding_str, "base64", 6)) { @@ -823,7 +826,9 @@ dissect_imf(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) next_tvb = tvb_new_subset_remaining(tvb, end_offset); } - dissector_try_string(media_type_dissector_table, content_type_str, next_tvb, pinfo, tree, (void*)parameters); + message_info.type = HTTP_OTHERS; + message_info.media_str = parameters; + dissector_try_string(media_type_dissector_table, content_type_str, next_tvb, pinfo, tree, (void*)&message_info); } else { /* just show the lines or highlight the rest of the buffer as message text */ diff --git a/epan/dissectors/packet-ipp.c b/epan/dissectors/packet-ipp.c index e0447bbb2d..481a05378b 100644 --- a/epan/dissectors/packet-ipp.c +++ b/epan/dissectors/packet-ipp.c @@ -189,16 +189,34 @@ static int add_value_head(const gchar *tag_desc, proto_tree *tree, tvbuff_t *tvb, int offset, int name_length, int value_length, char **name_val); static int -dissect_ipp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_) +dissect_ipp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) { proto_tree *ipp_tree; proto_item *ti; int offset = 0; - gboolean is_request = (pinfo->destport == pinfo->match_uint); - /* XXX - should this be based on the HTTP header? */ + http_message_info_t *message_info = (http_message_info_t *)data; + gboolean is_request; guint16 status_code; const gchar *status_type; + if (message_info != NULL) { + switch (message_info->type) { + + case HTTP_REQUEST: + is_request = TRUE; + break; + + case HTTP_RESPONSE: + is_request = FALSE; + break; + + default: + is_request = (pinfo->destport == pinfo->match_uint); + break; + } + } else + is_request = (pinfo->destport == pinfo->match_uint); + col_set_str(pinfo->cinfo, COL_PROTOCOL, "IPP"); if (is_request) col_set_str(pinfo->cinfo, COL_INFO, "IPP request"); diff --git a/epan/dissectors/packet-isup.c b/epan/dissectors/packet-isup.c index d161f7fd26..37a9126f97 100644 --- a/epan/dissectors/packet-isup.c +++ b/epan/dissectors/packet-isup.c @@ -38,6 +38,7 @@ * * National variants * French ISUP Specification: SPIROU 1998 - 002-005 edition 1 ( Info found here http://www.icg-corp.com/docs/ISUP.pdf ). + * See also http://www.fftelecoms.org/sites/default/files/contenus_lies/fft_interco_ip_-_sip-i_interface_specification_v1_0.pdf * Israeli ISUP Specification: excertp (for BCM message) found in https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=4231 . * Russian national ISUP-R 2000: RD 45.217-2001 book 4 * Japan ISUP http://www.ttc.or.jp/jp/document_list/sum/sum_JT-Q763v21.1.pdf @@ -54,12 +55,14 @@ #include <epan/sctpppids.h> #include <epan/reassemble.h> #include <epan/to_str.h> +#include <epan/media_params.h> #include <wsutil/str_util.h> #include "packet-q931.h" #include "packet-isup.h" #include "packet-e164.h" #include "packet-charging_ase.h" #include "packet-mtp3.h" +#include "packet-http.h" void proto_register_isup(void); void proto_reg_handoff_isup(void); @@ -10419,31 +10422,47 @@ dissect_application_isup(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, vo proto_tree *isup_tree = NULL; tvbuff_t *message_tvb; guint8 message_type; - gchar *content_type_parameter_str; + const char *version, *base; + int len_version, len_base; guint8 itu_isup_variant = ISUP_ITU_STANDARD_VARIANT; /* Default */ if (data) { - content_type_parameter_str = ascii_strdown_inplace((gchar *)data); - if (strstr(content_type_parameter_str, "ansi")) { - isup_standard = ANSI_STANDARD; - col_append_str(pinfo->cinfo, COL_PROTOCOL, "/ISUP(ANSI)"); - message_type = tvb_get_guint8(tvb, 0); - /* application/ISUP has no CIC */ - col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ", - "ISUP:%s", - val_to_str_ext_const(message_type, &ansi_isup_message_type_value_acro_ext, "reserved")); - if (tree) { - ti = proto_tree_add_item(tree, proto_isup, tvb, 0, -1, ENC_NA); - isup_tree = proto_item_add_subtree(ti, ett_isup); - } + http_message_info_t *message_info = (http_message_info_t *)data; + if (message_info->media_str) { + version = find_parameter(message_info->media_str, "version=", &len_version); + base = find_parameter(message_info->media_str, "base=", &len_base); + if ((version && len_version >= 4 && g_ascii_strncasecmp(version, "ansi", 4) == 0) || + (base && len_base >= 4 && g_ascii_strncasecmp(base, "ansi", 4) == 0)) { + /* + * "version" or "base" parameter begins with "ansi", so it's ANSI. + */ + isup_standard = ANSI_STANDARD; + col_append_str(pinfo->cinfo, COL_PROTOCOL, "/ISUP(ANSI)"); + message_type = tvb_get_guint8(tvb, 0); + /* application/ISUP has no CIC */ + col_append_sep_fstr(pinfo->cinfo, COL_INFO, ", ", + "ISUP:%s", + val_to_str_ext_const(message_type, &ansi_isup_message_type_value_acro_ext, "reserved")); + if (tree) { + ti = proto_tree_add_item(tree, proto_isup, tvb, 0, -1, ENC_NA); + isup_tree = proto_item_add_subtree(ti, ett_isup); + } - message_tvb = tvb_new_subset_remaining(tvb, 0); - dissect_ansi_isup_message(message_tvb, pinfo, isup_tree, ISUP_ITU_STANDARD_VARIANT, 0); - return tvb_reported_length(tvb); - } else if (strstr(content_type_parameter_str, "spirou")) { - isup_standard = ITU_STANDARD; - itu_isup_variant = ISUP_FRENCH_VARIANT; + message_tvb = tvb_new_subset_remaining(tvb, 0); + dissect_ansi_isup_message(message_tvb, pinfo, isup_tree, ISUP_ITU_STANDARD_VARIANT, 0); + return tvb_reported_length(tvb); + } else if ((version && g_ascii_strncasecmp(version, "spirou", len_version) == 0) || + (base && g_ascii_strncasecmp(base, "spirou", len_base) == 0)) { + /* + * "version" or "base" version is "spirou", so it's SPIROU. + */ + isup_standard = ITU_STANDARD; + itu_isup_variant = ISUP_FRENCH_VARIANT; + } else { + isup_standard = ITU_STANDARD; + } } else { + /* default to ITU */ isup_standard = ITU_STANDARD; } } else { diff --git a/epan/dissectors/packet-json.c b/epan/dissectors/packet-json.c index 044403b7b9..1fa50ea182 100644 --- a/epan/dissectors/packet-json.c +++ b/epan/dissectors/packet-json.c @@ -38,6 +38,8 @@ #include <wiretap/wtap.h> +#include "packet-http.h" + void proto_register_json(void); void proto_reg_handoff_json(void); static char *json_string_unescape(tvbparse_elem_t *tok); @@ -116,6 +118,7 @@ dissect_json(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) json_parser_data_t parser_data; tvbparse_t *tt; + http_message_info_t *message_info; const char *data_name; int offset; @@ -138,12 +141,20 @@ dissect_json(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data) /* * No information from "match_string" */ - data_name = (char *)data; - if (! (data_name && data_name[0])) { + message_info = (http_message_info_t *)data; + if (message_info == NULL) { /* * No information from dissector data */ data_name = NULL; + } else { + data_name = message_info->media_str; + if (! (data_name && data_name[0])) { + /* + * No information from dissector data + */ + data_name = NULL; + } } } diff --git a/epan/dissectors/packet-jxta.c b/epan/dissectors/packet-jxta.c index a0ea257cce..cf3681fad0 100644 --- a/epan/dissectors/packet-jxta.c +++ b/epan/dissectors/packet-jxta.c @@ -42,6 +42,7 @@ #include <wsutil/str_util.h> #include "packet-jxta.h" +#include "packet-http.h" void proto_register_jxta(void); void proto_reg_handoff_jxta(void); @@ -2052,11 +2053,11 @@ static int dissect_media( const gchar* fullmediatype, tvbuff_t * tvb, packet_inf gchar *mediatype = wmem_strdup(wmem_packet_scope(), fullmediatype); gchar *parms_at = strchr(mediatype, ';'); const char *save_match_string = pinfo->match_string; - char *media_str = NULL; + http_message_info_t message_info = { HTTP_OTHERS, NULL }; /* Based upon what is done in packet-media.c we set up type and params */ if (NULL != parms_at) { - media_str = wmem_strdup( wmem_packet_scope(), parms_at + 1 ); + message_info.media_str = wmem_strdup( wmem_packet_scope(), parms_at + 1 ); *parms_at = '\0'; } @@ -2086,7 +2087,7 @@ static int dissect_media( const gchar* fullmediatype, tvbuff_t * tvb, packet_inf } } } else { - dissected = dissector_try_string(media_type_dissector_table, mediatype, tvb, pinfo, tree, media_str) ? tvb_captured_length(tvb) : 0; + dissected = dissector_try_string(media_type_dissector_table, mediatype, tvb, pinfo, tree, &message_info) ? tvb_captured_length(tvb) : 0; if( dissected != (int) tvb_captured_length(tvb) ) { /* g_message( "%s : %d expected, %d dissected", mediatype, tvb_captured_length(tvb), dissected ); */ @@ -2094,7 +2095,7 @@ static int dissect_media( const gchar* fullmediatype, tvbuff_t * tvb, packet_inf } if (0 == dissected) { - dissected = call_dissector_with_data(media_handle, tvb, pinfo, tree, media_str); + dissected = call_dissector_with_data(media_handle, tvb, pinfo, tree, &message_info); } pinfo->match_string = save_match_string; diff --git a/epan/dissectors/packet-media.c b/epan/dissectors/packet-media.c index 5e6355f060..351e460773 100644 --- a/epan/dissectors/packet-media.c +++ b/epan/dissectors/packet-media.c @@ -32,6 +32,8 @@ #include <wsutil/str_util.h> +#include "packet-http.h" + void proto_register_media(void); /* proto_media cannot be static because it's referenced in the @@ -48,6 +50,7 @@ dissect_media(tvbuff_t *tvb, packet_info *pinfo , proto_tree *tree, void* data) int bytes; proto_item *ti; proto_tree *media_tree = 0; + http_message_info_t *message_info = (http_message_info_t *)data; heur_dtbl_entry_t *hdtbl_entry; if (dissector_try_heuristic(heur_subdissector_list, tvb, pinfo, tree, &hdtbl_entry, data)) { @@ -63,11 +66,12 @@ dissect_media(tvbuff_t *tvb, packet_info *pinfo , proto_tree *tree, void* data) ti = proto_tree_add_item(tree, proto_media, tvb, 0, -1, ENC_NA); media_tree = proto_item_add_subtree(ti, ett_media); - if (data) { + if (message_info != NULL && message_info->media_str != NULL) { /* The media type has parameters */ + proto_tree_add_bytes_format_value(media_tree, hf_media_type, tvb, 0, bytes, NULL, "%s; %s (%d byte%s)", - pinfo->match_string, (char *)data, + pinfo->match_string, message_info->media_str, bytes, plurality(bytes, "", "s")); } else { /* The media type has no parameters */ diff --git a/epan/dissectors/packet-msrp.c b/epan/dissectors/packet-msrp.c index c8b08c174f..79f380d049 100644 --- a/epan/dissectors/packet-msrp.c +++ b/epan/dissectors/packet-msrp.c @@ -36,6 +36,7 @@ #include <wsutil/str_util.h> #include "packet-msrp.h" +#include "packet-http.h" void proto_register_msrp(void); void proto_reg_handoff_msrp(void); @@ -471,7 +472,7 @@ dissect_msrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_ int found_match = 0; gint content_type_len, content_type_parameter_str_len; gchar *media_type_str_lower_case = NULL; - char *content_type_parameter_str = NULL; + http_message_info_t message_info = { HTTP_OTHERS, NULL }; tvbuff_t *next_tvb; gint parameter_offset; gint semi_colon_offset; @@ -655,7 +656,7 @@ dissect_msrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_ parameter_offset++; content_type_len = semi_colon_offset - value_offset; content_type_parameter_str_len = line_end_offset - parameter_offset; - content_type_parameter_str = tvb_get_string_enc(wmem_packet_scope(), tvb, + message_info.media_str = tvb_get_string_enc(wmem_packet_scope(), tvb, parameter_offset, content_type_parameter_str_len, ENC_UTF_8|ENC_NA); } media_type_str_lower_case = ascii_strdown_inplace( @@ -689,7 +690,7 @@ dissect_msrp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_ found_match = dissector_try_string(media_type_dissector_table, media_type_str_lower_case, next_tvb, pinfo, - msrp_data_tree, content_type_parameter_str); + msrp_data_tree, &message_info); /* If no match dump as text */ } if ( found_match == 0 ) diff --git a/epan/dissectors/packet-multipart.c b/epan/dissectors/packet-multipart.c index 760e76b56f..32107aefb0 100644 --- a/epan/dissectors/packet-multipart.c +++ b/epan/dissectors/packet-multipart.c @@ -59,12 +59,14 @@ #include <epan/packet.h> #include <epan/expert.h> +#include <epan/media_params.h> #include <epan/prefs.h> #include <wsutil/str_util.h> #include "packet-imf.h" #include "packet-dcerpc.h" #include "packet-gssapi.h" +#include "packet-http.h" void proto_register_multipart(void); void proto_reg_handoff_multipart(void); @@ -179,13 +181,12 @@ static gint process_preamble(proto_tree *tree, tvbuff_t *tvb, multipart_info_t *m_info, gboolean *last_boundary); static gint -process_body_part(proto_tree *tree, tvbuff_t *tvb, multipart_info_t *m_info, +process_body_part(proto_tree *tree, tvbuff_t *tvb, + http_message_info_t *input_message_info, multipart_info_t *m_info, packet_info *pinfo, gint start, gint idx, gboolean *last_boundary); static gint is_known_multipart_header(const char *header_str, guint len); -static gint -index_of_char(const char *str, const char c); /* Return a tvb that contains the binary representation of a base64 @@ -310,96 +311,6 @@ unfold_and_compact_mime_header(const char *lines, gint *first_colon_offset) return (ret); } -/* Return the index of a given char in the given string, - * or -1 if not found. - */ -static gint -index_of_char(const char *str, const char c) -{ - gint len = 0; - const char *p = str; - - while (*p && *p != c) { - p++; - len++; - } - - if (*p) - return len; - return -1; -} - -static char *find_parameter(char *parameters, const char *key, int *retlen) -{ - char *start, *p; - int keylen = 0; - int len = 0; - - if(!parameters || !*parameters || !key || strlen(key) == 0) - /* we won't be able to find anything */ - return NULL; - - keylen = (int) strlen(key); - p = parameters; - - while (*p) { - - while ((*p) && g_ascii_isspace(*p)) - p++; /* Skip white space */ - - if (g_ascii_strncasecmp(p, key, keylen) == 0) - break; - /* Skip to next parameter */ - p = strchr(p, ';'); - if (p == NULL) - { - return NULL; - } - p++; /* Skip semicolon */ - - } - if (*p == 0x0) - return NULL; /* key wasn't found */ - - start = p + keylen; - if (start[0] == 0) { - return NULL; - } - - /* - * Process the parameter value - */ - if (start[0] == '"') { - /* - * Parameter value is a quoted-string - */ - start++; /* Skip the quote */ - len = index_of_char(start, '"'); - if (len < 0) { - /* - * No closing quote - */ - return NULL; - } - } else { - /* - * Look for end of boundary - */ - p = start; - while (*p) { - if (*p == ';' || g_ascii_isspace(*p)) - break; - p++; - len++; - } - } - - if(retlen) - (*retlen) = len; - - return start; -} - /* Retrieve the media information from pinfo->private_data, * and compute the boundary string and its length. * Return a pointer to a filled-in multipart_info_t, or NULL on failure. @@ -409,7 +320,7 @@ static char *find_parameter(char *parameters, const char *key, int *retlen) * leading hyphens. (quote from rfc2046) */ static multipart_info_t * -get_multipart_info(packet_info *pinfo, const char *str) +get_multipart_info(packet_info *pinfo, http_message_info_t *message_info) { const char *start_boundary, *start_protocol = NULL; int len_boundary = 0, len_protocol = 0; @@ -418,16 +329,22 @@ get_multipart_info(packet_info *pinfo, const char *str) char *parameters; gint dummy; - if ((type == NULL) || (str == NULL)) { - /* - * We need both a content type AND parameters - * for multipart dissection. - */ + /* + * We need both a content type AND parameters + * for multipart dissection. + */ + if (type == NULL) { + return NULL; + } + if (message_info == NULL) { + return NULL; + } + if (message_info->media_str == NULL) { return NULL; } /* Clean up the parameters */ - parameters = unfold_and_compact_mime_header(str, &dummy); + parameters = unfold_and_compact_mime_header(message_info->media_str, &dummy); start_boundary = find_parameter(parameters, "boundary=", &len_boundary); @@ -626,14 +543,15 @@ dissect_kerberos_encrypted_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree * Return the offset to the start of the next body-part. */ static gint -process_body_part(proto_tree *tree, tvbuff_t *tvb, multipart_info_t *m_info, +process_body_part(proto_tree *tree, tvbuff_t *tvb, + http_message_info_t *input_message_info, multipart_info_t *m_info, packet_info *pinfo, gint start, gint idx, gboolean *last_boundary) { proto_tree *subtree; proto_item *ti; gint offset = start, next_offset = 0; - char *parameters = NULL; + http_message_info_t message_info = { input_message_info->type, NULL }; gint body_start, boundary_start, boundary_line_len; gchar *content_type_str = NULL; @@ -753,9 +671,9 @@ process_body_part(proto_tree *tree, tvbuff_t *tvb, multipart_info_t *m_info, if (semicolon_offset > 0) { value_str[semicolon_offset] = '\0'; - parameters = wmem_strdup(wmem_packet_scope(), value_str + semicolon_offset + 1); + message_info.media_str = wmem_strdup(wmem_packet_scope(), value_str + semicolon_offset + 1); } else { - parameters = NULL; + message_info.media_str = NULL; } content_type_str = wmem_ascii_strdown(wmem_packet_scope(), value_str, -1); @@ -764,7 +682,7 @@ process_body_part(proto_tree *tree, tvbuff_t *tvb, multipart_info_t *m_info, proto_item_append_text(ti, " (%s)", content_type_str); /* find the "name" parameter in case we don't find a content disposition "filename" */ - if((mimetypename = find_parameter(parameters, "name=", &len)) != NULL) { + if((mimetypename = find_parameter(message_info.media_str, "name=", &len)) != NULL) { mimetypename = g_strndup(mimetypename, len); } @@ -835,7 +753,7 @@ process_body_part(proto_tree *tree, tvbuff_t *tvb, multipart_info_t *m_info, tmp_tvb = encrypt.gssapi_decrypted_tvb; is_raw_data = FALSE; content_type_str = m_info->orig_content_type; - parameters = m_info->orig_parameters; + message_info.media_str = m_info->orig_parameters; } else if(encrypt.gssapi_encrypted_tvb) { tmp_tvb = encrypt.gssapi_encrypted_tvb; proto_tree_add_expert(tree, pinfo, &ei_multipart_decryption_not_possible, tmp_tvb, 0, -1); @@ -867,21 +785,21 @@ process_body_part(proto_tree *tree, tvbuff_t *tvb, multipart_info_t *m_info, * First try the dedicated multipart dissector table */ dissected = dissector_try_string(multipart_media_subdissector_table, - content_type_str, tmp_tvb, pinfo, subtree, parameters); + content_type_str, tmp_tvb, pinfo, subtree, &message_info); if (! dissected) { /* * Fall back to the default media dissector table */ dissected = dissector_try_string(media_type_dissector_table, - content_type_str, tmp_tvb, pinfo, subtree, parameters); + content_type_str, tmp_tvb, pinfo, subtree, &message_info); } if (! dissected) { const char *save_match_string = pinfo->match_string; pinfo->match_string = content_type_str; - call_dissector_with_data(media_handle, tmp_tvb, pinfo, subtree, parameters); + call_dissector_with_data(media_handle, tmp_tvb, pinfo, subtree, &message_info); pinfo->match_string = save_match_string; } - parameters = NULL; /* Shares same memory as content_type_str */ + message_info.media_str = NULL; /* Shares same memory as content_type_str */ } else { call_data_dissector(tmp_tvb, pinfo, subtree); } @@ -908,7 +826,8 @@ static int dissect_multipart(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree proto_tree *subtree; proto_item *ti; proto_item *type_ti; - multipart_info_t *m_info = get_multipart_info(pinfo, (const char*)data); + http_message_info_t *message_info = (http_message_info_t *)data; + multipart_info_t *m_info = get_multipart_info(pinfo, message_info); gint header_start = 0; gint body_index = 0; gboolean last_boundary = FALSE; @@ -952,7 +871,7 @@ static int dissect_multipart(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree * Process the encapsulated bodies */ while (last_boundary == FALSE) { - header_start = process_body_part(subtree, tvb, m_info, + header_start = process_body_part(subtree, tvb, message_info, m_info, pinfo, header_start, body_index++, &last_boundary); if (header_start == -1) { return tvb_reported_length(tvb); diff --git a/epan/dissectors/packet-sip.c b/epan/dissectors/packet-sip.c index aafd86ffb7..1670b4cb13 100644 --- a/epan/dissectors/packet-sip.c +++ b/epan/dissectors/packet-sip.c @@ -53,6 +53,8 @@ #include "packet-e164.h" #include "packet-sip.h" +#include "packet-http.h" + #include "packet-sdp.h" /* SDP needs a transport layer to determine request/response */ /* un-comment the following as well as this line in conversation.c, to enable debug printing */ @@ -2863,7 +2865,7 @@ dissect_sip_common(tvbuff_t *tvb, int offset, int remaining_length, packet_info char cseq_method[MAX_CSEQ_METHOD_SIZE] = ""; char call_id[MAX_CALL_ID_SIZE] = ""; gchar *media_type_str_lower_case = NULL; - char *content_type_parameter_str = NULL; + http_message_info_t message_info = { HTTP_OTHERS, NULL }; char *content_encoding_parameter_str = NULL; guint resend_for_packet = 0; guint request_for_response = 0; @@ -3614,7 +3616,7 @@ dissect_sip_common(tvbuff_t *tvb, int offset, int remaining_length, packet_info content_type_end = tvb_skip_wsp_return(tvb, semi_colon_offset-1); content_type_len = content_type_end - value_offset; content_type_parameter_str_len = value_offset + value_len - parameter_offset; - content_type_parameter_str = tvb_get_string_enc(wmem_packet_scope(), tvb, parameter_offset, + message_info.media_str = tvb_get_string_enc(wmem_packet_scope(), tvb, parameter_offset, content_type_parameter_str_len, ENC_UTF_8|ENC_NA); } media_type_str_lower_case = ascii_strdown_inplace( @@ -4168,7 +4170,7 @@ dissect_sip_common(tvbuff_t *tvb, int offset, int remaining_length, packet_info found_match = dissector_try_string(media_type_dissector_table, media_type_str_lower_case, next_tvb, pinfo, - message_body_tree, content_type_parameter_str); + message_body_tree, &message_info); DENDENT(); DPRINT(("done calling dissector_try_string() with found_match=%u", found_match)); @@ -4180,7 +4182,7 @@ dissect_sip_common(tvbuff_t *tvb, int offset, int remaining_length, packet_info found_match = dissector_try_string(media_type_dissector_table, "multipart/", next_tvb, pinfo, - message_body_tree, content_type_parameter_str); + message_body_tree, &message_info); DENDENT(); DPRINT(("done calling dissector_try_string() with found_match=%u", found_match)); } diff --git a/epan/dissectors/packet-spdy.c b/epan/dissectors/packet-spdy.c index 19640100ba..30835896c8 100644 --- a/epan/dissectors/packet-spdy.c +++ b/epan/dissectors/packet-spdy.c @@ -40,6 +40,7 @@ #include <epan/tap.h> #include "packet-tcp.h" #include "packet-ssl.h" +#include "packet-http.h" #ifdef HAVE_ZLIB #define ZLIB_CONST @@ -177,6 +178,7 @@ typedef struct _spdy_data_frame_t { } spdy_data_frame_t; typedef struct _spdy_stream_info_t { + http_type_t message_type; gchar *content_type; gchar *content_type_parameters; gchar *content_encoding; @@ -514,6 +516,7 @@ static spdy_conv_t * get_or_create_spdy_conversation_data(packet_info *pinfo) { */ static void spdy_save_stream_info(spdy_conv_t *conv_data, guint32 stream_id, + http_type_t message_type, gchar *content_type, gchar *content_type_params, gchar *content_encoding) { @@ -524,6 +527,7 @@ static void spdy_save_stream_info(spdy_conv_t *conv_data, } si = (spdy_stream_info_t *)wmem_alloc(wmem_file_scope(), sizeof(spdy_stream_info_t)); + si->message_type = message_type; si->content_type = content_type; si->content_type_parameters = content_type_params; si->content_encoding = content_encoding; @@ -725,6 +729,7 @@ static int dissect_spdy_data_payload(tvbuff_t *tvb, dissector_handle_t handle; guint num_data_frames; gboolean dissected; + http_message_info_t message_info; /* Add frame description. */ proto_item_append_text(spdy_proto, ", Stream: %d, Length: %d", @@ -911,11 +916,13 @@ static int dissect_spdy_data_payload(tvbuff_t *tvb, handle = dissector_get_string_handle(media_type_subdissector_table, si->content_type); } + message_info.type = si->message_type; + message_info.media_str = media_str; if (handle != NULL) { /* * We have a subdissector - call it. */ - dissected = call_dissector_with_data(handle, data_tvb, pinfo, spdy_tree, media_str); + dissected = call_dissector_with_data(handle, data_tvb, pinfo, spdy_tree, &message_info); } else { dissected = FALSE; } @@ -925,7 +932,7 @@ static int dissect_spdy_data_payload(tvbuff_t *tvb, * Calling the default media handle if there is a content-type that * wasn't handled above. */ - call_dissector_with_data(media_handle, next_tvb, pinfo, spdy_tree, media_str); + call_dissector_with_data(media_handle, next_tvb, pinfo, spdy_tree, &message_info); } else { /* Call the default data dissector */ call_data_dissector(next_tvb, pinfo, spdy_tree); @@ -1328,8 +1335,9 @@ static int dissect_spdy_header_payload( */ if (content_type != NULL && !pinfo->fd->flags.visited) { gchar *content_type_params = spdy_parse_content_type(content_type); - spdy_save_stream_info(conv_data, stream_id, content_type, - content_type_params, content_encoding); + spdy_save_stream_info(conv_data, stream_id, + (hdr_status == NULL) ? HTTP_REQUEST : HTTP_RESPONSE, + content_type, content_type_params, content_encoding); } return frame->length; diff --git a/epan/dissectors/packet-text-media.c b/epan/dissectors/packet-text-media.c index af480ef4c7..cc8de8c9a8 100644 --- a/epan/dissectors/packet-text-media.c +++ b/epan/dissectors/packet-text-media.c @@ -34,6 +34,7 @@ #include <epan/packet.h> +#include "packet-http.h" /* * Media dissector for line-based text media like text/plain, message/http. @@ -59,6 +60,7 @@ dissect_text_lines(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* da proto_item *ti; gint offset = 0, next_offset; gint len; + http_message_info_t *message_info; const char *data_name; int length = tvb_captured_length(tvb); @@ -78,12 +80,20 @@ dissect_text_lines(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* da /* * No information from "match_string" */ - data_name = (char *)data; - if (! (data_name && data_name[0])) { + message_info = (http_message_info_t *)data; + if (message_info == NULL) { /* * No information from dissector data */ data_name = NULL; + } else { + data_name = message_info->media_str; + if (! (data_name && data_name[0])) { + /* + * No information from dissector data + */ + data_name = NULL; + } } } diff --git a/epan/media_params.c b/epan/media_params.c new file mode 100644 index 0000000000..863025b437 --- /dev/null +++ b/epan/media_params.c @@ -0,0 +1,133 @@ +/* media_params.c + * Routines for parsing media type parameters + * Copyright 2004, Anders Broman. + * Copyright 2004, Olivier Biot. + * + * Refer to the AUTHORS file or the AUTHORS section in the man page + * for contacting the author(s) of this file. + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" + +#include <string.h> + +#include <glib.h> + +#include <epan/media_params.h> + +/* Return the index of a given char in the given string, + * or -1 if not found. + */ +gint +index_of_char(const char *str, const char c) +{ + gint len = 0; + const char *p = str; + + while (*p && *p != c) { + p++; + len++; + } + + if (*p) + return len; + return -1; +} + +char * +find_parameter(const char *parameters, const char *key, int *retlen) +{ + const char *start, *p; + int keylen = 0; + int len = 0; + + if(!parameters || !*parameters || !key || strlen(key) == 0) + /* we won't be able to find anything */ + return NULL; + + keylen = (int) strlen(key); + p = parameters; + + while (*p) { + + while ((*p) && g_ascii_isspace(*p)) + p++; /* Skip white space */ + + if (g_ascii_strncasecmp(p, key, keylen) == 0) + break; + /* Skip to next parameter */ + p = strchr(p, ';'); + if (p == NULL) + { + return NULL; + } + p++; /* Skip semicolon */ + + } + if (*p == 0x0) + return NULL; /* key wasn't found */ + + start = p + keylen; + if (start[0] == 0) { + return NULL; + } + + /* + * Process the parameter value + */ + if (start[0] == '"') { + /* + * Parameter value is a quoted-string + */ + start++; /* Skip the quote */ + len = index_of_char(start, '"'); + if (len < 0) { + /* + * No closing quote + */ + return NULL; + } + } else { + /* + * Look for end of boundary + */ + p = start; + while (*p) { + if (*p == ';' || g_ascii_isspace(*p)) + break; + p++; + len++; + } + } + + if(retlen) + (*retlen) = len; + + /* + * This is one of those ugly routines like strchr() where you can + * pass in a constant or non-constant string, and the result + * points into that string and inherits the constness of the + * input argument, but C doesn't support that, so the input + * parameter is const char * and the result is char *. + */ + return (char *)start; +} + diff --git a/epan/media_params.h b/epan/media_params.h new file mode 100644 index 0000000000..e6f0b98cc0 --- /dev/null +++ b/epan/media_params.h @@ -0,0 +1,52 @@ +/* media_params.h + * Routines for parsing media type parameters + * Copyright 2004, Anders Broman. + * Copyright 2004, Olivier Biot. + * + * Refer to the AUTHORS file or the AUTHORS section in the man page + * for contacting the author(s) of this file. + * + * Wireshark - Network traffic analyzer + * By Gerald Combs <gerald@wireshark.org> + * Copyright 1998 Gerald Combs + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#ifndef __MEDIA_PARAMS_H__ +#define __MEDIA_PARAMS_H__ + +#include <glib.h> + +#include "ws_symbol_export.h" + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Return the index of a given char in the given string, + * or -1 if not found. + */ +WS_DLL_PUBLIC gint +index_of_char(const char *str, const char c); + +WS_DLL_PUBLIC char * +find_parameter(const char *parameters, const char *key, int *retlen); + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* media_params.h */ |