diff options
author | Anders Broman <anders.broman@ericsson.com> | 2012-10-16 11:29:36 +0000 |
---|---|---|
committer | Anders Broman <anders.broman@ericsson.com> | 2012-10-16 11:29:36 +0000 |
commit | 002b91578c4b6684311ed3f4474cd81a45aac8f0 (patch) | |
tree | 3ae17cadccf758df188c78b973bffa330759d417 | |
parent | 1a68210e9f6a8070f0885c754ac58020fa3bc59e (diff) | |
download | wireshark-002b91578c4b6684311ed3f4474cd81a45aac8f0.tar.gz |
Copy over:
--------------------------------------------------------------------------------
Revision 45462 - Change 'for (i=1; i<=n;...' to 'for (i=0; i<n; ...)'
Done on general principles altho none of the cases
changed would have actually resulted in an infinite
loop because a Bounds error would eventually occur.
--------------------------------------------------------------------------------
Revision 45355 - Fix https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7802 :
Avoid an infinite loop when number_of_dup_tsns is equal to 65535
--------------------------------------------------------------------------------
Revision 45338 - pinfo is now used
--------------------------------------------------------------------------------
Revision 45337 - Fix https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=7801 :
Ensure that the sub-type length is at least 2 (for sub-type and length fields).
Prevents an infinite loop when the length equals 0.
--------------------------------------------------------------------------------
Revision 45329 - The sFlow specification says there's an address type "unknown", with an
address type value of 0, and with zero bytes of address; handle it
explicitly, and don't treat it as an error.
In the sFlow dissectors, do all the checks for "is this an sFlow
packet?" *before* we do anything to the columns and the protocol tree.
--------------------------------------------------------------------------------
Revision 45324 - fix fuzz test failures in sflow
in dissect_sflow_245_address_type(), don't reset the offset to 0 when
the address family is unkown
bring up an expert info instead and increment offset by the number of
bytes processed
--------------------------------------------------------------------------------
Revision 45321 - From Sven Eckelmann:
Fix dissection of IEEE 802.11 Channel Switch Announcement element.
--------------------------------------------------------------------------------
Revision 44559 - Use capture scoped memory for hash table functionality
--------------------------------------------------------------------------------
Revision 44438 - Use val_to_str_const() where appropriate;(...) - Done only for affected files for easier compare.
--------------------------------------------------------------------------------
Revision 43538 - Update FSF address - part II. - - Done only for affected files for easier compare.
--------------------------------------------------------------------------------
svn path=/trunk-1.8/; revision=45578
-rw-r--r-- | epan/dissectors/packet-3g-a11.c | 22 | ||||
-rw-r--r-- | epan/dissectors/packet-ieee80211.c | 2 | ||||
-rw-r--r-- | epan/dissectors/packet-sctp.c | 106 | ||||
-rw-r--r-- | epan/dissectors/packet-sflow.c | 119 |
4 files changed, 120 insertions, 129 deletions
diff --git a/epan/dissectors/packet-3g-a11.c b/epan/dissectors/packet-3g-a11.c index e57ef27806..16bf303b59 100644 --- a/epan/dissectors/packet-3g-a11.c +++ b/epan/dissectors/packet-3g-a11.c @@ -29,7 +29,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. * *Ref: * http://www.3gpp2.org/Public_html/specs/A.S0009-C_v3.0_100621.pdf @@ -46,6 +46,7 @@ #include <glib.h> #include <epan/packet.h> +#include <epan/expert.h> /* Include vendor id translation */ #include <epan/sminmpec.h> @@ -607,10 +608,11 @@ dissect_a11_radius( tvbuff_t *tvb, packet_info *pinfo, int offset, proto_tree *t /* X.S0011-005-D v2.0 Service Option Profile */ static const gchar * -dissect_3gpp2_service_option_profile(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_) +dissect_3gpp2_service_option_profile(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo) { int offset = 0; guint8 sub_type, sub_type_length; + proto_item *pi; /* Maximum service connections/Link Flows total 32 bit*/ proto_tree_add_item(tree, hf_a11_serv_opt_prof_max_serv, tvb, offset, 4, ENC_BIG_ENDIAN); @@ -622,8 +624,12 @@ dissect_3gpp2_service_option_profile(proto_tree *tree, tvbuff_t *tvb, packet_i sub_type = tvb_get_guint8(tvb,offset); proto_tree_add_item(tree, hf_a11_sub_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; - proto_tree_add_item(tree, hf_a11_sub_type_length, tvb, offset, 1, ENC_BIG_ENDIAN); + pi = proto_tree_add_item(tree, hf_a11_sub_type_length, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; + if (sub_type_length < 2) { + expert_add_info_format(pinfo, pi, PI_PROTOCOL, PI_WARN, "Sub-Type Length should be at least 2"); + sub_type_length = 2; + } if (sub_type==1){ proto_tree_add_item(tree, hf_a11_serv_opt, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; @@ -648,7 +654,7 @@ static const value_string a11_aut_flow_prof_subtype_vals[] = { /* X.S0011-005-D v2.0 Authorized Flow Profile IDs for the User */ static const gchar * -dissect_3gpp2_radius_aut_flow_profile_ids(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo _U_) +dissect_3gpp2_radius_aut_flow_profile_ids(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo) { proto_tree *sub_tree; int offset = 0; @@ -662,12 +668,16 @@ dissect_3gpp2_radius_aut_flow_profile_ids(proto_tree *tree, tvbuff_t *tvb, pac /* value is 2 octets */ value = tvb_get_ntohs(tvb,offset+2); item = proto_tree_add_text(tree, tvb, offset, sub_type_length, "%s = %u", - val_to_str(sub_type, a11_aut_flow_prof_subtype_vals, "Unknown"), value); + val_to_str_const(sub_type, a11_aut_flow_prof_subtype_vals, "Unknown"), value); sub_tree = proto_item_add_subtree(item, ett_a11_aut_flow_profile_ids); proto_tree_add_item(sub_tree, hf_a11_aut_flow_prof_sub_type, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; - proto_tree_add_item(sub_tree, hf_a11_aut_flow_prof_sub_type_len, tvb, offset, 1, ENC_BIG_ENDIAN); + item = proto_tree_add_item(sub_tree, hf_a11_aut_flow_prof_sub_type_len, tvb, offset, 1, ENC_BIG_ENDIAN); + if (sub_type_length < 2) { + expert_add_info_format(pinfo, item, PI_PROTOCOL, PI_WARN, "Sub-Type Length should be at least 2"); + sub_type_length = 2; + } offset++; proto_tree_add_item(sub_tree, hf_a11_aut_flow_prof_sub_type_value, tvb, offset, 2, ENC_BIG_ENDIAN); diff --git a/epan/dissectors/packet-ieee80211.c b/epan/dissectors/packet-ieee80211.c index c1fd25b09e..143a08c1f4 100644 --- a/epan/dissectors/packet-ieee80211.c +++ b/epan/dissectors/packet-ieee80211.c @@ -8402,6 +8402,8 @@ add_tagged_field(packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int off proto_tree_add_item(tree, hf_ieee80211_csa_channel_switch_count, tvb, offset, 1, ENC_LITTLE_ENDIAN); proto_item_append_text(ti, ", Count: %d ", tvb_get_guint8(tvb, offset)); offset += 1; + + break; } case TAG_MEASURE_REQ: /* 7.3.2.21 Measurement Request element (38) with update from 802.11k-2008 */ diff --git a/epan/dissectors/packet-sctp.c b/epan/dissectors/packet-sctp.c index 5b258b36d6..114fb65e0d 100644 --- a/epan/dissectors/packet-sctp.c +++ b/epan/dissectors/packet-sctp.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. */ /* * It should be compliant to @@ -1053,7 +1053,7 @@ dissect_supported_address_types_parameter(tvbuff_t *parameter_tvb, proto_tree *p offset = PARAMETER_VALUE_OFFSET; proto_item_append_text(parameter_item, " (Supported types: "); - for(addr_type_number = 1; addr_type_number <= number_of_addr_types; addr_type_number++) { + for(addr_type_number = 0; addr_type_number < number_of_addr_types; addr_type_number++) { proto_tree_add_item(parameter_tree, hf_supported_address_type, parameter_tvb, offset, SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH, ENC_BIG_ENDIAN); addr_type = tvb_get_ntohs(parameter_tvb, offset); switch (addr_type) { @@ -1069,7 +1069,7 @@ dissect_supported_address_types_parameter(tvbuff_t *parameter_tvb, proto_tree *p default: proto_item_append_text(parameter_item, "%u", addr_type); } - if (addr_type_number < number_of_addr_types) + if (addr_type_number < (number_of_addr_types-1)) proto_item_append_text(parameter_item, ", "); offset += SUPPORTED_ADDRESS_TYPE_PARAMETER_ADDRESS_TYPE_LENGTH; } @@ -1097,7 +1097,7 @@ dissect_outgoing_ssn_reset_request_parameter(tvbuff_t *parameter_tvb, proto_tree sid_offset = SENDERS_LAST_ASSIGNED_TSN_OFFSET + SENDERS_LAST_ASSIGNED_TSN_LENGTH; if (length > PARAMETER_HEADER_LENGTH + STREAM_RESET_SEQ_NR_LENGTH + STREAM_RESET_SEQ_NR_LENGTH + SENDERS_LAST_ASSIGNED_TSN_LENGTH) { number_of_sids = (length - (PARAMETER_HEADER_LENGTH + STREAM_RESET_SEQ_NR_LENGTH + STREAM_RESET_SEQ_NR_LENGTH + SENDERS_LAST_ASSIGNED_TSN_LENGTH)) / SID_LENGTH; - for(sid_number = 1; sid_number <= number_of_sids; sid_number++) { + for(sid_number = 0; sid_number < number_of_sids; sid_number++) { proto_tree_add_item(parameter_tree, hf_stream_reset_sid, parameter_tvb, sid_offset, SID_LENGTH, ENC_BIG_ENDIAN); sid_offset += SID_LENGTH; } @@ -1115,7 +1115,7 @@ dissect_incoming_ssn_reset_request_parameter(tvbuff_t *parameter_tvb, proto_tree sid_offset = STREAM_RESET_REQ_SEQ_NR_OFFSET + STREAM_RESET_SEQ_NR_LENGTH; if (length > PARAMETER_HEADER_LENGTH + STREAM_RESET_SEQ_NR_LENGTH) { number_of_sids = (length - (PARAMETER_HEADER_LENGTH + STREAM_RESET_SEQ_NR_LENGTH)) / SID_LENGTH; - for(sid_number = 1; sid_number <= number_of_sids; sid_number++) { + for(sid_number = 0; sid_number < number_of_sids; sid_number++) { proto_tree_add_item(parameter_tree, hf_stream_reset_sid, parameter_tvb, sid_offset, SID_LENGTH, ENC_BIG_ENDIAN); sid_offset += SID_LENGTH; } @@ -1234,7 +1234,7 @@ dissect_chunks_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree) guint16 chunk_number, offset; number_of_chunks = tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH; - for(chunk_number = 1, offset = PARAMETER_VALUE_OFFSET; chunk_number <= number_of_chunks; chunk_number++, offset += CHUNK_TYPE_LENGTH) + for(chunk_number = 0, offset = PARAMETER_VALUE_OFFSET; chunk_number < number_of_chunks; chunk_number++, offset += CHUNK_TYPE_LENGTH) proto_tree_add_item(parameter_tree, hf_chunks_to_auth, parameter_tvb, offset, CHUNK_TYPE_LENGTH, ENC_BIG_ENDIAN); } @@ -1257,7 +1257,7 @@ dissect_hmac_algo_parameter(tvbuff_t *parameter_tvb, proto_tree *parameter_tree) guint16 id_number, offset; number_of_ids = (tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH) / HMAC_ID_LENGTH; - for(id_number = 1, offset = PARAMETER_VALUE_OFFSET; id_number <= number_of_ids; id_number++, offset += HMAC_ID_LENGTH) + for(id_number = 0, offset = PARAMETER_VALUE_OFFSET; id_number < number_of_ids; id_number++, offset += HMAC_ID_LENGTH) proto_tree_add_item(parameter_tree, hf_hmac_id, parameter_tvb, offset, HMAC_ID_LENGTH, ENC_BIG_ENDIAN); } @@ -1269,10 +1269,10 @@ dissect_supported_extensions_parameter(tvbuff_t *parameter_tvb, proto_tree *para proto_item_append_text(parameter_item, " (Supported types: "); number_of_types = (tvb_get_ntohs(parameter_tvb, PARAMETER_LENGTH_OFFSET) - PARAMETER_HEADER_LENGTH) / CHUNK_TYPE_LENGTH; - for(type_number = 1, offset = PARAMETER_VALUE_OFFSET; type_number <= number_of_types; type_number++, offset += CHUNK_TYPE_LENGTH) { + for(type_number = 0, offset = PARAMETER_VALUE_OFFSET; type_number < number_of_types; type_number++, offset += CHUNK_TYPE_LENGTH) { proto_tree_add_item(parameter_tree, hf_supported_chunk_type, parameter_tvb, offset, CHUNK_TYPE_LENGTH, ENC_BIG_ENDIAN); - proto_item_append_text(parameter_item, "%s", val_to_str(tvb_get_guint8(parameter_tvb, offset), chunk_type_values, "Unknown")); - if (type_number < number_of_types) + proto_item_append_text(parameter_item, "%s", val_to_str_const(tvb_get_guint8(parameter_tvb, offset), chunk_type_values, "Unknown")); + if (type_number < (number_of_types-1)) proto_item_append_text(parameter_item, ", "); } @@ -1474,7 +1474,7 @@ dissect_parameter(tvbuff_t *parameter_tvb, packet_info *pinfo, proto_tree *chunk return; if (chunk_tree) { - parameter_item = proto_tree_add_text(chunk_tree, parameter_tvb, PARAMETER_HEADER_OFFSET, tvb_reported_length(parameter_tvb), "%s parameter", val_to_str(type, parameter_identifier_values, "Unknown")); + parameter_item = proto_tree_add_text(chunk_tree, parameter_tvb, PARAMETER_HEADER_OFFSET, tvb_reported_length(parameter_tvb), "%s parameter", val_to_str_const(type, parameter_identifier_values, "Unknown")); parameter_tree = proto_item_add_subtree(parameter_item, ett_sctp_chunk_parameter); type_item = proto_tree_add_item(parameter_tree, hf_parameter_type, parameter_tvb, PARAMETER_TYPE_OFFSET, PARAMETER_TYPE_LENGTH, ENC_BIG_ENDIAN); @@ -1653,7 +1653,7 @@ dissect_missing_mandatory_parameters_cause(tvbuff_t *cause_tvb, proto_tree *caus number_of_missing_parameters = tvb_get_ntohl(cause_tvb, CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET); proto_tree_add_item(cause_tree, hf_cause_number_of_missing_parameters, cause_tvb, CAUSE_NUMBER_OF_MISSING_PARAMETERS_OFFSET, CAUSE_NUMBER_OF_MISSING_PARAMETERS_LENGTH, ENC_BIG_ENDIAN); offset = CAUSE_FIRST_MISSING_PARAMETER_TYPE_OFFSET; - for(missing_parameter_number = 1; missing_parameter_number <= number_of_missing_parameters; missing_parameter_number++) { + for(missing_parameter_number = 0; missing_parameter_number < number_of_missing_parameters; missing_parameter_number++) { proto_tree_add_item(cause_tree, hf_cause_missing_parameter_type, cause_tvb, offset, CAUSE_MISSING_PARAMETER_TYPE_LENGTH, ENC_BIG_ENDIAN); offset += CAUSE_MISSING_PARAMETER_TYPE_LENGTH; } @@ -1705,7 +1705,7 @@ dissect_unrecognized_chunk_type_cause(tvbuff_t *cause_tvb, packet_info *pinfo, MIN(chunk_length, tvb_reported_length_remaining(cause_tvb, CAUSE_INFO_OFFSET))); dissect_sctp_chunk(unrecognized_chunk_tvb, pinfo, cause_tree,cause_tree, NULL, FALSE); unrecognized_type = tvb_get_guint8(unrecognized_chunk_tvb, CHUNK_TYPE_OFFSET); - proto_item_append_text(cause_item, " (Type: %u (%s))", unrecognized_type, val_to_str(unrecognized_type, chunk_type_values, "unknown")); + proto_item_append_text(cause_item, " (Type: %u (%s))", unrecognized_type, val_to_str_const(unrecognized_type, chunk_type_values, "unknown")); } static void @@ -1904,7 +1904,7 @@ dissect_error_cause(tvbuff_t *cause_tvb, packet_info *pinfo, proto_tree *chunk_t length = tvb_get_ntohs(cause_tvb, CAUSE_LENGTH_OFFSET); padding_length = tvb_reported_length(cause_tvb) - length; - cause_item = proto_tree_add_text(chunk_tree, cause_tvb, CAUSE_HEADER_OFFSET, tvb_reported_length(cause_tvb), "%s cause", val_to_str(code, cause_code_values, "Unknown")); + cause_item = proto_tree_add_text(chunk_tree, cause_tvb, CAUSE_HEADER_OFFSET, tvb_reported_length(cause_tvb), "%s cause", val_to_str_const(code, cause_code_values, "Unknown")); cause_tree = proto_item_add_subtree(cause_item, ett_sctp_chunk_cause); proto_tree_add_item(cause_tree, hf_cause_code, cause_tvb, CAUSE_CODE_OFFSET, CAUSE_CODE_LENGTH, ENC_BIG_ENDIAN); @@ -2128,58 +2128,11 @@ frag_hash(gconstpointer k) key->stream_id ^ key->stream_seq_num; } - - -static void -frag_free_msgs(sctp_frag_msg *msg) -{ - sctp_frag_be *beginend; - sctp_fragment *fragment; - - /* free all begins */ - while (msg->begins) { - beginend = msg->begins; - msg->begins = msg->begins->next; - g_free(beginend); - } - - /* free all ends */ - while (msg->ends) { - beginend = msg->ends; - msg->ends = msg->ends->next; - g_free(beginend); - } - - /* free all fragments */ - while (msg->fragments) { - fragment = msg->fragments; - msg->fragments = msg->fragments->next; - g_free(fragment->data); - g_free(fragment); - } - - /* msg->messages is se_ allocated, no need to free it */ - - g_free(msg); -} - -static gboolean -free_table_entry(gpointer key, gpointer value, gpointer user_data _U_) -{ - sctp_frag_msg *msg = value; - frag_key *fkey = key; - - frag_free_msgs(msg); - g_free(fkey); - return TRUE; -} - static void frag_table_init(void) { /* destroy an existing hash table and create a new one */ if (frag_table) { - g_hash_table_foreach_remove(frag_table, free_table_entry, NULL); g_hash_table_destroy(frag_table); frag_table=NULL; } @@ -2237,14 +2190,14 @@ add_fragment(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 tsn, msg = find_message(stream_id, stream_seq_num); if (!msg) { - msg = g_malloc (sizeof (sctp_frag_msg)); + msg = se_alloc (sizeof (sctp_frag_msg)); msg->begins = NULL; msg->ends = NULL; msg->fragments = NULL; msg->messages = NULL; msg->next = NULL; - key = g_malloc(sizeof (frag_key)); + key = se_alloc(sizeof (frag_key)); key->sport = sctp_info.sport; key->dport = sctp_info.dport; key->verification_tag = sctp_info.verification_tag; @@ -2284,12 +2237,12 @@ add_fragment(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 tsn, return NULL; /* create new fragment */ - fragment = g_malloc (sizeof (sctp_fragment)); + fragment = se_alloc (sizeof (sctp_fragment)); fragment->frame_num = pinfo->fd->num; fragment->tsn = tsn; fragment->len = tvb_length(tvb); fragment->next = NULL; - fragment->data = g_malloc (fragment->len); + fragment->data = se_alloc (fragment->len); tvb_memcpy(tvb, fragment->data, 0, fragment->len); /* add new fragment to linked list. sort ascending by tsn */ @@ -2313,7 +2266,7 @@ add_fragment(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 tsn, /* save begin or end if neccessary */ if (b_bit && !e_bit) { - beginend = g_malloc (sizeof (sctp_frag_be)); + beginend = se_alloc (sizeof (sctp_frag_be)); beginend->fragment = fragment; beginend->next = NULL; @@ -2338,7 +2291,7 @@ add_fragment(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, guint32 tsn, } if (!b_bit && e_bit) { - beginend = g_malloc (sizeof (sctp_frag_be)); + beginend = se_alloc (sizeof (sctp_frag_be)); beginend->fragment = fragment; beginend->next = NULL; @@ -2572,7 +2525,6 @@ fragment_reassembly(tvbuff_t *tvb, sctp_fragment* fragment, offset += frag_i->len; /* release fragment data */ - g_free(frag_i->data); frag_i->data = NULL; } @@ -2585,7 +2537,6 @@ fragment_reassembly(tvbuff_t *tvb, sctp_fragment* fragment, offset += frag_i->len; /* release fragment data */ - g_free(frag_i->data); frag_i->data = NULL; } @@ -2599,7 +2550,6 @@ fragment_reassembly(tvbuff_t *tvb, sctp_fragment* fragment, offset += frag_i->len; /* release fragment data */ - g_free(frag_i->data); frag_i->data = NULL; } } @@ -2625,7 +2575,6 @@ fragment_reassembly(tvbuff_t *tvb, sctp_fragment* fragment, if (beginend && beginend->next == begin) beginend->next = begin->next; } - g_free(begin); if (msg->ends == end) { msg->ends = end->next; @@ -2636,7 +2585,6 @@ fragment_reassembly(tvbuff_t *tvb, sctp_fragment* fragment, if (beginend && beginend->next == end) beginend->next = end->next; } - g_free(end); /* create data source */ new_tvb = tvb_new_child_real_data(tvb, message->data, len, len); @@ -3043,7 +2991,7 @@ dissect_sack_chunk(packet_info* pinfo, tvbuff_t *chunk_tvb, proto_tree *chunk_tr sctp_ack_block(pinfo, ha, chunk_tvb, acks_tree, NULL, cum_tsn_ack); last_end = 0; - for(gap_block_number = 1; gap_block_number <= number_of_gap_blocks; gap_block_number++) { + for(gap_block_number = 0; gap_block_number < number_of_gap_blocks; gap_block_number++) { proto_item *pi; proto_tree *pt; guint32 tsn_start; @@ -3100,7 +3048,7 @@ dissect_sack_chunk(packet_info* pinfo, tvbuff_t *chunk_tvb, proto_tree *chunk_tr /* handle the duplicate TSNs */ number_of_dup_tsns = tvb_get_ntohs(chunk_tvb, SACK_CHUNK_NUMBER_OF_DUP_TSNS_OFFSET); dup_tsn_offset = SACK_CHUNK_GAP_BLOCK_OFFSET + number_of_gap_blocks * SACK_CHUNK_GAP_BLOCK_LENGTH; - for(dup_tsn_number = 1; dup_tsn_number <= number_of_dup_tsns; dup_tsn_number++) { + for(dup_tsn_number = 0; dup_tsn_number < number_of_dup_tsns; dup_tsn_number++) { proto_tree_add_item(chunk_tree, hf_sack_chunk_duplicate_tsn, chunk_tvb, dup_tsn_offset, SACK_CHUNK_DUP_TSN_LENGTH, ENC_BIG_ENDIAN); dup_tsn_offset += SACK_CHUNK_DUP_TSN_LENGTH; } @@ -3179,7 +3127,7 @@ dissect_nr_sack_chunk(packet_info* pinfo, tvbuff_t *chunk_tvb, proto_tree *chunk sctp_ack_block(pinfo, ha, chunk_tvb, acks_tree, NULL, cum_tsn_ack); last_end = 0; - for(gap_block_number = 1; gap_block_number <= number_of_gap_blocks; gap_block_number++) { + for(gap_block_number = 0; gap_block_number < number_of_gap_blocks; gap_block_number++) { proto_item *pi; proto_tree *pt; guint32 tsn_start; @@ -3236,7 +3184,7 @@ dissect_nr_sack_chunk(packet_info* pinfo, tvbuff_t *chunk_tvb, proto_tree *chunk nr_gap_block_offset = gap_block_offset; last_end = 0; - for(nr_gap_block_number = 1; nr_gap_block_number <= number_of_nr_gap_blocks; nr_gap_block_number++) { + for(nr_gap_block_number = 0; nr_gap_block_number < number_of_nr_gap_blocks; nr_gap_block_number++) { proto_item *pi; proto_tree *pt; /*guint32 tsn_start;*/ @@ -3293,7 +3241,7 @@ dissect_nr_sack_chunk(packet_info* pinfo, tvbuff_t *chunk_tvb, proto_tree *chunk + number_of_nr_gap_blocks * NR_SACK_CHUNK_NR_GAP_BLOCK_LENGTH; - for(dup_tsn_number = 1; dup_tsn_number <= number_of_dup_tsns; dup_tsn_number++) { + for(dup_tsn_number = 0; dup_tsn_number < number_of_dup_tsns; dup_tsn_number++) { proto_tree_add_item(chunk_tree, hf_sack_chunk_duplicate_tsn, chunk_tvb, dup_tsn_offset, NR_SACK_CHUNK_DUP_TSN_LENGTH, ENC_BIG_ENDIAN); dup_tsn_offset += NR_SACK_CHUNK_DUP_TSN_LENGTH; } @@ -3690,11 +3638,11 @@ dissect_sctp_chunk(tvbuff_t *chunk_tvb, padding_length = reported_length - length; if (useinfo) - col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str(type, chunk_type_values, "RESERVED")); + col_append_fstr(pinfo->cinfo, COL_INFO, "%s ", val_to_str_const(type, chunk_type_values, "RESERVED")); if (tree) { /* create proto_tree stuff */ - chunk_item = proto_tree_add_text(sctp_tree, chunk_tvb, CHUNK_HEADER_OFFSET, reported_length, "%s chunk", val_to_str(type, chunk_type_values, "RESERVED")); + chunk_item = proto_tree_add_text(sctp_tree, chunk_tvb, CHUNK_HEADER_OFFSET, reported_length, "%s chunk", val_to_str_const(type, chunk_type_values, "RESERVED")); chunk_tree = proto_item_add_subtree(chunk_item, ett_sctp_chunk); /* then insert the chunk header components into the protocol tree */ diff --git a/epan/dissectors/packet-sflow.c b/epan/dissectors/packet-sflow.c index 5eeab5220b..6ea3568759 100644 --- a/epan/dissectors/packet-sflow.c +++ b/epan/dissectors/packet-sflow.c @@ -33,7 +33,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. * * * This file (mostly) implements a dissector for sFlow (RFC3176), @@ -58,6 +58,7 @@ #include <epan/packet.h> #include <epan/prefs.h> +#include <epan/expert.h> #define SFLOW_UDP_PORTS "6343" @@ -76,8 +77,9 @@ static gboolean global_analyze_samp_ip_headers = FALSE; #define ENTERPRISE_DEFAULT 0 -#define ADDR_TYPE_IPV4 1 -#define ADDR_TYPE_IPV6 2 +#define ADDR_TYPE_UNKNOWN 0 +#define ADDR_TYPE_IPV4 1 +#define ADDR_TYPE_IPV6 2 #define FLOWSAMPLE 1 #define COUNTERSSAMPLE 2 @@ -864,16 +866,21 @@ dissect_sflow_245_sampled_header(tvbuff_t *tvb, packet_info *pinfo, } static gint -dissect_sflow_245_address_type(tvbuff_t *tvb, proto_tree *tree, gint offset, +dissect_sflow_245_address_type(tvbuff_t *tvb, packet_info *pinfo, + proto_tree *tree, gint offset, struct sflow_address_type *hf_type, struct sflow_address_details *addr_detail) { guint32 addr_type; int len; + proto_item *pi; addr_type = tvb_get_ntohl(tvb, offset); offset += 4; switch (addr_type) { + case ADDR_TYPE_UNKNOWN: + len = 0; + break; case ADDR_TYPE_IPV4: len = 4; proto_tree_add_item(tree, hf_type->hf_addr_v4, tvb, offset, 4, ENC_BIG_ENDIAN); @@ -883,15 +890,14 @@ dissect_sflow_245_address_type(tvbuff_t *tvb, proto_tree *tree, gint offset, proto_tree_add_item(tree, hf_type->hf_addr_v6, tvb, offset, 16, ENC_NA); break; default: - /* acferen: November 10, 2010 - * - * We should never get here, but if we do we don't know - * the length for this address type. Not knowing the - * length this default case is doomed to failure. Might - * as well acknowledge that as soon as possible. - */ - proto_tree_add_text(tree, tvb, offset - 4, 4, "Unknown address type (%u)", addr_type); - return 0; /* malformed packet */ + /* Invalid address type, or a type we don't understand; we don't + know the length. W e treat it as having no contents; that + doesn't trap us in an endless loop, as we at least include + the address type and thus at least advance the offset by 4. + Note that we have a problem, though. */ + len = 0; + pi = proto_tree_add_text(tree, tvb, offset - 4, 4, "Unknown address type (%u)", addr_type); + expert_add_info_format(pinfo, pi, PI_MALFORMED, PI_ERROR, "Unknown/invalid address type"); } if (addr_detail) { @@ -926,10 +932,10 @@ dissect_sflow_245_extended_switch(tvbuff_t *tvb, proto_tree *tree, gint offset) /* extended router data, after the packet data */ static gint -dissect_sflow_245_extended_router(tvbuff_t *tvb, proto_tree *tree, gint offset) { +dissect_sflow_245_extended_router(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset) { struct sflow_address_type addr_type = {hf_sflow_245_nexthop_v4, hf_sflow_245_nexthop_v6}; - offset = dissect_sflow_245_address_type(tvb, tree, offset, &addr_type, NULL); + offset = dissect_sflow_245_address_type(tvb, pinfo, tree, offset, &addr_type, NULL); proto_tree_add_item(tree, hf_sflow_245_nexthop_src_mask, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(tree, hf_sflow_245_nexthop_dst_mask, tvb, offset, 4, ENC_BIG_ENDIAN); @@ -939,7 +945,7 @@ dissect_sflow_245_extended_router(tvbuff_t *tvb, proto_tree *tree, gint offset) /* extended MPLS data */ static gint -dissect_sflow_5_extended_mpls_data(tvbuff_t *tvb, proto_tree *tree, gint offset) { +dissect_sflow_5_extended_mpls_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset) { guint32 in_label_count, out_label_count, i, j; proto_tree *in_stack; proto_item *ti_in; @@ -947,7 +953,7 @@ dissect_sflow_5_extended_mpls_data(tvbuff_t *tvb, proto_tree *tree, gint offset) proto_item *ti_out; struct sflow_address_type addr_type = {hf_sflow_245_nexthop_v4, hf_sflow_245_nexthop_v6}; - offset = dissect_sflow_245_address_type(tvb, tree, offset, &addr_type, NULL); + offset = dissect_sflow_245_address_type(tvb, pinfo, tree, offset, &addr_type, NULL); in_label_count = tvb_get_ntohl(tvb, offset); proto_tree_add_text(tree, tvb, offset, 4, "In Label Stack Entries: %u", in_label_count); @@ -982,22 +988,22 @@ dissect_sflow_5_extended_mpls_data(tvbuff_t *tvb, proto_tree *tree, gint offset) /* extended NAT data */ static gint -dissect_sflow_5_extended_nat(tvbuff_t *tvb, proto_tree *tree, gint offset) { +dissect_sflow_5_extended_nat(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset) { struct sflow_address_type addr_type = {hf_sflow_245_ipv4_src, hf_sflow_245_ipv6_src}; - offset = dissect_sflow_245_address_type(tvb, tree, offset, &addr_type, NULL); + offset = dissect_sflow_245_address_type(tvb, pinfo, tree, offset, &addr_type, NULL); addr_type.hf_addr_v4 = hf_sflow_245_ipv4_dst; addr_type.hf_addr_v6 = hf_sflow_245_ipv6_dst; - offset = dissect_sflow_245_address_type(tvb, tree, offset, &addr_type, NULL); + offset = dissect_sflow_245_address_type(tvb, pinfo, tree, offset, &addr_type, NULL); return offset; } /* extended gateway data, after the packet data */ static gint -dissect_sflow_245_extended_gateway(tvbuff_t *tvb, proto_tree *tree, gint offset) { +dissect_sflow_245_extended_gateway(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, gint offset) { gint32 len = 0; gint32 i, j, comm_len, dst_len, dst_seg_len; guint32 path_type; @@ -1013,7 +1019,7 @@ dissect_sflow_245_extended_gateway(tvbuff_t *tvb, proto_tree *tree, gint offset) if (version == 5) { struct sflow_address_type addr_type = {hf_sflow_245_nexthop_v4, hf_sflow_245_nexthop_v6}; - offset = dissect_sflow_245_address_type(tvb, tree, offset, &addr_type, NULL); + offset = dissect_sflow_245_address_type(tvb, pinfo, tree, offset, &addr_type, NULL); } proto_tree_add_item(tree, hf_sflow_245_as, tvb, offset + len, 4, ENC_BIG_ENDIAN); @@ -1059,7 +1065,7 @@ dissect_sflow_245_extended_gateway(tvbuff_t *tvb, proto_tree *tree, gint offset) len += 4; kludge = 8; ti = proto_tree_add_text(tree, tvb, offset + len - kludge, kludge, - "%s, (%u entries)", val_to_str(path_type, sflow_245_as_types, "Unknown AS type"), dst_seg_len); + "%s, (%u entries)", val_to_str_const(path_type, sflow_245_as_types, "Unknown AS type"), dst_seg_len); sflow_245_dst_as_seg_tree = proto_item_add_subtree(ti, ett_sflow_245_gw_as_dst_seg); } @@ -1188,7 +1194,7 @@ dissect_sflow_5_ipv4(tvbuff_t *tvb, proto_tree *tree, gint offset) { /* 7 bits for type of service, plus 1 reserved bit */ tos = tvb_get_guint8(tvb, offset); proto_tree_add_text(tree, tvb, offset, 1, "%s", - val_to_str(tos >> 5, sflow_245_ipv4_precedence_types, "Unknown precedence type")); + val_to_str_const(tos >> 5, sflow_245_ipv4_precedence_types, "Unknown precedence type")); (tos & 0x10) >> 4 ? proto_tree_add_text(tree, tvb, offset, 1, "Delay: ...1... (Low)") : proto_tree_add_text(tree, tvb, offset, 1, "Delay: ...0... (Normal)"); @@ -1592,7 +1598,7 @@ dissect_sflow_5_extended_80211_rx(tvbuff_t *tvb, proto_tree *tree, gint offset) version = tvb_get_ntohl(tvb, offset); proto_tree_add_text(tree, tvb, offset, 4, "Version: %s", - val_to_str(version, sflow_5_ieee80211_versions, "Unknown")); + val_to_str_const(version, sflow_5_ieee80211_versions, "Unknown")); offset += 4; channel = tvb_get_ntohl(tvb, offset); @@ -1648,7 +1654,7 @@ dissect_sflow_5_extended_80211_tx(tvbuff_t *tvb, proto_tree *tree, gint offset) version = tvb_get_ntohl(tvb, offset); proto_tree_add_text(tree, tvb, offset, 4, "Version: %s", - val_to_str(version, sflow_5_ieee80211_versions, "Unknown")); + val_to_str_const(version, sflow_5_ieee80211_versions, "Unknown")); offset += 4; transmissions = tvb_get_ntohl(tvb, offset); @@ -1769,7 +1775,7 @@ dissect_sflow_24_flow_sample(tvbuff_t *tvb, packet_info *pinfo, * the end, so more info can be correct. */ ti = proto_tree_add_text(tree, tvb, offset, -1, "%s", - val_to_str(ext_type, sflow_245_extended_data_types, "Unknown extended information")); + val_to_str_const(ext_type, sflow_245_extended_data_types, "Unknown extended information")); extended_data_tree = proto_item_add_subtree(ti, ett_sflow_245_extended_data); proto_tree_add_uint(extended_data_tree, hf_sflow_245_extended_information_type, tvb, offset, 4, ext_type); offset += 4; @@ -1779,10 +1785,10 @@ dissect_sflow_24_flow_sample(tvbuff_t *tvb, packet_info *pinfo, offset = dissect_sflow_245_extended_switch(tvb, extended_data_tree, offset); break; case SFLOW_245_EXTENDED_ROUTER: - offset = dissect_sflow_245_extended_router(tvb, extended_data_tree, offset); + offset = dissect_sflow_245_extended_router(tvb, pinfo, extended_data_tree, offset); break; case SFLOW_245_EXTENDED_GATEWAY: - offset = dissect_sflow_245_extended_gateway(tvb, extended_data_tree, offset); + offset = dissect_sflow_245_extended_gateway(tvb, pinfo, extended_data_tree, offset); break; case SFLOW_245_EXTENDED_USER: break; @@ -1813,7 +1819,7 @@ dissect_sflow_5_flow_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, /* only accept default enterprise 0 (InMon sFlow) */ if (enterprise == ENTERPRISE_DEFAULT) { ti = proto_tree_add_text(tree, tvb, offset, -1, "%s", - val_to_str(format, sflow_5_flow_record_type, "Unknown sample format")); + val_to_str_const(format, sflow_5_flow_record_type, "Unknown sample format")); flow_data_tree = proto_item_add_subtree(ti, ett_sflow_5_flow_record); proto_tree_add_text(flow_data_tree, tvb, offset, 4, "Enterprise: standard sFlow (%u)", enterprise); @@ -1840,10 +1846,10 @@ dissect_sflow_5_flow_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, offset = dissect_sflow_245_extended_switch(tvb, flow_data_tree, offset); break; case SFLOW_5_ROUTER: - offset = dissect_sflow_245_extended_router(tvb, flow_data_tree, offset); + offset = dissect_sflow_245_extended_router(tvb, pinfo, flow_data_tree, offset); break; case SFLOW_5_GATEWAY: - offset = dissect_sflow_245_extended_gateway(tvb, flow_data_tree, offset); + offset = dissect_sflow_245_extended_gateway(tvb, pinfo, flow_data_tree, offset); break; case SFLOW_5_USER: offset = dissect_sflow_5_extended_user(tvb, flow_data_tree, offset); @@ -1852,10 +1858,10 @@ dissect_sflow_5_flow_record(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, offset = dissect_sflow_5_extended_url(tvb, flow_data_tree, offset); break; case SFLOW_5_MPLS_DATA: - offset = dissect_sflow_5_extended_mpls_data(tvb, flow_data_tree, offset); + offset = dissect_sflow_5_extended_mpls_data(tvb, pinfo, flow_data_tree, offset); break; case SFLOW_5_NAT: - offset = dissect_sflow_5_extended_nat(tvb, flow_data_tree, offset); + offset = dissect_sflow_5_extended_nat(tvb, pinfo, flow_data_tree, offset); break; case SFLOW_5_MPLS_TUNNEL: offset = dissect_sflow_5_extended_mpls_tunnel(tvb, flow_data_tree, offset); @@ -2212,7 +2218,7 @@ dissect_sflow_5_counters_record(tvbuff_t *tvb, proto_tree *tree, gint offset) { if (enterprise == ENTERPRISE_DEFAULT) { /* only accept default enterprise 0 (InMon sFlow) */ ti = proto_tree_add_text(tree, tvb, offset, -1, "%s", - val_to_str(format, sflow_5_counters_record_type, "Unknown sample format")); + val_to_str_const(format, sflow_5_counters_record_type, "Unknown sample format")); counter_data_tree = proto_item_add_subtree(ti, ett_sflow_5_counters_record); proto_tree_add_text(counter_data_tree, tvb, offset, 4, "Enterprise: standard sFlow (%u)", enterprise); @@ -2414,7 +2420,7 @@ dissect_sflow_24_counters_sample(tvbuff_t *tvb, proto_tree *tree, gint offset, p "Sampling Interval: %u", g_ntohl(counters_header.sampling_interval)); proto_tree_add_text(tree, tvb, offset + 12, 4, "Counters type: %s", - val_to_str(g_ntohl(counters_header.counters_type), + val_to_str_const(g_ntohl(counters_header.counters_type), sflow_245_counterstype, "Unknown type")); offset += sizeof (counters_header); @@ -2591,7 +2597,7 @@ dissect_sflow_245_samples(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g if (enterprise == ENTERPRISE_DEFAULT) { /* only accept default enterprise 0 (InMon sFlow) */ ti = proto_tree_add_text(tree, tvb, offset, -1, "%s", - val_to_str(format, sflow_245_sampletype, "Unknown sample format")); + val_to_str_const(format, sflow_245_sampletype, "Unknown sample format")); sflow_245_sample_tree = proto_item_add_subtree(ti, ett_sflow_245_sample); proto_tree_add_text(sflow_245_sample_tree, tvb, offset, 4, "Enterprise: standard sFlow (%u)", enterprise); @@ -2630,7 +2636,7 @@ dissect_sflow_245_samples(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, g } else { /* version 2 or 4 */ ti = proto_tree_add_text(tree, tvb, offset, -1, "%s", - val_to_str(sample_type, sflow_245_sampletype, "Unknown sample type")); + val_to_str_const(sample_type, sflow_245_sampletype, "Unknown sample type")); sflow_245_sample_tree = proto_item_add_subtree(ti, ett_sflow_245_sample); proto_tree_add_item(sflow_245_sample_tree, hf_sflow_245_sampletype, tvb, offset, 4, ENC_BIG_ENDIAN); @@ -2667,23 +2673,51 @@ dissect_sflow_245(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { volatile guint offset = 0; guint i = 0; + /* + * We fetch the version and address type so that we can determine, + * ahead of time, whether this is an sFlow packet or not, before + * we do *anything* to the columns or the protocol tree. + * + * XXX - we might want to deem this "not sFlow" if we don't have at + * least 8 bytes worth of data. + */ + version = tvb_get_ntohl(tvb, offset); + if (version != 2 && version != 4 && version != 5) { + /* Unknown version; assume it's not an sFlow packet. */ + return 0; + } + addr_details.addr_type = tvb_get_ntohl(tvb, offset + 4); + switch (addr_details.addr_type) { + case ADDR_TYPE_UNKNOWN: + case ADDR_TYPE_IPV4: + case ADDR_TYPE_IPV6: + break; + + default: + /* + * Address type we don't know about; assume it's not an sFlow + * packet. + */ + return 0; + } + /* Make entries in Protocol column and Info column on summary display */ col_set_str(pinfo->cinfo, COL_PROTOCOL, "sFlow"); - /* create display subtree for the protocol */ ti = proto_tree_add_item(tree, proto_sflow, tvb, 0, -1, ENC_NA); sflow_245_tree = proto_item_add_subtree(ti, ett_sflow_245); - version = tvb_get_ntohl(tvb, offset); col_add_fstr(pinfo->cinfo, COL_INFO, "V%u", version); proto_tree_add_item(sflow_245_tree, hf_sflow_version, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; - offset = dissect_sflow_245_address_type(tvb, sflow_245_tree, offset, + offset = dissect_sflow_245_address_type(tvb, pinfo, sflow_245_tree, offset, &addr_type, &addr_details); switch (addr_details.addr_type) { + case ADDR_TYPE_UNKNOWN: + break; case ADDR_TYPE_IPV4: col_append_fstr(pinfo->cinfo, COL_INFO, ", agent %s", ip_to_str(addr_details.agent_address.v4)); break; @@ -2691,9 +2725,6 @@ dissect_sflow_245(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { col_append_fstr(pinfo->cinfo, COL_INFO, ", agent %s", ip6_to_str((struct e_in6_addr *) addr_details.agent_address.v6)); break; - default: - /* unknown address. this will cause a malformed packet. */ - return 0; } if (version == 5) { |