~ubuntu-branches/ubuntu/gutsy/wireshark/gutsy-security

« back to all changes in this revision

Viewing changes to epan/dissectors/packet-iuup.c

  • Committer: Bazaar Package Importer
  • Author(s): Frederic Peters
  • Date: 2007-04-01 08:58:40 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20070401085840-or3qhrpv8alt1bwg
Tags: 0.99.5-1
* New upstream release.
* debian/patches/09_idl2wrs.dpatch: updated to patch idl2wrs.sh.in.

Show diffs side-by-side

added added

removed removed

Lines of Context:
3
3
 *
4
4
 * (c) 2005 Luis E. Garcia Ontanon <luis.ontanon@gmail.com>
5
5
 *
6
 
 * $Id: $
 
6
 * $Id$
7
7
 *
8
8
 * Wireshark - Network traffic analyzer
9
9
 * By Gerald Combs <gerald@wireshark.org>
21
21
 *
22
22
 * You should have received a copy of the GNU General Public License
23
23
 * along with this program; if not, write to the Free Software
24
 
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
24
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
25
25
 */
26
26
 
27
27
 
28
28
/*
29
 
 TO DO:
30
 
 - verify crc6(hdr) and crc10(payload)
31
 
    - write crc6
32
 
    - is the crc10 the same used for ATM OAM cells?
 
29
   Patch by Polystar (Peter Vestman, Petter Edblom):
 
30
        Corrected rfci handling in rate control messages
 
31
        Added crc6 and crc10 checks for header and payload
33
32
*/
34
33
 
35
34
#ifdef HAVE_CONFIG_H
43
42
#include <epan/tvbuff.h>
44
43
#include <epan/prefs.h>
45
44
#include <epan/emem.h>
 
45
#include <epan/expert.h>
46
46
 
47
47
 
48
48
typedef struct _iuup_rfci_t {
72
72
static int hf_iuup_fqc = -1;
73
73
static int hf_iuup_rfci = -1;
74
74
static int hf_iuup_hdr_crc = -1;
 
75
static int hf_iuup_hdr_crc_error = -1;
75
76
static int hf_iuup_payload_crc = -1;
 
77
static int hf_iuup_payload_crc_error = -1;
76
78
 
77
79
static int hf_iuup_ack_nack = -1;
78
80
static int hf_iuup_frame_number_t14 = -1;
318
320
    {3, "spare"},
319
321
    {0,NULL}
320
322
};
 
323
/*
 
324
 * Charles Michael Heard's CRC-10 code, from
 
325
 *
 
326
 *      http://cell-relay.indiana.edu/cell-relay/publications/software/CRC/crc10.html
 
327
 *
 
328
 * with the CRC table initialized with values computed by
 
329
 * his "gen_byte_crc10_table()" routine, rather than by calling that
 
330
 * routine at run time, and with various data type cleanups.
 
331
 */
 
