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

« back to all changes in this revision

Viewing changes to epan/dissectors/packet-catapult-dct2000.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:
1
1
/* packet-catapult-dct2000.c
2
2
 * Routines for Catapult DCT2000 packet stub header disassembly
3
3
 *
4
 
 * $Id: packet-catapult-dct2000.c 19439 2006-10-05 14:10:10Z martinm $
 
4
 * $Id: packet-catapult-dct2000.c 20266 2007-01-02 13:25:36Z martinm $
5
5
 *
6
6
 * Wireshark - Network traffic analyzer
7
7
 * By Gerald Combs <gerald@wireshark.org>
26
26
# include "config.h"
27
27
#endif
28
28
 
 
29
#include <glib.h>
 
30
 
29
31
#include <string.h>
30
32
#include <ctype.h>
31
33
#include <epan/packet.h>
50
52
static int hf_catapult_dct2000_direction = -1;
51
53
static int hf_catapult_dct2000_encap = -1;
52
54
static int hf_catapult_dct2000_unparsed_data = -1;
 
55
static int hf_catapult_dct2000_dissected_length = -1;
53
56
 
54
57
static int hf_catapult_dct2000_ipprim_addresses = -1;
55
58
static int hf_catapult_dct2000_ipprim_src_addr = -1;
86
89
    { DCT2000_ENCAP_SSCOP,               "SSCOP" },
87
90
    { WTAP_ENCAP_FRELAY,                 "Frame Relay" },
88
91
    { WTAP_ENCAP_MTP2,                   "MTP2" },
 
92
    { DCT2000_ENCAP_NBAP,                "NBAP" },
89
93
    { DCT2000_ENCAP_UNHANDLED,           "Unhandled Protocol" },
90
94
    { 0,                                 NULL },
91
95
};
103
107
void proto_register_catapult_dct2000(void);
104
108
 
105
109
static dissector_handle_t look_for_dissector(char *protocol_name);
 
110
static void parse_outhdr_string(guchar *outhdr_string);
 
111
static void attach_fp_info(packet_info *pinfo, gboolean received,
 
112
                           const char *protocol_name, int variant);
106
113
 
107
114
 
108
115
/* Look for the protocol data within an ipprim packet.
109
116
   Only set *data_offset if data field found. */
110
117
static gboolean find_ipprim_data_offset(tvbuff_t *tvb, int *data_offset,
111
 
                                        guint32 *source_addr, guint32 *dest_addr,
112
 
                                        guint16 *source_port, guint16 *dest_port,
 
118
                                        guint32 *source_addr_offset, guint32 *dest_addr_offset,
 
119
                                        guint32 *source_port_offset, guint32 *dest_port_offset,
113
120
                                        port_type *type_of_port)
114
121
{
115
122
    guint8 length;
154
161
            if (tag == 0x31 && length >=4 && length <= 6)
155
162
            {
156
163
                /* Dest IP address */
157
 
                *dest_addr = tvb_get_ipv4(tvb, offset);
 
164
                *dest_addr_offset = offset;
158
165
 
159
166
                /* Dest port follows (if present) */
160
167
                if (length > 4)
161
168
                {
162
 
                    *dest_port = tvb_get_ntohs(tvb, offset+4);
 
169
                    *dest_port_offset = offset + 4;
163
170
                }
164
171
            }
165
172
            if (tag == 0x32 && length == 4)
166
173
            {
167
174
                /* Source IP address */
168
 
                *source_addr = tvb_get_ipv4(tvb, offset);
 
175
                *source_addr_offset = offset;
169
176
            }
170
177
            if (tag == 0x33 && length == 2)
171
178
            {
172
179
                /* Get source port */
173
 
                *source_port = tvb_get_ntohs(tvb, offset);
 
180
                *source_port_offset = offset;
174
181
            }
175
182
 
176
183
            /* Skip the following value */
192
199
    int offset = *data_offset;
193
200
 
194
201
    /* Get the sctpprim command code. */
195
 
    guint8 tag = tvb_get_guint8(tvb, offset++);
 
202
    guint8 first_tag = tvb_get_guint8(tvb, offset++);
 
203
    guint8 tag;
196
204
 
197
205
    /* Only accept interested in data requests or indications */
198
 
    switch (tag)
 
206
    switch (first_tag)
199
207
    {
200
208
        case 0x04:  /* data request */
201
209
        case 0x62:  /* data indication */
204
212
            return FALSE;
205
213
    }
206
214
 
207
 
    /* Length field. msb set indicates 2 bytes */
208
 
    if (tvb_get_guint8(tvb, offset) & 0x80)
 
215
    if (first_tag == 0x04)
209
216
    {
210
 
        offset += 2;
 
217
        /* Overall length field. msb set indicates 2 bytes */
 
218
        if (tvb_get_guint8(tvb, offset) & 0x80)
 
219
        {
 
220
            offset += 2;
 
221
        }
 
222
        else
 
223
        {
 
224
            offset++;
 
225
        }
211
226
    }
212
227
    else
213
228
    {
214
 
        offset++;
 
229
        offset += 3;
215
230
    }
216
231
 
217
 
    /* Skip any other TLC fields before reach payload */
 
232
    /* Skip any other fields before reach payload */
218
233
    while (tvb_length_remaining(tvb, offset) > 2)
219
234
    {
220
235
        /* Look at next tag */
228
243
        }
229
244
        else
230
245
        {
231
 
            /* Read length in next byte */
232
 
            length = tvb_get_guint8(tvb, offset++);
233
 
            /* Skip the following value */
234
 
            offset += length;
 
246
            if (first_tag == 0x62)
 
247
            {
 
248
                switch (tag)
 
249
                {
 
250
                    case 0x0a: /* dest port */
 
251
                    case 0x1e: /* strseqnum */
 
252
                    case 0x0d:
 
253
                        offset += 2;
 
254
                        continue;
 
255
                    case 0x1d:
 
256
                    case 0x09:
 
257
                    case 0x0c:
 
258
                        offset += 4;
 
259
                        continue;
 
260
                }
 
261
            }
 
262
            else
 
263
            {
 
264
                /* Read length in next byte */
 
265
                length = tvb_get_guint8(tvb, offset++);
 
266
                /* Skip the following value */
 
267
                offset += length;
 
268
            }
235
269
        }
236
270
    }
