diff --git a/.gitignore b/.gitignore index 7453c50..2b485dc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -SOURCES/wireshark-1.10.3.tar.bz2 +SOURCES/wireshark-1.10.14.tar.bz2 SOURCES/wiresharkdoc-256x256.png SOURCES/wiresharkdoc-32x32.png SOURCES/wiresharkdoc-48x48.png diff --git a/.wireshark.metadata b/.wireshark.metadata index 5b79652..a92f041 100644 --- a/.wireshark.metadata +++ b/.wireshark.metadata @@ -1,4 +1,4 @@ -58b02d6c2f1ae086a6ec46289d1eea0cc4343309 SOURCES/wireshark-1.10.3.tar.bz2 +47c359dc1b9791d2091887a26fdba65f4a7ef3b8 SOURCES/wireshark-1.10.14.tar.bz2 270551daad7666a3203647d3f340cee221976634 SOURCES/wiresharkdoc-256x256.png a0c5d9f7540f9f63fbdce7047845bfe667dacb79 SOURCES/wiresharkdoc-32x32.png 278fb6ed0c8c02c3690ff8b813e9fd32aa79e975 SOURCES/wiresharkdoc-48x48.png diff --git a/SOURCES/wireshark-1.10.0-CVE-2013-7112.patch b/SOURCES/wireshark-1.10.0-CVE-2013-7112.patch deleted file mode 100644 index 260c673..0000000 --- a/SOURCES/wireshark-1.10.0-CVE-2013-7112.patch +++ /dev/null @@ -1,13 +0,0 @@ ---- trunk-1.10/epan/dissectors/packet-sip.c 2013/11/09 14:58:28 53194 -+++ trunk-1.10/epan/dissectors/packet-sip.c 2013/11/09 15:44:01 53195 -@@ -2134,6 +2134,10 @@ - */ - orig_offset = offset; - linelen = tvb_find_line_end(tvb, offset, -1, &next_offset, FALSE); -+ if(linelen==0){ -+ return -2; -+ } -+ - if (tvb_strnlen(tvb, offset, linelen) > -1) - { - /* diff --git a/SOURCES/wireshark-1.10.0-CVE-2013-7113.patch b/SOURCES/wireshark-1.10.0-CVE-2013-7113.patch deleted file mode 100644 index cd0e617..0000000 --- a/SOURCES/wireshark-1.10.0-CVE-2013-7113.patch +++ /dev/null @@ -1,286 +0,0 @@ ---- trunk-1.10/epan/dissectors/packet-bssgp.c 2013/12/06 04:33:58 53802 -+++ trunk-1.10/epan/dissectors/packet-bssgp.c 2013/12/06 07:14:45 53803 -@@ -79,7 +79,6 @@ - static int bssgp_decode_nri = 0; - static guint bssgp_nri_length = 4; - --static packet_info *gpinfo; - static guint8 g_pdu_type, g_rim_application_identity; - static proto_tree *gparent_tree; - static dissector_handle_t llc_handle; -@@ -898,7 +897,7 @@ - */ - - static guint16 --de_bssgp_llc_pdu(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_) -+de_bssgp_llc_pdu(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_) - { - tvbuff_t *next_tvb=NULL; - guint32 curr_offset; -@@ -912,10 +911,10 @@ - - if(next_tvb){ - if (llc_handle) { -- call_dissector(llc_handle, next_tvb, gpinfo, gparent_tree); -+ call_dissector(llc_handle, next_tvb, pinfo, gparent_tree); - } - else if (data_handle) { -- call_dissector(data_handle, next_tvb, gpinfo, gparent_tree); -+ call_dissector(data_handle, next_tvb, pinfo, gparent_tree); - } - } - -@@ -1100,7 +1099,7 @@ - }; - - static guint16 --de_bssgp_qos_profile(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_) -+de_bssgp_qos_profile(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_) - { - proto_item *pi, *pre_item; - guint32 curr_offset; -@@ -1113,7 +1112,7 @@ - /* octet 3-4 Peak bit rate provided by the network (note) - * NOTE: The bit rate 0 (zero) shall mean "best effort" in this IE. - */ -- link_dir = gpinfo->link_dir; -+ link_dir = pinfo->link_dir; - - peak_bit_rate = tvb_get_ntohs(tvb, curr_offset); - pi = proto_tree_add_text(tree, tvb, curr_offset, 1, "Peak bit rate: "); -@@ -1515,7 +1514,7 @@ - * 11.3.48 NSEI (Network Service Entity Identifier) - */ - static guint16 --de_bssgp_nsei(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_) -+de_bssgp_nsei(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_) - { - guint32 curr_offset; - guint16 nsei; -@@ -1526,7 +1525,7 @@ - proto_tree_add_item(tree, hf_bssgp_nsei, tvb, curr_offset, 2, ENC_BIG_ENDIAN); - curr_offset+=2; - -- col_append_sep_fstr(gpinfo->cinfo, COL_INFO, BSSGP_SEP, "NSEI %u", nsei); -+ col_append_sep_fstr(pinfo->cinfo, COL_INFO, BSSGP_SEP, "NSEI %u", nsei); - - - return(curr_offset-offset); -@@ -1535,7 +1534,7 @@ - * 11.3.49 RRLP APDU - */ - static guint16 --de_bssgp_rrlp_apdu(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_) -+de_bssgp_rrlp_apdu(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_) - { - tvbuff_t *next_tvb=NULL; - guint32 curr_offset; -@@ -1555,9 +1554,9 @@ - - if(next_tvb){ - if (rrlp_handle) { -- call_dissector(rrlp_handle, next_tvb, gpinfo, gparent_tree); -+ call_dissector(rrlp_handle, next_tvb, pinfo, gparent_tree); - }else if (data_handle) { -- call_dissector(data_handle, next_tvb, gpinfo, gparent_tree); -+ call_dissector(data_handle, next_tvb, pinfo, gparent_tree); - } - } - return(len); -@@ -1748,7 +1747,7 @@ - { - asn1_ctx_t asn1_ctx; - -- asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, TRUE, gpinfo); -+ asn1_ctx_init(&asn1_ctx, ASN1_ENC_PER, TRUE, pinfo); - /* 11.3.63.1.4 RAN-INFORMATION-REQUEST Application Container for the SON Transfer Application */ - /* Reporting Cell Identifier */ - /* convert to bit offset */ -@@ -1765,7 +1764,7 @@ - * 3GPP TS 25.413 - */ - new_tvb = tvb_new_subset_remaining(tvb, curr_offset); -- curr_offset = curr_offset + dissect_ranap_SourceCellID_PDU(new_tvb, gpinfo, tree, NULL); -+ curr_offset = curr_offset + dissect_ranap_SourceCellID_PDU(new_tvb, pinfo, tree, NULL); - break; - default : - proto_tree_add_text(tree, tvb, curr_offset, len, "Unknown RIM Application Identity"); -@@ -1847,7 +1846,7 @@ - if (msg_fcn_p == NULL){ - proto_tree_add_text(si_tree, tvb, curr_offset, 21, "Unknown SI message"); - }else{ -- (*msg_fcn_p)(tvb, si_tree, gpinfo, curr_offset+1, 20); -+ (*msg_fcn_p)(tvb, si_tree, pinfo, curr_offset+1, 20); - } - curr_offset+=21; - } -@@ -1895,14 +1894,14 @@ - * Source Cell ID) as defined in 3GPP TS 25.413 - */ - new_tvb = tvb_new_subset_remaining(tvb, curr_offset); -- curr_offset = curr_offset + dissect_ranap_SourceCellID_PDU(new_tvb, gpinfo, tree, NULL); -+ curr_offset = curr_offset + dissect_ranap_SourceCellID_PDU(new_tvb, pinfo, tree, NULL); - break; - case 2: - /* If the RAT discriminator field indicates E-UTRAN, this field is encoded as the E-UTRAN CGI IE as - * defined in 3GPP TS 36.413 - */ - new_tvb = tvb_new_subset_remaining(tvb, curr_offset); -- curr_offset = curr_offset + dissect_s1ap_Global_ENB_ID_PDU(new_tvb, gpinfo, tree, NULL); -+ curr_offset = curr_offset + dissect_s1ap_Global_ENB_ID_PDU(new_tvb, pinfo, tree, NULL); - break; - default: - break; -@@ -1916,7 +1915,7 @@ - * (UTRAN Source Cell ID) as defined in 3GPP TS 25.413 - */ - new_tvb = tvb_new_subset_remaining(tvb, curr_offset); -- curr_offset = curr_offset + dissect_ranap_SourceCellID_PDU(new_tvb, gpinfo, tree, NULL); -+ curr_offset = curr_offset + dissect_ranap_SourceCellID_PDU(new_tvb, pinfo, tree, NULL); - /* Octet (m+1)-n UTRA SI Container - * UTRA SI Container: This field contains System Information Container valid for the reporting cell - * encoded as defined in TS 25.331 -@@ -1972,7 +1971,7 @@ - }; - - static guint16 --de_bssgp_ran_app_error_cont(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_) -+de_bssgp_ran_app_error_cont(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_) - { - tvbuff_t *new_tvb = NULL; - guint32 curr_offset; -@@ -2018,7 +2017,7 @@ - * The "SON Transfer Cause" field is encoded as the SON Transfer Cause IE as defined in 3GPP TS 36.413 - */ - new_tvb = tvb_new_subset_remaining(tvb, curr_offset); -- curr_offset = curr_offset + dissect_s1ap_SONtransferCause_PDU(new_tvb, gpinfo, tree, NULL); -+ curr_offset = curr_offset + dissect_s1ap_SONtransferCause_PDU(new_tvb, pinfo, tree, NULL); - /* Erroneous Application Container including IEI and LI */ - proto_tree_add_text(tree, tvb, curr_offset, len-(curr_offset-offset), "Erroneous Application Container including IEI and LI"); - break; -@@ -2212,7 +2211,7 @@ - }; - - static guint16 --de_bssgp_rim_routing_inf(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_) -+de_bssgp_rim_routing_inf(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_) - { - guint8 oct; - guint16 rnc_id; -@@ -2261,7 +2260,7 @@ - curr_offset = curr_offset+ de_emm_trac_area_id(tvb, tree, pinfo, curr_offset, 5, add_string, string_len); - /* Octets 9-n contain the Global eNB ID (see 3GPP TS 36.413 [36]) of the eNodeB. */ - new_tvb = tvb_new_subset_remaining(tvb, curr_offset); -- dissect_s1ap_Global_ENB_ID_PDU(new_tvb, gpinfo, tree, NULL); -+ dissect_s1ap_Global_ENB_ID_PDU(new_tvb, pinfo, tree, NULL); - break; - default: - proto_tree_add_text(tree, tvb, curr_offset, 3, "Unknown RIM Routing Address discriminator"); -@@ -2301,7 +2300,7 @@ - * 11.3.72 MBMS Session Duration - */ - static guint16 --de_bssgp_mbms_session_dur(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_) -+de_bssgp_mbms_session_dur(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_) - { - tvbuff_t *new_tvb; - guint32 curr_offset; -@@ -2310,7 +2309,7 @@ - - /* AVP Code: 904 MBMS-Session-Duration Registered by packet-gtp.c */ - new_tvb =tvb_new_subset(tvb, offset, len, len); -- dissector_try_uint(diameter_3gpp_avp_dissector_table, 904, new_tvb, gpinfo, tree); -+ dissector_try_uint(diameter_3gpp_avp_dissector_table, 904, new_tvb, pinfo, tree); - - return(curr_offset-offset); - } -@@ -2322,7 +2321,7 @@ - * - */ - static guint16 --de_bssgp_mbms_sai_list(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_) -+de_bssgp_mbms_sai_list(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len, gchar *add_string _U_, int string_len _U_) - { - tvbuff_t *new_tvb; - guint32 curr_offset; -@@ -2331,7 +2330,7 @@ - - /* AVP Code: 903 MBMS-Service-Area Registered by packet-gtp.c */ - new_tvb =tvb_new_subset(tvb, offset, len, len); -- dissector_try_uint(diameter_3gpp_avp_dissector_table, 903, new_tvb, gpinfo, tree); -+ dissector_try_uint(diameter_3gpp_avp_dissector_table, 903, new_tvb, pinfo, tree); - - return(curr_offset-offset); - } -@@ -2840,7 +2839,7 @@ - * 11.3.94 Inter RAT Handover Info - */ - static guint16 --de_bssgp_inter_rat_ho_info(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_) -+de_bssgp_inter_rat_ho_info(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_) - { - tvbuff_t *new_tvb; - guint32 curr_offset; -@@ -2852,7 +2851,7 @@ - * Inter RAT Handover Information coded as specified in 3GPP - * Technical Specification 25.331 - */ -- dissect_rrc_InterRATHandoverInfo_PDU(new_tvb, gpinfo, tree, NULL); -+ dissect_rrc_InterRATHandoverInfo_PDU(new_tvb, pinfo, tree, NULL); - - return(len); - } -@@ -3096,7 +3095,7 @@ - - /* Octets 8-n contain the Global eNB ID (see 3GPP TS 36.413) of the eNodeB. */ - new_tvb = tvb_new_subset_remaining(tvb, curr_offset); -- dissect_s1ap_Global_ENB_ID_PDU(new_tvb, gpinfo, tree, NULL); -+ dissect_s1ap_Global_ENB_ID_PDU(new_tvb, pinfo, tree, NULL); - - return(len); - } -@@ -3104,7 +3103,7 @@ - * 11.3.104 E-UTRAN Inter RAT Handover Info - */ - static guint16 --de_bssgp_e_utran_inter_rat_ho_info(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_) -+de_bssgp_e_utran_inter_rat_ho_info(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_) - { - tvbuff_t *new_tvb; - guint32 curr_offset; -@@ -3118,7 +3117,7 @@ - * significant bit of the first octet of the octet string contains bit 8 of - * the first octet of the IE. - */ -- dissect_lte_rrc_UE_EUTRA_Capability_PDU(new_tvb, gpinfo, tree, NULL); -+ dissect_lte_rrc_UE_EUTRA_Capability_PDU(new_tvb, pinfo, tree, NULL); - - return(len); - } -@@ -3181,7 +3180,7 @@ - * 11.3.108 SON Transfer Application Identity - */ - static guint16 --de_bssgp_son_transfer_app_id(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset _U_, guint len _U_, gchar *add_string _U_, int string_len _U_) -+de_bssgp_son_transfer_app_id(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset _U_, guint len _U_, gchar *add_string _U_, int string_len _U_) - { - tvbuff_t *next_tvb; - -@@ -3190,7 +3189,7 @@ - */ - if(len > 0){ - next_tvb = tvb_new_subset(tvb, offset, len, len); -- dissect_s1ap_SONtransferApplicationIdentity_PDU(next_tvb, gpinfo, tree, NULL); -+ dissect_s1ap_SONtransferApplicationIdentity_PDU(next_tvb, pinfo, tree, NULL); - } - - return(len); -@@ -6370,8 +6369,6 @@ - int hf_idx; - void (*msg_fcn_p)(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint32 offset, guint len); - -- /* Save pinfo */ -- gpinfo = pinfo; - g_rim_application_identity = 0; - gparent_tree = tree; - len = tvb_length(tvb); diff --git a/SOURCES/wireshark-1.10.0-CVE-2013-7114.patch b/SOURCES/wireshark-1.10.0-CVE-2013-7114.patch deleted file mode 100644 index 5713a66..0000000 --- a/SOURCES/wireshark-1.10.0-CVE-2013-7114.patch +++ /dev/null @@ -1,71 +0,0 @@ ---- trunk/epan/dissectors/packet-ntlmssp.c 2013/11/28 16:33:54 53625 -+++ trunk/epan/dissectors/packet-ntlmssp.c 2013/11/28 16:39:04 53626 -@@ -517,9 +517,13 @@ - guint8 *sessionkey , const guint8 *encryptedsessionkey , int flags , - const ntlmssp_blob *ntlm_response, const ntlmssp_blob *lm_response _U_, ntlmssp_header_t *ntlmssph) - { -- char domain_name_unicode[256]; -- char user_uppercase[256]; -- char buf[512]; -+/* static const would be nicer, but -Werror=vla does not like it */ -+#define DOMAIN_NAME_BUF_SIZE 512 -+#define USER_BUF_SIZE 256 -+#define BUF_SIZE (DOMAIN_NAME_BUF_SIZE + USER_BUF_SIZE) -+ char domain_name_unicode[DOMAIN_NAME_BUF_SIZE]; -+ char user_uppercase[USER_BUF_SIZE]; -+ char buf[BUF_SIZE]; - /*guint8 md4[NTLMSSP_KEY_LEN];*/ - unsigned char nt_password_hash[NTLMSSP_KEY_LEN]; - unsigned char nt_proof[NTLMSSP_KEY_LEN]; -@@ -544,10 +544,10 @@ - nb_pass = get_md4pass_list(&pass_list, nt_password); - #endif - i = 0; -- memset(user_uppercase, 0, 256); -+ memset(user_uppercase, 0, USER_BUF_SIZE); - user_len = strlen(ntlmssph->acct_name); -- if (user_len < 129) { -- memset(buf, 0, 512); -+ if (user_len < USER_BUF_SIZE / 2) { -+ memset(buf, 0, BUF_SIZE); - str_to_unicode(ntlmssph->acct_name, buf); - for (j = 0; j < (2*user_len); j++) { - if (buf[j] != '\0') { -@@ -560,7 +540,7 @@ - return; - } - domain_len = strlen(ntlmssph->domain_name); -- if (domain_len < 129) { -+ if (domain_len < DOMAIN_NAME_BUF_SIZE / 2) { - str_to_unicode(ntlmssph->domain_name, domain_name_unicode); - } - else { -@@ -575,14 +579,14 @@ - printnbyte(nt_password_hash, NTLMSSP_KEY_LEN, "Current NT password hash: ", "\n"); - i++; - /* ntowf computation */ -- memset(buf, 0, 512); -+ memset(buf, 0, BUF_SIZE); - memcpy(buf, user_uppercase, user_len*2); - memcpy(buf+user_len*2, domain_name_unicode, domain_len*2); - md5_hmac(buf, domain_len*2+user_len*2, nt_password_hash, NTLMSSP_KEY_LEN, ntowf); - printnbyte(ntowf, NTLMSSP_KEY_LEN, "NTOWF: ", "\n"); - - /* LM response */ -- memset(buf, 0, 512); -+ memset(buf, 0, BUF_SIZE); - memcpy(buf, serverchallenge, 8); - memcpy(buf+8, clientchallenge, 8); - md5_hmac(buf, NTLMSSP_KEY_LEN, ntowf, NTLMSSP_KEY_LEN, lm_challenge_response); -@@ -590,9 +594,9 @@ - printnbyte(lm_challenge_response, 24, "LM Response: ", "\n"); - - /* NT proof = First NTLMSSP_KEY_LEN bytes of NT response */ -- memset(buf, 0, 512); -+ memset(buf, 0, BUF_SIZE); - memcpy(buf, serverchallenge, 8); -- memcpy(buf+8, ntlm_response->contents+NTLMSSP_KEY_LEN, ntlm_response->length-NTLMSSP_KEY_LEN); -+ memcpy(buf+8, ntlm_response->contents+NTLMSSP_KEY_LEN, MIN(BUF_SIZE - 8, ntlm_response->length-NTLMSSP_KEY_LEN)); - md5_hmac(buf, ntlm_response->length-8, ntowf, NTLMSSP_KEY_LEN, nt_proof); - printnbyte(nt_proof, NTLMSSP_KEY_LEN, "NT proof: ", "\n"); - if (!memcmp(nt_proof, ntlm_response->contents, NTLMSSP_KEY_LEN)) { diff --git a/SOURCES/wireshark-1.10.10-CVE-2014-6421.patch b/SOURCES/wireshark-1.10.10-CVE-2014-6421.patch deleted file mode 100644 index 6feb450..0000000 --- a/SOURCES/wireshark-1.10.10-CVE-2014-6421.patch +++ /dev/null @@ -1,16 +0,0 @@ -diff --git a/epan/dissectors/packet-rtp.c b/epan/dissectors/packet-rtp.c -index 1691cbf..9b9af9a 100644 ---- a/epan/dissectors/packet-rtp.c -+++ b/epan/dissectors/packet-rtp.c -@@ -879,8 +879,9 @@ srtp_add_address(packet_info *pinfo, address *addr, int port, int other_port, - /* - * Update the conversation data. - */ -- /* Free the hash if already exists */ -- rtp_free_hash_dyn_payload(p_conv_data->rtp_dyn_payload); -+ /* Free the hash if a different one already exists */ -+ /* if (p_conv_data->rtp_dyn_payload != rtp_dyn_payload) */ -+ /* rtp_free_hash_dyn_payload(p_conv_data->rtp_dyn_payload); */ - - g_strlcpy(p_conv_data->method, setup_method, MAX_RTP_SETUP_METHOD_SIZE+1); - p_conv_data->frame_number = setup_frame_number; diff --git a/SOURCES/wireshark-1.10.10-CVE-2014-6423.patch b/SOURCES/wireshark-1.10.10-CVE-2014-6423.patch deleted file mode 100644 index e3c42ef..0000000 --- a/SOURCES/wireshark-1.10.10-CVE-2014-6423.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/epan/dissectors/packet-megaco.c b/epan/dissectors/packet-megaco.c -index 4d870d8..ecc3147 100644 ---- a/epan/dissectors/packet-megaco.c -+++ b/epan/dissectors/packet-megaco.c -@@ -3294,7 +3294,7 @@ static void tvb_raw_text_add(tvbuff_t *tvb, proto_tree *tree){ - "%s", tvb_format_text_wsp(tvb,tvb_linebegin, - linelen)); - tvb_linebegin = tvb_lineend; -- } while ( tvb_lineend < tvb_len ); -+ } while ( tvb_lineend < tvb_len && linelen > 0 ); - } - - /* diff --git a/SOURCES/wireshark-1.10.10-CVE-2014-6424.patch b/SOURCES/wireshark-1.10.10-CVE-2014-6424.patch deleted file mode 100644 index 716e157..0000000 --- a/SOURCES/wireshark-1.10.10-CVE-2014-6424.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git a/epan/dissectors/packet-netflow.c b/epan/dissectors/packet-netflow.c -index ad432c6..99ca89b 100644 ---- a/epan/dissectors/packet-netflow.c -+++ b/epan/dissectors/packet-netflow.c -@@ -5128,7 +5128,7 @@ dissect_v9_v10_pdu_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *pdutree, - offset_e[i], 4, &ts_end[i]); - } else { - proto_tree_add_time(pdutree, hf_cflow_abstimeend, tvb, -- offset_s[i], 4, &ts_start[i]); -+ offset_e[i], 4, &ts_end[i]); - } - } - } diff --git a/SOURCES/wireshark-1.10.10-CVE-2014-6425.patch b/SOURCES/wireshark-1.10.10-CVE-2014-6425.patch index 8a9b5ac..34c37ce 100644 --- a/SOURCES/wireshark-1.10.10-CVE-2014-6425.patch +++ b/SOURCES/wireshark-1.10.10-CVE-2014-6425.patch @@ -2,7 +2,7 @@ diff --git a/epan/dissectors/packet-cups.c b/epan/dissectors/packet-cups.c index 6f60d9f..bcb8e37 100644 --- a/epan/dissectors/packet-cups.c +++ b/epan/dissectors/packet-cups.c -@@ -282,7 +282,7 @@ get_quoted_string(tvbuff_t *tvb, gint offset, gint *next_offset, guint *len) +@@ -280,7 +280,7 @@ get_quoted_string(tvbuff_t *tvb, gint offset, gint *next_offset, guint *len) if (o != -1) { offset++; l = o - offset; @@ -11,7 +11,7 @@ index 6f60d9f..bcb8e37 100644 offset = o + 1; } } -@@ -303,7 +303,7 @@ get_unquoted_string(tvbuff_t *tvb, gint offset, gint *next_offset, guint *len) +@@ -301,7 +301,7 @@ get_unquoted_string(tvbuff_t *tvb, gint offset, gint *next_offset, guint *len) o = tvb_pbrk_guint8(tvb, offset, -1, " \t\r\n", NULL); if (o != -1) { l = o - offset; diff --git a/SOURCES/wireshark-1.10.10-CVE-2014-6427.patch b/SOURCES/wireshark-1.10.10-CVE-2014-6427.patch deleted file mode 100644 index d9695db..0000000 --- a/SOURCES/wireshark-1.10.10-CVE-2014-6427.patch +++ /dev/null @@ -1,29 +0,0 @@ -diff --git a/epan/dissectors/packet-rtsp.c b/epan/dissectors/packet-rtsp.c -index 7d37413..8e06024 100644 ---- a/epan/dissectors/packet-rtsp.c -+++ b/epan/dissectors/packet-rtsp.c -@@ -442,7 +442,7 @@ static gboolean - is_rtsp_request_or_reply(const guchar *line, size_t linelen, rtsp_type_t *type) - { - guint ii; -- const guchar *next_token; -+ const guchar *token, *next_token; - int tokenlen; - gchar response_chars[4]; - -@@ -453,12 +453,12 @@ is_rtsp_request_or_reply(const guchar *line, size_t linelen, rtsp_type_t *type) - */ - *type = RTSP_REPLY; - /* The first token is the version. */ -- tokenlen = get_token_len(line, line+5, &next_token); -+ tokenlen = get_token_len(line, line+5, &token); - if (tokenlen != 0) { - /* The next token is the status code. */ -- tokenlen = get_token_len(next_token, line+linelen, &next_token); -+ tokenlen = get_token_len(token, line+linelen, &next_token); - if (tokenlen >= 3) { -- memcpy(response_chars, next_token, 3); -+ memcpy(response_chars, token, 3); - response_chars[3] = '\0'; - rtsp_stat_info->response_code = (guint)strtoul(response_chars, NULL, 10); - } diff --git a/SOURCES/wireshark-1.10.10-CVE-2014-6428.patch b/SOURCES/wireshark-1.10.10-CVE-2014-6428.patch deleted file mode 100644 index ec9f3c8..0000000 --- a/SOURCES/wireshark-1.10.10-CVE-2014-6428.patch +++ /dev/null @@ -1,12 +0,0 @@ -diff --git a/epan/dissectors/packet-ses.c b/epan/dissectors/packet-ses.c -index 5164403..81a9f4e 100644 ---- a/epan/dissectors/packet-ses.c -+++ b/epan/dissectors/packet-ses.c -@@ -1043,6 +1043,7 @@ dissect_spdu(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, - type = tvb_get_guint8(tvb, offset); - session.spdu_type = type; - session.abort_type = SESSION_NO_ABORT; -+ session.pres_ctx_id = 0; - session.ros_op = 0; - session.rtse_reassemble = FALSE; - diff --git a/SOURCES/wireshark-1.10.10-CVE-2014-6429.patch b/SOURCES/wireshark-1.10.10-CVE-2014-6429.patch deleted file mode 100644 index cc7c4b5..0000000 --- a/SOURCES/wireshark-1.10.10-CVE-2014-6429.patch +++ /dev/null @@ -1,88 +0,0 @@ -diff --git a/wiretap/ngsniffer.c b/wiretap/ngsniffer.c -index 3f987e2..ed61779 100644 ---- a/wiretap/ngsniffer.c -+++ b/wiretap/ngsniffer.c -@@ -2284,7 +2284,8 @@ SnifferDecompress(unsigned char *inbuf, size_t inlen, unsigned char *outbuf, - } - - bit_mask = 0; /* don't have any bits yet */ -- while (1) -+ /* Process until we've consumed all the input */ -+ while (pin < pin_end) - { - /* Shift down the bit mask we use to see whats encoded */ - bit_mask = bit_mask >> 1; -@@ -2292,20 +2293,30 @@ SnifferDecompress(unsigned char *inbuf, size_t inlen, unsigned char *outbuf, - /* If there are no bits left, time to get another 16 bits */ - if ( 0 == bit_mask ) - { -- bit_mask = 0x8000; /* start with the high bit */ -- bit_value = pletohs(pin); /* get the next 16 bits */ -- pin += 2; /* skip over what we just grabbed */ -- if ( pin >= pin_end ) -+ /* make sure there are at least *three* bytes -+ * available - the two bytes of the bit value, -+ * plus one byte after it */ -+ if ( pin + 2 >= pin_end ) - { -- *err = WTAP_ERR_UNC_TRUNCATED; /* data was oddly truncated */ -+ *err = WTAP_ERR_UNC_TRUNCATED; - return ( -1 ); - } -+ bit_mask = 0x8000; /* start with the high bit */ -+ bit_value = pletohs(pin); /* get the next 16 bits */ -+ pin += 2; /* skip over what we just grabbed */ - } - - /* Use the bits in bit_value to see what's encoded and what is raw data */ - if ( !(bit_mask & bit_value) ) - { - /* bit not set - raw byte we just copy */ -+ -+ /* If length would put us past end of output, avoid overflow */ -+ if ( pout + 1 > pout_end ) -+ { -+ *err = WTAP_ERR_UNC_OVERFLOW; -+ return ( -1 ); -+ } - *(pout++) = *(pin++); - } - else -@@ -2401,6 +2412,13 @@ SnifferDecompress(unsigned char *inbuf, size_t inlen, unsigned char *outbuf, - return ( -1 ); - } - -+ /* Check if offset would cause us to copy on top of ourselves */ -+ if ( pout - offset + length > pout ) -+ { -+ *err = WTAP_ERR_UNC_BAD_OFFSET; -+ return ( -1 ); -+ } -+ - /* Copy the string from previous text to output position, - advance output pointer */ - memcpy( pout, pout - offset, length ); -@@ -2430,6 +2448,12 @@ SnifferDecompress(unsigned char *inbuf, size_t inlen, unsigned char *outbuf, - return ( -1 ); - } - -+ /* Check if offset would cause us to copy on top of ourselves */ -+ if ( pout - offset + length > pout ) -+ { -+ *err = WTAP_ERR_UNC_BAD_OFFSET; -+ return ( -1 ); -+ } - /* Copy the string from previous text to output position, - advance output pointer */ - memcpy( pout, pout - offset, length ); -@@ -2437,10 +2461,6 @@ SnifferDecompress(unsigned char *inbuf, size_t inlen, unsigned char *outbuf, - break; - } - } -- -- /* If we've consumed all the input, we are done */ -- if ( pin >= pin_end ) -- break; - } - - return (int) ( pout - outbuf ); /* return length of expanded text */ diff --git a/SOURCES/wireshark-1.10.14-CVE-2015-3182.patch b/SOURCES/wireshark-1.10.14-CVE-2015-3182.patch new file mode 100644 index 0000000..71edb63 --- /dev/null +++ b/SOURCES/wireshark-1.10.14-CVE-2015-3182.patch @@ -0,0 +1,12 @@ +diff --git a/epan/dissectors/packet-dec-dnart.c b/epan/dissectors/packet-dec-dnart.c +index 79a15ca..a9622bb 100644 +--- a/epan/dissectors/packet-dec-dnart.c ++++ b/epan/dissectors/packet-dec-dnart.c +@@ -52,6 +52,7 @@ + #include + #include + #include ++#include + #include + #include + diff --git a/SOURCES/wireshark-1.10.14-CVE-2015-3810.patch b/SOURCES/wireshark-1.10.14-CVE-2015-3810.patch new file mode 100644 index 0000000..caeedb7 --- /dev/null +++ b/SOURCES/wireshark-1.10.14-CVE-2015-3810.patch @@ -0,0 +1,172 @@ +diff --git a/epan/dissectors/packet-http.c b/epan/dissectors/packet-http.c +index 225a7eb..e3e81f7 100644 +--- a/epan/dissectors/packet-http.c ++++ b/epan/dissectors/packet-http.c +@@ -2625,6 +2625,10 @@ dissect_http(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) + } else { + while (tvb_reported_length_remaining(tvb, offset) != 0) { + if (conv_data->upgrade == UPGRADE_WEBSOCKET && pinfo->fd->num >= conv_data->startframe) { ++ /* Websockets is a stream of data, preserve ++ * desegmentation functionality. */ ++ if (pinfo->can_desegment > 0) ++ pinfo->can_desegment++; + call_dissector_only(websocket_handle, tvb_new_subset_remaining(tvb, offset), pinfo, tree, NULL); + break; + } +diff --git a/epan/dissectors/packet-websocket.c b/epan/dissectors/packet-websocket.c +index e02825d..561e206 100644 +--- a/epan/dissectors/packet-websocket.c ++++ b/epan/dissectors/packet-websocket.c +@@ -31,6 +31,7 @@ + #include + #include + ++#include "packet-tcp.h" + + /* + * The information used comes from: +@@ -152,7 +153,7 @@ tvb_unmasked(tvbuff_t *tvb, const guint offset, guint payload_length, const guin + } + + static int +-dissect_websocket_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *ws_tree, guint8 opcode, guint payload_length, guint8 mask, const guint8* masking_key) ++dissect_websocket_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, proto_tree *ws_tree, guint8 opcode, guint payload_length, gboolean mask, const guint8* masking_key) + { + guint offset = 0; + proto_item *ti_unmask, *ti; +@@ -301,65 +302,35 @@ dissect_websocket_payload(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, p + } + + +-static int +-dissect_websocket(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) ++static void ++dissect_websocket_frame(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) + { + proto_item *ti, *ti_len; +- guint8 fin, opcode, mask; +- guint length, short_length, payload_length, recurse_length; +- guint payload_offset, mask_offset, recurse_offset; ++ guint8 fin, opcode; ++ gboolean mask; ++ guint short_length, payload_length; ++ guint payload_offset, mask_offset; + proto_tree *ws_tree = NULL; + const guint8 *masking_key = NULL; + tvbuff_t *tvb_payload = NULL; + +- length = tvb_length(tvb); +- if(length<2){ +- pinfo->desegment_len = 2; +- return 0; +- } +- + short_length = tvb_get_guint8(tvb, 1) & MASK_WS_PAYLOAD_LEN; ++ mask_offset = 2; + if(short_length==126){ +- if(length < 2+2){ +- pinfo->desegment_len = 2+2; +- return 0; +- } + payload_length = tvb_get_ntohs(tvb, 2); +- mask_offset = 2+2; +- } +- else if(short_length==127){ +- if(length < 2+8){ +- pinfo->desegment_len = 2+8; +- return 0; +- } +- /* warning C4244: '=' : conversion from 'guint64' to 'guint ', possible loss of data */ ++ mask_offset += 2; ++ } else if (short_length==127) { ++ /* warning C4244: '=' : conversion from 'guint64' to 'guint ', possible loss of data */ + payload_length = (guint)tvb_get_ntoh64(tvb, 2); +- mask_offset = 2+8; +- } +- else{ ++ mask_offset += 8; ++ } else { + payload_length = short_length; +- mask_offset = 2; + } + + /* Mask */ +- mask = (tvb_get_guint8(tvb, 1) & MASK_WS_MASK) >> 4; ++ mask = (tvb_get_guint8(tvb, 1) & MASK_WS_MASK) != 0; + payload_offset = mask_offset + (mask ? 4 : 0); + +- if (payload_offset + payload_length < payload_length) { +- /* Integer overflow, which means the packet contains a ridiculous +- * payload length. Just take what we've got available. +- * See bug https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8448 */ +- payload_length = tvb_reported_length_remaining(tvb, payload_offset); +- } +- +- if(length < payload_offset + payload_length){ +- /* XXXX Warning desegment_len is 32 bits */ +- pinfo->desegment_len = payload_offset + payload_length - length; +- return 0; +- } +- +- /* We've got the entire message! */ +- + col_set_str(pinfo->cinfo, COL_PROTOCOL, "WebSocket"); + col_set_str(pinfo->cinfo, COL_INFO, "WebSocket"); + +@@ -402,18 +373,49 @@ dissect_websocket(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *dat + + tvb_payload = tvb_new_subset_remaining(tvb, payload_offset); + dissect_websocket_payload(tvb_payload, pinfo, tree, ws_tree, opcode, payload_length, mask, masking_key); ++} ++ ++static guint ++get_websocket_frame_length(packet_info *pinfo _U_, tvbuff_t *tvb, int offset) ++{ ++ guint frame_length, payload_length; ++ gboolean mask; ++ ++ frame_length = 2; /* flags, opcode and Payload length */ ++ mask = tvb_get_guint8(tvb, offset + 1) & MASK_WS_MASK; ++ ++ payload_length = tvb_get_guint8(tvb, offset + 1) & MASK_WS_PAYLOAD_LEN; ++ offset += 2; /* Skip flags, opcode and Payload length */ + +- /* Call this function recursively, to see if we have enough data to parse another websocket message */ ++ /* Check for Extended Payload Length. */ ++ if (payload_length == 126) { ++ if (tvb_reported_length_remaining(tvb, offset) < 2) ++ return 0; /* Need more data. */ + +- recurse_offset = payload_offset + payload_length; +- if(length > recurse_offset){ +- recurse_length = dissect_websocket(tvb_new_subset_remaining(tvb, payload_offset+payload_length), pinfo, tree, data); +- if(pinfo->desegment_len) pinfo->desegment_offset += recurse_offset; +- return recurse_offset + recurse_length; ++ payload_length = tvb_get_ntohs(tvb, offset); ++ frame_length += 2; /* Extended payload length */ ++ } else if (payload_length == 127) { ++ if (tvb_reported_length_remaining(tvb, offset) < 8) ++ return 0; /* Need more data. */ ++ ++ payload_length = (guint)tvb_get_ntoh64(tvb, offset); ++ frame_length += 8; /* Extended payload length */ + } +- return recurse_offset; ++ ++ if (mask) ++ frame_length += 4; /* Masking-key */ ++ frame_length += payload_length; /* Payload data */ ++ return frame_length; + } + ++static int ++dissect_websocket(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_) ++{ ++ /* Need at least two bytes for flags, opcode and Payload length. */ ++ tcp_dissect_pdus(tvb, pinfo, tree, TRUE, 2, ++ get_websocket_frame_length, dissect_websocket_frame); ++ return tvb_length(tvb); ++} + + void + proto_register_websocket(void) diff --git a/SOURCES/wireshark-1.10.14-CVE-2015-3813.patch b/SOURCES/wireshark-1.10.14-CVE-2015-3813.patch new file mode 100644 index 0000000..13a010b --- /dev/null +++ b/SOURCES/wireshark-1.10.14-CVE-2015-3813.patch @@ -0,0 +1,18 @@ +diff --git a/epan/reassemble.c b/epan/reassemble.c +index 5ff9dcf..0838cb1 100644 +--- a/epan/reassemble.c ++++ b/epan/reassemble.c +@@ -1008,9 +1008,11 @@ fragment_add_work(fragment_data *fd_head, tvbuff_t *tvb, const int offset, + + /* If we have reached this point, the packet is not defragmented yet. + * Save all payload in a buffer until we can defragment. +- * XXX - what if we didn't capture the entire fragment due +- * to a too-short snapshot length? + */ ++ if (!tvb_bytes_exist(tvb, offset, fd->len)) { ++ g_slice_free(fragment_data, fd); ++ THROW(BoundsError); ++ } + fd->data = (unsigned char *)g_malloc(fd->len); + tvb_memcpy(tvb, fd->data, offset, fd->len); + LINK_FRAG(fd_head,fd); diff --git a/SOURCES/wireshark-1.10.14-CVE-2015-6243.patch b/SOURCES/wireshark-1.10.14-CVE-2015-6243.patch new file mode 100644 index 0000000..131cce4 --- /dev/null +++ b/SOURCES/wireshark-1.10.14-CVE-2015-6243.patch @@ -0,0 +1,12 @@ +diff --git a/epan/packet.c b/epan/packet.c +index 1ad0320..179011e 100644 +--- a/epan/packet.c ++++ b/epan/packet.c +@@ -1266,6 +1266,7 @@ dissector_get_string_handle(dissector_table_t sub_dissectors, + { + dtbl_entry_t *dtbl_entry; + ++ if (!string) return 0; + dtbl_entry = find_string_dtbl_entry(sub_dissectors, string); + if (dtbl_entry != NULL) + return dtbl_entry->current; diff --git a/SOURCES/wireshark-1.10.14-CVE-2015-6244.patch b/SOURCES/wireshark-1.10.14-CVE-2015-6244.patch new file mode 100644 index 0000000..e3ea1e6 --- /dev/null +++ b/SOURCES/wireshark-1.10.14-CVE-2015-6244.patch @@ -0,0 +1,51 @@ +diff --git a/epan/dissectors/packet-zbee-security.c b/epan/dissectors/packet-zbee-security.c +index 14fdb0a..34bc1a8 100644 +--- a/epan/dissectors/packet-zbee-security.c ++++ b/epan/dissectors/packet-zbee-security.c +@@ -590,11 +590,9 @@ dissect_zbee_secure(tvbuff_t *tvb, packet_info *pinfo, proto_tree* tree, guint o + } + + /* Check for null payload. */ +- if ( !(payload_len = tvb_reported_length_remaining(tvb, offset+mic_len)) ) { ++ payload_len = tvb_captured_length_remaining(tvb, offset+mic_len); ++ if (payload_len == 0) + return NULL; +- } else if ( payload_len < 0 ) { +- THROW(ReportedBoundsError); +- } + + /********************************************** + * Perform Security Operations on the Frame * +@@ -606,10 +604,31 @@ dissect_zbee_secure(tvbuff_t *tvb, packet_info *pinfo, proto_tree* tree, guint o + (packet.level == ZBEE_SEC_MIC128)) { + + /* Payload is only integrity protected. Just return the sub-tvbuff. */ +- return tvb_new_subset(tvb, offset, payload_len, payload_len); ++ return tvb_new_subset_length(tvb, offset, payload_len); + } + + #ifdef HAVE_LIBGCRYPT ++ /* Have we captured all the payload? */ ++ if (tvb_length_remaining(tvb, offset+mic_len) < payload_len) { ++ /* ++ * No - don't try to decrypt it. ++ * ++ * XXX - it looks as if the decryption code is assuming we have the ++ * MIC, which won't be the case if the packet was cut short. Is ++ * that in fact that case, or can we still make this work with a ++ * partially-captured packet? ++ */ ++ /* Add expert info. */ ++ expert_add_info_format(pinfo, sec_tree, PI_UNDECODED, PI_WARN, ++ "Encrypted payload, cut short when capturing - can't decrypt"); ++ /* Create a buffer for the undecrypted payload. */ ++ payload_tvb = tvb_new_subset_length(tvb, offset, payload_len); ++ /* Dump the payload to the data dissector. */ ++ call_dissector(data_handle, payload_tvb, pinfo, tree); ++ /* Couldn't decrypt, so return NULL. */ ++ return NULL; ++ } ++ + /* Allocate memory to decrypt the payload into. */ + dec_buffer = (guint8 *)g_malloc(payload_len); + diff --git a/SOURCES/wireshark-1.10.14-CVE-2015-6245.patch b/SOURCES/wireshark-1.10.14-CVE-2015-6245.patch new file mode 100644 index 0000000..7f687ef --- /dev/null +++ b/SOURCES/wireshark-1.10.14-CVE-2015-6245.patch @@ -0,0 +1,76 @@ +diff --git a/epan/dissectors/packet-gsm_rlcmac.c b/epan/dissectors/packet-gsm_rlcmac.c +index e4eac08..7a783ef 100644 +--- a/epan/dissectors/packet-gsm_rlcmac.c ++++ b/epan/dissectors/packet-gsm_rlcmac.c +@@ -60,7 +60,7 @@ + /* private typedefs */ + typedef struct + { +- guint8 offset; ++ gint offset; + guint8 li; + }length_indicator_t; + +@@ -6737,10 +6737,11 @@ static const value_string gsm_rlcmac_t3192_vals[] = { + { 0, NULL} + }; + +-static guint8 construct_gprs_data_segment_li_array(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint8 initial_offset, guint8 *li_count, length_indicator_t *li_array, guint64 *e) ++static gint construct_gprs_data_segment_li_array(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint8 initial_offset, guint8 *li_count, length_indicator_t *li_array, guint64 *e) + { +- guint8 offset = initial_offset, li_array_size = *li_count; +- proto_item *item; ++ gint offset = initial_offset; ++ guint8 li_array_size = *li_count; ++ proto_item *item; + + *li_count = 0; + while(*e == 0) +@@ -6763,15 +6764,15 @@ static guint8 construct_gprs_data_segment_li_array(tvbuff_t *tvb, proto_tree *tr + return (offset - initial_offset); + } + +-static guint8 construct_egprs_data_segment_li_array(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint8 initial_offset, guint8 *li_count, length_indicator_t *li_array, guint64 *e) ++static gint construct_egprs_data_segment_li_array(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo, guint8 initial_offset, guint8 *li_count, length_indicator_t *li_array, guint64 *e) + { +- guint8 offset = initial_offset, li_array_size = *li_count; +- proto_item *item; ++ gint offset = initial_offset; ++ guint8 li_array_size = *li_count; ++ proto_item *item; + + *li_count = 0; + while(*e == 0) + { +- DISSECTOR_ASSERT(*li_count < li_array_size); + item = proto_tree_add_bits_item(tree, hf_li, tvb, offset * 8, 7, ENC_BIG_ENDIAN); + proto_tree_add_bits_ret_val(tree, hf_e, tvb, (offset * 8) + 7, 1, e, ENC_BIG_ENDIAN); + if(*li_count < li_array_size) +@@ -7466,7 +7467,7 @@ dissect_ul_gprs_block(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, RlcMa + csnStream_t ar; + guint8 payload_type = tvb_get_bits8(tvb, 0, 2); + guint16 bit_length = tvb_length(tvb) * 8; +- guint16 bit_offset = 0; ++ gint bit_offset = 0; + length_indicator_t li_array[10]; + guint8 li_count = array_length(li_array); + +@@ -7595,7 +7596,7 @@ dissect_egprs_ul_data_block(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + { + proto_item *ti = NULL; + proto_tree *data_tree = NULL; +- guint8 offset = 0; ++ gint offset = 0; + length_indicator_t li_array[20]; + guint8 li_count = array_length(li_array); + guint64 e, tlli_i; +@@ -7655,7 +7656,8 @@ dissect_egprs_dl_data_block(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + { + proto_item *ti = NULL; + proto_tree *data_tree = NULL; +- guint16 offset = 0, block_number; ++ gint offset = 0; ++ guint16 block_number; + length_indicator_t li_array[20]; + guint8 li_count = array_length(li_array); + guint64 fbi, e; diff --git a/SOURCES/wireshark-1.10.14-CVE-2015-6246.patch b/SOURCES/wireshark-1.10.14-CVE-2015-6246.patch new file mode 100644 index 0000000..149fc45 --- /dev/null +++ b/SOURCES/wireshark-1.10.14-CVE-2015-6246.patch @@ -0,0 +1,32 @@ +diff --git a/epan/dissectors/packet-waveagent.c b/epan/dissectors/packet-waveagent.c +index b43cbfb..0d32ae6 100644 +--- a/epan/dissectors/packet-waveagent.c ++++ b/epan/dissectors/packet-waveagent.c +@@ -528,21 +528,20 @@ static void dissect_wa_payload(guint32 starting_offset, proto_item *parent_tree, + tag_len = tvb_get_ntohl(tvb, current_offset + 52); + + if (tag_len != 0) { +- const guint8 *tag_data_ptr; +- guint32 isr; +- +- tag_data_ptr = tvb_get_ptr (tvb, offset + 36, tag_len); ++ guint32 isr; ++ guint8 isr_value; + + for (isr = 0; isr < tag_len; isr++) { +- if (tag_data_ptr[isr] == 0xFF){ ++ isr_value = tvb_get_guint8(tvb, offset + 36 + isr); ++ if (isr_value == 0xFF){ + proto_tree_add_string (bss_tree, hf_waveagent_ifwlansupprates, tvb, offset + 36 + isr, + 1, + "BSS requires support for mandatory features of HT PHY (IEEE 802.11" + " - Clause 20)"); + } else { + ep_strbuf_append_printf(sb, "%2.1f%s ", +- (tag_data_ptr[isr] & 0x7F) * 0.5, +- (tag_data_ptr[isr] & 0x80) ? "(B)" : ""); ++ (isr_value & 0x7F) * 0.5, ++ (isr_value & 0x80) ? "(B)" : ""); + + } + } diff --git a/SOURCES/wireshark-1.10.14-CVE-2015-6248.patch b/SOURCES/wireshark-1.10.14-CVE-2015-6248.patch new file mode 100644 index 0000000..c1321a5 --- /dev/null +++ b/SOURCES/wireshark-1.10.14-CVE-2015-6248.patch @@ -0,0 +1,109 @@ +diff --git a/epan/proto.c b/epan/proto.c +index 004acb0..bf98a27 100644 +--- a/epan/proto.c ++++ b/epan/proto.c +@@ -1758,6 +1758,31 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, + return pi; + } + ++ ++/* ++ * Validates that field length bytes are available starting from ++ * start (pos/neg). Throws an exception if they aren't. ++ */ ++static void ++test_length(header_field_info *hfinfo, tvbuff_t *tvb, ++ gint start, gint length) ++{ ++ gint size = length; ++ ++ if (!tvb) ++ return; ++ ++ if (hfinfo->type == FT_STRINGZ) { ++ /* If we're fetching until the end of the TVB, only validate ++ * that the offset is within range. ++ */ ++ if (length == -1) ++ size = 0; ++ } ++ ++ tvb_ensure_bytes_exist(tvb, start, size); ++} ++ + /* Gets data from tvbuff, adds it to proto_tree, increments offset, + and returns proto_item* */ + proto_item * +@@ -1786,6 +1811,8 @@ ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length, + ptvc->offset += n; + } + ++ test_length(hfinfo, ptvc->tvb, offset, item_length); ++ + /* Coast clear. Try and fake it */ + TRY_TO_FAKE_THIS_ITEM(ptvc->tree, hfindex, hfinfo); + +@@ -1795,45 +1822,6 @@ ptvcursor_add(ptvcursor_t *ptvc, int hfindex, gint length, + offset, length, encoding); + } + +-/* +- * Validates that field length bytes are available starting from +- * start (pos/neg). Throws an exception if they aren't. +- */ +-static void +-test_length(header_field_info *hfinfo, proto_tree *tree, tvbuff_t *tvb, +- gint start, gint length, const guint encoding) +-{ +- gint size = length; +- +- if (!tvb) +- return; +- +- if (hfinfo->type == FT_UINT_BYTES || hfinfo->type == FT_UINT_STRING) { +- guint32 n; +- +- n = get_uint_value(tree, tvb, start, length, encoding); +- if (n > size + n) { +- /* If n > size + n then we have an integer overflow, so +- * set size to -1, which will force the +- * tvb_ensure_bytes_exist call below to throw a +- * ReportedBoundsError +- */ +- size = -1; +- } +- else { +- size += n; +- } +- } else if (hfinfo->type == FT_STRINGZ) { +- /* If we're fetching until the end of the TVB, only validate +- * that the offset is within range. +- */ +- if (length == -1) +- size = 0; +- } +- +- tvb_ensure_bytes_exist(tvb, start, size); +-} +- + /* Add an item to a proto_tree, using the text label registered to that item; + the item is extracted from the tvbuff handed to it. */ + proto_item * +@@ -1845,7 +1833,7 @@ proto_tree_add_item(proto_tree *tree, const int hfindex, tvbuff_t *tvb, + gint item_length; + + hfinfo = get_hfi_and_length(hfindex, tvb, start, &length, &item_length); +- test_length(hfinfo, tree, tvb, start, item_length, encoding); ++ test_length(hfinfo, tvb, start, item_length); + + TRY_TO_FAKE_THIS_ITEM(tree, hfindex, hfinfo); + +@@ -7540,7 +7528,7 @@ proto_tree_add_bits_item(proto_tree *tree, const int hf_index, tvbuff_t *tvb, + + octet_length = (no_of_bits + 7) >> 3; + octet_offset = bit_offset >> 3; +- test_length(hfinfo, tree, tvb, octet_offset, octet_length, encoding); ++ test_length(hfinfo, tvb, octet_offset, octet_length); + + /* Yes, we try to fake this item again in proto_tree_add_bits_ret_val() + * but only after doing a bunch more work (which we can, in the common diff --git a/SOURCES/wireshark-1.10.14-gdk-pixbuf-deprecated-segfault.patch b/SOURCES/wireshark-1.10.14-gdk-pixbuf-deprecated-segfault.patch new file mode 100644 index 0000000..a2f73ae --- /dev/null +++ b/SOURCES/wireshark-1.10.14-gdk-pixbuf-deprecated-segfault.patch @@ -0,0 +1,18 @@ +diff --git a/configure.ac b/configure.ac +index a17ef31..090923b 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1396,7 +1396,12 @@ else + # Don't use GLIB_CFLAGS + AM_PATH_GLIB_2_0($GLIB_MIN_VERSION, , AC_MSG_ERROR(GLib $GLIB_MIN_VERSION or later distribution not found.), gthread gmodule) + +- CPPFLAGS="-DGDK_PIXBUF_DISABLE_DEPRECATED $CPPFLAGS" ++ # XXX: Disabled to fix Segfault: it worked before the latest gdk-pixbuf ++ # update, because that function is now under a #ifndef ++ # GDK_PIXBUF_DISABLE_DEPRECATED block which makes the declaration ++ # invisible and wireshark's configure sets this CPP directive. ++ # ++ # CPPFLAGS="-DGDK_PIXBUF_DISABLE_DEPRECATED $CPPFLAGS" + CPPFLAGS="-DGDK_DISABLE_DEPRECATED $CPPFLAGS" + if test \( $gtk_config_major_version -eq 3 -a $gtk_config_minor_version -ge 10 \) ; then + ## Allow use of deprecated & disable deprecated warnings if Gtk >= 3.10; diff --git a/SOURCES/wireshark-1.10.14-tls-cert-verify-msgs.patch b/SOURCES/wireshark-1.10.14-tls-cert-verify-msgs.patch new file mode 100644 index 0000000..b1e7e60 --- /dev/null +++ b/SOURCES/wireshark-1.10.14-tls-cert-verify-msgs.patch @@ -0,0 +1,107 @@ +diff --git a/epan/dissectors/packet-ssl.c b/epan/dissectors/packet-ssl.c +index e97e46e..f70919b 100644 +--- a/epan/dissectors/packet-ssl.c ++++ b/epan/dissectors/packet-ssl.c +@@ -202,6 +202,8 @@ static gint hf_ssl_handshake_server_keyex_named_curve = -1; + static gint hf_ssl_handshake_server_keyex_point = -1; + static gint hf_ssl_handshake_client_keyex_epms = -1; + static gint hf_ssl_handshake_client_keyex_point = -1; ++static gint hf_ssl_handshake_client_vrfy_sig_len = -1; ++static gint hf_ssl_handshake_client_vrfy_sig = -1; + static gint hf_ssl_handshake_server_keyex_modulus = -1; + static gint hf_ssl_handshake_server_keyex_exponent = -1; + static gint hf_ssl_handshake_server_keyex_sig = -1; +@@ -682,6 +684,10 @@ static gint ssl_looks_like_valid_pct_handshake(tvbuff_t *tvb, + static gint dissect_ssl_hash_alg_list(tvbuff_t *tvb, proto_tree *tree, + guint32 offset, guint16 len); + ++static void dissect_ssl3_hnd_cli_cert_verify(tvbuff_t *tvb, proto_tree *tree, ++ guint32 offset, ++ const SslSession *session); ++ + /********************************************************************* + * + * Main dissector +@@ -2070,7 +2076,7 @@ dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo, + break; + + case SSL_HND_CERT_VERIFY: +- /* unimplemented */ ++ dissect_ssl3_hnd_cli_cert_verify(tvb, ssl_hand_tree, offset, session); + break; + + case SSL_HND_CLIENT_KEY_EXCHG: +@@ -3174,8 +3180,9 @@ dissect_ssl3_hnd_cert_req(tvbuff_t *tvb, + } + + static void +-dissect_ssl3_hnd_srv_keyex_sig(tvbuff_t *tvb, proto_tree *tree, +- guint32 offset, SslSession *session) ++dissect_ssl3_digitally_signed(tvbuff_t *tvb, proto_tree *tree, guint32 offset, ++ const SslSession *session, gint hf_sig_len, ++ gint hf_sig) + { + gint sig_len; + proto_item *ti_algo; +@@ -3202,10 +3209,40 @@ dissect_ssl3_hnd_srv_keyex_sig(tvbuff_t *tvb, proto_tree *tree, + + /* Sig */ + sig_len = tvb_get_ntohs(tvb, offset); +- proto_tree_add_item(tree, hf_ssl_handshake_server_keyex_sig_len, tvb, +- offset, 2, ENC_BIG_ENDIAN); +- proto_tree_add_item(tree, hf_ssl_handshake_server_keyex_sig, tvb, +- offset + 2, sig_len, ENC_NA); ++ proto_tree_add_item(tree, hf_sig_len, tvb, offset, 2, ENC_BIG_ENDIAN); ++ proto_tree_add_item(tree, hf_sig, tvb, offset + 2, sig_len, ENC_NA); ++} ++ ++static void ++dissect_ssl3_hnd_cli_cert_verify(tvbuff_t *tvb, proto_tree *tree, ++ guint32 offset, const SslSession *session) ++{ ++ dissect_ssl3_digitally_signed(tvb, tree, offset, session, ++ hf_ssl_handshake_client_vrfy_sig_len, ++ hf_ssl_handshake_client_vrfy_sig); ++} ++ ++static void ++dissect_ssl3_hnd_srv_keyex_sig(tvbuff_t *tvb, proto_tree *tree, ++ guint32 offset, SslSession *session) ++{ ++ /* ++ * TLSv1.2 (RFC 5246 sec 7.4.8) ++ * struct { ++ * digitally-signed struct { ++ * opaque handshake_messages[handshake_messages_length]; ++ * } ++ * } CertificateVerify; ++ * ++ * TLSv1.0/TLSv1.1 (RFC 5436 sec 7.4.8 and 7.4.3) works essentially the same ++ * as TLSv1.2, but the hash algorithms are not explicit in digitally-signed. ++ * ++ * SSLv3 (RFC 6101 sec 5.6.8) esseentially works the same as TLSv1.0 but it ++ * does more hashing including the master secret and padding. ++ */ ++ dissect_ssl3_digitally_signed(tvb, tree, offset, session, ++ hf_ssl_handshake_server_keyex_sig_len, ++ hf_ssl_handshake_server_keyex_sig); + } + + static void +@@ -5410,6 +5447,16 @@ proto_register_ssl(void) + FT_BYTES, BASE_NONE, NULL, 0x0, + "EC Diffie-Hellman client pubkey", HFILL } + }, ++ { &hf_ssl_handshake_client_vrfy_sig_len, ++ { "signature length", "ssl.handshake.client_cert_vrfy.sig_len", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Length of CertificateVerify's signature", HFILL } ++ }, ++ { &hf_ssl_handshake_client_vrfy_sig, ++ { "signature", "ssl.handshake.client_cert_vrfy.sig", ++ FT_BYTES, BASE_NONE, NULL, 0x0, ++ "CertificateVerify's signature", HFILL } ++ }, + { &hf_ssl_handshake_server_keyex_modulus, + { "modulus", "ssl.handshake.modulus", + FT_BYTES, BASE_NONE, NULL, 0x0, diff --git a/SOURCES/wireshark-1.10.14-tvbuff.patch b/SOURCES/wireshark-1.10.14-tvbuff.patch new file mode 100644 index 0000000..9fd049a --- /dev/null +++ b/SOURCES/wireshark-1.10.14-tvbuff.patch @@ -0,0 +1,662 @@ +diff --git a/epan/tvbuff.c b/epan/tvbuff.c +index 98968a0..db2cfd1 100644 +--- a/epan/tvbuff.c ++++ b/epan/tvbuff.c +@@ -53,7 +53,7 @@ + + static const guint8* + ensure_contiguous_no_exception(tvbuff_t *tvb, const gint offset, const gint length, +- int *exception); ++ int *pexception); + + static const guint8* + ensure_contiguous(tvbuff_t *tvb, const gint offset, const gint length); +@@ -241,45 +241,48 @@ tvb_new_child_real_data(tvbuff_t *parent, const guint8* data, const guint length + return tvb; + } + +-/* Computes the absolute offset and length based on a possibly-negative offset +- * and a length that is possible -1 (which means "to the end of the data"). +- * Returns TRUE/FALSE indicating whether the offset is in bounds or +- * not. The integer ptrs are modified with the new offset and length. +- * No exception is thrown. ++/* ++ * Check whether that offset goes more than one byte past the ++ * end of the buffer. + * +- * XXX - we return TRUE, not FALSE, if the offset is positive and right +- * after the end of the tvbuff (i.e., equal to the length). We do this +- * so that a dissector constructing a subset tvbuff for the next protocol +- * will get a zero-length tvbuff, not an exception, if there's no data +- * left for the next protocol - we want the next protocol to be the one +- * that gets an exception, so the error is reported as an error in that +- * protocol rather than the containing protocol. */ +-static gboolean +-compute_offset_length(const tvbuff_t *tvb, +- const gint offset, const gint length_val, +- guint *offset_ptr, guint *length_ptr, int *exception) ++ * If not, return 0; otherwise, return exception ++ */ ++static inline int ++validate_offset(const tvbuff_t *tvb, const guint abs_offset) + { +- DISSECTOR_ASSERT(offset_ptr); +- DISSECTOR_ASSERT(length_ptr); ++ int exception; ++ ++ if (G_LIKELY(abs_offset <= tvb->length)) ++ exception = 0; ++ else if (abs_offset <= tvb->reported_length) ++ exception = BoundsError; ++ else { ++ if (tvb->flags & TVBUFF_FRAGMENT) ++ exception = FragmentBoundsError; ++ else ++ exception = ReportedBoundsError; ++ } ++ ++ return exception; ++} ++ ++static int ++compute_offset(const tvbuff_t *tvb, const gint offset, guint *offset_ptr) ++{ ++ int exception; + +- /* Compute the offset */ + if (offset >= 0) { + /* Positive offset - relative to the beginning of the packet. */ + if ((guint) offset > tvb->reported_length) { +- if (exception) { +- if (tvb->flags & TVBUFF_FRAGMENT) { +- *exception = FragmentBoundsError; +- } else { +- *exception = ReportedBoundsError; +- } ++ if (tvb->flags & TVBUFF_FRAGMENT) { ++ exception = FragmentBoundsError; ++ } else { ++ exception = ReportedBoundsError; + } +- return FALSE; ++ return exception; + } + else if ((guint) offset > tvb->length) { +- if (exception) { +- *exception = BoundsError; +- } +- return FALSE; ++ return BoundsError; + } + else { + *offset_ptr = offset; +@@ -288,95 +291,90 @@ compute_offset_length(const tvbuff_t *tvb, + else { + /* Negative offset - relative to the end of the packet. */ + if ((guint) -offset > tvb->reported_length) { +- if (exception) { +- if (tvb->flags & TVBUFF_FRAGMENT) { +- *exception = FragmentBoundsError; +- } else { +- *exception = ReportedBoundsError; +- } ++ if (tvb->flags & TVBUFF_FRAGMENT) { ++ exception = FragmentBoundsError; ++ } else { ++ exception = ReportedBoundsError; + } +- return FALSE; ++ return exception; + } + else if ((guint) -offset > tvb->length) { +- if (exception) { +- *exception = BoundsError; +- } +- return FALSE; ++ return BoundsError; + } + else { + *offset_ptr = tvb->length + offset; + } + } + +- /* Compute the length */ +- if (length_val < -1) { +- if (exception) { +- /* XXX - ReportedBoundsError? */ +- *exception = BoundsError; +- } +- return FALSE; +- } +- else if (length_val == -1) { +- *length_ptr = tvb->length - *offset_ptr; +- } +- else { +- *length_ptr = length_val; +- } ++ return 0; ++} + +- return TRUE; ++static int ++compute_offset_and_remaining(const tvbuff_t *tvb, const gint offset, guint *offset_ptr, guint *rem_len) ++{ ++ int exception; ++ ++ exception = compute_offset(tvb, offset, offset_ptr); ++ if (!exception) ++ *rem_len = tvb->length - *offset_ptr; ++ ++ return exception; + } + +-static gboolean ++/* Computes the absolute offset and length based on a possibly-negative offset ++ * and a length that is possible -1 (which means "to the end of the data"). ++ * Returns integer indicating whether the offset is in bounds (0) or ++ * not (exception number). The integer ptrs are modified with the new offset and length. ++ * No exception is thrown. ++ * ++ * XXX - we return success (0), if the offset is positive and right ++ * after the end of the tvbuff (i.e., equal to the length). We do this ++ * so that a dissector constructing a subset tvbuff for the next protocol ++ * will get a zero-length tvbuff, not an exception, if there's no data ++ * left for the next protocol - we want the next protocol to be the one ++ * that gets an exception, so the error is reported as an error in that ++ * protocol rather than the containing protocol. */ ++static int + check_offset_length_no_exception(const tvbuff_t *tvb, + const gint offset, gint const length_val, +- guint *offset_ptr, guint *length_ptr, int *exception) ++ guint *offset_ptr, guint *length_ptr) + { +- guint end_offset; ++ guint end_offset; ++ int exception; + +- if (!compute_offset_length(tvb, +- offset, length_val, offset_ptr, length_ptr, exception)) { +- return FALSE; ++ DISSECTOR_ASSERT(offset_ptr); ++ DISSECTOR_ASSERT(length_ptr); ++ ++ /* Compute the offset */ ++ exception = compute_offset(tvb, offset, offset_ptr); ++ if (exception) ++ return exception; ++ ++ if (length_val < -1) { ++ /* XXX - ReportedBoundsError? */ ++ return BoundsError; + } + ++ /* Compute the length */ ++ if (length_val == -1) ++ *length_ptr = tvb->length - *offset_ptr; ++ else ++ *length_ptr = length_val; ++ + /* + * Compute the offset of the first byte past the length. + */ + end_offset = *offset_ptr + *length_ptr; + + /* +- * Check for an overflow, and clamp "end_offset" at the maximum +- * if we got an overflow - that should force us to indicate that +- * we're past the end of the tvbuff. ++ * Check for an overflow + */ + if (end_offset < *offset_ptr) +- end_offset = UINT_MAX; +- +- /* +- * Check whether that offset goes more than one byte past the +- * end of the buffer. +- * +- * If not, return TRUE; otherwise, return FALSE and, if "exception" +- * is non-null, return the appropriate exception through it. +- */ +- if (end_offset <= tvb->length) { +- return TRUE; +- } +- else { +- if (exception) { +- if (end_offset <= tvb->reported_length) { +- *exception = BoundsError; +- } +- else { +- if (tvb->flags & TVBUFF_FRAGMENT) { +- *exception = FragmentBoundsError; +- } else { +- *exception = ReportedBoundsError; +- } +- } +- } ++ exception = BoundsError; ++ else ++ exception = validate_offset(tvb, end_offset); + +- return FALSE; +- } ++ return exception; + } + + /* Checks (+/-) offset and length and throws an exception if +@@ -387,13 +385,11 @@ check_offset_length(const tvbuff_t *tvb, + const gint offset, gint const length_val, + guint *offset_ptr, guint *length_ptr) + { +- int exception = 0; +- +- if (!check_offset_length_no_exception(tvb, +- offset, length_val, offset_ptr, length_ptr, &exception)) { +- DISSECTOR_ASSERT(exception > 0); ++ int exception; ++ ++ exception = check_offset_length_no_exception(tvb, offset, length_val, offset_ptr, length_ptr); ++ if (exception) + THROW(exception); +- } + } + + static tvbuff_t * +@@ -538,7 +534,7 @@ tvb_new_octet_aligned(tvbuff_t *tvb, guint32 bit_offset, gint32 no_of_bits) + right = 8 - left; /* for right-shifting */ + + if (no_of_bits == -1) { +- datalen = tvb_length_remaining(tvb, byte_offset); ++ datalen = tvb_captured_length_remaining(tvb, byte_offset); + remaining_bits = 0; + } else { + datalen = no_of_bits >> 3; +@@ -560,7 +556,7 @@ tvb_new_octet_aligned(tvbuff_t *tvb, guint32 bit_offset, gint32 no_of_bits) + * if non extra byte is available, the last shifted byte requires + * special treatment + */ +- if (tvb_length_remaining(tvb, byte_offset) > datalen) { ++ if (tvb_captured_length_remaining(tvb, byte_offset) > datalen) { + data = tvb_get_ptr(tvb, byte_offset, datalen + 1); + + /* Do this allocation AFTER tvb_get_ptr() (which could throw an exception) */ +@@ -679,7 +675,7 @@ tvb_composite_finalize(tvbuff_t *tvb) + + + guint +-tvb_length(const tvbuff_t *tvb) ++tvb_captured_length(const tvbuff_t *tvb) + { + DISSECTOR_ASSERT(tvb && tvb->initialized); + +@@ -687,32 +683,33 @@ tvb_length(const tvbuff_t *tvb) + } + + gint +-tvb_length_remaining(const tvbuff_t *tvb, const gint offset) ++tvb_captured_length_remaining(const tvbuff_t *tvb, const gint offset) + { +- guint abs_offset, abs_length; ++ guint abs_offset, rem_length; ++ int exception; + + DISSECTOR_ASSERT(tvb && tvb->initialized); + +- if (compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, NULL)) { +- return abs_length; +- } +- else { +- return -1; +- } ++ exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &rem_length); ++ if (exception) ++ return 0; ++ ++ return rem_length; + } + + guint +-tvb_ensure_length_remaining(const tvbuff_t *tvb, const gint offset) ++tvb_ensure_captured_length_remaining(const tvbuff_t *tvb, const gint offset) + { +- guint abs_offset, abs_length; ++ guint abs_offset, rem_length; + int exception; + + DISSECTOR_ASSERT(tvb && tvb->initialized); + +- if (!compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, &exception)) { ++ exception = compute_offset_and_remaining(tvb, offset, &abs_offset, &rem_length); ++ if (exception) + THROW(exception); +- } +- if (abs_length == 0) { ++ ++ if (rem_length == 0) { + /* + * This routine ensures there's at least one byte available. + * There aren't any bytes available, so throw the appropriate +@@ -727,7 +724,7 @@ tvb_ensure_length_remaining(const tvbuff_t *tvb, const gint offset) + } else + THROW(BoundsError); + } +- return abs_length; ++ return rem_length; + } + + +@@ -739,18 +736,15 @@ gboolean + tvb_bytes_exist(const tvbuff_t *tvb, const gint offset, const gint length) + { + guint abs_offset, abs_length; ++ int exception; + + DISSECTOR_ASSERT(tvb && tvb->initialized); + +- if (!compute_offset_length(tvb, offset, length, &abs_offset, &abs_length, NULL)) ++ exception = check_offset_length_no_exception(tvb, offset, length, &abs_offset, &abs_length); ++ if (exception) + return FALSE; + +- if (abs_offset + abs_length <= tvb->length) { +- return TRUE; +- } +- else { +- return FALSE; +- } ++ return TRUE; + } + + /* Validates that 'length' bytes are available starting from +@@ -781,10 +775,13 @@ tvb_ensure_bytes_exist(const tvbuff_t *tvb, const gint offset, const gint length + gboolean + tvb_offset_exists(const tvbuff_t *tvb, const gint offset) + { +- guint abs_offset, abs_length; ++ guint abs_offset; ++ int exception; + + DISSECTOR_ASSERT(tvb && tvb->initialized); +- if (!compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, NULL)) ++ ++ exception = compute_offset(tvb, offset, &abs_offset); ++ if (exception) + return FALSE; + + if (abs_offset < tvb->length) { +@@ -806,19 +803,19 @@ tvb_reported_length(const tvbuff_t *tvb) + gint + tvb_reported_length_remaining(const tvbuff_t *tvb, const gint offset) + { +- guint abs_offset, abs_length; ++ guint abs_offset; ++ int exception; + + DISSECTOR_ASSERT(tvb && tvb->initialized); + +- if (compute_offset_length(tvb, offset, -1, &abs_offset, &abs_length, NULL)) { +- if (tvb->reported_length >= abs_offset) +- return tvb->reported_length - abs_offset; +- else +- return -1; +- } +- else { +- return -1; +- } ++ exception = compute_offset(tvb, offset, &abs_offset); ++ if (exception) ++ return 0; ++ ++ if (tvb->reported_length >= abs_offset) ++ return tvb->reported_length - abs_offset; ++ else ++ return 0; + } + + /* Set the reported length of a tvbuff to a given value; used for protocols +@@ -896,6 +893,7 @@ composite_ensure_contiguous_no_exception(tvbuff_t *tvb, const guint abs_offset, + tvbuff_t *member_tvb = NULL; + guint member_offset, member_length; + GSList *slist; ++ int exception; + + DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE); + +@@ -913,10 +911,11 @@ composite_ensure_contiguous_no_exception(tvbuff_t *tvb, const guint abs_offset, + } + DISSECTOR_ASSERT(member_tvb); + +- if (check_offset_length_no_exception(member_tvb, ++ exception = check_offset_length_no_exception(member_tvb, + abs_offset - composite->start_offsets[i], +- abs_length, &member_offset, &member_length, NULL)) { ++ abs_length, &member_offset, &member_length); + ++ if (!exception) { + /* + * The range is, in fact, contiguous within member_tvb. + */ +@@ -932,12 +931,15 @@ composite_ensure_contiguous_no_exception(tvbuff_t *tvb, const guint abs_offset, + } + + static const guint8* +-ensure_contiguous_no_exception(tvbuff_t *tvb, const gint offset, const gint length, int *exception) ++ensure_contiguous_no_exception(tvbuff_t *tvb, const gint offset, const gint length, int *pexception) + { + guint abs_offset, abs_length; ++ int exception; + +- if (!check_offset_length_no_exception(tvb, offset, length, +- &abs_offset, &abs_length, exception)) { ++ exception = check_offset_length_no_exception(tvb, offset, length, &abs_offset, &abs_length); ++ if (exception) { ++ if (pexception) ++ *pexception = exception; + return NULL; + } + +@@ -1046,7 +1048,7 @@ composite_memcpy(tvbuff_t *tvb, guint8* target, guint abs_offset, size_t abs_len + tvb_comp_t *composite; + tvbuff_t *member_tvb = NULL; + guint member_offset, member_length; +- gboolean retval; ++ int exception; + GSList *slist; + + DISSECTOR_ASSERT(tvb->type == TVBUFF_COMPOSITE); +@@ -1065,9 +1067,10 @@ composite_memcpy(tvbuff_t *tvb, guint8* target, guint abs_offset, size_t abs_len + } + DISSECTOR_ASSERT(member_tvb); + +- if (check_offset_length_no_exception(member_tvb, abs_offset - composite->start_offsets[i], +- (gint) abs_length, &member_offset, &member_length, NULL)) { +- ++ exception = check_offset_length_no_exception(member_tvb, abs_offset - composite->start_offsets[i], ++ (gint) abs_length, &member_offset, &member_length); ++ ++ if (!exception) { + DISSECTOR_ASSERT(!tvb->real_data); + return tvb_memcpy(member_tvb, target, member_offset, member_length); + } +@@ -1077,9 +1080,9 @@ composite_memcpy(tvbuff_t *tvb, guint8* target, guint abs_offset, size_t abs_len + * then iterate across the other member tvb's, copying their portions + * until we have copied all data. + */ +- retval = compute_offset_length(member_tvb, abs_offset - composite->start_offsets[i], -1, +- &member_offset, &member_length, NULL); +- DISSECTOR_ASSERT(retval); ++ exception = compute_offset_and_remaining(member_tvb, abs_offset - composite->start_offsets[i], ++ &member_offset, &member_length); ++ DISSECTOR_ASSERT(!exception); + + /* composite_memcpy() can't handle a member_length of zero. */ + DISSECTOR_ASSERT(member_length); +@@ -1909,6 +1912,21 @@ tvb_get_bits(tvbuff_t *tvb, const guint bit_offset, const gint no_of_bits, const + return (guint32)_tvb_get_bits64(tvb, bit_offset, no_of_bits); + } + ++static gint ++tvb_find_guint8_generic(tvbuff_t *tvb, guint abs_offset, guint limit, guint8 needle) ++{ ++ const guint8 *ptr; ++ const guint8 *result; ++ ++ ptr = tvb_get_ptr(tvb, abs_offset, limit); ++ ++ result = (const guint8 *) memchr(ptr, needle, limit); ++ if (!result) ++ return -1; ++ ++ return (gint) ((result - ptr) + abs_offset); ++} ++ + /* Find first occurrence of needle in tvbuff, starting at offset. Searches + * at most maxlength number of bytes; if maxlength is -1, searches to + * end of tvbuff. +@@ -1920,16 +1938,15 @@ gint + tvb_find_guint8(tvbuff_t *tvb, const gint offset, const gint maxlength, const guint8 needle) + { + const guint8 *result; +- guint abs_offset, junk_length; ++ guint abs_offset; + guint tvbufflen; + guint limit; + + DISSECTOR_ASSERT(tvb && tvb->initialized); + +- check_offset_length(tvb, offset, 0, &abs_offset, &junk_length); ++ check_offset_length(tvb, offset, -1, &abs_offset, &tvbufflen); + + /* Only search to end of tvbuff, w/o throwing exception. */ +- tvbufflen = tvb_length_remaining(tvb, abs_offset); + if (maxlength == -1) { + /* No maximum length specified; search to end of tvbuff. */ + limit = tvbufflen; +@@ -1985,16 +2002,15 @@ gint + tvb_pbrk_guint8(tvbuff_t *tvb, const gint offset, const gint maxlength, const guint8 *needles, guchar *found_needle) + { + const guint8 *result; +- guint abs_offset, junk_length; ++ guint abs_offset; + guint tvbufflen; + guint limit; + + DISSECTOR_ASSERT(tvb && tvb->initialized); + +- check_offset_length(tvb, offset, 0, &abs_offset, &junk_length); ++ check_offset_length(tvb, offset, -1, &abs_offset, &tvbufflen); + + /* Only search to end of tvbuff, w/o throwing exception. */ +- tvbufflen = tvb_length_remaining(tvb, abs_offset); + if (maxlength == -1) { + /* No maximum length specified; search to end of tvbuff. */ + limit = tvbufflen; +@@ -2845,11 +2861,12 @@ static gint + _tvb_get_nstringz(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8* buffer, gint *bytes_copied) + { + gint stringlen; +- guint abs_offset, junk_length; ++ guint abs_offset; + gint limit, len; + gboolean decreased_max = FALSE; + +- check_offset_length(tvb, offset, 0, &abs_offset, &junk_length); ++ /* Only read to end of tvbuff, w/o throwing exception. */ ++ check_offset_length(tvb, offset, -1, &abs_offset, &len); + + /* There must at least be room for the terminating NUL. */ + DISSECTOR_ASSERT(bufsize != 0); +@@ -2861,9 +2878,6 @@ _tvb_get_nstringz(tvbuff_t *tvb, const gint offset, const guint bufsize, guint8* + return 0; + } + +- /* Only read to end of tvbuff, w/o throwing exception. */ +- len = tvb_length_remaining(tvb, abs_offset); +- + /* check_offset_length() won't throw an exception if we're + * looking at the byte immediately after the end of the tvbuff. */ + if (len == 0) { +@@ -2984,7 +2998,7 @@ tvb_find_line_end(tvbuff_t *tvb, const gint offset, int len, gint *next_offset, + guchar found_needle = 0; + + if (len == -1) +- len = tvb_length_remaining(tvb, offset); ++ len = tvb_captured_length_remaining(tvb, offset); + /* + * XXX - what if "len" is still -1, meaning "offset is past the + * end of the tvbuff"? +@@ -3100,7 +3114,7 @@ tvb_find_line_end_unquoted(tvbuff_t *tvb, const gint offset, int len, gint *next + int linelen; + + if (len == -1) +- len = tvb_length_remaining(tvb, offset); ++ len = tvb_captured_length_remaining(tvb, offset); + /* + * XXX - what if "len" is still -1, meaning "offset is past the + * end of the tvbuff"? +@@ -3238,7 +3252,7 @@ tvb_skip_wsp(tvbuff_t *tvb, const gint offset, const gint maxlength) + guint8 tempchar; + + /* Get the length remaining */ +- tvb_len = tvb_length(tvb); ++ tvb_len = tvb_captured_length(tvb); + end = offset + maxlength; + if (end >= tvb_len) + { +@@ -3310,7 +3324,7 @@ tvb_bcd_dig_to_ep_str(tvbuff_t *tvb, const gint offset, const gint len, dgt_set_ + dgt = &Dgt1_9_bcd; + + if (len == -1) { +- length = tvb_length(tvb); ++ length = tvb_captured_length(tvb); + if (length < offset) { + return ""; + } +diff --git a/epan/tvbuff.h b/epan/tvbuff.h +index 8950feb..f815c1f 100644 +--- a/epan/tvbuff.h ++++ b/epan/tvbuff.h +@@ -213,16 +213,28 @@ WS_DLL_PUBLIC tvbuff_t* tvb_new_composite(void); + WS_DLL_PUBLIC void tvb_composite_finalize(tvbuff_t* tvb); + + +-/* Get total length of buffer */ +-WS_DLL_PUBLIC guint tvb_length(const tvbuff_t*); ++/* Get amount of captured data in the buffer (which is *NOT* necessarily the ++ * * length of the packet). You probably want tvb_reported_length instead. */ ++WS_DLL_PUBLIC guint tvb_captured_length(const tvbuff_t *tvb); ++ ++/* DEPRECATED, do not use in new code, call tvb_captured_length directly! */ ++#define tvb_length tvb_captured_length + + /** Computes bytes to end of buffer, from offset (which can be negative, +- * to indicate bytes from end of buffer). Function returns -1 to +- * indicate that offset is out of bounds. No exception is thrown. */ +-WS_DLL_PUBLIC gint tvb_length_remaining(const tvbuff_t*, const gint offset); ++ * to indicate bytes from end of buffer). Function returns 0 if offset is out ++ * of bounds. No exception is thrown. */ ++WS_DLL_PUBLIC gint tvb_captured_length_remaining(const tvbuff_t *tvb, const gint offset); ++ ++/* DEPRECATED, do not use in new code, call tvb_captured_length_remaining directly! */ ++#define tvb_length_remaining tvb_captured_length_remaining ++ + + /** Same as above, but throws an exception if the offset is out of bounds. */ +-WS_DLL_PUBLIC guint tvb_ensure_length_remaining(const tvbuff_t*, const gint offset); ++WS_DLL_PUBLIC guint tvb_ensure_captured_length_remaining(const tvbuff_t *tvb, ++ const gint offset); ++ ++/* DEPRECATED, do not use in new code, call tvb_ensure_captured_length_remaining directly! */ ++#define tvb_ensure_length_remaining tvb_ensure_captured_length_remaining + + /* Checks (w/o throwing exception) that the bytes referred to by + * 'offset'/'length' actually exist in the buffer */ +@@ -240,8 +252,7 @@ WS_DLL_PUBLIC guint tvb_reported_length(const tvbuff_t*); + + /** Computes bytes of reported packet data to end of buffer, from offset + * (which can be negative, to indicate bytes from end of buffer). Function +- * returns -1 to indicate that offset is out of bounds. No exception is +- * thrown. */ ++ * returns 0 if offset is out of bounds. No exception is thrown. */ + WS_DLL_PUBLIC gint tvb_reported_length_remaining(const tvbuff_t *tvb, const gint offset); + + /** Set the reported length of a tvbuff to a given value; used for protocols diff --git a/SOURCES/wireshark-1.10.3-dtls-elliptic-curves.patch b/SOURCES/wireshark-1.10.3-dtls-elliptic-curves.patch new file mode 100644 index 0000000..7024eb1 --- /dev/null +++ b/SOURCES/wireshark-1.10.3-dtls-elliptic-curves.patch @@ -0,0 +1,106 @@ +diff --git a/epan/dissectors/packet-dtls.c b/epan/dissectors/packet-dtls.c +index f0c8a3e..5e287e0 100644 +--- a/epan/dissectors/packet-dtls.c ++++ b/epan/dissectors/packet-dtls.c +@@ -119,6 +119,9 @@ static gint hf_dtls_handshake_extensions_len = -1; + static gint hf_dtls_handshake_extension_type = -1; + static gint hf_dtls_handshake_extension_len = -1; + static gint hf_dtls_handshake_extension_data = -1; ++static gint hf_ssl_handshake_extension_elliptic_curves_len = -1; ++static gint hf_ssl_handshake_extension_elliptic_curves = -1; ++static gint hf_ssl_handshake_extension_elliptic_curve = -1; + static gint hf_dtls_handshake_session_ticket_lifetime_hint = -1; + static gint hf_dtls_handshake_session_ticket_len = -1; + static gint hf_dtls_handshake_session_ticket = -1; +@@ -165,6 +168,7 @@ static gint ett_dtls_heartbeat = -1; + static gint ett_dtls_cipher_suites = -1; + static gint ett_dtls_comp_methods = -1; + static gint ett_dtls_extension = -1; ++static gint ett_dtls_extension_curves = -1; + static gint ett_dtls_new_ses_ticket = -1; + static gint ett_dtls_certs = -1; + static gint ett_dtls_cert_types = -1; +@@ -1654,6 +1658,43 @@ dissect_dtls_hnd_hello_common(tvbuff_t *tvb, proto_tree *tree, + } + + static gint ++dissect_dtls_hnd_hello_ext_elliptic_curves(tvbuff_t *tvb, ++ proto_tree *tree, guint32 offset) ++{ ++ gint16 curves_length; ++ proto_tree *curves_tree; ++ proto_item *ti; ++ ++ curves_length = tvb_get_ntohs(tvb, offset); ++ proto_tree_add_item(tree, hf_ssl_handshake_extension_elliptic_curves_len, ++ tvb, offset, 2, ENC_BIG_ENDIAN); ++ ++ offset += 2; ++ tvb_ensure_bytes_exist(tvb, offset, curves_length); ++ ti = proto_tree_add_none_format(tree, ++ hf_ssl_handshake_extension_elliptic_curves, ++ tvb, offset, curves_length, ++ "Elliptic curves (%d curve%s)", ++ curves_length / 2, ++ plurality(curves_length/2, "", "s")); ++ ++ /* make this a subtree */ ++ curves_tree = proto_item_add_subtree(ti, ett_dtls_extension_curves); ++ ++ /* loop over all curves */ ++ while (curves_length > 0) ++ { ++ proto_tree_add_item(curves_tree, ++ hf_ssl_handshake_extension_elliptic_curve, ++ tvb, offset, 2, ENC_BIG_ENDIAN); ++ offset += 2; ++ curves_length -= 2; ++ } ++ ++ return offset; ++} ++ ++static gint + dissect_dtls_hnd_hello_ext(tvbuff_t *tvb, + proto_tree *tree, guint32 offset, guint32 left) + { +@@ -1700,6 +1741,9 @@ dissect_dtls_hnd_hello_ext(tvbuff_t *tvb, + tvb, offset, 1, ENC_BIG_ENDIAN); + offset += ext_len; + break; ++ case SSL_HND_HELLO_EXT_ELLIPTIC_CURVES: ++ offset = dissect_dtls_hnd_hello_ext_elliptic_curves(tvb, ext_tree, offset); ++ break; + default: + proto_tree_add_bytes_format(ext_tree, hf_dtls_handshake_extension_data, + tvb, offset, ext_len, NULL, +@@ -2534,6 +2578,21 @@ proto_register_dtls(void) + FT_BYTES, BASE_NONE, NULL, 0x0, + "Hello Extension data", HFILL } + }, ++ { &hf_ssl_handshake_extension_elliptic_curves_len, ++ { "Elliptic Curves Length", "dtls.handshake.extensions_elliptic_curves_length", ++ FT_UINT16, BASE_DEC, NULL, 0x0, ++ "Length of elliptic curves field", HFILL } ++ }, ++ { &hf_ssl_handshake_extension_elliptic_curves, ++ { "Elliptic Curves List", "dtls.handshake.extensions_elliptic_curves", ++ FT_NONE, BASE_NONE, NULL, 0x0, ++ "List of elliptic curves supported", HFILL } ++ }, ++ { &hf_ssl_handshake_extension_elliptic_curve, ++ { "Elliptic curve", "dtls.handshake.extensions_elliptic_curve", ++ FT_UINT16, BASE_HEX, VALS(ssl_extension_curves), 0x0, ++ NULL, HFILL } ++ }, + { &hf_dtls_handshake_session_ticket_lifetime_hint, + { "Session Ticket Lifetime Hint", "dtls.handshake.session_ticket_lifetime_hint", + FT_UINT32, BASE_DEC, NULL, 0x0, +@@ -2707,6 +2766,7 @@ proto_register_dtls(void) + &ett_dtls_cipher_suites, + &ett_dtls_comp_methods, + &ett_dtls_extension, ++ &ett_dtls_extension_curves, + &ett_dtls_new_ses_ticket, + &ett_dtls_certs, + &ett_dtls_cert_types, diff --git a/SOURCES/wireshark-1.10.3-nanosecond-timestamps.patch b/SOURCES/wireshark-1.10.3-nanosecond-timestamps.patch new file mode 100644 index 0000000..2809de3 --- /dev/null +++ b/SOURCES/wireshark-1.10.3-nanosecond-timestamps.patch @@ -0,0 +1,2476 @@ +diff --git a/acinclude.m4 b/acinclude.m4 +index f962022..719bdbe 100644 +--- a/acinclude.m4 ++++ b/acinclude.m4 +@@ -615,7 +615,7 @@ install a newer version of the header file.]) + AC_CHECK_FUNCS(pcap_datalink_val_to_description) + AC_CHECK_FUNCS(pcap_list_datalinks pcap_set_datalink pcap_lib_version) + AC_CHECK_FUNCS(pcap_get_selectable_fd pcap_free_datalinks) +- AC_CHECK_FUNCS(pcap_create bpf_image) ++ AC_CHECK_FUNCS(pcap_create bpf_image pcap_set_tstamp_precision) + fi + LIBS="$ac_save_LIBS" + ]) +diff --git a/cmake/modules/FindPCAP.cmake b/cmake/modules/FindPCAP.cmake +index 1d3c1b6..bde07d7 100644 +--- a/cmake/modules/FindPCAP.cmake ++++ b/cmake/modules/FindPCAP.cmake +@@ -121,6 +121,7 @@ CHECK_FUNCTION_EXISTS("pcap_get_selectable_fd" HAVE_PCAP_GET_SELECTABLE_FD) + CHECK_FUNCTION_EXISTS("pcap_lib_version" HAVE_PCAP_LIB_VERSION) + CHECK_FUNCTION_EXISTS("pcap_list_datalinks" HAVE_PCAP_LIST_DATALINKS) + CHECK_FUNCTION_EXISTS("pcap_set_datalink" HAVE_PCAP_SET_DATALINK) ++CHECK_FUNCTION_EXISTS("pcap_set_tstamp_precision" HAVE_PCAP_SET_TSTAMP_PRECISION) + # Remote pcap checks + CHECK_FUNCTION_EXISTS("pcap_open" H_PCAP_OPEN) + CHECK_FUNCTION_EXISTS("pcap_findalldevs_ex" H_FINDALLDEVS_EX) +diff --git a/cmakeconfig.h.in b/cmakeconfig.h.in +index 2ef36d1..fee55c5 100644 +--- a/cmakeconfig.h.in ++++ b/cmakeconfig.h.in +@@ -252,6 +252,9 @@ + #cmakedefine HAVE_PCAP_REMOTE 1 + #cmakedefine HAVE_REMOTE 1 + ++/* Define to 1 if you have the `pcap_set_tstamp_precision' function. */ ++#cmakedefine HAVE_PCAP_SET_TSTAMP_PRECISION 1 ++ + /* Define to 1 if you have the header file. */ + #cmakedefine HAVE_PORTAUDIO_H 1 + +diff --git a/dumpcap.c b/dumpcap.c +index adba93d..bae3fbf 100644 +--- a/dumpcap.c ++++ b/dumpcap.c +@@ -641,7 +641,12 @@ relinquish_all_capabilities(void) + #endif + + static pcap_t * +-open_capture_device(interface_options *interface_opts, ++open_capture_device(capture_options *capture_opts ++#ifndef HAVE_PCAP_SET_TSTAMP_PRECISION ++ _U_ ++#endif ++ , ++ interface_options *interface_opts, + char (*open_err_str)[PCAP_ERRBUF_SIZE]) + { + pcap_t *pcap_h; +@@ -714,6 +719,31 @@ open_capture_device(interface_options *interface_opts, + pcap_set_promisc(pcap_h, interface_opts->promisc_mode); + pcap_set_timeout(pcap_h, CAP_READ_TIMEOUT); + ++#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION ++ /* ++ * If we're writing pcap-ng files, try to enable ++ * nanosecond-resolution capture; any code that ++ * can read pcap-ng files must be able to handle ++ * nanosecond-resolution time stamps. ++ * ++ * If we're writing pcap files, don't try to enable ++ * nanosecond-resolution capture, as not all code ++ * that reads pcap files recognizes the nanosecond- ++ * resolution pcap file magic number. ++ */ ++ if (capture_opts->use_pcapng) { ++ /* ++ * The only errors this is documenting as returning ++ * are PCAP_ERROR_TSTAMP_PRECISION_NOTSUP, which jus ++ * means we can't do nanosecond precision on this adapter, ++ * in which case we just live with whatever resolution ++ * we get by default, and PCAP_ERROR_ACTIVATED, which ++ * can't happen as we haven't activated the pcap_t yet. ++ */ ++ pcap_set_tstamp_precision(pcap_h, PCAP_TSTAMP_PRECISION_NANO); ++ } ++#endif ++ + g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, + "buffersize %d.", interface_opts->buffer_size); + if (interface_opts->buffer_size != 0) { +@@ -913,7 +943,7 @@ show_filter_code(capture_options *capture_opts) + + for (j = 0; j < capture_opts->ifaces->len; j++) { + interface_opts = g_array_index(capture_opts->ifaces, interface_options, j); +- pcap_h = open_capture_device(&interface_opts, &open_err_str); ++ pcap_h = open_capture_device(capture_opts, &interface_opts, &open_err_str); + if (pcap_h == NULL) { + /* Open failed; get messages */ + get_capture_device_open_failure_messages(open_err_str, +@@ -2680,10 +2710,16 @@ capture_loop_open_input(capture_options *capture_opts, loop_data *ld, + g_array_append_val(ld->pcaps, pcap_opts); + + g_log(LOG_DOMAIN_CAPTURE_CHILD, G_LOG_LEVEL_DEBUG, "capture_loop_open_input : %s", interface_opts.name); +- pcap_opts->pcap_h = open_capture_device(&interface_opts, &open_err_str); ++ pcap_opts->pcap_h = open_capture_device(capture_opts, &interface_opts, &open_err_str); + + if (pcap_opts->pcap_h != NULL) { + /* we've opened "iface" as a network device */ ++ ++#ifdef HAVE_PCAP_SET_TSTAMP_PRECISION ++ /* Find out if we're getting nanosecond-precision time stamps */ ++ pcap_opts->ts_nsec = pcap_get_tstamp_precision(pcap_opts->pcap_h) == PCAP_TSTAMP_PRECISION_NANO; ++#endif ++ + #ifdef _WIN32 + /* try to set the capture buffer size */ + if (interface_opts.buffer_size > 1 && +diff --git a/editcap.c b/editcap.c +index 9ba8245..8caa1bf 100644 +--- a/editcap.c ++++ b/editcap.c +@@ -125,7 +125,6 @@ fd_hash_t fd_hash[MAX_DUP_DEPTH]; + int dup_window = DEFAULT_DUP_DEPTH; + int cur_dup_entry = 0; + +-#define ONE_MILLION 1000000 + #define ONE_BILLION 1000000000 + + /* Weights of different errors we can introduce */ +@@ -143,7 +142,7 @@ int cur_dup_entry = 0; + + + struct time_adjustment { +- struct timeval tv; ++ nstime_t tv; + int is_negative; + }; + +@@ -368,18 +367,18 @@ set_time_adjustment(char *optarg_str_p) + exit(1); + } + } +- time_adj.tv.tv_sec = val; ++ time_adj.tv.secs = val; + + /* now collect the partial seconds, if any */ + if (*frac != '\0') { /* chars left, so get fractional part */ + val = strtol(&(frac[1]), &end, 10); +- /* if more than 6 fractional digits truncate to 6 */ +- if((end - &(frac[1])) > 6) { +- frac[7] = 't'; /* 't' for truncate */ ++ /* if more than 9 fractional digits truncate to 9 */ ++ if((end - &(frac[1])) > 9) { ++ frac[10] = 't'; /* 't' for truncate */ + val = strtol(&(frac[1]), &end, 10); + } + if (*frac != '.' || end == NULL || end == frac +- || val < 0 || val > ONE_MILLION || val == LONG_MIN || val == LONG_MAX) { ++ || val < 0 || val > ONE_BILLION || val == LONG_MIN || val == LONG_MAX) { + fprintf(stderr, "editcap: \"%s\" isn't a valid time adjustment\n", + optarg_str_p); + exit(1); +@@ -390,15 +389,15 @@ set_time_adjustment(char *optarg_str_p) + } + + /* adjust fractional portion from fractional to numerator +- * e.g., in "1.5" from 5 to 500000 since .5*10^6 = 500000 */ ++ * e.g., in "1.5" from 5 to 500000000 since .5*10^9 = 500000000 */ + if (frac && end) { /* both are valid */ + frac_digits = end - frac - 1; /* fractional digit count (remember '.') */ +- while(frac_digits < 6) { /* this is frac of 10^6 */ ++ while(frac_digits < 9) { /* this is frac of 10^9 */ + val *= 10; + frac_digits++; + } + } +- time_adj.tv.tv_usec = (int)val; ++ time_adj.tv.nsecs = (int) val; + } + + static void +@@ -443,18 +442,18 @@ set_strict_time_adj(char *optarg_str_p) + exit(1); + } + } +- strict_time_adj.tv.tv_sec = val; ++ strict_time_adj.tv.secs = val; + + /* now collect the partial seconds, if any */ + if (*frac != '\0') { /* chars left, so get fractional part */ + val = strtol(&(frac[1]), &end, 10); +- /* if more than 6 fractional digits truncate to 6 */ +- if((end - &(frac[1])) > 6) { +- frac[7] = 't'; /* 't' for truncate */ ++ /* if more than 9 fractional digits truncate to 9 */ ++ if((end - &(frac[1])) > 9) { ++ frac[10] = 't'; /* 't' for truncate */ + val = strtol(&(frac[1]), &end, 10); + } + if (*frac != '.' || end == NULL || end == frac +- || val < 0 || val > ONE_MILLION || val == LONG_MIN || val == LONG_MAX) { ++ || val < 0 || val > ONE_BILLION || val == LONG_MIN || val == LONG_MAX) { + fprintf(stderr, "editcap: \"%s\" isn't a valid time adjustment\n", + optarg_str_p); + exit(1); +@@ -465,15 +464,15 @@ set_strict_time_adj(char *optarg_str_p) + } + + /* adjust fractional portion from fractional to numerator +- * e.g., in "1.5" from 5 to 500000 since .5*10^6 = 500000 */ ++ * e.g., in "1.5" from 5 to 500000000 since .5*10^9 = 500000000 */ + if (frac && end) { /* both are valid */ + frac_digits = end - frac - 1; /* fractional digit count (remember '.') */ +- while(frac_digits < 6) { /* this is frac of 10^6 */ ++ while(frac_digits < 9) { /* this is frac of 10^9 */ + val *= 10; + frac_digits++; + } + } +- strict_time_adj.tv.tv_usec = (int)val; ++ strict_time_adj.tv.nsecs = (int) val; + } + + static void +@@ -1319,14 +1318,14 @@ main(int argc, char *argv[]) + */ + /* printf("++out of order, need to adjust this packet!\n"); */ + snap_phdr = *phdr; +- snap_phdr.ts.secs = previous_time.secs + strict_time_adj.tv.tv_sec; ++ snap_phdr.ts.secs = previous_time.secs + strict_time_adj.tv.secs; + snap_phdr.ts.nsecs = previous_time.nsecs; +- if (snap_phdr.ts.nsecs + strict_time_adj.tv.tv_usec * 1000 > ONE_MILLION * 1000) { ++ if (snap_phdr.ts.nsecs + strict_time_adj.tv.nsecs > ONE_BILLION) { + /* carry */ + snap_phdr.ts.secs++; +- snap_phdr.ts.nsecs += (strict_time_adj.tv.tv_usec - ONE_MILLION) * 1000; ++ snap_phdr.ts.nsecs += strict_time_adj.tv.nsecs - ONE_BILLION; + } else { +- snap_phdr.ts.nsecs += strict_time_adj.tv.tv_usec * 1000; ++ snap_phdr.ts.nsecs += strict_time_adj.tv.nsecs; + } + phdr = &snap_phdr; + } +@@ -1337,14 +1336,14 @@ main(int argc, char *argv[]) + * packet's timestamp plus delta. + */ + snap_phdr = *phdr; +- snap_phdr.ts.secs = previous_time.secs + strict_time_adj.tv.tv_sec; ++ snap_phdr.ts.secs = previous_time.secs + strict_time_adj.tv.secs; + snap_phdr.ts.nsecs = previous_time.nsecs; +- if (snap_phdr.ts.nsecs + strict_time_adj.tv.tv_usec * 1000 > ONE_MILLION * 1000) { ++ if (snap_phdr.ts.nsecs + strict_time_adj.tv.nsecs > ONE_BILLION) { + /* carry */ + snap_phdr.ts.secs++; +- snap_phdr.ts.nsecs += (strict_time_adj.tv.tv_usec - ONE_MILLION) * 1000; ++ snap_phdr.ts.nsecs += strict_time_adj.tv.nsecs - ONE_BILLION; + } else { +- snap_phdr.ts.nsecs += strict_time_adj.tv.tv_usec * 1000; ++ snap_phdr.ts.nsecs += strict_time_adj.tv.nsecs; + } + phdr = &snap_phdr; + } +@@ -1355,32 +1354,32 @@ main(int argc, char *argv[]) + + /* assume that if the frame's tv_sec is 0, then + * the timestamp isn't supported */ +- if (phdr->ts.secs > 0 && time_adj.tv.tv_sec != 0) { ++ if (phdr->ts.secs > 0 && time_adj.tv.secs != 0) { + snap_phdr = *phdr; + if (time_adj.is_negative) +- snap_phdr.ts.secs -= time_adj.tv.tv_sec; ++ snap_phdr.ts.secs -= time_adj.tv.secs; + else +- snap_phdr.ts.secs += time_adj.tv.tv_sec; ++ snap_phdr.ts.secs += time_adj.tv.secs; + phdr = &snap_phdr; + } + + /* assume that if the frame's tv_sec is 0, then + * the timestamp isn't supported */ +- if (phdr->ts.secs > 0 && time_adj.tv.tv_usec != 0) { ++ if (phdr->ts.secs > 0 && time_adj.tv.nsecs != 0) { + snap_phdr = *phdr; + if (time_adj.is_negative) { /* subtract */ +- if (snap_phdr.ts.nsecs/1000 < time_adj.tv.tv_usec) { /* borrow */ ++ if (snap_phdr.ts.nsecs < time_adj.tv.nsecs) { /* borrow */ + snap_phdr.ts.secs--; +- snap_phdr.ts.nsecs += ONE_MILLION * 1000; ++ snap_phdr.ts.nsecs += ONE_BILLION; + } +- snap_phdr.ts.nsecs -= time_adj.tv.tv_usec * 1000; ++ snap_phdr.ts.nsecs -= time_adj.tv.nsecs; + } else { /* add */ +- if (snap_phdr.ts.nsecs + time_adj.tv.tv_usec * 1000 > ONE_MILLION * 1000) { ++ if (snap_phdr.ts.nsecs + time_adj.tv.nsecs > ONE_BILLION) { + /* carry */ + snap_phdr.ts.secs++; +- snap_phdr.ts.nsecs += (time_adj.tv.tv_usec - ONE_MILLION) * 1000; ++ snap_phdr.ts.nsecs += time_adj.tv.nsecs - ONE_BILLION; + } else { +- snap_phdr.ts.nsecs += time_adj.tv.tv_usec * 1000; ++ snap_phdr.ts.nsecs += time_adj.tv.nsecs; + } + } + phdr = &snap_phdr; +diff --git a/epan/column-utils.c b/epan/column-utils.c +index 6ed9f85..8e89409 100644 +--- a/epan/column-utils.c ++++ b/epan/column-utils.c +@@ -675,6 +675,7 @@ set_abs_date_time(const frame_data *fd, gchar *buf, gboolean local) + { + struct tm *tmp; + time_t then; ++ int tsprecision; + + if (fd->flags.has_ts) { + then = fd->abs_ts.secs; +@@ -685,9 +686,33 @@ set_abs_date_time(const frame_data *fd, gchar *buf, gboolean local) + } else + tmp = NULL; + if (tmp != NULL) { +- switch(timestamp_get_precision()) { +- case TS_PREC_FIXED_SEC: +- case TS_PREC_AUTO_SEC: ++ switch (timestamp_get_precision()) { ++ case TS_PREC_FIXED_SEC: ++ tsprecision = WTAP_TSPREC_SEC; ++ break; ++ case TS_PREC_FIXED_DSEC: ++ tsprecision = WTAP_TSPREC_DSEC; ++ break; ++ case TS_PREC_FIXED_CSEC: ++ tsprecision = WTAP_TSPREC_CSEC; ++ break; ++ case TS_PREC_FIXED_MSEC: ++ tsprecision = WTAP_TSPREC_MSEC; ++ break; ++ case TS_PREC_FIXED_USEC: ++ tsprecision = WTAP_TSPREC_USEC; ++ break; ++ case TS_PREC_FIXED_NSEC: ++ tsprecision = WTAP_TSPREC_NSEC; ++ break; ++ case TS_PREC_AUTO: ++ tsprecision = fd->tsprec; ++ break; ++ default: ++ g_assert_not_reached(); ++ } ++ switch(tsprecision) { ++ case WTAP_TSPREC_SEC: + g_snprintf(buf, COL_MAX_LEN,"%04d-%02d-%02d %02d:%02d:%02d", + tmp->tm_year + 1900, + tmp->tm_mon + 1, +@@ -696,8 +721,7 @@ set_abs_date_time(const frame_data *fd, gchar *buf, gboolean local) + tmp->tm_min, + tmp->tm_sec); + break; +- case TS_PREC_FIXED_DSEC: +- case TS_PREC_AUTO_DSEC: ++ case WTAP_TSPREC_DSEC: + g_snprintf(buf, COL_MAX_LEN,"%04d-%02d-%02d %02d:%02d:%02d.%01d", + tmp->tm_year + 1900, + tmp->tm_mon + 1, +@@ -707,8 +731,7 @@ set_abs_date_time(const frame_data *fd, gchar *buf, gboolean local) + tmp->tm_sec, + fd->abs_ts.nsecs / 100000000); + break; +- case TS_PREC_FIXED_CSEC: +- case TS_PREC_AUTO_CSEC: ++ case WTAP_TSPREC_CSEC: + g_snprintf(buf, COL_MAX_LEN,"%04d-%02d-%02d %02d:%02d:%02d.%02d", + tmp->tm_year + 1900, + tmp->tm_mon + 1, +@@ -718,8 +741,7 @@ set_abs_date_time(const frame_data *fd, gchar *buf, gboolean local) + tmp->tm_sec, + fd->abs_ts.nsecs / 10000000); + break; +- case TS_PREC_FIXED_MSEC: +- case TS_PREC_AUTO_MSEC: ++ case WTAP_TSPREC_MSEC: + g_snprintf(buf, COL_MAX_LEN, "%04d-%02d-%02d %02d:%02d:%02d.%03d", + tmp->tm_year + 1900, + tmp->tm_mon + 1, +@@ -729,8 +751,7 @@ set_abs_date_time(const frame_data *fd, gchar *buf, gboolean local) + tmp->tm_sec, + fd->abs_ts.nsecs / 1000000); + break; +- case TS_PREC_FIXED_USEC: +- case TS_PREC_AUTO_USEC: ++ case WTAP_TSPREC_USEC: + g_snprintf(buf, COL_MAX_LEN, "%04d-%02d-%02d %02d:%02d:%02d.%06d", + tmp->tm_year + 1900, + tmp->tm_mon + 1, +@@ -740,8 +761,7 @@ set_abs_date_time(const frame_data *fd, gchar *buf, gboolean local) + tmp->tm_sec, + fd->abs_ts.nsecs / 1000); + break; +- case TS_PREC_FIXED_NSEC: +- case TS_PREC_AUTO_NSEC: ++ case WTAP_TSPREC_NSEC: + g_snprintf(buf, COL_MAX_LEN, "%04d-%02d-%02d %02d:%02d:%02d.%09d", + tmp->tm_year + 1900, + tmp->tm_mon + 1, +@@ -780,36 +800,57 @@ col_set_utc_date_time(const frame_data *fd, column_info *cinfo, const int col) + } + + static void +-set_time_seconds(const nstime_t *ts, gchar *buf) ++set_time_seconds(const frame_data *fd, const nstime_t *ts, gchar *buf) + { +- switch(timestamp_get_precision()) { +- case TS_PREC_FIXED_SEC: +- case TS_PREC_AUTO_SEC: ++ int tsprecision; ++ ++ switch (timestamp_get_precision()) { ++ case TS_PREC_FIXED_SEC: ++ tsprecision = WTAP_TSPREC_SEC; ++ break; ++ case TS_PREC_FIXED_DSEC: ++ tsprecision = WTAP_TSPREC_DSEC; ++ break; ++ case TS_PREC_FIXED_CSEC: ++ tsprecision = WTAP_TSPREC_CSEC; ++ break; ++ case TS_PREC_FIXED_MSEC: ++ tsprecision = WTAP_TSPREC_MSEC; ++ break; ++ case TS_PREC_FIXED_USEC: ++ tsprecision = WTAP_TSPREC_USEC; ++ break; ++ case TS_PREC_FIXED_NSEC: ++ tsprecision = WTAP_TSPREC_NSEC; ++ break; ++ case TS_PREC_AUTO: ++ tsprecision = fd->tsprec; ++ break; ++ default: ++ g_assert_not_reached(); ++ } ++ switch(tsprecision) { ++ case WTAP_TSPREC_SEC: + display_signed_time(buf, COL_MAX_LEN, + (gint32) ts->secs, ts->nsecs / 1000000000, TO_STR_TIME_RES_T_SECS); + break; +- case TS_PREC_FIXED_DSEC: +- case TS_PREC_AUTO_DSEC: ++ case WTAP_TSPREC_DSEC: + display_signed_time(buf, COL_MAX_LEN, + (gint32) ts->secs, ts->nsecs / 100000000, TO_STR_TIME_RES_T_DSECS); + break; +- case TS_PREC_FIXED_CSEC: +- case TS_PREC_AUTO_CSEC: ++ case WTAP_TSPREC_CSEC: + display_signed_time(buf, COL_MAX_LEN, + (gint32) ts->secs, ts->nsecs / 10000000, TO_STR_TIME_RES_T_CSECS); + break; +- case TS_PREC_FIXED_MSEC: +- case TS_PREC_AUTO_MSEC: ++ case WTAP_TSPREC_MSEC: + display_signed_time(buf, COL_MAX_LEN, + (gint32) ts->secs, ts->nsecs / 1000000, TO_STR_TIME_RES_T_MSECS); + break; +- case TS_PREC_FIXED_USEC: +- case TS_PREC_AUTO_USEC: ++ case WTAP_TSPREC_USEC: + display_signed_time(buf, COL_MAX_LEN, + (gint32) ts->secs, ts->nsecs / 1000, TO_STR_TIME_RES_T_USECS); + break; +- case TS_PREC_FIXED_NSEC: +- case TS_PREC_AUTO_NSEC: ++ case WTAP_TSPREC_NSEC: + display_signed_time(buf, COL_MAX_LEN, + (gint32) ts->secs, ts->nsecs, TO_STR_TIME_RES_T_NSECS); + break; +@@ -819,11 +860,12 @@ set_time_seconds(const nstime_t *ts, gchar *buf) + } + + static void +-set_time_hour_min_sec(const nstime_t *ts, gchar *buf) ++set_time_hour_min_sec(const frame_data *fd, const nstime_t *ts, gchar *buf) + { + time_t secs = ts->secs; + long nsecs = (long) ts->nsecs; + gboolean negative = FALSE; ++ int tsprecision; + + if (secs < 0) { + secs = -secs; +@@ -834,9 +876,33 @@ set_time_hour_min_sec(const nstime_t *ts, gchar *buf) + negative = TRUE; + } + +- switch(timestamp_get_precision()) { ++ switch (timestamp_get_precision()) { + case TS_PREC_FIXED_SEC: +- case TS_PREC_AUTO_SEC: ++ tsprecision = WTAP_TSPREC_SEC; ++ break; ++ case TS_PREC_FIXED_DSEC: ++ tsprecision = WTAP_TSPREC_DSEC; ++ break; ++ case TS_PREC_FIXED_CSEC: ++ tsprecision = WTAP_TSPREC_CSEC; ++ break; ++ case TS_PREC_FIXED_MSEC: ++ tsprecision = WTAP_TSPREC_MSEC; ++ break; ++ case TS_PREC_FIXED_USEC: ++ tsprecision = WTAP_TSPREC_USEC; ++ break; ++ case TS_PREC_FIXED_NSEC: ++ tsprecision = WTAP_TSPREC_NSEC; ++ break; ++ case TS_PREC_AUTO: ++ tsprecision = fd->tsprec; ++ break; ++ default: ++ g_assert_not_reached(); ++ } ++ switch(tsprecision) { ++ case WTAP_TSPREC_SEC: + if (secs >= (60*60)) { + g_snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2ds", + negative ? "- " : "", +@@ -854,8 +920,7 @@ set_time_hour_min_sec(const nstime_t *ts, gchar *buf) + (gint32) secs); + } + break; +- case TS_PREC_FIXED_DSEC: +- case TS_PREC_AUTO_DSEC: ++ case WTAP_TSPREC_DSEC: + if (secs >= (60*60)) { + g_snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d.%01lds", + negative ? "- " : "", +@@ -876,8 +941,7 @@ set_time_hour_min_sec(const nstime_t *ts, gchar *buf) + nsecs / 100000000); + } + break; +- case TS_PREC_FIXED_CSEC: +- case TS_PREC_AUTO_CSEC: ++ case WTAP_TSPREC_CSEC: + if (secs >= (60*60)) { + g_snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d.%02lds", + negative ? "- " : "", +@@ -898,8 +962,7 @@ set_time_hour_min_sec(const nstime_t *ts, gchar *buf) + nsecs / 10000000); + } + break; +- case TS_PREC_FIXED_MSEC: +- case TS_PREC_AUTO_MSEC: ++ case WTAP_TSPREC_MSEC: + if (secs >= (60*60)) { + g_snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d.%03lds", + negative ? "- " : "", +@@ -920,8 +983,7 @@ set_time_hour_min_sec(const nstime_t *ts, gchar *buf) + nsecs / 1000000); + } + break; +- case TS_PREC_FIXED_USEC: +- case TS_PREC_AUTO_USEC: ++ case WTAP_TSPREC_USEC: + if (secs >= (60*60)) { + g_snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d.%06lds", + negative ? "- " : "", +@@ -942,8 +1004,7 @@ set_time_hour_min_sec(const nstime_t *ts, gchar *buf) + nsecs / 1000); + } + break; +- case TS_PREC_FIXED_NSEC: +- case TS_PREC_AUTO_NSEC: ++ case WTAP_TSPREC_NSEC: + if (secs >= (60*60)) { + g_snprintf(buf, COL_MAX_LEN, "%s%dh %2dm %2d.%09lds", + negative ? "- " : "", +@@ -978,14 +1039,14 @@ col_set_rel_time(const frame_data *fd, column_info *cinfo, const int col) + } + switch (timestamp_get_seconds_type()) { + case TS_SECONDS_DEFAULT: +- set_time_seconds(&fd->rel_ts, cinfo->col_buf[col]); ++ set_time_seconds(fd, &fd->rel_ts, cinfo->col_buf[col]); + cinfo->col_expr.col_expr[col] = "frame.time_relative"; + g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->col_buf[col],COL_MAX_LEN); + break; + case TS_SECONDS_HOUR_MIN_SEC: +- set_time_hour_min_sec(&fd->rel_ts, cinfo->col_buf[col]); ++ set_time_hour_min_sec(fd, &fd->rel_ts, cinfo->col_buf[col]); + cinfo->col_expr.col_expr[col] = "frame.time_relative"; +- set_time_seconds(&fd->rel_ts, cinfo->col_expr.col_expr_val[col]); ++ set_time_seconds(fd, &fd->rel_ts, cinfo->col_expr.col_expr_val[col]); + break; + default: + g_assert_not_reached(); +@@ -1002,14 +1063,14 @@ col_set_delta_time(const frame_data *fd, column_info *cinfo, const int col) + + switch (timestamp_get_seconds_type()) { + case TS_SECONDS_DEFAULT: +- set_time_seconds(&del_cap_ts, cinfo->col_buf[col]); ++ set_time_seconds(fd, &del_cap_ts, cinfo->col_buf[col]); + cinfo->col_expr.col_expr[col] = "frame.time_delta"; + g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->col_buf[col],COL_MAX_LEN); + break; + case TS_SECONDS_HOUR_MIN_SEC: +- set_time_hour_min_sec(&del_cap_ts, cinfo->col_buf[col]); ++ set_time_hour_min_sec(fd, &del_cap_ts, cinfo->col_buf[col]); + cinfo->col_expr.col_expr[col] = "frame.time_delta"; +- set_time_seconds(&del_cap_ts, cinfo->col_expr.col_expr_val[col]); ++ set_time_seconds(fd, &del_cap_ts, cinfo->col_expr.col_expr_val[col]); + break; + default: + g_assert_not_reached(); +@@ -1032,14 +1093,14 @@ col_set_delta_time_dis(const frame_data *fd, column_info *cinfo, const int col) + + switch (timestamp_get_seconds_type()) { + case TS_SECONDS_DEFAULT: +- set_time_seconds(&del_dis_ts, cinfo->col_buf[col]); ++ set_time_seconds(fd, &del_dis_ts, cinfo->col_buf[col]); + cinfo->col_expr.col_expr[col] = "frame.time_delta_displayed"; + g_strlcpy(cinfo->col_expr.col_expr_val[col],cinfo->col_buf[col],COL_MAX_LEN); + break; + case TS_SECONDS_HOUR_MIN_SEC: +- set_time_hour_min_sec(&del_dis_ts, cinfo->col_buf[col]); ++ set_time_hour_min_sec(fd, &del_dis_ts, cinfo->col_buf[col]); + cinfo->col_expr.col_expr[col] = "frame.time_delta_displayed"; +- set_time_seconds(&del_dis_ts, cinfo->col_expr.col_expr_val[col]); ++ set_time_seconds(fd, &del_dis_ts, cinfo->col_expr.col_expr_val[col]); + break; + default: + g_assert_not_reached(); +@@ -1053,6 +1114,7 @@ set_abs_time(const frame_data *fd, gchar *buf, gboolean local) + { + struct tm *tmp; + time_t then; ++ int tsprecision; + + if (fd->flags.has_ts) { + then = fd->abs_ts.secs; +@@ -1063,48 +1125,67 @@ set_abs_time(const frame_data *fd, gchar *buf, gboolean local) + } else + tmp = NULL; + if (tmp != NULL) { +- switch(timestamp_get_precision()) { ++ switch (timestamp_get_precision()) { + case TS_PREC_FIXED_SEC: +- case TS_PREC_AUTO_SEC: ++ tsprecision = WTAP_TSPREC_SEC; ++ break; ++ case TS_PREC_FIXED_DSEC: ++ tsprecision = WTAP_TSPREC_DSEC; ++ break; ++ case TS_PREC_FIXED_CSEC: ++ tsprecision = WTAP_TSPREC_CSEC; ++ break; ++ case TS_PREC_FIXED_MSEC: ++ tsprecision = WTAP_TSPREC_MSEC; ++ break; ++ case TS_PREC_FIXED_USEC: ++ tsprecision = WTAP_TSPREC_USEC; ++ break; ++ case TS_PREC_FIXED_NSEC: ++ tsprecision = WTAP_TSPREC_NSEC; ++ break; ++ case TS_PREC_AUTO: ++ tsprecision = fd->tsprec; ++ break; ++ default: ++ g_assert_not_reached(); ++ } ++ switch(tsprecision) { ++ case WTAP_TSPREC_SEC: + g_snprintf(buf, COL_MAX_LEN,"%02d:%02d:%02d", + tmp->tm_hour, + tmp->tm_min, + tmp->tm_sec); + break; +- case TS_PREC_FIXED_DSEC: +- case TS_PREC_AUTO_DSEC: ++ case WTAP_TSPREC_DSEC: + g_snprintf(buf, COL_MAX_LEN,"%02d:%02d:%02d.%01d", + tmp->tm_hour, + tmp->tm_min, + tmp->tm_sec, + fd->abs_ts.nsecs / 100000000); + break; +- case TS_PREC_FIXED_CSEC: +- case TS_PREC_AUTO_CSEC: ++ case WTAP_TSPREC_CSEC: + g_snprintf(buf, COL_MAX_LEN,"%02d:%02d:%02d.%02d", + tmp->tm_hour, + tmp->tm_min, + tmp->tm_sec, + fd->abs_ts.nsecs / 10000000); + break; +- case TS_PREC_FIXED_MSEC: +- case TS_PREC_AUTO_MSEC: ++ case WTAP_TSPREC_MSEC: + g_snprintf(buf, COL_MAX_LEN,"%02d:%02d:%02d.%03d", + tmp->tm_hour, + tmp->tm_min, + tmp->tm_sec, + fd->abs_ts.nsecs / 1000000); + break; +- case TS_PREC_FIXED_USEC: +- case TS_PREC_AUTO_USEC: ++ case WTAP_TSPREC_USEC: + g_snprintf(buf, COL_MAX_LEN,"%02d:%02d:%02d.%06d", + tmp->tm_hour, + tmp->tm_min, + tmp->tm_sec, + fd->abs_ts.nsecs / 1000); + break; +- case TS_PREC_FIXED_NSEC: +- case TS_PREC_AUTO_NSEC: ++ case WTAP_TSPREC_NSEC: + g_snprintf(buf, COL_MAX_LEN, "%02d:%02d:%02d.%09d", + tmp->tm_hour, + tmp->tm_min, +@@ -1143,38 +1224,59 @@ col_set_utc_time(const frame_data *fd, column_info *cinfo, const int col) + static gboolean + set_epoch_time(const frame_data *fd, gchar *buf) + { ++ int tsprecision; ++ + if (!fd->flags.has_ts) { + buf[0] = '\0'; + return FALSE; + } +- switch(timestamp_get_precision()) { +- case TS_PREC_FIXED_SEC: +- case TS_PREC_AUTO_SEC: ++ switch (timestamp_get_precision()) { ++ case TS_PREC_FIXED_SEC: ++ tsprecision = WTAP_TSPREC_SEC; ++ break; ++ case TS_PREC_FIXED_DSEC: ++ tsprecision = WTAP_TSPREC_DSEC; ++ break; ++ case TS_PREC_FIXED_CSEC: ++ tsprecision = WTAP_TSPREC_CSEC; ++ break; ++ case TS_PREC_FIXED_MSEC: ++ tsprecision = WTAP_TSPREC_MSEC; ++ break; ++ case TS_PREC_FIXED_USEC: ++ tsprecision = WTAP_TSPREC_USEC; ++ break; ++ case TS_PREC_FIXED_NSEC: ++ tsprecision = WTAP_TSPREC_NSEC; ++ break; ++ case TS_PREC_AUTO: ++ tsprecision = fd->tsprec; ++ break; ++ default: ++ g_assert_not_reached(); ++ } ++ switch(tsprecision) { ++ case WTAP_TSPREC_SEC: + display_epoch_time(buf, COL_MAX_LEN, + fd->abs_ts.secs, fd->abs_ts.nsecs / 1000000000, TO_STR_TIME_RES_T_SECS); + break; +- case TS_PREC_FIXED_DSEC: +- case TS_PREC_AUTO_DSEC: ++ case WTAP_TSPREC_DSEC: + display_epoch_time(buf, COL_MAX_LEN, + fd->abs_ts.secs, fd->abs_ts.nsecs / 100000000, TO_STR_TIME_RES_T_DSECS); + break; +- case TS_PREC_FIXED_CSEC: +- case TS_PREC_AUTO_CSEC: ++ case WTAP_TSPREC_CSEC: + display_epoch_time(buf, COL_MAX_LEN, + fd->abs_ts.secs, fd->abs_ts.nsecs / 10000000, TO_STR_TIME_RES_T_CSECS); + break; +- case TS_PREC_FIXED_MSEC: +- case TS_PREC_AUTO_MSEC: ++ case WTAP_TSPREC_MSEC: + display_epoch_time(buf, COL_MAX_LEN, + fd->abs_ts.secs, fd->abs_ts.nsecs / 1000000, TO_STR_TIME_RES_T_MSECS); + break; +- case TS_PREC_FIXED_USEC: +- case TS_PREC_AUTO_USEC: ++ case WTAP_TSPREC_USEC: + display_epoch_time(buf, COL_MAX_LEN, + fd->abs_ts.secs, fd->abs_ts.nsecs / 1000, TO_STR_TIME_RES_T_USECS); + break; +- case TS_PREC_FIXED_NSEC: +- case TS_PREC_AUTO_NSEC: ++ case WTAP_TSPREC_NSEC: + display_epoch_time(buf, COL_MAX_LEN, + fd->abs_ts.secs, fd->abs_ts.nsecs, TO_STR_TIME_RES_T_NSECS); + break; +@@ -1211,10 +1313,10 @@ set_fd_time(frame_data *fd, gchar *buf) + if (fd->flags.has_ts) { + switch (timestamp_get_seconds_type()) { + case TS_SECONDS_DEFAULT: +- set_time_seconds(&fd->rel_ts, buf); ++ set_time_seconds(fd, &fd->rel_ts, buf); + break; + case TS_SECONDS_HOUR_MIN_SEC: +- set_time_seconds(&fd->rel_ts, buf); ++ set_time_seconds(fd, &fd->rel_ts, buf); + break; + default: + g_assert_not_reached(); +@@ -1232,10 +1334,10 @@ set_fd_time(frame_data *fd, gchar *buf) + + switch (timestamp_get_seconds_type()) { + case TS_SECONDS_DEFAULT: +- set_time_seconds(&del_cap_ts, buf); ++ set_time_seconds(fd, &del_cap_ts, buf); + break; + case TS_SECONDS_HOUR_MIN_SEC: +- set_time_hour_min_sec(&del_cap_ts, buf); ++ set_time_hour_min_sec(fd, &del_cap_ts, buf); + break; + default: + g_assert_not_reached(); +@@ -1253,10 +1355,10 @@ set_fd_time(frame_data *fd, gchar *buf) + + switch (timestamp_get_seconds_type()) { + case TS_SECONDS_DEFAULT: +- set_time_seconds(&del_dis_ts, buf); ++ set_time_seconds(fd, &del_dis_ts, buf); + break; + case TS_SECONDS_HOUR_MIN_SEC: +- set_time_hour_min_sec(&del_dis_ts, buf); ++ set_time_hour_min_sec(fd, &del_dis_ts, buf); + break; + default: + g_assert_not_reached(); +@@ -1400,38 +1502,33 @@ col_set_time(column_info *cinfo, const gint el, const nstime_t *ts, const char * + for (col = cinfo->col_first[el]; col <= cinfo->col_last[el]; col++) { + if (cinfo->fmt_matx[col][el]) { + switch(timestamp_get_precision()) { +- case TS_PREC_FIXED_SEC: +- case TS_PREC_AUTO_SEC: +- display_signed_time(cinfo->col_buf[col], COL_MAX_LEN, +- (gint32) ts->secs, ts->nsecs / 1000000000, TO_STR_TIME_RES_T_SECS); +- break; +- case TS_PREC_FIXED_DSEC: +- case TS_PREC_AUTO_DSEC: +- display_signed_time(cinfo->col_buf[col], COL_MAX_LEN, +- (gint32) ts->secs, ts->nsecs / 100000000, TO_STR_TIME_RES_T_DSECS); +- break; +- case TS_PREC_FIXED_CSEC: +- case TS_PREC_AUTO_CSEC: +- display_signed_time(cinfo->col_buf[col], COL_MAX_LEN, +- (gint32) ts->secs, ts->nsecs / 10000000, TO_STR_TIME_RES_T_CSECS); +- break; +- case TS_PREC_FIXED_MSEC: +- case TS_PREC_AUTO_MSEC: +- display_signed_time(cinfo->col_buf[col], COL_MAX_LEN, +- (gint32) ts->secs, ts->nsecs / 1000000, TO_STR_TIME_RES_T_MSECS); +- break; +- case TS_PREC_FIXED_USEC: +- case TS_PREC_AUTO_USEC: +- display_signed_time(cinfo->col_buf[col], COL_MAX_LEN, +- (gint32) ts->secs, ts->nsecs / 1000, TO_STR_TIME_RES_T_USECS); +- break; +- case TS_PREC_FIXED_NSEC: +- case TS_PREC_AUTO_NSEC: +- display_signed_time(cinfo->col_buf[col], COL_MAX_LEN, +- (gint32) ts->secs, ts->nsecs, TO_STR_TIME_RES_T_NSECS); +- break; +- default: +- g_assert_not_reached(); ++ case TS_PREC_FIXED_SEC: ++ display_signed_time(cinfo->col_buf[col], COL_MAX_LEN, ++ (gint32) ts->secs, ts->nsecs / 1000000000, TO_STR_TIME_RES_T_SECS); ++ break; ++ case TS_PREC_FIXED_DSEC: ++ display_signed_time(cinfo->col_buf[col], COL_MAX_LEN, ++ (gint32) ts->secs, ts->nsecs / 100000000, TO_STR_TIME_RES_T_DSECS); ++ break; ++ case TS_PREC_FIXED_CSEC: ++ display_signed_time(cinfo->col_buf[col], COL_MAX_LEN, ++ (gint32) ts->secs, ts->nsecs / 10000000, TO_STR_TIME_RES_T_CSECS); ++ break; ++ case TS_PREC_FIXED_MSEC: ++ display_signed_time(cinfo->col_buf[col], COL_MAX_LEN, ++ (gint32) ts->secs, ts->nsecs / 1000000, TO_STR_TIME_RES_T_MSECS); ++ break; ++ case TS_PREC_FIXED_USEC: ++ display_signed_time(cinfo->col_buf[col], COL_MAX_LEN, ++ (gint32) ts->secs, ts->nsecs / 1000, TO_STR_TIME_RES_T_USECS); ++ break; ++ case TS_PREC_FIXED_NSEC: ++ case TS_PREC_AUTO: /* default to maximum */ ++ display_signed_time(cinfo->col_buf[col], COL_MAX_LEN, ++ (gint32) ts->secs, ts->nsecs, TO_STR_TIME_RES_T_NSECS); ++ break; ++ default: ++ g_assert_not_reached(); + } + cinfo->col_data[col] = cinfo->col_buf[col]; + cinfo->col_expr.col_expr[col] = fieldname; +diff --git a/epan/column.c b/epan/column.c +index 231f1c5..43da75f 100644 +--- a/epan/column.c ++++ b/epan/column.c +@@ -254,28 +254,23 @@ get_timestamp_column_longest_string(const gint type, const gint precision) + case(TS_ABSOLUTE_WITH_DATE): + case(TS_UTC_WITH_DATE): + switch(precision) { +- case(TS_PREC_AUTO_SEC): + case(TS_PREC_FIXED_SEC): + return "0000-00-00 00:00:00"; + break; +- case(TS_PREC_AUTO_DSEC): + case(TS_PREC_FIXED_DSEC): + return "0000-00-00 00:00:00.0"; + break; +- case(TS_PREC_AUTO_CSEC): + case(TS_PREC_FIXED_CSEC): + return "0000-00-00 00:00:00.00"; + break; +- case(TS_PREC_AUTO_MSEC): + case(TS_PREC_FIXED_MSEC): + return "0000-00-00 00:00:00.000"; + break; +- case(TS_PREC_AUTO_USEC): + case(TS_PREC_FIXED_USEC): + return "0000-00-00 00:00:00.000000"; + break; +- case(TS_PREC_AUTO_NSEC): + case(TS_PREC_FIXED_NSEC): ++ case(TS_PREC_AUTO): /* Leave enough room for the maximum */ + return "0000-00-00 00:00:00.000000000"; + break; + default: +@@ -285,28 +280,23 @@ get_timestamp_column_longest_string(const gint type, const gint precision) + case(TS_ABSOLUTE): + case(TS_UTC): + switch(precision) { +- case(TS_PREC_AUTO_SEC): + case(TS_PREC_FIXED_SEC): + return "00:00:00"; + break; +- case(TS_PREC_AUTO_DSEC): + case(TS_PREC_FIXED_DSEC): + return "00:00:00.0"; + break; +- case(TS_PREC_AUTO_CSEC): + case(TS_PREC_FIXED_CSEC): + return "00:00:00.00"; + break; +- case(TS_PREC_AUTO_MSEC): + case(TS_PREC_FIXED_MSEC): + return "00:00:00.000"; + break; +- case(TS_PREC_AUTO_USEC): + case(TS_PREC_FIXED_USEC): + return "00:00:00.000000"; + break; +- case(TS_PREC_AUTO_NSEC): + case(TS_PREC_FIXED_NSEC): ++ case(TS_PREC_AUTO): /* Leave enough room for the maximum */ + return "00:00:00.000000000"; + break; + default: +@@ -317,28 +307,23 @@ get_timestamp_column_longest_string(const gint type, const gint precision) + case(TS_DELTA): + case(TS_DELTA_DIS): + switch(precision) { +- case(TS_PREC_AUTO_SEC): + case(TS_PREC_FIXED_SEC): + return "0000"; + break; +- case(TS_PREC_AUTO_DSEC): + case(TS_PREC_FIXED_DSEC): + return "0000.0"; + break; +- case(TS_PREC_AUTO_CSEC): + case(TS_PREC_FIXED_CSEC): + return "0000.00"; + break; +- case(TS_PREC_AUTO_MSEC): + case(TS_PREC_FIXED_MSEC): + return "0000.000"; + break; +- case(TS_PREC_AUTO_USEC): + case(TS_PREC_FIXED_USEC): + return "0000.000000"; + break; +- case(TS_PREC_AUTO_NSEC): + case(TS_PREC_FIXED_NSEC): ++ case(TS_PREC_AUTO): /* Leave enough room for the maximum */ + return "0000.000000000"; + break; + default: +@@ -348,28 +333,23 @@ get_timestamp_column_longest_string(const gint type, const gint precision) + case(TS_EPOCH): + /* This is enough to represent 2^63 (signed 64-bit integer) + fractions */ + switch(precision) { +- case(TS_PREC_AUTO_SEC): + case(TS_PREC_FIXED_SEC): + return "0000000000000000000"; + break; +- case(TS_PREC_AUTO_DSEC): + case(TS_PREC_FIXED_DSEC): + return "0000000000000000000.0"; + break; +- case(TS_PREC_AUTO_CSEC): + case(TS_PREC_FIXED_CSEC): + return "0000000000000000000.00"; + break; +- case(TS_PREC_AUTO_MSEC): + case(TS_PREC_FIXED_MSEC): + return "0000000000000000000.000"; + break; +- case(TS_PREC_AUTO_USEC): + case(TS_PREC_FIXED_USEC): + return "0000000000000000000.000000"; + break; +- case(TS_PREC_AUTO_NSEC): + case(TS_PREC_FIXED_NSEC): ++ case(TS_PREC_AUTO): /* Leave enough room for the maximum */ + return "0000000000000000000.000000000"; + break; + default: +diff --git a/epan/frame_data.c b/epan/frame_data.c +index 63d9805..79b435e 100644 +--- a/epan/frame_data.c ++++ b/epan/frame_data.c +@@ -269,6 +269,7 @@ frame_data_init(frame_data *fdata, guint32 num, + fdata->flags.ignored = 0; + fdata->flags.has_ts = (phdr->presence_flags & WTAP_HAS_TS) ? 1 : 0; + fdata->flags.has_if_id = (phdr->presence_flags & WTAP_HAS_INTERFACE_ID) ? 1 : 0; ++ fdata->tsprec = (guint16)phdr->pkt_tsprec; + fdata->flags.has_pack_flags = (phdr->presence_flags & WTAP_HAS_PACK_FLAGS) ? 1 : 0; + fdata->color_filter = NULL; + fdata->abs_ts.secs = phdr->ts.secs; +diff --git a/epan/frame_data.h b/epan/frame_data.h +index 580d238..2a73cdf 100644 +--- a/epan/frame_data.h ++++ b/epan/frame_data.h +@@ -69,6 +69,7 @@ typedef struct _frame_data { + unsigned int has_if_id : 1; /**< 1 = has interface ID, 0 = no interface ID */ + unsigned int has_pack_flags : 1; /**< 1 = has packet flags, 0 = no packet flags */ + } flags; ++ gint16 tsprec; /**< Time stamp precision */ + + const void *color_filter; /**< Per-packet matching color_filter_t object */ + +diff --git a/epan/timestamp.c b/epan/timestamp.c +index 155d8bb..65aa41c 100644 +--- a/epan/timestamp.c ++++ b/epan/timestamp.c +@@ -30,7 +30,7 @@ + * and distinguish it from a command line value */ + static ts_type timestamp_type = TS_NOT_SET; + +-static int timestamp_precision = TS_PREC_AUTO_USEC; ++static int timestamp_precision = TS_PREC_AUTO; + + static ts_seconds_type timestamp_seconds_type = TS_SECONDS_NOT_SET; + +diff --git a/epan/timestamp.h b/epan/timestamp.h +index 0992b3e..3881696 100644 +--- a/epan/timestamp.h ++++ b/epan/timestamp.h +@@ -52,19 +52,13 @@ typedef enum { + } ts_type; + + typedef enum { +- TS_PREC_AUTO, /* recent */ +- TS_PREC_FIXED_SEC, /* recent and internal */ +- TS_PREC_FIXED_DSEC, /* recent and internal */ +- TS_PREC_FIXED_CSEC, /* recent and internal */ +- TS_PREC_FIXED_MSEC, /* recent and internal */ +- TS_PREC_FIXED_USEC, /* recent and internal */ +- TS_PREC_FIXED_NSEC, /* recent and internal */ +- TS_PREC_AUTO_SEC, /* internal */ +- TS_PREC_AUTO_DSEC, /* internal */ +- TS_PREC_AUTO_CSEC, /* internal */ +- TS_PREC_AUTO_MSEC, /* internal */ +- TS_PREC_AUTO_USEC, /* internal */ +- TS_PREC_AUTO_NSEC /* internal */ ++ TS_PREC_AUTO, ++ TS_PREC_FIXED_SEC, ++ TS_PREC_FIXED_DSEC, ++ TS_PREC_FIXED_CSEC, ++ TS_PREC_FIXED_MSEC, ++ TS_PREC_FIXED_USEC, ++ TS_PREC_FIXED_NSEC, + } ts_precision; + + typedef enum { +diff --git a/epan/wslua/make-init-lua.pl b/epan/wslua/make-init-lua.pl +index 878faf5..e9f186d 100755 +--- a/epan/wslua/make-init-lua.pl ++++ b/epan/wslua/make-init-lua.pl +@@ -33,6 +33,7 @@ my $WSROOT = shift; + die "'$WSROOT' is not a directory" unless -d $WSROOT; + + my $wtap_encaps_table = ''; ++my $wtap_tsprecs_table = ''; + my $wtap_filetypes_table = ''; + my $ft_types_table = ''; + my $bases_table = ''; +@@ -42,6 +43,7 @@ my $menu_groups = ''; + + my %replacements = %{{ + WTAP_ENCAPS => \$wtap_encaps_table, ++ WTAP_TSPRECS => \$wtap_tsprecs_table, + WTAP_FILETYPES => \$wtap_filetypes_table, + FT_TYPES => \$ft_types_table, + BASES => \$bases_table, +@@ -69,6 +71,7 @@ close TEMPLATE; + # + + $wtap_encaps_table = "-- Wiretap encapsulations XXX\nwtap_encaps = {\n"; ++$wtap_tsprecs_table = "-- Wiretap timestamp precision types\nwtap_tsprecs = {\n"; + $wtap_filetypes_table = "-- Wiretap file types\nwtap_filetypes = {\n"; + + open WTAP_H, "< $WSROOT/wiretap/wtap.h" or die "cannot open '$WSROOT/wiretap/wtap.h': $!"; +@@ -81,10 +84,17 @@ while() { + if ( /^#define WTAP_FILE_([A-Z0-9_]+)\s+(\d+)/ ) { + $wtap_filetypes_table .= "\t[\"$1\"] = $2,\n"; + } ++ ++ if ( /^#define WTAP_TSPREC_([A-Z0-9_]+)\s+(\d+)/ ) { ++ $wtap_tsprecs_table .= "\t[\"$1\"] = $2,\n"; ++ # for backwards compatibility we need to add them to the filetypes table too ++ $wtap_filetypes_table .= "\t[\"TSPREC_$1\"] = $2,\n"; ++ } + } + + $wtap_encaps_table =~ s/,\n$/\n}\nwtap = wtap_encaps -- for bw compatibility\n/msi; + $wtap_filetypes_table =~ s/,\n$/\n}\n/msi; ++$wtap_tsprecs_table =~ s/,\n$/\n}\n/msi; + + # + # Extract values from epan/ftypes/ftypes.h: +diff --git a/epan/wslua/template-init.lua b/epan/wslua/template-init.lua +index 2538c4c..31f298e 100644 +--- a/epan/wslua/template-init.lua ++++ b/epan/wslua/template-init.lua +@@ -66,6 +66,8 @@ end + + -- %WTAP_ENCAPS% + ++-- %WTAP_TSPRECS% ++ + -- %WTAP_FILETYPES% + + -- %FT_TYPES% +diff --git a/file.c b/file.c +index 5059e0b..6db3c68 100644 +--- a/file.c ++++ b/file.c +@@ -222,7 +222,6 @@ void + cf_timestamp_auto_precision(capture_file *cf) + { + int i; +- int prec = timestamp_get_precision(); + + + /* don't try to get the file's precision if none is opened */ +@@ -230,38 +229,6 @@ cf_timestamp_auto_precision(capture_file *cf) + return; + } + +- /* if we are in auto mode, set precision of current file */ +- if (prec == TS_PREC_AUTO || +- prec == TS_PREC_AUTO_SEC || +- prec == TS_PREC_AUTO_DSEC || +- prec == TS_PREC_AUTO_CSEC || +- prec == TS_PREC_AUTO_MSEC || +- prec == TS_PREC_AUTO_USEC || +- prec == TS_PREC_AUTO_NSEC) +- { +- switch(wtap_file_tsprecision(cf->wth)) { +- case(WTAP_FILE_TSPREC_SEC): +- timestamp_set_precision(TS_PREC_AUTO_SEC); +- break; +- case(WTAP_FILE_TSPREC_DSEC): +- timestamp_set_precision(TS_PREC_AUTO_DSEC); +- break; +- case(WTAP_FILE_TSPREC_CSEC): +- timestamp_set_precision(TS_PREC_AUTO_CSEC); +- break; +- case(WTAP_FILE_TSPREC_MSEC): +- timestamp_set_precision(TS_PREC_AUTO_MSEC); +- break; +- case(WTAP_FILE_TSPREC_USEC): +- timestamp_set_precision(TS_PREC_AUTO_USEC); +- break; +- case(WTAP_FILE_TSPREC_NSEC): +- timestamp_set_precision(TS_PREC_AUTO_NSEC); +- break; +- default: +- g_assert_not_reached(); +- } +- } + /* Set the column widths of those columns that show the time in + "command-line-specified" format. */ + for (i = 0; i < cf->cinfo.num_cols; i++) { +diff --git a/rawshark.c b/rawshark.c +index dbb9f42..1d2ff97 100644 +--- a/rawshark.c ++++ b/rawshark.c +@@ -832,35 +832,6 @@ main(int argc, char *argv[]) + } + } + +- /* Set timestamp precision; there should arguably be a command-line +- option to let the user set this. */ +-#if 0 +- switch(wtap_file_tsprecision(cfile.wth)) { +- case(WTAP_FILE_TSPREC_SEC): +- timestamp_set_precision(TS_PREC_AUTO_SEC); +- break; +- case(WTAP_FILE_TSPREC_DSEC): +- timestamp_set_precision(TS_PREC_AUTO_DSEC); +- break; +- case(WTAP_FILE_TSPREC_CSEC): +- timestamp_set_precision(TS_PREC_AUTO_CSEC); +- break; +- case(WTAP_FILE_TSPREC_MSEC): +- timestamp_set_precision(TS_PREC_AUTO_MSEC); +- break; +- case(WTAP_FILE_TSPREC_USEC): +- timestamp_set_precision(TS_PREC_AUTO_USEC); +- break; +- case(WTAP_FILE_TSPREC_NSEC): +- timestamp_set_precision(TS_PREC_AUTO_NSEC); +- break; +- default: +- g_assert_not_reached(); +- } +-#else +- timestamp_set_precision(TS_PREC_AUTO_USEC); +-#endif +- + /* Process the packets in the file */ + err = load_cap_file(&cfile); + +diff --git a/tshark.c b/tshark.c +index 98b95bf..8c8de07 100644 +--- a/tshark.c ++++ b/tshark.c +@@ -1903,31 +1903,6 @@ main(int argc, char *argv[]) + return 2; + } + +- /* Set timestamp precision; there should arguably be a command-line +- option to let the user set this. */ +- switch(wtap_file_tsprecision(cfile.wth)) { +- case(WTAP_FILE_TSPREC_SEC): +- timestamp_set_precision(TS_PREC_AUTO_SEC); +- break; +- case(WTAP_FILE_TSPREC_DSEC): +- timestamp_set_precision(TS_PREC_AUTO_DSEC); +- break; +- case(WTAP_FILE_TSPREC_CSEC): +- timestamp_set_precision(TS_PREC_AUTO_CSEC); +- break; +- case(WTAP_FILE_TSPREC_MSEC): +- timestamp_set_precision(TS_PREC_AUTO_MSEC); +- break; +- case(WTAP_FILE_TSPREC_USEC): +- timestamp_set_precision(TS_PREC_AUTO_USEC); +- break; +- case(WTAP_FILE_TSPREC_NSEC): +- timestamp_set_precision(TS_PREC_AUTO_NSEC); +- break; +- default: +- g_assert_not_reached(); +- } +- + /* Process the packets in the file */ + TRY { + #ifdef HAVE_LIBPCAP +@@ -2030,9 +2005,6 @@ main(int argc, char *argv[]) + } + } + +- /* For now, assume libpcap gives microsecond precision. */ +- timestamp_set_precision(TS_PREC_AUTO_USEC); +- + /* + * XXX - this returns FALSE if an error occurred, but it also + * returns FALSE if the capture stops because a time limit +diff --git a/ui/cli/tap-comparestat.c b/ui/cli/tap-comparestat.c +index 6f55926..d449f32 100644 +--- a/ui/cli/tap-comparestat.c ++++ b/ui/cli/tap-comparestat.c +@@ -545,8 +545,6 @@ comparestat_init(const char *optarg, void* userdata _U_) + cs->zebra_time.secs=0; + cs->zebra_time.nsecs=1; + cs->nr_tree=se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "nr_tree"); +- /* microsecond precision */ +- timestamp_set_precision(TS_PREC_AUTO_NSEC); + + if(filter){ + cs->filter=g_strdup(filter); +diff --git a/ui/gtk/compare_stat.c b/ui/gtk/compare_stat.c +index e07ee96..b8ad2b2 100644 +--- a/ui/gtk/compare_stat.c ++++ b/ui/gtk/compare_stat.c +@@ -584,8 +584,6 @@ comparestat_draw(void *arg) + second_file_amount=cs->second_file_amount; + /* reset after numbering */ + cs->nr_tree=se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "nr_tree"); +- /* microsecond precision for Info column*/ +- timestamp_set_precision(TS_PREC_AUTO_NSEC); + /* reset ordering */ + nstime_set_unset(&cs->current_time); + +@@ -738,8 +736,6 @@ gtk_comparestat_init(const char *opt_arg, void* userdata _U_) + cs->zebra_time.secs=0; + cs->zebra_time.nsecs=1; + cs->nr_tree=se_tree_create(EMEM_TREE_TYPE_RED_BLACK, "nr_tree"); +- /* microsecond precision */ +- timestamp_set_precision(TS_PREC_AUTO_NSEC); + + /* transient_for top_level */ + cs->win=dlg_window_new("compare-stat"); +diff --git a/ui/gtk/main_menubar.c b/ui/gtk/main_menubar.c +index 23ceff2..dd83125 100644 +--- a/ui/gtk/main_menubar.c ++++ b/ui/gtk/main_menubar.c +@@ -635,11 +635,7 @@ timestamp_precision_new_cb (GtkRadioAction *action, GtkRadioAction *current _U_, + value = gtk_radio_action_get_current_value (action); + if (recent.gui_time_precision != value) { + /* the actual precision will be set in packet_list_queue_draw() below */ +- if (value == TS_PREC_AUTO) { +- timestamp_set_precision(TS_PREC_AUTO_SEC); +- } else { +- timestamp_set_precision(value); +- } ++ timestamp_set_precision(value); + recent.gui_time_precision = value; + /* This call adjusts column width */ + cf_timestamp_auto_precision(&cfile); +@@ -1818,7 +1814,7 @@ static const GtkRadioActionEntry main_menu_bar_radio_view_time_entries [] = + static const GtkRadioActionEntry main_menu_bar_radio_view_time_fileformat_prec_entries [] = + { + /* name, stock id, label, accel, tooltip, value */ +- { "/View/TimeDisplayFormat/FileFormatPrecision-Automatic", NULL, "Automatic (File Format Precision)", NULL, NULL, TS_PREC_AUTO }, ++ { "/View/TimeDisplayFormat/FileFormatPrecision-Automatic", NULL, "Automatic (use precision indicated in the file)", NULL, NULL, TS_PREC_AUTO }, + { "/View/TimeDisplayFormat/FileFormatPrecision-Seconds", NULL, "Seconds: 0", NULL, NULL, TS_PREC_FIXED_SEC }, + { "/View/TimeDisplayFormat/FileFormatPrecision-Deciseconds", NULL, "Deciseconds: 0.1", NULL, NULL, TS_PREC_FIXED_DSEC }, + { "/View/TimeDisplayFormat/FileFormatPrecision-Centiseconds", NULL, "Centiseconds: 0.12", NULL, NULL, TS_PREC_FIXED_CSEC }, +@@ -4634,8 +4630,8 @@ menu_recent_read_finished(void) + cf_timestamp_auto_precision(&cfile); + packet_list_queue_draw(); + /* the actual precision will be set in packet_list_queue_draw() below */ +- if (recent.gui_time_precision == TS_PREC_AUTO) { +- timestamp_set_precision(TS_PREC_AUTO_SEC); ++ if (recent.gui_time_precision > TS_PREC_FIXED_NSEC) { ++ timestamp_set_precision(TS_PREC_AUTO); + } else { + timestamp_set_precision(recent.gui_time_precision); + } +diff --git a/ui/qt/main.cpp b/ui/qt/main.cpp +index 12b0e81..3193702 100644 +--- a/ui/qt/main.cpp ++++ b/ui/qt/main.cpp +@@ -856,7 +856,7 @@ int main(int argc, char *argv[]) + + g_log(NULL, G_LOG_LEVEL_DEBUG, "FIX: timestamp types should be set elsewhere"); + timestamp_set_type(TS_RELATIVE); +- timestamp_set_precision(TS_PREC_AUTO_USEC); ++ timestamp_set_precision(TS_PREC_AUTO); + timestamp_set_seconds_type(TS_SECONDS_DEFAULT); + + ///////// +diff --git a/wiretap/5views.c b/wiretap/5views.c +index e8dd0b8..c7a9078 100644 +--- a/wiretap/5views.c ++++ b/wiretap/5views.c +@@ -191,7 +191,7 @@ int _5views_open(wtap *wth, int *err, gchar **err_info) + wth->subtype_seek_read = _5views_seek_read; + wth->file_encap = encap; + wth->snapshot_length = 0; /* not available in header */ +- wth->tsprecision = WTAP_FILE_TSPREC_NSEC; ++ wth->file_tsprec = WTAP_TSPREC_NSEC; + + return 1; + } +diff --git a/wiretap/aethra.c b/wiretap/aethra.c +index d04bf8d..02d1b6c 100644 +--- a/wiretap/aethra.c ++++ b/wiretap/aethra.c +@@ -178,7 +178,7 @@ int aethra_open(wtap *wth, int *err, gchar **err_info) + */ + wth->file_encap = WTAP_ENCAP_ISDN; + wth->snapshot_length = 0; /* not available in header */ +- wth->tsprecision = WTAP_FILE_TSPREC_MSEC; ++ wth->file_tsprec = WTAP_TSPREC_MSEC; + return 1; + } + +diff --git a/wiretap/ascendtext.c b/wiretap/ascendtext.c +index d0b4e76..a05fe34 100644 +--- a/wiretap/ascendtext.c ++++ b/wiretap/ascendtext.c +@@ -229,7 +229,7 @@ int ascend_open(wtap *wth, int *err, gchar **err_info) + } + ascend->inittime = statbuf.st_ctime; + ascend->adjusted = 0; +- wth->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wth->file_tsprec = WTAP_TSPREC_USEC; + + init_parse_ascend(); + +diff --git a/wiretap/ber.c b/wiretap/ber.c +index 990db1d..6904367 100644 +--- a/wiretap/ber.c ++++ b/wiretap/ber.c +@@ -192,7 +192,7 @@ int ber_open(wtap *wth, int *err, gchar **err_info) + + wth->subtype_read = ber_read; + wth->subtype_seek_read = ber_seek_read; +- wth->tsprecision = WTAP_FILE_TSPREC_SEC; ++ wth->file_tsprec = WTAP_TSPREC_SEC; + + return 1; + } +diff --git a/wiretap/btsnoop.c b/wiretap/btsnoop.c +index 042cc8b..1a2e8ac 100644 +--- a/wiretap/btsnoop.c ++++ b/wiretap/btsnoop.c +@@ -147,7 +147,7 @@ int btsnoop_open(wtap *wth, int *err, gchar **err_info) + wth->subtype_seek_read = btsnoop_seek_read; + wth->file_encap = file_encap; + wth->snapshot_length = 0; /* not available in header */ +- wth->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wth->file_tsprec = WTAP_TSPREC_USEC; + wth->file_type = WTAP_FILE_BTSNOOP; + return 1; + } +@@ -443,7 +443,7 @@ gboolean btsnoop_dump_open_h1(wtap_dumper *wdh, int *err) + switch (wdh->file_type) { + + case WTAP_FILE_BTSNOOP: +- wdh->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wdh->tsprecision = WTAP_TSPREC_USEC; + break; + + default: +@@ -485,7 +485,7 @@ gboolean btsnoop_dump_open_h4(wtap_dumper *wdh, int *err) + switch (wdh->file_type) { + + case WTAP_FILE_BTSNOOP: +- wdh->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wdh->tsprecision = WTAP_TSPREC_USEC; + break; + + default: +diff --git a/wiretap/camins.c b/wiretap/camins.c +index 879b68d..3c7a608 100644 +--- a/wiretap/camins.c ++++ b/wiretap/camins.c +@@ -372,7 +372,7 @@ int camins_open(wtap *wth, int *err, gchar **err_info _U_) + + wth->file_encap = WTAP_ENCAP_DVBCI; + wth->snapshot_length = 0; +- wth->tsprecision = WTAP_FILE_TSPREC_MSEC; ++ wth->file_tsprec = WTAP_TSPREC_MSEC; + + wth->priv = NULL; + +diff --git a/wiretap/catapult_dct2000.c b/wiretap/catapult_dct2000.c +index a17ab0d..b389d2a 100644 +--- a/wiretap/catapult_dct2000.c ++++ b/wiretap/catapult_dct2000.c +@@ -262,7 +262,7 @@ catapult_dct2000_open(wtap *wth, int *err, gchar **err_info) + wth->subtype_close = catapult_dct2000_close; + + /* Choose microseconds (have 4 decimal places...) */ +- wth->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wth->file_tsprec = WTAP_TSPREC_USEC; + + + /***************************************************************/ +diff --git a/wiretap/commview.c b/wiretap/commview.c +index 935d15f..f85b1c8 100644 +--- a/wiretap/commview.c ++++ b/wiretap/commview.c +@@ -126,7 +126,7 @@ int commview_open(wtap *wth, int *err, gchar **err_info) + + wth->file_type = WTAP_FILE_COMMVIEW; + wth->file_encap = WTAP_ENCAP_PER_PACKET; +- wth->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wth->file_tsprec = WTAP_TSPREC_USEC; + + return 1; /* Our kind of file */ + } +diff --git a/wiretap/cosine.c b/wiretap/cosine.c +index d6db197..76892b2 100644 +--- a/wiretap/cosine.c ++++ b/wiretap/cosine.c +@@ -282,7 +282,7 @@ int cosine_open(wtap *wth, int *err, gchar **err_info) + wth->snapshot_length = 0; /* not known */ + wth->subtype_read = cosine_read; + wth->subtype_seek_read = cosine_seek_read; +- wth->tsprecision = WTAP_FILE_TSPREC_CSEC; ++ wth->file_tsprec = WTAP_TSPREC_CSEC; + + return 1; + } +diff --git a/wiretap/csids.c b/wiretap/csids.c +index a60fd11..30702b4 100644 +--- a/wiretap/csids.c ++++ b/wiretap/csids.c +@@ -139,7 +139,7 @@ int csids_open(wtap *wth, int *err, gchar **err_info) + wth->snapshot_length = 0; /* not known */ + wth->subtype_read = csids_read; + wth->subtype_seek_read = csids_seek_read; +- wth->tsprecision = WTAP_FILE_TSPREC_SEC; ++ wth->file_tsprec = WTAP_TSPREC_SEC; + + return 1; + } +diff --git a/wiretap/daintree-sna.c b/wiretap/daintree-sna.c +index a9edc71..4c79217 100644 +--- a/wiretap/daintree-sna.c ++++ b/wiretap/daintree-sna.c +@@ -125,7 +125,7 @@ int daintree_sna_open(wtap *wth, int *err, gchar **err_info) + /* set up for file type */ + wth->file_type = WTAP_FILE_DAINTREE_SNA; + wth->file_encap = WTAP_ENCAP_IEEE802_15_4_NOFCS; +- wth->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wth->file_tsprec = WTAP_TSPREC_USEC; + wth->snapshot_length = 0; /* not available in header */ + + return 1; /* it's a Daintree file */ +diff --git a/wiretap/dbs-etherwatch.c b/wiretap/dbs-etherwatch.c +index 11ab38a..cc3d0c3 100644 +--- a/wiretap/dbs-etherwatch.c ++++ b/wiretap/dbs-etherwatch.c +@@ -192,7 +192,7 @@ int dbs_etherwatch_open(wtap *wth, int *err, gchar **err_info) + wth->snapshot_length = 0; /* not known */ + wth->subtype_read = dbs_etherwatch_read; + wth->subtype_seek_read = dbs_etherwatch_seek_read; +- wth->tsprecision = WTAP_FILE_TSPREC_CSEC; ++ wth->file_tsprec = WTAP_TSPREC_CSEC; + + return 1; + } +diff --git a/wiretap/dct3trace.c b/wiretap/dct3trace.c +index e2285ec..94e1012 100644 +--- a/wiretap/dct3trace.c ++++ b/wiretap/dct3trace.c +@@ -181,7 +181,7 @@ int dct3trace_open(wtap *wth, int *err, gchar **err_info) + wth->snapshot_length = 0; /* not known */ + wth->subtype_read = dct3trace_read; + wth->subtype_seek_read = dct3trace_seek_read; +- wth->tsprecision = WTAP_FILE_TSPREC_SEC; ++ wth->file_tsprec = WTAP_TSPREC_SEC; + + return 1; + } +diff --git a/wiretap/erf.c b/wiretap/erf.c +index 6fe4847..d762745 100644 +--- a/wiretap/erf.c ++++ b/wiretap/erf.c +@@ -274,7 +274,7 @@ extern int erf_open(wtap *wth, int *err, gchar **err_info) + + wth->subtype_read = erf_read; + wth->subtype_seek_read = erf_seek_read; +- wth->tsprecision = WTAP_FILE_TSPREC_NSEC; ++ wth->file_tsprec = WTAP_TSPREC_NSEC; + + erf_populate_interfaces(wth); + +@@ -698,7 +698,7 @@ int erf_dump_open(wtap_dumper *wdh, int *err) + + switch(wdh->file_type){ + case WTAP_FILE_ERF: +- wdh->tsprecision = WTAP_FILE_TSPREC_NSEC; ++ wdh->tsprecision = WTAP_TSPREC_NSEC; + break; + default: + *err = WTAP_ERR_UNSUPPORTED_FILE_TYPE; +diff --git a/wiretap/eyesdn.c b/wiretap/eyesdn.c +index c32f5b8..5ff55df 100644 +--- a/wiretap/eyesdn.c ++++ b/wiretap/eyesdn.c +@@ -148,7 +148,7 @@ int eyesdn_open(wtap *wth, int *err, gchar **err_info) + wth->snapshot_length = 0; /* not known */ + wth->subtype_read = eyesdn_read; + wth->subtype_seek_read = eyesdn_seek_read; +- wth->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wth->file_tsprec = WTAP_TSPREC_USEC; + + return 1; + } +diff --git a/wiretap/file_access.c b/wiretap/file_access.c +index cbea1af..640b867 100644 +--- a/wiretap/file_access.c ++++ b/wiretap/file_access.c +@@ -357,7 +357,7 @@ wtap* wtap_open_offline(const char *filename, int *err, char **err_info, + wth->file_encap = WTAP_ENCAP_UNKNOWN; + wth->subtype_sequential_close = NULL; + wth->subtype_close = NULL; +- wth->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wth->file_tsprec = WTAP_TSPREC_USEC; + wth->priv = NULL; + + init_open_routines(); +diff --git a/wiretap/hcidump.c b/wiretap/hcidump.c +index 50c37c1..f7b839f 100644 +--- a/wiretap/hcidump.c ++++ b/wiretap/hcidump.c +@@ -157,7 +157,7 @@ int hcidump_open(wtap *wth, int *err, gchar **err_info) + + wth->subtype_read = hcidump_read; + wth->subtype_seek_read = hcidump_seek_read; +- wth->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wth->file_tsprec = WTAP_TSPREC_USEC; + + return 1; + } +diff --git a/wiretap/i4btrace.c b/wiretap/i4btrace.c +index 5cabbfe..e0e4f4a 100644 +--- a/wiretap/i4btrace.c ++++ b/wiretap/i4btrace.c +@@ -112,7 +112,7 @@ int i4btrace_open(wtap *wth, int *err, gchar **err_info) + i4btrace->byte_swapped = byte_swapped; + + wth->file_encap = WTAP_ENCAP_ISDN; +- wth->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wth->file_tsprec = WTAP_TSPREC_USEC; + + return 1; + } +diff --git a/wiretap/ipfix.c b/wiretap/ipfix.c +index 9a65680..97d4529 100644 +--- a/wiretap/ipfix.c ++++ b/wiretap/ipfix.c +@@ -239,7 +239,7 @@ ipfix_open(wtap *wth, int *err, gchar **err_info) + /* all's good, this is a IPFIX file */ + wth->file_encap = WTAP_ENCAP_RAW_IPFIX; + wth->snapshot_length = 0; +- wth->tsprecision = WTAP_FILE_TSPREC_SEC; ++ wth->file_tsprec = WTAP_TSPREC_SEC; + wth->subtype_read = ipfix_read; + wth->subtype_seek_read = ipfix_seek_read; + wth->subtype_close = ipfix_close; +diff --git a/wiretap/iptrace.c b/wiretap/iptrace.c +index 152e008..aad4b3c 100644 +--- a/wiretap/iptrace.c ++++ b/wiretap/iptrace.c +@@ -72,13 +72,13 @@ int iptrace_open(wtap *wth, int *err, gchar **err_info) + wth->file_type = WTAP_FILE_IPTRACE_1_0; + wth->subtype_read = iptrace_read_1_0; + wth->subtype_seek_read = iptrace_seek_read_1_0; +- wth->tsprecision = WTAP_FILE_TSPREC_SEC; ++ wth->file_tsprec = WTAP_TSPREC_SEC; + } + else if (strcmp(name, "iptrace 2.0") == 0) { + wth->file_type = WTAP_FILE_IPTRACE_2_0; + wth->subtype_read = iptrace_read_2_0; + wth->subtype_seek_read = iptrace_seek_read_2_0; +- wth->tsprecision = WTAP_FILE_TSPREC_NSEC; ++ wth->file_tsprec = WTAP_TSPREC_NSEC; + } + else { + return 0; +diff --git a/wiretap/iseries.c b/wiretap/iseries.c +index e31d5ec..8d5e111 100644 +--- a/wiretap/iseries.c ++++ b/wiretap/iseries.c +@@ -250,7 +250,7 @@ iseries_open (wtap * wth, int *err, gchar ** err_info) + wth->snapshot_length = 0; + wth->subtype_read = iseries_read; + wth->subtype_seek_read = iseries_seek_read; +- wth->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wth->file_tsprec = WTAP_TSPREC_USEC; + + if (file_seek (wth->fh, 0, SEEK_SET, err) == -1) + { +@@ -290,7 +290,7 @@ iseries_open (wtap * wth, int *err, gchar ** err_info) + wth->snapshot_length = 0; + wth->subtype_read = iseries_read; + wth->subtype_seek_read = iseries_seek_read; +- wth->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wth->file_tsprec = WTAP_TSPREC_USEC; + + if (file_seek (wth->fh, 0, SEEK_SET, err) == -1) + { +diff --git a/wiretap/k12.c b/wiretap/k12.c +index 85db119..5923eb9 100644 +--- a/wiretap/k12.c ++++ b/wiretap/k12.c +@@ -832,7 +832,7 @@ int k12_open(wtap *wth, int *err, gchar **err_info) { + wth->subtype_seek_read = k12_seek_read; + wth->subtype_close = k12_close; + wth->priv = (void *)file_data; +- wth->tsprecision = WTAP_FILE_TSPREC_NSEC; ++ wth->file_tsprec = WTAP_TSPREC_NSEC; + + return 1; + } +diff --git a/wiretap/k12text.l b/wiretap/k12text.l +index 817eb92..fdfd3a7 100644 +--- a/wiretap/k12text.l ++++ b/wiretap/k12text.l +@@ -351,7 +351,7 @@ k12text_open(wtap *wth, int *err, gchar **err_info _U_) + wth->snapshot_length = 0; + wth->subtype_read = k12text_read; + wth->subtype_seek_read = k12text_seek_read; +- wth->tsprecision = WTAP_FILE_TSPREC_NSEC; ++ wth->file_tsprec = WTAP_TSPREC_NSEC; + + return 1; + } +diff --git a/wiretap/lanalyzer.c b/wiretap/lanalyzer.c +index eb83872..35dad96 100644 +--- a/wiretap/lanalyzer.c ++++ b/wiretap/lanalyzer.c +@@ -348,7 +348,7 @@ int lanalyzer_open(wtap *wth, int *err, gchar **err_info) + wth->subtype_read = lanalyzer_read; + wth->subtype_seek_read = lanalyzer_seek_read; + wth->snapshot_length = 0; +- wth->tsprecision = WTAP_FILE_TSPREC_NSEC; ++ wth->file_tsprec = WTAP_TSPREC_NSEC; + + /* Read records until we find the start of packets */ + while (1) { +diff --git a/wiretap/libpcap.c b/wiretap/libpcap.c +index 47dafc7..5477073 100644 +--- a/wiretap/libpcap.c ++++ b/wiretap/libpcap.c +@@ -107,7 +107,7 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info) + a program using either standard or ss990417 libpcap. */ + byte_swapped = FALSE; + modified = FALSE; +- wth->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wth->file_tsprec = WTAP_TSPREC_USEC; + break; + + case PCAP_MODIFIED_MAGIC: +@@ -115,7 +115,7 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info) + a program using either ss990915 or ss991029 libpcap. */ + byte_swapped = FALSE; + modified = TRUE; +- wth->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wth->file_tsprec = WTAP_TSPREC_USEC; + break; + + case PCAP_SWAPPED_MAGIC: +@@ -124,7 +124,7 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info) + ss990417 libpcap. */ + byte_swapped = TRUE; + modified = FALSE; +- wth->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wth->file_tsprec = WTAP_TSPREC_USEC; + break; + + case PCAP_SWAPPED_MODIFIED_MAGIC: +@@ -133,7 +133,7 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info) + or ss991029 libpcap. */ + byte_swapped = TRUE; + modified = TRUE; +- wth->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wth->file_tsprec = WTAP_TSPREC_USEC; + break; + + case PCAP_NSEC_MAGIC: +@@ -142,7 +142,7 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info) + except that the time stamps have nanosecond resolution. */ + byte_swapped = FALSE; + modified = FALSE; +- wth->tsprecision = WTAP_FILE_TSPREC_NSEC; ++ wth->file_tsprec = WTAP_TSPREC_NSEC; + break; + + case PCAP_SWAPPED_NSEC_MAGIC: +@@ -152,7 +152,7 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info) + nanosecond resolution. */ + byte_swapped = TRUE; + modified = FALSE; +- wth->tsprecision = WTAP_FILE_TSPREC_NSEC; ++ wth->file_tsprec = WTAP_TSPREC_NSEC; + break; + + default: +@@ -311,7 +311,7 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info) + * precision to nanosecond precision. + */ + wth->file_type = WTAP_FILE_PCAP_AIX; +- wth->tsprecision = WTAP_FILE_TSPREC_NSEC; ++ wth->file_tsprec = WTAP_TSPREC_NSEC; + return 1; + } + +@@ -400,7 +400,7 @@ int libpcap_open(wtap *wth, int *err, gchar **err_info) + * + * Try the standard format first. + */ +- if(wth->tsprecision == WTAP_FILE_TSPREC_NSEC) { ++ if(wth->file_tsprec == WTAP_TSPREC_NSEC) { + wth->file_type = WTAP_FILE_PCAP_NSEC; + } else { + wth->file_type = WTAP_FILE_PCAP; +@@ -662,7 +662,7 @@ static gboolean libpcap_read(wtap *wth, int *err, gchar **err_info, + /* Update the Timestamp, if not already done */ + if (wth->file_encap != WTAP_ENCAP_ERF) { + wth->phdr.ts.secs = hdr.hdr.ts_sec; +- if(wth->tsprecision == WTAP_FILE_TSPREC_NSEC) { ++ if(wth->file_tsprec == WTAP_TSPREC_NSEC) { + wth->phdr.ts.nsecs = hdr.hdr.ts_usec; + } else { + wth->phdr.ts.nsecs = hdr.hdr.ts_usec * 1000; +@@ -901,18 +901,18 @@ gboolean libpcap_dump_open(wtap_dumper *wdh, int *err) + case WTAP_FILE_PCAP_SS990417: /* modified, but with the old magic, sigh */ + case WTAP_FILE_PCAP_NOKIA: /* Nokia libpcap of some sort */ + magic = PCAP_MAGIC; +- wdh->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wdh->tsprecision = WTAP_TSPREC_USEC; + break; + + case WTAP_FILE_PCAP_SS990915: /* new magic, extra crap */ + case WTAP_FILE_PCAP_SS991029: + magic = PCAP_MODIFIED_MAGIC; +- wdh->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wdh->tsprecision = WTAP_TSPREC_USEC; + break; + + case WTAP_FILE_PCAP_NSEC: /* same as WTAP_FILE_PCAP, but nsec precision */ + magic = PCAP_NSEC_MAGIC; +- wdh->tsprecision = WTAP_FILE_TSPREC_NSEC; ++ wdh->tsprecision = WTAP_TSPREC_NSEC; + break; + + default: +@@ -966,7 +966,7 @@ static gboolean libpcap_dump(wtap_dumper *wdh, + phdrsize = pcap_get_phdr_size(wdh->encap, pseudo_header); + + rec_hdr.hdr.ts_sec = (guint32) phdr->ts.secs; +- if(wdh->tsprecision == WTAP_FILE_TSPREC_NSEC) { ++ if(wdh->tsprecision == WTAP_TSPREC_NSEC) { + rec_hdr.hdr.ts_usec = phdr->ts.nsecs; + } else { + rec_hdr.hdr.ts_usec = phdr->ts.nsecs / 1000; +diff --git a/wiretap/mime_file.c b/wiretap/mime_file.c +index 6c64d0e..d0aae88 100644 +--- a/wiretap/mime_file.c ++++ b/wiretap/mime_file.c +@@ -190,7 +190,7 @@ mime_file_open(wtap *wth, int *err, gchar **err_info) + + wth->file_type = WTAP_FILE_MIME; + wth->file_encap = WTAP_ENCAP_MIME; +- wth->tsprecision = WTAP_FILE_TSPREC_SEC; ++ wth->file_tsprec = WTAP_TSPREC_SEC; + wth->subtype_read = mime_read; + wth->subtype_seek_read = mime_seek_read; + wth->snapshot_length = 0; +diff --git a/wiretap/mp2t.c b/wiretap/mp2t.c +index 8496437..de057ba 100644 +--- a/wiretap/mp2t.c ++++ b/wiretap/mp2t.c +@@ -220,7 +220,7 @@ mp2t_open(wtap *wth, int *err, gchar **err_info) + + wth->file_type = WTAP_FILE_MPEG_2_TS; + wth->file_encap = WTAP_ENCAP_MPEG_2_TS; +- wth->tsprecision = WTAP_FILE_TSPREC_NSEC; ++ wth->file_tsprec = WTAP_TSPREC_NSEC; + wth->subtype_read = mp2t_read; + wth->subtype_seek_read = mp2t_seek_read; + wth->snapshot_length = 0; +diff --git a/wiretap/mpeg.c b/wiretap/mpeg.c +index 5c6710f..4545ffb 100644 +--- a/wiretap/mpeg.c ++++ b/wiretap/mpeg.c +@@ -299,7 +299,7 @@ good_magic: + + wth->file_type = WTAP_FILE_MPEG; + wth->file_encap = WTAP_ENCAP_MPEG; +- wth->tsprecision = WTAP_FILE_TSPREC_NSEC; ++ wth->file_tsprec = WTAP_TSPREC_NSEC; + wth->subtype_read = mpeg_read; + wth->subtype_seek_read = mpeg_seek_read; + wth->snapshot_length = 0; +diff --git a/wiretap/netmon.c b/wiretap/netmon.c +index e53bdfc..3b3ed46 100644 +--- a/wiretap/netmon.c ++++ b/wiretap/netmon.c +@@ -402,7 +402,7 @@ int netmon_open(wtap *wth, int *err, gchar **err_info) + * Version 1.x of the file format supports + * millisecond precision. + */ +- wth->tsprecision = WTAP_FILE_TSPREC_MSEC; ++ wth->file_tsprec = WTAP_TSPREC_MSEC; + break; + + case 2: +@@ -412,7 +412,7 @@ int netmon_open(wtap *wth, int *err, gchar **err_info) + * currently support that, so say + * "nanosecond precision" for now. + */ +- wth->tsprecision = WTAP_FILE_TSPREC_NSEC; ++ wth->file_tsprec = WTAP_TSPREC_NSEC; + break; + } + return 1; +diff --git a/wiretap/netscaler.c b/wiretap/netscaler.c +index ba1126c..617b17b 100644 +--- a/wiretap/netscaler.c ++++ b/wiretap/netscaler.c +@@ -651,7 +651,7 @@ int nstrace_open(wtap *wth, int *err, gchar **err_info) + nstrace->nstrace_buf_offset = 0; + } + +- wth->tsprecision = WTAP_FILE_TSPREC_NSEC; ++ wth->file_tsprec = WTAP_TSPREC_NSEC; + wth->phdr.ts.secs = nstrace->nspm_curtime; + wth->phdr.ts.nsecs = 0; + +diff --git a/wiretap/netscreen.c b/wiretap/netscreen.c +index ad218af..a029dd6 100644 +--- a/wiretap/netscreen.c ++++ b/wiretap/netscreen.c +@@ -184,7 +184,7 @@ int netscreen_open(wtap *wth, int *err, gchar **err_info) + wth->snapshot_length = 0; /* not known */ + wth->subtype_read = netscreen_read; + wth->subtype_seek_read = netscreen_seek_read; +- wth->tsprecision = WTAP_FILE_TSPREC_DSEC; ++ wth->file_tsprec = WTAP_TSPREC_DSEC; + + return 1; + } +diff --git a/wiretap/nettl.c b/wiretap/nettl.c +index 757ddaa..d881eeb 100644 +--- a/wiretap/nettl.c ++++ b/wiretap/nettl.c +@@ -287,7 +287,7 @@ int nettl_open(wtap *wth, int *err, gchar **err_info) + if (file_seek(wth->fh, FILE_HDR_SIZE, SEEK_SET, err) == -1) { + return -1; + } +- wth->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wth->file_tsprec = WTAP_TSPREC_USEC; + + return 1; + } +diff --git a/wiretap/network_instruments.c b/wiretap/network_instruments.c +index 3640d28..9ba7100 100644 +--- a/wiretap/network_instruments.c ++++ b/wiretap/network_instruments.c +@@ -247,7 +247,7 @@ int network_instruments_open(wtap *wth, int *err, gchar **err_info) + wth->subtype_close = NULL; + wth->subtype_sequential_close = NULL; + wth->snapshot_length = 0; /* not available in header */ +- wth->tsprecision = WTAP_FILE_TSPREC_NSEC; ++ wth->file_tsprec = WTAP_TSPREC_NSEC; + wth->file_type = WTAP_FILE_NETWORK_INSTRUMENTS; + + /* reset the pointer to the first packet */ +diff --git a/wiretap/netxray.c b/wiretap/netxray.c +index c2af737..d4d2710 100644 +--- a/wiretap/netxray.c ++++ b/wiretap/netxray.c +@@ -495,12 +495,12 @@ int netxray_open(wtap *wth, int *err, gchar **err_info) + + case WTAP_FILE_NETXRAY_OLD: + ticks_per_sec = 1000.0; +- wth->tsprecision = WTAP_FILE_TSPREC_MSEC; ++ wth->file_tsprec = WTAP_TSPREC_MSEC; + break; + + case WTAP_FILE_NETXRAY_1_0: + ticks_per_sec = 1000.0; +- wth->tsprecision = WTAP_FILE_TSPREC_MSEC; ++ wth->file_tsprec = WTAP_TSPREC_MSEC; + break; + + case WTAP_FILE_NETXRAY_1_1: +@@ -511,7 +511,7 @@ int netxray_open(wtap *wth, int *err, gchar **err_info) + * and older versions of Windows Sniffer. + */ + ticks_per_sec = 1000000.0; +- wth->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wth->file_tsprec = WTAP_TSPREC_USEC; + break; + + case WTAP_FILE_NETXRAY_2_00x: +@@ -668,9 +668,9 @@ int netxray_open(wtap *wth, int *err, gchar **err_info) + * XXX - Seems reasonable to use nanosecs only if TPS >= 10M + */ + if (ticks_per_sec >= 1e7) +- wth->tsprecision = WTAP_FILE_TSPREC_NSEC; ++ wth->file_tsprec = WTAP_TSPREC_NSEC; + else +- wth->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wth->file_tsprec = WTAP_TSPREC_USEC; + break; + + default: +diff --git a/wiretap/ngsniffer.c b/wiretap/ngsniffer.c +index f15694f..4ada82d 100644 +--- a/wiretap/ngsniffer.c ++++ b/wiretap/ngsniffer.c +@@ -799,7 +799,7 @@ ngsniffer_open(wtap *wth, int *err, gchar **err_info) + * isn't stored in the capture file. + */ + +- wth->tsprecision = WTAP_FILE_TSPREC_NSEC; /* XXX */ ++ wth->file_tsprec = WTAP_TSPREC_NSEC; /* XXX */ + + return 1; + } +diff --git a/wiretap/packetlogger.c b/wiretap/packetlogger.c +index eece1a0..fcaedc9 100644 +--- a/wiretap/packetlogger.c ++++ b/wiretap/packetlogger.c +@@ -118,7 +118,7 @@ int packetlogger_open(wtap *wth, int *err, gchar **err_info) + + wth->file_type = WTAP_FILE_PACKETLOGGER; + wth->file_encap = WTAP_ENCAP_PACKETLOGGER; +- wth->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wth->file_tsprec = WTAP_TSPREC_USEC; + + return 1; /* Our kind of file */ + } +diff --git a/wiretap/pcapng.c b/wiretap/pcapng.c +index f652057..338be96 100644 +--- a/wiretap/pcapng.c ++++ b/wiretap/pcapng.c +@@ -371,7 +371,6 @@ typedef struct wtapng_block_s { + const union wtap_pseudo_header *pseudo_header; + struct wtap_pkthdr *packet_header; + const guint8 *frame_buffer; +- int *file_encap; + } wtapng_block_t; + + /* Interface data in private struct */ +@@ -379,6 +378,7 @@ typedef struct interface_data_s { + int wtap_encap; + guint32 snap_len; + guint64 time_units_per_second; ++ int tsprecision; + } interface_data_t; + + typedef struct { +@@ -643,10 +643,12 @@ pcapng_read_section_header_block(FILE_T fh, gboolean first_block, + + /* "Interface Description Block" */ + static int +-pcapng_read_if_descr_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, +- wtapng_block_t *wblock, int *err, gchar **err_info) ++pcapng_read_if_descr_block(wtap *wth, FILE_T fh, pcapng_block_header_t *bh, ++ pcapng_t *pn, wtapng_block_t *wblock, int *err, ++ gchar **err_info) + { +- guint64 time_units_per_second = 1000000; /* default */ ++ guint64 time_units_per_second = 1000000; /* default = 10^6 */ ++ int tsprecision = WTAP_TSPREC_USEC; + int bytes_read; + int block_read; + int to_read, opt_cont_buf_len; +@@ -690,6 +692,7 @@ pcapng_read_if_descr_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, + + wblock->data.if_descr.wtap_encap = wtap_pcap_encap_to_wtap_encap(wblock->data.if_descr.link_type); + wblock->data.if_descr.time_units_per_second = time_units_per_second; ++ wblock->data.if_descr.tsprecision = tsprecision; + + pcapng_debug3("pcapng_read_if_descr_block: IDB link_type %u (%s), snap %u", + wblock->data.if_descr.link_type, +@@ -821,7 +824,20 @@ pcapng_read_if_descr_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, + } + wblock->data.if_descr.time_units_per_second = time_units_per_second; + wblock->data.if_descr.if_tsresol = if_tsresol; +- pcapng_debug2("pcapng_read_if_descr_block: if_tsresol %u, units/s %" G_GINT64_MODIFIER "u", wblock->data.if_descr.if_tsresol, wblock->data.if_descr.time_units_per_second); ++ if (time_units_per_second >= 1000000000) ++ tsprecision = WTAP_TSPREC_NSEC; ++ else if (time_units_per_second >= 1000000) ++ tsprecision = WTAP_TSPREC_USEC; ++ else if (time_units_per_second >= 1000) ++ tsprecision = WTAP_TSPREC_MSEC; ++ else if (time_units_per_second >= 100) ++ tsprecision = WTAP_TSPREC_CSEC; ++ else if (time_units_per_second >= 10) ++ tsprecision = WTAP_TSPREC_DSEC; ++ else ++ tsprecision = WTAP_TSPREC_SEC; ++ wblock->data.if_descr.tsprecision = tsprecision; ++ pcapng_debug3("pcapng_read_if_descr_block: if_tsresol %u, units/s %" G_GINT64_MODIFIER "u, tsprecision %d", wblock->data.if_descr.if_tsresol, wblock->data.if_descr.time_units_per_second, tsprecision); + } else { + pcapng_debug1("pcapng_read_if_descr_block: if_tsresol length %u not 1 as expected", oh.option_length); + } +@@ -883,12 +899,33 @@ pcapng_read_if_descr_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, + + g_free(option_content); + +- if (*wblock->file_encap == WTAP_ENCAP_UNKNOWN) { +- *wblock->file_encap = wblock->data.if_descr.wtap_encap; ++ /* ++ * If the per-file encapsulation isn't known, set it to this ++ * interface's encapsulation. ++ * ++ * If it *is* known, and it isn't this interface's encapsulation, ++ * set it to WTAP_ENCAP_PER_PACKET, as this file doesn't ++ * have a single encapsulation for all interfaces in the file, ++ * so it probably doesn't have a single encapsulation for all ++ * packets in the file. ++ */ ++ if (wth->file_encap == WTAP_ENCAP_UNKNOWN) { ++ wth->file_encap = wblock->data.if_descr.wtap_encap; + } else { +- if (*wblock->file_encap != wblock->data.if_descr.wtap_encap) { +- *wblock->file_encap = WTAP_ENCAP_PER_PACKET; +- } ++ if (wth->file_encap != wblock->data.if_descr.wtap_encap) { ++ wth->file_encap = WTAP_ENCAP_PER_PACKET; ++ } ++ } ++ ++ /* ++ * The same applies to the per-file time stamp resolution. ++ */ ++ if (wth->file_tsprec == WTAP_TSPREC_UNKNOWN) { ++ wth->file_tsprec = wblock->data.if_descr.tsprecision; ++ } else { ++ if (wth->file_tsprec != wblock->data.if_descr.tsprecision) { ++ wth->file_tsprec = WTAP_TSPREC_PER_PACKET; ++ } + } + + return block_read; +@@ -1065,6 +1102,7 @@ pcapng_read_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn, wta + pcap_get_phdr_size(int_data.wtap_encap, wblock->pseudo_header)); + wblock->packet_header->interface_id = wblock->data.packet.interface_id; + wblock->packet_header->pkt_encap = int_data.wtap_encap; ++ wblock->packet_header->pkt_tsprec = int_data.tsprecision; + + memset((void *)wblock->pseudo_header, 0, sizeof(union wtap_pseudo_header)); + pseudo_header_len = pcap_process_pseudo_header(fh, +@@ -1328,6 +1366,7 @@ pcapng_read_simple_packet_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t * + wblock->packet_header->presence_flags = WTAP_HAS_CAP_LEN|WTAP_HAS_INTERFACE_ID; + wblock->packet_header->interface_id = 0; + wblock->packet_header->pkt_encap = int_data.wtap_encap; ++ wblock->packet_header->pkt_tsprec = int_data.tsprecision; + wblock->packet_header->ts.secs = 0; + wblock->packet_header->ts.nsecs = 0; + wblock->packet_header->interface_id = 0; +@@ -1905,7 +1944,7 @@ pcapng_read_unknown_block(FILE_T fh, pcapng_block_header_t *bh, pcapng_t *pn _U_ + + + static int +-pcapng_read_block(FILE_T fh, gboolean first_block, pcapng_t *pn, wtapng_block_t *wblock, int *err, gchar **err_info) ++pcapng_read_block(wtap *wth, FILE_T fh, gboolean first_block, pcapng_t *pn, wtapng_block_t *wblock, int *err, gchar **err_info) + { + int block_read; + int bytes_read; +@@ -1953,7 +1992,7 @@ pcapng_read_block(FILE_T fh, gboolean first_block, pcapng_t *pn, wtapng_block_t + bytes_read = pcapng_read_section_header_block(fh, first_block, &bh, pn, wblock, err, err_info); + break; + case(BLOCK_TYPE_IDB): +- bytes_read = pcapng_read_if_descr_block(fh, &bh, pn, wblock, err, err_info); ++ bytes_read = pcapng_read_if_descr_block(wth, fh, &bh, pn, wblock, err, err_info); + break; + case(BLOCK_TYPE_PB): + bytes_read = pcapng_read_packet_block(fh, &bh, pn, wblock, err, err_info, FALSE); +@@ -2043,6 +2082,7 @@ pcapng_process_idb(wtap *wth, pcapng_t *pcapng, wtapng_block_t *wblock) + interface_data.wtap_encap = wblock->data.if_descr.wtap_encap; + interface_data.snap_len = wblock->data.if_descr.snap_len; + interface_data.time_units_per_second = wblock->data.if_descr.time_units_per_second; ++ interface_data.tsprecision = wblock->data.if_descr.tsprecision; + + g_array_append_val(pcapng->interface_data, interface_data); + pcapng->number_of_interfaces++; +@@ -2072,11 +2112,10 @@ pcapng_open(wtap *wth, int *err, gchar **err_info) + wblock.frame_buffer = NULL; + wblock.pseudo_header = NULL; + wblock.packet_header = NULL; +- wblock.file_encap = &wth->file_encap; + + pcapng_debug0("pcapng_open: opening file"); + /* read first block */ +- bytes_read = pcapng_read_block(wth->fh, TRUE, &pn, &wblock, err, err_info); ++ bytes_read = pcapng_read_block(wth, wth->fh, TRUE, &pn, &wblock, err, err_info); + if (bytes_read <= 0) { + pcapng_debug0("pcapng_open: couldn't read first SHB"); + *err = file_error(wth->fh, err_info); +@@ -2110,7 +2149,7 @@ pcapng_open(wtap *wth, int *err, gchar **err_info) + + wth->file_encap = WTAP_ENCAP_UNKNOWN; + wth->snapshot_length = 0; +- wth->tsprecision = WTAP_FILE_TSPREC_NSEC; ++ wth->file_tsprec = WTAP_TSPREC_NSEC; + pcapng = (pcapng_t *)g_malloc(sizeof(pcapng_t)); + wth->priv = (void *)pcapng; + *pcapng = pn; +@@ -2156,7 +2195,7 @@ pcapng_open(wtap *wth, int *err, gchar **err_info) + if (bh.block_type != BLOCK_TYPE_IDB) { + break; /* No more IDB:s */ + } +- bytes_read = pcapng_read_block(wth->fh, FALSE, &pn, &wblock, err, err_info); ++ bytes_read = pcapng_read_block(wth, wth->fh, FALSE, &pn, &wblock, err, err_info); + if (bytes_read == 0) { + pcapng_debug0("No more IDBs available..."); + break; +@@ -2200,14 +2239,13 @@ pcapng_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) + wblock.frame_buffer = buffer_start_ptr(wth->frame_buffer); + wblock.pseudo_header = &wth->phdr.pseudo_header; + wblock.packet_header = &wth->phdr; +- wblock.file_encap = &wth->file_encap; + + pcapng->add_new_ipv4 = wth->add_new_ipv4; + pcapng->add_new_ipv6 = wth->add_new_ipv6; + + /* read next block */ + while (1) { +- bytes_read = pcapng_read_block(wth->fh, FALSE, pcapng, &wblock, err, err_info); ++ bytes_read = pcapng_read_block(wth, wth->fh, FALSE, pcapng, &wblock, err, err_info); + if (bytes_read <= 0) { + pcapng_debug1("pcapng_read: data_offset is finally %" G_GINT64_MODIFIER "d", *data_offset); + pcapng_debug0("pcapng_read: couldn't read packet block"); +@@ -2219,6 +2257,7 @@ pcapng_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) + case(BLOCK_TYPE_SHB): + /* We don't currently support multi-section files. */ + wth->phdr.pkt_encap = WTAP_ENCAP_UNKNOWN; ++ wth->phdr.pkt_tsprec = WTAP_TSPREC_UNKNOWN; + *err = WTAP_ERR_UNSUPPORTED; + *err_info = g_strdup_printf("pcapng: multi-section files not currently supported."); + return FALSE; +@@ -2332,10 +2371,9 @@ pcapng_seek_read(wtap *wth, gint64 seek_off, + wblock.frame_buffer = pd; + wblock.pseudo_header = pseudo_header; + wblock.packet_header = &wth->phdr; +- wblock.file_encap = &wth->file_encap; + + /* read the block */ +- bytes_read = pcapng_read_block(wth->random_fh, FALSE, pcapng, &wblock, err, err_info); ++ bytes_read = pcapng_read_block(wth, wth->random_fh, FALSE, pcapng, &wblock, err, err_info); + if (bytes_read <= 0) { + *err = file_error(wth->random_fh, err_info); + pcapng_debug3("pcapng_seek_read: couldn't read packet block (err=%d, errno=%d, bytes_read=%d).", +diff --git a/wiretap/peekclassic.c b/wiretap/peekclassic.c +index e8b890e..8437d34 100644 +--- a/wiretap/peekclassic.c ++++ b/wiretap/peekclassic.c +@@ -354,7 +354,7 @@ peekclassic_open(wtap *wth, int *err, gchar **err_info) + } + + wth->snapshot_length = 0; /* not available in header */ +- wth->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wth->file_tsprec = WTAP_TSPREC_USEC; + + return 1; + } +diff --git a/wiretap/peektagged.c b/wiretap/peektagged.c +index 7f178ae..712ea88 100644 +--- a/wiretap/peektagged.c ++++ b/wiretap/peektagged.c +@@ -338,7 +338,7 @@ int peektagged_open(wtap *wth, int *err, gchar **err_info) + wth->file_encap = file_encap; + wth->subtype_read = peektagged_read; + wth->subtype_seek_read = peektagged_seek_read; +- wth->tsprecision = WTAP_FILE_TSPREC_NSEC; ++ wth->file_tsprec = WTAP_TSPREC_NSEC; + + peektagged = (peektagged_t *)g_malloc(sizeof(peektagged_t)); + wth->priv = (void *)peektagged; +diff --git a/wiretap/pppdump.c b/wiretap/pppdump.c +index 239f1a8..e3d4165 100644 +--- a/wiretap/pppdump.c ++++ b/wiretap/pppdump.c +@@ -301,7 +301,7 @@ pppdump_open(wtap *wth, int *err, gchar **err_info) + wth->subtype_read = pppdump_read; + wth->subtype_seek_read = pppdump_seek_read; + wth->subtype_close = pppdump_close; +- wth->tsprecision = WTAP_FILE_TSPREC_DSEC; ++ wth->file_tsprec = WTAP_TSPREC_DSEC; + + state->seek_state = g_new(pppdump_t,1); + +diff --git a/wiretap/radcom.c b/wiretap/radcom.c +index 8e9b701..719d904 100644 +--- a/wiretap/radcom.c ++++ b/wiretap/radcom.c +@@ -167,7 +167,7 @@ int radcom_open(wtap *wth, int *err, gchar **err_info) + wth->subtype_read = radcom_read; + wth->subtype_seek_read = radcom_seek_read; + wth->snapshot_length = 0; /* not available in header, only in frame */ +- wth->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wth->file_tsprec = WTAP_TSPREC_USEC; + + #if 0 + tm.tm_year = pletohs(&start_date.year)-1900; +diff --git a/wiretap/snoop.c b/wiretap/snoop.c +index d2f765b..2da076d 100644 +--- a/wiretap/snoop.c ++++ b/wiretap/snoop.c +@@ -433,7 +433,7 @@ int snoop_open(wtap *wth, int *err, gchar **err_info) + wth->subtype_seek_read = snoop_seek_read; + wth->file_encap = file_encap; + wth->snapshot_length = 0; /* not available in header */ +- wth->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wth->file_tsprec = WTAP_TSPREC_USEC; + return 1; + } + +diff --git a/wiretap/tnef.c b/wiretap/tnef.c +index 3afd1d4..f352c24 100644 +--- a/wiretap/tnef.c ++++ b/wiretap/tnef.c +@@ -128,7 +128,7 @@ int tnef_open(wtap *wth, int *err, gchar **err_info) + + wth->subtype_read = tnef_read; + wth->subtype_seek_read = tnef_seek_read; +- wth->tsprecision = WTAP_FILE_TSPREC_SEC; ++ wth->file_tsprec = WTAP_TSPREC_SEC; + + return 1; + } +diff --git a/wiretap/toshiba.c b/wiretap/toshiba.c +index 07f00eb..f88474d 100644 +--- a/wiretap/toshiba.c ++++ b/wiretap/toshiba.c +@@ -213,7 +213,7 @@ int toshiba_open(wtap *wth, int *err, gchar **err_info) + wth->snapshot_length = 0; /* not known */ + wth->subtype_read = toshiba_read; + wth->subtype_seek_read = toshiba_seek_read; +- wth->tsprecision = WTAP_FILE_TSPREC_CSEC; ++ wth->file_tsprec = WTAP_TSPREC_CSEC; + + return 1; + } +diff --git a/wiretap/visual.c b/wiretap/visual.c +index 59400ba..a0f9852 100644 +--- a/wiretap/visual.c ++++ b/wiretap/visual.c +@@ -267,7 +267,7 @@ int visual_open(wtap *wth, int *err, gchar **err_info) + /* Set up the pointers to the handlers for this file type */ + wth->subtype_read = visual_read; + wth->subtype_seek_read = visual_seek_read; +- wth->tsprecision = WTAP_FILE_TSPREC_MSEC; ++ wth->file_tsprec = WTAP_TSPREC_MSEC; + + /* Add Visual-specific information to the wiretap struct for later use. */ + visual = (struct visual_read_info *)g_malloc(sizeof(struct visual_read_info)); +diff --git a/wiretap/vms.c b/wiretap/vms.c +index f5c440b..550a5ac 100644 +--- a/wiretap/vms.c ++++ b/wiretap/vms.c +@@ -253,7 +253,7 @@ int vms_open(wtap *wth, int *err, gchar **err_info) + wth->snapshot_length = 0; /* not known */ + wth->subtype_read = vms_read; + wth->subtype_seek_read = vms_seek_read; +- wth->tsprecision = WTAP_FILE_TSPREC_CSEC; ++ wth->file_tsprec = WTAP_TSPREC_CSEC; + + return 1; + } +diff --git a/wiretap/vwr.c b/wiretap/vwr.c +index 0f1dbc3..881ad64 100644 +--- a/wiretap/vwr.c ++++ b/wiretap/vwr.c +@@ -653,7 +653,7 @@ int vwr_open(wtap *wth, int *err, gchar **err_info) + wth->snapshot_length = 0; + wth->subtype_read = vwr_read; + wth->subtype_seek_read = vwr_seek_read; +- wth->tsprecision = WTAP_FILE_TSPREC_USEC; ++ wth->file_tsprec = WTAP_TSPREC_USEC; + + if (fpgaVer == vVW510021_W_FPGA) { + wth->file_type = WTAP_FILE_VWR_80211; +diff --git a/wiretap/wtap-int.h b/wiretap/wtap-int.h +index 1c17a42..15d5102 100644 +--- a/wiretap/wtap-int.h ++++ b/wiretap/wtap-int.h +@@ -69,11 +69,19 @@ struct wtap { + int file_encap; /* per-file, for those + * file formats that have + * per-file encapsulation +- * types +- */ +- int tsprecision; /* timestamp precision of the lower 32bits +- * e.g. WTAP_FILE_TSPREC_USEC ++ * types rather than per-packet ++ * encapsulation types + */ ++ int file_tsprec; /* per-file timestamp precision ++ * of the fractional part of ++ * the time stamp, for those ++ * file formats that have ++ * per-file timestamp ++ * precision rather than ++ * per-packet timestamp ++ * precision ++ * e.g. WTAP_TSPREC_USEC ++ */ + wtap_new_ipv4_callback_t add_new_ipv4; + wtap_new_ipv6_callback_t add_new_ipv6; + GPtrArray *fast_seek; +@@ -105,7 +113,7 @@ struct wtap_dumper { + subtype_close_func subtype_close; + + int tsprecision; /**< timestamp precision of the lower 32bits +- * e.g. WTAP_FILE_TSPREC_USEC ++ * e.g. WTAP_TSPREC_USEC + */ + struct addrinfo *addrinfo_list; + struct wtapng_section_s *shb_hdr; +diff --git a/wiretap/wtap.c b/wiretap/wtap.c +index ee0cbc2..69803d6 100644 +--- a/wiretap/wtap.c ++++ b/wiretap/wtap.c +@@ -95,9 +95,9 @@ wtap_file_encap(wtap *wth) + } + + int +-wtap_file_tsprecision(wtap *wth) ++wtap_file_tsprec(wtap *wth) + { +- return wth->tsprecision; ++ return wth->file_tsprec; + } + + wtapng_section_t * +@@ -862,6 +862,8 @@ wtap_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) + * capture file type doesn't have to set it), and if it + * *is* WTAP_ENCAP_PER_PACKET, the caller needs to set it + * anyway. ++ * ++ * Do the same for the packet time stamp resolution. + */ + wth->phdr.pkt_encap = wth->file_encap; + +diff --git a/wiretap/wtap.h b/wiretap/wtap.h +index 36674e9..b49c280 100644 +--- a/wiretap/wtap.h ++++ b/wiretap/wtap.h +@@ -319,12 +319,14 @@ extern "C" { + #define WTAP_NUM_FILE_TYPES wtap_get_num_file_types() + + /* timestamp precision (currently only these values are supported) */ +-#define WTAP_FILE_TSPREC_SEC 0 +-#define WTAP_FILE_TSPREC_DSEC 1 +-#define WTAP_FILE_TSPREC_CSEC 2 +-#define WTAP_FILE_TSPREC_MSEC 3 +-#define WTAP_FILE_TSPREC_USEC 6 +-#define WTAP_FILE_TSPREC_NSEC 9 ++#define WTAP_TSPREC_UNKNOWN -2 ++#define WTAP_TSPREC_PER_PACKET -1 ++#define WTAP_TSPREC_SEC 0 ++#define WTAP_TSPREC_DSEC 1 ++#define WTAP_TSPREC_CSEC 2 ++#define WTAP_TSPREC_MSEC 3 ++#define WTAP_TSPREC_USEC 6 ++#define WTAP_TSPREC_NSEC 9 + + /* + * Maximum packet size we'll support. +@@ -866,7 +868,8 @@ struct wtap_pkthdr { + struct wtap_nstime ts; + guint32 caplen; /* data length in the file */ + guint32 len; /* data length on the wire */ +- int pkt_encap; ++ int pkt_encap; /* WTAP_ENCAP_ value for this packet */ ++ int pkt_tsprec; /* WTAP_TSPREC_ value for this packet */ + /* pcapng variables */ + guint32 interface_id; /* identifier of the interface. */ + /* options */ +@@ -1010,6 +1013,7 @@ typedef struct wtapng_iface_descriptions_s { + typedef struct wtapng_if_descr_s { + int wtap_encap; /**< link_type translated to wtap_encap */ + guint64 time_units_per_second; ++ int tsprecision; /**< WTAP_TSPREC_ value for this interface */ + + /* mandatory */ + guint16 link_type; +@@ -1214,7 +1218,7 @@ int wtap_file_type(wtap *wth); + WS_DLL_PUBLIC + int wtap_file_encap(wtap *wth); + WS_DLL_PUBLIC +-int wtap_file_tsprecision(wtap *wth); ++int wtap_file_tsprec(wtap *wth); + WS_DLL_PUBLIC + wtapng_section_t* wtap_file_get_shb_info(wtap *wth); + WS_DLL_PUBLIC diff --git a/SOURCES/wireshark-1.10.3-tls-ext-encrypt-then-mac.patch b/SOURCES/wireshark-1.10.3-tls-ext-encrypt-then-mac.patch new file mode 100644 index 0000000..bf3bcd9 --- /dev/null +++ b/SOURCES/wireshark-1.10.3-tls-ext-encrypt-then-mac.patch @@ -0,0 +1,24 @@ +diff --git a/epan/dissectors/packet-ssl-utils.c b/epan/dissectors/packet-ssl-utils.c +index 8f85f11..a58ccfb 100644 +--- a/epan/dissectors/packet-ssl-utils.c ++++ b/epan/dissectors/packet-ssl-utils.c +@@ -1034,6 +1034,7 @@ const value_string tls_hello_extension_types[] = { + { 13, "signature_algorithms" }, /* RFC 5246 */ + { 14, "use_srtp" }, + { SSL_HND_HELLO_EXT_HEARTBEAT, "Heartbeat" }, /* RFC 6520 */ ++ { SSL_HND_HELLO_EXT_ENCRYPT_THEN_MAC_TYPE, "Encrypt then MAC" }, /* RFC 7366 */ + { SSL_HND_HELLO_EXT_EXTENDED_MASTER_SECRET_TYPE, "Extended Master Secret" }, /* https://tools.ietf.org/html/draft-ietf-tls-session-hash-01 */ + { 35, "SessionTicket TLS" }, /* RFC 4507 */ + { SSL_HND_HELLO_EXT_NPN, "next_protocol_negotiation"}, /* http://technotes.googlecode.com/git/nextprotoneg.html */ +diff --git a/epan/dissectors/packet-ssl-utils.h b/epan/dissectors/packet-ssl-utils.h +index 5968b8e..82dc39b 100644 +--- a/epan/dissectors/packet-ssl-utils.h ++++ b/epan/dissectors/packet-ssl-utils.h +@@ -153,6 +153,7 @@ + #define SSL_HND_HELLO_EXT_EC_POINT_FORMATS 0x000b + #define SSL_HND_HELLO_EXT_SIG_HASH_ALGS 0x000d + #define SSL_HND_HELLO_EXT_HEARTBEAT 0x000f ++#define SSL_HND_HELLO_EXT_ENCRYPT_THEN_MAC_TYPE 0x0016 + #define SSL_HND_HELLO_EXT_EXTENDED_MASTER_SECRET_TYPE 0x0017 + #define SSL_HND_HELLO_EXT_RENEG_INFO 0xff01 + #define SSL_HND_HELLO_EXT_NPN 0x3374 diff --git a/SOURCES/wireshark-1.10.3-tls-ext-master-secret.patch b/SOURCES/wireshark-1.10.3-tls-ext-master-secret.patch new file mode 100644 index 0000000..3427382 --- /dev/null +++ b/SOURCES/wireshark-1.10.3-tls-ext-master-secret.patch @@ -0,0 +1,127 @@ +diff --git a/epan/dissectors/packet-ssl-utils.c b/epan/dissectors/packet-ssl-utils.c +index efb170a..8f85f11 100644 +--- a/epan/dissectors/packet-ssl-utils.c ++++ b/epan/dissectors/packet-ssl-utils.c +@@ -1034,6 +1034,7 @@ const value_string tls_hello_extension_types[] = { + { 13, "signature_algorithms" }, /* RFC 5246 */ + { 14, "use_srtp" }, + { SSL_HND_HELLO_EXT_HEARTBEAT, "Heartbeat" }, /* RFC 6520 */ ++ { SSL_HND_HELLO_EXT_EXTENDED_MASTER_SECRET_TYPE, "Extended Master Secret" }, /* https://tools.ietf.org/html/draft-ietf-tls-session-hash-01 */ + { 35, "SessionTicket TLS" }, /* RFC 4507 */ + { SSL_HND_HELLO_EXT_NPN, "next_protocol_negotiation"}, /* http://technotes.googlecode.com/git/nextprotoneg.html */ + { SSL_HND_HELLO_EXT_RENEG_INFO, "renegotiation_info" }, /* RFC 5746 */ +diff --git a/epan/dissectors/packet-ssl-utils.h b/epan/dissectors/packet-ssl-utils.h +index 1ba1598..5968b8e 100644 +--- a/epan/dissectors/packet-ssl-utils.h ++++ b/epan/dissectors/packet-ssl-utils.h +@@ -148,14 +148,15 @@ + #define PCT_ERR_SERVER_AUTH_FAILED 0x05 + #define PCT_ERR_SPECS_MISMATCH 0x06 + +-#define SSL_HND_HELLO_EXT_SERVER_NAME 0x0 +-#define SSL_HND_HELLO_EXT_ELLIPTIC_CURVES 0x000a +-#define SSL_HND_HELLO_EXT_EC_POINT_FORMATS 0x000b +-#define SSL_HND_HELLO_EXT_SIG_HASH_ALGS 0x000d +-#define SSL_HND_HELLO_EXT_HEARTBEAT 0x000f +-#define SSL_HND_HELLO_EXT_RENEG_INFO 0xff01 +-#define SSL_HND_HELLO_EXT_NPN 0x3374 +-#define SSL_HND_CERT_STATUS_TYPE_OCSP 1 ++#define SSL_HND_HELLO_EXT_SERVER_NAME 0x0 ++#define SSL_HND_HELLO_EXT_ELLIPTIC_CURVES 0x000a ++#define SSL_HND_HELLO_EXT_EC_POINT_FORMATS 0x000b ++#define SSL_HND_HELLO_EXT_SIG_HASH_ALGS 0x000d ++#define SSL_HND_HELLO_EXT_HEARTBEAT 0x000f ++#define SSL_HND_HELLO_EXT_EXTENDED_MASTER_SECRET_TYPE 0x0017 ++#define SSL_HND_HELLO_EXT_RENEG_INFO 0xff01 ++#define SSL_HND_HELLO_EXT_NPN 0x3374 ++#define SSL_HND_CERT_STATUS_TYPE_OCSP 1 + + /* + * Lookup tables +@@ -211,13 +212,16 @@ typedef struct _StringInfo { + #define DTLSV1DOT0_VERSION_NOT 0x100 + #define DTLSV1DOT2_VERSION 0xfefd + +-#define SSL_CLIENT_RANDOM (1<<0) +-#define SSL_SERVER_RANDOM (1<<1) +-#define SSL_CIPHER (1<<2) +-#define SSL_HAVE_SESSION_KEY (1<<3) +-#define SSL_VERSION (1<<4) +-#define SSL_MASTER_SECRET (1<<5) +-#define SSL_PRE_MASTER_SECRET (1<<6) ++#define SSL_CLIENT_RANDOM (1<<0) ++#define SSL_SERVER_RANDOM (1<<1) ++#define SSL_CIPHER (1<<2) ++#define SSL_HAVE_SESSION_KEY (1<<3) ++#define SSL_VERSION (1<<4) ++#define SSL_MASTER_SECRET (1<<5) ++#define SSL_PRE_MASTER_SECRET (1<<6) ++#define SSL_CLIENT_EXTENDED_MASTER_SECRET (1<<7) ++#define SSL_SERVER_EXTENDED_MASTER_SECRET (1<<8) ++ + + #define SSL_CIPHER_MODE_STREAM 0 + #define SSL_CIPHER_MODE_CBC 1 +diff --git a/epan/dissectors/packet-ssl.c b/epan/dissectors/packet-ssl.c +index 6f22158..d774929 100644 +--- a/epan/dissectors/packet-ssl.c ++++ b/epan/dissectors/packet-ssl.c +@@ -2396,7 +2396,8 @@ dissect_ssl3_hnd_hello_common(tvbuff_t *tvb, proto_tree *tree, + + static gint + dissect_ssl3_hnd_hello_ext(tvbuff_t *tvb, +- proto_tree *tree, guint32 offset, guint32 left) ++ proto_tree *tree, guint32 offset, guint32 left, ++ gboolean is_client, SslDecryptSession *ssl) + { + guint16 extension_length; + guint16 ext_type; +@@ -2459,6 +2460,10 @@ dissect_ssl3_hnd_hello_ext(tvbuff_t *tvb, + tvb, offset, 1, ENC_BIG_ENDIAN); + offset += ext_len; + break; ++ case SSL_HND_HELLO_EXT_EXTENDED_MASTER_SECRET_TYPE: ++ if (ssl) ++ ssl->state |= (is_client ? SSL_CLIENT_EXTENDED_MASTER_SECRET : SSL_SERVER_EXTENDED_MASTER_SECRET); ++ break; + default: + proto_tree_add_bytes_format(ext_tree, hf_ssl_handshake_extension_data, + tvb, offset, ext_len, NULL, +@@ -2673,7 +2678,7 @@ dissect_ssl3_hnd_hello_ext_ec_point_formats(tvbuff_t *tvb, + static void + dissect_ssl3_hnd_cli_hello(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, guint32 offset, guint32 length, +- SslDecryptSession*ssl) ++ SslDecryptSession *ssl) + { + /* struct { + * ProtocolVersion client_version; +@@ -2798,14 +2803,16 @@ dissect_ssl3_hnd_cli_hello(tvbuff_t *tvb, packet_info *pinfo, + if (length > offset - start_offset) + { + dissect_ssl3_hnd_hello_ext(tvb, tree, offset, +- length - (offset - start_offset)); ++ length - (offset - start_offset), TRUE, ++ ssl); + } + } + } + + static void + dissect_ssl3_hnd_srv_hello(tvbuff_t *tvb, +- proto_tree *tree, guint32 offset, guint32 length, SslDecryptSession *ssl) ++ proto_tree *tree, guint32 offset, guint32 length, ++ SslDecryptSession *ssl) + { + /* struct { + * ProtocolVersion server_version; +@@ -2873,7 +2880,8 @@ no_cipher: + if (length > offset - start_offset) + { + dissect_ssl3_hnd_hello_ext(tvb, tree, offset, +- length - (offset - start_offset)); ++ length - (offset - start_offset), FALSE, ++ ssl); + } + } + } diff --git a/SOURCES/wireshark-1.10.3-tls-hash-algs.patch b/SOURCES/wireshark-1.10.3-tls-hash-algs.patch new file mode 100644 index 0000000..6a0422a --- /dev/null +++ b/SOURCES/wireshark-1.10.3-tls-hash-algs.patch @@ -0,0 +1,129 @@ +diff --git a/epan/dissectors/packet-ssl-utils.h b/epan/dissectors/packet-ssl-utils.h +index aaadbe7..ccac6ae 100644 +--- a/epan/dissectors/packet-ssl-utils.h ++++ b/epan/dissectors/packet-ssl-utils.h +@@ -151,6 +151,7 @@ + #define SSL_HND_HELLO_EXT_SERVER_NAME 0x0 + #define SSL_HND_HELLO_EXT_ELLIPTIC_CURVES 0x000a + #define SSL_HND_HELLO_EXT_EC_POINT_FORMATS 0x000b ++#define SSL_HND_HELLO_EXT_SIG_HASH_ALGS 0x000d + #define SSL_HND_HELLO_EXT_HEARTBEAT 0x000f + #define SSL_HND_HELLO_EXT_RENEG_INFO 0xff01 + #define SSL_HND_HELLO_EXT_NPN 0x3374 +diff --git a/epan/dissectors/packet-ssl.c b/epan/dissectors/packet-ssl.c +index d75a3cc..b50ca22 100644 +--- a/epan/dissectors/packet-ssl.c ++++ b/epan/dissectors/packet-ssl.c +@@ -542,6 +542,9 @@ static gint dissect_ssl3_hnd_hello_ext_elliptic_curves(tvbuff_t *tvb, + static gint dissect_ssl3_hnd_hello_ext_ec_point_formats(tvbuff_t *tvb, + proto_tree *tree, guint32 offset); + ++static gint dissect_ssl3_hnd_hello_ext_sig_hash_algs(tvbuff_t *tvb, ++ proto_tree *tree, guint32 offset, guint32 ext_len); ++ + static gint dissect_ssl3_hnd_hello_ext_npn(tvbuff_t *tvb, + proto_tree *tree, guint32 offset, guint32 ext_len); + +@@ -674,6 +677,10 @@ static gint ssl_looks_like_valid_v2_handshake(tvbuff_t *tvb, + static gint ssl_looks_like_valid_pct_handshake(tvbuff_t *tvb, + const guint32 offset, + const guint32 record_length); ++ ++static gint dissect_ssl_hash_alg_list(tvbuff_t *tvb, proto_tree *tree, ++ guint32 offset, guint16 len); ++ + /********************************************************************* + * + * Main dissector +@@ -2439,6 +2446,9 @@ dissect_ssl3_hnd_hello_ext(tvbuff_t *tvb, + case SSL_HND_HELLO_EXT_EC_POINT_FORMATS: + offset = dissect_ssl3_hnd_hello_ext_ec_point_formats(tvb, ext_tree, offset); + break; ++ case SSL_HND_HELLO_EXT_SIG_HASH_ALGS: ++ offset = dissect_ssl3_hnd_hello_ext_sig_hash_algs(tvb, ext_tree, offset, ext_len); ++ break; + case SSL_HND_HELLO_EXT_NPN: + offset = dissect_ssl3_hnd_hello_ext_npn(tvb, ext_tree, offset, ext_len); + break; +@@ -2502,6 +2512,29 @@ dissect_ssl3_hnd_hello_ext_npn(tvbuff_t *tvb, + } + + static gint ++dissect_ssl3_hnd_hello_ext_sig_hash_algs(tvbuff_t *tvb, ++ proto_tree *tree, guint32 offset, guint32 ext_len) ++{ ++ guint16 sh_alg_length; ++ gint ret; ++ ++ sh_alg_length = tvb_get_ntohs(tvb, offset); ++ proto_tree_add_uint(tree, hf_ssl_handshake_sig_hash_alg_len, ++ tvb, offset, 2, sh_alg_length); ++ offset += 2; ++ if (ext_len<2 || sh_alg_length!=ext_len-2) { ++ /* ERROR: sh_alg_length must be 2 less than ext_len */ ++ return offset; ++ } ++ ++ ret = dissect_ssl_hash_alg_list(tvb, tree, offset, sh_alg_length); ++ if (ret >=0) ++ offset += ret; ++ ++ return offset; ++} ++ ++static gint + dissect_ssl3_hnd_hello_ext_reneg_info(tvbuff_t *tvb, + proto_tree *tree, guint32 offset, guint32 ext_len) + { +@@ -4957,6 +4990,51 @@ ssl_looks_like_valid_pct_handshake(tvbuff_t *tvb, const guint32 offset, + return ret; + } + ++/* dissect a list of hash algorithms, return the number of bytes dissected ++ * this is used for the signature algorithms extension and for the ++ * TLS1.2 certificate request */ ++static gint ++dissect_ssl_hash_alg_list(tvbuff_t *tvb, proto_tree *tree, ++ guint32 offset, guint16 len) ++{ ++ guint32 offset_start; ++ proto_tree *subtree, *alg_tree; ++ proto_tree *ti; ++ ++ offset_start = offset; ++ if (len==0) ++ return 0; ++ ++ ti = proto_tree_add_none_format(tree, ++ hf_ssl_handshake_sig_hash_algs, ++ tvb, offset, len, ++ "Signature Hash Algorithms (%u algorithm%s)", ++ len/2, ++ plurality(len/2, "", "s")); ++ subtree = proto_item_add_subtree(ti, ett_ssl_sig_hash_algs); ++ ++ if (len % 2) { ++ proto_tree_add_text(tree, tvb, offset, 2, ++ "Invalid Signature Hash Algorithm length: %d", len); ++ return offset-offset_start; ++ } ++ ++ while (len > 0) { ++ ti = proto_tree_add_item(subtree, hf_ssl_handshake_sig_hash_alg, ++ tvb, offset, 2, ENC_BIG_ENDIAN); ++ alg_tree = proto_item_add_subtree(ti, ett_ssl_sig_hash_alg); ++ ++ proto_tree_add_item(alg_tree, hf_ssl_handshake_sig_hash_hash, ++ tvb, offset, 1, ENC_BIG_ENDIAN); ++ proto_tree_add_item(alg_tree, hf_ssl_handshake_sig_hash_sig, ++ tvb, offset+1, 1, ENC_BIG_ENDIAN); ++ ++ offset += 2; ++ len -= 2; ++ } ++ return offset-offset_start; ++} ++ + /* UAT */ + + #ifdef HAVE_LIBGNUTLS diff --git a/SOURCES/wireshark-1.10.3-tls-key-exchange-msgs.patch b/SOURCES/wireshark-1.10.3-tls-key-exchange-msgs.patch new file mode 100644 index 0000000..29260dd --- /dev/null +++ b/SOURCES/wireshark-1.10.3-tls-key-exchange-msgs.patch @@ -0,0 +1,1469 @@ +diff --git a/epan/dissectors/packet-dtls.c b/epan/dissectors/packet-dtls.c +index 5e287e0..c43126d 100644 +--- a/epan/dissectors/packet-dtls.c ++++ b/epan/dissectors/packet-dtls.c +@@ -307,31 +307,31 @@ dtls_parse_old_keys(void) + /* record layer dissector */ + static gint dissect_dtls_record(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, guint32 offset, +- guint *conv_version, ++ SslSession *session, + SslDecryptSession *conv_data); + + /* change cipher spec dissector */ + static void dissect_dtls_change_cipher_spec(tvbuff_t *tvb, + proto_tree *tree, + guint32 offset, +- guint *conv_version, guint8 content_type); ++ SslSession *session, guint8 content_type); + + /* alert message dissector */ + static void dissect_dtls_alert(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, guint32 offset, +- guint *conv_version); ++ SslSession *session); + + /* handshake protocol dissector */ + static void dissect_dtls_handshake(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, guint32 offset, + guint32 record_length, +- guint *conv_version, ++ SslSession *session, + SslDecryptSession *conv_data, guint8 content_type); + + /* heartbeat message dissector */ + static void dissect_dtls_heartbeat(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, guint32 offset, +- guint *conv_version, guint32 record_length); ++ SslSession *session, guint32 record_length); + + + static void dissect_dtls_hnd_cli_hello(tvbuff_t *tvb, +@@ -363,7 +363,7 @@ static void dissect_dtls_hnd_cert_req(tvbuff_t *tvb, + static void dissect_dtls_hnd_finished(tvbuff_t *tvb, + proto_tree *tree, + guint32 offset, +- guint* conv_version); ++ SslSession *session); + + /* + * Support Functions +@@ -395,7 +395,7 @@ dissect_dtls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) + guint32 offset; + gboolean first_record_in_frame; + SslDecryptSession *ssl_session; +- guint* conv_version; ++ SslSession *session; + Ssl_private_key_t *private_key; + + ti = NULL; +@@ -427,7 +427,7 @@ dissect_dtls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) + + ssl_session = se_new0(SslDecryptSession); + ssl_session_init(ssl_session); +- ssl_session->version = SSL_VER_UNKNOWN; ++ ssl_session->session.version = SSL_VER_UNKNOWN; + conversation_add_proto_data(conversation, proto_dtls, ssl_session); + + /* we need to know witch side of conversation is speaking */ +@@ -454,7 +454,7 @@ dissect_dtls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) + ssl_session->private_key = private_key->sexp_pkey; + } + } +- conv_version= & ssl_session->version; ++ session = &ssl_session->session; + + /* try decryption only the first time we see this packet + * (to keep cipher synchronized) */ +@@ -490,15 +490,15 @@ dissect_dtls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) + /* first try to dispatch off the cached version + * known to be associated with the conversation + */ +- switch(*conv_version) { ++ switch(session->version) { + case SSL_VER_DTLS: + offset = dissect_dtls_record(tvb, pinfo, dtls_tree, +- offset, conv_version, ++ offset, session, + ssl_session); + break; + case SSL_VER_DTLS1DOT2: + offset = dissect_dtls_record(tvb, pinfo, dtls_tree, +- offset, conv_version, ++ offset, session, + ssl_session); + break; + +@@ -510,7 +510,7 @@ dissect_dtls(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) + { + /* looks like dtls */ + offset = dissect_dtls_record(tvb, pinfo, dtls_tree, +- offset, conv_version, ++ offset, session, + ssl_session); + } + else +@@ -622,7 +622,7 @@ decrypt_dtls_record(tvbuff_t *tvb, packet_info *pinfo, guint32 offset, + decoder = ssl->client; + } + +- if (!decoder && ssl->cipher != 0x0001 && ssl->cipher != 0x0002) { ++ if (!decoder && ssl->session.cipher != 0x0001 && ssl->session.cipher != 0x0002) { + ssl_debug_printf("decrypt_dtls_record: no decoder available\n"); + return ret; + } +@@ -650,7 +650,7 @@ decrypt_dtls_record(tvbuff_t *tvb, packet_info *pinfo, guint32 offset, + &dtls_compressed_data, &dtls_decrypted_data, &dtls_decrypted_data_avail) == 0) + ret = 1; + } +- else if (ssl->cipher == 0x0001 || ssl->cipher == 0x0002) { ++ else if (ssl->session.cipher == 0x0001 || ssl->session.cipher == 0x0002) { + /* Non-encrypting cipher RSA-NULL-MD5 or RSA-NULL-SHA */ + memcpy(dtls_decrypted_data.data, tvb_get_ptr(tvb, offset, record_length), record_length); + dtls_decrypted_data_avail = dtls_decrypted_data.data_len = record_length; +@@ -677,7 +677,7 @@ decrypt_dtls_record(tvbuff_t *tvb, packet_info *pinfo, guint32 offset, + static gint + dissect_dtls_record(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, guint32 offset, +- guint *conv_version, ++ SslSession *session, + SslDecryptSession* ssl) + { + +@@ -812,14 +812,14 @@ dissect_dtls_record(tvbuff_t *tvb, packet_info *pinfo, + * structure and print the column version + */ + next_byte = tvb_get_guint8(tvb, offset); +- if (*conv_version == SSL_VER_UNKNOWN ++ if (session->version == SSL_VER_UNKNOWN + && dtls_is_authoritative_version_message(content_type, next_byte)) + { + if (version == DTLSV1DOT0_VERSION || + version == DTLSV1DOT0_VERSION_NOT) + { + +- *conv_version = SSL_VER_DTLS; ++ session->version = SSL_VER_DTLS; + if (ssl) { + ssl->version_netorder = version; + ssl->state |= SSL_VERSION; +@@ -829,7 +829,7 @@ dissect_dtls_record(tvbuff_t *tvb, packet_info *pinfo, + if (version == DTLSV1DOT2_VERSION) + { + +- *conv_version = SSL_VER_DTLS1DOT2; ++ session->version = SSL_VER_DTLS1DOT2; + if (ssl) { + ssl->version_netorder = version; + ssl->state |= SSL_VERSION; +@@ -867,7 +867,7 @@ dissect_dtls_record(tvbuff_t *tvb, packet_info *pinfo, + case SSL_ID_CHG_CIPHER_SPEC: + col_append_str(pinfo->cinfo, COL_INFO, "Change Cipher Spec"); + dissect_dtls_change_cipher_spec(tvb, dtls_record_tree, +- offset, conv_version, content_type); ++ offset, session, content_type); + if (ssl) ssl_change_cipher(ssl, ssl_packet_from_server(ssl, dtls_associations, pinfo)); + break; + case SSL_ID_ALERT: +@@ -882,12 +882,10 @@ dissect_dtls_record(tvbuff_t *tvb, packet_info *pinfo, + /* try to retrieve and use decrypted alert record, if any. */ + decrypted = ssl_get_record_info(tvb, proto_dtls, pinfo, offset); + if (decrypted) { +- dissect_dtls_alert(decrypted, pinfo, dtls_record_tree, 0, +- conv_version); ++ dissect_dtls_alert(decrypted, pinfo, dtls_record_tree, 0, session); + add_new_data_source(pinfo, decrypted, "Decrypted SSL record"); + } else { +- dissect_dtls_alert(tvb, pinfo, dtls_record_tree, offset, +- conv_version); ++ dissect_dtls_alert(tvb, pinfo, dtls_record_tree, offset, session); + } + break; + } +@@ -908,11 +906,11 @@ dissect_dtls_record(tvbuff_t *tvb, packet_info *pinfo, + decrypted = ssl_get_record_info(tvb, proto_dtls, pinfo, offset); + if (decrypted) { + dissect_dtls_handshake(decrypted, pinfo, dtls_record_tree, 0, +- tvb_length(decrypted), conv_version, ssl, content_type); ++ tvb_length(decrypted), session, ssl, content_type); + add_new_data_source(pinfo, decrypted, "Decrypted SSL record"); + } else { + dissect_dtls_handshake(tvb, pinfo, dtls_record_tree, offset, +- record_length, conv_version, ssl, content_type); ++ record_length, session, ssl, content_type); + } + break; + } +@@ -935,7 +933,7 @@ dissect_dtls_record(tvbuff_t *tvb, packet_info *pinfo, + + proto_item_set_text(dtls_record_tree, + "%s Record Layer: %s Protocol: %s", +- val_to_str_const(*conv_version, ssl_version_short_names, "SSL"), ++ val_to_str_const(session->version, ssl_version_short_names, "SSL"), + val_to_str_const(content_type, ssl_31_content_type, "unknown"), + association?association->info:"Application Data"); + +@@ -988,11 +986,11 @@ dissect_dtls_record(tvbuff_t *tvb, packet_info *pinfo, + decrypted = ssl_get_record_info(tvb, proto_dtls, pinfo, offset); + if (decrypted) { + dissect_dtls_heartbeat(decrypted, pinfo, dtls_record_tree, 0, +- conv_version, record_length); ++ session, record_length); + add_new_data_source(pinfo, decrypted, "Decrypted SSL record"); + } else { + dissect_dtls_heartbeat(tvb, pinfo, dtls_record_tree, offset, +- conv_version, record_length); ++ session, record_length); + } + break; + } +@@ -1011,7 +1009,7 @@ dissect_dtls_record(tvbuff_t *tvb, packet_info *pinfo, + static void + dissect_dtls_change_cipher_spec(tvbuff_t *tvb, + proto_tree *tree, guint32 offset, +- guint* conv_version, guint8 content_type) ++ SslSession *session, guint8 content_type) + { + /* + * struct { +@@ -1023,7 +1021,7 @@ dissect_dtls_change_cipher_spec(tvbuff_t *tvb, + { + proto_item_set_text(tree, + "%s Record Layer: %s Protocol: Change Cipher Spec", +- val_to_str_const(*conv_version, ssl_version_short_names, "SSL"), ++ val_to_str_const(session->version, ssl_version_short_names, "SSL"), + val_to_str_const(content_type, ssl_31_content_type, "unknown")); + proto_tree_add_item(tree, hf_dtls_change_cipher_spec, tvb, + offset, 1, ENC_NA); +@@ -1034,7 +1032,7 @@ dissect_dtls_change_cipher_spec(tvbuff_t *tvb, + static void + dissect_dtls_alert(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, guint32 offset, +- guint* conv_version) ++ SslSession *session) + { + /* struct { + * AlertLevel level; +@@ -1087,7 +1085,7 @@ dissect_dtls_alert(tvbuff_t *tvb, packet_info *pinfo, + { + proto_item_set_text(tree, "%s Record Layer: Alert " + "(Level: %s, Description: %s)", +- val_to_str_const(*conv_version, ssl_version_short_names, "SSL"), ++ val_to_str_const(session->version, ssl_version_short_names, "SSL"), + level, desc); + proto_tree_add_item(ssl_alert_tree, hf_dtls_alert_message_level, + tvb, offset++, 1, ENC_BIG_ENDIAN); +@@ -1099,7 +1097,7 @@ dissect_dtls_alert(tvbuff_t *tvb, packet_info *pinfo, + { + proto_item_set_text(tree, + "%s Record Layer: Encrypted Alert", +- val_to_str_const(*conv_version, ssl_version_short_names, "SSL")); ++ val_to_str_const(session->version, ssl_version_short_names, "SSL")); + proto_item_set_text(ssl_alert_tree, + "Alert Message: Encrypted Alert"); + } +@@ -1111,7 +1109,7 @@ dissect_dtls_alert(tvbuff_t *tvb, packet_info *pinfo, + static void + dissect_dtls_handshake(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, guint32 offset, +- guint32 record_length, guint *conv_version, ++ guint32 record_length, SslSession *session, + SslDecryptSession* ssl, guint8 content_type) + { + /* struct { +@@ -1338,7 +1336,7 @@ dissect_dtls_handshake(tvbuff_t *tvb, packet_info *pinfo, + if (first_iteration) + { + proto_item_set_text(tree, "%s Record Layer: %s Protocol: %s%s", +- val_to_str_const(*conv_version, ssl_version_short_names, "SSL"), ++ val_to_str_const(session->version, ssl_version_short_names, "SSL"), + val_to_str_const(content_type, ssl_31_content_type, "unknown"), + (msg_type_str!=NULL) ? msg_type_str : + "Encrypted Handshake Message", +@@ -1347,7 +1345,7 @@ dissect_dtls_handshake(tvbuff_t *tvb, packet_info *pinfo, + else + { + proto_item_set_text(tree, "%s Record Layer: %s Protocol: %s%s", +- val_to_str_const(*conv_version, ssl_version_short_names, "SSL"), ++ val_to_str_const(session->version, ssl_version_short_names, "SSL"), + val_to_str_const(content_type, ssl_31_content_type, "unknown"), + "Multiple Handshake Messages", + (frag_str!=NULL) ? frag_str : ""); +@@ -1489,8 +1487,7 @@ dissect_dtls_handshake(tvbuff_t *tvb, packet_info *pinfo, + break; + + case SSL_HND_FINISHED: +- dissect_dtls_hnd_finished(sub_tvb, ssl_hand_tree, +- 0, conv_version); ++ dissect_dtls_hnd_finished(sub_tvb, ssl_hand_tree, 0, session); + break; + } + +@@ -1502,7 +1499,7 @@ dissect_dtls_handshake(tvbuff_t *tvb, packet_info *pinfo, + static void + dissect_dtls_heartbeat(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, guint32 offset, +- guint* conv_version, guint32 record_length) ++ SslSession *session, guint32 record_length) + { + /* struct { + * HeartbeatMessageType type; +@@ -1549,7 +1546,7 @@ dissect_dtls_heartbeat(tvbuff_t *tvb, packet_info *pinfo, + if (type && (payload_length <= record_length - 16 - 3)) { + proto_item_set_text(tree, "%s Record Layer: Heartbeat " + "%s", +- val_to_str_const(*conv_version, ssl_version_short_names, "SSL"), ++ val_to_str_const(session->version, ssl_version_short_names, "SSL"), + type); + proto_tree_add_item(dtls_heartbeat_tree, hf_dtls_heartbeat_message_type, + tvb, offset, 1, ENC_BIG_ENDIAN); +@@ -1571,7 +1568,7 @@ dissect_dtls_heartbeat(tvbuff_t *tvb, packet_info *pinfo, + } else { + proto_item_set_text(tree, + "%s Record Layer: Encrypted Heartbeat", +- val_to_str_const(*conv_version, ssl_version_short_names, "SSL")); ++ val_to_str_const(session->version, ssl_version_short_names, "SSL")); + proto_item_set_text(dtls_heartbeat_tree, + "Encrypted Heartbeat Message"); + } +@@ -1933,15 +1930,15 @@ dissect_dtls_hnd_srv_hello(tvbuff_t *tvb, + /* PAOLO: handle session cipher suite */ + if (ssl) { + /* store selected cipher suite for decryption */ +- ssl->cipher = tvb_get_ntohs(tvb, offset); +- if (ssl_find_cipher(ssl->cipher,&ssl->cipher_suite) < 0) { +- ssl_debug_printf("dissect_dtls_hnd_srv_hello can't find cipher suite %X\n", ssl->cipher); ++ ssl->session.cipher = tvb_get_ntohs(tvb, offset); ++ if (ssl_find_cipher(ssl->session.cipher,&ssl->cipher_suite) < 0) { ++ ssl_debug_printf("dissect_dtls_hnd_srv_hello can't find cipher suite %X\n", ssl->session.cipher); + goto no_cipher; + } + + ssl->state |= SSL_CIPHER; + ssl_debug_printf("dissect_dtls_hnd_srv_hello found cipher %X, state %X\n", +- ssl->cipher, ssl->state); ++ ssl->session.cipher, ssl->state); + + /* if we have restored a session now we can have enough material + * to build session key, check it out*/ +@@ -1963,7 +1960,7 @@ dissect_dtls_hnd_srv_hello(tvbuff_t *tvb, + no_cipher: + if (ssl) { + /* store selected compression method for decompression */ +- ssl->compression = tvb_get_guint8(tvb, offset+2); ++ ssl->session.compression = tvb_get_guint8(tvb, offset+2); + } + if (!tree) + return offset; +@@ -2223,7 +2220,7 @@ dissect_dtls_hnd_cert_req(tvbuff_t *tvb, + + static void + dissect_dtls_hnd_finished(tvbuff_t *tvb, proto_tree *tree, guint32 offset, +- guint* conv_version) ++ SslSession *session) + { + /* + * struct { +@@ -2237,7 +2234,7 @@ dissect_dtls_hnd_finished(tvbuff_t *tvb, proto_tree *tree, guint32 offset, + return; + } + +- switch(*conv_version) { ++ switch(session->version) { + case SSL_VER_DTLS: + proto_tree_add_item(tree, hf_dtls_handshake_finished, + tvb, offset, 12, ENC_NA); +diff --git a/epan/dissectors/packet-ssl-utils.c b/epan/dissectors/packet-ssl-utils.c +index 68681f5..efb170a 100644 +--- a/epan/dissectors/packet-ssl-utils.c ++++ b/epan/dissectors/packet-ssl-utils.c +@@ -2358,13 +2358,13 @@ ssl_generate_keyring_material(SslDecryptSession*ssl_session) + + /* create both client and server ciphers*/ + ssl_debug_printf("ssl_generate_keyring_material ssl_create_decoder(client)\n"); +- ssl_session->client_new = ssl_create_decoder(&ssl_session->cipher_suite, ssl_session->compression, c_mk, c_wk, c_iv); ++ ssl_session->client_new = ssl_create_decoder(&ssl_session->cipher_suite, ssl_session->session.compression, c_mk, c_wk, c_iv); + if (!ssl_session->client_new) { + ssl_debug_printf("ssl_generate_keyring_material can't init client decoder\n"); + goto fail; + } + ssl_debug_printf("ssl_generate_keyring_material ssl_create_decoder(server)\n"); +- ssl_session->server_new = ssl_create_decoder(&ssl_session->cipher_suite, ssl_session->compression, s_mk, s_wk, s_iv); ++ ssl_session->server_new = ssl_create_decoder(&ssl_session->cipher_suite, ssl_session->session.compression, s_mk, s_wk, s_iv); + if (!ssl_session->server_new) { + ssl_debug_printf("ssl_generate_keyring_material can't init client decoder\n"); + goto fail; +diff --git a/epan/dissectors/packet-ssl-utils.h b/epan/dissectors/packet-ssl-utils.h +index ccac6ae..1ba1598 100644 +--- a/epan/dissectors/packet-ssl-utils.h ++++ b/epan/dissectors/packet-ssl-utils.h +@@ -304,6 +304,12 @@ typedef struct { + SslRecordInfo* handshake_data; + } SslPacketInfo; + ++typedef struct _SslSession { ++ gint cipher; ++ gint compression; ++ guint32 version; ++} SslSession; ++ + typedef struct _SslDecryptSession { + guchar _master_secret[48]; + guchar _session_id[256]; +@@ -320,8 +326,6 @@ typedef struct _SslDecryptSession { + guchar _client_data_for_iv[24]; + StringInfo client_data_for_iv; + +- gint cipher; +- gint compression; + gint state; + SslCipherSuite cipher_suite; + SslDecoder *server; +@@ -330,9 +334,9 @@ typedef struct _SslDecryptSession { + SslDecoder *client_new; + SSL_PRIVATE_KEY* private_key; + SSL_PSK_KEY* psk; +- guint32 version; + guint16 version_netorder; + StringInfo app_data_segment; ++ SslSession session; + + address srv_addr; + port_type srv_ptype; +diff --git a/epan/dissectors/packet-ssl.c b/epan/dissectors/packet-ssl.c +index b50ca22..6f22158 100644 +--- a/epan/dissectors/packet-ssl.c ++++ b/epan/dissectors/packet-ssl.c +@@ -507,7 +507,7 @@ ssl_association_info(void) + /* record layer dissector */ + static gint dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, guint32 offset, +- guint *conv_version, guint conv_cipher, ++ SslSession *session, + gboolean *need_desegmentation, + SslDecryptSession *conv_data, + const gboolean first_record_in_frame); +@@ -516,24 +516,23 @@ static gint dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo, + static void dissect_ssl3_change_cipher_spec(tvbuff_t *tvb, + proto_tree *tree, + guint32 offset, +- guint *conv_version, const guint8 content_type); ++ SslSession *session, const guint8 content_type); + + /* alert message dissector */ + static void dissect_ssl3_alert(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, guint32 offset, +- guint *conv_version); ++ SslSession *session); + + /* handshake protocol dissector */ + static void dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, guint32 offset, +- guint32 record_length, +- guint *conv_version, guint conv_cipher, ++ guint32 record_length, SslSession *session, + SslDecryptSession *conv_data, const guint8 content_type); + + /* heartbeat message dissector */ + static void dissect_ssl3_heartbeat(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, guint32 offset, +- guint *conv_version, guint32 record_length); ++ SslSession *session, guint32 record_length); + + /* hello extension dissector */ + static gint dissect_ssl3_hnd_hello_ext_elliptic_curves(tvbuff_t *tvb, +@@ -574,20 +573,22 @@ static void dissect_ssl3_hnd_cert(tvbuff_t *tvb, + static void dissect_ssl3_hnd_cert_req(tvbuff_t *tvb, + proto_tree *tree, + guint32 offset, packet_info *pinfo, +- const guint *conv_version); ++ SslSession *session); + + static void dissect_ssl3_hnd_srv_keyex_ecdh(tvbuff_t *tvb, +- proto_tree *tree, +- guint32 offset, guint32 length); +- ++ proto_tree *tree, ++ guint32 offset, guint32 length, ++ SslSession *session); + +-static void dissect_ssl3_hnd_srv_keyex_dh(tvbuff_t *tvb, +- proto_tree *tree, +- guint32 offset, guint32 length); ++static void dissect_ssl3_hnd_srv_keyex_dhe(tvbuff_t *tvb, ++ proto_tree *tree, ++ guint32 offset, guint32 length, ++ SslSession *session); + + static void dissect_ssl3_hnd_srv_keyex_rsa(tvbuff_t *tvb, + proto_tree *tree, +- guint32 offset, guint32 length); ++ guint32 offset, guint32 length, ++ SslSession *session); + + static void dissect_ssl3_hnd_cli_keyex_ecdh(tvbuff_t *tvb, + proto_tree *tree, +@@ -605,7 +606,7 @@ static void dissect_ssl3_hnd_cli_keyex_rsa(tvbuff_t *tvb, + static void dissect_ssl3_hnd_finished(tvbuff_t *tvb, + proto_tree *tree, + const guint32 offset, +- const guint *conv_version); ++ SslSession *session); + + static void dissect_ssl3_hnd_cert_status(tvbuff_t *tvb, + proto_tree *tree, +@@ -620,7 +621,7 @@ static void dissect_ssl3_hnd_cert_status(tvbuff_t *tvb, + /* record layer dissector */ + static gint dissect_ssl2_record(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, guint32 offset, +- guint *conv_version, ++ SslSession *session, + gboolean *need_desegmentation, + SslDecryptSession *ssl, gboolean first_record_in_frame); + +@@ -701,8 +702,7 @@ dissect_ssl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) + gboolean first_record_in_frame; + gboolean need_desegmentation; + SslDecryptSession *ssl_session; +- guint *conv_version; +- guint conv_cipher; ++ SslSession *session; + + ti = NULL; + ssl_tree = NULL; +@@ -736,11 +736,10 @@ dissect_ssl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) + else { + ssl_session = (SslDecryptSession *)se_alloc0(sizeof(SslDecryptSession)); + ssl_session_init(ssl_session); +- ssl_session->version = SSL_VER_UNKNOWN; ++ ssl_session->session.version = SSL_VER_UNKNOWN; + conversation_add_proto_data(conversation, proto_ssl, ssl_session); + } +- conv_version =& ssl_session->version; +- conv_cipher = ssl_session->cipher; ++ session = &ssl_session->session; + + /* try decryption only the first time we see this packet + * (to keep cipher synchronized) */ +@@ -789,11 +788,11 @@ dissect_ssl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) + /* first try to dispatch off the cached version + * known to be associated with the conversation + */ +- switch (*conv_version) { ++ switch (session->version) { + case SSL_VER_SSLv2: + case SSL_VER_PCT: + offset = dissect_ssl2_record(tvb, pinfo, ssl_tree, +- offset, conv_version, ++ offset, session, + &need_desegmentation, + ssl_session, + first_record_in_frame); +@@ -810,7 +809,7 @@ dissect_ssl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) + if (ssl_is_v2_client_hello(tvb, offset)) + { + offset = dissect_ssl2_record(tvb, pinfo, ssl_tree, +- offset, conv_version, ++ offset, session, + &need_desegmentation, + ssl_session, + first_record_in_frame); +@@ -818,8 +817,7 @@ dissect_ssl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) + else + { + offset = dissect_ssl3_record(tvb, pinfo, ssl_tree, +- offset, conv_version, +- conv_cipher, ++ offset, session, + &need_desegmentation, + ssl_session, + first_record_in_frame); +@@ -834,7 +832,7 @@ dissect_ssl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) + { + /* looks like sslv2 or pct client hello */ + offset = dissect_ssl2_record(tvb, pinfo, ssl_tree, +- offset, conv_version, ++ offset, session, + &need_desegmentation, + ssl_session, + first_record_in_frame); +@@ -843,8 +841,7 @@ dissect_ssl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) + { + /* looks like sslv3 or tls */ + offset = dissect_ssl3_record(tvb, pinfo, ssl_tree, +- offset, conv_version, +- conv_cipher, ++ offset, session, + &need_desegmentation, + ssl_session, + first_record_in_frame); +@@ -867,7 +864,7 @@ dissect_ssl(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) + + /* Set the protocol column */ + col_set_str(pinfo->cinfo, COL_PROTOCOL, +- val_to_str_const(*conv_version, ssl_version_short_names, "SSL")); ++ val_to_str_const(session->version, ssl_version_short_names, "SSL")); + } + break; + } +@@ -1434,8 +1431,7 @@ dissect_ssl_payload(tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *t + *********************************************************************/ + static gint + dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo, +- proto_tree *tree, guint32 offset, +- guint *conv_version, guint conv_cipher, ++ proto_tree *tree, guint32 offset, SslSession *session, + gboolean *need_desegmentation, + SslDecryptSession *ssl, const gboolean first_record_in_frame) + { +@@ -1473,7 +1469,7 @@ dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo, + available_bytes = tvb_length_remaining(tvb, offset); + + /* TLS 1.0/1.1 just ignores unknown records - RFC 2246 chapter 6. The TLS Record Protocol */ +- if ((*conv_version==SSL_VER_TLS || *conv_version==SSL_VER_TLSv1DOT1 || *conv_version==SSL_VER_TLSv1DOT2) && ++ if ((session->version==SSL_VER_TLS || session->version==SSL_VER_TLSv1DOT1 || session->version==SSL_VER_TLSv1DOT2) && + (available_bytes >=1 ) && !ssl_is_valid_content_type(tvb_get_guint8(tvb, offset))) { + proto_tree_add_text(tree, tvb, offset, available_bytes, "Ignored Unknown Record"); + /* on second and subsequent records per frame +@@ -1483,7 +1479,7 @@ dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo, + col_append_str(pinfo->cinfo, COL_INFO, ", "); + } + col_append_str(pinfo->cinfo, COL_INFO, "Ignored Unknown Record"); +- col_set_str(pinfo->cinfo, COL_PROTOCOL, val_to_str_const(*conv_version, ssl_version_short_names, "SSL")); ++ col_set_str(pinfo->cinfo, COL_PROTOCOL, val_to_str_const(session->version, ssl_version_short_names, "SSL")); + return offset + available_bytes; + } + +@@ -1568,7 +1564,7 @@ dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo, + + /* Set the protocol column */ + col_set_str(pinfo->cinfo, COL_PROTOCOL, +- val_to_str_const(*conv_version, ssl_version_short_names, "SSL")); ++ val_to_str_const(session->version, ssl_version_short_names, "SSL")); + + return offset + 5 + record_length; + } +@@ -1614,51 +1610,51 @@ dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo, + * structure and print the column version + */ + next_byte = tvb_get_guint8(tvb, offset); +- if (*conv_version == SSL_VER_UNKNOWN ++ if (session->version == SSL_VER_UNKNOWN + && ssl_is_authoritative_version_message(content_type, next_byte)) + { + if (version == SSLV3_VERSION) + { +- *conv_version = SSL_VER_SSLv3; ++ session->version = SSL_VER_SSLv3; + if (ssl) { + ssl->version_netorder = version; + ssl->state |= SSL_VERSION; + ssl_debug_printf("dissect_ssl3_record found version 0x%04X -> state 0x%02X\n", ssl->version_netorder, ssl->state); + } +- /*ssl_set_conv_version(pinfo, ssl->version);*/ ++ /*ssl_set_conv_version(pinfo, ssl->session.version);*/ + } + else if (version == TLSV1_VERSION) + { + +- *conv_version = SSL_VER_TLS; ++ session->version = SSL_VER_TLS; + if (ssl) { + ssl->version_netorder = version; + ssl->state |= SSL_VERSION; + ssl_debug_printf("dissect_ssl3_record found version 0x%04X(TLS 1.0) -> state 0x%02X\n", ssl->version_netorder, ssl->state); + } +- /*ssl_set_conv_version(pinfo, ssl->version);*/ ++ /*ssl_set_conv_version(pinfo, ssl->session.version);*/ + } + else if (version == TLSV1DOT1_VERSION) + { + +- *conv_version = SSL_VER_TLSv1DOT1; ++ session->version = SSL_VER_TLSv1DOT1; + if (ssl) { + ssl->version_netorder = version; + ssl->state |= SSL_VERSION; + ssl_debug_printf("dissect_ssl3_record found version 0x%04X(TLS 1.1) -> state 0x%02X\n", ssl->version_netorder, ssl->state); + } +- /*ssl_set_conv_version(pinfo, ssl->version);*/ ++ /*ssl_set_conv_version(pinfo, ssl->session.version);*/ + } + else if (version == TLSV1DOT2_VERSION) + { + +- *conv_version = SSL_VER_TLSv1DOT2; ++ session->version = SSL_VER_TLSv1DOT2; + if (ssl) { + ssl->version_netorder = version; + ssl->state |= SSL_VERSION; + ssl_debug_printf("dissect_ssl3_record found version 0x%04X(TLS 1.2) -> state 0x%02X\n", ssl->version_netorder, ssl->state); + } +- /*ssl_set_conv_version(pinfo, ssl->version);*/ ++ /*ssl_set_conv_version(pinfo, ssl->session.version);*/ + } + } + +@@ -1670,7 +1666,7 @@ dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo, + } + + col_set_str(pinfo->cinfo, COL_PROTOCOL, +- val_to_str_const(*conv_version, ssl_version_short_names, "SSL")); ++ val_to_str_const(session->version, ssl_version_short_names, "SSL")); + + /* + * now dissect the next layer +@@ -1685,7 +1681,7 @@ dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo, + ssl_debug_printf("dissect_ssl3_change_cipher_spec\n"); + col_append_str(pinfo->cinfo, COL_INFO, "Change Cipher Spec"); + dissect_ssl3_change_cipher_spec(tvb, ssl_record_tree, +- offset, conv_version, content_type); ++ offset, session, content_type); + if (ssl) ssl_change_cipher(ssl, ssl_packet_from_server(ssl, ssl_associations, pinfo)); + break; + case SSL_ID_ALERT: +@@ -1701,9 +1697,9 @@ dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo, + decrypted = ssl_get_record_info(tvb, proto_ssl, pinfo, offset); + if (decrypted) { + add_new_data_source(pinfo, decrypted, "Decrypted SSL record"); +- dissect_ssl3_alert(decrypted, pinfo, ssl_record_tree, 0, conv_version); ++ dissect_ssl3_alert(decrypted, pinfo, ssl_record_tree, 0, session); + } else { +- dissect_ssl3_alert(tvb, pinfo, ssl_record_tree, offset, conv_version); ++ dissect_ssl3_alert(tvb, pinfo, ssl_record_tree, offset, session); + } + break; + } +@@ -1726,10 +1722,11 @@ dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo, + /* add desegmented data to the data source list */ + add_new_data_source(pinfo, decrypted, "Decrypted SSL record"); + dissect_ssl3_handshake(decrypted, pinfo, ssl_record_tree, 0, +- tvb_length(decrypted), conv_version, conv_cipher, ssl, content_type); ++ tvb_length(decrypted), session, ++ ssl, content_type); + } else { + dissect_ssl3_handshake(tvb, pinfo, ssl_record_tree, offset, +- record_length, conv_version, conv_cipher, ssl, content_type); ++ record_length, session, ssl, content_type); + } + break; + } +@@ -1755,7 +1752,7 @@ dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo, + + proto_item_set_text(ssl_record_tree, + "%s Record Layer: %s Protocol: %s", +- val_to_str_const(*conv_version, ssl_version_short_names, "SSL"), ++ val_to_str_const(session->version, ssl_version_short_names, "SSL"), + val_to_str_const(content_type, ssl_31_content_type, "unknown"), + association?association->info:"Application Data"); + +@@ -1778,9 +1775,9 @@ dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo, + decrypted = ssl_get_record_info(tvb, proto_ssl, pinfo, offset); + if (decrypted) { + add_new_data_source(pinfo, decrypted, "Decrypted SSL record"); +- dissect_ssl3_heartbeat(decrypted, pinfo, ssl_record_tree, 0, conv_version, record_length); ++ dissect_ssl3_heartbeat(decrypted, pinfo, ssl_record_tree, 0, session, record_length); + } else { +- dissect_ssl3_heartbeat(tvb, pinfo, ssl_record_tree, offset, conv_version, record_length); ++ dissect_ssl3_heartbeat(tvb, pinfo, ssl_record_tree, offset, session, record_length); + } + break; + } +@@ -1799,7 +1796,7 @@ dissect_ssl3_record(tvbuff_t *tvb, packet_info *pinfo, + static void + dissect_ssl3_change_cipher_spec(tvbuff_t *tvb, + proto_tree *tree, guint32 offset, +- guint *conv_version, const guint8 content_type) ++ SslSession *session, const guint8 content_type) + { + /* + * struct { +@@ -1811,7 +1808,7 @@ dissect_ssl3_change_cipher_spec(tvbuff_t *tvb, + { + proto_item_set_text(tree, + "%s Record Layer: %s Protocol: Change Cipher Spec", +- val_to_str_const(*conv_version, ssl_version_short_names, "SSL"), ++ val_to_str_const(session->version, ssl_version_short_names, "SSL"), + val_to_str_const(content_type, ssl_31_content_type, "unknown")); + proto_tree_add_item(tree, hf_ssl_change_cipher_spec, tvb, + offset++, 1, ENC_NA); +@@ -1822,7 +1819,7 @@ dissect_ssl3_change_cipher_spec(tvbuff_t *tvb, + static void + dissect_ssl3_alert(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, guint32 offset, +- guint *conv_version) ++ SslSession *session) + { + /* struct { + * AlertLevel level; +@@ -1872,7 +1869,7 @@ dissect_ssl3_alert(tvbuff_t *tvb, packet_info *pinfo, + { + proto_item_set_text(tree, "%s Record Layer: Alert " + "(Level: %s, Description: %s)", +- val_to_str_const(*conv_version, ssl_version_short_names, "SSL"), ++ val_to_str_const(session->version, ssl_version_short_names, "SSL"), + level, desc); + proto_tree_add_item(ssl_alert_tree, hf_ssl_alert_message_level, + tvb, offset++, 1, ENC_BIG_ENDIAN); +@@ -1884,7 +1881,7 @@ dissect_ssl3_alert(tvbuff_t *tvb, packet_info *pinfo, + { + proto_item_set_text(tree, + "%s Record Layer: Encrypted Alert", +- val_to_str_const(*conv_version, ssl_version_short_names, "SSL")); ++ val_to_str_const(session->version, ssl_version_short_names, "SSL")); + proto_item_set_text(ssl_alert_tree, + "Alert Message: Encrypted Alert"); + } +@@ -1896,7 +1893,7 @@ dissect_ssl3_alert(tvbuff_t *tvb, packet_info *pinfo, + static void + dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, guint32 offset, +- guint32 record_length, guint *conv_version, guint conv_cipher, ++ guint32 record_length, SslSession *session, + SslDecryptSession *ssl, const guint8 content_type) + { + /* struct { +@@ -1981,7 +1978,7 @@ dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo, + if (first_iteration) + { + proto_item_set_text(tree, "%s Record Layer: %s Protocol: %s", +- val_to_str_const(*conv_version, ssl_version_short_names, "SSL"), ++ val_to_str_const(session->version, ssl_version_short_names, "SSL"), + val_to_str_const(content_type, ssl_31_content_type, "unknown"), + (msg_type_str!=NULL) ? msg_type_str : + "Encrypted Handshake Message"); +@@ -1989,7 +1986,7 @@ dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo, + else + { + proto_item_set_text(tree, "%s Record Layer: %s Protocol: %s", +- val_to_str_const(*conv_version, ssl_version_short_names, "SSL"), ++ val_to_str_const(session->version, ssl_version_short_names, "SSL"), + val_to_str_const(content_type, ssl_31_content_type, "unknown"), + "Multiple Handshake Messages"); + } +@@ -2048,15 +2045,15 @@ dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo, + break; + + case SSL_HND_SERVER_KEY_EXCHG: { +- switch (ssl_get_keyex_alg(conv_cipher)) { ++ switch (ssl_get_keyex_alg(session->cipher)) { + case KEX_DH: +- dissect_ssl3_hnd_srv_keyex_dh(tvb, ssl_hand_tree, offset, length); ++ dissect_ssl3_hnd_srv_keyex_dhe(tvb, ssl_hand_tree, offset, length, session); + break; + case KEX_RSA: +- dissect_ssl3_hnd_srv_keyex_rsa(tvb, ssl_hand_tree, offset, length); ++ dissect_ssl3_hnd_srv_keyex_rsa(tvb, ssl_hand_tree, offset, length, session); + break; + case KEX_ECDH: +- dissect_ssl3_hnd_srv_keyex_ecdh(tvb, ssl_hand_tree, offset, length); ++ dissect_ssl3_hnd_srv_keyex_ecdh(tvb, ssl_hand_tree, offset, length, session); + break; + default: + break; +@@ -2065,7 +2062,7 @@ dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo, + break; + + case SSL_HND_CERT_REQUEST: +- dissect_ssl3_hnd_cert_req(tvb, ssl_hand_tree, offset, pinfo, conv_version); ++ dissect_ssl3_hnd_cert_req(tvb, ssl_hand_tree, offset, pinfo, session); + break; + + case SSL_HND_SVR_HELLO_DONE: +@@ -2077,7 +2074,7 @@ dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo, + break; + + case SSL_HND_CLIENT_KEY_EXCHG: +- switch (ssl_get_keyex_alg(conv_cipher)) { ++ switch (ssl_get_keyex_alg(session->cipher)) { + case KEX_DH: + dissect_ssl3_hnd_cli_keyex_dh(tvb, ssl_hand_tree, offset, length); + break; +@@ -2098,7 +2095,7 @@ dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo, + if (!ssl) + break; + +- cipher_num = ssl->cipher; ++ cipher_num = ssl->session.cipher; + + if (cipher_num == 0x8a || cipher_num == 0x8b || cipher_num == 0x8c || cipher_num == 0x8d) + { +@@ -2174,7 +2171,7 @@ dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo, + * (it's the encrypted len and should be equal to record len - 2) + * in case of rsa1024 that would be 128 + 2 = 130; for psk not necessary + */ +- if (ssl->cipher_suite.kex==KEX_RSA && (ssl->version == SSL_VER_TLS||ssl->version == SSL_VER_TLSv1DOT1||ssl->version == SSL_VER_TLSv1DOT2)) ++ if (ssl->cipher_suite.kex==KEX_RSA && (ssl->session.version == SSL_VER_TLS||ssl->session.version == SSL_VER_TLSv1DOT1||ssl->session.version == SSL_VER_TLSv1DOT2)) + { + encrlen = tvb_get_ntohs(tvb, offset); + skip = 2; +@@ -2214,8 +2211,7 @@ dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo, + break; + + case SSL_HND_FINISHED: +- dissect_ssl3_hnd_finished(tvb, ssl_hand_tree, +- offset, conv_version); ++ dissect_ssl3_hnd_finished(tvb, ssl_hand_tree, offset, session); + break; + + case SSL_HND_CERT_STATUS: +@@ -2236,7 +2232,7 @@ dissect_ssl3_handshake(tvbuff_t *tvb, packet_info *pinfo, + static void + dissect_ssl3_heartbeat(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, guint32 offset, +- guint *conv_version, guint32 record_length) ++ SslSession *session, guint32 record_length) + { + /* struct { + * HeartbeatMessageType type; +@@ -2283,7 +2279,7 @@ dissect_ssl3_heartbeat(tvbuff_t *tvb, packet_info *pinfo, + if (type && (payload_length <= record_length - 16 - 3)) { + proto_item_set_text(tree, "%s Record Layer: Heartbeat " + "%s", +- val_to_str_const(*conv_version, ssl_version_short_names, "SSL"), ++ val_to_str_const(session->version, ssl_version_short_names, "SSL"), + type); + proto_tree_add_item(tls_heartbeat_tree, hf_ssl_heartbeat_message_type, + tvb, offset, 1, ENC_BIG_ENDIAN); +@@ -2305,7 +2301,7 @@ dissect_ssl3_heartbeat(tvbuff_t *tvb, packet_info *pinfo, + } else { + proto_item_set_text(tree, + "%s Record Layer: Encrypted Heartbeat", +- val_to_str_const(*conv_version, ssl_version_short_names, "SSL")); ++ val_to_str_const(session->version, ssl_version_short_names, "SSL")); + proto_item_set_text(tls_heartbeat_tree, + "Encrypted Heartbeat Message"); + } +@@ -2840,15 +2836,15 @@ dissect_ssl3_hnd_srv_hello(tvbuff_t *tvb, + /* PAOLO: handle session cipher suite */ + if (ssl) { + /* store selected cipher suite for decryption */ +- ssl->cipher = tvb_get_ntohs(tvb, offset); +- if (ssl_find_cipher(ssl->cipher,&ssl->cipher_suite) < 0) { +- ssl_debug_printf("dissect_ssl3_hnd_srv_hello can't find cipher suite 0x%X\n", ssl->cipher); ++ ssl->session.cipher = tvb_get_ntohs(tvb, offset); ++ if (ssl_find_cipher(ssl->session.cipher,&ssl->cipher_suite) < 0) { ++ ssl_debug_printf("dissect_ssl3_hnd_srv_hello can't find cipher suite 0x%X\n", ssl->session.cipher); + goto no_cipher; + } + + ssl->state |= SSL_CIPHER; + ssl_debug_printf("dissect_ssl3_hnd_srv_hello found CIPHER 0x%04X -> state 0x%02X\n", +- ssl->cipher, ssl->state); ++ ssl->session.cipher, ssl->state); + + /* if we have restored a session now we can have enough material + * to build session key, check it out*/ +@@ -2867,7 +2863,7 @@ no_cipher: + + if (ssl) { + /* store selected compression method for decryption */ +- ssl->compression = tvb_get_guint8(tvb, offset); ++ ssl->session.compression = tvb_get_guint8(tvb, offset); + } + /* and the server-selected compression method */ + proto_tree_add_item(tree, hf_ssl_handshake_comp_method, +@@ -2975,7 +2971,7 @@ dissect_ssl3_hnd_cert(tvbuff_t *tvb, + static void + dissect_ssl3_hnd_cert_req(tvbuff_t *tvb, + proto_tree *tree, guint32 offset, packet_info *pinfo, +- const guint *conv_version) ++ SslSession *session) + { + /* + * enum { +@@ -3066,7 +3062,7 @@ dissect_ssl3_hnd_cert_req(tvbuff_t *tvb, + } + } + +- switch (*conv_version) { ++ switch (session->version) { + case SSL_VER_TLSv1DOT2: + sh_alg_length = tvb_get_ntohs(tvb, offset); + proto_tree_add_uint(tree, hf_ssl_handshake_sig_hash_alg_len, +@@ -3170,74 +3166,77 @@ dissect_ssl3_hnd_cert_req(tvbuff_t *tvb, + } + + static void ++dissect_ssl3_hnd_srv_keyex_sig(tvbuff_t *tvb, proto_tree *tree, ++ guint32 offset, SslSession *session) ++{ ++ gint sig_len; ++ proto_item *ti_algo; ++ proto_tree *ssl_algo_tree; ++ ++ switch (session->version) { ++ case SSL_VER_TLSv1DOT2: ++ case SSL_VER_DTLS1DOT2: ++ ti_algo = proto_tree_add_item(tree, hf_ssl_handshake_sig_hash_alg, tvb, ++ offset, 2, ENC_BIG_ENDIAN); ++ ssl_algo_tree = proto_item_add_subtree(ti_algo, ett_ssl_sig_hash_alg); ++ ++ /* SignatureAndHashAlgorithm { hash, signature } */ ++ proto_tree_add_item(ssl_algo_tree, hf_ssl_handshake_sig_hash_hash, tvb, ++ offset, 1, ENC_BIG_ENDIAN); ++ proto_tree_add_item(ssl_algo_tree, hf_ssl_handshake_sig_hash_sig, tvb, ++ offset + 1, 1, ENC_BIG_ENDIAN); ++ offset += 2; ++ break; ++ ++ default: ++ break; ++ } ++ ++ /* Sig */ ++ sig_len = tvb_get_ntohs(tvb, offset); ++ proto_tree_add_item(tree, hf_ssl_handshake_server_keyex_sig_len, tvb, ++ offset, 2, ENC_BIG_ENDIAN); ++ proto_tree_add_item(tree, hf_ssl_handshake_server_keyex_sig, tvb, ++ offset + 2, sig_len, ENC_NA); ++} ++ ++static void + dissect_ssl3_hnd_srv_keyex_ecdh(tvbuff_t *tvb, proto_tree *tree, +- guint32 offset, guint32 length) ++ guint32 offset, guint32 length, ++ SslSession *session) + { +- gint curve_type, curve_type_offset; +- gint named_curve, named_curve_offset; +- gint point_len, point_len_offset; +- gint sig_len, sig_len_offset; ++ gint curve_type; ++ gint point_len; + proto_item *ti_ecdh; + proto_tree *ssl_ecdh_tree; +- guint32 orig_offset; + +- orig_offset = offset; ++ ti_ecdh = proto_tree_add_text(tree, tvb, offset, length, ++ "EC Diffie-Hellman Server Params"); ++ ssl_ecdh_tree = proto_item_add_subtree(ti_ecdh, ett_ssl_keyex_params); + +- curve_type_offset = offset; ++ /* curve_type */ + curve_type = tvb_get_guint8(tvb, offset); ++ proto_tree_add_item(ssl_ecdh_tree, hf_ssl_handshake_server_keyex_curve_type, tvb, ++ offset, 1, ENC_BIG_ENDIAN); ++ offset++; + if (curve_type != 3) + return; /* only named_curves are supported */ +- offset += 1; +- if ((offset - orig_offset) > length) { +- return; +- } + +- named_curve_offset = offset; +- named_curve = tvb_get_ntohs(tvb, offset); ++ /* case curve_type == named_curve; namedcurve */ ++ proto_tree_add_item(ssl_ecdh_tree, hf_ssl_handshake_server_keyex_named_curve, tvb, ++ offset, 2, ENC_BIG_ENDIAN); + offset += 2; +- if ((offset - orig_offset) > length) { +- return; +- } + +- point_len_offset = offset; ++ /* point */ + point_len = tvb_get_guint8(tvb, offset); +- if ((offset + point_len - orig_offset) > length) { +- return; +- } ++ proto_tree_add_item(ssl_ecdh_tree, hf_ssl_handshake_server_keyex_point_len, tvb, ++ offset, 1, ENC_BIG_ENDIAN); ++ proto_tree_add_item(ssl_ecdh_tree, hf_ssl_handshake_server_keyex_point, tvb, ++ offset + 1, point_len, ENC_NA); + offset += 1 + point_len; + +- sig_len_offset = offset; +- sig_len = tvb_get_ntohs(tvb, offset); +- offset += 2 + sig_len; +- if ((offset - orig_offset) != length) { +- /* Lengths don't line up (wasn't what we expected?) */ +- return; +- } +- +- ti_ecdh = proto_tree_add_text(tree, tvb, orig_offset, +- (offset - orig_offset), "EC Diffie-Hellman Server Params"); +- ssl_ecdh_tree = proto_item_add_subtree(ti_ecdh, ett_ssl_keyex_params); +- +- /* curve_type */ +- proto_tree_add_uint(ssl_ecdh_tree, hf_ssl_handshake_server_keyex_curve_type, +- tvb, curve_type_offset, 1, curve_type); +- +- /* named_curve */ +- proto_tree_add_uint(ssl_ecdh_tree, hf_ssl_handshake_server_keyex_named_curve, +- tvb, named_curve_offset, 2, named_curve); +- +- /* point */ +- proto_tree_add_uint(ssl_ecdh_tree, hf_ssl_handshake_server_keyex_point_len, +- tvb, point_len_offset, 1, point_len); +- proto_tree_add_item(ssl_ecdh_tree, hf_ssl_handshake_server_keyex_point, +- tvb, point_len_offset+1, point_len, ENC_NA); +- +- /* Sig */ +- proto_tree_add_uint(ssl_ecdh_tree, hf_ssl_handshake_server_keyex_sig_len, +- tvb, sig_len_offset, 2, sig_len); +- proto_tree_add_item(ssl_ecdh_tree, hf_ssl_handshake_server_keyex_sig, +- tvb, sig_len_offset + 2, sig_len, ENC_NA); +- ++ /* signature */ ++ dissect_ssl3_hnd_srv_keyex_sig(tvb, ssl_ecdh_tree, offset, session); + } + + static void +@@ -3271,139 +3270,80 @@ dissect_ssl3_hnd_cli_keyex_ecdh(tvbuff_t *tvb, proto_tree *tree, + } + + static void +-dissect_ssl3_hnd_srv_keyex_dh(tvbuff_t *tvb, proto_tree *tree, +- guint32 offset, guint32 length) ++dissect_ssl3_hnd_srv_keyex_dhe(tvbuff_t *tvb, proto_tree *tree, ++ guint32 offset, guint32 length, ++ SslSession *session) + { +- gint p_len, p_len_offset; +- gint g_len, g_len_offset; +- gint ys_len, ys_len_offset; +- gint sig_len, sig_len_offset; ++ gint p_len, g_len, ys_len; + proto_item *ti_dh; + proto_tree *ssl_dh_tree; +- guint32 orig_offset; + +- orig_offset = offset; ++ ti_dh = proto_tree_add_text(tree, tvb, offset, length, ++ "Diffie-Hellman Server Params"); ++ ssl_dh_tree = proto_item_add_subtree(ti_dh, ett_ssl_keyex_params); + +- p_len_offset = offset; ++ /* p */ + p_len = tvb_get_ntohs(tvb, offset); ++ proto_tree_add_item(ssl_dh_tree, hf_ssl_handshake_server_keyex_p_len, tvb, ++ offset, 2, ENC_BIG_ENDIAN); ++ proto_tree_add_item(ssl_dh_tree, hf_ssl_handshake_server_keyex_p, tvb, ++ offset + 2, p_len, ENC_NA); + offset += 2 + p_len; +- if ((offset - orig_offset) > length) { +- return; +- } + +- g_len_offset = offset; ++ /* g */ + g_len = tvb_get_ntohs(tvb, offset); ++ proto_tree_add_item(ssl_dh_tree, hf_ssl_handshake_server_keyex_g_len, tvb, ++ offset, 2, ENC_BIG_ENDIAN); ++ proto_tree_add_item(ssl_dh_tree, hf_ssl_handshake_server_keyex_g, tvb, ++ offset + 2, g_len, ENC_NA); + offset += 2 + g_len; +- if ((offset - orig_offset) > length) { +- return; +- } + +- ys_len_offset = offset; ++ /* Ys */ + ys_len = tvb_get_ntohs(tvb, offset); ++ proto_tree_add_uint(ssl_dh_tree, hf_ssl_handshake_server_keyex_ys_len, tvb, ++ offset, 2, ys_len); ++ proto_tree_add_item(ssl_dh_tree, hf_ssl_handshake_server_keyex_ys, tvb, ++ offset + 2, ys_len, ENC_NA); + offset += 2 + ys_len; +- if ((offset - orig_offset) > length) { +- return; +- } +- +- sig_len_offset = offset; +- sig_len = tvb_get_ntohs(tvb, offset); +- offset += 2 + sig_len; +- if ((offset - orig_offset) != length) { +- /* Lengths don't line up (wasn't what we expected?) */ +- return; +- } +- +- ti_dh = proto_tree_add_text(tree, tvb, orig_offset, +- (offset - orig_offset), "Diffie-Hellman Server Params"); +- ssl_dh_tree = proto_item_add_subtree(ti_dh, ett_ssl_keyex_params); +- +- /* p */ +- proto_tree_add_uint(ssl_dh_tree, hf_ssl_handshake_server_keyex_p_len, +- tvb, p_len_offset, 2, p_len); +- proto_tree_add_item(ssl_dh_tree, hf_ssl_handshake_server_keyex_p, +- tvb, p_len_offset + 2, p_len, ENC_NA); +- +- /* g */ +- proto_tree_add_uint(ssl_dh_tree, hf_ssl_handshake_server_keyex_g_len, +- tvb, g_len_offset, 2, g_len); +- proto_tree_add_item(ssl_dh_tree, hf_ssl_handshake_server_keyex_g, +- tvb, g_len_offset + 2, g_len, ENC_NA); +- +- /* Ys */ +- proto_tree_add_uint(ssl_dh_tree, hf_ssl_handshake_server_keyex_ys_len, +- tvb, ys_len_offset, 2, ys_len); +- proto_tree_add_item(ssl_dh_tree, hf_ssl_handshake_server_keyex_ys, +- tvb, ys_len_offset + 2, ys_len, ENC_NA); +- +- /* Sig */ +- proto_tree_add_uint(ssl_dh_tree, hf_ssl_handshake_server_keyex_sig_len, +- tvb, sig_len_offset, 2, sig_len); +- proto_tree_add_item(ssl_dh_tree, hf_ssl_handshake_server_keyex_sig, +- tvb, sig_len_offset + 2, sig_len, ENC_NA); + ++ /* signature */ ++ dissect_ssl3_hnd_srv_keyex_sig(tvb, ssl_dh_tree, offset, session); + } + + /* Only used in RSA-EXPORT cipher suites */ + static void + dissect_ssl3_hnd_srv_keyex_rsa(tvbuff_t *tvb, proto_tree *tree, +- guint32 offset, guint32 length) ++ guint32 offset, guint32 length, ++ SslSession *session) + { +- gint modulus_len, modulus_len_offset; +- gint exponent_len, exponent_len_offset; +- gint sig_len, sig_len_offset; ++ gint modulus_len, exponent_len; + proto_item *ti_rsa; + proto_tree *ssl_rsa_tree; +- guint32 orig_offset; +- +- orig_offset = offset; +- +- modulus_len_offset = offset; +- modulus_len = tvb_get_ntohs(tvb, offset); +- offset += 2 + modulus_len; +- if ((offset - orig_offset) > length) { +- return; +- } +- +- exponent_len_offset = offset; +- exponent_len = tvb_get_ntohs(tvb, offset); +- offset += 2 + exponent_len; +- if ((offset - orig_offset) > length) { +- return; +- } +- +- sig_len_offset = offset; +- sig_len = tvb_get_ntohs(tvb, offset); +- offset += 2 + sig_len; +- if ((offset - orig_offset) != length) { +- /* Lengths don't line up (wasn't what we expected?) */ +- return; +- } + +- ti_rsa = proto_tree_add_text(tree, tvb, orig_offset, +- (offset - orig_offset), "RSA-EXPORT Server Params"); ++ ti_rsa = proto_tree_add_text(tree, tvb, offset, length, ++ "RSA_EXPORT Server Params"); + ssl_rsa_tree = proto_item_add_subtree(ti_rsa, ett_ssl_keyex_params); + + /* modulus */ +- proto_tree_add_uint(ssl_rsa_tree, hf_ssl_handshake_server_keyex_modulus_len, +- tvb, modulus_len_offset, 2, modulus_len); ++ modulus_len = tvb_get_ntohs(tvb, offset); ++ proto_tree_add_item(ssl_rsa_tree, hf_ssl_handshake_server_keyex_modulus_len, ++ tvb, offset, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(ssl_rsa_tree, hf_ssl_handshake_server_keyex_modulus, +- tvb, modulus_len_offset + 2, modulus_len, ENC_NA); ++ tvb, offset + 2, modulus_len, ENC_NA); ++ offset += 2 + modulus_len; + + /* exponent */ +- proto_tree_add_uint(ssl_rsa_tree, hf_ssl_handshake_server_keyex_exponent_len, +- tvb, exponent_len_offset, 2, exponent_len); ++ exponent_len = tvb_get_ntohs(tvb, offset); ++ proto_tree_add_item(ssl_rsa_tree, hf_ssl_handshake_server_keyex_exponent_len, ++ tvb, offset, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(ssl_rsa_tree, hf_ssl_handshake_server_keyex_exponent, +- tvb, exponent_len_offset + 2, exponent_len, ENC_NA); +- +- /* Sig */ +- proto_tree_add_uint(ssl_rsa_tree, hf_ssl_handshake_server_keyex_sig_len, +- tvb, sig_len_offset, 2, sig_len); +- proto_tree_add_item(ssl_rsa_tree, hf_ssl_handshake_server_keyex_sig, +- tvb, sig_len_offset + 2, sig_len, ENC_NA); ++ tvb, offset + 2, exponent_len, ENC_NA); ++ offset += 2 + exponent_len; + ++ /* signature */ ++ dissect_ssl3_hnd_srv_keyex_sig(tvb, ssl_rsa_tree, offset, session); + } + +- + static void + dissect_ssl3_hnd_cli_keyex_dh(tvbuff_t *tvb, proto_tree *tree, + guint32 offset, guint32 length) +@@ -3468,7 +3408,7 @@ dissect_ssl3_hnd_cli_keyex_rsa(tvbuff_t *tvb, proto_tree *tree, + static void + dissect_ssl3_hnd_finished(tvbuff_t *tvb, + proto_tree *tree, const guint32 offset, +- const guint *conv_version) ++ SslSession *session) + { + /* For TLS: + * struct { +@@ -3488,7 +3428,7 @@ dissect_ssl3_hnd_finished(tvbuff_t *tvb, + return; + } + +- switch (*conv_version) { ++ switch (session->version) { + case SSL_VER_TLS: + case SSL_VER_TLSv1DOT1: + case SSL_VER_TLSv1DOT2: +@@ -3568,7 +3508,7 @@ dissect_ssl3_hnd_cert_status(tvbuff_t *tvb, proto_tree *tree, + /* record layer dissector */ + static gint + dissect_ssl2_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, +- guint32 offset, guint *conv_version, ++ guint32 offset, SslSession *session, + gboolean *need_desegmentation, + SslDecryptSession *ssl, gboolean first_record_in_frame) + { +@@ -3684,19 +3624,19 @@ dissect_ssl2_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + /* if we get a server_hello or later handshake in v2, then set + * this to sslv2 + */ +- if (*conv_version == SSL_VER_UNKNOWN) ++ if (session->version == SSL_VER_UNKNOWN) + { + if (ssl_looks_like_valid_pct_handshake(tvb, + (initial_offset + + record_length_length), + record_length)) { +- *conv_version = SSL_VER_PCT; +- /*ssl_set_conv_version(pinfo, ssl->version);*/ ++ session->version = SSL_VER_PCT; ++ /*ssl_set_conv_version(pinfo, ssl->session.version);*/ + } + else if (msg_type >= 2 && msg_type <= 8) + { +- *conv_version = SSL_VER_SSLv2; +- /*ssl_set_conv_version(pinfo, ssl->version);*/ ++ session->version = SSL_VER_SSLv2; ++ /*ssl_set_conv_version(pinfo, ssl->session.version);*/ + } + } + +@@ -3705,20 +3645,20 @@ dissect_ssl2_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + * (e.g., on a client hello) + */ + col_set_str(pinfo->cinfo, COL_PROTOCOL, +- (*conv_version == SSL_VER_PCT) ? "PCT" : "SSLv2"); ++ (session->version == SSL_VER_PCT) ? "PCT" : "SSLv2"); + + /* see if the msg_type is valid; if not the payload is + * probably encrypted, so note that fact and bail + */ + msg_type_str = try_val_to_str(msg_type, +- (*conv_version == SSL_VER_PCT) ++ (session->version == SSL_VER_PCT) + ? pct_msg_types : ssl_20_msg_types); + if (!msg_type_str +- || ((*conv_version != SSL_VER_PCT) && ++ || ((session->version != SSL_VER_PCT) && + !ssl_looks_like_valid_v2_handshake(tvb, initial_offset + + record_length_length, + record_length)) +- || ((*conv_version == SSL_VER_PCT) && ++ || ((session->version == SSL_VER_PCT) && + !ssl_looks_like_valid_pct_handshake(tvb, initial_offset + + record_length_length, + record_length))) +@@ -3726,7 +3666,7 @@ dissect_ssl2_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + if (ssl_record_tree) + { + proto_item_set_text(ssl_record_tree, "%s Record Layer: %s", +- (*conv_version == SSL_VER_PCT) ++ (session->version == SSL_VER_PCT) + ? "PCT" : "SSLv2", + "Encrypted Data"); + +@@ -3751,7 +3691,7 @@ dissect_ssl2_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + if (ssl_record_tree) + { + proto_item_set_text(ssl_record_tree, "%s Record Layer: %s", +- (*conv_version == SSL_VER_PCT) ++ (session->version == SSL_VER_PCT) + ? "PCT" : "SSLv2", + msg_type_str); + } +@@ -3804,13 +3744,13 @@ dissect_ssl2_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, + if (ssl_record_tree) + { + proto_tree_add_item(ssl_record_tree, +- (*conv_version == SSL_VER_PCT) ++ (session->version == SSL_VER_PCT) + ? hf_pct_msg_type : hf_ssl2_msg_type, + tvb, offset, 1, ENC_BIG_ENDIAN); + } + offset += 1; /* move past msg_type byte */ + +- if (*conv_version != SSL_VER_PCT) ++ if (session->version != SSL_VER_PCT) + { + /* dissect the message (only handle client hello right now) */ + switch (msg_type) { +@@ -4580,7 +4520,7 @@ void ssl_set_master_secret(guint32 frame_num, address *addr_srv, address *addr_c + } else { + ssl = (SslDecryptSession *)se_alloc0(sizeof(SslDecryptSession)); + ssl_session_init(ssl); +- ssl->version = SSL_VER_UNKNOWN; ++ ssl->session.version = SSL_VER_UNKNOWN; + conversation_add_proto_data(conversation, proto_ssl, ssl); + } + +@@ -4589,31 +4529,31 @@ void ssl_set_master_secret(guint32 frame_num, address *addr_srv, address *addr_c + ssl_set_server(ssl, addr_srv, ptype, port_srv); + + /* version */ +- if ((ssl->version==SSL_VER_UNKNOWN) && (version!=SSL_VER_UNKNOWN)) { ++ if ((ssl->session.version==SSL_VER_UNKNOWN) && (version!=SSL_VER_UNKNOWN)) { + switch (version) { + case SSL_VER_SSLv3: +- ssl->version = SSL_VER_SSLv3; ++ ssl->session.version = SSL_VER_SSLv3; + ssl->version_netorder = SSLV3_VERSION; + ssl->state |= SSL_VERSION; + ssl_debug_printf("ssl_set_master_secret set version 0x%04X -> state 0x%02X\n", ssl->version_netorder, ssl->state); + break; + + case SSL_VER_TLS: +- ssl->version = SSL_VER_TLS; ++ ssl->session.version = SSL_VER_TLS; + ssl->version_netorder = TLSV1_VERSION; + ssl->state |= SSL_VERSION; + ssl_debug_printf("ssl_set_master_secret set version 0x%04X -> state 0x%02X\n", ssl->version_netorder, ssl->state); + break; + + case SSL_VER_TLSv1DOT1: +- ssl->version = SSL_VER_TLSv1DOT1; ++ ssl->session.version = SSL_VER_TLSv1DOT1; + ssl->version_netorder = TLSV1DOT1_VERSION; + ssl->state |= SSL_VERSION; + ssl_debug_printf("ssl_set_master_secret set version 0x%04X -> state 0x%02X\n", ssl->version_netorder, ssl->state); + break; + + case SSL_VER_TLSv1DOT2: +- ssl->version = SSL_VER_TLSv1DOT2; ++ ssl->session.version = SSL_VER_TLSv1DOT2; + ssl->version_netorder = TLSV1DOT2_VERSION; + ssl->state |= SSL_VERSION; + ssl_debug_printf("ssl_set_master_secret set version 0x%04X -> state 0x%02X\n", ssl->version_netorder, ssl->state); +@@ -4623,12 +4563,12 @@ void ssl_set_master_secret(guint32 frame_num, address *addr_srv, address *addr_c + + /* cipher */ + if (cipher > 0) { +- ssl->cipher = cipher; +- if (ssl_find_cipher(ssl->cipher,&ssl->cipher_suite) < 0) { +- ssl_debug_printf("ssl_set_master_secret can't find cipher suite 0x%X\n", ssl->cipher); ++ ssl->session.cipher = cipher; ++ if (ssl_find_cipher(ssl->session.cipher,&ssl->cipher_suite) < 0) { ++ ssl_debug_printf("ssl_set_master_secret can't find cipher suite 0x%X\n", ssl->session.cipher); + } else { + ssl->state |= SSL_CIPHER; +- ssl_debug_printf("ssl_set_master_secret set CIPHER 0x%04X -> state 0x%02X\n", ssl->cipher, ssl->state); ++ ssl_debug_printf("ssl_set_master_secret set CIPHER 0x%04X -> state 0x%02X\n", ssl->session.cipher, ssl->state); + } + } + diff --git a/SOURCES/wireshark-1.10.6-CVE-2014-2281.patch b/SOURCES/wireshark-1.10.6-CVE-2014-2281.patch deleted file mode 100644 index 32bf3b1..0000000 --- a/SOURCES/wireshark-1.10.6-CVE-2014-2281.patch +++ /dev/null @@ -1,41 +0,0 @@ -diff --git a/epan/dissectors/packet-nfs.c b/epan/dissectors/packet-nfs.c -index 414e928..eb005e0 100644 ---- a/epan/dissectors/packet-nfs.c -+++ b/epan/dissectors/packet-nfs.c -@@ -950,24 +950,31 @@ nfs_name_snoop_add_name(int xid, tvbuff_t *tvb, int name_offset, int name_len, i - nfs_name_snoop_t *nns, *old_nns; - const char *ptr=NULL; - -+ if (name_len <= 0) { -+ /* Do we need some way to signal an error here? This could be -+ * programmatic or just a corrupt packet, depending on the -+ * caller... */ -+ return; -+ } -+ - /* filter out all '.' and '..' names */ - if(!name){ - ptr=(const char *)tvb_get_ptr(tvb, name_offset, name_len); - } else { - ptr=name; - } -- if(ptr[0]=='.'){ -- if(ptr[1]==0){ -+ if (ptr[0] == '.') { -+ if (name_len <= 1 || ptr[1] == 0) { - return; - } -- if(ptr[1]=='.'){ -- if(ptr[2]==0){ -+ if (ptr[1] == '.') { -+ if (name_len <= 2 || ptr[2] == 0) { - return; - } - } - } - -- nns=(nfs_name_snoop_t *)g_malloc(sizeof(nfs_name_snoop_t)); -+ nns = g_new(nfs_name_snoop_t, 1); - - nns->fh_length=0; - nns->fh=NULL; diff --git a/SOURCES/wireshark-1.10.6-CVE-2014-2282.patch b/SOURCES/wireshark-1.10.6-CVE-2014-2282.patch deleted file mode 100644 index 6b3441c..0000000 --- a/SOURCES/wireshark-1.10.6-CVE-2014-2282.patch +++ /dev/null @@ -1,29 +0,0 @@ -diff --git a/epan/dissectors/packet-m3ua.c b/epan/dissectors/packet-m3ua.c -index 5ad56a3..f0f96dc 100644 ---- a/epan/dissectors/packet-m3ua.c -+++ b/epan/dissectors/packet-m3ua.c -@@ -39,7 +39,7 @@ - #include - #include - #include --#include -+#include - #include "packet-mtp3.h" - #include "packet-sccp.h" - #include "packet-frame.h" -@@ -1160,12 +1160,14 @@ dissect_protocol_data_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, pro - guint16 ulp_length; - tvbuff_t *payload_tvb; - proto_item *item, *gen_item; -- mtp3_tap_rec_t* mtp3_tap = ep_new0(mtp3_tap_rec_t); -+ mtp3_tap_rec_t* mtp3_tap; - proto_tree *q708_tree; - gint heuristic_standard; - guint8 si; - guint32 opc, dpc; - -+ mtp3_tap = wmem_new0(pinfo->pool, mtp3_tap_rec_t); -+ - si = tvb_get_guint8(parameter_tvb, DATA_SI_OFFSET); - ulp_length = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH - DATA_HDR_LENGTH; - payload_tvb = tvb_new_subset(parameter_tvb, DATA_ULP_OFFSET, ulp_length, ulp_length); diff --git a/SOURCES/wireshark-1.10.6-CVE-2014-2283.patch b/SOURCES/wireshark-1.10.6-CVE-2014-2283.patch deleted file mode 100644 index b5aa80a..0000000 --- a/SOURCES/wireshark-1.10.6-CVE-2014-2283.patch +++ /dev/null @@ -1,48 +0,0 @@ -diff --git a/epan/dissectors/packet-rlc.c b/epan/dissectors/packet-rlc.c -index 32f6b6f..1715be4 100644 ---- a/epan/dissectors/packet-rlc.c -+++ b/epan/dissectors/packet-rlc.c -@@ -413,7 +413,7 @@ rlc_sdu_create(void) - { - struct rlc_sdu *sdu; - -- sdu = (struct rlc_sdu *)se_alloc0(sizeof(struct rlc_sdu)); -+ sdu = (struct rlc_sdu *)g_malloc0(sizeof(struct rlc_sdu)); - return sdu; - } - -@@ -474,7 +474,7 @@ rlc_frag_create(tvbuff_t *tvb, enum rlc_mode mode, packet_info *pinfo, - { - struct rlc_frag *frag; - -- frag = (struct rlc_frag *)se_alloc0(sizeof(struct rlc_frag)); -+ frag = (struct rlc_frag *)g_malloc0(sizeof(struct rlc_frag)); - rlc_frag_assign(frag, mode, pinfo, seq, li); - rlc_frag_assign_data(frag, tvb, offset, length); - -@@ -518,6 +518,7 @@ free_sequence_table_entry_data(gpointer data) - g_list_free(list->list); - list->list = NULL; /* for good measure */ - } -+ g_free(list); - } - - /** Utility functions used for various comparions/cleanups in tree **/ -@@ -875,7 +876,7 @@ get_frags(packet_info * pinfo, struct rlc_channel * ch_lookup) - } else if (pinfo != NULL) { - struct rlc_channel *ch; - ch = rlc_channel_create(ch_lookup->mode, pinfo); -- frags = (struct rlc_frag **)se_alloc0(sizeof(struct rlc_frag *) * 4096); -+ frags = (struct rlc_frag **)g_malloc0(sizeof(struct rlc_frag *) * 4096); - g_hash_table_insert(fragment_table, ch, frags); - } else { - return NULL; -@@ -1227,7 +1228,7 @@ rlc_is_duplicate(enum rlc_mode mode, packet_info *pinfo, guint16 seq, - list = (struct rlc_seqlist *)g_hash_table_lookup(sequence_table, &lookup.ch); - if (!list) { - /* we see this channel for the first time */ -- list = (struct rlc_seqlist *)se_alloc0(sizeof(*list)); -+ list = (struct rlc_seqlist *)g_malloc0(sizeof(*list)); - rlc_channel_assign(&list->ch, mode, pinfo); - g_hash_table_insert(sequence_table, &list->ch, list); - } diff --git a/SOURCES/wireshark-1.10.6-CVE-2014-2299.patch b/SOURCES/wireshark-1.10.6-CVE-2014-2299.patch deleted file mode 100644 index 171caa2..0000000 --- a/SOURCES/wireshark-1.10.6-CVE-2014-2299.patch +++ /dev/null @@ -1,32 +0,0 @@ -diff --git a/wiretap/mpeg.c b/wiretap/mpeg.c -index 1500162..bd3ab24 100644 ---- a/wiretap/mpeg.c -+++ b/wiretap/mpeg.c -@@ -111,7 +111,7 @@ mpeg_read_rec_data(FILE_T fh, guint8 *pd, int length, int *err, - - #define SCRHZ 27000000 - --static gboolean -+static gboolean - mpeg_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) - { - mpeg_t *mpeg = (mpeg_t *)wth->priv; -@@ -225,6 +225,18 @@ mpeg_read(wtap *wth, int *err, gchar **err_info, gint64 *data_offset) - } - *data_offset = file_tell(wth->fh); - -+ if (packet_size > WTAP_MAX_PACKET_SIZE) { -+ /* -+ * Larger than we can handle. Don't blow up trying -+ * to allocate space for an immensely-large packet -+ * or clobber the stack. -+ */ -+ *err = WTAP_ERR_BAD_FILE; -+ *err_info = g_strdup_printf("mpeg: File has %u-byte packet, bigger than maximum of %u", -+ packet_size, WTAP_MAX_PACKET_SIZE); -+ return FALSE; -+ } -+ - buffer_assure_space(wth->frame_buffer, packet_size); - if (!mpeg_read_rec_data(wth->fh, buffer_start_ptr(wth->frame_buffer), - packet_size, err, err_info)) diff --git a/SOURCES/wireshark-1.10.x-disable-warning-dialog.patch b/SOURCES/wireshark-1.10.x-disable-warning-dialog.patch index 7eb937e..6d1c0cc 100644 --- a/SOURCES/wireshark-1.10.x-disable-warning-dialog.patch +++ b/SOURCES/wireshark-1.10.x-disable-warning-dialog.patch @@ -2,7 +2,7 @@ diff --git a/ui/gtk/main.c b/ui/gtk/main.c index 82cff80..0137c3b 100644 --- a/ui/gtk/main.c +++ b/ui/gtk/main.c -@@ -2040,50 +2040,6 @@ read_configuration_files(char **gdp_path, char **dp_path) +@@ -2043,50 +2043,6 @@ read_configuration_files(char **gdp_path, char **dp_path) return prefs_p; } @@ -53,7 +53,7 @@ index 82cff80..0137c3b 100644 /* And now our feature presentation... [ fade to music ] */ int main(int argc, char *argv[]) -@@ -3030,7 +2986,6 @@ main(int argc, char *argv[]) +@@ -3039,7 +2995,6 @@ main(int argc, char *argv[]) up on top of us. */ if (cf_name) { show_main_window(TRUE); @@ -61,7 +61,7 @@ index 82cff80..0137c3b 100644 if (rfilter != NULL) { if (!dfilter_compile(rfilter, &rfcode)) { bad_dfilter_alert_box(top_level, rfilter); -@@ -3108,7 +3063,6 @@ main(int argc, char *argv[]) +@@ -3117,7 +3072,6 @@ main(int argc, char *argv[]) dfilter_free(rfcode); cfile.rfcode = NULL; show_main_window(FALSE); @@ -69,7 +69,7 @@ index 82cff80..0137c3b 100644 main_set_for_capture_in_progress(FALSE); set_capture_if_dialog_for_capture_in_progress(FALSE); } -@@ -3125,7 +3079,6 @@ main(int argc, char *argv[]) +@@ -3134,7 +3088,6 @@ main(int argc, char *argv[]) } /* "-k" was specified; start a capture. */ show_main_window(FALSE); @@ -77,7 +77,7 @@ index 82cff80..0137c3b 100644 /* If no user interfaces were specified on the command line, copy the list of selected interfaces to the set of interfaces -@@ -3143,7 +3096,6 @@ main(int argc, char *argv[]) +@@ -3152,7 +3105,6 @@ main(int argc, char *argv[]) } } else { show_main_window(FALSE); @@ -85,7 +85,7 @@ index 82cff80..0137c3b 100644 main_set_for_capture_in_progress(FALSE); set_capture_if_dialog_for_capture_in_progress(FALSE); } -@@ -3154,7 +3106,6 @@ main(int argc, char *argv[]) +@@ -3163,7 +3115,6 @@ main(int argc, char *argv[]) } #else /* HAVE_LIBPCAP */ show_main_window(FALSE); diff --git a/SOURCES/wireshark-1.10.x-ftbfs-glib2.patch b/SOURCES/wireshark-1.10.x-ftbfs-glib2.patch new file mode 100644 index 0000000..5fa4f75 --- /dev/null +++ b/SOURCES/wireshark-1.10.x-ftbfs-glib2.patch @@ -0,0 +1,31 @@ +diff --git a/CMakeLists.txt b/CMakeLists.txt +index e6b8e46..f308c12 100644 +--- a/CMakeLists.txt ++++ b/CMakeLists.txt +@@ -183,7 +183,6 @@ if(ENABLE_EXTRA_GCC_CHECKS) # This overrides -Werror + endif() + + add_definitions( +- -DG_DISABLE_DEPRECATED + -DG_DISABLE_SINGLE_INCLUDES + ) + +diff --git a/configure.ac b/configure.ac +index cf593db..4e2f0d2 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -1474,14 +1474,6 @@ then + fi + AC_SUBST(MOC) + +-# Error out if a glib header other than a "top level" header +-# (glib.h, glib-object.h, gio.h) or certain other headers( e.g.,gmodule.h) +-# is used. +-CPPFLAGS="-DG_DISABLE_SINGLE_INCLUDES $CPPFLAGS" +- +-# Error out on the usage of deprecated glib functions +-CPPFLAGS="-DG_DISABLE_DEPRECATED $CPPFLAGS" +- + # + # Check whether GLib modules are supported, to determine whether we + # can support plugins. diff --git a/SOURCES/wireshark-1.10.x-remove-last-data-source.patch b/SOURCES/wireshark-1.10.x-remove-last-data-source.patch index e55647e..e7533fd 100644 --- a/SOURCES/wireshark-1.10.x-remove-last-data-source.patch +++ b/SOURCES/wireshark-1.10.x-remove-last-data-source.patch @@ -2,7 +2,7 @@ diff --git a/epan/dissectors/packet-tcp.c b/epan/dissectors/packet-tcp.c index e9af5f8..d994233 100644 --- a/epan/dissectors/packet-tcp.c +++ b/epan/dissectors/packet-tcp.c -@@ -1922,6 +1922,7 @@ again: +@@ -1924,6 +1924,7 @@ again: * being a new higher-level PDU that also * needs desegmentation). */ diff --git a/SOURCES/wireshark-1.10.x-resolv-error-string.patch b/SOURCES/wireshark-1.10.x-resolv-error-string.patch index dcc87f0..8246302 100644 --- a/SOURCES/wireshark-1.10.x-resolv-error-string.patch +++ b/SOURCES/wireshark-1.10.x-resolv-error-string.patch @@ -2,7 +2,7 @@ diff --git a/tshark.c b/tshark.c index f930f9d..e3ac6c6 100644 --- a/tshark.c +++ b/tshark.c -@@ -289,7 +289,7 @@ print_usage(gboolean print_ver) +@@ -294,7 +294,7 @@ print_usage(gboolean print_ver) fprintf(output, " -R packet Read filter in Wireshark display filter syntax\n"); fprintf(output, " -Y packet displaY filter in Wireshark display filter syntax\n"); fprintf(output, " -n disable all name resolutions (def: all enabled)\n"); @@ -11,7 +11,7 @@ index f930f9d..e3ac6c6 100644 fprintf(output, " -d %s ...\n", decode_as_arg_template); fprintf(output, " \"Decode As\", see the man page for details\n"); fprintf(output, " Example: tcp.port==8888,http\n"); -@@ -1344,7 +1344,7 @@ main(int argc, char *argv[]) +@@ -1357,7 +1357,7 @@ main(int argc, char *argv[]) if (badopt != '\0') { cmdarg_err("-N specifies unknown resolving option '%c';", badopt); diff --git a/SOURCES/wireshark-1.6.1-group-msg.patch b/SOURCES/wireshark-1.6.1-group-msg.patch index 31af194..d24e7df 100644 --- a/SOURCES/wireshark-1.6.1-group-msg.patch +++ b/SOURCES/wireshark-1.6.1-group-msg.patch @@ -7,7 +7,7 @@ diff --git a/capture_sync.c b/capture_sync.c index 8c49ed2..65e242d 100644 --- a/capture_sync.c +++ b/capture_sync.c -@@ -368,6 +368,7 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session) +@@ -369,6 +369,7 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session) gchar *signal_pipe_name; #else char errmsg[1024+1]; @@ -15,7 +15,7 @@ index 8c49ed2..65e242d 100644 int sync_pipe[2]; /* pipe used to send messages from child to parent */ enum PIPES { PIPE_READ, PIPE_WRITE }; /* Constants 0 and 1 for PIPE_READ and PIPE_WRITE */ #endif -@@ -638,8 +639,10 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session) +@@ -639,8 +640,10 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session) dup2(sync_pipe[PIPE_WRITE], 2); ws_close(sync_pipe[PIPE_READ]); execv(argv[0], argv); @@ -28,7 +28,7 @@ index 8c49ed2..65e242d 100644 sync_pipe_errmsg_to_parent(2, errmsg, ""); /* Exit with "_exit()", so that we don't close the connection -@@ -731,6 +734,7 @@ sync_pipe_open_command(char** argv, int *data_read_fd, +@@ -732,6 +735,7 @@ sync_pipe_open_command(char** argv, int *data_read_fd, PROCESS_INFORMATION pi; #else char errmsg[1024+1]; @@ -36,7 +36,7 @@ index 8c49ed2..65e242d 100644 int sync_pipe[2]; /* pipe used to send messages from child to parent */ int data_pipe[2]; /* pipe used to send data from child to parent */ #endif -@@ -865,8 +869,10 @@ sync_pipe_open_command(char** argv, int *data_read_fd, +@@ -866,8 +870,10 @@ sync_pipe_open_command(char** argv, int *data_read_fd, ws_close(sync_pipe[PIPE_READ]); ws_close(sync_pipe[PIPE_WRITE]); execv(argv[0], argv); diff --git a/SPECS/wireshark.spec b/SPECS/wireshark.spec index 258c1f5..11f2f53 100644 --- a/SPECS/wireshark.spec +++ b/SPECS/wireshark.spec @@ -20,8 +20,8 @@ Summary: Network traffic analyzer Name: wireshark -Version: 1.10.3 -Release: 12%{?dist} +Version: 1.10.14 +Release: 7%{?dist} License: GPL+ Group: Applications/Internet Source0: http://wireshark.org/download/src/%{name}-%{version}.tar.bz2 @@ -43,22 +43,28 @@ Patch5: wireshark-1.8.x-dcom-string-overrun.patch Patch6: wireshark-1.10.0-CVE-2013-3557.patch Patch7: wireshark-1.10.x-disable-warning-dialog.patch Patch8: wireshark-1.10.x-resolv-error-string.patch -Patch9: wireshark-1.10.0-CVE-2013-7112.patch -Patch10: wireshark-1.10.0-CVE-2013-7113.patch -Patch11: wireshark-1.10.0-CVE-2013-7114.patch -Patch12: wireshark-1.10.x-remove-last-data-source.patch -Patch13: wireshark-1.10.6-CVE-2014-2281.patch -Patch14: wireshark-1.10.6-CVE-2014-2282.patch -Patch15: wireshark-1.10.6-CVE-2014-2283.patch -Patch16: wireshark-1.10.6-CVE-2014-2299.patch -Patch17: wireshark-1.10.10-CVE-2014-6421.patch -Patch18: wireshark-1.10.10-CVE-2014-6423.patch -Patch19: wireshark-1.10.10-CVE-2014-6424.patch -Patch20: wireshark-1.10.10-CVE-2014-6425.patch -Patch21: wireshark-1.10.10-CVE-2014-6426.patch -Patch22: wireshark-1.10.10-CVE-2014-6427.patch -Patch23: wireshark-1.10.10-CVE-2014-6428.patch -Patch24: wireshark-1.10.10-CVE-2014-6429.patch +Patch9: wireshark-1.10.x-remove-last-data-source.patch +Patch10: wireshark-1.10.x-ftbfs-glib2.patch +Patch11: wireshark-1.10.10-CVE-2014-6425.patch +Patch12: wireshark-1.10.10-CVE-2014-6426.patch +Patch13: wireshark-1.10.3-nanosecond-timestamps.patch +Patch14: wireshark-1.10.3-dtls-elliptic-curves.patch +Patch15: wireshark-1.10.3-tls-hash-algs.patch +Patch16: wireshark-1.10.3-tls-key-exchange-msgs.patch +Patch17: wireshark-1.10.3-tls-ext-master-secret.patch +Patch18: wireshark-1.10.3-tls-ext-encrypt-then-mac.patch +Patch19: wireshark-1.10.14-tls-cert-verify-msgs.patch +Patch20: wireshark-1.10.14-CVE-2015-3810.patch +Patch21: wireshark-1.10.14-CVE-2015-3813.patch +Patch22: wireshark-1.10.14-CVE-2015-6243.patch +Patch23: wireshark-1.10.14-tvbuff.patch +# Depends on Patch23 +Patch24: wireshark-1.10.14-CVE-2015-6244.patch +Patch25: wireshark-1.10.14-CVE-2015-6245.patch +Patch26: wireshark-1.10.14-CVE-2015-6246.patch +Patch27: wireshark-1.10.14-CVE-2015-6248.patch +Patch28: wireshark-1.10.14-gdk-pixbuf-deprecated-segfault.patch +Patch29: wireshark-1.10.14-CVE-2015-3182.patch Url: http://www.wireshark.org/ BuildRequires: libpcap-devel >= 0.9 @@ -159,22 +165,27 @@ and plugins. %patch6 -p1 -b .cve-2013-3557 %patch7 -p1 -b .disable-warning-dialog %patch8 -p1 -b .resolv-error-string -%patch9 -p1 -b .cve-2013-7112 -%patch10 -p1 -b .cve-2013-7113 -%patch11 -p1 -b .cve-2013-7114 -%patch12 -p1 -b .remove-last-data-source -%patch13 -p1 -b .cve-2014-2281 -%patch14 -p1 -b .cve-2014-2282 -%patch15 -p1 -b .cve-2014-2283 -%patch16 -p1 -b .cve-2014-2299 -%patch17 -p1 -b .cve-2014-6421 -%patch18 -p1 -b .cve.2014-6423 -%patch19 -p1 -b .cve.2014-6424 -%patch20 -p1 -b .cve.2014-6425 -%patch21 -p1 -b .cve.2014-6426 -%patch22 -p1 -b .cve.2014-6427 -%patch23 -p1 -b .cve.2014-6428 -%patch24 -p1 -b .cve.2014-6429 +%patch9 -p1 -b .remove-last-data-source +%patch10 -p1 -b .ftbfs-glib2 +%patch11 -p1 -b .cve.2014-6425 +%patch12 -p1 -b .cve.2014-6426 +%patch13 -p1 -b .nanosecond-timestamps +%patch14 -p1 -b .dtls-elliptic-curves +%patch15 -p1 -b .tls-hash-algs +%patch16 -p1 -b .tls-key-exchange-msgs +%patch17 -p1 -b .tls-master-secret +%patch18 -p1 -b .tls-encrypt-then-mac +%patch19 -p1 -b .tls-cert-verify-msgs +%patch20 -p1 -b .cve-2015-3810 +%patch21 -p1 -b .cve-2015-3813 +%patch22 -p1 -b .cve-2015-6243 +%patch23 -p1 -b .tvbuff +%patch24 -p1 -b .cve-2015-6244 +%patch25 -p1 -b .cve-2015-6245 +%patch26 -p1 -b .cve-2015-6246 +%patch27 -p1 -b .cve-2015-6248 +%patch28 -p1 -b .gdk-deprecated +%patch29 -p1 -b .cve-2015-3182 %build %ifarch s390 s390x sparcv9 sparc64 @@ -183,9 +194,11 @@ export PIECFLAGS="-fPIE" export PIECFLAGS="-fpie" %endif +export RELRO="-Wl,-z,relro,-z,now" + # -fstack-protector-strong replaced -fstack-protector-all -export CFLAGS="$RPM_OPT_FLAGS $CPPFLAGS $PIECFLAGS -D_LARGEFILE64_SOURCE" -export CXXFLAGS="$RPM_OPT_FLAGS $CPPFLAGS $PIECFLAGS -D_LARGEFILE64_SOURCE" +export CFLAGS="$RPM_OPT_FLAGS $CPPFLAGS $PIECFLAGS $RELRO -D_LARGEFILE64_SOURCE" +export CXXFLAGS="$RPM_OPT_FLAGS $CPPFLAGS $PIECFLAGS $RELRO -D_LARGEFILE64_SOURCE" export LDFLAGS="$LDFLAGS -pie" # Temporary hack - wireshark-1.8.0 is not compilable with upstream @@ -414,11 +427,74 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : %{_datadir}/aclocal/* %changelog -* Mon Oct 13 2014 Peter Hatina - 1.10.3-12 +* Tue Oct 6 2015 Peter Hatina - 1.10.14-7 +- Rebase some tvbuff API from upstream to 1.10.14 +- Fixes crash when tvb_length_remaining() is used +- Related: CVE-2015-6244 + +* Mon Oct 5 2015 Peter Hatina - 1.10.14-6 +- Security patch +- Resolves: CVE-2015-3182 + +* Thu Oct 1 2015 Peter Hatina - 1.10.14-5 +- Fix crash caused by -DGDK_PIXBUF_DEPRECATED on startup +- Resolves: rhbz#1267959 + +* Tue Sep 22 2015 Peter Hatina - 1.10.14-4 +- Security patches +- Resolves: CVE-2015-6243 + CVE-2015-6244 + CVE-2015-6245 + CVE-2015-6246 + CVE-2015-6248 + +* Fri Aug 7 2015 Peter Hatina - 1.10.14-3 +- Security patches +- Resolves: CVE-2015-3810 + CVE-2015-3813 + +* Mon Jul 6 2015 Peter Hatina - 1.10.14-2 +- Add certificate verify message decoding in TLS extension +- Resolves: #1239150 + +* Thu Jul 2 2015 Peter Hatina - 1.10.14-1 +- Upgrade to 1.10.14 +- Resolves: #1238676 + +* Tue Jun 2 2015 Peter Hatina - 1.10.3-20 +- add master secret extension decoding in TLS extension +- add encrypt-then-mac extension decoding in TLS extension +- Resolves: #1222901 + +* Tue Jun 2 2015 Peter Hatina - 1.10.3-19 +- create pcap file if -F pcap specified +- Resolves: #1227199 + +* Wed May 20 2015 Peter Hatina - 1.10.3-18 +- add key exchange algorithms decoding in TLS extension +- Resolves: #1222600 + +* Mon May 18 2015 Peter Hatina - 1.10.3-17 +- add signature algorithms decoding in TLS extension +- Resolves: #1221701 + +* Wed May 6 2015 Peter Hatina - 1.10.3-16 +- add relro check +- Resolves: #1092532 + +* Tue Apr 21 2015 Peter Hatina - 1.10.3-15 +- add elliptic curves decoding in DTLS HELLO +- Resolves: #1131202 + +* Tue Apr 21 2015 Peter Hatina - 1.10.3-14 +- introduced nanosecond time precision +- Resolves: #1213339 + +* Mon Oct 13 2014 Peter Hatina - 1.10.3-13 - security patches -- Related: #1148266 +- Resolves: #1148267 -* Fri Oct 3 2014 Peter Hatina - 1.10.3-11 +* Fri Oct 3 2014 Peter Hatina - 1.10.3-12 - security patches - Resolves: CVE-2014-6421 CVE-2014-6423 @@ -429,6 +505,10 @@ gtk-update-icon-cache %{_datadir}/icons/hicolor &>/dev/null || : CVE-2014-6428 CVE-2014-6429 +* Thu Aug 28 2014 Peter Hatina - 1.10.3-11 +- fix FTBFS due to glib2-2.40 +- Resolves: #1132673 + * Mon Mar 10 2014 Peter Hatina - 1.10.3-10 - fix missing tshark's name resolving flag in help message - Related: #1004250