332
static const guint16 byte_crc10_table[256] = {
 
333
        0x0000, 0x0233, 0x0255, 0x0066, 0x0299, 0x00aa, 0x00cc, 0x02ff,
 
334
        0x0301, 0x0132, 0x0154, 0x0367, 0x0198, 0x03ab, 0x03cd, 0x01fe,
 
335
        0x0031, 0x0202, 0x0264, 0x0057, 0x02a8, 0x009b, 0x00fd, 0x02ce,
 
336
        0x0330, 0x0103, 0x0165, 0x0356, 0x01a9, 0x039a, 0x03fc, 0x01cf,
 
337
        0x0062, 0x0251, 0x0237, 0x0004, 0x02fb, 0x00c8, 0x00ae, 0x029d,
 
338
        0x0363, 0x0150, 0x0136, 0x0305, 0x01fa, 0x03c9, 0x03af, 0x019c,
 
339
        0x0053, 0x0260, 0x0206, 0x0035, 0x02ca, 0x00f9, 0x009f, 0x02ac,
 
340
        0x0352, 0x0161, 0x0107, 0x0334, 0x01cb, 0x03f8, 0x039e, 0x01ad,
 
341
        0x00c4, 0x02f7, 0x0291, 0x00a2, 0x025d, 0x006e, 0x0008, 0x023b,
 
342
        0x03c5, 0x01f6, 0x0190, 0x03a3, 0x015c, 0x036f, 0x0309, 0x013a,
 
343
        0x00f5, 0x02c6, 0x02a0, 0x0093, 0x026c, 0x005f, 0x0039, 0x020a,
 
344
        0x03f4, 0x01c7, 0x01a1, 0x0392, 0x016d, 0x035e, 0x0338, 0x010b,
 
345
        0x00a6, 0x0295, 0x02f3, 0x00c0, 0x023f, 0x000c, 0x006a, 0x0259,
 
346
        0x03a7, 0x0194, 0x01f2, 0x03c1, 0x013e, 0x030d, 0x036b, 0x0158,
 
347
        0x0097, 0x02a4, 0x02c2, 0x00f1, 0x020e, 0x003d, 0x005b, 0x0268,
 
348
        0x0396, 0x01a5, 0x01c3, 0x03f0, 0x010f, 0x033c, 0x035a, 0x0169,
 
349
        0x0188, 0x03bb, 0x03dd, 0x01ee, 0x0311, 0x0122, 0x0144, 0x0377,
 
350
        0x0289, 0x00ba, 0x00dc, 0x02ef, 0x0010, 0x0223, 0x0245, 0x0076,
 
351
        0x01b9, 0x038a, 0x03ec, 0x01df, 0x0320, 0x0113, 0x0175, 0x0346,
 
352
        0x02b8, 0x008b, 0x00ed, 0x02de, 0x0021, 0x0212, 0x0274, 0x0047,
 
353
        0x01ea, 0x03d9, 0x03bf, 0x018c, 0x0373, 0x0140, 0x0126, 0x0315,
 
354
        0x02eb, 0x00d8, 0x00be, 0x028d, 0x0072, 0x0241, 0x0227, 0x0014,
 
355
        0x01db, 0x03e8, 0x038e, 0x01bd, 0x0342, 0x0171, 0x0117, 0x0324,
 
356
        0x02da, 0x00e9, 0x008f, 0x02bc, 0x0043, 0x0270, 0x0216, 0x0025,
 
357
        0x014c, 0x037f, 0x0319, 0x012a, 0x03d5, 0x01e6, 0x0180, 0x03b3,
 
358
        0x024d, 0x007e, 0x0018, 0x022b, 0x00d4, 0x02e7, 0x0281, 0x00b2,
 
359
        0x017d, 0x034e, 0x0328, 0x011b, 0x03e4, 0x01d7, 0x01b1, 0x0382,
 
360
        0x027c, 0x004f, 0x0029, 0x021a, 0x00e5, 0x02d6, 0x02b0, 0x0083,
 
361
        0x012e, 0x031d, 0x037b, 0x0148, 0x03b7, 0x0184, 0x01e2, 0x03d1,
 
362
        0x022f, 0x001c, 0x007a, 0x0249, 0x00b6, 0x0285, 0x02e3, 0x00d0,
 
363
        0x011f, 0x032c, 0x034a, 0x0179, 0x0386, 0x01b5, 0x01d3, 0x03e0,
 
364
        0x021e, 0x002d, 0x004b, 0x0278, 0x0087, 0x02b4, 0x02d2, 0x00e1
 
365
};
 
366
 
 
367
/* update the data block's CRC-10 remainder one byte at a time */
 
368
static guint16
 
369
update_crc10_by_bytes(guint16 crc10, const guint8 *data_blk_ptr,
 
370
                      int data_blk_size)
 
371
{
 
372
    register int i;
 
373
    guint16 crc10_accum = 0;
 
374
 
 
375
    for (i = 0;  i < data_blk_size; i++) {
 
376
        crc10_accum = ((crc10_accum << 8) & 0x3ff)
 
377
                ^ byte_crc10_table[( crc10_accum >> 2) & 0xff]
 
378
                ^ *data_blk_ptr++;
 
379
    }
 
380
    crc10_accum = ((crc10_accum << 8) & 0x3ff)
 
381
                    ^ byte_crc10_table[( crc10_accum >> 2) & 0xff]
 
382
                    ^ (crc10>>2);
 
383
    crc10_accum = ((crc10_accum << 8) & 0x3ff)
 
384
                    ^ byte_crc10_table[( crc10_accum >> 2) & 0xff]
 
385
                    ^ ((crc10<<6) & 0xFF);
 
386
    
 
387
    return crc10_accum;
 
388
}
 
389
 
 
390
 
 
391
static guint16
 