237
271
 
282
316
            /* 2-byte length field */
283
317
            offset += 2;
284
318
 
 
319
            /* Skip 2-byte length field */
 
320
            offset += 2;
 
321
 
285
322
            /* Data is here!!! */
286
323
            *data_offset = offset;
287
324
            return TRUE;
354
391
    else
355
392
    if ((strcmp(protocol_name, "xcap_caps") == 0) ||
356
393
        (strcmp(protocol_name, "mm1") == 0) ||
 
394
        (strcmp(protocol_name, "mm3") == 0) ||
357
395
        (strcmp(protocol_name, "mm7") == 0))
358
396
    {
359
397
        return find_dissector("http");
372
410
    {
373
411
        return find_dissector("rtp");
374
412
    }
 
413
    else
 
414
    if (strcmp(protocol_name, "sipt") == 0)
 
415
    {
 
416
        return find_dissector("sip");
 
417
    }
 
418
    else
 
419
    if (strncmp(protocol_name, "nbap_sctp", strlen("nbap_sctp")) == 0)
 
420
    {
 
421
        return find_dissector("nbap");
 
422
    }
 
423
    else
 
424
    if (strncmp(protocol_name, "gtp", strlen("gtp")) == 0)
 
425
    {
 
426
        return find_dissector("gtp");
 
427
    }
375
428
 
376
429
    /* Try for an exact match */
377
430
    else
382
435
 
383
436
 
384
437
/* Populate outhdr_values array with numbers found in outhdr_string */
385
 
void parse_outhdr_string(char *outhdr_string)
 
438
void parse_outhdr_string(guchar *outhdr_string)
386
439
{
387
440
    int n = 0;
388
441
 
393
446
        guint digits;
394
447
 
395
448
        /* Find digits */
396
 
        for (digits = 0; digits < strlen(outhdr_string); digits++, n++)
 
449
        for (digits = 0; digits < strlen((gchar*)outhdr_string); digits++, n++)
397
450
        {
398
451
            if (!isdigit(outhdr_string[n]))
399
452
            {
409
462
 
410
463
        /* Convert digits into value */
411
464
        outhdr_values[outhdr_values_found++] =
412
 
            atoi(format_text(outhdr_string+start_i, digits));
 
465
            atoi((char*)format_text((guchar*)outhdr_string+start_i, digits));
413
466
 
414
467
        /* Skip comma */
415
468
        n++;
632
685
    }
633
686
 
634
687
    /* Add useful details to protocol tree label */
635
 
    protocol_name = tvb_get_ephemeral_string(tvb, protocol_start, protocol_length);
 
688
    protocol_name = (char*)tvb_get_ephemeral_string(tvb, protocol_start, protocol_length);
636
689
    if (tree)
637
690
    {
638
691
        proto_item_append_text(ti, "   context=%s.%u   t=%s   %c   prot=%s (v=%s)",
653
706
    {
654
707
        parse_outhdr_string(tvb_get_ephemeral_string(tvb, outhdr_start, outhdr_length));
655
708
        attach_fp_info(pinfo, direction, protocol_name,
656
 
                       atoi(tvb_get_ephemeral_string(tvb, variant_start, variant_length)));
 
709
                       atoi((char*)tvb_get_ephemeral_string(tvb, variant_start, variant_length)));
657
710
    }
658
711
 
659
712
 
696
749
        case DCT2000_ENCAP_MTP2:
697
750
            protocol_handle = find_dissector("mtp2");
698
751
            break;
 
752
        case DCT2000_ENCAP_NBAP:
 
753
            protocol_handle = find_dissector("nbap");
 
754
            break;
699
755
        case DCT2000_ENCAP_UNHANDLED:
700
756
            /* Show context.port in src or dest column as appropriate */
701
757
            if (check_col(pinfo->cinfo, COL_DEF_SRC) && direction == 0)
723
779
            /* Try IP Prim heuristic if configured to */
724
780
            if (catapult_dct2000_try_ipprim_heuristic)
725
781
            {
726
 
                guint32 source_addr = 0, dest_addr = 0;
727
 
                guint16 source_port = 0, dest_port = 0;
 
782
                guint32 source_addr_offset = 0, dest_addr_offset = 0;
 
783
                guint32 source_port_offset = 0, dest_port_offset = 0;
728
784
                port_type type_of_port = PT_NONE;
 
785
                int offset_before_ipprim_header = offset;
729
786
 
730
787
                heur_protocol_handle = look_for_dissector(protocol_name);
731
788
                if ((heur_protocol_handle != 0) &&
732
 
                    find_ipprim_data_offset(tvb, &offset, &source_addr, &dest_addr,
733
 
                                            &source_port, &dest_port, &type_of_port))
 
789
                    find_ipprim_data_offset(tvb, &offset,
 
790
                                            &source_addr_offset, &dest_addr_offset,
 
791
                                            &source_port_offset, &dest_port_offset,
 
792
                                            &type_of_port))
734
793
                {
735
794
                    proto_tree *ipprim_tree;
736
795
                    proto_item *ti;
737
796
                    protocol_handle = heur_protocol_handle;
738
797
 
739
 
                    if (source_addr && check_col(pinfo->cinfo, COL_DEF_SRC))
 
798
                    if (source_addr_offset && check_col(pinfo->cinfo, COL_DEF_SRC))
740
799
                    {
741
800
                        col_append_fstr(pinfo->cinfo, COL_DEF_SRC,
742
 
                                        "(%s:%u)", (char*)get_hostname(source_addr), source_port);
 
801
                                        "(%s:%u)",
 
802
                                        (char*)get_hostname(tvb_get_ipv4(tvb, source_addr_offset)),
 
803
                                        tvb_get_ntohs(tvb, source_port_offset));
743
804
                    }
744
 
                    if (dest_addr && check_col(pinfo->cinfo, COL_DEF_DST))
 
805
                    if (dest_addr_offset && check_col(pinfo->cinfo, COL_DEF_DST))
745
806
                    {
746
807
                        col_append_fstr(pinfo->cinfo, COL_DEF_DST,
747
 
                                        "(%s:%u)", (char*)get_hostname(dest_addr), dest_port);
 
808
                                        "(%s:%u)",
 
809
                                        (char*)get_hostname(tvb_get_ipv4(tvb, dest_addr_offset)),
 
810
                                        tvb_get_ntohs(tvb, dest_port_offset));
748
811
                    }
749
812
 
750
813
                    /* Add address parameters to tree */
751
814
                    /* Unfortunately can't automatically create a conversation filter for this...
752
815
                       I could create a fake IP header from these details, but then it would be tricky
753
816
                       to get FP dissector called as it has no well-known ports or heuristics... */
754
 
                    ti =  proto_tree_add_string_format(dct2000_tree, hf_catapult_dct2000_ipprim_addresses, tvb, offset, 0,
 
817
                    ti =  proto_tree_add_string_format(dct2000_tree, hf_catapult_dct2000_ipprim_addresses,
 
818
                                                       tvb, offset_before_ipprim_header, 0,
755
819
                                                       "", "IPPrim transport (%s): %s:%u -> %s:%u",
756
820
                                                       (type_of_port == PT_UDP) ? "UDP" : "TCP",
757
 
                                                       (char *)get_hostname(source_addr), source_port,
758
 
                                                       (char *)get_hostname(dest_addr), dest_port);
 
821
                                                       (source_addr_offset) ?
 
822
                                                           (char *)get_hostname(tvb_get_ipv4(tvb, source_addr_offset)) :
 
823
                                                           "0.0.0.0",
 
824
                                                       (source_port_offset) ?
 
825
                                                           tvb_get_ntohs(tvb, source_port_offset) :
 
826
                                                           0,
 
827
                                                       (dest_addr_offset) ?
 
828
                                                           (char *)get_hostname(tvb_get_ipv4(tvb, dest_addr_offset)) :
 
829
                                                           "0.0.0.0",
 
830
                                                       (dest_port_offset) ?
 
831
                                                           tvb_get_ntohs(tvb, dest_port_offset) :
 
832
                                                           0);
759
833
                    ipprim_tree = proto_item_add_subtree(ti, ett_catapult_dct2000_ipprim);
760
834
 
761
835
 
762
 
                    if (source_addr != 0)
 
836
                    if (source_addr_offset != 0)
763
837
                    {
764
838
                        proto_item *addr_ti;
765
 
                        proto_tree_add_ipv4(ipprim_tree, hf_catapult_dct2000_ipprim_src_addr,
766
 
                                            tvb, offset, 0, source_addr);
767
 
                        addr_ti = proto_tree_add_ipv4(ipprim_tree, hf_catapult_dct2000_ipprim_addr,
768
 
                                                      tvb, offset, 0, source_addr);
 
839
                        proto_tree_add_item(ipprim_tree, hf_catapult_dct2000_ipprim_src_addr,
 
840
                                            tvb, source_addr_offset, 4, FALSE);
 
841
                        addr_ti = proto_tree_add_item(ipprim_tree, hf_catapult_dct2000_ipprim_addr,
 
842
                                                      tvb, source_addr_offset, 4, FALSE);
769
843
                        PROTO_ITEM_SET_HIDDEN(addr_ti);
770
844
                    }
771
 
                    if (source_port != 0)
 
845
                    if (source_port_offset != 0)
772
846
                    {
773
847
                        proto_item *port_ti;
774
 
                        proto_tree_add_uint(ipprim_tree,
 
848
                        proto_tree_add_item(ipprim_tree,
775
849
                                            (type_of_port == PT_UDP) ?
776
850
                                               hf_catapult_dct2000_ipprim_udp_src_port :
777
851
                                               hf_catapult_dct2000_ipprim_tcp_src_port,
778
 
                                            tvb, offset, 0, source_port);
779
 
                        port_ti = proto_tree_add_uint(ipprim_tree,
 
852
                                            tvb, source_port_offset, 2, FALSE);
 
853
                        port_ti = proto_tree_add_item(ipprim_tree,
780
854
                                                      (type_of_port == PT_UDP) ?
781
855
                                                          hf_catapult_dct2000_ipprim_udp_port :
782
856
                                                          hf_catapult_dct2000_ipprim_tcp_port,
783
 
                                                      tvb, offset, 0, source_port);
 
857
                                                      tvb, source_port_offset, 2, FALSE);
784
858
                        PROTO_ITEM_SET_HIDDEN(port_ti);
785
859
                    }
786
 
                    if (dest_addr != 0)
 
860
                    if (dest_addr_offset != 0)
787
861
                    {
788
862
                        proto_item *addr_ti;
789
 
                        proto_tree_add_ipv4(ipprim_tree, hf_catapult_dct2000_ipprim_dst_addr,
790
 
                                            tvb, offset, 0, dest_addr);
791
 
                        addr_ti = proto_tree_add_ipv4(ipprim_tree, hf_catapult_dct2000_ipprim_addr,
792
 
                                                      tvb, offset, 0, dest_addr);
 
863
                        proto_tree_add_item(ipprim_tree, hf_catapult_dct2000_ipprim_dst_addr,
 
864
                                            tvb, dest_addr_offset, 4, FALSE);
 
865
                        addr_ti = proto_tree_add_item(ipprim_tree, hf_catapult_dct2000_ipprim_addr,
 
866
                                                      tvb, dest_addr_offset, 4, FALSE);
793
867
                        PROTO_ITEM_SET_HIDDEN(addr_ti);
794
868
                    }
795
 
                    if (dest_port != 0)
 
869
                    if (dest_port_offset != 0)
796
870
                    {
797
871
                        proto_item *port_ti;
798
 
                        proto_tree_add_uint(ipprim_tree,
 
872
                        proto_tree_add_item(ipprim_tree,
799
873
                                            (type_of_port == PT_UDP) ?
800
874
                                               hf_catapult_dct2000_ipprim_udp_dst_port :
801
875
                                               hf_catapult_dct2000_ipprim_tcp_dst_port,
802
 
                                            tvb, offset, 0, dest_port);
803
 
                        port_ti = proto_tree_add_uint(ipprim_tree,
 
876
                                            tvb, dest_port_offset, 2, FALSE);
 
877
                        port_ti = proto_tree_add_item(ipprim_tree,
804
878
                                                      (type_of_port == PT_UDP) ?
805
879
                                                          hf_catapult_dct2000_ipprim_udp_port :
806
880
                                                          hf_catapult_dct2000_ipprim_tcp_port,
807
 
                                                      tvb, offset, 0, dest_port);
 
881
                                                      tvb, dest_port_offset, 2, FALSE);
808
882
                        PROTO_ITEM_SET_HIDDEN(port_ti);
809
883
                    }
 
884
 
 
885
                    /* Set length for IPPrim tree */
 
886
                    proto_item_set_len(ipprim_tree, offset - offset_before_ipprim_header);
810
887
                }
811
888
            }
812
889
 
864
941
                         tvb_get_ephemeral_string(tvb, variant_start, variant_length));
