From fb21f52328f91c384232a74983b67da2c0abc832 Mon Sep 17 00:00:00 2001 From: Anders Broman Date: Tue, 30 Oct 2012 16:02:51 +0000 Subject: Copy over: Revision 43761 - Use same capitalization for Service request message as for other messages -------------------------------------------------------------------------------------- Revision 44082 - Fix a few Clang warnings (dead increment, dead assignment) -------------------------------------------------------------------------------------- Revision 44514 - bugfix minor memory leaks with GString use -------------------------------------------------------------------------------------- Revision 45046 - Test Procedures messages should be also integrity protected -------------------------------------------------------------------------------------- Revision 45267 - Use a value string array for EPS Bearer Identity and remove useless de_esm_lnkd_eps_bearer_id function -------------------------------------------------------------------------------------- Revision 45660 - Add back the "%!" removed in r33773; otherwise, for some unknown reason, only 1 page will be viewable. (Tested w/gsview 5.0 and ghostscript 9.06) #BACKPORT(1.8, 1.6) -------------------------------------------------------------------------------------- Revision 45614 - fix https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7869 make tpiLen a guint such that it can store 2 + tvb_get_guint8(...) without overflow -------------------------------------------------------------------------------------- Revision 45696 - From Sho Amano via https://www.wireshark.org/lists/wireshark-dev/201210/msg00186.html: Fix WLAN decryption when using a WPA PSK key -------------------------------------------------------------------------------------- Revision 45717 - Avoid potential infinite loops. Fixes https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7879 -------------------------------------------------------------------------------------- Revision 45742 - From Steve Magnani fix USB descriptor parsing https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7909 -------------------------------------------------------------------------------------- Revision 45770 - Allow to be successfully sscanf'd no matter the locale for the decimal symbol. Fixes https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=2880 (again). -------------------------------------------------------------------------------------- Revision 45789 - From Umberto Corponi via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7912 : Allow dissection of ESM messages with integrity protection and EEA0 ciphering From me: Tighten heuristic to check for allowed EPS bearer identity values -------------------------------------------------------------------------------------- Revision 45823 - Fix https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7790 : Add missing offset increment after displaying minimum count svn path=/trunk-1.8/; revision=45837 --- epan/dissectors/packet-ieee80211.c | 8 +- epan/dissectors/packet-nas_eps.c | 57 +- epan/dissectors/packet-rtcp.c | 16 +- epan/dissectors/packet-smb2.c | 51 +- epan/dissectors/packet-usb.c | 10 +- epan/dissectors/packet-wtp.c | 1489 ++++++++++++++++++------------------ print.ps | 1 + ui/cli/tap-iostat.c | 247 +++--- 8 files changed, 915 insertions(+), 964 deletions(-) diff --git a/epan/dissectors/packet-ieee80211.c b/epan/dissectors/packet-ieee80211.c index 221dc8a52c..4f1aa9f5bb 100644 --- a/epan/dissectors/packet-ieee80211.c +++ b/epan/dissectors/packet-ieee80211.c @@ -16785,16 +16785,16 @@ void set_airpdcap_keys(void) keys->Keys[keys->nKeys] = key; keys->nKeys++; } - else if(dk->type == AIRPDCAP_KEY_TYPE_WPA_PMK) + else if(dk->type == AIRPDCAP_KEY_TYPE_WPA_PSK) { - key.KeyType = AIRPDCAP_KEY_TYPE_WPA_PMK; + key.KeyType = AIRPDCAP_KEY_TYPE_WPA_PSK; bytes = g_byte_array_new(); hex_str_to_bytes(dk->key->str, bytes, FALSE); /* XXX - Pass the correct array of bytes... */ - if (bytes->len <= AIRPDCAP_WPA_PMK_LEN) { - memcpy(key.KeyData.Wpa.Pmk, bytes->data, bytes->len); + if (bytes->len <= AIRPDCAP_WPA_PSK_LEN) { + memcpy(key.KeyData.Wpa.Psk, bytes->data, bytes->len); keys->Keys[keys->nKeys] = key; keys->nKeys++; diff --git a/epan/dissectors/packet-nas_eps.c b/epan/dissectors/packet-nas_eps.c index a9f1bac3d2..d42efdfe4f 100644 --- a/epan/dissectors/packet-nas_eps.c +++ b/epan/dissectors/packet-nas_eps.c @@ -21,7 +21,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * References: 3GPP TS 24.301 V10.6.1 (2012-03) */ @@ -185,7 +185,6 @@ static int hf_nas_eps_egbr_dl = -1; static int hf_nas_eps_esm_cause = -1; static int hf_nas_eps_esm_eit = -1; -static int hf_nas_eps_esm_lnkd_eps_bearer_id = -1; static int hf_nas_eps_esm_notif_ind = -1; static int hf_nas_eps_esm_pdn_type = -1; static int hf_nas_eps_esm_pdn_ipv4 = -1; @@ -2445,20 +2444,6 @@ static const value_string nas_eps_esm_linked_bearer_id_vals[] = { { 0, NULL } }; - - -static guint16 -de_esm_lnkd_eps_bearer_id(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U_, guint32 offset, guint len _U_, gchar *add_string _U_, int string_len _U_) -{ - guint32 curr_offset; - - curr_offset = offset; - - proto_tree_add_item(tree, hf_nas_eps_esm_lnkd_eps_bearer_id, tvb, curr_offset, 1, ENC_BIG_ENDIAN); - - return(len); -} - /* * 9.9.4.7 LLC service access point identifier * See subclause 10.5.6.9 in 3GPP TS 24.008 @@ -2714,7 +2699,7 @@ guint16 (*esm_elem_fcn[])(tvbuff_t *tvb, proto_tree *tree, packet_info *pinfo _U de_esm_qos, /* 9.9.4.3 EPS quality of service */ de_esm_cause, /* 9.9.4.4 ESM cause */ de_esm_inf_trf_flg, /* 9.9.4.5 ESM information transfer flag */ - de_esm_lnkd_eps_bearer_id, /* 9.9.4.6 Linked EPS bearer identity */ + NULL, /* 9.9.4.6 Linked EPS bearer identity */ NULL, /* 9.9.4.7 LLC service access point identifier */ de_esm_notif_ind, /* 9.9.4.7a Notification indicator */ NULL, /* 9.9.4.8 Packet flow identifier */ @@ -4476,6 +4461,26 @@ get_nas_emm_msg_params(guint8 oct, const gchar **msg_str, int *ett_tree, int *hf return; } +static const value_string nas_eps_esm_bearer_id_vals[] = { + { 0x0, "No EPS bearer identity assigned"}, + { 0x1, "Reserved"}, + { 0x2, "Reserved"}, + { 0x3, "Reserved"}, + { 0x4, "Reserved"}, + { 0x5, "EPS bearer identity value 5"}, + { 0x6, "EPS bearer identity value 6"}, + { 0x7, "EPS bearer identity value 7"}, + { 0x8, "EPS bearer identity value 8"}, + { 0x9, "EPS bearer identity value 9"}, + { 0xa, "EPS bearer identity value 10"}, + { 0xb, "EPS bearer identity value 11"}, + { 0xc, "EPS bearer identity value 12"}, + { 0xd, "EPS bearer identity value 13"}, + { 0xe, "EPS bearer identity value 14"}, + { 0xf, "EPS bearer identity value 15"}, + { 0, NULL } +}; + /* * EPS session management messages. * A plain NAS message is pased to this function @@ -4636,7 +4641,7 @@ dissect_nas_eps_plain(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) /* SERVICE REQUEST (security header type equal to 12 or greater) is not a plain NAS message */ pd = tvb_get_guint8(tvb,offset); if (pd >= 0xc0) { - col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "SERVICE REQUEST"); + col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Service request"); /* Security header type Security header type 9.3.1 M V 1/2 */ proto_tree_add_item(nas_eps_tree, hf_nas_eps_security_header_type, tvb, 0, 1, ENC_BIG_ENDIAN); /* Protocol discriminator Protocol discriminator 9.2 M V 1/2 */ @@ -4755,13 +4760,13 @@ dissect_nas_eps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) dissect_nas_eps_emm_msg(tvb, pinfo, nas_eps_tree, offset, FALSE); return; } else { - proto_tree_add_text(tree, tvb, offset, len, "All ESM messages should be integrity protected"); + proto_tree_add_text(tree, tvb, offset, len, "All ESM / Test Procedures messages should be integrity protected"); return; } } else { /* SERVICE REQUEST (12 or greater) is not a plain NAS message treat separately */ if (security_header_type >= 12) { - col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "SERVICE REQUEST"); + col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Service request"); nas_emm_service_req(tvb, nas_eps_tree, pinfo, offset, len-offset); return; } @@ -4776,10 +4781,11 @@ dissect_nas_eps(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) proto_tree_add_item(nas_eps_tree, hf_nas_eps_seq_no, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; /* Integrity protected and ciphered = 2, Integrity protected and ciphered with new EPS security context = 4 */ - /* Read security_header_type AND pd */ + /* Read security_header_type / EPS bearer id AND pd */ pd = tvb_get_guint8(tvb,offset); /* If pd is in plaintext this message probably isn't ciphered */ - if ((pd != 7) && (pd != 2) && (pd != 15)) { + if ((pd != 7) && (pd != 15) && + (((pd&0x0f) != 2) || (((pd&0x0f) == 2) && ((pd&0xf0) > 0) && ((pd&0xf0) < 0x50)))) { proto_tree_add_text(nas_eps_tree, tvb, offset, len-6,"Ciphered message"); return; } @@ -4862,7 +4868,7 @@ proto_register_nas_eps(void) { }, { &hf_nas_eps_bearer_id, { "EPS bearer identity", "nas_eps.bearer_id", - FT_UINT8, BASE_DEC, NULL, 0xf0, + FT_UINT8, BASE_DEC, VALS(nas_eps_esm_bearer_id_vals), 0xf0, NULL, HFILL } }, { &hf_nas_eps_spare_bits, @@ -5492,11 +5498,6 @@ proto_register_nas_eps(void) { FT_BOOLEAN, 8, TFS(&nas_eps_emm_eit_vals), 0x01, NULL, HFILL } }, - { &hf_nas_eps_esm_lnkd_eps_bearer_id, - { "Linked EPS bearer identity","nas_eps.esm.lnkd_eps_bearer_id", - FT_UINT8,BASE_DEC, VALS(nas_eps_esm_linked_bearer_id_vals), 0x0f, - NULL, HFILL } - }, { &hf_nas_eps_esm_notif_ind, { "Notification indicator value","nas_eps.esm.notif_ind", FT_UINT8,BASE_DEC, VALS(nas_eps_esm_notif_ind_vals), 0x0, diff --git a/epan/dissectors/packet-rtcp.c b/epan/dissectors/packet-rtcp.c index 1eadc097e8..0be9be9bfd 100644 --- a/epan/dissectors/packet-rtcp.c +++ b/epan/dissectors/packet-rtcp.c @@ -30,7 +30,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ /* @@ -1517,7 +1517,8 @@ dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree default: break; } - offset += packet_len; + if ((int)(offset + packet_len) >= offset) + offset += packet_len; return offset; } else if ( g_ascii_strncasecmp(ascii_name, mux_app_name_str,4 ) == 0 ) @@ -1550,8 +1551,8 @@ dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree /* fall back to just showing the data if it's the wrong length */ proto_tree_add_item( tree, hf_rtcp_app_data, tvb, offset, packet_len, ENC_NA ); } - offset += packet_len; - + if ((int)(offset + packet_len) >= offset) + offset += packet_len; return offset; } else @@ -1572,7 +1573,8 @@ dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree */ packet_len -= tvb_get_guint8( tvb, offset + packet_len - 1 ); } - offset += packet_len; + if ((int)(offset + packet_len) >= offset) + offset += packet_len; return offset; } else @@ -1589,8 +1591,8 @@ dissect_rtcp_app( tvbuff_t *tvb,packet_info *pinfo, int offset, proto_tree *tree packet_len -= tvb_get_guint8( tvb, offset + packet_len - 1 ); } proto_tree_add_item( tree, hf_rtcp_app_data, tvb, offset, packet_len, ENC_NA ); - offset += packet_len; - + if ((int)(offset + packet_len) >= offset) + offset += packet_len; return offset; } } diff --git a/epan/dissectors/packet-smb2.c b/epan/dissectors/packet-smb2.c index 2b9a65f211..69172bf8bb 100644 --- a/epan/dissectors/packet-smb2.c +++ b/epan/dissectors/packet-smb2.c @@ -27,7 +27,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef HAVE_CONFIG_H @@ -819,8 +819,6 @@ dissect_smb2_olb_buffer(packet_info *pinfo, proto_tree *parent_tree, tvbuff_t *t sub_tvb=tvb_new_subset(tvb, off, MIN((int)len, tvb_length_remaining(tvb, off)), len); dissector(sub_tvb, pinfo, sub_tree, si); - - return; } static int @@ -2141,7 +2139,6 @@ dissect_smb2_secblob(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2_i } else { call_dissector(gssapi_handle, tvb, pinfo, tree); } - return; } static int @@ -2163,6 +2160,8 @@ dissect_smb2_session_setup_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree TL_IS_DISSECTOR_HELPER, NULL, NULL, NULL); if(!error_string){ ntlmssp_tap_id=find_tap_id("ntlmssp"); + } else { + g_string_free(error_string, TRUE); } } @@ -2660,7 +2659,6 @@ static void dissect_smb2_file_directory_info(tvbuff_t *tvb, packet_info *pinfo _ return; } } - return; } static void dissect_smb2_full_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_) @@ -2748,7 +2746,6 @@ static void dissect_smb2_full_directory_info(tvbuff_t *tvb, packet_info *pinfo _ return; } } - return; } static void dissect_smb2_both_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_) @@ -2857,7 +2854,6 @@ static void dissect_smb2_both_directory_info(tvbuff_t *tvb, packet_info *pinfo _ return; } } - return; } static void dissect_smb2_file_name_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_) @@ -2918,7 +2914,6 @@ static void dissect_smb2_file_name_info(tvbuff_t *tvb, packet_info *pinfo _U_, p return; } } - return; } static void dissect_smb2_id_both_directory_info(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *parent_tree, smb2_info_t *si _U_) @@ -3034,7 +3029,6 @@ static void dissect_smb2_id_both_directory_info(tvbuff_t *tvb, packet_info *pinf return; } } - return; } @@ -3068,7 +3062,6 @@ dissect_smb2_find_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, smb2 } proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_length(tvb), ENC_NA); - return; } static int @@ -3500,7 +3493,6 @@ dissect_smb2_getinfo_response_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_length(tvb), ENC_NA); } - return; } @@ -3861,8 +3853,6 @@ static void dissect_smb2_FSCTL_PIPE_TRANSCEIVE(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, proto_tree *top_tree, gboolean data_in _U_) { dissect_file_data_dcerpc(tvb, pinfo, tree, offset, tvb_length_remaining(tvb, offset), top_tree); - - return; } static void @@ -3879,9 +3869,6 @@ dissect_smb2_FSCTL_LMR_REQUEST_RESILIENCY(tvbuff_t *tvb, packet_info *pinfo _U_, /* reserved */ proto_tree_add_item(tree, hf_smb2_ioctl_resiliency_reserved, tvb, offset, 4, ENC_LITTLE_ENDIAN); - offset += 4; - - return; } static void @@ -3919,9 +3906,6 @@ dissect_windows_sockaddr_in(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *p if (parent_item) { proto_item_append_text(parent_item, ", IPv4: %s", tvb_ip_to_str(tvb, offset)); } - offset += 4; - - return; } static void @@ -3967,8 +3951,6 @@ dissect_windows_sockaddr_in6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree * /* sin6_scope_id */ proto_tree_add_item(sub_tree, hf_windows_sockaddr_in6_scope_id, tvb, offset, 2, ENC_LITTLE_ENDIAN); - offset += 4; - return; } static void @@ -4004,12 +3986,10 @@ dissect_windows_sockaddr_storage(tvbuff_t *tvb, packet_info *pinfo, proto_tree * if (parent_item) { proto_item_append_text(sub_item, ", Family: %d (0x%04x)", family, family); } - offset += 2; + /*offset += 2;*/ /* unknown */ - offset += 126; - - return; + /*offset += 126;*/ } #define NETWORK_INTERFACE_CAP_RSS 0x00000001 @@ -4093,7 +4073,6 @@ dissect_smb2_NETWORK_INTERFACE_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tre /* socket address */ dissect_windows_sockaddr_storage(tvb, pinfo, sub_tree, offset); - offset += 128; if(next_offset){ tvbuff_t *next_tvb; @@ -4104,7 +4083,6 @@ dissect_smb2_NETWORK_INTERFACE_INFO(tvbuff_t *tvb, packet_info *pinfo, proto_tre /* next extra info */ dissect_smb2_NETWORK_INTERFACE_INFO(next_tvb, pinfo, parent_tree); } - return; } static void @@ -4158,8 +4136,6 @@ dissect_smb2_FSCTL_GET_SHADOW_COPY_DATA(tvbuff_t *tvb, packet_info *pinfo _U_, p break; } } - - return; } int @@ -4326,8 +4302,6 @@ dissect_smb2_ioctl_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, pro default: proto_tree_add_item(tree, hf_smb2_unknown, tvb, 0, tvb_length(tvb), ENC_NA); } - - return; } static void @@ -4500,6 +4474,7 @@ dissect_smb2_read_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, i /* minimum count */ proto_tree_add_item(tree, hf_smb2_min_count, tvb, offset, 4, ENC_LITTLE_ENDIAN); + offset += 4; /* channel */ proto_tree_add_item(tree, hf_smb2_channel, tvb, offset, 4, ENC_LITTLE_ENDIAN); @@ -4583,7 +4558,6 @@ dissect_smb2_ExtA_buffer_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree * proto_item_append_text(item, ": SMB2_FILE_INFO_0f"); } dissect_smb2_file_info_0f(tvb, pinfo, tree, 0, si); - return; } static void @@ -4601,7 +4575,6 @@ dissect_smb2_SecD_buffer_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree * proto_item_append_text(item, ": SMB2_SEC_INFO_00"); } dissect_smb2_sec_info_00(tvb, pinfo, tree, 0, si); - return; } static void @@ -4619,8 +4592,6 @@ dissect_smb2_TWrp_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr proto_item_append_text(item, ": Timestamp"); } dissect_nt_64bit_time(tvb, tree, 0, hf_smb2_twrp_timestamp); - - return; } static void @@ -4762,7 +4733,6 @@ dissect_smb2_DH2Q_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr /* create guid */ proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_create_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN); - offset += 16; } static void @@ -4789,7 +4759,6 @@ dissect_smb2_DH2Q_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_t /* flags */ proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN); - offset += 4; } static void @@ -4820,7 +4789,6 @@ dissect_smb2_DH2C_buffer_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree * /* flags */ proto_tree_add_item(sub_tree, hf_smb2_dh2x_buffer_flags, tvb, offset, 4, ENC_LITTLE_ENDIAN); - offset += 4; } static void @@ -4851,8 +4819,6 @@ dissect_smb2_MxAc_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr } dissect_nt_64bit_time(tvb, tree, offset, hf_smb2_mxac_timestamp); - - return; } static void @@ -4884,8 +4850,6 @@ dissect_smb2_MxAc_buffer_response(tvbuff_t *tvb, packet_info *pinfo _U_, proto_t offset += 4; dissect_smb_access_mask(tvb, sub_tree, offset); - - return; } /* @@ -4983,7 +4947,6 @@ dissect_SMB2_CREATE_LEASE_VX(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree * offset += 16; proto_tree_add_item(sub_tree, hf_smb2_lease_epoch, tvb, offset, 4, ENC_LITTLE_ENDIAN); - offset += 4; } static void @@ -5035,7 +4998,6 @@ dissect_smb2_APP_INSTANCE_buffer_request(tvbuff_t *tvb, packet_info *pinfo _U_, /* create guid */ proto_tree_add_item(sub_tree, hf_smb2_APP_INSTANCE_buffer_app_guid, tvb, offset, 16, ENC_LITTLE_ENDIAN); - offset += 16; } static void @@ -5140,7 +5102,6 @@ dissect_smb2_create_extra_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *pa /* next extra info */ dissect_smb2_create_extra_info(chain_tvb, pinfo, parent_tree, si); } - return; } static int diff --git a/epan/dissectors/packet-usb.c b/epan/dissectors/packet-usb.c index 706d0e2008..9286a5087c 100644 --- a/epan/dissectors/packet-usb.c +++ b/epan/dissectors/packet-usb.c @@ -1103,8 +1103,9 @@ dissect_usb_interface_descriptor(packet_info *pinfo, proto_tree *parent_tree, tv if(item){ proto_item_set_len(item, len); } - if (offset != old_offset + len) { - /* unknown records */ + if (offset < old_offset+len) { + /* skip unknown records */ + offset = old_offset + len; } return offset; @@ -1227,8 +1228,9 @@ dissect_usb_endpoint_descriptor(packet_info *pinfo, proto_tree *parent_tree, tvb if(item){ proto_item_set_len(item, len); } - if (offset != old_offset + len) { - /* unknown records */ + if (offset < old_offset+len) { + /* skip unknown records */ + offset = old_offset + len; } return offset; diff --git a/epan/dissectors/packet-wtp.c b/epan/dissectors/packet-wtp.c index cf2df5a924..1d5e630c70 100644 --- a/epan/dissectors/packet-wtp.c +++ b/epan/dissectors/packet-wtp.c @@ -24,7 +24,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifdef HAVE_CONFIG_H @@ -150,60 +150,59 @@ static const value_string vals_tpi_opt[] = { }; /* File scoped variables for the protocol and registered fields */ -static int proto_wtp = HF_EMPTY; +static int proto_wtp = HF_EMPTY; /* These fields used by fixed part of header */ -static int hf_wtp_header_sub_pdu_size = HF_EMPTY; -static int hf_wtp_header_flag_continue = HF_EMPTY; -static int hf_wtp_header_pdu_type = HF_EMPTY; -static int hf_wtp_header_flag_Trailer = HF_EMPTY; -static int hf_wtp_header_flag_RID = HF_EMPTY; -static int hf_wtp_header_flag_TID = HF_EMPTY; -static int hf_wtp_header_flag_TID_response = HF_EMPTY; +static int hf_wtp_header_sub_pdu_size = HF_EMPTY; +static int hf_wtp_header_flag_continue = HF_EMPTY; +static int hf_wtp_header_pdu_type = HF_EMPTY; +static int hf_wtp_header_flag_Trailer = HF_EMPTY; +static int hf_wtp_header_flag_RID = HF_EMPTY; +static int hf_wtp_header_flag_TID = HF_EMPTY; +static int hf_wtp_header_flag_TID_response = HF_EMPTY; /* These fields used by Invoke packets */ -static int hf_wtp_header_Inv_version = HF_EMPTY; -static int hf_wtp_header_Inv_flag_TIDNew = HF_EMPTY; -static int hf_wtp_header_Inv_flag_UP = HF_EMPTY; -static int hf_wtp_header_Inv_Reserved = HF_EMPTY; -static int hf_wtp_header_Inv_TransactionClass = HF_EMPTY; - - -static int hf_wtp_header_variable_part = HF_EMPTY; -static int hf_wtp_data = HF_EMPTY; - -static int hf_wtp_tpi_type = HF_EMPTY; -static int hf_wtp_tpi_psn = HF_EMPTY; -static int hf_wtp_tpi_opt = HF_EMPTY; -static int hf_wtp_tpi_optval = HF_EMPTY; -static int hf_wtp_tpi_info = HF_EMPTY; - -static int hf_wtp_header_Ack_flag_TVETOK = HF_EMPTY; -static int hf_wtp_header_Abort_type = HF_EMPTY; -static int hf_wtp_header_Abort_reason_provider = HF_EMPTY; -static int hf_wtp_header_Abort_reason_user = HF_EMPTY; -static int hf_wtp_header_sequence_number = HF_EMPTY; -static int hf_wtp_header_missing_packets = HF_EMPTY; +static int hf_wtp_header_Inv_version = HF_EMPTY; +static int hf_wtp_header_Inv_flag_TIDNew = HF_EMPTY; +static int hf_wtp_header_Inv_flag_UP = HF_EMPTY; +static int hf_wtp_header_Inv_Reserved = HF_EMPTY; +static int hf_wtp_header_Inv_TransactionClass = HF_EMPTY; + +static int hf_wtp_header_variable_part = HF_EMPTY; +static int hf_wtp_data = HF_EMPTY; + +static int hf_wtp_tpi_type = HF_EMPTY; +static int hf_wtp_tpi_psn = HF_EMPTY; +static int hf_wtp_tpi_opt = HF_EMPTY; +static int hf_wtp_tpi_optval = HF_EMPTY; +static int hf_wtp_tpi_info = HF_EMPTY; + +static int hf_wtp_header_Ack_flag_TVETOK = HF_EMPTY; +static int hf_wtp_header_Abort_type = HF_EMPTY; +static int hf_wtp_header_Abort_reason_provider = HF_EMPTY; +static int hf_wtp_header_Abort_reason_user = HF_EMPTY; +static int hf_wtp_header_sequence_number = HF_EMPTY; +static int hf_wtp_header_missing_packets = HF_EMPTY; /* These fields used when reassembling WTP fragments */ -static int hf_wtp_fragments = HF_EMPTY; -static int hf_wtp_fragment = HF_EMPTY; -static int hf_wtp_fragment_overlap = HF_EMPTY; -static int hf_wtp_fragment_overlap_conflict = HF_EMPTY; -static int hf_wtp_fragment_multiple_tails = HF_EMPTY; -static int hf_wtp_fragment_too_long_fragment = HF_EMPTY; -static int hf_wtp_fragment_error = HF_EMPTY; -static int hf_wtp_fragment_count = HF_EMPTY; -static int hf_wtp_reassembled_in = HF_EMPTY; -static int hf_wtp_reassembled_length = HF_EMPTY; +static int hf_wtp_fragments = HF_EMPTY; +static int hf_wtp_fragment = HF_EMPTY; +static int hf_wtp_fragment_overlap = HF_EMPTY; +static int hf_wtp_fragment_overlap_conflict = HF_EMPTY; +static int hf_wtp_fragment_multiple_tails = HF_EMPTY; +static int hf_wtp_fragment_too_long_fragment = HF_EMPTY; +static int hf_wtp_fragment_error = HF_EMPTY; +static int hf_wtp_fragment_count = HF_EMPTY; +static int hf_wtp_reassembled_in = HF_EMPTY; +static int hf_wtp_reassembled_length = HF_EMPTY; /* Initialize the subtree pointers */ -static gint ett_wtp = ETT_EMPTY; -static gint ett_wtp_sub_pdu_tree = ETT_EMPTY; -static gint ett_header = ETT_EMPTY; -static gint ett_tpilist = ETT_EMPTY; -static gint ett_wsp_fragments = ETT_EMPTY; -static gint ett_wtp_fragment = ETT_EMPTY; +static gint ett_wtp = ETT_EMPTY; +static gint ett_wtp_sub_pdu_tree = ETT_EMPTY; +static gint ett_header = ETT_EMPTY; +static gint ett_tpilist = ETT_EMPTY; +static gint ett_wsp_fragments = ETT_EMPTY; +static gint ett_wtp_fragment = ETT_EMPTY; static const fragment_items wtp_frag_items = { &ett_wtp_fragment, @@ -227,7 +226,7 @@ static dissector_handle_t wsp_handle; /* * reassembly of WSP */ -static GHashTable *wtp_fragment_table = NULL; +static GHashTable *wtp_fragment_table = NULL; static void wtp_defragment_init(void) @@ -238,22 +237,22 @@ wtp_defragment_init(void) /* * Extract some bitfields */ -#define pdu_type(octet) (((octet) >> 3) & 0x0F) /* Note pdu type must not be 0x00 */ -#define transaction_class(octet) ((octet) & 0x03) /* ......XX */ -#define transmission_trailer(octet) (((octet) >> 1) & 0x01) /* ......X. */ +#define pdu_type(octet) (((octet) >> 3) & 0x0F) /* Note pdu type must not be 0x00 */ +#define transaction_class(octet) ((octet) & 0x03) /* ......XX */ +#define transmission_trailer(octet) (((octet) >> 1) & 0x01) /* ......X. */ static char retransmission_indicator(unsigned char octet) { switch (pdu_type(octet)) { - case INVOKE: - case RESULT: - case ACK: - case SEGMENTED_INVOKE: - case SEGMENTED_RESULT: - case NEGATIVE_ACK: - return octet & 0x01; /* .......X */ - default: - return 0; + case INVOKE: + case RESULT: + case ACK: + case SEGMENTED_INVOKE: + case SEGMENTED_RESULT: + case NEGATIVE_ACK: + return octet & 0x01; /* .......X */ + default: + return 0; } } @@ -263,49 +262,49 @@ static char retransmission_indicator(unsigned char octet) static void wtp_handle_tpi(proto_tree *tree, tvbuff_t *tvb) { - int offset = 0; - unsigned char tByte; - unsigned char tType; - unsigned char tLen; - proto_tree *subTree = NULL; - proto_item *pi; + int offset = 0; + unsigned char tByte; + unsigned char tType; + unsigned char tLen; + proto_tree *subTree = NULL; + proto_item *pi; tByte = tvb_get_guint8(tvb, offset++); tType = (tByte & 0x78) >> 3; - if (tByte & 0x04) /* Long TPI */ - tLen = tvb_get_guint8(tvb, offset++); + if (tByte & 0x04) /* Long TPI */ + tLen = tvb_get_guint8(tvb, offset++); else - tLen = tByte & 0x03; + tLen = tByte & 0x03; pi = proto_tree_add_uint(tree, hf_wtp_tpi_type, - tvb, 0, tvb_length(tvb), tType); + tvb, 0, tvb_length(tvb), tType); subTree = proto_item_add_subtree(pi, ett_tpilist); switch (tType) { - case 0x00: /* Error*/ - /* \todo */ - break; - case 0x01: /* Info */ - /* Beware, untested case here */ - proto_tree_add_item(subTree, hf_wtp_tpi_info, - tvb, offset, tLen, ENC_NA); - break; - case 0x02: /* Option */ - proto_tree_add_item(subTree, hf_wtp_tpi_opt, - tvb, offset++, 1, ENC_LITTLE_ENDIAN); - proto_tree_add_item(subTree, hf_wtp_tpi_optval, - tvb, offset, tLen - 1, ENC_NA); - break; - case 0x03: /* PSN */ - proto_tree_add_item(subTree, hf_wtp_tpi_psn, - tvb, offset, 1, ENC_LITTLE_ENDIAN); - break; - case 0x04: /* SDU boundary */ - /* \todo */ - break; - case 0x05: /* Frame boundary */ - /* \todo */ - break; - default: - break; + case 0x00: /* Error*/ + /* \todo */ + break; + case 0x01: /* Info */ + /* Beware, untested case here */ + proto_tree_add_item(subTree, hf_wtp_tpi_info, + tvb, offset, tLen, ENC_NA); + break; + case 0x02: /* Option */ + proto_tree_add_item(subTree, hf_wtp_tpi_opt, + tvb, offset++, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(subTree, hf_wtp_tpi_optval, + tvb, offset, tLen - 1, ENC_NA); + break; + case 0x03: /* PSN */ + proto_tree_add_item(subTree, hf_wtp_tpi_psn, + tvb, offset, 1, ENC_LITTLE_ENDIAN); + break; + case 0x04: /* SDU boundary */ + /* \todo */ + break; + case 0x05: /* Frame boundary */ + /* \todo */ + break; + default: + break; } } @@ -313,33 +312,33 @@ wtp_handle_tpi(proto_tree *tree, tvbuff_t *tvb) static void dissect_wtp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { - char *szInfo; - int offCur = 0; /* current offset from start of WTP data */ - gint returned_length, str_index = 0; + char *szInfo; + int offCur = 0; /* current offset from start of WTP data */ + gint returned_length, str_index = 0; - unsigned char b0; + unsigned char b0; /* continuation flag */ - unsigned char fCon; /* Continue flag */ - unsigned char fRID; /* Re-transmission indicator*/ - unsigned char fTTR = '\0'; /* Transmission trailer */ - guint cbHeader = 0; /* Fixed header length */ - guint vHeader = 0; /* Variable header length*/ - int abortType = 0; + unsigned char fCon; /* Continue flag */ + unsigned char fRID; /* Re-transmission indicator*/ + unsigned char fTTR = '\0'; /* Transmission trailer */ + guint cbHeader = 0; /* Fixed header length */ + guint vHeader = 0; /* Variable header length*/ + int abortType = 0; /* Set up structures we'll need to add the protocol subtree and manage it */ - proto_item *ti = NULL; - proto_tree *wtp_tree = NULL; - - char pdut; - char clsTransaction = 3; - int numMissing = 0; /* Number of missing packets in a negative ack */ - int i; - tvbuff_t *wsp_tvb = NULL; - guint8 psn = 0; /* Packet sequence number*/ - guint16 TID = 0; /* Transaction-Id */ - int dataOffset; - gint dataLen; + proto_item *ti = NULL; + proto_tree *wtp_tree = NULL; + + char pdut; + char clsTransaction = 3; + int numMissing = 0; /* Number of missing packets in a negative ack */ + int i; + tvbuff_t *wsp_tvb = NULL; + guint8 psn = 0; /* Packet sequence number*/ + guint16 TID = 0; /* Transaction-Id */ + int dataOffset; + gint dataLen; #define SZINFO_SIZE 256 szInfo=ep_alloc(SZINFO_SIZE); @@ -347,50 +346,50 @@ dissect_wtp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) b0 = tvb_get_guint8 (tvb, offCur + 0); /* Discover Concatenated PDUs */ if (b0 == 0) { - guint c_fieldlen = 0; /* Length of length-field */ - guint c_pdulen = 0; /* Length of conc. PDU */ - - if (tree) { - ti = proto_tree_add_item(tree, proto_wtp, - tvb, offCur, 1, ENC_NA); - wtp_tree = proto_item_add_subtree(ti, ett_wtp_sub_pdu_tree); - proto_item_append_text(ti, ", PDU concatenation"); - } - offCur = 1; - i = 1; - while (offCur < (int) tvb_reported_length(tvb)) { - tvbuff_t *wtp_tvb; - /* The length of an embedded WTP PDU is coded as either: - * - a 7-bit value contained in one octet with highest bit == 0. - * - a 15-bit value contained in two octets (little endian) - * if the 1st octet has its highest bit == 1. - * This means that this is NOT encoded as an uintvar-integer!!! - */ - b0 = tvb_get_guint8(tvb, offCur + 0); - if (b0 & 0x80) { - c_fieldlen = 2; - c_pdulen = ((b0 & 0x7f) << 8) | tvb_get_guint8(tvb, offCur + 1); - } else { - c_fieldlen = 1; - c_pdulen = b0; - } - if (tree) { - proto_tree_add_uint(wtp_tree, hf_wtp_header_sub_pdu_size, - tvb, offCur, c_fieldlen, c_pdulen); - } - if (i > 1) { - col_append_str(pinfo->cinfo, COL_INFO, ", "); - } - /* Skip the length field for the WTP sub-tvb */ - wtp_tvb = tvb_new_subset(tvb, offCur + c_fieldlen, c_pdulen, c_pdulen); - dissect_wtp_common(wtp_tvb, pinfo, wtp_tree); - offCur += c_fieldlen + c_pdulen; - i++; - } - if (tree) { - proto_item_append_text(ti, ", PDU count: %u", i); - } - return; + guint c_fieldlen = 0; /* Length of length-field */ + guint c_pdulen = 0; /* Length of conc. PDU */ + + if (tree) { + ti = proto_tree_add_item(tree, proto_wtp, + tvb, offCur, 1, ENC_NA); + wtp_tree = proto_item_add_subtree(ti, ett_wtp_sub_pdu_tree); + proto_item_append_text(ti, ", PDU concatenation"); + } + offCur = 1; + i = 1; + while (offCur < (int) tvb_reported_length(tvb)) { + tvbuff_t *wtp_tvb; + /* The length of an embedded WTP PDU is coded as either: + * - a 7-bit value contained in one octet with highest bit == 0. + * - a 15-bit value contained in two octets (little endian) + * if the 1st octet has its highest bit == 1. + * This means that this is NOT encoded as an uintvar-integer!!! + */ + b0 = tvb_get_guint8(tvb, offCur + 0); + if (b0 & 0x80) { + c_fieldlen = 2; + c_pdulen = ((b0 & 0x7f) << 8) | tvb_get_guint8(tvb, offCur + 1); + } else { + c_fieldlen = 1; + c_pdulen = b0; + } + if (tree) { + proto_tree_add_uint(wtp_tree, hf_wtp_header_sub_pdu_size, + tvb, offCur, c_fieldlen, c_pdulen); + } + if (i > 1) { + col_append_str(pinfo->cinfo, COL_INFO, ", "); + } + /* Skip the length field for the WTP sub-tvb */ + wtp_tvb = tvb_new_subset(tvb, offCur + c_fieldlen, c_pdulen, c_pdulen); + dissect_wtp_common(wtp_tvb, pinfo, wtp_tree); + offCur += c_fieldlen + c_pdulen; + i++; + } + if (tree) { + proto_item_append_text(ti, ", PDU count: %u", i); + } + return; } /* No concatenation */ fCon = b0 & 0x80; @@ -398,257 +397,253 @@ dissect_wtp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) pdut = pdu_type(b0); #ifdef DEBUG - printf("WTP packet %u: tree = %p, pdu = %s (%u) length: %u\n", - pinfo->fd->num, tree, - val_to_str(pdut, vals_wtp_pdu_type, "Unknown PDU type 0x%x"), - pdut, tvb_length(tvb)); + printf("WTP packet %u: tree = %p, pdu = %s (%u) length: %u\n", + pinfo->fd->num, tree, + val_to_str(pdut, vals_wtp_pdu_type, "Unknown PDU type 0x%x"), + pdut, tvb_length(tvb)); #endif /* Develop the string to put in the Info column */ returned_length = g_snprintf(szInfo, SZINFO_SIZE, "WTP %s", - val_to_str(pdut, vals_wtp_pdu_type, "Unknown PDU type 0x%x")); + val_to_str(pdut, vals_wtp_pdu_type, "Unknown PDU type 0x%x")); str_index += MIN(returned_length, SZINFO_SIZE-str_index); switch (pdut) { - case INVOKE: - fTTR = transmission_trailer(b0); - TID = tvb_get_ntohs(tvb, offCur + 1); - psn = 0; - clsTransaction = transaction_class(tvb_get_guint8(tvb, offCur + 3)); - returned_length = g_snprintf(&szInfo[str_index], SZINFO_SIZE-str_index, - " Class %d", clsTransaction); + case INVOKE: + fTTR = transmission_trailer(b0); + TID = tvb_get_ntohs(tvb, offCur + 1); + psn = 0; + clsTransaction = transaction_class(tvb_get_guint8(tvb, offCur + 3)); + returned_length = g_snprintf(&szInfo[str_index], SZINFO_SIZE-str_index, + " Class %d", clsTransaction); str_index += MIN(returned_length, SZINFO_SIZE-str_index); - cbHeader = 4; - break; - - case SEGMENTED_INVOKE: - case SEGMENTED_RESULT: - fTTR = transmission_trailer(b0); - TID = tvb_get_ntohs(tvb, offCur + 1); - psn = tvb_get_guint8(tvb, offCur + 3); - if (psn != 0) { - returned_length = g_snprintf(&szInfo[str_index], SZINFO_SIZE-str_index, - " (%u)", psn); + cbHeader = 4; + break; + + case SEGMENTED_INVOKE: + case SEGMENTED_RESULT: + fTTR = transmission_trailer(b0); + TID = tvb_get_ntohs(tvb, offCur + 1); + psn = tvb_get_guint8(tvb, offCur + 3); + if (psn != 0) { + returned_length = g_snprintf(&szInfo[str_index], SZINFO_SIZE-str_index, + " (%u)", psn); str_index += MIN(returned_length, SZINFO_SIZE-str_index); - } - cbHeader = 4; - break; - - case ABORT: - cbHeader = 4; - break; - - case RESULT: - fTTR = transmission_trailer(b0); - TID = tvb_get_ntohs(tvb, offCur + 1); - psn = 0; - cbHeader = 3; - break; - - case ACK: - cbHeader = 3; - break; - - case NEGATIVE_ACK: - /* Variable number of missing packets */ - numMissing = tvb_get_guint8(tvb, offCur + 3); - cbHeader = numMissing + 4; - break; - - default: - break; + } + cbHeader = 4; + break; + + case ABORT: + cbHeader = 4; + break; + + case RESULT: + fTTR = transmission_trailer(b0); + TID = tvb_get_ntohs(tvb, offCur + 1); + psn = 0; + cbHeader = 3; + break; + + case ACK: + cbHeader = 3; + break; + + case NEGATIVE_ACK: + /* Variable number of missing packets */ + numMissing = tvb_get_guint8(tvb, offCur + 3); + cbHeader = numMissing + 4; + break; + + default: + break; }; if (fRID) { - returned_length = g_snprintf(&szInfo[str_index], SZINFO_SIZE-str_index, " R" ); + returned_length = g_snprintf(&szInfo[str_index], SZINFO_SIZE-str_index, " R" ); str_index += MIN(returned_length, SZINFO_SIZE-str_index); }; /* In the interest of speed, if "tree" is NULL, don't do any work not necessary to generate protocol tree items. */ if (tree) { #ifdef DEBUG - fprintf(stderr, "dissect_wtp: cbHeader = %d\n", cbHeader); + fprintf(stderr, "dissect_wtp: cbHeader = %d\n", cbHeader); #endif - /* NOTE - Length will be set when we process the TPI */ - ti = proto_tree_add_item(tree, proto_wtp, tvb, offCur, 0, ENC_NA); + /* NOTE - Length will be set when we process the TPI */ + ti = proto_tree_add_item(tree, proto_wtp, tvb, offCur, 0, ENC_NA); #ifdef DEBUG - fprintf(stderr, "dissect_wtp: (7) Returned from proto_tree_add_item\n"); + fprintf(stderr, "dissect_wtp: (7) Returned from proto_tree_add_item\n"); #endif - wtp_tree = proto_item_add_subtree(ti, ett_wtp); + wtp_tree = proto_item_add_subtree(ti, ett_wtp); -/* Code to process the packet goes here */ + /* Code to process the packet goes here */ #ifdef DEBUG - fprintf(stderr, "dissect_wtp: cbHeader = %d\n", cbHeader); - fprintf(stderr, "dissect_wtp: offCur = %d\n", offCur); + fprintf(stderr, "dissect_wtp: cbHeader = %d\n", cbHeader); + fprintf(stderr, "dissect_wtp: offCur = %d\n", offCur); #endif - /* Add common items: only CON and PDU Type */ - proto_tree_add_item( - wtp_tree, /* tree */ - hf_wtp_header_flag_continue, /* id */ - tvb, - offCur, /* start of highlight */ - 1, /* length of highlight*/ - b0 /* value */ - ); - proto_tree_add_item(wtp_tree, hf_wtp_header_pdu_type, tvb, offCur, 1, ENC_LITTLE_ENDIAN); - - switch(pdut) { - case INVOKE: - proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN); - proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); - proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); - proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); - - proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_version , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); - proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_flag_TIDNew, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); - proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_flag_UP, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); - proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_Reserved, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); - proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_TransactionClass, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); - proto_item_append_text(ti, - ", PDU: Invoke (%u)" - ", Transaction Class: %s (%u)", - INVOKE, - val_to_str(clsTransaction, vals_transaction_classes, "Undefined"), - clsTransaction); - break; - - case RESULT: - proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN); - proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); - proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); - proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); - proto_item_append_text(ti, ", PDU: Result (%u)", RESULT); - break; - - case ACK: - proto_tree_add_item(wtp_tree, hf_wtp_header_Ack_flag_TVETOK, tvb, offCur, 1, ENC_BIG_ENDIAN); - - proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); - proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); - proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); - proto_item_append_text(ti, ", PDU: ACK (%u)", ACK); - break; - - case ABORT: - abortType = tvb_get_guint8 (tvb, offCur) & 0x07; - proto_tree_add_item(wtp_tree, hf_wtp_header_Abort_type , tvb, offCur , 1, ENC_LITTLE_ENDIAN); - proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); - proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); - - if (abortType == PROVIDER) - { - guint8 reason = tvb_get_guint8(tvb, offCur + 3); - proto_tree_add_item( wtp_tree, hf_wtp_header_Abort_reason_provider , tvb, offCur + 3 , 1, ENC_LITTLE_ENDIAN); - proto_item_append_text(ti, - ", PDU: Abort (%u)" - ", Type: Provider (%u)" - ", Reason: %s (%u)", - ABORT, - PROVIDER, - val_to_str(reason, vals_abort_reason_provider, "Undefined"), - reason); - } - else if (abortType == USER) - { - guint8 reason = tvb_get_guint8(tvb, offCur + 3); - proto_tree_add_item(wtp_tree, hf_wtp_header_Abort_reason_user , tvb, offCur + 3 , 1, ENC_LITTLE_ENDIAN); - proto_item_append_text(ti, - ", PDU: Abort (%u)" - ", Type: User (%u)" - ", Reason: %s (%u)", - ABORT, - PROVIDER, - val_to_str_ext_const(reason, &vals_wsp_reason_codes_ext, "Undefined"), - reason); - } - break; - - case SEGMENTED_INVOKE: - proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN); - proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); - proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); - proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); - - proto_tree_add_item(wtp_tree, hf_wtp_header_sequence_number , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); - proto_item_append_text(ti, - ", PDU: Segmented Invoke (%u)" - ", Packet Sequence Number: %u", - SEGMENTED_INVOKE, psn); - break; - - case SEGMENTED_RESULT: - proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN); - proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); - proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); - proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); - - proto_tree_add_item(wtp_tree, hf_wtp_header_sequence_number , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); - proto_item_append_text(ti, - ", PDU: Segmented Result (%u)" - ", Packet Sequence Number: %u", - SEGMENTED_RESULT, psn); - break; - - case NEGATIVE_ACK: - proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); - proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); - proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); - - proto_tree_add_item(wtp_tree, hf_wtp_header_missing_packets , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); - /* Iterate through missing packets */ - for (i = 0; i < numMissing; i++) - { - proto_tree_add_item(wtp_tree, hf_wtp_header_sequence_number, tvb, offCur + 4 + i, 1, ENC_LITTLE_ENDIAN); - } - proto_item_append_text(ti, - ", PDU: Negative Ack (%u)" - ", Missing Packets: %u", - NEGATIVE_ACK, numMissing); - break; - - default: - break; - }; - if (fRID) { - proto_item_append_text(ti, ", Retransmission"); - } + /* Add common items: only CON and PDU Type */ + proto_tree_add_item( + wtp_tree, /* tree */ + hf_wtp_header_flag_continue, /* id */ + tvb, + offCur, /* start of highlight */ + 1, /* length of highlight*/ + b0 /* value */ + ); + proto_tree_add_item(wtp_tree, hf_wtp_header_pdu_type, tvb, offCur, 1, ENC_LITTLE_ENDIAN); + + switch(pdut) { + case INVOKE: + proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); + + proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_version , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_flag_TIDNew, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_flag_UP, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_Reserved, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(wtp_tree, hf_wtp_header_Inv_TransactionClass, tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti, + ", PDU: Invoke (%u)" + ", Transaction Class: %s (%u)", + INVOKE, + val_to_str_const(clsTransaction, vals_transaction_classes, "Undefined"), + clsTransaction); + break; + + case RESULT: + proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); + proto_item_append_text(ti, ", PDU: Result (%u)", RESULT); + break; + + case ACK: + proto_tree_add_item(wtp_tree, hf_wtp_header_Ack_flag_TVETOK, tvb, offCur, 1, ENC_BIG_ENDIAN); + + proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); + proto_item_append_text(ti, ", PDU: ACK (%u)", ACK); + break; + + case ABORT: + abortType = tvb_get_guint8 (tvb, offCur) & 0x07; + proto_tree_add_item(wtp_tree, hf_wtp_header_Abort_type , tvb, offCur , 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); + + if (abortType == PROVIDER) { + guint8 reason = tvb_get_guint8(tvb, offCur + 3); + proto_tree_add_item( wtp_tree, hf_wtp_header_Abort_reason_provider , tvb, offCur + 3 , 1, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti, + ", PDU: Abort (%u)" + ", Type: Provider (%u)" + ", Reason: %s (%u)", + ABORT, + PROVIDER, + val_to_str_const(reason, vals_abort_reason_provider, "Undefined"), + reason); + } + else if (abortType == USER) { + guint8 reason = tvb_get_guint8(tvb, offCur + 3); + proto_tree_add_item(wtp_tree, hf_wtp_header_Abort_reason_user , tvb, offCur + 3 , 1, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti, + ", PDU: Abort (%u)" + ", Type: User (%u)" + ", Reason: %s (%u)", + ABORT, + PROVIDER, + val_to_str_ext_const(reason, &vals_wsp_reason_codes_ext, "Undefined"), + reason); + } + break; + + case SEGMENTED_INVOKE: + proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); + + proto_tree_add_item(wtp_tree, hf_wtp_header_sequence_number , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti, + ", PDU: Segmented Invoke (%u)" + ", Packet Sequence Number: %u", + SEGMENTED_INVOKE, psn); + break; + + case SEGMENTED_RESULT: + proto_tree_add_item(wtp_tree, hf_wtp_header_flag_Trailer, tvb, offCur, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); + + proto_tree_add_item(wtp_tree, hf_wtp_header_sequence_number , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); + proto_item_append_text(ti, + ", PDU: Segmented Result (%u)" + ", Packet Sequence Number: %u", + SEGMENTED_RESULT, psn); + break; + + case NEGATIVE_ACK: + proto_tree_add_item(wtp_tree, hf_wtp_header_flag_RID, tvb, offCur, 1, ENC_LITTLE_ENDIAN); + proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID_response, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); + proto_tree_add_item(wtp_tree, hf_wtp_header_flag_TID, tvb, offCur + 1, 2, ENC_BIG_ENDIAN); + + proto_tree_add_item(wtp_tree, hf_wtp_header_missing_packets , tvb, offCur + 3, 1, ENC_LITTLE_ENDIAN); + /* Iterate through missing packets */ + for (i = 0; i < numMissing; i++) + { + proto_tree_add_item(wtp_tree, hf_wtp_header_sequence_number, tvb, offCur + 4 + i, 1, ENC_LITTLE_ENDIAN); + } + proto_item_append_text(ti, + ", PDU: Negative Ack (%u)" + ", Missing Packets: %u", + NEGATIVE_ACK, numMissing); + break; + + default: + break; + }; + if (fRID) { + proto_item_append_text(ti, ", Retransmission"); + } } else { /* tree is NULL */ #ifdef DEBUG - fprintf(stderr, "dissect_wtp: (4) tree was %p\n", tree); + fprintf(stderr, "dissect_wtp: (4) tree was %p\n", tree); #endif } - /* Process the variable part */ - if (fCon) { /* Now, analyze variable part */ - unsigned char tCon; - unsigned char tByte; - unsigned char tpiLen; - tvbuff_t *tmp_tvb; - - vHeader = 0; /* Start scan all over */ - - do { - tByte = tvb_get_guint8(tvb, offCur + cbHeader + vHeader); - tCon = tByte & 0x80; - if (tByte & 0x04) /* Long TPI */ - tpiLen = 2 + tvb_get_guint8(tvb, - offCur + cbHeader + vHeader + 1); - else - tpiLen = 1 + (tByte & 0x03); - if (tree) - { - tmp_tvb = tvb_new_subset(tvb, offCur + cbHeader + vHeader, - tpiLen, tpiLen); - wtp_handle_tpi(wtp_tree, tmp_tvb); - } - vHeader += tpiLen; - } while (tCon); - } else { - /* There is no variable part */ - } /* End of variable part of header */ - - /* Set the length of the WTP protocol part now we know the length of the - * fixed and variable WTP headers */ - if (tree) - proto_item_set_len(ti, cbHeader + vHeader); + /* Process the variable part */ + if (fCon) { /* Now, analyze variable part */ + guint8 tCon; + guint8 tByte; + guint tpiLen; + tvbuff_t *tmp_tvb; + + vHeader = 0; /* Start scan all over */ + + do { + tByte = tvb_get_guint8(tvb, offCur + cbHeader + vHeader); + tCon = tByte & 0x80; + if (tByte & 0x04) /* Long TPI */ + tpiLen = 2 + tvb_get_guint8(tvb, offCur + cbHeader + vHeader + 1); + else + tpiLen = 1 + (tByte & 0x03); + if (tree) + { + tmp_tvb = tvb_new_subset(tvb, offCur + cbHeader + vHeader, tpiLen, tpiLen); + wtp_handle_tpi(wtp_tree, tmp_tvb); + } + vHeader += tpiLen; + } while (tCon); + } else { + /* There is no variable part */ + } /* End of variable part of header */ + + /* Set the length of the WTP protocol part now we know the length of the + * fixed and variable WTP headers */ + if (tree) + proto_item_set_len(ti, cbHeader + vHeader); #ifdef DEBUG fprintf( stderr, "dissect_wtp: cbHeader = %d\n", cbHeader ); @@ -664,124 +659,124 @@ dissect_wtp_common(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) * reassembled. (XXX - does the reassembly code handle this * for packets other than the last packet?) * - * Try calling a subdissector only if: - * - The WTP payload is ressembled in this very packet, - * - The WTP payload is not fragmented across packets. - */ + * Try calling a subdissector only if: + * - The WTP payload is ressembled in this very packet, + * - The WTP payload is not fragmented across packets. + */ dataOffset = offCur + cbHeader + vHeader; dataLen = tvb_reported_length_remaining(tvb, dataOffset); if ((dataLen >= 0) && - ! ((pdut==ACK) || (pdut==NEGATIVE_ACK) || (pdut==ABORT))) + ! ((pdut==ACK) || (pdut==NEGATIVE_ACK) || (pdut==ABORT))) { - /* Try to reassemble if needed, and hand over to WSP - * A fragmented WTP packet is either: - * - An INVOKE with fTTR (transmission trailer) not set, - * - a SEGMENTED_INVOKE, - * - A RESULT with fTTR (transmission trailer) not set, - * - a SEGMENTED_RESULT. - */ - if ( ( (pdut == SEGMENTED_INVOKE) || (pdut == SEGMENTED_RESULT) - || ( ((pdut == INVOKE) || (pdut == RESULT)) && (!fTTR) ) - ) && tvb_bytes_exist(tvb, dataOffset, dataLen) ) - { - /* Try reassembling fragments */ - fragment_data *fd_wtp = NULL; - guint32 reassembled_in = 0; - gboolean save_fragmented = pinfo->fragmented; - - pinfo->fragmented = TRUE; - fd_wtp = fragment_add_seq(tvb, dataOffset, pinfo, TID, - wtp_fragment_table, psn, dataLen, !fTTR); - /* XXX - fragment_add_seq() yields NULL unless Wireshark knows - * that the packet is part of a reassembled whole. This means - * that fd_wtp will be NULL as long as Wireshark did not encounter - * (and process) the packet containing the last fragment. - * This implies that Wireshark needs two passes over the data for - * correct reassembly. At the first pass, a capture containing - * three fragments plus a retransmssion of the last fragment - * will progressively show: - * - * Packet 1: (Unreassembled fragment 1) - * Packet 2: (Unreassembled fragment 2) - * Packet 3: (Reassembled WTP) - * Packet 4: (WTP payload reassembled in packet 3) - * - * However at subsequent evaluation (e.g., by applying a display - * filter) the packet summary will show: - * - * Packet 1: (WTP payload reassembled in packet 3) - * Packet 2: (WTP payload reassembled in packet 3) - * Packet 3: (Reassembled WTP) - * Packet 4: (WTP payload reassembled in packet 3) - * - * This is important to know, and also affects read filters! - */ - wsp_tvb = process_reassembled_data(tvb, dataOffset, pinfo, - "Reassembled WTP", fd_wtp, &wtp_frag_items, - NULL, wtp_tree); + /* Try to reassemble if needed, and hand over to WSP + * A fragmented WTP packet is either: + * - An INVOKE with fTTR (transmission trailer) not set, + * - a SEGMENTED_INVOKE, + * - A RESULT with fTTR (transmission trailer) not set, + * - a SEGMENTED_RESULT. + */ + if ( ( (pdut == SEGMENTED_INVOKE) || (pdut == SEGMENTED_RESULT) + || ( ((pdut == INVOKE) || (pdut == RESULT)) && (!fTTR) ) + ) && tvb_bytes_exist(tvb, dataOffset, dataLen) ) + { + /* Try reassembling fragments */ + fragment_data *fd_wtp = NULL; + guint32 reassembled_in = 0; + gboolean save_fragmented = pinfo->fragmented; + + pinfo->fragmented = TRUE; + fd_wtp = fragment_add_seq(tvb, dataOffset, pinfo, TID, + wtp_fragment_table, psn, dataLen, !fTTR); + /* XXX - fragment_add_seq() yields NULL unless Wireshark knows + * that the packet is part of a reassembled whole. This means + * that fd_wtp will be NULL as long as Wireshark did not encounter + * (and process) the packet containing the last fragment. + * This implies that Wireshark needs two passes over the data for + * correct reassembly. At the first pass, a capture containing + * three fragments plus a retransmssion of the last fragment + * will progressively show: + * + * Packet 1: (Unreassembled fragment 1) + * Packet 2: (Unreassembled fragment 2) + * Packet 3: (Reassembled WTP) + * Packet 4: (WTP payload reassembled in packet 3) + * + * However at subsequent evaluation (e.g., by applying a display + * filter) the packet summary will show: + * + * Packet 1: (WTP payload reassembled in packet 3) + * Packet 2: (WTP payload reassembled in packet 3) + * Packet 3: (Reassembled WTP) + * Packet 4: (WTP payload reassembled in packet 3) + * + * This is important to know, and also affects read filters! + */ + wsp_tvb = process_reassembled_data(tvb, dataOffset, pinfo, + "Reassembled WTP", fd_wtp, &wtp_frag_items, + NULL, wtp_tree); #ifdef DEBUG - printf("WTP: Packet %u %s -> %d: wsp_tvb = %p, fd_wtp = %p, frame = %u\n", - pinfo->fd->num, - fd_wtp ? "Reassembled" : "Not reassembled", - fd_wtp ? fd_wtp->reassembled_in : -1, - wsp_tvb, - fd_wtp - ); + printf("WTP: Packet %u %s -> %d: wsp_tvb = %p, fd_wtp = %p, frame = %u\n", + pinfo->fd->num, + fd_wtp ? "Reassembled" : "Not reassembled", + fd_wtp ? fd_wtp->reassembled_in : -1, + wsp_tvb, + fd_wtp + ); #endif - if (fd_wtp) { - /* Reassembled */ - reassembled_in = fd_wtp->reassembled_in; - if (pinfo->fd->num == reassembled_in) { - /* Reassembled in this very packet: - * We can safely hand the tvb to the WSP dissector */ - call_dissector(wsp_handle, wsp_tvb, pinfo, tree); - } else { - /* Not reassembled in this packet */ - if (check_col(pinfo->cinfo, COL_INFO)) { - col_append_fstr(pinfo->cinfo, COL_INFO, - "%s (WTP payload reassembled in packet %u)", - szInfo, fd_wtp->reassembled_in); - } - if (tree) { - proto_tree_add_text(wtp_tree, tvb, dataOffset, -1, - "Payload"); - } - } - } else { - /* Not reassembled yet, or not reassembled at all */ - if (check_col(pinfo->cinfo, COL_INFO)) { - col_append_fstr(pinfo->cinfo, COL_INFO, - "%s (Unreassembled fragment %u)", - szInfo, psn); - } - if (tree) { - proto_tree_add_text(wtp_tree, tvb, dataOffset, -1, - "Payload"); - } - } - /* Now reset fragmentation information in pinfo */ - pinfo->fragmented = save_fragmented; - } - else if ( ((pdut == INVOKE) || (pdut == RESULT)) && (fTTR) ) - { - /* Non-fragmented payload */ - wsp_tvb = tvb_new_subset_remaining(tvb, dataOffset); - /* We can safely hand the tvb to the WSP dissector */ - call_dissector(wsp_handle, wsp_tvb, pinfo, tree); - } - else - { - /* Nothing to hand to subdissector */ - if (check_col(pinfo->cinfo, COL_INFO)) - col_append_str(pinfo->cinfo, COL_INFO, szInfo); - } - } - else - { - /* Nothing to hand to subdissector */ - if (check_col(pinfo->cinfo, COL_INFO)) - col_append_str(pinfo->cinfo, COL_INFO, szInfo); - } + if (fd_wtp) { + /* Reassembled */ + reassembled_in = fd_wtp->reassembled_in; + if (pinfo->fd->num == reassembled_in) { + /* Reassembled in this very packet: + * We can safely hand the tvb to the WSP dissector */ + call_dissector(wsp_handle, wsp_tvb, pinfo, tree); + } else { + /* Not reassembled in this packet */ + if (check_col(pinfo->cinfo, COL_INFO)) { + col_append_fstr(pinfo->cinfo, COL_INFO, + "%s (WTP payload reassembled in packet %u)", + szInfo, fd_wtp->reassembled_in); + } + if (tree) { + proto_tree_add_text(wtp_tree, tvb, dataOffset, -1, + "Payload"); + } + } + } else { + /* Not reassembled yet, or not reassembled at all */ + if (check_col(pinfo->cinfo, COL_INFO)) { + col_append_fstr(pinfo->cinfo, COL_INFO, + "%s (Unreassembled fragment %u)", + szInfo, psn); + } + if (tree) { + proto_tree_add_text(wtp_tree, tvb, dataOffset, -1, + "Payload"); + } + } + /* Now reset fragmentation information in pinfo */ + pinfo->fragmented = save_fragmented; + } + else if ( ((pdut == INVOKE) || (pdut == RESULT)) && (fTTR) ) + { + /* Non-fragmented payload */ + wsp_tvb = tvb_new_subset_remaining(tvb, dataOffset); + /* We can safely hand the tvb to the WSP dissector */ + call_dissector(wsp_handle, wsp_tvb, pinfo, tree); + } + else + { + /* Nothing to hand to subdissector */ + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, szInfo); + } + } + else + { + /* Nothing to hand to subdissector */ + if (check_col(pinfo->cinfo, COL_INFO)) + col_append_str(pinfo->cinfo, COL_INFO, szInfo); + } } /* @@ -822,274 +817,239 @@ proto_register_wtp(void) /* Setup list of header fields */ static hf_register_info hf[] = { - { &hf_wtp_header_sub_pdu_size, - { "Sub PDU size", - "wtp.sub_pdu_size", - FT_UINT16, BASE_DEC, NULL, 0x0, - "Size of Sub-PDU (bytes)", HFILL - } - }, - { &hf_wtp_header_flag_continue, - { "Continue Flag", - "wtp.continue_flag", - FT_BOOLEAN, 8, TFS( &continue_truth ), 0x80, - NULL, HFILL - } - }, - { &hf_wtp_header_pdu_type, - { "PDU Type", - "wtp.pdu_type", - FT_UINT8, BASE_HEX, VALS( vals_wtp_pdu_type ), 0x78, - NULL, HFILL - } - }, - { &hf_wtp_header_flag_Trailer, - { "Trailer Flags", - "wtp.trailer_flags", - FT_UINT8, BASE_HEX, VALS( vals_transaction_trailer ), 0x06, - NULL, HFILL - } - }, - { &hf_wtp_header_flag_RID, - { "Re-transmission Indicator", - "wtp.RID", - FT_BOOLEAN, 8, TFS( &RID_truth ), 0x01, - NULL, HFILL - } - }, - { &hf_wtp_header_flag_TID_response, - { "TID Response", - "wtp.TID.response", - FT_BOOLEAN, 16, TFS( &tid_response_truth ), 0x8000, - NULL, HFILL - } - }, - { &hf_wtp_header_flag_TID, - { "Transaction ID", - "wtp.TID", - FT_UINT16, BASE_HEX, NULL, 0x7FFF, - NULL, HFILL - } - }, - { &hf_wtp_header_Inv_version, - { "Version", - "wtp.header.version", - FT_UINT8, BASE_HEX, VALS( vals_version ), 0xC0, - NULL, HFILL - } - }, - { &hf_wtp_header_Inv_flag_TIDNew, - { "TIDNew", - "wtp.header.TIDNew", - FT_BOOLEAN, 8, TFS( &TIDNew_truth ), 0x20, - NULL, HFILL - } - }, - { &hf_wtp_header_Inv_flag_UP, - { "U/P flag", - "wtp.header.UP", - FT_BOOLEAN, 8, TFS( &UP_truth ), 0x10, - NULL, HFILL - } - }, - { &hf_wtp_header_Inv_Reserved, - { "Reserved", - "wtp.inv.reserved", - FT_UINT8, BASE_HEX, NULL, 0x0C, - NULL, HFILL - } - }, - { &hf_wtp_header_Inv_TransactionClass, - { "Transaction Class", - "wtp.inv.transaction_class", - FT_UINT8, BASE_HEX, VALS( vals_transaction_classes ), 0x03, - NULL, HFILL - } - }, - { &hf_wtp_header_Ack_flag_TVETOK, - { "Tve/Tok flag", - "wtp.ack.tvetok", - FT_BOOLEAN, 8, TFS( &TVETOK_truth ), 0x04, - NULL, HFILL - } - }, - { &hf_wtp_header_Abort_type, - { "Abort Type", - "wtp.abort.type", - FT_UINT8, BASE_HEX, VALS ( vals_abort_type ), 0x07, - NULL, HFILL - } - }, - { &hf_wtp_header_Abort_reason_provider, - { "Abort Reason", - "wtp.abort.reason.provider", - FT_UINT8, BASE_HEX, VALS ( vals_abort_reason_provider ), 0x00, - NULL, HFILL - } - }, - /* Assume WSP is the user and use its reason codes */ - { &hf_wtp_header_Abort_reason_user, - { "Abort Reason", - "wtp.abort.reason.user", - FT_UINT8, BASE_HEX|BASE_EXT_STRING, &vals_wsp_reason_codes_ext, 0x00, - NULL, HFILL - } - }, - { &hf_wtp_header_sequence_number, - { "Packet Sequence Number", - "wtp.header.sequence", - FT_UINT8, BASE_DEC, NULL, 0x00, - NULL, HFILL - } - }, - { &hf_wtp_header_missing_packets, - { "Missing Packets", - "wtp.header.missing_packets", - FT_UINT8, BASE_DEC, NULL, 0x00, - NULL, HFILL - } - }, - { &hf_wtp_header_variable_part, - { "Header: Variable part", - "wtp.header_variable_part", - FT_BYTES, BASE_NONE, NULL, 0x0, - "Variable part of the header", HFILL - } - }, - { &hf_wtp_data, - { "Data", - "wtp.header_data", - FT_BYTES, BASE_NONE, NULL, 0x0, - NULL, HFILL - } - }, - { &hf_wtp_tpi_type, - { "TPI", - "wtp.tpi", - FT_UINT8, BASE_HEX, VALS(vals_tpi_type), 0x00, - "Identification of the Transport Information Item", HFILL - } - }, - { &hf_wtp_tpi_psn, - { "Packet sequence number", - "wtp.tpi.psn", - FT_UINT8, BASE_DEC, NULL, 0x00, - "Sequence number of this packet", HFILL - } - }, - { &hf_wtp_tpi_opt, - { "Option", - "wtp.tpi.opt", - FT_UINT8, BASE_HEX, VALS(vals_tpi_opt), 0x00, - "The given option for this TPI", HFILL - } - }, - { &hf_wtp_tpi_optval, - { "Option Value", - "wtp.tpi.opt.val", - FT_NONE, BASE_NONE, NULL, 0x00, - "The value that is supplied with this option", HFILL - } - }, - { &hf_wtp_tpi_info, - { "Information", - "wtp.tpi.info", - FT_NONE, BASE_NONE, NULL, 0x00, - "The information being send by this TPI", HFILL - } - }, - - /* Fragment fields */ - { &hf_wtp_fragment_overlap, - { "Fragment overlap", - "wtp.fragment.overlap", - FT_BOOLEAN, BASE_NONE, NULL, 0x0, - "Fragment overlaps with other fragments", HFILL - } - }, - { &hf_wtp_fragment_overlap_conflict, - { "Conflicting data in fragment overlap", - "wtp.fragment.overlap.conflict", - FT_BOOLEAN, BASE_NONE, NULL, 0x0, - "Overlapping fragments contained conflicting data", HFILL - } - }, - { &hf_wtp_fragment_multiple_tails, - { "Multiple tail fragments found", - "wtp.fragment.multipletails", - FT_BOOLEAN, BASE_NONE, NULL, 0x0, - "Several tails were found when defragmenting the packet", HFILL - } - }, - { &hf_wtp_fragment_too_long_fragment, - { "Fragment too long", - "wtp.fragment.toolongfragment", - FT_BOOLEAN, BASE_NONE, NULL, 0x0, - "Fragment contained data past end of packet", HFILL - } - }, - { &hf_wtp_fragment_error, - { "Defragmentation error", - "wtp.fragment.error", - FT_FRAMENUM, BASE_NONE, NULL, 0x0, - "Defragmentation error due to illegal fragments", HFILL - } - }, - { &hf_wtp_fragment_count, - { "Fragment count", - "wtp.fragment.count", - FT_UINT32, BASE_DEC, NULL, 0x0, - NULL, HFILL - } - }, - { &hf_wtp_reassembled_in, - { "Reassembled in", - "wtp.reassembled.in", - FT_FRAMENUM, BASE_NONE, NULL, 0x0, - "WTP fragments are reassembled in the given packet", HFILL - } - }, - { &hf_wtp_reassembled_length, - { "Reassembled WTP length", - "wtp.reassembled.length", - FT_UINT32, BASE_DEC, NULL, 0x0, - "The total length of the reassembled payload", HFILL - } - }, - { &hf_wtp_fragment, - { "WTP Fragment", - "wtp.fragment", - FT_FRAMENUM, BASE_NONE, NULL, 0x0, - NULL, HFILL - } - }, - { &hf_wtp_fragments, - { "WTP Fragments", - "wtp.fragments", - FT_NONE, BASE_NONE, NULL, 0x0, - NULL, HFILL - } - }, + { &hf_wtp_header_sub_pdu_size, + { "Sub PDU size", "wtp.sub_pdu_size", + FT_UINT16, BASE_DEC, NULL, 0x0, + "Size of Sub-PDU (bytes)", HFILL + } + }, + { &hf_wtp_header_flag_continue, + { "Continue Flag", "wtp.continue_flag", + FT_BOOLEAN, 8, TFS( &continue_truth ), 0x80, + NULL, HFILL + } + }, + { &hf_wtp_header_pdu_type, + { "PDU Type", "wtp.pdu_type", + FT_UINT8, BASE_HEX, VALS( vals_wtp_pdu_type ), 0x78, + NULL, HFILL + } + }, + { &hf_wtp_header_flag_Trailer, + { "Trailer Flags", "wtp.trailer_flags", + FT_UINT8, BASE_HEX, VALS( vals_transaction_trailer ), 0x06, + NULL, HFILL + } + }, + { &hf_wtp_header_flag_RID, + { "Re-transmission Indicator", "wtp.RID", + FT_BOOLEAN, 8, TFS( &RID_truth ), 0x01, + NULL, HFILL + } + }, + { &hf_wtp_header_flag_TID_response, + { "TID Response", "wtp.TID.response", + FT_BOOLEAN, 16, TFS( &tid_response_truth ), 0x8000, + NULL, HFILL + } + }, + { &hf_wtp_header_flag_TID, + { "Transaction ID", "wtp.TID", + FT_UINT16, BASE_HEX, NULL, 0x7FFF, + NULL, HFILL + } + }, + { &hf_wtp_header_Inv_version, + { "Version", "wtp.header.version", + FT_UINT8, BASE_HEX, VALS( vals_version ), 0xC0, + NULL, HFILL + } + }, + { &hf_wtp_header_Inv_flag_TIDNew, + { "TIDNew", "wtp.header.TIDNew", + FT_BOOLEAN, 8, TFS( &TIDNew_truth ), 0x20, + NULL, HFILL + } + }, + { &hf_wtp_header_Inv_flag_UP, + { "U/P flag", "wtp.header.UP", + FT_BOOLEAN, 8, TFS( &UP_truth ), 0x10, + NULL, HFILL + } + }, + { &hf_wtp_header_Inv_Reserved, + { "Reserved", "wtp.inv.reserved", + FT_UINT8, BASE_HEX, NULL, 0x0C, + NULL, HFILL + } + }, + { &hf_wtp_header_Inv_TransactionClass, + { "Transaction Class", "wtp.inv.transaction_class", + FT_UINT8, BASE_HEX, VALS( vals_transaction_classes ), 0x03, + NULL, HFILL + } + }, + { &hf_wtp_header_Ack_flag_TVETOK, + { "Tve/Tok flag", "wtp.ack.tvetok", + FT_BOOLEAN, 8, TFS( &TVETOK_truth ), 0x04, + NULL, HFILL + } + }, + { &hf_wtp_header_Abort_type, + { "Abort Type", "wtp.abort.type", + FT_UINT8, BASE_HEX, VALS ( vals_abort_type ), 0x07, + NULL, HFILL + } + }, + { &hf_wtp_header_Abort_reason_provider, + { "Abort Reason", "wtp.abort.reason.provider", + FT_UINT8, BASE_HEX, VALS ( vals_abort_reason_provider ), 0x00, + NULL, HFILL + } + }, + /* Assume WSP is the user and use its reason codes */ + { &hf_wtp_header_Abort_reason_user, + { "Abort Reason", "wtp.abort.reason.user", + FT_UINT8, BASE_HEX|BASE_EXT_STRING, &vals_wsp_reason_codes_ext, 0x00, + NULL, HFILL + } + }, + { &hf_wtp_header_sequence_number, + { "Packet Sequence Number", "wtp.header.sequence", + FT_UINT8, BASE_DEC, NULL, 0x00, + NULL, HFILL + } + }, + { &hf_wtp_header_missing_packets, + { "Missing Packets", "wtp.header.missing_packets", + FT_UINT8, BASE_DEC, NULL, 0x00, + NULL, HFILL + } + }, + { &hf_wtp_header_variable_part, + { "Header: Variable part", "wtp.header_variable_part", + FT_BYTES, BASE_NONE, NULL, 0x0, + "Variable part of the header", HFILL + } + }, + { &hf_wtp_data, + { "Data", "wtp.header_data", + FT_BYTES, BASE_NONE, NULL, 0x0, + NULL, HFILL + } + }, + { &hf_wtp_tpi_type, + { "TPI", "wtp.tpi", + FT_UINT8, BASE_HEX, VALS(vals_tpi_type), 0x00, + "Identification of the Transport Information Item", HFILL + } + }, + { &hf_wtp_tpi_psn, + { "Packet sequence number", "wtp.tpi.psn", + FT_UINT8, BASE_DEC, NULL, 0x00, + "Sequence number of this packet", HFILL + } + }, + { &hf_wtp_tpi_opt, + { "Option", "wtp.tpi.opt", + FT_UINT8, BASE_HEX, VALS(vals_tpi_opt), 0x00, + "The given option for this TPI", HFILL + } + }, + { &hf_wtp_tpi_optval, + { "Option Value", "wtp.tpi.opt.val", + FT_NONE, BASE_NONE, NULL, 0x00, + "The value that is supplied with this option", HFILL + } + }, + { &hf_wtp_tpi_info, + { "Information", "wtp.tpi.info", + FT_NONE, BASE_NONE, NULL, 0x00, + "The information being send by this TPI", HFILL + } + }, + + /* Fragment fields */ + { &hf_wtp_fragment_overlap, + { "Fragment overlap", "wtp.fragment.overlap", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "Fragment overlaps with other fragments", HFILL + } + }, + { &hf_wtp_fragment_overlap_conflict, + { "Conflicting data in fragment overlap", "wtp.fragment.overlap.conflict", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "Overlapping fragments contained conflicting data", HFILL + } + }, + { &hf_wtp_fragment_multiple_tails, + { "Multiple tail fragments found", "wtp.fragment.multipletails", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "Several tails were found when defragmenting the packet", HFILL + } + }, + { &hf_wtp_fragment_too_long_fragment, + { "Fragment too long", "wtp.fragment.toolongfragment", + FT_BOOLEAN, BASE_NONE, NULL, 0x0, + "Fragment contained data past end of packet", HFILL + } + }, + { &hf_wtp_fragment_error, + { "Defragmentation error", "wtp.fragment.error", + FT_FRAMENUM, BASE_NONE, NULL, 0x0, + "Defragmentation error due to illegal fragments", HFILL + } + }, + { &hf_wtp_fragment_count, + { "Fragment count", "wtp.fragment.count", + FT_UINT32, BASE_DEC, NULL, 0x0, + NULL, HFILL + } + }, + { &hf_wtp_reassembled_in, + { "Reassembled in", "wtp.reassembled.in", + FT_FRAMENUM, BASE_NONE, NULL, 0x0, + "WTP fragments are reassembled in the given packet", HFILL + } + }, + { &hf_wtp_reassembled_length, + { "Reassembled WTP length", "wtp.reassembled.length", + FT_UINT32, BASE_DEC, NULL, 0x0, + "The total length of the reassembled payload", HFILL + } + }, + { &hf_wtp_fragment, + { "WTP Fragment", "wtp.fragment", + FT_FRAMENUM, BASE_NONE, NULL, 0x0, + NULL, HFILL + } + }, + { &hf_wtp_fragments, + { "WTP Fragments", "wtp.fragments", + FT_NONE, BASE_NONE, NULL, 0x0, + NULL, HFILL + } + }, }; /* Setup protocol subtree array */ static gint *ett[] = { - &ett_wtp, - &ett_wtp_sub_pdu_tree, - &ett_header, - &ett_tpilist, - &ett_wsp_fragments, - &ett_wtp_fragment, + &ett_wtp, + &ett_wtp_sub_pdu_tree, + &ett_header, + &ett_tpilist, + &ett_wsp_fragments, + &ett_wtp_fragment, }; /* Register the protocol name and description */ proto_wtp = proto_register_protocol( - "Wireless Transaction Protocol", /* protocol name for use by wireshark */ - "WTP", /* short version of name */ - "wtp" /* Abbreviated protocol name, should Match IANA - < URL:http://www.iana.org/assignments/port-numbers/ > - */ - ); + "Wireless Transaction Protocol", /* protocol name for use by wireshark */ + "WTP", /* short version of name */ + "wtp" /* Abbreviated protocol name, should Match IANA + < URL:http://www.iana.org/assignments/port-numbers/ > + */ + ); /* Required calls to register the header fields and subtrees used */ proto_register_field_array(proto_wtp, hf, array_length(hf)); @@ -1116,3 +1076,16 @@ proto_reg_handoff_wtp(void) dissector_add_uint("gsm-sms-ud.udh.port", UDP_PORT_WTP_WSP, wtp_fromudp_handle); dissector_add_uint("gsm-sms.udh.port", UDP_PORT_WTP_WSP, wtp_fromudp_handle); } + +/* + * Editor modelines - http://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 4 + * tab-width: 4 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=4 tabstop=4 expandtab: + * :indentSize=4:tabSize=4:noTabs=true: + */ diff --git a/print.ps b/print.ps index 5ae242934c..523abf6f87 100644 --- a/print.ps +++ b/print.ps @@ -4,6 +4,7 @@ % Anything else is thrown away, and is for testing only. % % ---- wireshark preamble start ---- % +%! %!PS-Adobe-2.0 % % Wireshark - Network traffic analyzer diff --git a/ui/cli/tap-iostat.c b/ui/cli/tap-iostat.c index 35e0a49465..1f259ebae4 100644 --- a/ui/cli/tap-iostat.c +++ b/ui/cli/tap-iostat.c @@ -38,14 +38,14 @@ #include "globals.h" #define CALC_TYPE_FRAMES 0 -#define CALC_TYPE_BYTES 1 -#define CALC_TYPE_FRAMES_AND_BYTES 2 -#define CALC_TYPE_COUNT 3 -#define CALC_TYPE_SUM 4 -#define CALC_TYPE_MIN 5 -#define CALC_TYPE_MAX 6 -#define CALC_TYPE_AVG 7 -#define CALC_TYPE_LOAD 8 +#define CALC_TYPE_BYTES 1 +#define CALC_TYPE_FRAMES_AND_BYTES 2 +#define CALC_TYPE_COUNT 3 +#define CALC_TYPE_SUM 4 +#define CALC_TYPE_MIN 5 +#define CALC_TYPE_MAX 6 +#define CALC_TYPE_AVG 7 +#define CALC_TYPE_LOAD 8 typedef struct { const char *func_name; @@ -104,7 +104,7 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du GPtrArray *gp; guint i; int ftype; - + mit = (io_stat_item_t *) arg; parent = mit->parent; relative_time = (guint64)((pinfo->fd->rel_ts.secs*1000000) + ((pinfo->fd->rel_ts.nsecs+500)/1000)); @@ -122,7 +122,7 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du } /* If we have moved into a new interval (row), create a new io_stat_item_t struct for every interval - * between the last struct and this one. If an item was not found in a previous interval, an empty + * between the last struct and this one. If an item was not found in a previous interval, an empty * struct will be created for it. */ rt = relative_time; while (rt >= it->time + parent->interval) { @@ -184,7 +184,7 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du it->counter += (gint64)fvalue_get_integer64(&((field_info *)gp->pdata[i])->value); break; case FT_FLOAT: - it->float_counter += + it->float_counter += (gfloat)fvalue_get_floating(&((field_info *)gp->pdata[i])->value); break; case FT_DOUBLE: @@ -244,7 +244,7 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du val = fvalue_get_integer64(&((field_info *)gp->pdata[i])->value); if((it->frames==1 && i==0) || ((gint64)val < (gint64)it->counter)) { it->counter=val; - } + } break; case FT_FLOAT: float_val=(gfloat)fvalue_get_floating(&((field_info *)gp->pdata[i])->value); @@ -256,7 +256,7 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du double_val=fvalue_get_floating(&((field_info *)gp->pdata[i])->value); if((it->frames==1 && i==0) || (double_val < it->double_counter)) { it->double_counter=double_val; - } + } break; case FT_RELATIVE_TIME: new_time = (nstime_t *)fvalue_get(&((field_info *)gp->pdata[i])->value); @@ -296,7 +296,7 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du break; case FT_UINT64: val = fvalue_get_integer64(&((field_info *)gp->pdata[i])->value); - if(val > it->counter) + if(val > it->counter) it->counter=val; break; case FT_INT8: @@ -304,12 +304,12 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du case FT_INT24: case FT_INT32: val = fvalue_get_sinteger(&((field_info *)gp->pdata[i])->value); - if((gint32)val > (gint32)it->counter) + if((gint32)val > (gint32)it->counter) it->counter=val; break; case FT_INT64: val = fvalue_get_integer64(&((field_info *)gp->pdata[i])->value); - if ((gint64)val > (gint64)it->counter) + if ((gint64)val > (gint64)it->counter) it->counter=val; break; case FT_FLOAT: @@ -343,7 +343,7 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du gp=proto_get_finfo_ptr_array(edt->tree, it->hf_index); if(gp){ guint64 val; - + ftype=proto_registrar_get_ftype(it->hf_index); for(i=0;ilen;i++){ it->num++; @@ -422,21 +422,21 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du } break; } - /* Store the highest value for this item in order to determine the width of each stat column. + /* Store the highest value for this item in order to determine the width of each stat column. * For real numbers we only need to know its magnitude (the value to the left of the decimal point * so round it up before storing it as an integer in max_vals. For AVG of RELATIVE_TIME fields, * calc the average, round it to the next second and store the seconds. For all other calc types - * of RELATIVE_TIME fields, store the counters without modification. + * of RELATIVE_TIME fields, store the counters without modification. * fields. */ switch(it->calc_type) { case CALC_TYPE_FRAMES: case CALC_TYPE_FRAMES_AND_BYTES: - parent->max_frame[it->colnum] = + parent->max_frame[it->colnum] = MAX(parent->max_frame[it->colnum], it->frames); if (it->calc_type==CALC_TYPE_FRAMES_AND_BYTES) - parent->max_vals[it->colnum] = + parent->max_vals[it->colnum] = MAX(parent->max_vals[it->colnum], it->counter); - + case CALC_TYPE_BYTES: case CALC_TYPE_COUNT: case CALC_TYPE_LOAD: @@ -448,20 +448,20 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du ftype=proto_registrar_get_ftype(it->hf_index); switch(ftype) { case FT_FLOAT: - parent->max_vals[it->colnum] = + parent->max_vals[it->colnum] = MAX(parent->max_vals[it->colnum], (guint64)(it->float_counter+0.5)); break; case FT_DOUBLE: - parent->max_vals[it->colnum] = + parent->max_vals[it->colnum] = MAX(parent->max_vals[it->colnum],(guint64)(it->double_counter+0.5)); break; case FT_RELATIVE_TIME: - parent->max_vals[it->colnum] = - MAX(parent->max_vals[it->colnum], it->counter); - break; + parent->max_vals[it->colnum] = + MAX(parent->max_vals[it->colnum], it->counter); + break; default: /* UINT16-64 and INT8-64 */ - parent->max_vals[it->colnum] = + parent->max_vals[it->colnum] = MAX(parent->max_vals[it->colnum], it->counter); break; } @@ -472,20 +472,20 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du ftype=proto_registrar_get_ftype(it->hf_index); switch(ftype) { case FT_FLOAT: - parent->max_vals[it->colnum] = + parent->max_vals[it->colnum] = MAX(parent->max_vals[it->colnum], (guint64)it->float_counter/it->num); break; case FT_DOUBLE: - parent->max_vals[it->colnum] = + parent->max_vals[it->colnum] = MAX(parent->max_vals[it->colnum],(guint64)it->double_counter/it->num); break; case FT_RELATIVE_TIME: - parent->max_vals[it->colnum] = - MAX(parent->max_vals[it->colnum], ((it->counter/it->num) + 500000000) / NANOSECS_PER_SEC); + parent->max_vals[it->colnum] = + MAX(parent->max_vals[it->colnum], ((it->counter/it->num) + 500000000) / NANOSECS_PER_SEC); break; default: /* UINT16-64 and INT8-64 */ - parent->max_vals[it->colnum] = + parent->max_vals[it->colnum] = MAX(parent->max_vals[it->colnum], it->counter/it->num); break; } @@ -493,21 +493,21 @@ iostat_packet(void *arg, packet_info *pinfo, epan_dissect_t *edt, const void *du return TRUE; } -static int +static int magnitude (guint64 val, int max_w) { int i, mag=0; for (i=0; i 0 && len < 6) { - spaces_ptr = &spaces[len]; + spaces_ptr = &spaces[len]; if ((lenval-lenlab)%2==0) { printf("%s%s%s|", spaces_ptr, label, spaces_ptr); } else { - printf("%s%s%s|", spaces_ptr-1, label, spaces_ptr); + printf("%s%s%s|", spaces_ptr-1, label, spaces_ptr); } } else if (len > 0 && len <= 15) { printf("%s|", label); @@ -548,7 +548,7 @@ iostat_draw(void *arg) io_stat_item_t *mit, **stat_cols, *item, **item_in_column; gboolean last_row=FALSE; io_stat_t *iot; - column_width *col_w; + column_width *col_w; struct tm * tm_time; time_t the_time; @@ -576,19 +576,19 @@ iostat_draw(void *arg) /* Calc the capture duration's magnitude (dur_mag) */ dur_secs = (int)duration/1000000; dur_mag = magnitude((guint64)dur_secs, 5); - g_snprintf(dur_mag_s, 3, "%u", dur_mag); + g_snprintf(dur_mag_s, 3, "%u", dur_mag); /* Calc the interval's magnitude */ - invl_mag = magnitude((guint64)interval/1000000, 5); + invl_mag = magnitude((guint64)interval/1000000, 5); /* Set or get the interval precision */ if (interval==duration) { - /* + /* * An interval arg of 0 or an interval size exceeding the capture duration was specified. * Set the decimal precision of duration based on its magnitude. */ if (dur_mag >= 2) invl_prec = 1; - else if (dur_mag==1) + else if (dur_mag==1) invl_prec = 3; else invl_prec = 6; @@ -604,7 +604,7 @@ iostat_draw(void *arg) for (i=0; iinterval==G_MAXINT32) + if (iot->interval==G_MAXINT32) interval = duration; /* Recalc the dur_mag in case rounding has increased its magnitude */ @@ -612,18 +612,18 @@ iostat_draw(void *arg) dur_mag = magnitude((guint64)dur_secs, 5); /* Calc the width of the time interval column (incl borders and padding). */ - if (invl_prec==0) + if (invl_prec==0) invl_col_w = (2*dur_mag) + 8; else invl_col_w = (2*dur_mag) + (2*invl_prec) + 10; - /* Update the width of the time interval column for "-t ad" */ - if (timestamp_get_type()==TS_ABSOLUTE_WITH_DATE) + /* Update the width of the time interval column for "-t ad" */ + if (timestamp_get_type()==TS_ABSOLUTE_WITH_DATE) invl_col_w = MAX(invl_col_w, 23); - else - invl_col_w = MAX(invl_col_w, 12); + else + invl_col_w = MAX(invl_col_w, 12); - borderlen = MAX(borderlen, invl_col_w); + borderlen = MAX(borderlen, invl_col_w); /* Calc the total width of each row in the stats table and build the printf format string for each * column based on its field type, width, and name length. @@ -647,9 +647,9 @@ iostat_draw(void *arg) g_snprintf(fr_mag_s, 3, "%u", fr_mag); if (type==CALC_TYPE_FRAMES) { - fmt = g_strconcat(" %", fr_mag_s, "u |", NULL); - } else { - /* CALC_TYPE_FRAMES_AND_BYTES + fmt = g_strconcat(" %", fr_mag_s, "u |", NULL); + } else { + /* CALC_TYPE_FRAMES_AND_BYTES */ val_mag = magnitude(iot->max_vals[j], 15); val_mag = MAX(5, val_mag); @@ -672,10 +672,10 @@ iostat_draw(void *arg) g_snprintf(val_mag_s, 3, "%u", val_mag); fmt = g_strconcat(" %", val_mag_s, G_GINT64_MODIFIER, "u |", NULL); break; - + default: ftype = proto_registrar_get_ftype(stat_cols[j]->hf_index); - switch (ftype) { + switch (ftype) { case FT_FLOAT: case FT_DOUBLE: val_mag = magnitude(iot->max_vals[j], 15); @@ -684,7 +684,7 @@ iostat_draw(void *arg) col_w[j].val = val_mag + 7; break; case FT_RELATIVE_TIME: - /* Convert FT_RELATIVE_TIME field to seconds + /* Convert FT_RELATIVE_TIME field to seconds * CALC_TYPE_LOAD was already converted in iostat_packet() ) */ if (type==CALC_TYPE_LOAD) { iot->max_vals[j] /= interval; @@ -695,14 +695,14 @@ iostat_draw(void *arg) g_snprintf(val_mag_s, 3, "%u", val_mag); fmt = g_strconcat(" %", val_mag_s, "u.%06u |", NULL); col_w[j].val = val_mag + 7; - break; - + break; + default: val_mag = magnitude(iot->max_vals[j], 15); val_mag = MAX(namelen, val_mag); col_w[j].val = val_mag; g_snprintf(val_mag_s, 3, "%u", val_mag); - + switch (ftype) { case FT_UINT8: case FT_UINT16: @@ -710,7 +710,7 @@ iostat_draw(void *arg) case FT_UINT32: case FT_UINT64: fmt = g_strconcat(" %", val_mag_s, G_GINT64_MODIFIER, "u |", NULL); - break; + break; case FT_INT8: case FT_INT16: case FT_INT24: @@ -722,11 +722,11 @@ iostat_draw(void *arg) } /* End of ftype switch */ } /* End of calc_type switch */ tabrow_w += col_w[j].val + 3; - if (fmt) + if (fmt) fmts[j] = fmt; } /* End of for loop (columns) */ - borderlen = MAX(borderlen, tabrow_w); + borderlen = MAX(borderlen, tabrow_w); /* Calc the max width of the list of filters. */ maxfltr_w = 0; @@ -741,7 +741,7 @@ iostat_draw(void *arg) /* The stat table is not wrapped (by tshark) but filter is wrapped at the width of the stats table * (which currently = borderlen); however, if the filter width exceeds the table width and the * table width is less than 102 bytes, set borderlen to the lesser of the max filter width and 102. - * The filters will wrap at the lesser of borderlen-2 and the last space in the filter. + * The filters will wrap at the lesser of borderlen-2 and the last space in the filter. * NOTE: 102 is the typical size of a user window when the font is fixed width (e.g., COURIER 10). * XXX: A pref could be added to change the max width from the default size of 102. */ if (maxfltr_w > borderlen && borderlen < 102) @@ -749,27 +749,27 @@ iostat_draw(void *arg) /* Prevent double right border by adding a space */ if (borderlen-tabrow_w==1) - borderlen++; + borderlen++; /* Display the top border */ printf("\n"); for (i=0; i 0) { - g_snprintf(invl_prec_s, 3, "%u", invl_prec); - invl_fmt = g_strconcat("%", invl_mag_s, "u.%0", invl_prec_s, "u", NULL); + g_snprintf(invl_prec_s, 3, "%u", invl_prec); + invl_fmt = g_strconcat("%", invl_mag_s, "u.%0", invl_prec_s, "u", NULL); if (interval==duration) { full_fmt = g_strconcat("| Interval size: ", invl_fmt, " secs (dur)%s", NULL); spaces_s = &spaces[30+invl_mag+invl_prec]; @@ -788,24 +788,24 @@ iostat_draw(void *arg) g_free(invl_fmt); g_free(full_fmt); - if (invl_prec > 0) + if (invl_prec > 0) invl_fmt = g_strconcat("%", dur_mag_s, "u.%0", invl_prec_s, "u", NULL); - else + else invl_fmt = g_strconcat("%", dur_mag_s, "u", NULL); - + /* Display the list of filters and their column numbers vertically */ printf("|\n| Col"); for(j=0; jfilters[j] || (iot->filters[j]==0)) { - /* + if (!iot->filters[j] || (iot->filters[j]==0)) { + /* * An empty (no filter) comma field was specified */ spaces_s = &spaces[16 + 10]; printf("Frames and bytes%s|\n", spaces_s); } else { filter = iot->filters[j]; len_filt = (int) strlen(filter); - + /* If the width of the widest filter exceeds the width of the stat table, borderlen has * been set to 102 bytes above and filters wider than 102 will wrap at 91 bytes. */ if (len_filt+11 <= borderlen) { @@ -820,11 +820,11 @@ iostat_draw(void *arg) const gchar *pos; gsize len; int next_start, max_w=borderlen-11; - + do { if (len_filt > max_w) { sfilter1 = g_strndup( (gchar *) filter, (gsize) max_w); - /* + /* * Find the pos of the last space in sfilter1. If a space is found, set * sfilter2 to the string prior to that space and print it; otherwise, wrap * the filter at max_w. */ @@ -848,7 +848,7 @@ iostat_draw(void *arg) printf("%s%s|\n", filter, &spaces[((int)strlen(filter))+10]); break; } - } while (1); + } while (1); } } } @@ -867,11 +867,11 @@ iostat_draw(void *arg) for(j=0; jcalc_type==CALC_TYPE_FRAMES_AND_BYTES) - spaces_s = &spaces[borderlen - (col_w[j].fr + col_w[j].val)] - 3; + spaces_s = &spaces[borderlen - (col_w[j].fr + col_w[j].val)] - 3; else if (item->calc_type==CALC_TYPE_FRAMES) - spaces_s = &spaces[borderlen - col_w[j].fr]; + spaces_s = &spaces[borderlen - col_w[j].fr]; else - spaces_s = &spaces[borderlen - col_w[j].val]; + spaces_s = &spaces[borderlen - col_w[j].val]; printf("%-2u%s|", j+1, spaces_s); } @@ -879,15 +879,15 @@ iostat_draw(void *arg) filler_s = &spaces[tabrow_w+1]; printf("%s|", filler_s); } - - k = 11; + + k = 11; switch (timestamp_get_type()) { case TS_ABSOLUTE: printf("\n| Time "); break; case TS_ABSOLUTE_WITH_DATE: printf("\n| Date and time"); - k = 16; + k = 16; break; case TS_RELATIVE: case TS_NOT_SET: @@ -897,7 +897,7 @@ iostat_draw(void *arg) break; } - spaces_s = &spaces[borderlen-(invl_col_w-k)]; + spaces_s = &spaces[borderlen-(invl_col_w-k)]; printf("%s|", spaces_s); /* Display the stat label in each column */ @@ -934,7 +934,7 @@ iostat_draw(void *arg) item_in_column[j] = stat_cols[j]; } - /* Display the table values + /* Display the table values * * The outer loop is for time interval rows and the inner loop is for stat column items.*/ for (i=0; itm_hour, tm_time->tm_min, tm_time->tm_sec); break; - + case TS_ABSOLUTE_WITH_DATE: printf("| %04d-%02d-%02d %02d:%02d:%02d |", tm_time->tm_year + 1900, @@ -971,7 +971,7 @@ iostat_draw(void *arg) tm_time->tm_min, tm_time->tm_sec); break; - + case TS_RELATIVE: case TS_NOT_SET: @@ -998,7 +998,7 @@ iostat_draw(void *arg) /* Display stat values in each column for this row */ for (j=0; jcalc_type) { @@ -1063,8 +1063,8 @@ iostat_draw(void *arg) case FT_RELATIVE_TIME: if (!last_row) { printf(fmt, - (int) (item->counter/interval), - (int)((item->counter%interval)*1000000 / interval)); + (int) (item->counter/interval), + (int)((item->counter%interval)*1000000 / interval)); } else { printf(fmt, (int) (item->counter/(invl_end-t)), @@ -1079,7 +1079,7 @@ iostat_draw(void *arg) if (fmt) g_free(fmt); } else { - item_in_column[j] = item_in_column[j]->next; + item_in_column[j] = item_in_column[j]->next; } } else { printf(fmt, (guint64)0); @@ -1089,7 +1089,7 @@ iostat_draw(void *arg) printf("%s|", filler_s); printf("\n"); t += interval; - + } for(i=0;iitems[i].calc_type==CALC_TYPE_FRAMES || io->items[i].calc_type==CALC_TYPE_BYTES){ if(parenp!=p) { - fprintf(stderr, + fprintf(stderr, "\ntshark: %s does not require or allow a field name within the parens.\n", calc_type_table[j].func_name); exit(10); @@ -1276,13 +1276,29 @@ iostat_init(const char *optarg, void* userdata _U_) gdouble interval_float; guint32 idx=0, i; io_stat_t *io; - const gchar *filters=NULL, *str, *pos; + const gchar *filters, *str, *pos; - if (sscanf(optarg, "io,stat,%lf,%n", &interval_float, (int *)&idx)==0) { - fprintf(stderr, "\ntshark: invalid \"-z io,stat,[,]\" argument\n"); + if ((*(optarg+(strlen(optarg)-1)) == ',') || + (sscanf(optarg, "io,stat,%lf%n", &interval_float, (int *)&idx) != 1) || + (idx < 8)) { + fprintf(stderr, "\ntshark: invalid \"-z io,stat,[,][,]...\" argument\n"); exit(1); } + filters=optarg+idx; + if (*filters) { + if (*filters != ',') { + /* For locale's that use ',' instead of '.', the comma might + * have been consumed during the floating point conversion. */ + --filters; + if (*filters != ',') { + fprintf(stderr, "\ntshark: invalid \"-z io,stat,[,][,]...\" argument\n"); + exit(1); + } + } + } else + filters=NULL; + switch (timestamp_get_type()) { case TS_DELTA: case TS_DELTA_DIS: @@ -1291,11 +1307,11 @@ iostat_init(const char *optarg, void* userdata _U_) case TS_UTC_WITH_DATE: fprintf(stderr, "\ntshark: invalid -t operand. io,stat only supports -t \n"); exit(1); - default: - break; + default: + break; } - - io = (io_stat_t *) g_malloc(sizeof(io_stat_t)); + + io = (io_stat_t *) g_malloc(sizeof(io_stat_t)); /* If interval is 0, calculate statistics over the whole file by setting the interval to * G_MAXINT32 */ @@ -1308,7 +1324,7 @@ iostat_init(const char *optarg, void* userdata _U_) /* * Determine what interval precision the user has specified */ io->invl_prec = 6; - for (i=10; i<10000000; i*=10) { + for (i=10; i<10000000; i*=10) { if (io->interval%i > 0) break; io->invl_prec--; @@ -1324,17 +1340,12 @@ iostat_init(const char *optarg, void* userdata _U_) io->num_cols = 1; io->start_time=0; - if (idx) { - filters = optarg + idx; - if (strlen(filters) > 0 ) { - str = filters; - while((str = strchr(str, ','))) { - io->num_cols++; - str++; - } + if (filters && (*filters != '\0')) { + str = filters; + while((str = strchr(str, ','))) { + io->num_cols++; + str++; } - } else { - filters=NULL; } io->items = (io_stat_item_t *) g_malloc(sizeof(io_stat_item_t) * io->num_cols); @@ -1345,7 +1356,7 @@ iostat_init(const char *optarg, void* userdata _U_) for (i=0; inum_cols; i++) { io->max_vals[i] = 0; io->max_frame[i] = 0; - } + } /* Register a tap listener for each filter */ if((!filters) || (filters[0]==0)) { -- cgit v1.2.1