diff options
Diffstat (limited to 'epan/dissectors/packet-umts_rlc.c')
-rw-r--r-- | epan/dissectors/packet-umts_rlc.c | 304 |
1 files changed, 171 insertions, 133 deletions
diff --git a/epan/dissectors/packet-umts_rlc.c b/epan/dissectors/packet-umts_rlc.c index fec5c31445..8ad24eeb7b 100644 --- a/epan/dissectors/packet-umts_rlc.c +++ b/epan/dissectors/packet-umts_rlc.c @@ -11,11 +11,13 @@ #include "config.h" -#include <epan/packet.h> #include <epan/conversation.h> +#include <epan/exceptions.h> #include <epan/expert.h> +#include <epan/packet.h> #include <epan/prefs.h> #include <epan/proto_data.h> +#include <epan/show_exception.h> #include <wiretap/wtap.h> @@ -36,7 +38,7 @@ void proto_register_rlc(void); void proto_reg_handoff_rlc(void); -int proto_umts_rlc = -1; +int proto_umts_rlc; extern int proto_fp; @@ -71,81 +73,82 @@ static const enum_val_t li_size_enumvals[] = { {NULL, NULL, -1}}; /* fields */ -static int hf_rlc_seq = -1; -static int hf_rlc_ext = -1; -static int hf_rlc_pad = -1; -static int hf_rlc_frags = -1; -static int hf_rlc_frag = -1; -static int hf_rlc_duplicate_of = -1; -static int hf_rlc_reassembled_in = -1; -static int hf_rlc_he = -1; -static int hf_rlc_dc = -1; -static int hf_rlc_p = -1; -static int hf_rlc_li = -1; -static int hf_rlc_li_value = -1; -static int hf_rlc_li_ext = -1; -static int hf_rlc_li_data = -1; -static int hf_rlc_data = -1; -static int hf_rlc_ciphered_data = -1; -static int hf_rlc_ciphered_lis_data = -1; -static int hf_rlc_ctrl_type = -1; -static int hf_rlc_r1 = -1; -static int hf_rlc_rsn = -1; -static int hf_rlc_hfni = -1; -static int hf_rlc_sufi = -1; -static int hf_rlc_sufi_type = -1; -static int hf_rlc_sufi_lsn = -1; -static int hf_rlc_sufi_wsn = -1; -static int hf_rlc_sufi_sn = -1; -static int hf_rlc_sufi_l = -1; -static int hf_rlc_sufi_fsn = -1; -static int hf_rlc_sufi_len = -1; -static int hf_rlc_sufi_bitmap = -1; -static int hf_rlc_sufi_cw = -1; -static int hf_rlc_sufi_n = -1; -static int hf_rlc_sufi_sn_ack = -1; -static int hf_rlc_sufi_sn_mrw = -1; -static int hf_rlc_sufi_poll_sn = -1; -static int hf_rlc_header_only = -1; -static int hf_rlc_channel = -1; -static int hf_rlc_channel_rbid = -1; -static int hf_rlc_channel_dir = -1; -static int hf_rlc_channel_ueid = -1; -static int hf_rlc_sequence_number = -1; -static int hf_rlc_length = -1; -static int hf_rlc_bitmap_string = -1; +static int hf_rlc_seq; +static int hf_rlc_ext; +static int hf_rlc_pad; +static int hf_rlc_reassembled_data; +static int hf_rlc_frags; +static int hf_rlc_frag; +static int hf_rlc_duplicate_of; +static int hf_rlc_reassembled_in; +static int hf_rlc_he; +static int hf_rlc_dc; +static int hf_rlc_p; +static int hf_rlc_li; +static int hf_rlc_li_value; +static int hf_rlc_li_ext; +static int hf_rlc_li_data; +static int hf_rlc_data; +static int hf_rlc_ciphered_data; +static int hf_rlc_ciphered_lis_data; +static int hf_rlc_ctrl_type; +static int hf_rlc_r1; +static int hf_rlc_rsn; +static int hf_rlc_hfni; +static int hf_rlc_sufi; +static int hf_rlc_sufi_type; +static int hf_rlc_sufi_lsn; +static int hf_rlc_sufi_wsn; +static int hf_rlc_sufi_sn; +static int hf_rlc_sufi_l; +static int hf_rlc_sufi_fsn; +static int hf_rlc_sufi_len; +static int hf_rlc_sufi_bitmap; +static int hf_rlc_sufi_cw; +static int hf_rlc_sufi_n; +static int hf_rlc_sufi_sn_ack; +static int hf_rlc_sufi_sn_mrw; +static int hf_rlc_sufi_poll_sn; +static int hf_rlc_header_only; +static int hf_rlc_channel; +static int hf_rlc_channel_rbid; +static int hf_rlc_channel_dir; +static int hf_rlc_channel_ueid; +static int hf_rlc_sequence_number; +static int hf_rlc_length; +static int hf_rlc_bitmap_string; /* subtrees */ -static int ett_rlc = -1; -static int ett_rlc_frag = -1; -static int ett_rlc_fragments = -1; -static int ett_rlc_sdu = -1; -static int ett_rlc_sufi = -1; -static int ett_rlc_bitmap = -1; -static int ett_rlc_rlist = -1; -static int ett_rlc_channel = -1; - -static expert_field ei_rlc_li_reserved = EI_INIT; -static expert_field ei_rlc_he = EI_INIT; -static expert_field ei_rlc_li_incorrect_mal = EI_INIT; -static expert_field ei_rlc_sufi_cw = EI_INIT; -static expert_field ei_rlc_kasumi_implementation_missing = EI_INIT; -static expert_field ei_rlc_reassembly_unknown_error = EI_INIT; -static expert_field ei_rlc_reassembly_lingering_endpoint = EI_INIT; -static expert_field ei_rlc_sufi_len = EI_INIT; -static expert_field ei_rlc_reassembly_fail_unfinished_sequence = EI_INIT; -static expert_field ei_rlc_reassembly_fail_flag_set = EI_INIT; -static expert_field ei_rlc_sufi_type = EI_INIT; -static expert_field ei_rlc_reserved_bits_not_zero = EI_INIT; -static expert_field ei_rlc_ctrl_type = EI_INIT; -static expert_field ei_rlc_li_incorrect_warn = EI_INIT; -static expert_field ei_rlc_li_too_many = EI_INIT; -static expert_field ei_rlc_header_only = EI_INIT; -static expert_field ei_rlc_ciphered_data = EI_INIT; -static expert_field ei_rlc_no_per_frame_data = EI_INIT; -static expert_field ei_rlc_incomplete_sequence = EI_INIT; -static expert_field ei_rlc_unknown_udp_framing_tag = EI_INIT; -static expert_field ei_rlc_missing_udp_framing_tag = EI_INIT; +static int ett_rlc; +static int ett_rlc_frag; +static int ett_rlc_fragments; +static int ett_rlc_sdu; +static int ett_rlc_sufi; +static int ett_rlc_bitmap; +static int ett_rlc_rlist; +static int ett_rlc_channel; + +static expert_field ei_rlc_li_reserved; +static expert_field ei_rlc_he; +static expert_field ei_rlc_li_incorrect_mal; +static expert_field ei_rlc_sufi_cw; +static expert_field ei_rlc_kasumi_implementation_missing; +static expert_field ei_rlc_reassembly_unknown_error; +static expert_field ei_rlc_reassembly_lingering_endpoint; +static expert_field ei_rlc_sufi_len; +static expert_field ei_rlc_reassembly_fail_unfinished_sequence; +static expert_field ei_rlc_reassembly_fail_flag_set; +static expert_field ei_rlc_sufi_type; +static expert_field ei_rlc_reserved_bits_not_zero; +static expert_field ei_rlc_ctrl_type; +static expert_field ei_rlc_li_incorrect_warn; +static expert_field ei_rlc_li_too_many; +static expert_field ei_rlc_header_only; +static expert_field ei_rlc_ciphered_data; +static expert_field ei_rlc_no_per_frame_data; +static expert_field ei_rlc_incomplete_sequence; +static expert_field ei_rlc_unknown_udp_framing_tag; +static expert_field ei_rlc_missing_udp_framing_tag; static dissector_handle_t ip_handle; static dissector_handle_t rrc_handle; @@ -375,7 +378,7 @@ rlc_channel_create(enum rlc_mode mode, packet_info *pinfo, struct atm_phdr *atm) struct rlc_channel *ch; int rv; - ch = (struct rlc_channel *)g_malloc0(sizeof(struct rlc_channel)); + ch = g_new0(struct rlc_channel, 1); rv = rlc_channel_assign(ch, mode, pinfo, atm); if (rv != 0) { @@ -420,7 +423,7 @@ rlc_sdu_create(void) { struct rlc_sdu *sdu; - sdu = (struct rlc_sdu *)wmem_alloc0(wmem_file_scope(), sizeof(struct rlc_sdu)); + sdu = wmem_new0(wmem_file_scope(), struct rlc_sdu); return sdu; } @@ -470,8 +473,7 @@ rlc_frag_assign_data(struct rlc_frag *frag, tvbuff_t *tvb, guint16 offset, guint16 length) { frag->len = length; - frag->data = (guint8 *)g_malloc(length); - tvb_memcpy(tvb, frag->data, offset, length); + frag->data = (guint8 *)tvb_memdup(wmem_file_scope(), tvb, offset, length); return 0; } @@ -482,7 +484,7 @@ rlc_frag_create(tvbuff_t *tvb, enum rlc_mode mode, packet_info *pinfo, { struct rlc_frag *frag; - frag = (struct rlc_frag *)wmem_alloc0(wmem_file_scope(), sizeof(struct rlc_frag)); + frag = wmem_new0(wmem_file_scope(), struct rlc_frag); rlc_frag_assign(frag, mode, pinfo, seq, li, atm); rlc_frag_assign_data(frag, tvb, offset, length); @@ -584,7 +586,7 @@ fragment_table_cleanup(void) /* add the list of fragments for this sdu to 'tree' */ static void -tree_add_fragment_list(struct rlc_sdu *sdu, tvbuff_t *tvb, proto_tree *tree) +tree_add_fragment_list(struct rlc_sdu *sdu, tvbuff_t *tvb,packet_info *pinfo, proto_tree *tree) { proto_item *ti; proto_tree *frag_tree; @@ -592,8 +594,9 @@ tree_add_fragment_list(struct rlc_sdu *sdu, tvbuff_t *tvb, proto_tree *tree) struct rlc_frag *sdufrag; ti = proto_tree_add_item(tree, hf_rlc_frags, tvb, 0, -1, ENC_NA); + proto_item_set_generated(ti); frag_tree = proto_item_add_subtree(ti, ett_rlc_fragments); - proto_item_append_text(ti, " (%u bytes, %u fragments): ", + proto_item_append_text(ti, " (%u bytes, %u fragments) ", sdu->len, sdu->fragcnt); sdufrag = sdu->frags; offset = 0; @@ -607,9 +610,14 @@ tree_add_fragment_list(struct rlc_sdu *sdu, tvbuff_t *tvb, proto_tree *tree) sdufrag->len, sdufrag->frame_num, "Frame: %u, payload: none (0 bytes) (Seq: %u)", sdufrag->frame_num, sdufrag->seq); } + + mark_frame_as_depended_upon(pinfo->fd, sdufrag->frame_num); + offset += sdufrag->len; sdufrag = sdufrag->next; } + ti = proto_tree_add_item(ti, hf_rlc_reassembled_data, tvb, 0, -1, ENC_NA); + proto_item_set_generated(ti); } /* add the list of fragments for this sdu to 'tree' */ @@ -622,8 +630,9 @@ tree_add_fragment_list_incomplete(struct rlc_sdu *sdu, tvbuff_t *tvb, proto_tree struct rlc_frag *sdufrag; ti = proto_tree_add_item(tree, hf_rlc_frags, tvb, 0, 0, ENC_NA); + proto_item_set_generated(ti); frag_tree = proto_item_add_subtree(ti, ett_rlc_fragments); - proto_item_append_text(ti, " (%u bytes, %u fragments): ", + proto_item_append_text(ti, " (%u bytes, %u fragments) ", sdu->len, sdu->fragcnt); sdufrag = sdu->frags; offset = 0; @@ -639,6 +648,9 @@ tree_add_fragment_list_incomplete(struct rlc_sdu *sdu, tvbuff_t *tvb, proto_tree /* Add the same description to too the two given proto_items */ static void add_description(proto_item *li_ti, proto_item *length_ti, + const char *format, ...) G_GNUC_PRINTF(3, 4); +static void +add_description(proto_item *li_ti, proto_item *length_ti, const char *format, ...) { #define MAX_INFO_BUFFER 256 @@ -647,7 +659,7 @@ add_description(proto_item *li_ti, proto_item *length_ti, va_list ap; va_start(ap, format); - g_vsnprintf(info_buffer, MAX_INFO_BUFFER, format, ap); + vsnprintf(info_buffer, MAX_INFO_BUFFER, format, ap); va_end(ap); proto_item_append_text(li_ti, " (%s)", info_buffer); @@ -761,7 +773,7 @@ tree_add_li(enum rlc_mode mode, struct rlc_li *li, guint8 li_idx, guint32 hdr_of if (li->li > tvb_reported_length_remaining(tvb, hdr_offs)) return li_tree; if (li->len > li->li) return li_tree; ti = proto_tree_add_item(li_tree, hf_rlc_li_data, tvb, hdr_offs + li->li - li->len, li->len, ENC_NA); - PROTO_ITEM_SET_HIDDEN(ti); + proto_item_set_hidden(ti); } return li_tree; @@ -848,7 +860,7 @@ reassemble_data(struct rlc_channel *ch, struct rlc_sdu *sdu, struct rlc_frag *fr temp = sdu->frags; while (temp && ((offs + temp->len) <= sdu->len)) { memcpy(sdu->data + offs, temp->data, temp->len); - g_free(temp->data); + wmem_free(wmem_file_scope(), temp->data); temp->data = NULL; /* mark this fragment in reassembled table */ g_hash_table_insert(reassembled_table, temp, sdu); @@ -951,6 +963,7 @@ reassemble_sequence(struct rlc_frag ** frags, struct rlc_seqlist * endlist, /* Reset the specified channel's reassembly data, useful for when a sequence * resets on transport channel swap. */ +/* TODO: not currently called */ void rlc_reset_channel(enum rlc_mode mode, guint8 rbid, guint8 dir, guint32 ueid, struct atm_phdr *atm) @@ -966,14 +979,16 @@ rlc_reset_channel(enum rlc_mode mode, guint8 rbid, guint8 dir, guint32 ueid, ch_lookup.ueid = ueid; frags = get_frags(NULL, &ch_lookup, atm); endlist = get_endlist(NULL, &ch_lookup, atm); - DISSECTOR_ASSERT(frags && endlist); - - endlist->fail_packet = 0; - g_list_free(endlist->list); - endlist->list = NULL; + if (endlist) { + endlist->fail_packet = 0; + g_list_free(endlist->list); + endlist->list = NULL; + } - for (i = 0; i < 4096; i++) { - frags[i] = NULL; + if (frags) { + for (i = 0; i < 4096; i++) { + frags[i] = NULL; + } } } @@ -1023,7 +1038,7 @@ add_fragment(enum rlc_mode mode, tvbuff_t *tvb, packet_info *pinfo, endlist = get_endlist(pinfo, &ch_lookup, atm); /* If already done reassembly */ - if (pinfo->fd->flags.visited) { + if (PINFO_FD_VISITED(pinfo)) { if (tree && len > 0) { if (endlist->list && endlist->list->next) { gint16 start = (GPOINTER_TO_INT(endlist->list->data) + 1) % snmod; @@ -1225,7 +1240,7 @@ get_reassembled_data(enum rlc_mode mode, tvbuff_t *tvb, packet_info *pinfo, /* reassembly happened here, so create the fragment list */ if (tree && sdu->fragcnt > 1) - tree_add_fragment_list(sdu, sdu->tvb, tree); + tree_add_fragment_list(sdu, sdu->tvb, pinfo, tree); return sdu->tvb; } @@ -1293,7 +1308,7 @@ rlc_is_duplicate(enum rlc_mode mode, packet_info *pinfo, guint16 seq, } if(is_unseen) { /* Add to list for the first time this frame is checked */ - seq_new = (struct rlc_seq *)wmem_alloc0(wmem_file_scope(), sizeof(struct rlc_seq)); + seq_new = wmem_new0(wmem_file_scope(), struct rlc_seq); *seq_new = seq_item; seq_new->arrival = pinfo->abs_ts; list->list = g_list_append(list->list, seq_new); /* insert in order of arrival */ @@ -1305,7 +1320,10 @@ static void rlc_call_subdissector(enum rlc_channel_type channel, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) { + gboolean is_rrc_payload = TRUE; + volatile dissector_handle_t next_dissector = NULL; enum rrc_message_type msgtype; + switch (channel) { case RLC_UL_CCCH: msgtype = RRC_MESSAGE_TYPE_UL_CCCH; @@ -1314,11 +1332,10 @@ rlc_call_subdissector(enum rlc_channel_type channel, tvbuff_t *tvb, msgtype = RRC_MESSAGE_TYPE_DL_CCCH; break; case RLC_DL_CTCH: + /* Payload of DL CTCH is BMC*/ + is_rrc_payload = FALSE; msgtype = RRC_MESSAGE_TYPE_INVALID; - call_dissector(bmc_handle, tvb, pinfo, tree); - /* once the packet has been dissected, protect it from further changes using a 'fence' in the INFO column */ - col_append_str(pinfo->cinfo, COL_INFO," "); - col_set_fence(pinfo->cinfo, COL_INFO); + next_dissector = bmc_handle; break; case RLC_UL_DCCH: msgtype = RRC_MESSAGE_TYPE_UL_DCCH; @@ -1333,17 +1350,18 @@ rlc_call_subdissector(enum rlc_channel_type channel, tvbuff_t *tvb, msgtype = RRC_MESSAGE_TYPE_BCCH_FACH; break; case RLC_PS_DTCH: + /* Payload of PS DTCH is PDCP or just IP*/ + is_rrc_payload = FALSE; msgtype = RRC_MESSAGE_TYPE_INVALID; /* assume transparent PDCP for now */ - call_dissector(ip_handle, tvb, pinfo, tree); - /* once the packet has been dissected, protect it from further changes using a 'fence' in the INFO column */ - col_append_str(pinfo->cinfo, COL_INFO," "); - col_set_fence(pinfo->cinfo, COL_INFO); + next_dissector = ip_handle; break; default: return; /* stop dissecting */ } - if (msgtype != RRC_MESSAGE_TYPE_INVALID) { + + if (is_rrc_payload && msgtype != RRC_MESSAGE_TYPE_INVALID) { + /* Passing the RRC sub type in the 'rrc_info' struct */ struct rrc_info *rrcinf; fp_info *fpinf; fpinf = (fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0); @@ -1353,7 +1371,21 @@ rlc_call_subdissector(enum rlc_channel_type channel, tvbuff_t *tvb, p_add_proto_data(wmem_file_scope(), pinfo, proto_rrc, 0, rrcinf); } rrcinf->msgtype[fpinf->cur_tb] = msgtype; - call_dissector(rrc_handle, tvb, pinfo, tree); + next_dissector = rrc_handle; + } + + if(next_dissector != NULL) { + TRY { + call_dissector(next_dissector, tvb, pinfo, tree); + } + CATCH_NONFATAL_ERRORS { + /* + * Sub dissector threw an exception + * Show the exception and continue dissecting other SDUs. + */ + show_exception(tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE); + } + ENDTRY; /* once the packet has been dissected, protect it from further changes using a 'fence' in the INFO column */ col_append_str(pinfo->cinfo, COL_INFO," "); col_set_fence(pinfo->cinfo, COL_INFO); @@ -1370,13 +1402,13 @@ add_channel_info(packet_info * pinfo, proto_tree * tree, fp_info * fpinf, rlc_in channel_tree = proto_item_add_subtree(item, ett_rlc_channel); proto_item_append_text(item, " (rbid: %u, dir: %s, uid: 0x%08x)", rlcinf->rbid[fpinf->cur_tb], val_to_str_const(pinfo->link_dir, rlc_dir_vals, "Unknown"), rlcinf->ueid[fpinf->cur_tb]); - PROTO_ITEM_SET_GENERATED(item); + proto_item_set_generated(item); item = proto_tree_add_uint(channel_tree, hf_rlc_channel_rbid, NULL, 0, 0, rlcinf->rbid[fpinf->cur_tb]); - PROTO_ITEM_SET_GENERATED(item); + proto_item_set_generated(item); item = proto_tree_add_uint(channel_tree, hf_rlc_channel_dir, NULL, 0, 0, pinfo->link_dir); - PROTO_ITEM_SET_GENERATED(item); + proto_item_set_generated(item); item = proto_tree_add_uint(channel_tree, hf_rlc_channel_ueid, NULL, 0, 0, rlcinf->ueid[fpinf->cur_tb]); - PROTO_ITEM_SET_GENERATED(item); + proto_item_set_generated(item); } @@ -1386,7 +1418,7 @@ translate_hex_key(gchar * char_key){ int i,j; guint8 * key_in; - key_in = wmem_alloc0(wmem_packet_scope(), sizeof(guint8)*16); + key_in = wmem_alloc0(pinfo->pool, sizeof(guint8)*16); j= (int)(strlen(char_key)/2)-1; /*Translate "hex-string" into a byte aligned block */ for(i = (int)strlen(char_key); i> 0; i-=2 ){ @@ -1429,7 +1461,7 @@ rlc_decipher_tvb(tvbuff_t *tvb, packet_info *pinfo, guint32 counter, guint8 rbid /*Fix the key into a byte block*/ /*TODO: This should be done in a preferences callback function*/ - out = wmem_alloc0(wmem_packet_scope(), strlen(global_rlc_kasumi_key)+1); + out = wmem_alloc0(pinfo->pool, strlen(global_rlc_kasumi_key)+1); memcpy(out,global_rlc_kasumi_key,strlen(global_rlc_kasumi_key)); /*Copy from prefrence const pointer*/ key_in = translate_hex_key(out); /*Translation*/ @@ -1481,7 +1513,8 @@ is_ciphered_according_to_rrc(packet_info *pinfo, fp_info *fpinf, rlc_info *rlcin /* Making sure the sequence number where ciphering starts makes sense */ /* TODO: This check is incorrect if the sequence numbers wrap around */ if(ciphering_begin_seq >= 0 && ciphering_begin_seq <= seq){ - return TRUE; + /* Finally, make sure the encryption algorithm isn't set to UEA0 (no ciphering)*/ + return ciphering_info->ciphering_algorithm != 0; } } } @@ -1577,7 +1610,7 @@ rlc_decipher(tvbuff_t *tvb, packet_info * pinfo, proto_tree * tree, fp_info * fp if(!tree){ /*Preserve counter value for next dissection round*/ guint32 * ciph; - ciph = (guint32 *)g_malloc(sizeof(guint32)*2); + ciph = g_new(guint32, 2); ciph[0] = ps_counter[rlcinf->rbid[pos]][0]; ciph[1] = ps_counter[rlcinf->rbid[pos]][1]; g_tree_insert(counter_map, GINT_TO_POINTER((gint)pinfo->num), ciph); @@ -1617,7 +1650,7 @@ rlc_decipher(tvbuff_t *tvb, packet_info * pinfo, proto_tree * tree, fp_info * fp if(!tree){/*Preserve counter for second packet analysis run*/ guint32 * ciph; - ciph = (guint32 *)g_malloc(sizeof(guint32)*2); + ciph = g_new(guint32, 2); ciph[0] = ps_counter[rlcinf->rbid[pos]][0]; ciph[1] = ps_counter[rlcinf->rbid[pos]][1]; g_tree_insert(counter_map, GINT_TO_POINTER((gint)pinfo->num+1), ciph); @@ -1665,7 +1698,7 @@ dissect_rlc_tm(enum rlc_channel_type channel, tvbuff_t *tvb, packet_info *pinfo, static void -rlc_um_reassemble(tvbuff_t *tvb, guint8 offs, packet_info *pinfo, proto_tree *tree, +rlc_um_reassemble(tvbuff_t *tvb, guint16 offs, packet_info *pinfo, proto_tree *tree, proto_tree *top_level, enum rlc_channel_type channel, guint16 seq, struct rlc_li *li, guint16 num_li, gboolean li_is_on_2_bytes, struct atm_phdr *atm) @@ -1892,7 +1925,8 @@ dissect_rlc_um(enum rlc_channel_type channel, tvbuff_t *tvb, packet_info *pinfo, guint32 orig_num; guint8 seq; guint8 ext; - guint8 next_byte, offs = 0; + guint8 next_byte; + guint16 offs = 0; gint16 cur_tb, num_li = 0; gboolean is_truncated, li_is_on_2_bytes; proto_item *truncated_ti; @@ -1964,11 +1998,11 @@ dissect_rlc_um(enum rlc_channel_type channel, tvbuff_t *tvb, packet_info *pinfo, truncated_ti = proto_tree_add_boolean(tree, hf_rlc_header_only, tvb, 0, 0, is_truncated); if (is_truncated) { - PROTO_ITEM_SET_GENERATED(truncated_ti); + proto_item_set_generated(truncated_ti); expert_add_info(pinfo, truncated_ti, &ei_rlc_header_only); return; } else { - PROTO_ITEM_SET_HIDDEN(truncated_ti); + proto_item_set_hidden(truncated_ti); } } @@ -1984,7 +2018,7 @@ dissect_rlc_um(enum rlc_channel_type channel, tvbuff_t *tvb, packet_info *pinfo, } static void -dissect_rlc_status(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint8 offset) +dissect_rlc_status(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint16 offset) { guint8 sufi_type, bits; guint64 len, sn, wsn, lsn, l; @@ -2063,16 +2097,16 @@ dissect_rlc_status(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guin bitmap_tree = proto_tree_add_subtree(sufi_tree, tvb, bit_offset/8, (gint)len, ett_rlc_bitmap, &ti, "Decoded bitmap:"); col_append_str(pinfo->cinfo, COL_INFO, " BITMAP=("); - buff = (gchar *)wmem_alloc(wmem_packet_scope(), BUFF_SIZE); + buff = (gchar *)wmem_alloc(pinfo->pool, BUFF_SIZE); for (i=0; i<len; i++) { bits = tvb_get_bits8(tvb, bit_offset, 8); for (l=0, j=0; l<8; l++) { if ((bits << l) & 0x80) { - j += g_snprintf(&buff[j], BUFF_SIZE-j, "%4u,", (unsigned)(sn+(8*i)+l)&0xfff); + j += snprintf(&buff[j], BUFF_SIZE-j, "%4u,", (unsigned)(sn+(8*i)+l)&0xfff); col_append_fstr(pinfo->cinfo, COL_INFO, " %u", (unsigned)(sn+(8*i)+l)&0xfff); number_of_bitmap_entries++; } else { - j += g_snprintf(&buff[j], BUFF_SIZE-j, " ,"); + j += snprintf(&buff[j], BUFF_SIZE-j, " ,"); } } proto_tree_add_string_format(bitmap_tree, hf_rlc_bitmap_string, tvb, bit_offset/8, 1, buff, "%s", buff); @@ -2210,7 +2244,7 @@ dissect_rlc_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree) } static void -rlc_am_reassemble(tvbuff_t *tvb, guint8 offs, packet_info *pinfo, +rlc_am_reassemble(tvbuff_t *tvb, guint16 offs, packet_info *pinfo, proto_tree *tree, proto_tree *top_level, enum rlc_channel_type channel, guint16 seq, gboolean poll_set, struct rlc_li *li, guint16 num_li, gboolean final, gboolean li_is_on_2_bytes, @@ -2303,11 +2337,11 @@ dissect_rlc_am(enum rlc_channel_type channel, tvbuff_t *tvb, packet_info *pinfo, fp_info *fpinf; rlc_info *rlcinf; guint8 ext, dc; - guint8 next_byte, offs = 0; + guint8 next_byte; guint32 orig_num = 0; gint16 num_li = 0; gint16 cur_tb; - guint16 seq; + guint16 seq, offs = 0; gboolean is_truncated, li_is_on_2_bytes; proto_item *truncated_ti, *ti; guint64 polling; @@ -2396,21 +2430,21 @@ dissect_rlc_am(enum rlc_channel_type channel, tvbuff_t *tvb, packet_info *pinfo, truncated_ti = proto_tree_add_boolean(tree, hf_rlc_header_only, tvb, 0, 0, is_truncated); if (is_truncated) { - PROTO_ITEM_SET_GENERATED(truncated_ti); + proto_item_set_generated(truncated_ti); expert_add_info(pinfo, truncated_ti, &ei_rlc_header_only); return; } else { - PROTO_ITEM_SET_HIDDEN(truncated_ti); + proto_item_set_hidden(truncated_ti); } } /* do not detect duplicates or reassemble, if prefiltering is done */ if (pinfo->num == 0) return; /* check for duplicates, but not if already visited */ - if (pinfo->fd->flags.visited == FALSE && rlc_is_duplicate(RLC_AM, pinfo, seq, &orig_num, atm) == TRUE) { + if (!PINFO_FD_VISITED(pinfo) && rlc_is_duplicate(RLC_AM, pinfo, seq, &orig_num, atm) == TRUE) { g_hash_table_insert(duplicate_table, GUINT_TO_POINTER(pinfo->num), GUINT_TO_POINTER(orig_num)); return; - } else if (pinfo->fd->flags.visited == TRUE && tree) { + } else if (PINFO_FD_VISITED(pinfo) && tree) { gpointer value = g_hash_table_lookup(duplicate_table, GUINT_TO_POINTER(pinfo->num)); if (value != NULL) { col_add_fstr(pinfo->cinfo, COL_INFO, "[RLC AM Fragment] [Duplicate] SN=%u %s", seq, (polling != 0) ? "(P)" : ""); @@ -2696,14 +2730,14 @@ dissect_rlc_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data fpi = (fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0); if (fpi == NULL) { /* Allocate new info struct for this frame */ - fpi = (fp_info *)wmem_alloc0(wmem_file_scope(), sizeof(fp_info)); + fpi = wmem_new0(wmem_file_scope(), fp_info); } else { fpInfoAlreadySet = TRUE; } rlci = (rlc_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_umts_rlc, 0); if (rlci == NULL) { /* Allocate new info struct for this frame */ - rlci = (rlc_info *)wmem_alloc0(wmem_file_scope(), sizeof(rlc_info)); + rlci = wmem_new0(wmem_file_scope(), rlc_info); } else { rlcInfoAlreadySet = TRUE; } @@ -2872,6 +2906,10 @@ proto_register_rlc(void) { "Padding", "rlc.padding", FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL } }, + { &hf_rlc_reassembled_data, + { "Reassembled RLC Data", "rlc.reassembled_data", + FT_BYTES, BASE_NONE, NULL, 0, "The reassembled payload", HFILL } + }, { &hf_rlc_frags, { "Reassembled Fragments", "rlc.fragments", FT_NONE, BASE_NONE, NULL, 0, "Fragments", HFILL } @@ -3036,7 +3074,7 @@ proto_register_rlc(void) { &ei_rlc_reserved_bits_not_zero, { "rlc.reserved_bits_not_zero", PI_PROTOCOL, PI_WARN, "reserved bits not zero", EXPFILL }}, { &ei_rlc_ctrl_type, { "rlc.ctrl_pdu_type.invalid", PI_PROTOCOL, PI_WARN, "Invalid RLC AM control type", EXPFILL }}, { &ei_rlc_he, { "rlc.he.invalid", PI_PROTOCOL, PI_WARN, "Incorrect HE value", EXPFILL }}, - { &ei_rlc_ciphered_data, { "rlc.ciphered_data", PI_UNDECODED, PI_WARN, "Cannot dissect RLC frame because it is ciphered", EXPFILL }}, + { &ei_rlc_ciphered_data, { "rlc.ciphered", PI_UNDECODED, PI_WARN, "Cannot dissect RLC frame because it is ciphered", EXPFILL }}, { &ei_rlc_no_per_frame_data, { "rlc.no_per_frame_data", PI_PROTOCOL, PI_WARN, "Can't dissect RLC frame because no per-frame info was attached!", EXPFILL }}, { &ei_rlc_incomplete_sequence, { "rlc.incomplete_sequence", PI_MALFORMED, PI_ERROR, "Error: Incomplete sequence", EXPFILL }}, { &ei_rlc_unknown_udp_framing_tag, { "rlc.unknown_udp_framing_tag", PI_UNDECODED, PI_WARN, "Unknown UDP framing tag, aborting dissection", EXPFILL }}, |