865
942
        }
866
943
    }
 
944
    else
 
945
    {
 
946
        /* Show number of dissected bytes */
 
947
        proto_item *ti = proto_tree_add_uint(dct2000_tree,
 
948
                                             hf_catapult_dct2000_dissected_length,
 
949
                                             tvb, 0, 0, tvb_reported_length(tvb)-offset);
 
950
        PROTO_ITEM_SET_GENERATED(ti);
 
951
    }
867
952
}
868
953
 
869
954
 
939
1024
              "Unparsed DCT2000 protocol data", HFILL
940
1025
            }
941
1026
        },
 
1027
        { &hf_catapult_dct2000_dissected_length,
 
1028
            { "Dissected length",
 
1029
              "dct2000.dissected-length", FT_UINT16, BASE_DEC, NULL, 0x0,
 
1030
              "Number of bytes dissected by subdissector(s)", HFILL
 
1031
            }
 
1032
        },
942
1033
        { &hf_catapult_dct2000_ipprim_addresses,
943
1034
            { "IPPrim Addresses",
944
1035
              "dct2000.ipprim", FT_STRING, BASE_NONE, NULL, 0x0,
1008
1099
    };
1009
1100
 
1010
1101
    module_t *catapult_dct2000_module;
1011
 
    
 
1102
 
1012
1103
    /* Register protocol. */
1013
 
    proto_catapult_dct2000 = proto_register_protocol("DCT2000", "DCT2000", "dct2000");
 
1104
    proto_catapult_dct2000 = proto_register_protocol("Catapult DCT2000 packet",
 
1105
                                                     "DCT2000",
 
1106
                                                     "dct2000");
1014
1107
    proto_register_field_array(proto_catapult_dct2000, hf, array_length(hf));
1015
1108
    proto_register_subtree_array(ett, array_length(ett));
1016
1109
 
1027
1120
 
1028
1121
    /* Determines whether for not-handled protocols we should try to parse it if:
1029
1122
       - it looks like its embedded in an ipprim message, AND
1030
 
       - the DCT2000 protocol name matches an wireshark dissector name */
 
1123
       - the DCT2000 protocol name matches a wireshark dissector name */
1031
1124
    prefs_register_bool_preference(catapult_dct2000_module, "ipprim_heuristic",
1032
1125
                                   "Use IP Primitive heuristic",
1033
1126
                                   "If a payload looks like its embedded in an "
1034
 
                                   "IP primitive message, and there is an wireshark "
 
1127
                                   "IP primitive message, and there is a wireshark "
1035
1128
                                   "dissector matching the DCT2000 protocol name, "
1036
1129
                                   "try parsing the payload using that dissector",
1037
1130
                                   &catapult_dct2000_try_ipprim_heuristic);
1038
1131
 
1039
1132
    /* Determines whether for not-handled protocols we should try to parse it if:
1040
1133
       - it looks like its embedded in an sctpprim message, AND
1041
 
       - the DCT2000 protocol name matches an wireshark dissector name */
 
1134
       - the DCT2000 protocol name matches n wireshark dissector name */
1042
1135
    prefs_register_bool_preference(catapult_dct2000_module, "sctpprim_heuristic",
1043
1136
                                   "Use SCTP Primitive heuristic",
1044
1137
                                   "If a payload looks like its embedded in an "
1045
 
                                   "SCTP primitive message, and there is an wireshark "
 
1138
                                   "SCTP primitive message, and there is a wireshark "
1046
1139
                                   "dissector matching the DCT2000 protocol name, "
1047
1140
                                   "try parsing the payload using that dissector",
1048
1141
                                   &catapult_dct2000_try_sctpprim_heuristic);