diff --git a/epan/dissectors/packet-3g-a11.c b/epan/dissectors/packet-3g-a11.c index 58b6047c74..d3c169d1b1 100644 --- a/epan/dissectors/packet-3g-a11.c +++ b/epan/dissectors/packet-3g-a11.c @@ -444,7 +444,7 @@ decode_sse(proto_tree* ext_tree, tvbuff_t* tvb, int offset, guint ext_len) "Cannot decode Protocol Type - SSE too short"); return; } - proto_tree_add_item(ext_tree, hf_a11_ses_ptype, tvb, offset, 2, FALSE); + proto_tree_add_item(ext_tree, hf_a11_ses_ptype, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; ext_len -= 2; @@ -455,7 +455,7 @@ decode_sse(proto_tree* ext_tree, tvbuff_t* tvb, int offset, guint ext_len) "Cannot decode Session Key - SSE too short"); return; } - proto_tree_add_item(ext_tree, hf_a11_ses_key, tvb, offset, 4, FALSE); + proto_tree_add_item(ext_tree, hf_a11_ses_key, tvb, offset, 4, ENC_BIG_ENDIAN); offset += 4; ext_len -= 4; @@ -467,7 +467,7 @@ decode_sse(proto_tree* ext_tree, tvbuff_t* tvb, int offset, guint ext_len) "Cannot decode Session Id Version - SSE too short"); return; } - proto_tree_add_item(ext_tree, hf_a11_ses_sidver, tvb, offset+1, 1, FALSE); + proto_tree_add_item(ext_tree, hf_a11_ses_sidver, tvb, offset+1, 1, ENC_BIG_ENDIAN); offset += 2; ext_len -= 2; @@ -479,7 +479,7 @@ decode_sse(proto_tree* ext_tree, tvbuff_t* tvb, int offset, guint ext_len) "Cannot decode SRID - SSE too short"); return; } - proto_tree_add_item(ext_tree, hf_a11_ses_mnsrid, tvb, offset, 2, FALSE); + proto_tree_add_item(ext_tree, hf_a11_ses_mnsrid, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; ext_len -= 2; @@ -490,7 +490,7 @@ decode_sse(proto_tree* ext_tree, tvbuff_t* tvb, int offset, guint ext_len) "Cannot decode MSID Type - SSE too short"); return; } - proto_tree_add_item(ext_tree, hf_a11_ses_msid_type, tvb, offset, 2, FALSE); + proto_tree_add_item(ext_tree, hf_a11_ses_msid_type, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; ext_len -= 2; @@ -503,7 +503,7 @@ decode_sse(proto_tree* ext_tree, tvbuff_t* tvb, int offset, guint ext_len) return; } msid_len = tvb_get_guint8(tvb, offset); - proto_tree_add_item(ext_tree, hf_a11_ses_msid_len, tvb, offset, 1, FALSE); + proto_tree_add_item(ext_tree, hf_a11_ses_msid_len, tvb, offset, 1, ENC_BIG_ENDIAN); offset += 1; ext_len -= 1; @@ -772,27 +772,27 @@ static void dissect_ase(tvbuff_t* tvb, int offset, guint ase_len, proto_tree* ex proto_tree* exts_tree = proto_item_add_subtree(ti, ett_a11_ase); /* Entry Length */ - proto_tree_add_item(exts_tree, hf_a11_ase_len_type, tvb, offset+clen, 1, FALSE); + proto_tree_add_item(exts_tree, hf_a11_ase_len_type, tvb, offset+clen, 1, ENC_BIG_ENDIAN); clen++; /* SRID */ - proto_tree_add_item(exts_tree, hf_a11_ase_srid_type, tvb, offset+clen, 1, FALSE); + proto_tree_add_item(exts_tree, hf_a11_ase_srid_type, tvb, offset+clen, 1, ENC_BIG_ENDIAN); clen++; /* Service Option */ - proto_tree_add_item(exts_tree, hf_a11_ase_servopt_type, tvb, offset+clen, 2, FALSE); + proto_tree_add_item(exts_tree, hf_a11_ase_servopt_type, tvb, offset+clen, 2, ENC_BIG_ENDIAN); clen+=2; /* GRE Protocol Type*/ - proto_tree_add_item(exts_tree, hf_a11_ase_gre_proto_type, tvb, offset+clen, 2, FALSE); + proto_tree_add_item(exts_tree, hf_a11_ase_gre_proto_type, tvb, offset+clen, 2, ENC_BIG_ENDIAN); clen+=2; /* GRE Key */ - proto_tree_add_item(exts_tree, hf_a11_ase_gre_key, tvb, offset+clen, 4, FALSE); + proto_tree_add_item(exts_tree, hf_a11_ase_gre_key, tvb, offset+clen, 4, ENC_BIG_ENDIAN); clen+=4; /* PCF IP Address */ - proto_tree_add_item(exts_tree, hf_a11_ase_pcf_addr_key, tvb, offset+clen, 4, FALSE); + proto_tree_add_item(exts_tree, hf_a11_ase_pcf_addr_key, tvb, offset+clen, 4, ENC_BIG_ENDIAN); clen+=4; } } @@ -885,11 +885,11 @@ static void dissect_fwd_qosinfo(tvbuff_t* tvb, int offset, proto_tree* ext_tree) * Starts with a length field * http://www.3gpp2.org/Public_html/specs/A.S0009-C_v1.0_070801.pdf */ - proto_tree_add_item(ext_tree, hf_a11_fqi_length, tvb, offset+clen, 2, FALSE); + proto_tree_add_item(ext_tree, hf_a11_fqi_length, tvb, offset+clen, 2, ENC_BIG_ENDIAN); clen = clen + 2; /* SR Id */ - proto_tree_add_item(ext_tree, hf_a11_fqi_srid, tvb, offset+clen, 1, FALSE); + proto_tree_add_item(ext_tree, hf_a11_fqi_srid, tvb, offset+clen, 1, ENC_BIG_ENDIAN); clen++; /* Flags */ @@ -899,7 +899,7 @@ static void dissect_fwd_qosinfo(tvbuff_t* tvb, int offset, proto_tree* ext_tree) /* Flow Count */ flow_count = tvb_get_guint8(tvb, offset+clen); flow_count &= 0x1F; - proto_tree_add_item(ext_tree, hf_a11_fqi_flowcount, tvb, offset+clen, 1, FALSE); + proto_tree_add_item(ext_tree, hf_a11_fqi_flowcount, tvb, offset+clen, 1, ENC_BIG_ENDIAN); clen++; for(flow_index=0; flow_index= 4) proto_tree_add_item(ntp_tree, hf_ntp_keyid, tvb, macofs, 4, - FALSE); + ENC_NA); macofs += 4; maclen = tvb_reported_length_remaining(tvb, macofs); if (maclen > 0) proto_tree_add_item(ntp_tree, hf_ntp_mac, tvb, macofs, - maclen, FALSE); + maclen, ENC_NA); } static int @@ -848,7 +848,7 @@ dissect_ntp_ext(tvbuff_t *tvb, proto_tree *ntp_tree, int offset) endoffset = offset + extlen; tf = proto_tree_add_item(ntp_tree, hf_ntp_ext, tvb, offset, extlen, - FALSE); + ENC_NA); ext_tree = proto_item_add_subtree(tf, ett_ntp_ext); flags = tvb_get_guint8(tvb, offset); @@ -863,7 +863,7 @@ dissect_ntp_ext(tvbuff_t *tvb, proto_tree *ntp_tree, int offset) flags); offset++; - proto_tree_add_item(ext_tree, hf_ntp_ext_op, tvb, offset, 1, FALSE); + proto_tree_add_item(ext_tree, hf_ntp_ext_op, tvb, offset, 1, ENC_BIG_ENDIAN); offset++; proto_tree_add_uint(ext_tree, hf_ntp_ext_len, tvb, offset, 2, extlen); @@ -875,7 +875,7 @@ dissect_ntp_ext(tvbuff_t *tvb, proto_tree *ntp_tree, int offset) } proto_tree_add_item(ext_tree, hf_ntp_ext_associd, tvb, offset, 4, - FALSE); + ENC_BIG_ENDIAN); offset += 4; /* check whether everything up to "vallen" is present */ @@ -885,10 +885,10 @@ dissect_ntp_ext(tvbuff_t *tvb, proto_tree *ntp_tree, int offset) } proto_tree_add_item(ext_tree, hf_ntp_ext_tstamp, tvb, offset, 4, - FALSE); + ENC_BIG_ENDIAN); offset += 4; proto_tree_add_item(ext_tree, hf_ntp_ext_fstamp, tvb, offset, 4, - FALSE); + ENC_BIG_ENDIAN); offset += 4; /* XXX fstamp can be server flags */ @@ -909,7 +909,7 @@ dissect_ntp_ext(tvbuff_t *tvb, proto_tree *ntp_tree, int offset) return endoffset; } proto_tree_add_item(ext_tree, hf_ntp_ext_val, tvb, offset, - vallen, FALSE); + vallen, ENC_NA); } offset += vallen_round; @@ -929,7 +929,7 @@ dissect_ntp_ext(tvbuff_t *tvb, proto_tree *ntp_tree, int offset) return endoffset; } proto_tree_add_item(ext_tree, hf_ntp_ext_sig, tvb, - offset, siglen, FALSE); + offset, siglen, ENC_NA); } return endoffset; } @@ -1079,7 +1079,7 @@ dissect_ntp_ctrl(tvbuff_t *tvb, proto_tree *ntp_tree, guint8 flags) */ if (datalen) { data_offset = 12; - td = proto_tree_add_item(ntp_tree, hf_ntpctrl_data, tvb, data_offset, datalen, TRUE); + td = proto_tree_add_item(ntp_tree, hf_ntpctrl_data, tvb, data_offset, datalen, ENC_NA); data_tree = proto_item_add_subtree(td, ett_ntpctrl_data); switch(flags2 & NTPCTRL_OP_MASK) { case NTPCTRL_OP_READSTAT: @@ -1089,7 +1089,7 @@ dissect_ntp_ctrl(tvbuff_t *tvb, proto_tree *ntp_tree, guint8 flags) * , */ while(datalen) { - ti = proto_tree_add_item(data_tree, hf_ntpctrl_item, tvb, data_offset, 4, TRUE); + ti = proto_tree_add_item(data_tree, hf_ntpctrl_item, tvb, data_offset, 4, ENC_NA); item_tree = proto_item_add_subtree(ti, ett_ntpctrl_item); proto_tree_add_uint(item_tree, hf_ntpctrl_associd, tvb, data_offset, 2, tvb_get_ntohs(tvb, data_offset)); data_offset += 2; diff --git a/epan/proto.c b/epan/proto.c index 9c722069e0..6f913009ac 100644 --- a/epan/proto.c +++ b/epan/proto.c @@ -1212,8 +1212,9 @@ proto_lookup_or_create_interesting_hfids(proto_tree *tree, static proto_item * proto_tree_new_item(field_info *new_fi, proto_tree *tree, tvbuff_t *tvb, gint start, gint length, - const guint encoding) + const guint encoding_arg) { + guint encoding = encoding_arg; proto_item *pi; guint32 value, n; float floatval; @@ -1258,6 +1259,12 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, break; case FT_UINT_BYTES: + /* + * Map all non-zero values to little-endian for + * backwards compatibility. + */ + if (encoding) + encoding = ENC_LITTLE_ENDIAN; n = get_uint_value(tvb, start, length, encoding); proto_tree_set_bytes_tvb(new_fi, tvb, start + length, n); @@ -1267,6 +1274,12 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, break; case FT_BOOLEAN: + /* + * Map all non-zero values to little-endian for + * backwards compatibility. + */ + if (encoding) + encoding = ENC_LITTLE_ENDIAN; proto_tree_set_boolean(new_fi, get_uint_value(tvb, start, length, encoding)); break; @@ -1276,12 +1289,24 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, case FT_UINT16: case FT_UINT24: case FT_UINT32: + /* + * Map all non-zero values to little-endian for + * backwards compatibility. + */ + if (encoding) + encoding = ENC_LITTLE_ENDIAN; proto_tree_set_uint(new_fi, get_uint_value(tvb, start, length, encoding)); break; case FT_INT64: case FT_UINT64: + /* + * Map all non-zero values to little-endian for + * backwards compatibility. + */ + if (encoding) + encoding = ENC_LITTLE_ENDIAN; DISSECTOR_ASSERT( length <= 8 && length >= 1); proto_tree_set_uint64_tvb(new_fi, tvb, start, length, encoding); break; @@ -1291,11 +1316,23 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, case FT_INT16: case FT_INT24: case FT_INT32: + /* + * Map all non-zero values to little-endian for + * backwards compatibility. + */ + if (encoding) + encoding = ENC_LITTLE_ENDIAN; proto_tree_set_int(new_fi, get_int_value(tvb, start, length, encoding)); break; case FT_IPv4: + /* + * Map all non-zero values to little-endian for + * backwards compatibility. + */ + if (encoding) + encoding = ENC_LITTLE_ENDIAN; DISSECTOR_ASSERT(length == FT_IPv4_LEN); value = tvb_get_ipv4(tvb, start); /* @@ -1326,6 +1363,12 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, break; case FT_GUID: + /* + * Map all non-zero values to little-endian for + * backwards compatibility. + */ + if (encoding) + encoding = ENC_LITTLE_ENDIAN; DISSECTOR_ASSERT(length == FT_GUID_LEN); proto_tree_set_guid_tvb(new_fi, tvb, start, encoding); break; @@ -1335,7 +1378,6 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, break; case FT_FLOAT: - DISSECTOR_ASSERT(length == 4); /* * NOTE: to support code written when * proto_tree_add_item() took a gboolean as its @@ -1349,6 +1391,9 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, * formats in the encoding as well * (IEEE decimal, System/3x0, VAX). */ + if (encoding) + encoding = ENC_LITTLE_ENDIAN; + DISSECTOR_ASSERT(length == 4); if (encoding) floatval = tvb_get_letohieee_float(tvb, start); else @@ -1370,6 +1415,8 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, * formats in the encoding as well * (IEEE decimal, System/3x0, VAX). */ + if (encoding == TRUE) + encoding = ENC_LITTLE_ENDIAN; DISSECTOR_ASSERT(length == 8); if (encoding) doubleval = tvb_get_letohieee_double(tvb, start); @@ -1445,6 +1492,20 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, break; case FT_UINT_STRING: + /* + * NOTE: to support code written when + * proto_tree_add_item() took a gboolean as its + * last argument, with FALSE meaning "big-endian" + * and TRUE meaning "little-endian", we treat any + * non-zero value of "encoding" as meaning + * "little-endian". + * + * At some point in the future, we might + * support character encodings in the + * encoding value as well. + */ + if (encoding) + encoding = ENC_LITTLE_ENDIAN; n = get_uint_value(tvb, start, length, encoding); proto_tree_set_string_tvb(new_fi, tvb, start + length, n); @@ -1461,21 +1522,56 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, break; case FT_ABSOLUTE_TIME: - case FT_RELATIVE_TIME: - /* Historically, FT_TIMEs were only timespecs and 'encoding' - * only specified if the timespec was stored in big- or - * little-endian format. + /* + * Absolute times can be in any of a number of + * formats, and they can be big-endian or + * little-endian. + * + * Historically FT_TIMEs were only timespecs; + * the only question was whether they were stored + * in big- or little-endian format. + * + * For backwards compatibility, we interpret an + * encoding of 1 as meaning "little-endian timespec", + * so that passing TRUE is interpreted as that. */ - if (encoding == ENC_TIME_TIMESPEC_BE) { /* or FALSE/ENC_BIG_ENDIAN */ + if (encoding == TRUE) + encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN; + switch (encoding) { + + case ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN: + /* + * 4-byte UNIX epoch, possibly followed by + * 4-byte fractional time in nanoseconds, + * both big-endian. + */ DISSECTOR_ASSERT(length == 8 || length == 4); time_stamp.secs = tvb_get_ntohl(tvb, start); if (length == 8) time_stamp.nsecs = tvb_get_ntohl(tvb, start+4); else time_stamp.nsecs = 0; - } else if (encoding == ENC_TIME_NTP) { + break; + + case ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN: + /* + * 4-byte UNIX epoch, possibly followed by + * 4-byte fractional time in nanoseconds, + * both little-endian. + */ + DISSECTOR_ASSERT(length == 8 || length == 4); + time_stamp.secs = tvb_get_letohl(tvb, start); + if (length == 8) + time_stamp.nsecs = tvb_get_letohl(tvb, start+4); + else + time_stamp.nsecs = 0; + break; + + case ENC_TIME_NTP|ENC_BIG_ENDIAN: + /* + * NTP time stamp, big-endian. + */ DISSECTOR_ASSERT(length == 8); - DISSECTOR_ASSERT(new_fi->hfinfo->display == ABSOLUTE_TIME_UTC); /* XXX - where should this go? */ #define NTP_BASETIME 2208988800ul @@ -1483,21 +1579,90 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, if (time_stamp.secs) time_stamp.secs -= NTP_BASETIME; - /* We're using nanoseconds here (and we will display nanoseconds), - * but NTP's timestamps have a precision in microseconds or greater. + /* + * We're using nanoseconds here (and we will + * display nanoseconds), but NTP's timestamps + * have a precision in microseconds or greater. * Round to 1 microsecond. */ - time_stamp.nsecs = 1000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0); + time_stamp.nsecs = (int)(1000000*(tvb_get_ntohl(tvb, start+4)/4294967296.0)); time_stamp.nsecs *= 1000; - } else { /* TRUE or ENC_LITTLE_ENDIAN/ENC_TIME_TIMESPEC_LE */ + break; + + case ENC_TIME_NTP|ENC_LITTLE_ENDIAN: + /* + * NTP time stamp, big-endian. + */ + DISSECTOR_ASSERT(length == 8); + time_stamp.secs = tvb_get_letohl(tvb, start); + if (time_stamp.secs) + time_stamp.secs -= NTP_BASETIME; + + /* + * We're using nanoseconds here (and we will + * display nanoseconds), but NTP's timestamps + * have a precision in microseconds or greater. + * Round to 1 microsecond. + */ + time_stamp.nsecs = (int)(1000000*(tvb_get_letohl(tvb, start+4)/4294967296.0)); + time_stamp.nsecs *= 1000; + break; + + default: + DISSECTOR_ASSERT_NOT_REACHED(); + time_stamp.secs = 0; + time_stamp.nsecs = 0; + break; + } + proto_tree_set_time(new_fi, &time_stamp); + break; + + case FT_RELATIVE_TIME: + /* + * Relative times can be in any of a number of + * formats, and they can be big-endian or + * little-endian. + * + * Historically FT_TIMEs were only timespecs; + * the only question was whether they were stored + * in big- or little-endian format. + * + * For backwards compatibility, we interpret an + * encoding of 1 as meaning "little-endian timespec", + * so that passing TRUE is interpreted as that. + */ + if (encoding == TRUE) + encoding = ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN; + switch (encoding) { + + case ENC_TIME_TIMESPEC|ENC_BIG_ENDIAN: + /* + * 4-byte UNIX epoch, possibly followed by + * 4-byte fractional time in nanoseconds, + * both big-endian. + */ + DISSECTOR_ASSERT(length == 8 || length == 4); + time_stamp.secs = tvb_get_ntohl(tvb, start); + if (length == 8) + time_stamp.nsecs = tvb_get_ntohl(tvb, start+4); + else + time_stamp.nsecs = 0; + break; + + case ENC_TIME_TIMESPEC|ENC_LITTLE_ENDIAN: + /* + * 4-byte UNIX epoch, possibly followed by + * 4-byte fractional time in nanoseconds, + * both little-endian. + */ DISSECTOR_ASSERT(length == 8 || length == 4); time_stamp.secs = tvb_get_letohl(tvb, start); if (length == 8) time_stamp.nsecs = tvb_get_letohl(tvb, start+4); else time_stamp.nsecs = 0; + break; } - proto_tree_set_time(new_fi, &time_stamp); break; @@ -1508,12 +1673,7 @@ proto_tree_new_item(field_info *new_fi, proto_tree *tree, DISSECTOR_ASSERT_NOT_REACHED(); break; } - /* - * XXX - this should just check the ENC_*_ENDIAN bit, with - * those fields for which we treat any non-zero value of - * "encoding" checking the rest of the bits. - */ - FI_SET_FLAG(new_fi, (encoding) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN); + FI_SET_FLAG(new_fi, (encoding & ENC_LITTLE_ENDIAN) ? FI_LITTLE_ENDIAN : FI_BIG_ENDIAN); /* Don't add new node to proto_tree until now so that any exceptions * raised by a tvbuff access method doesn't leave junk in the proto_tree. */ diff --git a/epan/proto.h b/epan/proto.h index 6dc5f70425..457211e0cd 100644 --- a/epan/proto.h +++ b/epan/proto.h @@ -205,13 +205,16 @@ typedef struct _protocol protocol_t; */ #define ENC_BIG_ENDIAN 0x00000000 #define ENC_LITTLE_ENDIAN 0x80000000 -/* Historically FT_TIMEs were only timespecs, the only question was whether - * they were stored in big- or little-endian format. These macros use the - * big/little-endian values for backwards compatibility. + +/* + * Historically FT_TIMEs were only timespecs; the only question was whether + * they were stored in big- or little-endian format. + * + * For backwards compatibility, we interpret an encoding of 1 as meaning + * "little-endian timespec", so that passing TRUE is interpreted as that. */ -#define ENC_TIME_TIMESPEC_BE ENC_BIG_ENDIAN -#define ENC_TIME_TIMESPEC_LE ENC_LITTLE_ENDIAN -#define ENC_TIME_NTP 0x00000002 +#define ENC_TIME_TIMESPEC 0 +#define ENC_TIME_NTP 2 #define ENC_NA 0x00000000