392
update_crc6_by_bytes(guint16 crc6, unsigned char byte1, unsigned char byte2)
 
393
{
 
394
    char bit;
 
395
    unsigned int remainder = 0;
 
396
    unsigned int polynomial = 0x6F << 15;
 
397
 
 
398
    unsigned int data = ( byte1<<8 | byte2 ) << 6;
 
399
    remainder = data;
 
400
 
 
401
    for (bit = 15; bit >= 0; --bit)
 
402
    {
 
403
        if (remainder & (0x40 << bit))
 
404
        {
 
405
            remainder ^= polynomial;
 
406
        }
 
407
        polynomial >>= 1;
 
408
    }
 
409
 
 
410
    return (remainder ^ crc6);
 
411
}
 
412
 
321
413
 
322
414
static proto_item*
323
415
proto_tree_add_bits(proto_tree* tree, int hf, tvbuff_t* tvb, int offset, int bit_offset, guint bits, gchar** buf) {
545
637
}
546
638
 
547
639
static void dissect_iuup_ratectl(tvbuff_t* tvb, packet_info* pinfo _U_, proto_tree* tree) {
548
 
    guint num = tvb_get_guint8(tvb,3) & 0x3f;
 
640
    guint num = tvb_get_guint8(tvb,4) & 0x3f;
549
641
    guint i;
550
642
    proto_item* pi;
551
643
    proto_tree* inds_tree;
552
 
    int offset = 2;
 
644
    int offset = 4;
553
645
    
554
 
    pi = proto_tree_add_item(tree,hf_iuup_num_rfci_ind,tvb,3,1,FALSE);
 
646
    pi = proto_tree_add_item(tree,hf_iuup_num_rfci_ind,tvb,4,1,FALSE);
555
647
    inds_tree = proto_item_add_subtree(pi,ett_rfciinds);
556
648
    
557
649
    for (i = 0; i < num; i++) {
561
653
    
562
654
}
563
655
 
 
656
proto_item *add_hdr_crc(tvbuff_t* tvb, packet_info* pinfo, proto_item* iuup_tree, guint16 crccheck)
 
657
{
 
658
   proto_item *crc_item;
 
659
   if (crccheck) {
 
660
      crc_item = proto_tree_add_item(iuup_tree,hf_iuup_hdr_crc_error,tvb,2,1,FALSE);
 
661
      expert_add_info_format(pinfo, crc_item, PI_CHECKSUM, PI_ERROR, "Bad checksum");
 
662
   } else {
 
663
      crc_item = proto_tree_add_item(iuup_tree,hf_iuup_hdr_crc,tvb,2,1,FALSE);
 
664
   }
 
665
   return crc_item;
 
666
}
 
667
 
 
668
proto_item *add_payload_crc(tvbuff_t* tvb, packet_info* pinfo, proto_item* iuup_tree)
 
669
{
 
670
   proto_item *crc_item;
 
671
   int length = tvb_length(tvb);
 
672
   guint16 crc10 = tvb_get_ntohs(tvb, 2) & 0x3FF;
 
673
   guint16 crccheck = update_crc10_by_bytes(crc10, tvb_get_ptr(tvb, 4, length - 4), length - 4);
 
674
   if (crccheck) {
 
675
      crc_item = proto_tree_add_item(iuup_tree,hf_iuup_payload_crc_error,tvb,2,2,FALSE);
 
676
      expert_add_info_format(pinfo, crc_item, PI_CHECKSUM, PI_ERROR, "Bad checksum");
 
677
   } else {
 
678
      crc_item = proto_tree_add_item(iuup_tree,hf_iuup_payload_crc,tvb,2,2,FALSE);
 
679
   }
 
680
   return crc_item;
 
681
}
 
682
 
564
683
#define ACKNACK_MASK  0x0c
565
684
#define PROCEDURE_MASK  0x0f
566
685
#define FQC_MASK 0xc0
576
695
    guint8 second_octet;
577
696
    guint8 pdutype;
578
697
    guint phdr = 0;
 
698
    guint16  hdrcrc6;
 
699
    guint16  crccheck;
579
700
    tvbuff_t* tvb = tvb_in;
580
701
    
581
702
    if (check_col(pinfo->cinfo, COL_PROTOCOL))
600
721
    
601
722
    first_octet =  tvb_get_guint8(tvb,0);
602
723
    second_octet =  tvb_get_guint8(tvb,1);
 
724
    hdrcrc6 = tvb_get_guint8(tvb, 2) >> 2;
 
725
    crccheck = update_crc6_by_bytes(hdrcrc6, first_octet, second_octet);
 
726
    
603
727
    pdutype = ( first_octet & PDUTYPE_MASK ) >> 4;
604
728
    
605
729
    if (tree) {
629
753
            }
630
754
                
631
755
            proto_tree_add_item(iuup_tree,hf_iuup_rfci,tvb,1,1,FALSE);
632
 
            proto_tree_add_item(iuup_tree,hf_iuup_hdr_crc,tvb,2,1,FALSE);
633
 
            proto_tree_add_item(iuup_tree,hf_iuup_payload_crc,tvb,2,2,FALSE);
 
756
            add_hdr_crc(tvb, pinfo, iuup_tree, crccheck);
 
757
            add_payload_crc(tvb, pinfo, iuup_tree);
634
758
            dissect_iuup_payload(tvb,pinfo,iuup_tree,second_octet & 0x3f,4);
635
759
            return;
636
760
        case PDUTYPE_DATA_NO_CRC:
647
771
            }
