summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnders Broman <anders.broman@ericsson.com>2012-10-16 11:29:36 +0000
committerAnders Broman <anders.broman@ericsson.com>2012-10-16 11:29:36 +0000
commit002b91578c4b6684311ed3f4474cd81a45aac8f0 (patch)
tree3ae17cadccf758df188c78b973bffa330759d417
parent1a68210e9f6a8070f0885c754ac58020fa3bc59e (diff)
downloadwireshark-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.c22
-rw-r--r--epan/dissectors/packet-ieee80211.c2
-rw-r--r--epan/dissectors/packet-sctp.c106
-rw-r--r--epan/dissectors/packet-sflow.c119
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) {