func: static rlc_um_reassemble(tvbuff_t *tvb, guint8 offs, packet_info *pinfo, proto_tree proto_tree *top_level, enum rlc_channel_type channel, guint16 struct rlc_li *li, guint16 num_li, gboolean li_is_on_2_bytes) guint8 i ; gint length ; for (i = 0; i < num_li; i++) if ( ( ! li_is_on_2_bytes && ( li [ i ] . li == 0x7f ) ) || ( li [ i ] . li == 0x7fff ) )  offs += tvb_captured_length_remaining ( tvb , offs ); if ( ( ! li_is_on_2_bytes && ( li [ i ] . li == 0x7c ) ) || ( li [ i ] . li == 0x7ffc ) )  if ( li [ i ] . li == 0x7ffa )  length = tvb_reported_length_remaining ( tvb , offs ); if ( length > 1 )  length --; if ( global_rlc_perform_reassemby )  add_fragment ( RLC_UM , tvb , pinfo , li [ i ] . tree , offs , seq , i , length , TRUE ); offs += length; offs += 1; offs += li [ i ] . len; static struct rlc_frag add_fragment(enum rlc_mode mode, tvbuff_t *tvb, packet_info proto_tree *tree, guint16 offset, guint16 seq, guint16 guint16 len, gboolean final) struct rlc_channel ch_lookup ; int snmod ; if ( rlc_channel_assign ( & ch_lookup , mode , pinfo ) == - 1 )  static rlc_channel_assign(struct rlc_channel *ch, enum rlc_mode mode, packet_info *pinfo) struct atm_phdr * atm ; rlc_info * rlcinf ; fp_info * fpinf ; atm = & pinfo -> pseudo_header -> atm; fpinf = ( fp_info * ) p_get_proto_data ( wmem_file_scope ( ) , pinfo , proto_fp , 0 ); rlcinf = ( rlc_info * ) p_get_proto_data ( wmem_file_scope ( ) , pinfo , proto_rlc , 0 ); if ( ! fpinf || ! rlcinf )  return - 1 ; if ( rlcinf -> urnti [ fpinf -> cur_tb ] )  if ( ! atm )  return - 1 ; return 0 ; snmod = getChannelSNModulus ( & ch_lookup ); static guint16 getChannelSNModulus(struct rlc_channel * ch_lookup) if ( RLC_UM == ch_lookup -> mode )  return 128 ; return 4096 ; if ( g_hash_table_lookup_extended ( reassembled_table , & frag_lookup , & orig_key , & value ) )  frags = get_frags ( pinfo , & ch_lookup ); static struct rlc_frag get_frags(packet_info * pinfo, struct rlc_channel * ch_lookup) gpointer value = NULL ; if ( g_hash_table_lookup_extended ( fragment_table , ch_lookup , NULL , & value ) )  frags = ( struct rlc_frag * * ) value; if ( pinfo != NULL )  frags = ( struct rlc_frag * * ) wmem_alloc0 ( wmem_file_scope ( ) , sizeof ( struct rlc_frag * ) * 4096 ); return NULL ; return frags ; endlist = get_endlist ( pinfo , & ch_lookup ); static struct rlc_seqlist get_endlist(packet_info * pinfo, struct rlc_channel * ch_lookup) gpointer value = NULL ; struct rlc_seqlist * endlist = NULL ; if ( g_hash_table_lookup_extended ( endpoints , ch_lookup , NULL , & value ) )  endlist = ( struct rlc_seqlist * ) value; if ( pinfo != NULL )  return NULL ; return endlist ; if ( pinfo -> fd -> flags . visited )  if ( endlist -> fail_packet != 0 )  frag = rlc_frag_create ( tvb , mode , pinfo , offset , len , seq , num_li ); static struct rlc_frag rlc_frag_create(tvbuff_t *tvb, enum rlc_mode mode, packet_info guint16 offset, guint16 length, guint16 seq, guint16 li) struct rlc_frag * frag ; frag = ( struct rlc_frag * ) wmem_alloc0 ( wmem_file_scope ( ) , sizeof ( struct rlc_frag ) ); return frag ; if ( frags [ seq ] != NULL )  if ( num_li > 0 )  frags [ seq ] = frag; if ( endlist -> list && num_li != 0 )  gint16 first = GPOINTER_TO_INT ( endlist -> list -> data ) ; if ( seq == first )  endlist -> list -> data = GINT_TO_POINTER ( first - 1 ); if ( final )  endlist -> list = g_list_append ( endlist -> list , GINT_TO_POINTER ( ( gint ) seq ) ); if ( endlist -> list && endlist -> list -> next )  gint16 start = ( GPOINTER_TO_INT ( endlist -> list -> data ) + 1 ) % snmod ; gint16 end = GPOINTER_TO_INT ( endlist -> list -> next -> data ) ; if ( frags [ end ] == NULL )  if ( start == end && frags [ start ] -> len == 0 )  frags [ start ] = frags [ start ] -> next; for (;  moduloCompare(start,end,snmod ) < 0; start = (start+1)%snmod) static int moduloCompare(guint16 a, guint16 b, guint16 modulus) int ret ; a = a % modulus; b = b % modulus; if ( a <= b )  ret = a - b; ret = a - ( b + modulus ); if ( ret == ( 1 - modulus ) )  ret = 1; return ret ; if ( frags [ start ] == NULL )  start = ( GPOINTER_TO_INT ( endlist -> list -> data ) + 1 ) % snmod; reassemble_sequence ( frags , endlist , & ch_lookup , start , end ); static reassemble_sequence(struct rlc_frag ** frags, struct rlc_seqlist * struct rlc_channel * ch_lookup, guint16 start, guint16 end) struct rlc_sdu * sdu = rlc_sdu_create ( ) ; static struct rlc_sdu rlc_sdu_create(void) struct rlc_sdu * sdu ; sdu = ( struct rlc_sdu * ) wmem_alloc0 ( wmem_file_scope ( ) , sizeof ( struct rlc_sdu ) ); return sdu ; reassemble_data ( ch_lookup , sdu , NULL ); static reassemble_data(struct rlc_channel *ch, struct rlc_sdu *sdu, struct rlc_frag *frag) struct rlc_frag * temp ; guint16 offs = 0 ; if ( ! sdu || ! ch || ! sdu -> frags )  if ( sdu -> data )  if ( frag )  sdu -> reassembled_in = frag; sdu -> reassembled_in = sdu -> last; sdu -> data = ( guint8 * ) wmem_alloc ( wmem_file_scope ( ) , sdu -> len ); temp = sdu -> frags; while ( temp && ( ( offs + temp -> len ) <= sdu -> len ) )  memcpy ( sdu -> data + offs , temp -> data , temp -> len ); temp -> data = NULL; g_hash_table_insert ( reassembled_table , temp , sdu ); offs += temp -> len; temp = temp -> next; 