648
772
                
649
773
            proto_tree_add_item(iuup_tree,hf_iuup_rfci,tvb,1,1,FALSE);
650
 
            proto_tree_add_item(iuup_tree,hf_iuup_hdr_crc,tvb,2,1,FALSE);
 
774
            add_hdr_crc(tvb, pinfo, iuup_tree, crccheck);
651
775
            dissect_iuup_payload(tvb,pinfo,iuup_tree,second_octet & 0x3f,3);
652
776
            return;
653
777
        case PDUTYPE_DATA_CONTROL_PROC:
656
780
                proto_tree_add_item(iuup_tree,hf_iuup_frame_number_t14,tvb,0,1,FALSE);
657
781
                proto_tree_add_item(iuup_tree,hf_iuup_mode_version,tvb,1,1,FALSE);
658
782
                proc_item = proto_tree_add_item(iuup_tree,hf_iuup_procedure_indicator,tvb,1,1,FALSE);
659
 
                proto_tree_add_item(iuup_tree,hf_iuup_hdr_crc,tvb,2,1,FALSE);
 
783
                add_hdr_crc(tvb, pinfo, iuup_tree, crccheck);
660
784
            }
661
785
            
662
786
            if (check_col(pinfo->cinfo, COL_INFO)) {
678
802
                            proto_tree_add_item(iuup_tree,hf_iuup_spare_ff,tvb,3,1,FALSE);
679
803
                            return;
680
804
                        case PROC_RATE:
 
805
                            if (!tree) return;
 
806
                            dissect_iuup_ratectl(tvb,pinfo,iuup_tree);
 
807
                            return;
681
808
                        case PROC_TIME:
682
809
                        case PROC_ERROR:
683
810
                            break;
702
829
            
703
830
            switch( second_octet & PROCEDURE_MASK ) {
704
831
                case PROC_INIT:
705
 
                    if (tree) proto_tree_add_item(iuup_tree,hf_iuup_payload_crc,tvb,2,2,FALSE);
 
832
                    if (tree) add_payload_crc(tvb, pinfo, iuup_tree);
706
833
                    dissect_iuup_init(tvb,pinfo,iuup_tree);
707
834
                    return;
708
835
                case PROC_RATE:
709
836
                    if (!tree) return;
 
837
                    add_payload_crc(tvb, pinfo, iuup_tree);
710
838
                    dissect_iuup_ratectl(tvb,pinfo,iuup_tree);
711
839
                    return;
712
840
                case PROC_TIME:
765
893
    circuits = g_hash_table_new(g_direct_hash,g_direct_equal);
766
894
 
767
895
    if (!iuup_prefs_initialized) {
768
 
                iuup_prefs_initialized = TRUE;
769
 
    } else {
770
 
        if ( dynamic_payload_type > 95 )
 
896
        iuup_prefs_initialized = TRUE;
 
897
    } else if ( dynamic_payload_type > 95 ) {
771
898
            dissector_delete("rtp.pt", dynamic_payload_type, iuup_handle);
772
 
        }
 
899
    }
773
900
    
774
901
    dynamic_payload_type = temp_dynamic_payload_type;
775
902
    
776
 
    if ( dynamic_payload_type > 95 ){
777
 
                dissector_add("rtp.pt", dynamic_payload_type, iuup_handle);
778
 
        }
 
903
    if ( dynamic_payload_type > 95 ) {
 
904
        dissector_add("rtp.pt", dynamic_payload_type, iuup_handle);
 
905
    }
779
906
    
780
907
    dissector_add_string("rtp_dyn_payload_type","VND.3GPP.IUFP", iuup_handle);
781
908
 
788
915
 
789
916
 
790
917
#define HFS_RFCI(i) \
791
 
{ &hf_iuup_rfci_ratectl[i], { "RFCI " #i, "iuup.rfci." #i, FT_UINT8, BASE_DEC, VALS(iuup_rfci_indicator),1<<(i%8),"",HFILL}}, \
 
918
{ &hf_iuup_rfci_ratectl[i], { "RFCI " #i, "iuup.rfci." #i, FT_UINT8, BASE_DEC, VALS(iuup_rfci_indicator),0x80>>(i%8),"",HFILL}}, \
792
919
{ &hf_iuup_init_rfci[i], { "RFCI " #i, "iuup.rfci." #i, FT_UINT8, BASE_DEC, NULL,0x3f,"",HFILL}}, \
793
920
{ &hf_iuup_init_rfci_flow_len[i][0], { "RFCI " #i " Flow 0 Len", "iuup.rfci."#i".flow.0.len", FT_UINT16, BASE_DEC, NULL,0x0,"",HFILL}}, \
794
921
{ &hf_iuup_init_rfci_flow_len[i][1], { "RFCI " #i " Flow 1 Len", "iuup.rfci."#i".flow.1.len", FT_UINT16, BASE_DEC, NULL,0x0,"",HFILL}}, \
821
948
        { &hf_iuup_fqc, { "FQC", "iuup.fqc", FT_UINT8, BASE_DEC, VALS(iuup_fqcs),0xc0,"Frame Quality Classification",HFILL}},
822
949
        { &hf_iuup_rfci, { "RFCI", "iuup.rfci", FT_UINT8, BASE_HEX, NULL, 0x3f, "RAB sub-Flow Combination Indicator",HFILL}},
823
950
        { &hf_iuup_hdr_crc, { "Header CRC", "iuup.header_crc", FT_UINT8, BASE_HEX, NULL,0xfc,"",HFILL}},        
 
951
        { &hf_iuup_hdr_crc_error, { "Header CRC [incorrect]", "iuup.header_crc", FT_UINT8, BASE_HEX, NULL,0xfc,"",HFILL}},        
824
952
        { &hf_iuup_payload_crc, { "Payload CRC", "iuup.payload_crc", FT_UINT16, BASE_HEX, NULL,0x03FF,"",HFILL}},
 
953
        { &hf_iuup_payload_crc_error, { "Payload CRC [incorrect]", "iuup.payload_crc", FT_UINT16, BASE_HEX, NULL,0x03FF,"",HFILL}},
825
954
        { &hf_iuup_ack_nack, { "Ack/Nack", "iuup.ack", FT_UINT8, BASE_DEC, VALS(iuup_acknack_vals),0x0c,"Ack/Nack",HFILL}},
826
955
        { &hf_iuup_frame_number_t14, { "Frame Number", "iuup.framenum", FT_UINT8, BASE_DEC, NULL,0x03,"",HFILL}},
827
956
        { &hf_iuup_mode_version, { "Mode Version", "iuup.mode", FT_UINT8, BASE_HEX, NULL,0xf0,"",HFILL}},
898
1027
 
899
1028
    
900
1029
    proto_iuup = proto_register_protocol("IuUP", "IuUP", "iuup");
901
 
        proto_register_field_array(proto_iuup, hf, array_length(hf));
902
 
        proto_register_subtree_array(ett, array_length(ett));
 
1030
    proto_register_field_array(proto_iuup, hf, array_length(hf));
 
1031
    proto_register_subtree_array(ett, array_length(ett));
903
1032
    register_dissector("iuup", dissect_iuup, proto_iuup);
904
1033
    register_init_routine(&init_iuup);
905
1034
    
906
 
        iuup_handle = create_dissector_handle(dissect_iuup, proto_iuup);
 
1035
    iuup_handle = create_dissector_handle(dissect_iuup, proto_iuup);
907
1036
 
908
1037
    iuup_module = prefs_register_protocol(proto_iuup, init_iuup);
909
1038