Fixup: tvb_get_string(z) -> tvb_get_string(z)_enc
[metze/wireshark/wip.git] / epan / dissectors / packet-rlc.c
1 /* Routines for UMTS RLC (Radio Link Control) v9.3.0 disassembly
2  * http://www.3gpp.org/ftp/Specs/archive/25_series/25.322/
3  *
4  * Wireshark - Network traffic analyzer
5  * By Gerald Combs <gerald@wireshark.org>
6  * Copyright 1998 Gerald Combs
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21  */
22
23 #include "config.h"
24
25 #include <string.h>
26 #include <glib.h>
27
28 #include <epan/packet.h>
29 #include <epan/wmem/wmem.h>
30 #include <epan/conversation.h>
31 #include <epan/asn1.h>
32 #include <epan/expert.h>
33 #include <epan/prefs.h>
34 #include <wiretap/wtap.h>
35
36 /*
37  * Optional include, for KASUMI support,
38  * see header file for more information.
39  * */
40 #include <epan/crypt/kasumi.h>
41
42 #include "packet-umts_fp.h"
43 #include "packet-umts_mac.h"
44 #include "packet-rlc.h"
45 #include "packet-rrc.h"
46
47 /* TODO:
48  * - distinguish between startpoints and endpoints?
49  * - use sub_num in fragment identification?
50  */
51
52 #define DEBUG_FRAME(number, msg) {if (pinfo->fd->num == number) printf("%u: %s\n", number, msg);}
53
54 #define ROL16(a,b) (guint16)((a<<b)|(a>>(16-b)))
55
56 void proto_register_rlc(void);
57 void proto_reg_handoff_rlc(void);
58
59 int proto_rlc = -1;
60
61 extern int proto_fp;
62
63 /* Preference to perform reassembly */
64 static gboolean global_rlc_perform_reassemby = TRUE;
65
66 /* Preference to expect RLC headers without payloads */
67 static gboolean global_rlc_headers_expected = FALSE;
68
69
70 /* Heuristic dissection */
71 static gboolean global_rlc_heur = FALSE;
72
73 /* Preference to expect ciphered data */
74 static gboolean global_rlc_ciphered = FALSE;
75
76 /* Preference to try deciphering */
77 static gboolean global_rlc_try_decipher = FALSE;
78
79 #ifdef HAVE_UMTS_KASUMI
80 static const char *global_rlc_kasumi_key = NULL;
81 #endif
82
83 /* LI size preference */
84 #define RLC_LI_UPPERLAYER 255 /* LI-size comes from rlc_info struct rather than preference */
85 static gint global_rlc_li_size = RLC_LI_UPPERLAYER;
86
87 static const enum_val_t li_size_enumvals[] = {
88     {"7 bits", "7 bits", RLC_LI_7BITS},
89     {"15 bits", "15 bits", RLC_LI_15BITS},
90     {"Let upper layers decide", "Let upper layers decide", RLC_LI_UPPERLAYER},
91     {NULL, NULL, -1}};
92
93 /* fields */
94 static int hf_rlc_seq = -1;
95 static int hf_rlc_ext = -1;
96 static int hf_rlc_pad = -1;
97 static int hf_rlc_frags = -1;
98 static int hf_rlc_frag = -1;
99 static int hf_rlc_duplicate_of = -1;
100 static int hf_rlc_reassembled_in = -1;
101 static int hf_rlc_he = -1;
102 static int hf_rlc_dc = -1;
103 static int hf_rlc_p = -1;
104 static int hf_rlc_li = -1;
105 static int hf_rlc_li_value = -1;
106 static int hf_rlc_li_ext = -1;
107 static int hf_rlc_li_data = -1;
108 static int hf_rlc_data = -1;
109 static int hf_rlc_ctrl_type = -1;
110 static int hf_rlc_r1 = -1;
111 static int hf_rlc_rsn = -1;
112 static int hf_rlc_hfni = -1;
113 static int hf_rlc_sufi = -1;
114 static int hf_rlc_sufi_type = -1;
115 static int hf_rlc_sufi_lsn = -1;
116 static int hf_rlc_sufi_wsn = -1;
117 static int hf_rlc_sufi_sn = -1;
118 static int hf_rlc_sufi_l = -1;
119 static int hf_rlc_sufi_fsn = -1;
120 static int hf_rlc_sufi_len = -1;
121 static int hf_rlc_sufi_bitmap = -1;
122 static int hf_rlc_sufi_cw = -1;
123 static int hf_rlc_sufi_n = -1;
124 static int hf_rlc_sufi_sn_ack = -1;
125 static int hf_rlc_sufi_sn_mrw = -1;
126 static int hf_rlc_sufi_poll_sn = -1;
127 static int hf_rlc_header_only = -1;
128 static int hf_rlc_channel = -1;
129 static int hf_rlc_channel_rbid = -1;
130 static int hf_rlc_channel_dir = -1;
131 static int hf_rlc_channel_ueid = -1;
132
133 /* subtrees */
134 static int ett_rlc = -1;
135 static int ett_rlc_frag = -1;
136 static int ett_rlc_fragments = -1;
137 static int ett_rlc_sdu = -1;
138 static int ett_rlc_sufi = -1;
139 static int ett_rlc_bitmap = -1;
140 static int ett_rlc_rlist = -1;
141 static int ett_rlc_channel = -1;
142
143 static expert_field ei_rlc_li_reserved = EI_INIT;
144 static expert_field ei_rlc_he = EI_INIT;
145 static expert_field ei_rlc_li_incorrect_mal = EI_INIT;
146 static expert_field ei_rlc_sufi_cw = EI_INIT;
147 static expert_field ei_rlc_kasumi_implementation_missing = EI_INIT;
148 static expert_field ei_rlc_reassembly_unknown_error = EI_INIT;
149 static expert_field ei_rlc_reassembly_lingering_endpoint = EI_INIT;
150 static expert_field ei_rlc_sufi_len = EI_INIT;
151 static expert_field ei_rlc_reassembly_fail_unfinished_sequence = EI_INIT;
152 static expert_field ei_rlc_reassembly_fail_flag_set = EI_INIT;
153 static expert_field ei_rlc_sufi_type = EI_INIT;
154 static expert_field ei_rlc_reserved_bits_not_zero = EI_INIT;
155 static expert_field ei_rlc_ctrl_type = EI_INIT;
156 static expert_field ei_rlc_li_incorrect_warn = EI_INIT;
157 static expert_field ei_rlc_li_too_many = EI_INIT;
158 static expert_field ei_rlc_header_only = EI_INIT;
159
160 static dissector_handle_t ip_handle;
161 static dissector_handle_t rrc_handle;
162 static dissector_handle_t bmc_handle;
163
164 enum rlc_channel_type {
165     RLC_PCCH,
166     RLC_BCCH,
167     RLC_UL_CCCH,
168     RLC_DL_CCCH,
169     RLC_UL_DCCH,
170     RLC_DL_DCCH,
171     RLC_PS_DTCH,
172     RLC_DL_CTCH,
173     RLC_UNKNOWN_CH
174 };
175
176 static const value_string rlc_dir_vals[] = {
177     { P2P_DIR_UL, "Uplink" },
178     { P2P_DIR_DL, "Downlink" },
179     { 0, NULL }
180 };
181
182 static const true_false_string rlc_header_only_val = {
183     "RLC PDU header only", "RLC PDU header and body present"
184 };
185
186 static const true_false_string rlc_ext_val = {
187     "Next field is Length Indicator and E Bit", "Next field is data, piggybacked STATUS PDU or padding"
188 };
189
190 static const true_false_string rlc_dc_val = {
191     "Data", "Control"
192 };
193
194 static const true_false_string rlc_p_val = {
195     "Request a status report", "Status report not requested"
196 };
197
198 static const value_string rlc_he_vals[] = {
199     { 0, "The succeeding octet contains data" },
200     { 1, "The succeeding octet contains a length indicator and E bit" },
201     { 2, "The succeeding octet contains data and the last octet of the PDU is the last octet of an SDU" },
202     { 0, NULL }
203 };
204
205 #define RLC_STATUS      0x0
206 #define RLC_RESET       0x1
207 #define RLC_RESET_ACK   0x2
208 static const value_string rlc_ctrl_vals[] = {
209     { RLC_STATUS,       "Status" },
210     { RLC_RESET,        "Reset" },
211     { RLC_RESET_ACK,    "Reset Ack" },
212     { 0, NULL }
213 };
214
215 #define RLC_SUFI_NOMORE     0x0
216 #define RLC_SUFI_WINDOW     0x1
217 #define RLC_SUFI_ACK        0x2
218 #define RLC_SUFI_LIST       0x3
219 #define RLC_SUFI_BITMAP     0x4
220 #define RLC_SUFI_RLIST      0x5
221 #define RLC_SUFI_MRW        0x6
222 #define RLC_SUFI_MRW_ACK    0x7
223 #define RLC_SUFI_POLL       0x8
224 static const value_string rlc_sufi_vals[] = {
225     { RLC_SUFI_NOMORE,  "No more data" },
226     { RLC_SUFI_WINDOW,  "Window size" },
227     { RLC_SUFI_ACK,     "Acknowledgement" },
228     { RLC_SUFI_LIST,    "List" },
229     { RLC_SUFI_BITMAP,  "Bitmap" },
230     { RLC_SUFI_RLIST,   "Relative list" },
231     { RLC_SUFI_MRW,     "Move receiving window" },
232     { RLC_SUFI_MRW_ACK, "Move receiving window acknowledgement" },
233     { RLC_SUFI_POLL,    "Poll" },
234     { 0, NULL }
235 };
236
237 /* reassembly related data */
238 static GHashTable *fragment_table    = NULL; /* table of not yet assembled fragments */
239 static GHashTable *endpoints = NULL; /* List of SDU-endpoints */
240 static GHashTable *reassembled_table = NULL; /* maps fragment -> complete sdu */
241 static GHashTable *sequence_table    = NULL; /* channel -> seq */
242 static GHashTable *duplicate_table = NULL; /* duplicates */
243
244 /* identify an RLC channel, using one of two options:
245  *  - via Radio Bearer ID and U-RNTI
246  *  - via Radio Bearer ID and (VPI/VCI/CID) + Link ID
247  */
248 struct rlc_channel {
249     guint32          urnti;
250     guint16          vpi;
251     guint16          vci;
252     guint8           cid;
253     guint16          link;  /* link number */
254     guint8           rbid;  /* radio bearer ID */
255     guint8           dir;   /* direction */
256     enum rlc_li_size li_size;
257     enum rlc_mode    mode;
258 };
259
260 /* used for duplicate detection */
261 struct rlc_seq {
262     guint32  frame_num;
263     nstime_t arrival;
264     guint16  seq;
265     guint16  oc;        /* overflow counter, this is not used? */
266 };
267
268 struct rlc_seqlist {
269     struct rlc_channel ch;
270     GList *list;
271     /* We will store one seqlist per channel so this is a good place to indicate
272      *  whether or not this channel's reassembly has failed or not. */
273     guint fail_packet; /* Equal to packet where fail flag was set or 0 otherwise. */
274 };
275
276 /* fragment representation */
277 struct rlc_frag {
278     guint32             frame_num;
279     struct rlc_channel  ch;
280     guint16             seq;  /* RLC sequence number */
281     guint16             li;   /* LI within current RLC frame */
282     guint16             len;  /* length of fragment data */
283     guint8             *data; /* store fragment data here */
284
285     struct rlc_frag *next; /* next fragment */
286 };
287
288 struct rlc_sdu {
289     tvbuff_t        *tvb;     /* contains reassembled tvb */
290     guint16          len;     /* total length of reassembled SDU */
291     guint16          fragcnt; /* number of fragments within this SDU */
292     guint8          *data;    /* reassembled data buffer */
293
294     struct rlc_frag *reassembled_in;
295     struct rlc_frag *frags;   /* pointer to list of fragments */
296     struct rlc_frag *last;    /* pointer to last fragment */
297 };
298
299 struct rlc_li {
300     guint16     li;   /* original li */
301     guint16     len;  /* length of this data fragment */
302     guint8      ext;  /* extension bit value */
303     proto_tree *tree; /* subtree for this LI */
304 };
305
306 /*** KASUMI related variables and structs ***/
307 typedef struct umts_kat_key{    /*Stores 128-bits KASUMI key*/
308     guint64 high;       /*64 MSB*/
309     guint64 low;    /*64 LSB*/
310 }kasumi_key;
311
312
313 /*Counter used as input for confidentiality algorithm*/
314 static guint32 ps_counter[31][2] ;
315 static gboolean counter_init[31][2];
316 static guint32 max_counter = 0;
317 static GTree  * counter_map;    /*Saves the countervalues at first pass through, since they will be update*/
318
319 /* hashtable functions for fragment table
320  * rlc_channel -> SDU
321  */
322 static guint
323 rlc_channel_hash(gconstpointer key)
324 {
325     const struct rlc_channel *ch = (const struct rlc_channel *)key;
326
327     if (ch->urnti)
328         return ch->urnti | ch->rbid | ch->mode;
329
330     return (ch->vci << 16) | (ch->link << 16) | ch->vpi | ch->vci;
331 }
332
333 static gboolean
334 rlc_channel_equal(gconstpointer a, gconstpointer b)
335 {
336     const struct rlc_channel *x = (const struct rlc_channel *)a, *y = (const struct rlc_channel *)b;
337
338     if (x->urnti || y->urnti)
339         return x->urnti == y->urnti &&
340             x->rbid == y->rbid &&
341             x->mode == y->mode &&
342             x->dir == y->dir ? TRUE : FALSE;
343
344     return x->vpi == y->vpi &&
345         x->vci == y->vci &&
346         x->cid == y->cid &&
347         x->rbid == y->rbid &&
348         x->mode == y->mode &&
349         x->dir == y->dir &&
350         x->link == y->link ? TRUE : FALSE;
351 }
352
353 static int
354 rlc_channel_assign(struct rlc_channel *ch, enum rlc_mode mode, packet_info *pinfo)
355 {
356     struct atm_phdr *atm;
357     rlc_info        *rlcinf;
358     fp_info         *fpinf;
359
360     atm = &pinfo->pseudo_header->atm;
361     fpinf = (fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0);
362     rlcinf = (rlc_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_rlc, 0);
363     if (!fpinf || !rlcinf) return -1;
364
365     if (rlcinf->urnti[fpinf->cur_tb]) {
366         ch->urnti = rlcinf->urnti[fpinf->cur_tb];
367         ch->vpi = ch->vci = ch->link = ch->cid = 0;
368     } else {
369         if (!atm) return -1;
370         ch->urnti = 1;
371         ch->vpi = atm->vpi;
372         ch->vci = atm->vci;
373         ch->cid = atm->aal2_cid;
374         ch->link = pinfo->link_number;
375     }
376     ch->rbid = rlcinf->rbid[fpinf->cur_tb];
377     ch->dir = pinfo->p2p_dir;
378     ch->mode = mode;
379     ch->li_size = rlcinf->li_size[fpinf->cur_tb];
380
381     return 0;
382 }
383
384 static struct rlc_channel *
385 rlc_channel_create(enum rlc_mode mode, packet_info *pinfo)
386 {
387     struct rlc_channel *ch;
388     int rv;
389
390     ch = (struct rlc_channel *)g_malloc0(sizeof(struct rlc_channel));
391     rv = rlc_channel_assign(ch, mode, pinfo);
392
393     if (rv != 0) {
394         /* channel assignment failed */
395         g_free(ch);
396         ch = NULL;
397         REPORT_DISSECTOR_BUG("Failed to assign channel");
398     }
399     return ch;
400 }
401
402 static void
403 rlc_channel_delete(gpointer data)
404 {
405     g_free(data);
406 }
407
408 /* hashtable functions for reassembled table
409  * fragment -> SDU
410  */
411 static guint
412 rlc_frag_hash(gconstpointer key)
413 {
414     const struct rlc_frag *frag = (const struct rlc_frag *)key;
415     return (frag->frame_num << 12) | frag->seq;
416 }
417
418 static gboolean
419 rlc_frag_equal(gconstpointer a, gconstpointer b)
420 {
421     const struct rlc_frag *x = (const struct rlc_frag *)a;
422     const struct rlc_frag *y = (const struct rlc_frag *)b;
423
424     return rlc_channel_equal(&x->ch, &y->ch) &&
425         x->seq == y->seq &&
426         x->frame_num == y->frame_num &&
427         x->li == y->li ? TRUE : FALSE;
428 }
429
430 static struct rlc_sdu *
431 rlc_sdu_create(void)
432 {
433     struct rlc_sdu *sdu;
434
435     sdu = (struct rlc_sdu *)wmem_alloc0(wmem_file_scope(), sizeof(struct rlc_sdu));
436     return sdu;
437 }
438
439 static void
440 rlc_frag_delete(gpointer data)
441 {
442     struct rlc_frag *frag = (struct rlc_frag *)data;
443
444     if (frag->data) {
445         g_free(frag->data);
446         frag->data = NULL;
447     }
448 }
449
450 static void
451 rlc_sdu_frags_delete(gpointer data)
452 {
453     struct rlc_sdu  *sdu = (struct rlc_sdu *)data;
454     struct rlc_frag *frag;
455
456     frag = sdu->frags;
457     while (frag) {
458         if (frag->data) {
459             g_free(frag->data);
460         }
461         frag->data = NULL;
462         frag = frag->next;
463     }
464 }
465
466 static int
467 rlc_frag_assign(struct rlc_frag *frag, enum rlc_mode mode, packet_info *pinfo,
468         guint16 seq, guint16 li)
469 {
470     frag->frame_num = pinfo->fd->num;
471     frag->seq       = seq;
472     frag->li        = li;
473     frag->len       = 0;
474     frag->data      = NULL;
475     rlc_channel_assign(&frag->ch, mode, pinfo);
476
477     return 0;
478 }
479
480 static int
481 rlc_frag_assign_data(struct rlc_frag *frag, tvbuff_t *tvb,
482              guint16 offset, guint16 length)
483 {
484     frag->len  = length;
485     frag->data = (guint8 *)g_malloc(length);
486     tvb_memcpy(tvb, frag->data, offset, length);
487     return 0;
488 }
489
490 static struct rlc_frag *
491 rlc_frag_create(tvbuff_t *tvb, enum rlc_mode mode, packet_info *pinfo,
492         guint16 offset, guint16 length, guint16 seq, guint16 li)
493 {
494     struct rlc_frag *frag;
495
496     frag = (struct rlc_frag *)wmem_alloc0(wmem_file_scope(), sizeof(struct rlc_frag));
497     rlc_frag_assign(frag, mode, pinfo, seq, li);
498     rlc_frag_assign_data(frag, tvb, offset, length);
499
500     return frag;
501 }
502
503 static int
504 rlc_cmp_seq(gconstpointer a, gconstpointer b)
505 {
506     const struct rlc_seq *_a = (const struct rlc_seq *)a, *_b = (const struct rlc_seq *)b;
507
508     return  _a->seq < _b->seq ? -1 :
509             _a->seq > _b->seq ?  1 :
510             0;
511 }
512
513 static int moduloCompare(guint16 a, guint16 b, guint16 modulus)
514 {
515     int ret;
516     a = a % modulus;
517     b = b % modulus;
518
519     if( a <= b ){
520         ret = a - b;
521     } else {
522         ret = a - (b + modulus);
523     }
524     if( ret == (1 - modulus) ){
525         ret = 1;
526     }
527     return ret;
528 }
529
530 static guint16 getChannelSNModulus(struct rlc_channel * ch_lookup)
531 {
532     if( RLC_UM == ch_lookup->mode){ /*FIXME: This is a very heuristic way to detemine SN bitwidth. */
533         return 128;
534     } else {
535         return 4096;
536     }
537 }
538
539 /* "Value destroy" function called each time an entry is removed
540  *  from the sequence_table hash.
541  * It frees the GList pointed to by the entry.
542  */
543 static void
544 free_sequence_table_entry_data(gpointer data)
545 {
546     struct rlc_seqlist *list = (struct rlc_seqlist *)data;
547     if (list->list != NULL) {
548         g_list_free(list->list);
549         list->list = NULL;   /* for good measure */
550     }
551 }
552
553 /** Utility functions used for various comparions/cleanups in tree **/
554 static gint
555 rlc_simple_key_cmp(gconstpointer b_ptr, gconstpointer a_ptr, gpointer ignore _U_){
556     if( GPOINTER_TO_INT(a_ptr) > GPOINTER_TO_INT(b_ptr) ){
557         return  -1;
558     }
559     return GPOINTER_TO_INT(a_ptr) < GPOINTER_TO_INT(b_ptr);
560 }
561
562 static void
563 fragment_table_init(void)
564 {
565     int i;
566     if (fragment_table) {
567         g_hash_table_destroy(fragment_table);
568     }
569     if (endpoints) {
570         g_hash_table_destroy(endpoints);
571     }
572     if (reassembled_table) {
573         g_hash_table_destroy(reassembled_table);
574     }
575     if (sequence_table) {
576         g_hash_table_destroy(sequence_table);
577     }
578     if (duplicate_table) {
579         g_hash_table_destroy(duplicate_table);
580     }
581     if(counter_map){
582         g_tree_destroy(counter_map);
583     }
584     fragment_table = g_hash_table_new_full(rlc_channel_hash, rlc_channel_equal, rlc_channel_delete, NULL);
585     endpoints = g_hash_table_new_full(rlc_channel_hash, rlc_channel_equal, rlc_channel_delete, NULL);
586     reassembled_table = g_hash_table_new_full(rlc_frag_hash, rlc_frag_equal,
587         rlc_frag_delete, rlc_sdu_frags_delete);
588     sequence_table = g_hash_table_new_full(rlc_channel_hash, rlc_channel_equal,
589         NULL, free_sequence_table_entry_data);
590     duplicate_table = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL);
591
592     /*Reset and or clear deciphering variables*/
593     counter_map = g_tree_new_full(rlc_simple_key_cmp,NULL,NULL,rlc_channel_delete);
594     for(i = 0; i< 31; i++ ){
595         ps_counter[i][0] = 0;
596         ps_counter[i][1] = 0;
597         counter_init[i][0] = 0;
598         counter_init[i][1] = 0;
599     }
600     max_counter = 0;
601 }
602
603 /* add the list of fragments for this sdu to 'tree' */
604 static void
605 tree_add_fragment_list(struct rlc_sdu *sdu, tvbuff_t *tvb, proto_tree *tree)
606 {
607     proto_item      *ti;
608     proto_tree      *frag_tree;
609     guint16          offset;
610     struct rlc_frag *sdufrag;
611
612     ti = proto_tree_add_item(tree, hf_rlc_frags, tvb, 0, -1, ENC_NA);
613     frag_tree = proto_item_add_subtree(ti, ett_rlc_fragments);
614     proto_item_append_text(ti, " (%u bytes, %u fragments): ",
615         sdu->len, sdu->fragcnt);
616     sdufrag = sdu->frags;
617     offset = 0;
618     while (sdufrag) {
619         if (sdufrag->len > 0) {
620             proto_tree_add_uint_format(frag_tree, hf_rlc_frag, tvb, offset,
621                 sdufrag->len, sdufrag->frame_num, "Frame: %u, payload: %u-%u (%u bytes) (Seq: %u)",
622                 sdufrag->frame_num, offset, offset + sdufrag->len - 1, sdufrag->len, sdufrag->seq);
623         } else {
624             proto_tree_add_uint_format(frag_tree, hf_rlc_frag, tvb, offset,
625                 sdufrag->len, sdufrag->frame_num, "Frame: %u, payload: none (0 bytes) (Seq: %u)",
626                 sdufrag->frame_num, sdufrag->seq);
627         }
628         offset += sdufrag->len;
629         sdufrag = sdufrag->next;
630     }
631 }
632
633 /* add the list of fragments for this sdu to 'tree' */
634 static void
635 tree_add_fragment_list_incomplete(struct rlc_sdu *sdu, tvbuff_t *tvb, proto_tree *tree)
636 {
637     proto_item      *ti;
638     proto_tree      *frag_tree;
639     guint16          offset;
640     struct rlc_frag *sdufrag;
641
642     ti = proto_tree_add_item(tree, hf_rlc_frags, tvb, 0, 0, ENC_NA);
643     frag_tree = proto_item_add_subtree(ti, ett_rlc_fragments);
644     proto_item_append_text(ti, " (%u bytes, %u fragments): ",
645         sdu->len, sdu->fragcnt);
646     sdufrag = sdu->frags;
647     offset = 0;
648     while (sdufrag) {
649         proto_tree_add_uint_format(frag_tree, hf_rlc_frag, tvb, 0,
650             0, sdufrag->frame_num, "Frame: %u, payload %u-%u (%u bytes) (Seq: %u)",
651             sdufrag->frame_num, offset, offset + sdufrag->len - 1, sdufrag->len, sdufrag->seq);
652         offset += sdufrag->len;
653         sdufrag = sdufrag->next;
654     }
655 }
656
657 /* Add the same description to too the two given proto_items */
658 static void
659 add_description(proto_item *li_ti, proto_item *length_ti,
660                 const char *format, ...)
661 {
662 #define MAX_INFO_BUFFER 256
663     static char info_buffer[MAX_INFO_BUFFER];
664
665     va_list ap;
666
667     va_start(ap, format);
668     g_vsnprintf(info_buffer, MAX_INFO_BUFFER, format, ap);
669     va_end(ap);
670
671     proto_item_append_text(li_ti, " (%s)", info_buffer);
672     proto_item_append_text(length_ti, " (%s)", info_buffer);
673 }
674
675 /* add information for an LI to 'tree' */
676 static proto_tree *
677 tree_add_li(enum rlc_mode mode, struct rlc_li *li, guint8 li_idx, guint8 hdr_offs,
678         gboolean li_is_on_2_bytes, tvbuff_t *tvb, proto_tree *tree)
679 {
680     proto_item *root_ti, *ti;
681     proto_tree *li_tree;
682     guint8      li_offs;
683     guint64     length;
684
685     if (!tree) return NULL;
686
687     if (li_is_on_2_bytes) {
688         li_offs = hdr_offs + li_idx*2;
689         root_ti = proto_tree_add_item(tree, hf_rlc_li, tvb, li_offs, 2, ENC_NA);
690         li_tree = proto_item_add_subtree(root_ti, ett_rlc_frag);
691         ti = proto_tree_add_bits_ret_val(li_tree, hf_rlc_li_value, tvb, li_offs*8, 15, &length, ENC_BIG_ENDIAN);
692
693         switch (li->li) {
694             case 0x0000:
695                 add_description(root_ti, ti, "The previous RLC PDU was exactly filled with the last segment of an RLC SDU and there is no LI that indicates the end of the RLC SDU in the previous RLC PDU");
696                 break;
697             case 0x7ffa:
698                 if (mode == RLC_UM) {
699                     add_description(root_ti, ti, "The first data octet in this RLC PDU is the first octet of an RLC SDU and the second last octet in this RLC PDU is the last octet of the same RLC SDU. The remaining octet in the RLC PDU is ignored");
700                 } else {
701                     add_description(root_ti, ti, "Reserved");
702                 }
703                 break;
704             case 0x7ffb:
705                 add_description(root_ti, ti, "The second last octet in the previous RLC PDU is the last octet of an RLC SDU and there is no LI to indicate the end of SDU. The remaining octet in the previous RLC PDU is ignored");
706                 break;
707             case 0x7ffc:
708                 if (mode == RLC_UM) {
709                     add_description(root_ti, ti, "The first data octet in this RLC PDU is the first octet of an RLC SDU");
710                 } else {
711                     add_description(root_ti, ti, "Reserved");
712                 }
713                 break;
714             case 0x7ffd:
715                 if (mode == RLC_UM) {
716                     add_description(root_ti, ti, "The first data octet in this RLC PDU is the first octet of an RLC SDU and the last octet in this RLC PDU is the last octet of the same RLC SDU");
717                 } else {
718                     add_description(root_ti, ti, "Reserved");
719                 }
720                 break;
721             case 0x7ffe:
722                 if (mode == RLC_UM) {
723                     add_description(root_ti, ti, "The RLC PDU contains a segment of an SDU but neither the first octet nor the last octet of this SDU");
724                 } else {
725                     add_description(root_ti, ti, "The rest of the RLC PDU includes a piggybacked STATUS PDU");
726                 }
727                 break;
728             case 0x7fff:
729                 add_description(root_ti, ti, "The rest of the RLC PDU is padding");
730                 break;
731
732             default:
733                 add_description(root_ti, ti, "length=%u", (guint16)length);
734                 break;
735         }
736         proto_tree_add_bits_item(li_tree, hf_rlc_li_ext, tvb, li_offs*8+15, 1, ENC_BIG_ENDIAN);
737     } else {
738         li_offs = hdr_offs + li_idx;
739         root_ti = proto_tree_add_item(tree, hf_rlc_li, tvb, li_offs, 1, ENC_NA);
740         li_tree = proto_item_add_subtree(root_ti, ett_rlc_frag);
741         ti = proto_tree_add_bits_ret_val(li_tree, hf_rlc_li_value, tvb, li_offs*8, 7, &length, ENC_BIG_ENDIAN);
742         switch (li->li) {
743             case 0x00:
744                 add_description(root_ti, ti, "The previous RLC PDU was exactly filled with the last segment of an RLC SDU and there is no LI that indicates the end of the RLC SDU in the previous RLC PDU");
745                 break;
746             case 0x7c:
747                 if (mode == RLC_UM) {
748                     add_description(root_ti, ti, "The first data octet in this RLC PDU is the first octet of an RLC SDU");
749                 } else {
750                     add_description(root_ti, ti, "Reserved");
751                 }
752                 break;
753             case 0x7d:
754                 if (mode == RLC_UM) {
755                     add_description(root_ti, ti, "The first data octet in this RLC PDU is the first octet of an RLC SDU and the last octet in this RLC PDU is the last octet of the same RLC SDU");
756                 } else {
757                     add_description(root_ti, ti, "Reserved");
758                 }
759                 break;
760             case 0x7e:
761                 if (mode == RLC_UM) {
762                     add_description(root_ti, ti, "The RLC PDU contains a segment of an SDU but neither the first octet nor the last octet of this SDU");
763                 } else {
764                     add_description(root_ti, ti, "The rest of the RLC PDU includes a piggybacked STATUS PDU");
765                 }
766                 break;
767             case 0x7f:
768                 add_description(root_ti, ti, "The rest of the RLC PDU is padding");
769                 break;
770
771             default:
772                 add_description(root_ti, ti, "length=%u", (guint16)length);
773                 break;
774         }
775         proto_tree_add_bits_item(li_tree, hf_rlc_li_ext, tvb, li_offs*8+7, 1, ENC_BIG_ENDIAN);
776     }
777
778     if (li->len > 0) {
779         if (li->li > tvb_length_remaining(tvb, hdr_offs)) return li_tree;
780         if (li->len > li->li) return li_tree;
781         ti = proto_tree_add_item(li_tree, hf_rlc_li_data, tvb, hdr_offs + li->li - li->len, li->len, ENC_NA);
782         PROTO_ITEM_SET_HIDDEN(ti);
783     }
784
785     return li_tree;
786 }
787
788 /* add a fragment to an SDU */
789 static int
790 rlc_sdu_add_fragment(enum rlc_mode mode, struct rlc_sdu *sdu, struct rlc_frag *frag)
791 {
792     struct rlc_frag *tmp;
793
794     if (!sdu->frags) {
795         /* insert as first element */
796         sdu->frags = frag;
797         sdu->last = frag;
798         sdu->fragcnt++;
799         sdu->len += frag->len;
800         return 0;
801     }
802     switch (mode) {
803         case RLC_UM:
804             /* insert as last element */
805             sdu->last->next = frag;
806             frag->next = NULL;
807             sdu->last = frag;
808             sdu->len += frag->len;
809             break;
810         case RLC_AM:
811             /* insert ordered */
812             tmp = sdu->frags;
813
814             /* If receiving exotic border line sequence, e.g. 4094, 4095, 0, 1 */
815             if (frag->seq+2048 < tmp->seq) {
816                 while (tmp->next && frag->seq+2048 < tmp->seq)
817                     tmp = tmp->next;
818                 if (tmp->next == NULL) {
819                     tmp->next = frag;
820                     sdu->last = frag;
821                 } else {
822                     while (tmp->next && tmp->next->seq < frag->seq)
823                         tmp = tmp->next;
824                     frag->next = tmp->next;
825                     tmp->next = frag;
826                     if (frag->next == NULL) sdu->last = frag;
827                 }
828             } else { /* Receiving ordinary sequence */
829                 if (frag->seq < tmp->seq) {
830                     /* insert as first element */
831                     frag->next = tmp;
832                     sdu->frags = frag;
833                 } else {
834                     while (tmp->next && tmp->next->seq < frag->seq)
835                         tmp = tmp->next;
836                     frag->next = tmp->next;
837                     tmp->next = frag;
838                     if (frag->next == NULL) sdu->last = frag;
839                 }
840             }
841             sdu->len += frag->len;
842             break;
843         default:
844             return -2;
845     }
846     sdu->fragcnt++;
847     return 0;
848 }
849
850 static void
851 reassemble_data(struct rlc_channel *ch, struct rlc_sdu *sdu, struct rlc_frag *frag)
852 {
853     struct rlc_frag *temp;
854     guint16          offs = 0;
855
856     if (!sdu || !ch || !sdu->frags) return;
857
858     if (sdu->data) return; /* already assembled */
859
860     if (frag)
861         sdu->reassembled_in = frag;
862     else
863         sdu->reassembled_in = sdu->last;
864
865     sdu->data = (guint8 *)wmem_alloc(wmem_file_scope(), sdu->len);
866     temp = sdu->frags;
867     while (temp && ((offs + temp->len) <= sdu->len)) {
868         memcpy(sdu->data + offs, temp->data, temp->len);
869         g_free(temp->data);
870         temp->data = NULL;
871         /* mark this fragment in reassembled table */
872         g_hash_table_insert(reassembled_table, temp, sdu);
873
874         offs += temp->len;
875         temp = temp->next;
876     }
877 }
878
879 #define RLC_ADD_FRAGMENT_FAIL_PRINT 0
880 #define RLC_ADD_FRAGMENT_DEBUG_PRINT 0
881 #if RLC_ADD_FRAGMENT_DEBUG_PRINT
882 static void
883 printends(GList * list)
884 {
885     if (list == NULL)
886         return;
887     g_print("-> length: %d\n[", g_list_length(list));
888     while (list)
889     {
890         g_print("%d ", GPOINTER_TO_INT(list->data));
891         list = list->next;
892     }
893     g_print("]\n");
894 }
895 #endif
896
897 static struct rlc_frag **
898 get_frags(packet_info * pinfo, struct rlc_channel * ch_lookup)
899 {
900     gpointer value = NULL;
901     struct rlc_frag ** frags = NULL;
902     /* Look for already created frags table */
903     if (g_hash_table_lookup_extended(fragment_table, ch_lookup, NULL, &value)) {
904         frags = (struct rlc_frag **)value;
905     } else if (pinfo != NULL) {
906         struct rlc_channel *ch;
907         ch = rlc_channel_create(ch_lookup->mode, pinfo);
908         frags = (struct rlc_frag **)wmem_alloc0(wmem_file_scope(), sizeof(struct rlc_frag *) * 4096);
909         g_hash_table_insert(fragment_table, ch, frags);
910     } else {
911         return NULL;
912     }
913     return frags;
914 }
915 static struct rlc_seqlist *
916 get_endlist(packet_info * pinfo, struct rlc_channel * ch_lookup)
917 {
918     gpointer value = NULL;
919     struct rlc_seqlist * endlist = NULL;
920     /* If there already exists a frag table for this channel use that one. */
921     if (g_hash_table_lookup_extended(endpoints, ch_lookup, NULL, &value)) {
922         endlist = (struct rlc_seqlist *)value;
923     } else if (pinfo != NULL) { /* Else create a new one. */
924         struct rlc_channel * ch;
925
926         endlist = wmem_new(wmem_file_scope(), struct rlc_seqlist);
927         ch = rlc_channel_create(ch_lookup->mode, pinfo);
928         endlist->fail_packet = 0;
929         endlist->list = NULL;
930         endlist->list = g_list_prepend(endlist->list, GINT_TO_POINTER(-1));
931         g_hash_table_insert(endpoints, ch, endlist);
932     } else {
933         return NULL;
934     }
935     return endlist;
936 }
937
938 static void
939 reassemble_sequence(struct rlc_frag ** frags, struct rlc_seqlist * endlist,
940                     struct rlc_channel * ch_lookup, guint16 start, guint16 end)
941 {
942     GList * element = NULL;
943     struct rlc_sdu * sdu = rlc_sdu_create();
944
945     guint16 snmod = getChannelSNModulus(ch_lookup);
946
947     /* Insert fragments into SDU. */
948     for (; moduloCompare(start,end,snmod ) <= 0; start = (start+1)%snmod)
949     {
950         struct rlc_frag * tempfrag = NULL;
951         tempfrag = frags[start]->next;
952         frags[start]->next = NULL;
953         rlc_sdu_add_fragment(ch_lookup->mode, sdu, frags[start]);
954         frags[start] = tempfrag;
955     }
956
957     /* Remove first endpoint. */
958     element = g_list_first(endlist->list);
959     if (element) {
960         endlist->list = g_list_remove_link(endlist->list, element);
961         if (frags[end] != NULL) {
962             if (endlist->list) {
963                 endlist->list->data = GINT_TO_POINTER((GPOINTER_TO_INT(endlist->list->data) - 1 + snmod) % snmod);
964             }
965         }
966     }
967     reassemble_data(ch_lookup, sdu, NULL);
968 }
969
970 /* Reset the specified channel's reassembly data, useful for when a sequence
971  * resets on transport channel swap. */
972 void
973 rlc_reset_channel(enum rlc_mode mode, guint8 rbid, guint8 dir, guint32 urnti)
974 {
975     struct rlc_frag ** frags = NULL;
976     struct rlc_seqlist * endlist = NULL;
977     struct rlc_channel ch_lookup;
978     guint i;
979
980     ch_lookup.mode = mode;
981     ch_lookup.rbid = rbid;
982     ch_lookup.dir = dir;
983     ch_lookup.urnti = urnti;
984     frags = get_frags(NULL, &ch_lookup);
985     endlist = get_endlist(NULL, &ch_lookup);
986     DISSECTOR_ASSERT(frags && endlist);
987
988     endlist->fail_packet = 0;
989     g_list_free(endlist->list);
990     endlist->list = NULL;
991
992     for (i = 0; i < 4096; i++) {
993         frags[i] = NULL;
994     }
995 }
996
997 /* add a new fragment to an SDU
998  * if length == 0, just finalize the specified SDU
999  */
1000 static struct rlc_frag *
1001 add_fragment(enum rlc_mode mode, tvbuff_t *tvb, packet_info *pinfo,
1002          proto_tree *tree, guint16 offset, guint16 seq, guint16 num_li,
1003          guint16 len, gboolean final)
1004 {
1005     struct rlc_channel  ch_lookup;
1006     struct rlc_frag     frag_lookup, *frag = NULL;
1007     gpointer            orig_key = NULL, value = NULL;
1008     struct rlc_sdu     *sdu = NULL;
1009     struct rlc_frag ** frags = NULL;
1010     struct rlc_seqlist * endlist = NULL;
1011     GList * element = NULL;
1012     int snmod;
1013
1014     if (rlc_channel_assign(&ch_lookup, mode, pinfo) == -1) {
1015         return NULL;
1016     }
1017     rlc_frag_assign(&frag_lookup, mode, pinfo, seq, num_li);
1018     #if RLC_ADD_FRAGMENT_DEBUG_PRINT
1019         g_print("packet: %d, channel (%d %d %d) seq: %u, num_li: %u, offset: %u, \n", pinfo->fd->num, ch_lookup.dir, ch_lookup.rbid, ch_lookup.urnti, seq, num_li, offset);
1020     #endif
1021
1022     snmod = getChannelSNModulus(&ch_lookup);
1023
1024     /* look for an already assembled SDU */
1025     if (g_hash_table_lookup_extended(reassembled_table, &frag_lookup, &orig_key, &value)) {
1026         /* this fragment is already reassembled somewhere */
1027         frag = (struct rlc_frag *)orig_key;
1028         sdu = (struct rlc_sdu *)value;
1029         if (tree) {
1030             /* mark the fragment, if reassembly happened somewhere else */
1031             if (frag->seq != sdu->reassembled_in->seq ||
1032                 frag->li != sdu->reassembled_in->li)
1033                 proto_tree_add_uint(tree, hf_rlc_reassembled_in, tvb, 0, 0,
1034                     sdu->reassembled_in->frame_num);
1035         }
1036         return frag;
1037     }
1038
1039     frags = get_frags(pinfo, &ch_lookup);
1040     endlist = get_endlist(pinfo, &ch_lookup);
1041
1042     /* If already done reassembly */
1043     if (pinfo->fd->flags.visited) {
1044         if (tree && len > 0) {
1045             if (endlist->list && endlist->list->next) {
1046                 gint16 start = (GPOINTER_TO_INT(endlist->list->data) + 1) % snmod;
1047                 gint16 end = GPOINTER_TO_INT(endlist->list->next->data);
1048                 gint16 missing = start;
1049                 gboolean wecanreasmmore = TRUE;
1050
1051                 for (; moduloCompare(missing,end,snmod ) <= 0; missing = (missing+1)%snmod)
1052                 {
1053                     if (frags[missing] == NULL) {
1054                         wecanreasmmore = FALSE;
1055                         break;
1056                     }
1057                 }
1058
1059                 if (wecanreasmmore) {
1060                     reassemble_sequence(frags, endlist, &ch_lookup, start, end);
1061                 } else {
1062                     if (end >= 0 && end < snmod && frags[end]) {
1063                         proto_tree_add_expert_format(tree, pinfo, &ei_rlc_reassembly_fail_unfinished_sequence, tvb, 0, 0,
1064                                         "Did not perform reassembly because of unfinished sequence (%d->%d [packet %u]), could not find %d.", start, end, frags[end]->frame_num, missing);
1065                     } else {
1066                         proto_tree_add_expert_format(tree, pinfo, &ei_rlc_reassembly_fail_unfinished_sequence, tvb, 0, 0,
1067                                         "Did not perform reassembly because of unfinished sequence (%d->%d [could not determine packet]), could not find %d.", start, end, missing);
1068                     }
1069                 }
1070             } else if (endlist->list) {
1071                 if (endlist->fail_packet != 0 && endlist->fail_packet <= pinfo->fd->num) {
1072                     proto_tree_add_expert_format(tree, pinfo, &ei_rlc_reassembly_fail_flag_set, tvb, 0, 0, "Did not perform reassembly because fail flag was set in packet %u.", endlist->fail_packet);
1073                 } else {
1074                     gint16 end = GPOINTER_TO_INT(endlist->list->data);
1075                     if (end >= 0 && end < snmod && frags[end]) {
1076                         proto_tree_add_expert_format(tree, pinfo, &ei_rlc_reassembly_lingering_endpoint, tvb, 0, 0, "Did not perform reassembly because of unfinished sequence, found lingering endpoint (%d [packet %d]).", end, frags[end]->frame_num);
1077                     } else {
1078                         proto_tree_add_expert_format(tree, pinfo, &ei_rlc_reassembly_lingering_endpoint, tvb, 0, 0, "Did not perform reassembly because of unfinished sequence, found lingering endpoint (%d [could not determine packet]).", end);
1079                     }
1080                 }
1081             } else {
1082                 expert_add_info(pinfo, NULL, &ei_rlc_reassembly_unknown_error);
1083             }
1084         }
1085         return NULL; /* If already done reassembly and no SDU found, too bad */
1086     }
1087
1088     if (endlist->fail_packet != 0) { /* don't continue after sh*t has hit the fan */
1089         return NULL;
1090     }
1091
1092     frag = rlc_frag_create(tvb, mode, pinfo, offset, len, seq, num_li);
1093
1094     /* If frags[seq] is not NULL then we must have data from several PDUs in the
1095      * same RLC packet (using Length Indicators) or something has gone terribly
1096      * wrong. */
1097     if (frags[seq] != NULL) {
1098         if (num_li > 0) {
1099             struct rlc_frag * tempfrag = frags[seq];
1100             while (tempfrag->next != NULL)
1101                 tempfrag = tempfrag->next;
1102             tempfrag->next = frag;
1103         } else { /* This should never happen */
1104             endlist->fail_packet = pinfo->fd->num;
1105             return NULL;
1106         }
1107     } else {
1108         frags[seq] = frag;
1109     }
1110
1111     /* It is also possible that frags[seq] is NULL even though we do have data
1112      * from several PDUs in the same RLC packet. This is if the reassembly is
1113      * not lagging behind at all because of perfectly ordered sequences. */
1114     if (endlist->list && num_li != 0) {
1115         gint16 first = GPOINTER_TO_INT(endlist->list->data);
1116         if (seq == first) {
1117             endlist->list->data = GINT_TO_POINTER(first-1);
1118         }
1119     }
1120
1121     /* If this is an endpoint */
1122     if (final) {
1123         endlist->list = g_list_append(endlist->list, GINT_TO_POINTER((gint)seq));
1124     }
1125
1126     #if RLC_ADD_FRAGMENT_DEBUG_PRINT
1127     printends(endlist->list);
1128     #endif
1129
1130     /* Try to reassemble SDU. */
1131     if (endlist->list && endlist->list->next) {
1132         gint16 start = (GPOINTER_TO_INT(endlist->list->data) + 1) % snmod;
1133         gint16 end = GPOINTER_TO_INT(endlist->list->next->data);
1134         if (frags[end] == NULL) {
1135 #if RLC_ADD_FRAGMENT_FAIL_PRINT
1136             g_warning("frag[end] is null, this is probably because end was a startpoint but because of some error ended up being treated as an endpoint, setting fail flag, start %d, end %d, packet %u\n", start, end, pinfo->fd->num);
1137 #endif
1138             endlist->fail_packet = pinfo->fd->num;
1139             return NULL;
1140         }
1141
1142         /* If our endpoint is a LI=0 with no data. */
1143         if (start == end && frags[start]->len == 0) {
1144             element = g_list_first(endlist->list);
1145             if (element) {
1146                 endlist->list = g_list_remove_link(endlist->list, element);
1147             }
1148             frags[start] = frags[start]->next;
1149
1150             /* If frags[start] is not NULL now, then that means that there was
1151              * another fragment with the same seq number because of LI. If we
1152              * don't decrease the endpoint by 1 then that fragment will be
1153              * skipped and all hell will break lose. */
1154             if (frags[start] != NULL) {
1155                 endlist->list->data = GINT_TO_POINTER(start-1);
1156             }
1157             /* NOTE: frags[start] is wmem_alloced and will remain until file closes, we would want to free it here maybe. */
1158             return NULL;
1159         }
1160
1161         #if RLC_ADD_FRAGMENT_DEBUG_PRINT
1162         g_print("start: %d, end: %d\n",start, end);
1163         #endif
1164
1165         for (;  moduloCompare(start,end,snmod ) < 0; start = (start+1)%snmod)
1166         {
1167             if (frags[start] == NULL) {
1168                 if (MIN((start-seq+snmod)%snmod, (seq-start+snmod)%snmod) >= snmod/4) {
1169 #if RLC_ADD_FRAGMENT_FAIL_PRINT
1170                     g_warning(
1171 "Packet %u. Setting fail flag because RLC fragment with sequence number %u was \
1172 too far away from an unfinished sequence (%u->%u). The missing sequence number \
1173 is %u. The most recently complete sequence ended in packet %u.", pinfo->fd->num, seq, 0, end, start, 0);
1174 #endif
1175                     endlist->fail_packet = pinfo->fd->num; /* If it has gone too far, give up */
1176                     return NULL;
1177                 }
1178                 return frag;
1179             }
1180         }
1181         start = (GPOINTER_TO_INT(endlist->list->data) + 1) % snmod;
1182         reassemble_sequence(frags, endlist, &ch_lookup, start, end);
1183     } else if (endlist->list) {
1184         gint16 first = (GPOINTER_TO_INT(endlist->list->data) + 1) % snmod;
1185         /* If the distance between the oldest stored endpoint in endlist and
1186          * this endpoint is too large, set fail flag. */
1187         if (MIN((first-seq+snmod)%snmod, (seq-first+snmod)%snmod) >= snmod/4) {
1188 #if RLC_ADD_FRAGMENT_FAIL_PRINT
1189             g_warning(
1190 "Packet %u. Setting fail flag because RLC fragment with sequence number %u was \
1191 too far away from an unfinished sequence with start %u and without end.", pinfo->fd->num, seq, first);
1192 #endif
1193             endlist->fail_packet = pinfo->fd->num; /* Give up if things have gone too far. */
1194             return NULL;
1195         }
1196     }
1197
1198     return frag;
1199 }
1200
1201 /* is_data is used to identify rlc data parts that are not identified by an LI, but are at the end of
1202  * the RLC frame
1203  * these can be valid reassembly points, but only if the LI of the *next* relevant RLC frame is
1204  * set to '0' (this is indicated in the reassembled SDU
1205  */
1206 static tvbuff_t *
1207 get_reassembled_data(enum rlc_mode mode, tvbuff_t *tvb, packet_info *pinfo,
1208              proto_tree *tree, guint16 seq, guint16 num_li)
1209 {
1210     gpointer         orig_frag, orig_sdu;
1211     struct rlc_sdu  *sdu;
1212     struct rlc_frag  lookup, *frag;
1213
1214     rlc_frag_assign(&lookup, mode, pinfo, seq, num_li);
1215
1216     if (!g_hash_table_lookup_extended(reassembled_table, &lookup,
1217         &orig_frag, &orig_sdu))
1218         return NULL;
1219
1220     sdu = (struct rlc_sdu *)orig_sdu;
1221     if (!sdu || !sdu->data)
1222         return NULL;
1223
1224     /* TODO */
1225 #if 0
1226     if (!rlc_frag_equal(&lookup, sdu->reassembled_in)) return NULL;
1227 #endif
1228
1229     if (tree) {
1230         frag = sdu->frags;
1231         while (frag->next) {
1232             if (frag->next->seq - frag->seq > 1) {
1233                 proto_item *pi = proto_tree_add_text(tree, tvb, 0, 0,
1234                     "Error: Incomplete sequence");
1235                 PROTO_ITEM_SET_GENERATED(pi);
1236                 tree_add_fragment_list_incomplete(sdu, tvb, tree);
1237                 return NULL;
1238             }
1239             frag = frag->next;
1240         }
1241     }
1242     sdu->tvb = tvb_new_child_real_data(tvb, sdu->data, sdu->len, sdu->len);
1243     add_new_data_source(pinfo, sdu->tvb, "Reassembled RLC Message");
1244
1245     /* reassembly happened here, so create the fragment list */
1246     if (tree && sdu->fragcnt > 1)
1247         tree_add_fragment_list(sdu, sdu->tvb, tree);
1248
1249     return sdu->tvb;
1250 }
1251
1252 #define RLC_RETRANSMISSION_TIMEOUT 5 /* in seconds */
1253 static gboolean
1254 rlc_is_duplicate(enum rlc_mode mode, packet_info *pinfo, guint16 seq,
1255          guint32 *original)
1256 {
1257     GList              *element;
1258     struct rlc_seqlist  lookup, *list;
1259     struct rlc_seq      seq_item, *seq_new;
1260     guint16 snmod;
1261
1262     rlc_channel_assign(&lookup.ch, mode, pinfo);
1263     list = (struct rlc_seqlist *)g_hash_table_lookup(sequence_table, &lookup.ch);
1264     if (!list) {
1265         /* we see this channel for the first time */
1266         list = (struct rlc_seqlist *)wmem_alloc0(wmem_file_scope(), sizeof(*list));
1267         rlc_channel_assign(&list->ch, mode, pinfo);
1268         g_hash_table_insert(sequence_table, &list->ch, list);
1269     }
1270     seq_item.seq = seq;
1271     seq_item.frame_num = pinfo->fd->num;
1272
1273     /* When seq is 12 bit (in RLC protocol), it will wrap around after 4096. */
1274     /* Window size is at most 4095 so we remove packets further away than that */
1275     element = g_list_first(list->list);
1276     snmod = getChannelSNModulus(&lookup.ch);
1277     if (element) {
1278         seq_new = (struct rlc_seq *)element->data;
1279         /* Add SN modulus because %-operation for negative values in C is not equal to mathematical modulus */
1280         if (MIN((seq_new->seq-seq+snmod)%snmod, (seq-seq_new->seq+snmod)%snmod) >= snmod/4) {
1281             list->list = g_list_remove_link(list->list, element);
1282         }
1283     }
1284
1285     element = g_list_find_custom(list->list, &seq_item, rlc_cmp_seq);
1286     if (element) {
1287         seq_new = (struct rlc_seq *)element->data;
1288         if (seq_new->frame_num != seq_item.frame_num) {
1289             nstime_t delta;
1290             nstime_delta(&delta, &pinfo->fd->abs_ts, &seq_new->arrival);
1291             if (delta.secs < RLC_RETRANSMISSION_TIMEOUT) {
1292                 if (original)
1293                     *original = seq_new->frame_num;
1294                 return TRUE;
1295             }
1296             return FALSE;
1297         }
1298         return FALSE; /* we revisit the seq that was already seen */
1299     }
1300     seq_new = (struct rlc_seq *)wmem_alloc0(wmem_file_scope(), sizeof(struct rlc_seq));
1301     *seq_new = seq_item;
1302     seq_new->arrival = pinfo->fd->abs_ts;
1303     list->list = g_list_append(list->list, seq_new); /* insert in order of arrival */
1304     return FALSE;
1305 }
1306
1307 static void
1308 rlc_call_subdissector(enum rlc_channel_type channel, tvbuff_t *tvb,
1309               packet_info *pinfo, proto_tree *tree)
1310 {
1311     enum rrc_message_type msgtype;
1312     switch (channel) {
1313         case RLC_UL_CCCH:
1314             msgtype = RRC_MESSAGE_TYPE_UL_CCCH;
1315             break;
1316         case RLC_DL_CCCH:
1317             msgtype = RRC_MESSAGE_TYPE_DL_CCCH;
1318             break;
1319         case RLC_DL_CTCH:
1320             msgtype = RRC_MESSAGE_TYPE_INVALID;
1321             call_dissector(bmc_handle, tvb, pinfo, tree);
1322             break;
1323         case RLC_UL_DCCH:
1324             msgtype = RRC_MESSAGE_TYPE_UL_DCCH;
1325             break;
1326         case RLC_DL_DCCH:
1327             msgtype = RRC_MESSAGE_TYPE_DL_DCCH;
1328             break;
1329         case RLC_PCCH:
1330             msgtype = RRC_MESSAGE_TYPE_PCCH;
1331             break;
1332         case RLC_BCCH:
1333             msgtype = RRC_MESSAGE_TYPE_BCCH_FACH;
1334             break;
1335         case RLC_PS_DTCH:
1336             msgtype = RRC_MESSAGE_TYPE_INVALID;
1337             /* assume transparent PDCP for now */
1338             call_dissector(ip_handle, tvb, pinfo, tree);
1339             /* once the packet has been dissected, protect it from further changes */
1340             col_set_writable(pinfo->cinfo, FALSE);
1341             break;
1342         default:
1343             return; /* stop dissecting */
1344     }
1345     if (msgtype != RRC_MESSAGE_TYPE_INVALID) {
1346         struct rrc_info *rrcinf;
1347         fp_info *fpinf;
1348         fpinf = (fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0);
1349         rrcinf = (rrc_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_rrc, 0);
1350         if (!rrcinf) {
1351             rrcinf = (rrc_info *)wmem_alloc0(wmem_file_scope(), sizeof(struct rrc_info));
1352             p_add_proto_data(wmem_file_scope(), pinfo, proto_rrc, 0, rrcinf);
1353         }
1354         rrcinf->msgtype[fpinf->cur_tb] = msgtype;
1355         call_dissector(rrc_handle, tvb, pinfo, tree);
1356         /* once the packet has been dissected, protect it from further changes */
1357         col_set_writable(pinfo->cinfo, FALSE);
1358     }
1359 }
1360
1361 static void
1362 add_channel_info(packet_info * pinfo, proto_tree * tree, fp_info * fpinf, rlc_info * rlcinf)
1363 {
1364     proto_item * item;
1365     proto_tree * channel_tree ;
1366
1367     item = proto_tree_add_item(tree, hf_rlc_channel, NULL, 0, 0, ENC_NA);
1368     channel_tree = proto_item_add_subtree(item, ett_rlc_channel);
1369     proto_item_append_text(item, " (rbid: %u, dir: %s, uid: %u)", rlcinf->rbid[fpinf->cur_tb],
1370                            val_to_str_const(pinfo->p2p_dir, rlc_dir_vals, "Unknown"), rlcinf->urnti[fpinf->cur_tb]);
1371     PROTO_ITEM_SET_GENERATED(item);
1372     item = proto_tree_add_uint(channel_tree, hf_rlc_channel_rbid, NULL, 0, 0, rlcinf->rbid[fpinf->cur_tb]);
1373     PROTO_ITEM_SET_GENERATED(item);
1374     item = proto_tree_add_uint(channel_tree, hf_rlc_channel_dir, NULL, 0, 0, pinfo->p2p_dir);
1375     PROTO_ITEM_SET_GENERATED(item);
1376     item = proto_tree_add_uint(channel_tree, hf_rlc_channel_ueid, NULL, 0, 0, rlcinf->urnti[fpinf->cur_tb]);
1377     PROTO_ITEM_SET_GENERATED(item);
1378
1379 }
1380
1381 #ifdef HAVE_UMTS_KASUMI
1382 static guint8 *
1383 translate_hex_key(gchar * char_key){
1384     int i,j;
1385     guint8 * key_in;
1386
1387     key_in = g_malloc0(sizeof(guint8)*16);
1388     j= (int)(strlen(char_key)/2)-1;
1389     /*Translate "hex-string" into a byte aligned block */
1390     for(i = (int)strlen(char_key); i> 0; i-=2 ){
1391         key_in[j] =  ( (guint8)  (strtol( &char_key[i-2], NULL, 16 ) ));
1392         char_key[i-2] = '\0';
1393         j--;
1394     }
1395     return key_in;
1396
1397 }
1398 #endif
1399
1400 /** @brief Deciphers a given tvb
1401  *
1402  * Note that the actual KASUMI implementation needs to be placed into
1403  * epan/crypt/kasumi.* by "end users" since due to patents the acutal implementation
1404  * cannot be distributed openly at the moment.
1405  *
1406  * Refer to 3GPP TS 35.201 and 3GPP TS 35.202 for further information.
1407  *
1408  *  @param tvb The ciphered data.
1409  *  @param  pinfo Packet info.
1410  *  @param counter the COUNTER value input
1411  *  @param rbid the radiobear id
1412  *  @param dir Direction of the link
1413  *  @param header_size Size of the unciphered header
1414  *  @return tvb Returns a deciphered tvb
1415  */
1416 static tvbuff_t *
1417 #ifndef HAVE_UMTS_KASUMI
1418 rlc_decipher_tvb(tvbuff_t *tvb _U_, packet_info *pinfo, guint32 counter _U_,
1419                  guint8 rbid _U_, gboolean dir _U_, guint8 header_size _U_) {
1420     /*Check if we have a KASUMI implementation*/
1421     expert_add_info(pinfo, NULL, &ei_rlc_kasumi_implementation_missing);
1422     return NULL;
1423 #else
1424 rlc_decipher_tvb(tvbuff_t *tvb, packet_info *pinfo, guint32 counter, guint8 rbid, gboolean dir, guint8 header_size) {
1425     guint i;
1426     guint8* out=NULL,*key_in = NULL;
1427     tvbuff_t *t;
1428
1429     /*Fix the key into a byte block*/
1430     /*TODO: This should be done in a preferences callback function*/
1431     out = wmem_alloc0(wmem_packet_scope(), strlen(global_rlc_kasumi_key)+1);
1432     memcpy(out,global_rlc_kasumi_key,strlen(global_rlc_kasumi_key));    /*Copy from prefrence const pointer*/
1433     key_in = translate_hex_key(out);    /*Translation*/
1434
1435     /*Location for decrypted data*/
1436     out = g_malloc( tvb_length(tvb) );
1437
1438     /*Build data input but dont send the header*/
1439     for(i = 0; i< tvb_length(tvb)-header_size; i++ ){
1440         out[i+header_size] = tvb_get_guint8(tvb, header_size+i);
1441     }
1442     /*Call KASUMI confidentiality function, note that rbid is zero indxed*/
1443     f8( key_in, counter, rbid-1, dir, &out[header_size], (tvb_length(tvb)-header_size)*8 );
1444
1445     /*Restore header in tvb*/
1446     for (i = 0; i < header_size; i++) {
1447         out[i] = tvb_get_guint8(tvb, i);
1448     }
1449
1450     /*Create new tvb.*/
1451     t = tvb_new_real_data(out,tvb_length(tvb), tvb_reported_length(tvb));
1452     /*add_new_data_source(pinfo, tvb, "Data enciphered");*/
1453     add_new_data_source(pinfo, t, "Deciphered data");
1454     return t;
1455 #endif /* HAVE_UMTS_KASUMI */
1456 }
1457
1458 /*
1459  * @param key is created with GINT_TO_POINTER
1460  * @param value is a pointer to a guint32
1461  * @param data is a pointer to a guint32
1462  */
1463 static gboolean
1464 iter_same(gpointer key, gpointer value, gpointer data) {
1465     /*If true we found the correct frame*/
1466     if ((guint32)GPOINTER_TO_INT(key) > *(guint32*)data){
1467         *((guint32*)data) = *((guint32*)value);
1468         return TRUE;
1469     }
1470     *((guint32*)data) = (guint32)GPOINTER_TO_INT(key);
1471
1472     return TRUE;
1473 }
1474
1475 /**
1476  * Used for looking up and old ciphering counter value in the counter_map tree.
1477  * @param key is created with GINT_TO_POINTER
1478  * @param value is pointer to an array of 2 guint32s
1479  * @param data is a pointer to an array of 3 guint32s
1480  */
1481 static gboolean
1482 rlc_find_old_counter(gpointer key, gpointer value, gpointer data) {
1483
1484     /*If true we found the correct frame*/
1485     if( (guint32)GPOINTER_TO_INT(key) >= ((guint32 *)data)[0] ){
1486         return TRUE;
1487     }
1488     /*Overwrite the data since the previous one wasn't correct*/
1489     ((guint32*)data)[1] = ((guint32*)value)[0];
1490     ((guint32*)data)[2] = ((guint32*)value)[1];
1491
1492     return FALSE;
1493 }
1494
1495 static void
1496 rlc_decipher(tvbuff_t *tvb, packet_info * pinfo, proto_tree * tree, fp_info * fpinf,
1497              rlc_info * rlcinf, guint16 seq, enum rlc_mode mode)
1498 {
1499     rrc_ciphering_info * c_inf;
1500     guint8 indx, header_size, hfn_shift;
1501     gint16 pos;
1502
1503     indx = fpinf->is_uplink ? 1 : 0;
1504     pos = fpinf->cur_tb;
1505     if (mode ==RLC_UM) {
1506         header_size = 1;
1507         hfn_shift = 7;
1508     } else {
1509         header_size = 2;
1510         hfn_shift = 12;
1511     }
1512
1513     /*Ciphering info singled in RRC by securitymodecommands */
1514     c_inf =  (rrc_ciphering_info *)g_tree_lookup(rrc_ciph_inf, GINT_TO_POINTER((gint)fpinf->com_context_id));
1515
1516     /*TODO: This doesnt really work for all packets..*/
1517     /*Check if we have ciphering info and that this frame is ciphered*/
1518     if(c_inf!=NULL && ( (c_inf->setup_frame > 0 && c_inf->setup_frame < pinfo->fd->num && c_inf->seq_no[rlcinf->rbid[pos]][indx] == -1)  ||
1519                      (c_inf->setup_frame < pinfo->fd->num && c_inf->seq_no[rlcinf->rbid[pos]][indx] >= 0  && c_inf->seq_no[rlcinf->rbid[pos]][indx] <= seq) )){
1520
1521         tvbuff_t *t;
1522
1523         /*Check if this counter has been initialized*/
1524         if(!counter_init[rlcinf->rbid[pos]][indx] ){
1525             guint32 frame_num = pinfo->fd->num;
1526
1527             /*Initializes counter*/
1528             counter_init[rlcinf->rbid[pos]][0] = TRUE;
1529             counter_init[rlcinf->rbid[pos]][1] = TRUE;
1530             /*Find apropriate start value*/
1531             g_tree_foreach(c_inf->start_ps, (GTraverseFunc)iter_same, &frame_num);
1532
1533             /*Set COUNTER value accordingly as specified by 6.4.8 in 3GPP TS 33.102 */
1534             if(max_counter +2 > frame_num && c_inf->seq_no[rlcinf->rbid[pos]][indx] == -1){
1535                 ps_counter[rlcinf->rbid[pos]][0] = (max_counter+2) << hfn_shift;
1536                 ps_counter[rlcinf->rbid[pos]][1] = (max_counter+2) << hfn_shift;
1537             }else{
1538                 ps_counter[rlcinf->rbid[pos]][0] = frame_num << hfn_shift;
1539                 ps_counter[rlcinf->rbid[pos]][1] = frame_num << hfn_shift;
1540             }
1541
1542             if(!tree){
1543                 /*Preserve counter value for next dissection round*/
1544                 guint32 * ciph;
1545                 ciph = (guint32 *)g_malloc(sizeof(guint32)*2);
1546                 ciph[0] = ps_counter[rlcinf->rbid[pos]][0];
1547                 ciph[1] = ps_counter[rlcinf->rbid[pos]][1];
1548                 g_tree_insert(counter_map, GINT_TO_POINTER((gint)pinfo->fd->num), ciph);
1549             }
1550
1551         }
1552         /*Update the maximal COUNTER value seen so far*/
1553         max_counter = MAX(max_counter,((ps_counter[rlcinf->rbid[pos]][indx]) | seq) >> hfn_shift);
1554
1555     /*XXX:Since RBID in umts isnt configured properly..*/
1556         if(rlcinf->rbid[pos] == 9 ){
1557             if(tree){
1558                 guint32 frame_num[3];
1559                 /*Set frame num we will be "searching" around*/
1560                 frame_num[0] = pinfo->fd->num;
1561                 /*Find the correct counter value*/
1562                 g_tree_foreach(counter_map, (GTraverseFunc)rlc_find_old_counter, &frame_num[0]);
1563                 t = rlc_decipher_tvb(tvb, pinfo, (frame_num[indx+1] | seq),16,!fpinf->is_uplink,header_size);
1564             }else{
1565                 t = rlc_decipher_tvb(tvb, pinfo, ((ps_counter[rlcinf->rbid[pos]][indx]) | seq),16,!fpinf->is_uplink,header_size);
1566             }
1567         }else{
1568             if(tree){
1569                 /*We need to find the original counter value for second dissection pass*/
1570                 guint32 frame_num[3];
1571                 frame_num[0] = pinfo->fd->num;
1572                 g_tree_foreach(counter_map, (GTraverseFunc)rlc_find_old_counter, &frame_num[0]);
1573                 t = rlc_decipher_tvb(tvb, pinfo, (frame_num[indx+1] | seq),rlcinf->rbid[pos],!fpinf->is_uplink,header_size);
1574             }else
1575                 t = rlc_decipher_tvb(tvb, pinfo, ((ps_counter[rlcinf->rbid[pos]][indx]) | seq),rlcinf->rbid[pos],!fpinf->is_uplink,header_size);
1576         }
1577
1578         /*Update the hyperframe number*/
1579         if(seq == 4095){
1580
1581             ps_counter[rlcinf->rbid[pos]][indx] += 1 << hfn_shift;
1582
1583             if(!tree){/*Preserve counter for second packet analysis run*/
1584                 guint32 * ciph;
1585                 ciph = (guint32 *)g_malloc(sizeof(guint32)*2);
1586                 ciph[0] = ps_counter[rlcinf->rbid[pos]][0];
1587                 ciph[1] = ps_counter[rlcinf->rbid[pos]][1];
1588                 g_tree_insert(counter_map, GINT_TO_POINTER((gint)pinfo->fd->num+1), ciph);
1589             }
1590         }
1591
1592         /*Unable to decipher the packet*/
1593         if(t == NULL){
1594             proto_tree_add_text(tree, tvb, 0, -1,
1595                 "Cannot dissect RLC frame because it is ciphered");
1596             col_append_str(pinfo->cinfo, COL_INFO, "[Ciphered Data]");
1597             return;
1598
1599         }else{
1600             col_append_str(pinfo->cinfo, COL_INFO, "[Deciphered Data]");
1601
1602             /*TODO: Old tvb should be freed here?*/
1603         }
1604     }
1605 }
1606
1607 static void
1608 dissect_rlc_tm(enum rlc_channel_type channel, tvbuff_t *tvb, packet_info *pinfo,
1609            proto_tree *top_level, proto_tree *tree)
1610 {
1611     fp_info       *fpinf;
1612     rlc_info      *rlcinf;
1613
1614     fpinf = (fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0);
1615     rlcinf = (rlc_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_rlc, 0);
1616
1617     if (tree) {
1618         if (fpinf && rlcinf) {
1619             /* Add "channel" information, very useful for debugging. */
1620             add_channel_info(pinfo, tree, fpinf, rlcinf);
1621         }
1622         proto_tree_add_item(tree, hf_rlc_data, tvb, 0, -1, ENC_NA);
1623     }
1624     rlc_call_subdissector(channel, tvb, pinfo, top_level);
1625 }
1626
1627
1628 static void
1629 rlc_um_reassemble(tvbuff_t *tvb, guint8 offs, packet_info *pinfo, proto_tree *tree,
1630           proto_tree *top_level, enum rlc_channel_type channel, guint16 seq,
1631           struct rlc_li *li, guint16 num_li, gboolean li_is_on_2_bytes)
1632 {
1633     guint8    i;
1634     gboolean  dissected = FALSE;
1635     gint      length;
1636     tvbuff_t *next_tvb  = NULL;
1637
1638     /* perform reassembly now */
1639     for (i = 0; i < num_li; i++) {
1640         if ((!li_is_on_2_bytes && (li[i].li == 0x7f)) || (li[i].li == 0x7fff)) {
1641             /* padding, must be last LI */
1642             if (tree) {
1643                 proto_tree_add_item(tree, hf_rlc_pad, tvb, offs, tvb_length_remaining(tvb, offs), ENC_NA);
1644             }
1645             offs += tvb_length_remaining(tvb, offs);
1646         } else if ((!li_is_on_2_bytes && (li[i].li == 0x7c)) || (li[i].li == 0x7ffc)) {
1647             /* a new SDU starts here, mark this seq as the first PDU. */
1648             struct rlc_channel  ch_lookup;
1649             struct rlc_seqlist * endlist = NULL;
1650             if( -1 != rlc_channel_assign(&ch_lookup, RLC_UM, pinfo ) ){
1651                 endlist = get_endlist(pinfo, &ch_lookup);
1652                 endlist->list->data = GINT_TO_POINTER((gint)seq);
1653                 endlist->fail_packet=0;
1654             }
1655
1656         } else if (li[i].li == 0x7ffa) {
1657             /* the first data octet in this RLC PDU is the first octet of an RLC SDU
1658                and the second last octet in this RLC PDU is the last octet of the same RLC SDU */
1659             length = tvb_length_remaining(tvb, offs);
1660             if (length > 1) {
1661                 length--;
1662                 if (tree && length) {
1663                     proto_tree_add_item(tree, hf_rlc_data, tvb, offs, length, ENC_NA);
1664                 }
1665                 if (global_rlc_perform_reassemby) {
1666                     add_fragment(RLC_UM, tvb, pinfo, li[i].tree, offs, seq, i, length, TRUE);
1667                     next_tvb = get_reassembled_data(RLC_UM, tvb, pinfo, tree, seq, i);
1668                 }
1669                 offs += length;
1670             }
1671             if (tree) {
1672                 proto_tree_add_item(tree, hf_rlc_pad, tvb, offs, 1, ENC_NA);
1673             }
1674             offs += 1;
1675         } else {
1676             if (tree && li[i].len) {
1677                 proto_tree_add_item(tree, hf_rlc_data, tvb, offs, li[i].len, ENC_NA);
1678             }
1679             if (global_rlc_perform_reassemby) {
1680                 add_fragment(RLC_UM, tvb, pinfo, li[i].tree, offs, seq, i, li[i].len, TRUE);
1681                 next_tvb = get_reassembled_data(RLC_UM, tvb, pinfo, tree, seq, i);
1682             }
1683         }
1684         if (next_tvb) {
1685             dissected = TRUE;
1686             rlc_call_subdissector(channel, next_tvb, pinfo, top_level);
1687             next_tvb = NULL;
1688         }
1689         offs += li[i].len;
1690     }
1691
1692     /* is there data left? */
1693     if (tvb_length_remaining(tvb, offs) > 0) {
1694         if (tree) {
1695             proto_tree_add_item(tree, hf_rlc_data, tvb, offs, -1, ENC_NA);
1696         }
1697         if (global_rlc_perform_reassemby) {
1698             /* add remaining data as fragment */
1699             add_fragment(RLC_UM, tvb, pinfo, tree, offs, seq, i, tvb_length_remaining(tvb, offs), FALSE);
1700             if (dissected == FALSE)
1701                 col_set_str(pinfo->cinfo, COL_INFO, "[RLC UM Fragment]");
1702         }
1703     }
1704     if (dissected == FALSE)
1705         col_append_fstr(pinfo->cinfo, COL_INFO, "[RLC UM Fragment]  SN=%u", seq);
1706     else
1707         if (channel == RLC_UNKNOWN_CH)
1708             col_append_fstr(pinfo->cinfo, COL_INFO, "[RLC UM Data]  SN=%u", seq);
1709 }
1710
1711 static gint16
1712 rlc_decode_li(enum rlc_mode mode, tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
1713           struct rlc_li *li, guint8 max_li, gboolean li_on_2_bytes)
1714 {
1715     guint8      ext, hdr_len, offs  = 0, num_li = 0, li_offs;
1716     guint16     next_bytes, prev_li = 0;
1717     proto_item *malformed;
1718     guint16     total_len;
1719
1720     switch (mode) {
1721         case RLC_AM:
1722             offs = 1;
1723             break;
1724         case RLC_UM:
1725             offs = 0;
1726             break;
1727         case RLC_TM:
1728             /* fall trough */
1729         case RLC_UNKNOWN_MODE:
1730         default:
1731             return -1;
1732     }
1733     hdr_len = offs;
1734     /* calculate header length */
1735     ext = tvb_get_guint8(tvb, hdr_len++) & 0x01;
1736     while (ext) {
1737         next_bytes = li_on_2_bytes ? tvb_get_ntohs(tvb, hdr_len) : tvb_get_guint8(tvb, hdr_len);
1738         ext = next_bytes & 0x01;
1739         hdr_len += li_on_2_bytes ? 2 : 1;
1740     }
1741     total_len = tvb_length_remaining(tvb, hdr_len);
1742
1743     /* do actual evaluation of LIs */
1744     ext = tvb_get_guint8(tvb, offs++) & 0x01;
1745     li_offs = offs;
1746     while (ext) {
1747         if (li_on_2_bytes) {
1748             next_bytes = tvb_get_ntohs(tvb, offs);
1749             offs += 2;
1750         } else {
1751             next_bytes = tvb_get_guint8(tvb, offs++);
1752         }
1753         ext = next_bytes & 0x01;
1754         li[num_li].ext = ext;
1755         li[num_li].li = next_bytes >> 1;
1756
1757         if (li_on_2_bytes) {
1758             switch (li[num_li].li) {
1759                 case 0x0000: /* previous segment was the last one */
1760                 case 0x7ffb: /* previous PDU contains last segment of SDU (minus last byte) */
1761                 case 0x7ffe: /* contains piggybacked STATUS in AM or segment in UM */
1762                 case 0x7fff: /* padding */
1763                     li[num_li].len = 0;
1764                     break;
1765                 case 0x7ffa: /* contains exactly one SDU (minus last byte), UM only */
1766                 case 0x7ffc: /* start of a new SDU, UM only */
1767                 case 0x7ffd: /* contains exactly one SDU, UM only */
1768                     if (mode == RLC_UM) {
1769                         /* valid for UM */
1770                         li[num_li].len = 0;
1771                         break;
1772                     }
1773                     /*invalid for AM */
1774                     /* add malformed LI for investigation */
1775                     malformed = tree_add_li(mode, &li[num_li], num_li, li_offs, li_on_2_bytes, tvb, tree);
1776                     expert_add_info(pinfo, malformed, &ei_rlc_li_reserved);
1777                     return -1; /* just give up on this */
1778                 default:
1779                     /* since the LI is an offset (from the end of the header), it
1780                     * may not be larger than the total remaining length and no
1781                     * LI may be smaller than its preceding one
1782                     */
1783                     if (((li[num_li].li > total_len) && !global_rlc_headers_expected)
1784                         || (li[num_li].li < prev_li)) {
1785                         /* add malformed LI for investigation */
1786                         malformed = tree_add_li(mode, &li[num_li], num_li, li_offs, li_on_2_bytes, tvb, tree);
1787                         expert_add_info(pinfo, malformed, &ei_rlc_li_incorrect_warn);
1788                         return -1; /* just give up on this */
1789                     }
1790                     li[num_li].len = li[num_li].li - prev_li;
1791                     prev_li = li[num_li].li;
1792             }
1793         } else {
1794             switch (li[num_li].li) {
1795                 case 0x00: /* previous segment was the last one */
1796                 case 0x7e: /* contains piggybacked STATUS in AM or segment in UM */
1797                 case 0x7f: /* padding */
1798                     li[num_li].len = 0;
1799                     break;
1800                 case 0x7c: /* start of a new SDU, UM only */
1801                 case 0x7d: /* contains exactly one SDU, UM only */
1802                     if (mode == RLC_UM) {
1803                         /* valid for UM */
1804                         li[num_li].len = 0;
1805                         break;
1806                     }
1807                     /*invalid for AM */
1808                     /* add malformed LI for investigation */
1809                     malformed = tree_add_li(mode, &li[num_li], num_li, li_offs, li_on_2_bytes, tvb, tree);
1810                     expert_add_info(pinfo, malformed, &ei_rlc_li_reserved);
1811                     return -1; /* just give up on this */
1812                 default:
1813                     /* since the LI is an offset (from the end of the header), it
1814                     * may not be larger than the total remaining length and no
1815                     * LI may be smaller than its preceding one
1816                     */
1817                     li[num_li].len = li[num_li].li - prev_li;
1818                     if (((li[num_li].li > total_len) && !global_rlc_headers_expected)
1819                         || (li[num_li].li < prev_li)) {
1820                         /* add malformed LI for investigation */
1821                         malformed = tree_add_li(mode, &li[num_li], num_li, li_offs, li_on_2_bytes, tvb, tree);
1822                         expert_add_info_format(pinfo, malformed, &ei_rlc_li_incorrect_mal, "Incorrect LI value 0x%x", li[num_li].li);
1823                         return -1; /* just give up on this */
1824                     }
1825                     prev_li = li[num_li].li;
1826             }
1827         }
1828         li[num_li].tree = tree_add_li(mode, &li[num_li], num_li, li_offs, li_on_2_bytes, tvb, tree);
1829         num_li++;
1830
1831         if (num_li > max_li) {
1832             /* OK, so this is not really a malformed packet, but for now,
1833             * we will treat it as such, so that it is marked in some way */
1834             expert_add_info(pinfo, li[num_li-1].tree, &ei_rlc_li_too_many);
1835             return -1;
1836         }
1837     }
1838     return num_li;
1839 }
1840
1841 static void
1842 dissect_rlc_um(enum rlc_channel_type channel, tvbuff_t *tvb, packet_info *pinfo,
1843            proto_tree *top_level, proto_tree *tree)
1844 {
1845 #define MAX_LI 16
1846     struct rlc_li  li[MAX_LI];
1847     fp_info       *fpinf;
1848     rlc_info      *rlcinf;
1849     guint32        orig_num;
1850     guint8         seq;
1851     guint8         next_byte, offs = 0;
1852     gint16         pos, num_li     = 0;
1853     gboolean       is_truncated, li_is_on_2_bytes;
1854     proto_item    *truncated_ti;
1855
1856     next_byte = tvb_get_guint8(tvb, offs++);
1857     seq = next_byte >> 1;
1858
1859     fpinf = (fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0);
1860     rlcinf = (rlc_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_rlc, 0);
1861
1862     if (tree) {
1863         if (fpinf && rlcinf) {
1864             /* Add "channel" information, very useful for debugging. */
1865             add_channel_info(pinfo, tree, fpinf, rlcinf);
1866         }
1867         /* show sequence number and extension bit */
1868         proto_tree_add_bits_item(tree, hf_rlc_seq, tvb, 0, 7, ENC_BIG_ENDIAN);
1869         proto_tree_add_bits_item(tree, hf_rlc_ext, tvb, 7, 1, ENC_BIG_ENDIAN);
1870     }
1871
1872     if (!fpinf || !rlcinf) {
1873         proto_tree_add_text(tree, tvb, 0, -1,
1874             "Cannot dissect RLC frame because per-frame info is missing");
1875         return;
1876     }
1877
1878     pos = fpinf->cur_tb;
1879
1880     if ((rlcinf->ciphered[pos] == TRUE && rlcinf->deciphered[pos] == FALSE) || global_rlc_ciphered) {
1881         if(global_rlc_try_decipher){
1882             rlc_decipher(tvb, pinfo, tree, fpinf, rlcinf, seq, RLC_UM);
1883         }else{
1884             proto_tree_add_text(tree, tvb, 0, -1,
1885                     "Cannot dissect RLC frame because it is ciphered");
1886             col_append_str(pinfo->cinfo, COL_INFO, "[Ciphered Data]");
1887             return;
1888         }
1889     }
1890
1891     if (global_rlc_li_size == RLC_LI_UPPERLAYER) {
1892         if (rlcinf->li_size[pos] == RLC_LI_VARIABLE) {
1893             li_is_on_2_bytes = (tvb_length(tvb) > 125) ? TRUE : FALSE;
1894         } else {
1895             li_is_on_2_bytes = (rlcinf->li_size[pos] == RLC_LI_15BITS) ? TRUE : FALSE;
1896         }
1897     } else { /* Override rlcinf configuration with preference. */
1898         li_is_on_2_bytes = (global_rlc_li_size == RLC_LI_15BITS) ? TRUE : FALSE;
1899     }
1900
1901
1902
1903     num_li = rlc_decode_li(RLC_UM, tvb, pinfo, tree, li, MAX_LI, li_is_on_2_bytes);
1904     if (num_li == -1) return; /* something went wrong */
1905     offs += ((li_is_on_2_bytes) ? 2 : 1) * num_li;
1906
1907     if (global_rlc_headers_expected) {
1908         /* There might not be any data, if only header was logged */
1909         is_truncated = (tvb_length_remaining(tvb, offs) == 0);
1910         truncated_ti = proto_tree_add_boolean(tree, hf_rlc_header_only, tvb, 0, 0,
1911                                               is_truncated);
1912         if (is_truncated) {
1913             PROTO_ITEM_SET_GENERATED(truncated_ti);
1914             expert_add_info(pinfo, truncated_ti, &ei_rlc_header_only);
1915             return;
1916         } else {
1917             PROTO_ITEM_SET_HIDDEN(truncated_ti);
1918         }
1919     }
1920
1921     /* do not detect duplicates or reassemble, if prefiltering is done */
1922     if (pinfo->fd->num == 0) return;
1923     /* check for duplicates */
1924     if (rlc_is_duplicate(RLC_UM, pinfo, seq, &orig_num) == TRUE) {
1925         col_add_fstr(pinfo->cinfo, COL_INFO, "[RLC UM Fragment] [Duplicate]  SN=%u", seq);
1926         proto_tree_add_uint(tree, hf_rlc_duplicate_of, tvb, 0, 0, orig_num);
1927         return;
1928     }
1929     rlc_um_reassemble(tvb, offs, pinfo, tree, top_level, channel, seq, li, num_li, li_is_on_2_bytes);
1930 }
1931
1932 static void
1933 dissect_rlc_status(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, guint8 offset)
1934 {
1935     guint8      sufi_type, bits;
1936     guint64     len, sn, wsn, lsn, l;
1937     guint16     value, previous_sn;
1938     gboolean    isErrorBurstInd;
1939     gint        bit_offset, previous_bit_offset;
1940     guint       i, j;
1941     proto_tree *sufi_tree, *bitmap_tree, *rlist_tree;
1942     proto_item *sufi_item, *ti;
1943     #define BUFF_SIZE 41
1944     gchar      *buff                     = NULL;
1945     guint8      cw[15];
1946     guint8      sufi_start_offset;
1947     gboolean    seen_last                = FALSE;
1948     guint16     number_of_bitmap_entries = 0;
1949
1950     bit_offset = offset*8 + 4; /* first SUFI type is always 4 bit shifted */
1951
1952     while (!seen_last && tvb_length_remaining(tvb, bit_offset/8) > 0) {
1953         /* SUFI */
1954         sufi_type = tvb_get_bits8(tvb, bit_offset, 4);
1955         sufi_start_offset = bit_offset/8;
1956         sufi_item = proto_tree_add_item(tree, hf_rlc_sufi, tvb, sufi_start_offset, 0, ENC_NA);
1957         sufi_tree = proto_item_add_subtree(sufi_item, ett_rlc_sufi);
1958         proto_tree_add_bits_item(sufi_tree, hf_rlc_sufi_type, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
1959         proto_item_append_text(sufi_item, " (%s)", val_to_str_const(sufi_type, rlc_sufi_vals, "Unknown"));
1960         bit_offset += 4;
1961         switch (sufi_type) {
1962             case RLC_SUFI_NOMORE:
1963                 seen_last = TRUE;
1964                 break;
1965             case RLC_SUFI_ACK:
1966                 proto_tree_add_bits_ret_val(sufi_tree, hf_rlc_sufi_lsn, tvb, bit_offset, 12, &lsn, ENC_BIG_ENDIAN);
1967                 col_append_fstr(pinfo->cinfo, COL_INFO, " LSN=%u", (guint16)lsn);
1968                 proto_item_append_text(sufi_item, " LSN=%u", (guint16)lsn);
1969                 bit_offset += 12;
1970                 seen_last = TRUE;
1971                 break;
1972             case RLC_SUFI_WINDOW:
1973                 proto_tree_add_bits_ret_val(sufi_tree, hf_rlc_sufi_wsn, tvb, bit_offset, 12, &wsn, ENC_BIG_ENDIAN);
1974                 col_append_fstr(pinfo->cinfo, COL_INFO, " WSN=%u", (guint16)wsn);
1975                 bit_offset += 12;
1976                 break;
1977             case RLC_SUFI_LIST:
1978                 proto_tree_add_bits_ret_val(sufi_tree, hf_rlc_sufi_len, tvb, bit_offset, 4, &len, ENC_BIG_ENDIAN);
1979                 col_append_fstr(pinfo->cinfo, COL_INFO,  " LIST(%u) - ", (guint8)len);
1980                 bit_offset += 4;
1981                 if (len) {
1982                     while (len) {
1983                         ti = proto_tree_add_bits_ret_val(sufi_tree, hf_rlc_sufi_sn, tvb, bit_offset, 12, &sn, ENC_BIG_ENDIAN);
1984                         proto_item_append_text(ti, " (AMD PDU not correctly received)");
1985                         bit_offset += 12;
1986                         ti = proto_tree_add_bits_ret_val(sufi_tree, hf_rlc_sufi_l, tvb, bit_offset, 4, &l, ENC_BIG_ENDIAN);
1987                         if (l) {
1988                             proto_item_append_text(ti, " (all consecutive AMD PDUs up to SN %u not correctly received)",
1989                                                    (unsigned)(sn+l)&0xfff);
1990                             col_append_fstr(pinfo->cinfo, COL_INFO,  "%u-%u ", (guint16)sn, (unsigned)(sn+l)&0xfff);
1991                         }
1992                         else {
1993                             col_append_fstr(pinfo->cinfo, COL_INFO,  "%u ", (guint16)sn);
1994                         }
1995                         bit_offset += 4;
1996                         len--;
1997                     }
1998                 } else {
1999                     expert_add_info(pinfo, tree, &ei_rlc_sufi_len);
2000                 }
2001                 break;
2002             case RLC_SUFI_BITMAP:
2003                 proto_tree_add_bits_ret_val(sufi_tree, hf_rlc_sufi_len, tvb, bit_offset, 4, &len, ENC_BIG_ENDIAN);
2004                 bit_offset += 4;
2005                 len++; /* bitmap is len + 1 */
2006                 proto_tree_add_bits_ret_val(sufi_tree, hf_rlc_sufi_fsn, tvb, bit_offset, 12, &sn, ENC_BIG_ENDIAN);
2007                 bit_offset += 12;
2008                 proto_tree_add_item(sufi_tree, hf_rlc_sufi_bitmap, tvb, bit_offset/8, (gint)len, ENC_NA);
2009                 ti = proto_tree_add_text(sufi_tree, tvb, bit_offset/8, (gint)len, "Decoded bitmap:");
2010                 col_append_str(pinfo->cinfo, COL_INFO, " BITMAP=(");
2011
2012                 bitmap_tree = proto_item_add_subtree(ti, ett_rlc_bitmap);
2013                 buff = (gchar *)wmem_alloc(wmem_packet_scope(), BUFF_SIZE);
2014                 for (i=0; i<len; i++) {
2015                     bits = tvb_get_bits8(tvb, bit_offset, 8);
2016                     for (l=0, j=0; l<8; l++) {
2017                         if ((bits << l) & 0x80) {
2018                             j += g_snprintf(&buff[j], BUFF_SIZE-j, "%4u,", (unsigned)(sn+(8*i)+l)&0xfff);
2019                             col_append_fstr(pinfo->cinfo, COL_INFO, " %u", (unsigned)(sn+(8*i)+l)&0xfff);
2020                             number_of_bitmap_entries++;
2021                         } else {
2022                             j += g_snprintf(&buff[j], BUFF_SIZE-j, "    ,");
2023                         }
2024                     }
2025                     proto_tree_add_text(bitmap_tree, tvb, bit_offset/8, 1, "%s", buff);
2026                     bit_offset += 8;
2027                 }
2028                 proto_item_append_text(ti, " (%u SNs)", number_of_bitmap_entries);
2029                 col_append_str(pinfo->cinfo, COL_INFO, " )");
2030                 break;
2031             case RLC_SUFI_RLIST:
2032                 previous_bit_offset = bit_offset;
2033                 proto_tree_add_bits_ret_val(sufi_tree, hf_rlc_sufi_len, tvb, bit_offset, 4, &len, ENC_BIG_ENDIAN);
2034                 bit_offset += 4;
2035                 proto_tree_add_bits_ret_val(sufi_tree, hf_rlc_sufi_fsn, tvb, bit_offset, 12, &sn, ENC_BIG_ENDIAN);
2036                 bit_offset += 12;
2037                 proto_item_append_text(sufi_item, " (%u codewords)", (guint16)len);
2038
2039                 for (i=0; i<len; i++) {
2040                     ti = proto_tree_add_bits_ret_val(sufi_tree, hf_rlc_sufi_cw, tvb, bit_offset, 4, &l, ENC_BIG_ENDIAN);
2041                     if (l == 0x01) {
2042                         proto_item_append_text(ti, " (Error burst indication)");
2043                     }
2044                     bit_offset += 4;
2045                     cw[i] = (guint8)l;
2046                 }
2047                 if (len && (((cw[len-1] & 0x01) == 0) || (cw[len-1] == 0x01))) {
2048                     expert_add_info(pinfo, tree, &ei_rlc_sufi_cw);
2049                 } else {
2050                     ti = proto_tree_add_text(sufi_tree, tvb, previous_bit_offset/8, (bit_offset-previous_bit_offset)/8, "Decoded list:");
2051                     rlist_tree = proto_item_add_subtree(ti, ett_rlc_rlist);
2052                     proto_tree_add_text(rlist_tree, tvb, (previous_bit_offset+4)/8, 12/8,
2053                                         "Sequence Number = %u (AMD PDU not correctly received)",(unsigned)sn);
2054                     col_append_fstr(pinfo->cinfo, COL_INFO, " RLIST=(%u", (unsigned)sn);
2055
2056                     for (i=0, isErrorBurstInd=FALSE, j=0, previous_sn=(guint16)sn, value=0; i<len; i++) {
2057                         if (cw[i] == 0x01) {
2058                             isErrorBurstInd = TRUE;
2059                         } else {
2060                             value |= (cw[i] >> 1) << j;
2061                             j += 3;
2062                             if (cw[i] & 0x01) {
2063                                 if (isErrorBurstInd) {
2064                                     previous_sn = (previous_sn + value) & 0xfff;
2065                                     ti = proto_tree_add_text(rlist_tree, tvb, (previous_bit_offset+16+4*i)/8, 1, "Length: %u", value);
2066                                     if (value) {
2067                                         proto_item_append_text(ti, "  (all consecutive AMD PDUs up to SN %u not correctly received)", previous_sn);
2068                                         col_append_fstr(pinfo->cinfo, COL_INFO, " ->%u", previous_sn);
2069                                     }
2070                                     isErrorBurstInd = FALSE;
2071                                 } else {
2072                                     value = (value + previous_sn) & 0xfff;
2073                                     proto_tree_add_text(rlist_tree, tvb, (previous_bit_offset+16+4*i)/8, 1, "Sequence Number = %u (AMD PDU not correctly received)",value);
2074                                     col_append_fstr(pinfo->cinfo, COL_INFO, " %u", value);
2075                                     previous_sn = value;
2076                                 }
2077                                 value = j = 0;
2078                             }
2079                         }
2080                     }
2081                     col_append_str(pinfo->cinfo, COL_INFO, ")");
2082                 }
2083                 break;
2084             case RLC_SUFI_MRW_ACK:
2085                 col_append_str(pinfo->cinfo, COL_INFO, " MRW-ACK");
2086                 proto_tree_add_bits_item(sufi_tree, hf_rlc_sufi_n, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
2087                 bit_offset += 4;
2088                 proto_tree_add_bits_ret_val(sufi_tree, hf_rlc_sufi_sn_ack, tvb, bit_offset, 12, &sn, ENC_BIG_ENDIAN);
2089                 bit_offset += 12;
2090                 col_append_fstr(pinfo->cinfo, COL_INFO, " SN=%u", (guint16)sn);
2091                 break;
2092             case RLC_SUFI_MRW:
2093                 col_append_str(pinfo->cinfo, COL_INFO, " MRW");
2094                 proto_tree_add_bits_ret_val(sufi_tree, hf_rlc_sufi_len, tvb, bit_offset, 4, &len, ENC_BIG_ENDIAN);
2095                 bit_offset += 4;
2096                 if (len) {
2097                     while (len) {
2098                         proto_tree_add_bits_ret_val(sufi_tree, hf_rlc_sufi_sn_mrw, tvb, bit_offset, 12, &sn, ENC_BIG_ENDIAN);
2099                         col_append_fstr(pinfo->cinfo, COL_INFO, " SN=%u", (guint16)sn);
2100                         bit_offset += 12;
2101                         len--;
2102                     }
2103                 } else {
2104                     /* only one SN_MRW field is present */
2105                     ti = proto_tree_add_bits_item(sufi_tree, hf_rlc_sufi_sn_mrw, tvb, bit_offset, 12, ENC_BIG_ENDIAN);
2106                     proto_item_append_text(ti, " (RLC SDU to be discarded in the Receiver extends above the configured transmission window in the Sender)");
2107                     bit_offset += 12;
2108                 }
2109                 proto_tree_add_bits_item(sufi_tree, hf_rlc_sufi_n, tvb, bit_offset, 4, ENC_BIG_ENDIAN);
2110                 bit_offset += 4;
2111                 break;
2112             case RLC_SUFI_POLL:
2113                 proto_tree_add_bits_item(sufi_tree, hf_rlc_sufi_poll_sn, tvb, bit_offset, 12, ENC_BIG_ENDIAN);
2114                 bit_offset += 12;
2115                 break;
2116
2117             default:
2118                 expert_add_info(pinfo, tree, &ei_rlc_sufi_type);
2119                 return; /* invalid value, ignore the rest */
2120         }
2121
2122         /* Set extent of SUFI root */
2123         proto_item_set_len(sufi_item, ((bit_offset+7)/8) - sufi_start_offset);
2124     }
2125 }
2126
2127 static void
2128 dissect_rlc_control(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2129 {
2130     guint8      type, next_byte;
2131     proto_item *ti;
2132     guint64     r1;
2133     guint64     rsn, hfn;
2134
2135     next_byte = tvb_get_guint8(tvb, 0);
2136     type = (next_byte >> 4) & 0x07;
2137
2138     ti = proto_tree_add_bits_item(tree, hf_rlc_ctrl_type, tvb, 1, 3, ENC_BIG_ENDIAN);
2139     switch (type) {
2140         case RLC_STATUS:
2141             dissect_rlc_status(tvb, pinfo, tree, 0);
2142             break;
2143         case RLC_RESET:
2144         case RLC_RESET_ACK:
2145             col_append_str(pinfo->cinfo, COL_INFO, (type == RLC_RESET) ? " RESET" : " RESET-ACK");
2146             proto_tree_add_bits_ret_val(tree, hf_rlc_rsn, tvb, 4, 1, &rsn, ENC_BIG_ENDIAN);
2147             proto_tree_add_bits_ret_val(tree, hf_rlc_r1, tvb, 5, 3, &r1, ENC_BIG_ENDIAN);
2148             if (r1) {
2149                 expert_add_info(pinfo, ti, &ei_rlc_reserved_bits_not_zero);
2150                 return;
2151             }
2152             proto_tree_add_bits_ret_val(tree, hf_rlc_hfni, tvb, 8, 20, &hfn, ENC_BIG_ENDIAN);
2153             col_append_fstr(pinfo->cinfo, COL_INFO, " RSN=%u HFN=%u", (guint16)rsn, (guint32)hfn);
2154             break;
2155         default:
2156             expert_add_info(pinfo, ti, &ei_rlc_ctrl_type);
2157             return; /* invalid */
2158     }
2159 }
2160
2161 static void
2162 rlc_am_reassemble(tvbuff_t *tvb, guint8 offs, packet_info *pinfo,
2163           proto_tree *tree, proto_tree *top_level,
2164           enum rlc_channel_type channel, guint16 seq, gboolean poll_set, struct rlc_li *li,
2165           guint16 num_li, gboolean final, gboolean li_is_on_2_bytes)
2166 {
2167     guint8    i;
2168     gboolean  piggyback = FALSE, dissected = FALSE;
2169     tvbuff_t *next_tvb  = NULL;
2170
2171     struct rlc_channel  ch_lookup;
2172     struct rlc_seqlist * endlist = NULL;
2173     if( 0 == seq ){ /* assuming that a new RRC Connection is established when 0==seq.  */
2174         if( -1 != rlc_channel_assign(&ch_lookup, RLC_AM, pinfo ) ){
2175             endlist = get_endlist(pinfo, &ch_lookup);
2176             endlist->list->data = GINT_TO_POINTER( -1);
2177         }
2178     }
2179
2180     /* perform reassembly now */
2181     for (i = 0; i < num_li; i++) {
2182         if ((!li_is_on_2_bytes && (li[i].li == 0x7e)) || (li[i].li == 0x7ffe)) {
2183             /* piggybacked status */
2184             piggyback = TRUE;
2185         } else if ((!li_is_on_2_bytes && (li[i].li == 0x7f)) || (li[i].li == 0x7fff)) {
2186             /* padding, must be last LI */
2187             if (tvb_length_remaining(tvb, offs) > 0) {
2188                 if (tree) {
2189                     proto_tree_add_item(tree, hf_rlc_pad, tvb, offs, -1, ENC_NA);
2190                 }
2191                 if (i == 0) {
2192                     /* Insert empty RLC frag so RLC doesn't miss this seq number. */
2193                     add_fragment(RLC_AM, tvb, pinfo, li[i].tree, offs, seq, i, 0, TRUE);
2194                 }
2195             }
2196             offs += tvb_length_remaining(tvb, offs);
2197         } else {
2198             if (tree) {
2199                 proto_tree_add_item(tree, hf_rlc_data, tvb, offs, li[i].len, ENC_NA);
2200             }
2201             if (global_rlc_perform_reassemby) {
2202                 add_fragment(RLC_AM, tvb, pinfo, li[i].tree, offs, seq, i, li[i].len, TRUE);
2203                 next_tvb = get_reassembled_data(RLC_AM, tvb, pinfo, tree, seq, i);
2204             }
2205         }
2206         if (next_tvb) {
2207             dissected = TRUE;
2208             rlc_call_subdissector(channel, next_tvb, pinfo, top_level);
2209             next_tvb = NULL;
2210         }
2211         offs += li[i].len;
2212     }
2213
2214     if (piggyback) {
2215         dissect_rlc_status(tvb, pinfo, tree, offs);
2216     } else {
2217         if (tvb_length_remaining(tvb, offs) > 0) {
2218             /* we have remaining data, which we need to mark in the tree */
2219             if (tree) {
2220                 proto_tree_add_item(tree, hf_rlc_data, tvb, offs, -1, ENC_NA);
2221             }
2222             if (global_rlc_perform_reassemby) {
2223                 add_fragment(RLC_AM, tvb, pinfo, tree, offs, seq, i,
2224                     tvb_length_remaining(tvb,offs), final);
2225                 if (final) {
2226                     next_tvb = get_reassembled_data(RLC_AM, tvb, pinfo, tree, seq, i);
2227                 }
2228             }
2229         }
2230         if (next_tvb) {
2231             dissected = TRUE;
2232             rlc_call_subdissector(channel, next_tvb, pinfo, top_level);
2233             next_tvb = NULL;
2234         }
2235     }
2236     if (dissected == FALSE)
2237         col_append_fstr(pinfo->cinfo, COL_INFO, "[RLC AM Fragment]  SN=%u %s",
2238                      seq, poll_set ? "(P)" : "");
2239     else
2240         if (channel == RLC_UNKNOWN_CH)
2241             col_append_fstr(pinfo->cinfo, COL_INFO, "[RLC AM Data]  SN=%u %s",
2242                          seq, poll_set ? "(P)" : "");
2243 }
2244
2245 static void
2246 dissect_rlc_am(enum rlc_channel_type channel, tvbuff_t *tvb, packet_info *pinfo,
2247            proto_tree *top_level, proto_tree *tree)
2248 {
2249 #define MAX_LI 16
2250     struct rlc_li  li[MAX_LI];
2251     fp_info       *fpinf;
2252     rlc_info      *rlcinf;
2253     guint8         ext, dc;
2254     guint8         next_byte, offs = 0;
2255     guint32        orig_num        = 0;
2256     gint16         num_li          = 0, pos;
2257     guint16        seq;
2258     gboolean       is_truncated, li_is_on_2_bytes;
2259     proto_item    *truncated_ti, *ti;
2260     guint64        polling;
2261
2262     fpinf = (fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0);
2263     rlcinf = (rlc_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_rlc, 0);
2264
2265     next_byte = tvb_get_guint8(tvb, offs++);
2266     dc = next_byte >> 7;
2267     if (tree) {
2268         if (fpinf && rlcinf) {
2269             /* Add "channel" information, very useful for debugging. */
2270             add_channel_info(pinfo, tree, fpinf, rlcinf);
2271         }
2272         proto_tree_add_bits_item(tree, hf_rlc_dc, tvb, 0, 1, ENC_BIG_ENDIAN);
2273     }
2274     if (dc == 0) {
2275         col_set_str(pinfo->cinfo, COL_INFO, "[RLC Control Frame]");
2276         dissect_rlc_control(tvb, pinfo, tree);
2277         return;
2278     }
2279
2280     seq = next_byte & 0x7f;
2281     seq <<= 5;
2282     next_byte = tvb_get_guint8(tvb, offs++);
2283     seq |= (next_byte >> 3);
2284
2285     ext = next_byte & 0x03;
2286     /* show header fields */
2287     proto_tree_add_bits_item(tree, hf_rlc_seq, tvb, 1, 12, ENC_BIG_ENDIAN);
2288     proto_tree_add_bits_ret_val(tree, hf_rlc_p, tvb, 13, 1, &polling, ENC_BIG_ENDIAN);
2289     ti = proto_tree_add_bits_item(tree, hf_rlc_he, tvb, 14, 2, ENC_BIG_ENDIAN);
2290
2291     /* header extension may only be 00, 01 or 10 */
2292     if (ext > 2) {
2293         expert_add_info(pinfo, ti, &ei_rlc_he);
2294         return;
2295     }
2296
2297     if (!fpinf || !rlcinf) {
2298         proto_tree_add_text(tree, tvb, 0, -1,
2299             "Cannot dissect RLC frame because per-frame info is missing");
2300         return;
2301     }
2302
2303     pos = fpinf->cur_tb;
2304
2305     /**
2306      * WARNING DECIPHERING IS HIGHLY EXPERIMENTAL!!!
2307      * */
2308     if (((rlcinf->ciphered[pos] == TRUE && rlcinf->deciphered[pos] == FALSE) || global_rlc_ciphered)) {
2309         if(global_rlc_try_decipher){
2310             rlc_decipher(tvb, pinfo, tree, fpinf, rlcinf, seq, RLC_AM);
2311         }else{
2312             proto_tree_add_text(tree, tvb, 0, -1,
2313                     "Cannot dissect RLC frame because it is ciphered");
2314             col_append_str(pinfo->cinfo, COL_INFO, "[Ciphered Data]");
2315             return;
2316         }
2317     }
2318
2319     if (global_rlc_li_size == RLC_LI_UPPERLAYER) {
2320         if (rlcinf->li_size[pos] == RLC_LI_VARIABLE) {
2321             li_is_on_2_bytes = (tvb_length(tvb) > 126) ? TRUE : FALSE;
2322         } else {
2323             li_is_on_2_bytes = (rlcinf->li_size[pos] == RLC_LI_15BITS) ? TRUE : FALSE;
2324         }
2325     } else { /* Override rlcinf configuration with preference. */
2326         li_is_on_2_bytes = (global_rlc_li_size == RLC_LI_15BITS) ? TRUE : FALSE;
2327     }
2328
2329     num_li = rlc_decode_li(RLC_AM, tvb, pinfo, tree, li, MAX_LI, li_is_on_2_bytes);
2330     if (num_li == -1) return; /* something went wrong */
2331     offs += ((li_is_on_2_bytes) ? 2 : 1) * num_li;
2332     if (global_rlc_headers_expected) {
2333         /* There might not be any data, if only header was logged */
2334         is_truncated = (tvb_length_remaining(tvb, offs) == 0);
2335         truncated_ti = proto_tree_add_boolean(tree, hf_rlc_header_only, tvb, 0, 0,
2336                                               is_truncated);
2337         if (is_truncated) {
2338             PROTO_ITEM_SET_GENERATED(truncated_ti);
2339             expert_add_info(pinfo, truncated_ti, &ei_rlc_header_only);
2340             return;
2341         } else {
2342             PROTO_ITEM_SET_HIDDEN(truncated_ti);
2343         }
2344     }
2345
2346     /* do not detect duplicates or reassemble, if prefiltering is done */
2347     if (pinfo->fd->num == 0) return;
2348     /* check for duplicates, but not if already visited */
2349     if (pinfo->fd->flags.visited == FALSE && rlc_is_duplicate(RLC_AM, pinfo, seq, &orig_num) == TRUE) {
2350         g_hash_table_insert(duplicate_table, GUINT_TO_POINTER(pinfo->fd->num), GUINT_TO_POINTER(orig_num));
2351         return;
2352     } else if (pinfo->fd->flags.visited == TRUE && tree) {
2353         gpointer value = g_hash_table_lookup(duplicate_table, GUINT_TO_POINTER(pinfo->fd->num));
2354         if (value != NULL) {
2355             col_add_fstr(pinfo->cinfo, COL_INFO, "[RLC AM Fragment] [Duplicate]  SN=%u %s", seq, (polling != 0) ? "(P)" : "");
2356             proto_tree_add_uint(tree, hf_rlc_duplicate_of, tvb, 0, 0, GPOINTER_TO_UINT(value));
2357             return;
2358         }
2359     }
2360
2361     rlc_am_reassemble(tvb, offs, pinfo, tree, top_level, channel, seq, polling != 0,
2362                       li, num_li, ext == 2, li_is_on_2_bytes);
2363 }
2364
2365 /* dissect entry functions */
2366 static void
2367 dissect_rlc_pcch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2368 {
2369     proto_tree *subtree = NULL;
2370
2371     col_set_str(pinfo->cinfo, COL_PROTOCOL, "RLC");
2372     col_clear(pinfo->cinfo, COL_INFO);
2373
2374     /* PCCH is always RLC TM */
2375     if (tree) {
2376         proto_item *ti;
2377         ti = proto_tree_add_item(tree, proto_rlc, tvb, 0, -1, ENC_NA);
2378         subtree = proto_item_add_subtree(ti, ett_rlc);
2379         proto_item_append_text(ti, " TM (PCCH)");
2380     }
2381     dissect_rlc_tm(RLC_PCCH, tvb, pinfo, tree, subtree);
2382 }
2383
2384 static void
2385 dissect_rlc_bcch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2386 {
2387     fp_info    *fpi;
2388     proto_item *ti      = NULL;
2389     proto_tree *subtree = NULL;
2390
2391     col_set_str(pinfo->cinfo, COL_PROTOCOL, "RLC");
2392     col_clear(pinfo->cinfo, COL_INFO);
2393
2394     fpi = (fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0);
2395     if (!fpi) return; /* dissection failure */
2396
2397     if (tree) {
2398         ti = proto_tree_add_item(tree, proto_rlc, tvb, 0, -1, ENC_NA);
2399         subtree = proto_item_add_subtree(ti, ett_rlc);
2400     }
2401     proto_item_append_text(ti, " TM (BCCH)");
2402     dissect_rlc_tm(RLC_BCCH, tvb, pinfo, tree, subtree);
2403 }
2404
2405 static void
2406 dissect_rlc_ccch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2407 {
2408     fp_info    *fpi;
2409     proto_item *ti      = NULL;
2410     proto_tree *subtree = NULL;
2411
2412     col_set_str(pinfo->cinfo, COL_PROTOCOL, "RLC");
2413     col_clear(pinfo->cinfo, COL_INFO);
2414
2415     fpi = (fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0);
2416     if (!fpi) return; /* dissection failure */
2417
2418     if (tree) {
2419         ti = proto_tree_add_item(tree, proto_rlc, tvb, 0, -1, ENC_NA);
2420         subtree = proto_item_add_subtree(ti, ett_rlc);
2421     }
2422
2423     if (fpi->is_uplink) {
2424         /* UL CCCH is always RLC TM */
2425         proto_item_append_text(ti, " TM (CCCH)");
2426         dissect_rlc_tm(RLC_UL_CCCH, tvb, pinfo, tree, subtree);
2427     } else {
2428         /* DL CCCH is always UM */
2429         proto_item_append_text(ti, " UM (CCCH)");
2430         dissect_rlc_um(RLC_DL_CCCH, tvb, pinfo, tree, subtree);
2431     }
2432 }
2433
2434 static void
2435 dissect_rlc_ctch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2436 {
2437     fp_info    *fpi;
2438     proto_item *ti      = NULL;
2439     proto_tree *subtree = NULL;
2440
2441
2442     col_set_str(pinfo->cinfo, COL_PROTOCOL, "RLC");
2443     col_clear(pinfo->cinfo, COL_INFO);
2444
2445     fpi = (fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0);
2446     if (!fpi) return; /* dissection failure */
2447
2448     if (tree) {
2449         ti = proto_tree_add_item(tree, proto_rlc, tvb, 0, -1, ENC_NA);
2450         subtree = proto_item_add_subtree(ti, ett_rlc);
2451     }
2452
2453     /* CTCH is always UM */
2454     proto_item_append_text(ti, " UM (CTCH)");
2455     dissect_rlc_um(RLC_DL_CTCH, tvb, pinfo, tree, subtree);
2456 }
2457
2458 static void
2459 dissect_rlc_dcch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2460 {
2461     proto_item            *ti      = NULL;
2462     proto_tree            *subtree = NULL;
2463     fp_info               *fpi;
2464     rlc_info              *rlci;
2465     enum rlc_channel_type  channel;
2466
2467     col_set_str(pinfo->cinfo, COL_PROTOCOL, "RLC");
2468     col_clear(pinfo->cinfo, COL_INFO);
2469
2470     fpi = (fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0);
2471     rlci = (rlc_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_rlc, 0);
2472
2473     if (!fpi || !rlci){
2474         ti = proto_tree_add_text(tree, tvb, 0, -1,
2475                      "Can't dissect RLC frame because no per-frame info was attached!");
2476         PROTO_ITEM_SET_GENERATED(ti);
2477         return;
2478     }
2479
2480     if (tree) {
2481         ti = proto_tree_add_item(tree, proto_rlc, tvb, 0, -1, ENC_NA);
2482         subtree = proto_item_add_subtree(ti, ett_rlc);
2483     }
2484
2485     channel = fpi->is_uplink ? RLC_UL_DCCH : RLC_DL_DCCH;
2486
2487     switch (rlci->mode[fpi->cur_tb]) {
2488         case RLC_UM:
2489             proto_item_append_text(ti, " UM (DCCH)");
2490             dissect_rlc_um(channel, tvb, pinfo, tree, subtree);
2491             break;
2492         case RLC_AM:
2493             proto_item_append_text(ti, " AM (DCCH)");
2494             dissect_rlc_am(channel, tvb, pinfo, tree, subtree);
2495             break;
2496     }
2497 }
2498
2499 static void
2500 dissect_rlc_ps_dtch(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2501 {
2502     proto_item *ti      = NULL;
2503     proto_tree *subtree = NULL;
2504     fp_info    *fpi;
2505     rlc_info   *rlci;
2506
2507     col_set_str(pinfo->cinfo, COL_PROTOCOL, "RLC");
2508     col_clear(pinfo->cinfo, COL_INFO);
2509
2510     fpi  = (fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0);
2511     rlci = (rlc_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_rlc, 0);
2512
2513     if (!fpi || !rlci) {
2514         ti = proto_tree_add_text(tree, tvb, 0, -1,
2515                      "Can't dissect RLC frame because no per-frame info was attached!");
2516         PROTO_ITEM_SET_GENERATED(ti);
2517         return;
2518     }
2519
2520     if (tree) {
2521         ti = proto_tree_add_item(tree, proto_rlc, tvb, 0, -1, ENC_NA);
2522         subtree = proto_item_add_subtree(ti, ett_rlc);
2523     }
2524
2525     switch (rlci->mode[fpi->cur_tb]) {
2526         case RLC_UM:
2527             proto_item_append_text(ti, " UM (PS DTCH)");
2528             dissect_rlc_um(RLC_PS_DTCH, tvb, pinfo, tree, subtree);
2529             break;
2530         case RLC_AM:
2531             proto_item_append_text(ti, " AM (PS DTCH)");
2532             dissect_rlc_am(RLC_PS_DTCH, tvb, pinfo, tree, subtree);
2533             break;
2534         case RLC_TM:
2535             proto_item_append_text(ti, " TM (PS DTCH)");
2536             dissect_rlc_tm(RLC_PS_DTCH, tvb, pinfo, tree, subtree);
2537             break;
2538     }
2539 }
2540
2541 static void
2542 dissect_rlc_dch_unknown(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
2543 {
2544     proto_item *ti      = NULL;
2545     proto_tree *subtree = NULL;
2546     fp_info    *fpi;
2547     rlc_info   *rlci;
2548
2549     col_set_str(pinfo->cinfo, COL_PROTOCOL, "RLC");
2550     col_clear(pinfo->cinfo, COL_INFO);
2551
2552     fpi = (fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0);
2553     rlci = (rlc_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_rlc, 0);
2554
2555     if (!fpi || !rlci) return;
2556
2557     if (tree) {
2558         ti = proto_tree_add_item(tree, proto_rlc, tvb, 0, -1, ENC_NA);
2559         subtree = proto_item_add_subtree(ti, ett_rlc);
2560     }
2561
2562     switch (rlci->mode[fpi->cur_tb]) {
2563         case RLC_UM:
2564             proto_item_append_text(ti, " UM (Unknown)");
2565             dissect_rlc_um(RLC_UNKNOWN_CH, tvb, pinfo, tree, subtree);
2566             break;
2567         case RLC_AM:
2568             proto_item_append_text(ti, " AM (Unknown)");
2569             dissect_rlc_am(RLC_UNKNOWN_CH, tvb, pinfo, tree, subtree);
2570             break;
2571         case RLC_TM:
2572             proto_item_append_text(ti, " TM (Unknown)");
2573             dissect_rlc_tm(RLC_UNKNOWN_CH, tvb, pinfo, tree, subtree);
2574             break;
2575     }
2576 }
2577
2578
2579 /* Heuristic dissector looks for supported framing protocol (see wiki page)  */
2580 static gboolean
2581 dissect_rlc_heur(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
2582 {
2583     gint        offset             = 0;
2584     fp_info    *fpi;
2585     rlc_info   *rlci;
2586     tvbuff_t   *rlc_tvb;
2587     guint8      tag                = 0;
2588     guint       channelType        = UMTS_CHANNEL_TYPE_UNSPECIFIED;
2589     gboolean    fpInfoAlreadySet   = FALSE;
2590     gboolean    rlcInfoAlreadySet  = FALSE;
2591     gboolean    channelTypePresent = FALSE;
2592     gboolean    rlcModePresent     = FALSE;
2593     proto_item *ti                 = NULL;
2594     proto_tree *subtree            = NULL;
2595
2596     /* This is a heuristic dissector, which means we get all the UDP
2597      * traffic not sent to a known dissector and not claimed by
2598      * a heuristic dissector called before us!
2599      */
2600     if (!global_rlc_heur) {
2601         return FALSE;
2602     }
2603
2604     /* Do this again on re-dissection to re-discover offset of actual PDU */
2605
2606     /* Needs to be at least as long as:
2607        - the signature string
2608        - conditional header bytes
2609        - tag for data
2610        - at least one byte of RLC PDU payload */
2611     if (tvb_length_remaining(tvb, offset) < (gint)(strlen(RLC_START_STRING)+2+2)) {
2612         return FALSE;
2613     }
2614
2615     /* OK, compare with signature string */
2616     if (tvb_strneql(tvb, offset, RLC_START_STRING, (gint)strlen(RLC_START_STRING)) != 0) {
2617         return FALSE;
2618     }
2619     offset += (gint)strlen(RLC_START_STRING);
2620
2621     /* If redissecting, use previous info struct (if available) */
2622     fpi = (fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0);
2623     if (fpi == NULL) {
2624         /* Allocate new info struct for this frame */
2625         fpi = (fp_info *)wmem_alloc0(wmem_file_scope(), sizeof(fp_info));
2626     } else {
2627         fpInfoAlreadySet = TRUE;
2628     }
2629     rlci = (rlc_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_rlc, 0);
2630     if (rlci == NULL) {
2631         /* Allocate new info struct for this frame */
2632         rlci = (rlc_info *)wmem_alloc0(wmem_file_scope(), sizeof(rlc_info));
2633     } else {
2634         rlcInfoAlreadySet = TRUE;
2635     }
2636
2637     /* Read conditional/optional fields */
2638     while (tag != RLC_PAYLOAD_TAG) {
2639         /* Process next tag */
2640         tag = tvb_get_guint8(tvb, offset++);
2641         switch (tag) {
2642             case RLC_CHANNEL_TYPE_TAG:
2643                 channelType = tvb_get_guint8(tvb, offset);
2644                 offset++;
2645                 channelTypePresent = TRUE;
2646                 break;
2647             case RLC_MODE_TAG:
2648                 rlci->mode[fpi->cur_tb] = tvb_get_guint8(tvb, offset);
2649                 offset++;
2650                 rlcModePresent = TRUE;
2651                 break;
2652             case RLC_DIRECTION_TAG:
2653                 if (tvb_get_guint8(tvb, offset) == DIRECTION_UPLINK) {
2654                     fpi->is_uplink = TRUE;
2655                     pinfo->p2p_dir = P2P_DIR_UL;
2656                 } else {
2657                     fpi->is_uplink = FALSE;
2658                     pinfo->p2p_dir = P2P_DIR_DL;
2659                 }
2660                 offset++;
2661                 break;
2662             case RLC_URNTI_TAG:
2663                 rlci->urnti[fpi->cur_tb] = tvb_get_ntohl(tvb, offset);
2664                 offset += 4;
2665                 break;
2666             case RLC_RADIO_BEARER_ID_TAG:
2667                 rlci->rbid[fpi->cur_tb] = tvb_get_guint8(tvb, offset);
2668                 offset++;
2669                 break;
2670             case RLC_LI_SIZE_TAG:
2671                 rlci->li_size[fpi->cur_tb] = (enum rlc_li_size) tvb_get_guint8(tvb, offset);
2672                 offset++;
2673                 break;
2674             case RLC_PAYLOAD_TAG:
2675                 /* Have reached data, so get out of loop */
2676                 continue;
2677             default:
2678                 /* It must be a recognised tag */
2679                 return FALSE;
2680         }
2681     }
2682
2683     if ((channelTypePresent == FALSE) && (rlcModePresent == FALSE)) {
2684         /* Conditional fields are missing */
2685         return FALSE;
2686     }
2687
2688     /* Store info in packet if needed */
2689     if (!fpInfoAlreadySet) {
2690         p_add_proto_data(wmem_file_scope(), pinfo, proto_fp, 0, fpi);
2691     }
2692     if (!rlcInfoAlreadySet) {
2693         p_add_proto_data(wmem_file_scope(), pinfo, proto_rlc, 0, rlci);
2694     }
2695
2696     /**************************************/
2697     /* OK, now dissect as RLC             */
2698
2699     /* Create tvb that starts at actual RLC PDU */
2700     rlc_tvb = tvb_new_subset_remaining(tvb, offset);
2701     switch (channelType) {
2702         case UMTS_CHANNEL_TYPE_UNSPECIFIED:
2703             /* Call relevant dissector according to RLC mode */
2704             col_set_str(pinfo->cinfo, COL_PROTOCOL, "RLC");
2705             col_clear(pinfo->cinfo, COL_INFO);
2706
2707             if (tree) {
2708                 ti = proto_tree_add_item(tree, proto_rlc, rlc_tvb, 0, -1, ENC_NA);
2709                 subtree = proto_item_add_subtree(ti, ett_rlc);
2710             }
2711
2712             if (rlci->mode[fpi->cur_tb] == RLC_AM) {
2713                 proto_item_append_text(ti, " AM");
2714                 dissect_rlc_am(RLC_UNKNOWN_CH, rlc_tvb, pinfo, tree, subtree);
2715             } else if (rlci->mode[fpi->cur_tb] == RLC_UM) {
2716                 proto_item_append_text(ti, " UM");
2717                 dissect_rlc_um(RLC_UNKNOWN_CH, rlc_tvb, pinfo, tree, subtree);
2718             } else {
2719                 proto_item_append_text(ti, " TM");
2720                 dissect_rlc_tm(RLC_UNKNOWN_CH, rlc_tvb, pinfo, tree, subtree);
2721             }
2722             break;
2723         case UMTS_CHANNEL_TYPE_PCCH:
2724             dissect_rlc_pcch(rlc_tvb, pinfo, tree);
2725             break;
2726         case UMTS_CHANNEL_TYPE_CCCH:
2727             dissect_rlc_ccch(rlc_tvb, pinfo, tree);
2728             break;
2729         case UMTS_CHANNEL_TYPE_DCCH:
2730             dissect_rlc_dcch(rlc_tvb, pinfo, tree);
2731             break;
2732         case UMTS_CHANNEL_TYPE_PS_DTCH:
2733             dissect_rlc_ps_dtch(rlc_tvb, pinfo, tree);
2734             break;
2735         case UMTS_CHANNEL_TYPE_CTCH:
2736             dissect_rlc_ctch(rlc_tvb, pinfo, tree);
2737             break;
2738         case UMTS_CHANNEL_TYPE_BCCH:
2739             dissect_rlc_bcch(rlc_tvb, pinfo, tree);
2740             break;
2741         default:
2742             /* Unknown channel type */
2743             return FALSE;
2744     }
2745
2746     return TRUE;
2747 }
2748
2749 gboolean
2750 rlc_is_ciphered(packet_info * pinfo){
2751     fp_info *fpinf;
2752     rlc_info *rlcinf;
2753
2754     if (!pinfo) {
2755         return global_rlc_ciphered;
2756     }
2757
2758     fpinf = (fp_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_fp, 0);
2759     rlcinf = (rlc_info *)p_get_proto_data(wmem_file_scope(), pinfo, proto_rlc, 0);
2760
2761     return ((rlcinf && fpinf && (rlcinf->ciphered[fpinf->cur_tb] == TRUE) && (rlcinf->deciphered[fpinf->cur_tb] == FALSE))
2762             || global_rlc_ciphered);
2763 }
2764
2765 void
2766 proto_register_rlc(void)
2767 {
2768     module_t *rlc_module;
2769     expert_module_t* expert_rlc;
2770     static hf_register_info hf[] = {
2771         { &hf_rlc_dc,
2772           { "D/C Bit", "rlc.dc",
2773             FT_BOOLEAN, BASE_NONE, TFS(&rlc_dc_val), 0, NULL, HFILL }
2774         },
2775         { &hf_rlc_ctrl_type,
2776           { "Control PDU Type", "rlc.ctrl_pdu_type",
2777             FT_UINT8, BASE_DEC, VALS(rlc_ctrl_vals), 0, "PDU Type", HFILL }
2778         },
2779         { &hf_rlc_r1,
2780           { "Reserved 1", "rlc.r1",
2781             FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
2782         },
2783         { &hf_rlc_rsn,
2784           { "Reset Sequence Number", "rlc.rsn",
2785             FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
2786         },
2787         { &hf_rlc_hfni,
2788           { "Hyper Frame Number Indicator", "rlc.hfni",
2789             FT_UINT24, BASE_DEC, NULL, 0, NULL, HFILL }
2790         },
2791         { &hf_rlc_seq,
2792           { "Sequence Number", "rlc.seq",
2793             FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
2794         },
2795         { &hf_rlc_ext,
2796           { "Extension Bit", "rlc.ext",
2797             FT_BOOLEAN, BASE_NONE, TFS(&rlc_ext_val), 0, NULL, HFILL }
2798         },
2799         { &hf_rlc_he,
2800           { "Header Extension Type", "rlc.he",
2801             FT_UINT8, BASE_DEC, VALS(rlc_he_vals), 0, NULL, HFILL }
2802         },
2803         { &hf_rlc_p,
2804           { "Polling Bit", "rlc.p",
2805             FT_BOOLEAN, BASE_NONE, TFS(&rlc_p_val), 0, NULL, HFILL }
2806         },
2807         { &hf_rlc_pad,
2808           { "Padding", "rlc.padding",
2809             FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
2810         },
2811         { &hf_rlc_frags,
2812           { "Reassembled Fragments", "rlc.fragments",
2813             FT_NONE, BASE_NONE, NULL, 0, "Fragments", HFILL }
2814         },
2815         { &hf_rlc_frag,
2816           { "RLC Fragment", "rlc.fragment",
2817             FT_FRAMENUM, BASE_NONE, NULL, 0, NULL, HFILL }
2818         },
2819         { &hf_rlc_duplicate_of,
2820           { "Duplicate of", "rlc.duplicate_of",
2821             FT_FRAMENUM, BASE_NONE, NULL, 0, NULL, HFILL }
2822         },
2823         { &hf_rlc_reassembled_in,
2824           { "Reassembled Message in frame", "rlc.reassembled_in",
2825             FT_FRAMENUM, BASE_NONE, NULL, 0, NULL, HFILL }
2826         },
2827         { &hf_rlc_data,
2828           { "Data", "rlc.data",
2829             FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
2830         },
2831         /* LI information */
2832         { &hf_rlc_li,
2833           { "LI", "rlc.li",
2834             FT_NONE, BASE_NONE, NULL, 0, "Length Indicator", HFILL }
2835         },
2836         { &hf_rlc_li_value,
2837           { "LI value", "rlc.li.value",
2838             FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
2839         },
2840         { &hf_rlc_li_ext,
2841           { "LI extension bit", "rlc.li.ext",
2842             FT_BOOLEAN, BASE_NONE, TFS(&rlc_ext_val), 0, NULL, HFILL }
2843         },
2844         { &hf_rlc_li_data,
2845           { "LI Data", "rlc.li.data",
2846             FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }
2847         },
2848         /* SUFI information */
2849         { &hf_rlc_sufi,
2850           { "SUFI", "rlc.sufi",
2851             FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }
2852         },
2853         { &hf_rlc_sufi_type,
2854           { "SUFI Type", "rlc.sufi.type",
2855             FT_UINT8, BASE_DEC, VALS(rlc_sufi_vals), 0, NULL, HFILL }
2856         },
2857         { &hf_rlc_sufi_lsn,
2858           { "Last Sequence Number", "rlc.sufi.lsn",
2859             FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
2860         },
2861         { &hf_rlc_sufi_wsn,
2862           { "Window Size Number", "rlc.sufi.wsn",
2863             FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
2864         },
2865         { &hf_rlc_sufi_sn,
2866           { "Sequence Number", "rlc.sufi.sn",
2867             FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
2868         },
2869         { &hf_rlc_sufi_l,
2870           { "Length", "rlc.sufi.l",
2871             FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
2872         },
2873         { &hf_rlc_sufi_len,
2874           { "Length", "rlc.sufi.len",
2875             FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
2876         },
2877         { &hf_rlc_sufi_fsn,
2878           { "First Sequence Number", "rlc.sufi.fsn",
2879             FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
2880         },
2881         { &hf_rlc_sufi_bitmap,
2882           { "Bitmap", "rlc.sufi.bitmap",
2883             FT_BYTES, BASE_NONE, NULL, 0, NULL, HFILL }
2884         },
2885         { &hf_rlc_sufi_cw,
2886           { "Codeword", "rlc.sufi.cw",
2887             FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
2888         },
2889         { &hf_rlc_sufi_n,
2890           { "Nlength", "rlc.sufi.n",
2891             FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
2892         },
2893         { &hf_rlc_sufi_sn_ack,
2894           { "SN ACK", "rlc.sufi.sn_ack",
2895             FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
2896         },
2897         { &hf_rlc_sufi_sn_mrw,
2898           { "SN MRW", "rlc.sufi.sn_mrw",
2899             FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
2900         },
2901         { &hf_rlc_sufi_poll_sn,
2902           { "Poll SN", "rlc.sufi.poll_sn",
2903             FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }
2904         },
2905         /* Other information */
2906         { &hf_rlc_header_only,
2907           { "RLC PDU header only", "rlc.header_only",
2908             FT_BOOLEAN, BASE_NONE, TFS(&rlc_header_only_val), 0 ,NULL, HFILL }
2909         },
2910         { &hf_rlc_channel,
2911           { "Channel", "rlc.channel",
2912             FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }
2913         },
2914         { &hf_rlc_channel_rbid,
2915           { "Radio Bearer ID", "rlc.channel.rbid",
2916             FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }
2917         },
2918         { &hf_rlc_channel_dir,
2919           { "Direction", "rlc.channel.dir",
2920             FT_UINT8, BASE_DEC, VALS(rlc_dir_vals), 0, NULL, HFILL }
2921         },
2922         { &hf_rlc_channel_ueid,
2923           { "User Equipment ID", "rlc.channel.ueid",
2924             FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }
2925         }
2926     };
2927     static gint *ett[] = {
2928         &ett_rlc,
2929         &ett_rlc_frag,
2930         &ett_rlc_fragments,
2931         &ett_rlc_sdu,
2932         &ett_rlc_sufi,
2933         &ett_rlc_bitmap,
2934         &ett_rlc_rlist,
2935         &ett_rlc_channel
2936     };
2937     static ei_register_info ei[] = {
2938         { &ei_rlc_reassembly_fail_unfinished_sequence, { "rlc.reassembly.fail.unfinished_sequence", PI_REASSEMBLE, PI_ERROR, "Did not perform reassembly because of previous unfinished sequence.", EXPFILL }},
2939         { &ei_rlc_reassembly_fail_flag_set, { "rlc.reassembly.fail.flag_set", PI_REASSEMBLE, PI_ERROR, "Did not perform reassembly because fail flag was set previously.", EXPFILL }},
2940         { &ei_rlc_reassembly_lingering_endpoint, { "rlc.lingering_endpoint", PI_REASSEMBLE, PI_ERROR, "Lingering endpoint.", EXPFILL }},
2941         { &ei_rlc_reassembly_unknown_error, { "rlc.reassembly.unknown_error", PI_REASSEMBLE, PI_ERROR, "Unknown error.", EXPFILL }},
2942         { &ei_rlc_kasumi_implementation_missing, { "rlc.kasumi_implementation_missing", PI_UNDECODED, PI_WARN, "Unable to decipher packet since KASUMI implementation is missing.", EXPFILL }},
2943         { &ei_rlc_li_reserved, { "rlc.li.reserved", PI_PROTOCOL, PI_WARN, "Uses reserved LI", EXPFILL }},
2944         { &ei_rlc_li_incorrect_warn, { "rlc.li.incorrect", PI_PROTOCOL, PI_WARN, "Incorrect LI value", EXPFILL }},
2945         { &ei_rlc_li_incorrect_mal, { "rlc.li.incorrect", PI_MALFORMED, PI_ERROR, "Incorrect LI value 0x%x", EXPFILL }},
2946         { &ei_rlc_li_too_many, { "rlc.li.too_many", PI_MALFORMED, PI_ERROR, "Too many LI entries", EXPFILL }},
2947         { &ei_rlc_header_only, { "rlc.header_only.expert", PI_SEQUENCE, PI_NOTE, "RLC PDU SDUs have been omitted", EXPFILL }},
2948         { &ei_rlc_sufi_len, { "rlc.sufi.len.invalid", PI_MALFORMED, PI_ERROR, "Invalid length", EXPFILL }},
2949         { &ei_rlc_sufi_cw, { "rlc.sufi.cw.invalid", PI_PROTOCOL, PI_WARN, "Invalid last codeword", EXPFILL }},
2950         { &ei_rlc_sufi_type, { "rlc.sufi.type.invalid", PI_PROTOCOL, PI_WARN, "Invalid SUFI type", EXPFILL }},
2951         { &ei_rlc_reserved_bits_not_zero, { "rlc.reserved_bits_not_zero", PI_PROTOCOL, PI_WARN, "reserved bits not zero", EXPFILL }},
2952         { &ei_rlc_ctrl_type, { "rlc.ctrl_pdu_type.invalid", PI_PROTOCOL, PI_WARN, "Invalid RLC AM control type %u", EXPFILL }},
2953         { &ei_rlc_he, { "rlc.he.invalid", PI_PROTOCOL, PI_WARN, "Incorrect HE value", EXPFILL }},
2954     };
2955
2956     proto_rlc = proto_register_protocol("Radio Link Control", "RLC", "rlc");
2957     register_dissector("rlc.bcch",        dissect_rlc_bcch,        proto_rlc);
2958     register_dissector("rlc.pcch",        dissect_rlc_pcch,        proto_rlc);
2959     register_dissector("rlc.ccch",        dissect_rlc_ccch,        proto_rlc);
2960     register_dissector("rlc.ctch",        dissect_rlc_ctch,        proto_rlc);
2961     register_dissector("rlc.dcch",        dissect_rlc_dcch,        proto_rlc);
2962     register_dissector("rlc.ps_dtch",     dissect_rlc_ps_dtch,     proto_rlc);
2963     register_dissector("rlc.dch_unknown", dissect_rlc_dch_unknown, proto_rlc);
2964
2965     proto_register_field_array(proto_rlc, hf, array_length(hf));
2966     proto_register_subtree_array(ett, array_length(ett));
2967     expert_rlc = expert_register_protocol(proto_rlc);
2968     expert_register_field_array(expert_rlc, ei, array_length(ei));
2969
2970     /* Preferences */
2971     rlc_module = prefs_register_protocol(proto_rlc, NULL);
2972
2973     prefs_register_bool_preference(rlc_module, "heuristic_rlc_over_udp",
2974         "Try Heuristic RLC over UDP framing",
2975         "When enabled, use heuristic dissector to find RLC frames sent with "
2976         "UDP framing",
2977         &global_rlc_heur);
2978
2979     prefs_register_bool_preference(rlc_module, "perform_reassembly",
2980         "Try to reassemble SDUs",
2981         "When enabled, try to reassemble SDUs from the various PDUs received",
2982         &global_rlc_perform_reassemby);
2983
2984     prefs_register_bool_preference(rlc_module, "header_only_mode",
2985         "May see RLC headers only",
2986         "When enabled, if data is not present, don't report as an error, but instead "
2987         "add expert info to indicate that headers were omitted",
2988         &global_rlc_headers_expected);
2989
2990     prefs_register_bool_preference(rlc_module, "ciphered_data",
2991         "Ciphered data",
2992         "When enabled, rlc will assume all data is ciphered",
2993         &global_rlc_ciphered);
2994
2995     prefs_register_bool_preference(rlc_module, "try_decipher",
2996         "Try to Decipher data",
2997         "When enabled, rlc will try to decipher data. (Experimental)",
2998         &global_rlc_try_decipher);
2999
3000     prefs_register_enum_preference(rlc_module, "li_size",
3001         "LI size",
3002         "LI size in bits, either 7 or 15 bit",
3003         &global_rlc_li_size, li_size_enumvals, FALSE);
3004
3005 #ifdef HAVE_UMTS_KASUMI
3006     prefs_register_string_preference(rlc_module, "kasumi_key",
3007         "KASUMI key", "Key for kasumi 32 characters long hex-string", &global_rlc_kasumi_key);
3008 #endif /* HAVE_UMTS_KASUMI */
3009
3010     register_init_routine(fragment_table_init);
3011 }
3012
3013 void
3014 proto_reg_handoff_rlc(void)
3015 {
3016     rrc_handle = find_dissector("rrc");
3017     ip_handle  = find_dissector("ip");
3018     bmc_handle = find_dissector("bmc");
3019     /* Add as a heuristic UDP dissector */
3020     heur_dissector_add("udp", dissect_rlc_heur, proto_rlc);
3021 }
3022
3023 /*
3024  * Editor modelines
3025  *
3026  * Local Variables:
3027  * c-basic-offset: 4
3028  * tab-width: 8
3029  * indent-tabs-mode: nil
3030  * End:
3031  *
3032  * ex: set shiftwidth=4 tabstop=8 expandtab:
3033  * :indentSize=4:tabSize=8:noTabs=true:
3034  */