From Tobias Witek:
authorAnders Broman <anders.broman@ericsson.com>
Thu, 5 Nov 2009 21:54:06 +0000 (21:54 -0000)
committerAnders Broman <anders.broman@ericsson.com>
Thu, 5 Nov 2009 21:54:06 +0000 (21:54 -0000)
w protocols: UMTS RLC (ETSI TS 125 322), UMTS MAC (ETSI TS 125 321)
https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=3495

svn path=/trunk/; revision=30838

asn1/rrc/packet-rrc-template.c
asn1/rrc/packet-rrc-template.h
epan/dissectors/Makefile.common
epan/dissectors/packet-meta.c
epan/dissectors/packet-rlc.c
epan/dissectors/packet-rrc.c
epan/dissectors/packet-rrc.h
epan/dissectors/packet-umts_fp.c
epan/dissectors/packet-umts_fp.h
epan/frame_data.h

index c29075b97ce2a1f709491031089ce9d7d9b09447..e59231bebfda39654a9e9102f62de72c41215e66 100644 (file)
 
 static dissector_handle_t gsm_a_dtap_handle;
 static dissector_handle_t rrc_ue_radio_access_cap_info_handle=NULL;
+static dissector_handle_t rrc_pcch_handle=NULL;
+static dissector_handle_t rrc_ul_ccch_handle=NULL;
+static dissector_handle_t rrc_dl_ccch_handle=NULL;
+static dissector_handle_t rrc_ul_dcch_handle=NULL;
 static dissector_handle_t rrc_dl_dcch_handle=NULL;
 
 /* Include constants */
 #include "packet-rrc-val.h"
 
 /* Initialize the protocol and registered fields */
-static int proto_rrc = -1;
+int proto_rrc = -1;
 static int hf_test;
 #include "packet-rrc-hf.c"
 
@@ -74,6 +78,8 @@ static proto_tree *top_tree;
 
 #include "packet-rrc-fn.c"
 
+#include "packet-rrc.h"
+
 /* 
 TODO: Remove the dummy function when these functions are taken into use
 
@@ -106,8 +112,10 @@ dissect_rrc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
         */
        proto_item      *rrc_item = NULL;
        proto_tree      *rrc_tree = NULL;
+       struct rrc_info *rrcinf;
 
        top_tree = tree;
+       rrcinf = p_get_proto_data(pinfo->fd, proto_rrc);
 
        /* make entry in the Protocol column on summary display */
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "RRC");
@@ -116,6 +124,27 @@ dissect_rrc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        rrc_item = proto_tree_add_item(tree, proto_rrc, tvb, 0, -1, FALSE);
        rrc_tree = proto_item_add_subtree(rrc_item, ett_rrc);
 
+       if (rrcinf) {
+               switch (rrcinf->msgtype[pinfo->fd->subnum]) {
+                       case RRC_MESSAGE_TYPE_PCCH:
+                               call_dissector(rrc_pcch_handle, tvb, pinfo, rrc_tree);
+                               break;
+                       case RRC_MESSAGE_TYPE_UL_CCCH:
+                               call_dissector(rrc_ul_ccch_handle, tvb, pinfo, rrc_tree);
+                               break;
+                       case RRC_MESSAGE_TYPE_DL_CCCH:
+                               call_dissector(rrc_dl_ccch_handle, tvb, pinfo, rrc_tree);
+                               break;
+                       case RRC_MESSAGE_TYPE_UL_DCCH:
+                               call_dissector(rrc_ul_dcch_handle, tvb, pinfo, rrc_tree);
+                               break;
+                       case RRC_MESSAGE_TYPE_DL_DCCH:
+                               call_dissector(rrc_dl_dcch_handle, tvb, pinfo, rrc_tree);
+                               break;
+                       default:
+                               ;
+               }
+       }
 }
 /*--- proto_register_rrc -------------------------------------------*/
 void proto_register_rrc(void) {
@@ -157,6 +186,11 @@ proto_reg_handoff_rrc(void)
 {
 
        gsm_a_dtap_handle = find_dissector("gsm_a_dtap");
+       rrc_pcch_handle = find_dissector("rrc.pcch");
+       rrc_ul_ccch_handle = find_dissector("rrc.ul.ccch");
+       rrc_dl_ccch_handle = find_dissector("rrc.dl.ccch");
+       rrc_ul_dcch_handle = find_dissector("rrc.ul.dcch");
+       rrc_dl_dcch_handle = find_dissector("rrc.dl.dcch");
        rrc_ue_radio_access_cap_info_handle = find_dissector("rrc.ue_radio_access_cap_info");
        rrc_dl_dcch_handle = find_dissector("rrc.dl.dcch");
 }
index 3d13cade397caa269c8a22ffbd8de6c57be75da3..111acdaa45bedff10f7e9dd0ac1f949abbfb6579 100644 (file)
 #ifndef PACKET_RRC_H
 #define PACKET_RRC_H
 
+extern int proto_rrc;
 #include "packet-rrc-exp.h"
 
+enum rrc_message_type {
+       RRC_MESSAGE_TYPE_INVALID        = 0,
+       RRC_MESSAGE_TYPE_PCCH           = 1,
+       RRC_MESSAGE_TYPE_UL_CCCH,
+       RRC_MESSAGE_TYPE_DL_CCCH,
+       RRC_MESSAGE_TYPE_UL_DCCH,
+       RRC_MESSAGE_TYPE_DL_DCCH,
+};
+
+#define MAX_RRC_FRAMES 64
+typedef struct rrc_info
+{
+       enum rrc_message_type msgtype[MAX_RRC_FRAMES];
+} rrc_info;
+
 #endif  /* PACKET_RRC_H */
index 51d34aa4b3fb748ea13b22920b0ebaccac72cca9..0315b6f73b1e8850fe5c9fa3e4b2bd884772a808 100644 (file)
@@ -450,6 +450,7 @@ DISSECTOR_SRC = \
        packet-fmp.c            \
        packet-fmp_notify.c     \
        packet-force10-oui.c    \
+       packet-fp_hint.c        \
        packet-fr.c             \
        packet-fractalgeneratorprotocol.c \
        packet-frame.c          \
@@ -618,6 +619,7 @@ DISSECTOR_SRC = \
        packet-megaco.c         \
        packet-memcache.c       \
        packet-mesh.c           \
+       packet-meta.c           \
        packet-mgcp.c           \
        packet-mikey.c          \
        packet-miop.c           \
@@ -745,6 +747,7 @@ DISSECTOR_SRC = \
        packet-rgmp.c           \
        packet-rip.c            \
        packet-ripng.c          \
+       packet-rlc.c            \
        packet-rlc-lte.c                \
        packet-rlm.c            \
        packet-rlogin.c         \
@@ -879,6 +882,7 @@ DISSECTOR_SRC = \
        packet-usb-hid.c        \
        packet-usb-hub.c        \
        packet-umts_fp.c        \
+       packet-umts_mac.c       \
        packet-user_encap.c     \
        packet-uts.c            \
        packet-v120.c           \
@@ -1106,6 +1110,7 @@ DISSECTOR_INCLUDES =      \
        packet-logotypecertextn.h       \
        packet-lte-rrc.h        \
        packet-mac-lte.h                \
+       packet-meta.h   \
        packet-mgcp.h           \
        packet-mikey.h  \
        packet-mip6.h   \
@@ -1167,6 +1172,7 @@ DISSECTOR_INCLUDES =      \
        packet-rdt.h    \
        packet-rgmp.h   \
        packet-ripng.h  \
+       packet-rlc.h    \
        packet-rlc-lte.h                \
        packet-rmi.h    \
        packet-rmt-alc.h        \
@@ -1229,6 +1235,7 @@ DISSECTOR_INCLUDES =      \
        packet-tte.h \
        packet-udp.h    \
        packet-umts_fp.h        \
+       packet-umts_mac.c       \
        packet-usb.h    \
        packet-usb-hid.h        \
        packet-vines.h  \
index cfbbde6cc2a8482a6f0c91757932e1b33729087c..893a080ad4be6a76033b83ed8a0cdaec20369a46 100644 (file)
@@ -26,6 +26,7 @@
 #endif
 
 #include <string.h>
+#include <stdio.h>
 
 #include <glib.h>
 #include <epan/packet.h>
@@ -409,6 +410,7 @@ static dissector_handle_t *dxt_get_dissector(guint16 proto, packet_info *pinfo)
                default:
                        next_dissector = &data_handle;
        }
+       if (!*next_dissector) next_dissector = &data_handle;
        return next_dissector;
 }
 
@@ -482,7 +484,7 @@ proto_register_meta(void)
                { &hf_meta_item_id, { "Item ID", "meta.item.id", FT_UINT16, BASE_HEX, VALS(meta_id_vals), 0x0, NULL, HFILL } },
                { &hf_meta_item_type, { "Item Type", "meta.item.type", FT_UINT8, BASE_HEX, VALS(meta_type_vals), 0x0, NULL, HFILL } },
                { &hf_meta_item_len, { "Item Length", "meta.item.len", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
-               { &hf_meta_item_data, { "Item Data", "meta.item.data", FT_BYTES, BASE_HEX, NULL, 0x0, NULL, HFILL } },
+               { &hf_meta_item_data, { "Item Data", "meta.item.data", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
 
                /* specific meta items */
                { &hf_meta_item_direction, { "Direction", "meta.direction", FT_UINT8, BASE_DEC, VALS(meta_direction_vals), 0, NULL, HFILL } },
index 791422b2409938a1daf6b52bb4bc5f6ef4d402ab..0c84e00e278d390b5442560689ea8533ca936477 100644 (file)
@@ -391,18 +391,32 @@ static int rlc_cmp_seq(gconstpointer a, gconstpointer b)
                        0;
 }
 
+/* callback function to use for g_hash_table_foreach_remove()
+ * always return TRUE (=always delete the entry)
+ * this is required for backwards compatibility
+ * with older versions of glib which do not have
+ * a g_hash_table_remove_all() (because of this,
+ * hashtables are emptied using g_hash_table_foreach_remove()
+ * in conjunction with this funcion)
+ */
+static gboolean free_table_entry(gpointer key _U_,
+       gpointer value _U_, gpointer user_data _U_)
+{
+       return TRUE;
+}
+
 static void fragment_table_init(void)
 {
        if (fragment_table) {
-               g_hash_table_remove_all(fragment_table);
+               g_hash_table_foreach_remove(fragment_table, free_table_entry, NULL);
                g_hash_table_destroy(fragment_table);
        }
        if (reassembled_table) {
-               g_hash_table_remove_all(reassembled_table);
+               g_hash_table_foreach_remove(reassembled_table, free_table_entry, NULL);
                g_hash_table_destroy(reassembled_table);
        }
        if (sequence_table) {
-               g_hash_table_remove_all(sequence_table);
+               g_hash_table_foreach_remove(sequence_table, free_table_entry, NULL);
                g_hash_table_destroy(sequence_table);
        }
        fragment_table = g_hash_table_new_full(rlc_channel_hash, rlc_channel_equal,
@@ -745,6 +759,8 @@ static void rlc_call_subdissector(enum channel_type channel, tvbuff_t *tvb,
                        return; /* abort */
        }
        if (msgtype != RRC_MESSAGE_TYPE_INVALID) {
+#if 0
+               /* TODO: call rrc dissector correctly */
                struct rrc_info *rrcinf;
                fp_info *fpinf;
                fpinf = p_get_proto_data(pinfo->fd, proto_fp);
@@ -754,6 +770,7 @@ static void rlc_call_subdissector(enum channel_type channel, tvbuff_t *tvb,
                        p_add_proto_data(pinfo->fd, proto_rrc, rrcinf);
                }
                rrcinf->msgtype[fpinf->cur_tb] = msgtype;
+#endif
                call_dissector(rrc_handle, tvb, pinfo, tree);
                /* once the packet has been dissected, protect it from further changes */
                col_set_writable(pinfo->cinfo, FALSE);
@@ -1330,7 +1347,7 @@ proto_register_rlc(void)
                { &hf_rlc_ext, { "Extension Bit", "rlc.ext", FT_BOOLEAN, BASE_DEC, TFS(&rlc_ext_val), 0x01, NULL, HFILL } },
                { &hf_rlc_he, { "Header Extension Type", "rlc.he", FT_UINT8, BASE_DEC, VALS(rlc_he_vals), 0, NULL, HFILL } },
                { &hf_rlc_p, { "Polling Bit", "rlc.p", FT_BOOLEAN, 8, TFS(&rlc_p_val), 0x04, NULL, HFILL } },
-               { &hf_rlc_pad, { "Padding", "rlc.padding", FT_BYTES, BASE_HEX, NULL, 0x0, NULL, HFILL } },
+               { &hf_rlc_pad, { "Padding", "rlc.padding", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
                { &hf_rlc_frags, { "Reassembled Fragments", "rlc.fragments", FT_NONE, BASE_NONE, NULL, 0, "Fragments", HFILL } },
                { &hf_rlc_frag, { "RLC Fragment", "rlc.fragment", FT_FRAMENUM, BASE_NONE, NULL, 0, NULL, HFILL } },
                { &hf_rlc_duplicate_of, { "Duplicate of", "rlc.duplicate_of", FT_FRAMENUM, BASE_NONE, NULL, 0, NULL, HFILL } },
@@ -1350,7 +1367,7 @@ proto_register_rlc(void)
                { &hf_rlc_sufi_l, { "L", "rlc.sufi.l", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
                { &hf_rlc_sufi_len, { "Length", "rlc.sufi.len", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
                { &hf_rlc_sufi_fsn, { "FSN", "rlc.sufi.fsn", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
-               { &hf_rlc_sufi_bitmap, { "Bitmap", "rlc.sufi.bitmap", FT_BYTES, BASE_HEX, NULL, 0x0, NULL, HFILL } },
+               { &hf_rlc_sufi_bitmap, { "Bitmap", "rlc.sufi.bitmap", FT_BYTES, BASE_NONE, NULL, 0x0, NULL, HFILL } },
                { &hf_rlc_sufi_cw, { "CW", "rlc.sufi.cw", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
                { &hf_rlc_sufi_n, { "N", "rlc.sufi.n", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL } },
                { &hf_rlc_sufi_sn_ack, { "SN ACK", "rlc.sufi.sn_ack", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL } },
index f483fa8720b9a9e33d8870c655d970274980e966..98e3faffd1a206ebc42359a47247662b17e6bc2f 100644 (file)
 
 static dissector_handle_t gsm_a_dtap_handle;
 static dissector_handle_t rrc_ue_radio_access_cap_info_handle=NULL;
+static dissector_handle_t rrc_pcch_handle=NULL;
+static dissector_handle_t rrc_ul_ccch_handle=NULL;
+static dissector_handle_t rrc_dl_ccch_handle=NULL;
+static dissector_handle_t rrc_ul_dcch_handle=NULL;
 static dissector_handle_t rrc_dl_dcch_handle=NULL;
 
 /* Include constants */
@@ -215,10 +219,10 @@ static dissector_handle_t rrc_dl_dcch_handle=NULL;
 #define maxURNTI_Group                 8
 
 /*--- End of included file: packet-rrc-val.h ---*/
-#line 61 "packet-rrc-template.c"
+#line 65 "packet-rrc-template.c"
 
 /* Initialize the protocol and registered fields */
-static int proto_rrc = -1;
+int proto_rrc = -1;
 static int hf_test;
 
 /*--- Included file: packet-rrc-hf.c ---*/
@@ -8013,7 +8017,7 @@ static int hf_rrc_GsmSecurityCapability_a5_2 = -1;
 static int hf_rrc_GsmSecurityCapability_a5_1 = -1;
 
 /*--- End of included file: packet-rrc-hf.c ---*/
-#line 66 "packet-rrc-template.c"
+#line 70 "packet-rrc-template.c"
 
 /* Initialize the subtree pointers */
 static int ett_rrc = -1;
@@ -12813,7 +12817,7 @@ static gint ett_rrc_UE_RadioAccessCapability_r6 = -1;
 static gint ett_rrc_UL_RFC3095_Context = -1;
 
 /*--- End of included file: packet-rrc-ett.c ---*/
-#line 71 "packet-rrc-template.c"
+#line 75 "packet-rrc-template.c"
 
 /* Global variables */
 static proto_tree *top_tree;
@@ -112094,7 +112098,9 @@ static int dissect_MeasurementReport_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _
 
 
 /*--- End of included file: packet-rrc-fn.c ---*/
-#line 76 "packet-rrc-template.c"
+#line 80 "packet-rrc-template.c"
+
+#include "packet-rrc.h"
 
 /* 
 TODO: Remove the dummy function when these functions are taken into use
@@ -112128,8 +112134,10 @@ dissect_rrc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
         */
        proto_item      *rrc_item = NULL;
        proto_tree      *rrc_tree = NULL;
+       struct rrc_info *rrcinf;
 
        top_tree = tree;
+       rrcinf = p_get_proto_data(pinfo->fd, proto_rrc);
 
        /* make entry in the Protocol column on summary display */
        col_set_str(pinfo->cinfo, COL_PROTOCOL, "RRC");
@@ -112138,6 +112146,27 @@ dissect_rrc(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        rrc_item = proto_tree_add_item(tree, proto_rrc, tvb, 0, -1, FALSE);
        rrc_tree = proto_item_add_subtree(rrc_item, ett_rrc);
 
+       if (rrcinf) {
+               switch (rrcinf->msgtype[pinfo->fd->subnum]) {
+                       case RRC_MESSAGE_TYPE_PCCH:
+                               call_dissector(rrc_pcch_handle, tvb, pinfo, rrc_tree);
+                               break;
+                       case RRC_MESSAGE_TYPE_UL_CCCH:
+                               call_dissector(rrc_ul_ccch_handle, tvb, pinfo, rrc_tree);
+                               break;
+                       case RRC_MESSAGE_TYPE_DL_CCCH:
+                               call_dissector(rrc_dl_ccch_handle, tvb, pinfo, rrc_tree);
+                               break;
+                       case RRC_MESSAGE_TYPE_UL_DCCH:
+                               call_dissector(rrc_ul_dcch_handle, tvb, pinfo, rrc_tree);
+                               break;
+                       case RRC_MESSAGE_TYPE_DL_DCCH:
+                               call_dissector(rrc_dl_dcch_handle, tvb, pinfo, rrc_tree);
+                               break;
+                       default:
+                               ;
+               }
+       }
 }
 /*--- proto_register_rrc -------------------------------------------*/
 void proto_register_rrc(void) {
@@ -143298,7 +143327,7 @@ void proto_register_rrc(void) {
         NULL, HFILL }},
 
 /*--- End of included file: packet-rrc-hfarr.c ---*/
-#line 127 "packet-rrc-template.c"
+#line 156 "packet-rrc-template.c"
     { &hf_test,
       { "RAB Test", "rrc.RAB.test",
         FT_UINT8, BASE_DEC, NULL, 0,
@@ -148104,7 +148133,7 @@ void proto_register_rrc(void) {
     &ett_rrc_UL_RFC3095_Context,
 
 /*--- End of included file: packet-rrc-ettarr.c ---*/
-#line 138 "packet-rrc-template.c"
+#line 167 "packet-rrc-template.c"
   };
 
 
@@ -148178,7 +148207,7 @@ void proto_register_rrc(void) {
 
 
 /*--- End of included file: packet-rrc-dis-reg.c ---*/
-#line 150 "packet-rrc-template.c"
+#line 179 "packet-rrc-template.c"
 
 }
 
@@ -148189,6 +148218,11 @@ proto_reg_handoff_rrc(void)
 {
 
        gsm_a_dtap_handle = find_dissector("gsm_a_dtap");
+       rrc_pcch_handle = find_dissector("rrc.pcch");
+       rrc_ul_ccch_handle = find_dissector("rrc.ul.ccch");
+       rrc_dl_ccch_handle = find_dissector("rrc.dl.ccch");
+       rrc_ul_dcch_handle = find_dissector("rrc.ul.dcch");
+       rrc_dl_dcch_handle = find_dissector("rrc.dl.dcch");
        rrc_ue_radio_access_cap_info_handle = find_dissector("rrc.ue_radio_access_cap_info");
        rrc_dl_dcch_handle = find_dissector("rrc.dl.dcch");
 }
index 59cae09030921b8296a8d3ae567d1ebc9e1b4305..eadcefff7caf0a4e00001c30584ba0fbebe67bba 100644 (file)
@@ -33,6 +33,7 @@
 #ifndef PACKET_RRC_H
 #define PACKET_RRC_H
 
+extern int proto_rrc;
 
 /*--- Included file: packet-rrc-exp.h ---*/
 #line 1 "packet-rrc-exp.h"
@@ -41,6 +42,21 @@ void dissect_rrc_InterRATHandoverInfo_PDU(tvbuff_t *tvb _U_, packet_info *pinfo
 void dissect_rrc_ToTargetRNC_Container_PDU(tvbuff_t *tvb _U_, packet_info *pinfo _U_, proto_tree *tree _U_);
 
 /*--- End of included file: packet-rrc-exp.h ---*/
-#line 29 "packet-rrc-template.h"
+#line 30 "packet-rrc-template.h"
+
+enum rrc_message_type {
+       RRC_MESSAGE_TYPE_INVALID        = 0,
+       RRC_MESSAGE_TYPE_PCCH           = 1,
+       RRC_MESSAGE_TYPE_UL_CCCH,
+       RRC_MESSAGE_TYPE_DL_CCCH,
+       RRC_MESSAGE_TYPE_UL_DCCH,
+       RRC_MESSAGE_TYPE_DL_DCCH,
+};
+
+#define MAX_RRC_FRAMES 64
+typedef struct rrc_info
+{
+       enum rrc_message_type msgtype[MAX_RRC_FRAMES];
+} rrc_info;
 
 #endif  /* PACKET_RRC_H */
index da289d2a57096e09f8953d2a3565628315e698b9..a13c0069f63e87ded366734a9729560c19fedfe6 100644 (file)
@@ -39,6 +39,7 @@
  * TODO:
  *  - IUR interface-specific formats
  *  - verify header & payload CRCs
+ *  - do CRC verification before further parsing
  */
 
 /* Initialize the protocol and registered fields. */
@@ -168,6 +169,14 @@ static int ett_fp_hsdsch_new_ie_flags = -1;
 static int ett_fp_rach_new_ie_flags = -1;
 static int ett_fp_hsdsch_pdu_block_header = -1;
 
+static dissector_handle_t mac_fdd_dch_handle;
+static dissector_handle_t mac_fdd_rach_handle;
+static dissector_handle_t mac_fdd_fach_handle;
+static dissector_handle_t mac_fdd_pch_handle;
+static dissector_handle_t mac_fdd_edch_handle;
+static dissector_handle_t mac_fdd_hsdsch_handle;
+
+static proto_tree *top_level_tree = NULL;
 
 /* E-DCH channel header information */
 struct subframe_info
@@ -178,7 +187,6 @@ struct subframe_info
     guint16 number_of_mac_d_pdus[64];
 };
 
-
 static const value_string channel_type_vals[] =
 {
     { CHANNEL_RACH_FDD,     "RACH_FDD" },
@@ -330,13 +338,15 @@ static const value_string common_control_frame_type_vals[] = {
 
 /* Dissect message parts */
 static int dissect_tb_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-                           int offset, struct fp_info *p_fp_info, int *num_tbs);
+                           int offset, struct fp_info *p_fp_info,
+                           dissector_handle_t *data_handle);
 static int dissect_macd_pdu_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                                  int offset, guint16 length, guint16 number_of_pdus);
 static int dissect_macd_pdu_data_type_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                                         int offset, guint16 length, guint16 number_of_pdus);
+
 static int dissect_crci_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-                             int num_tbs, int offset);
+                             fp_info *p_fp_info, int offset);
 static void dissect_spare_extension_and_crc(tvbuff_t *tvb, packet_info *pinfo,
                                             proto_tree *tree, guint8 dch_crc_present,
                                             int offset);
@@ -436,17 +446,26 @@ void proto_register_fp(void);
 void proto_reg_handoff_fp(void);
 
 
-
+static int get_tb_count(struct fp_info *p_fp_info)
+{
+    int chan, tb_count = 0;
+    for (chan = 0; chan < p_fp_info->num_chans; chan++) {
+        tb_count += p_fp_info->chan_num_tbs[chan];
+    }
+    return tb_count;
+}
 
 /* Dissect the TBs of a data frame */
 int dissect_tb_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-                    int offset, struct fp_info *p_fp_info, int *num_tbs)
+                    int offset, struct fp_info *p_fp_info,
+                    dissector_handle_t *data_handle)
 {
-    int chan;
+    int chan, num_tbs = 0;
     int bit_offset = 0;
     guint data_bits = 0;
     proto_item *tree_ti = NULL;
     proto_tree *data_tree = NULL;
+    gboolean dissected = FALSE;
 
     if (tree)
     {
@@ -473,19 +492,28 @@ int dissect_tb_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
         }
 
         /* Show TBs from non-empty channels */
+        pinfo->fd->subnum = chan; /* set subframe number to current TB */
         for (n=0; n < p_fp_info->chan_num_tbs[chan]; n++)
         {
             proto_item *ti;
             if (data_tree)
             {
+                               tvbuff_t *next_tvb;
                 ti = proto_tree_add_item(data_tree, hf_fp_tb, tvb,
                                          offset + (bit_offset/8),
                                          ((bit_offset % 8) + p_fp_info->chan_tf_size[chan] + 7) / 8,
                                          FALSE);
                 proto_item_set_text(ti, "TB (chan %u, tb %u, %u bits)",
                                     chan+1, n+1, p_fp_info->chan_tf_size[chan]);
+                if (data_handle && p_fp_info->chan_tf_size[chan] > 0) {
+                        next_tvb = tvb_new_subset(tvb, offset + bit_offset/8,
+                                ((bit_offset % 8) + p_fp_info->chan_tf_size[chan] + 7) / 8, -1);
+                       /* TODO: maybe this decision can be based only on info available in fp_info */
+                        call_dissector(*data_handle, next_tvb, pinfo, top_level_tree);
+                        dissected = TRUE;
+                }
             }
-            (*num_tbs)++;
+            num_tbs++;
 
             /* Advance bit offset */
             bit_offset += p_fp_info->chan_tf_size[chan];
@@ -499,17 +527,17 @@ int dissect_tb_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
         }
     }
 
-    if (check_col(pinfo->cinfo, COL_INFO))
+    if (dissected == FALSE && check_col(pinfo->cinfo, COL_INFO))
     {
         col_append_fstr(pinfo->cinfo, COL_INFO, "(%u bits in %u tbs)",
-                        data_bits, *num_tbs);
+                        data_bits, num_tbs);
     }
 
     /* Data tree should cover entire length */
     if (data_tree)
     {
         proto_item_set_len(tree_ti, bit_offset/8);
-        proto_item_append_text(tree_ti, " (%u bits in %u tbs)", data_bits, *num_tbs);
+        proto_item_append_text(tree_ti, " (%u bits in %u tbs)", data_bits, num_tbs);
     }
 
     /* Move offset past TBs (we know its already padded out to next byte) */
@@ -528,6 +556,7 @@ int dissect_macd_pdu_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
     int bit_offset = 0;
     proto_item *pdus_ti = NULL;
     proto_tree *data_tree = NULL;
+       gboolean dissected = FALSE;
 
     /* Add data subtree */
     if (tree)
@@ -552,11 +581,17 @@ int dissect_macd_pdu_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
         /* Data bytes! */
         if (data_tree)
         {
+                       tvbuff_t *next_tvb;
+               pinfo->fd->subnum = pdu; /* set subframe number to current TB */
             pdu_ti = proto_tree_add_item(data_tree, hf_fp_mac_d_pdu, tvb,
                                          offset + (bit_offset/8),
                                          ((bit_offset % 8) + length + 7) / 8,
                                          FALSE);
             proto_item_set_text(pdu_ti, "MAC-d PDU (PDU %u)", pdu+1);
+                       next_tvb = tvb_new_subset(tvb, offset + bit_offset/8,
+                               ((bit_offset % 8) + length + 7)/8, -1);
+                       call_dissector(mac_fdd_hsdsch_handle, next_tvb, pinfo, top_level_tree);
+                       dissected = TRUE;
         }
 
         /* Advance bit offset */
@@ -576,7 +611,7 @@ int dissect_macd_pdu_data(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
     offset += (bit_offset / 8);
 
     /* Show summary in info column */
-    if (check_col(pinfo->cinfo, COL_INFO))
+    if (dissected == FALSE && check_col(pinfo->cinfo, COL_INFO))
     {
         col_append_fstr(pinfo->cinfo, COL_INFO, "   %u PDUs of %u bits",
                         number_of_pdus, length);
@@ -634,17 +669,17 @@ int dissect_macd_pdu_data_type_2(tvbuff_t *tvb, packet_info *pinfo, proto_tree *
     return offset;
 }
 
-
-
 /* Dissect CRCI bits (uplink) */
 int dissect_crci_bits(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
-                      int num_tbs, int offset)
+                      fp_info *p_fp_info, int offset)
 {
-    int n;
+    int n, num_tbs;
     proto_item *ti = NULL;
     proto_tree *crcis_tree = NULL;
     guint errors = 0;
 
+    num_tbs = get_tb_count(p_fp_info);
+
     /* Add CRCIs subtree */
     if (tree)
     {
@@ -1209,7 +1244,6 @@ void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
     }
     else
     {
-        int num_tbs = 0;
         guint8 cfn;
         guint32 propagation_delay = 0;
         proto_item *propagation_delay_ti = NULL;
@@ -1262,14 +1296,16 @@ void dissect_rach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
         }
 
         /* TB data */
-        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &num_tbs);
+        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &mac_fdd_rach_handle);
 
         /* CRCIs */
-        offset = dissect_crci_bits(tvb, pinfo, tree, num_tbs, offset);
+        offset = dissect_crci_bits(tvb, pinfo, tree, p_fp_info, offset);
 
         /* Info introduced in R6 */
-        if ((p_fp_info->release == 6) ||
-            (p_fp_info->release == 7))
+               /* only check if it looks as if they are present */
+        if (((p_fp_info->release == 6) ||
+            (p_fp_info->release == 7)) &&
+                       tvb_length_remaining(tvb, offset) > 2)
         {
             int n;
             guint8 flags;
@@ -1469,7 +1505,6 @@ void dissect_fach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
     }
     else
     {
-        int num_tbs = 0;
         guint8 cfn;
 
         /* DATA */
@@ -1494,7 +1529,7 @@ void dissect_fach_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
         offset++;
 
         /* TB data */
-        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &num_tbs);
+        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &mac_fdd_fach_handle);
 
         /* New IE flags (if it looks as though they are present) */
         if ((p_fp_info->release == 7) &&
@@ -1543,7 +1578,6 @@ void dissect_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
     }
     else
     {
-        int num_tbs = 0;
         guint8 cfn;
 
         /* DATA */
@@ -1601,7 +1635,7 @@ void dissect_dsch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
         }
 
         /* TB data */
-        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &num_tbs);
+        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, NULL);
 
         /* Spare Extension and Payload CRC */
         dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
@@ -1635,7 +1669,6 @@ void dissect_usch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
     }
     else
     {
-        int num_tbs = 0;
         guint cfn;
         guint16 rx_timing_deviation;
         proto_item *rx_timing_deviation_ti;
@@ -1663,14 +1696,14 @@ void dissect_usch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
         offset++;
 
         /* TB data */
-        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &num_tbs);
+        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, NULL);
 
         /* QE */
         proto_tree_add_item(tree, hf_fp_quality_estimate, tvb, offset, 1, FALSE);
         offset++;
 
         /* CRCIs */
-        offset = dissect_crci_bits(tvb, pinfo, tree, num_tbs, offset);
+        offset = dissect_crci_bits(tvb, pinfo, tree, p_fp_info, offset);
 
         /* New IEs */
         if ((p_fp_info->release == 7) &&
@@ -1725,8 +1758,6 @@ void dissect_pch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
     }
     else
     {
-        int num_tbs = 0;
-
         /* DATA */
 
         /* 12-bit CFN value */
@@ -1761,7 +1792,7 @@ void dissect_pch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
         }
 
         /* TB data */
-        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &num_tbs);
+               offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &mac_fdd_pch_handle);
 
         /* Spare Extension and Payload CRC */
         dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
@@ -1795,7 +1826,6 @@ void dissect_cpch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
     }
     else
     {
-        int num_tbs = 0;
         guint cfn;
 
         /* DATA */
@@ -1820,10 +1850,10 @@ void dissect_cpch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tr
         offset++;
 
         /* TB data */
-        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &num_tbs);
+        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, NULL);
 
         /* CRCIs */
-        offset = dissect_crci_bits(tvb, pinfo, tree, num_tbs, offset);
+        offset = dissect_crci_bits(tvb, pinfo, tree, p_fp_info, offset);
 
         /* Spare Extension and Payload CRC */
         dissect_spare_extension_and_crc(tvb, pinfo, tree, 1, offset);
@@ -2283,7 +2313,6 @@ void dissect_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
         /************************/
         /* DCH data here        */
         int chan;
-        int num_tbs = 0;
 
         /* CFN */
         proto_tree_add_item(tree, hf_fp_cfn, tvb, offset, 1, FALSE);
@@ -2303,7 +2332,7 @@ void dissect_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
         }
 
         /* Dissect TB data */
-        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &num_tbs);
+        offset = dissect_tb_data(tvb, pinfo, tree, offset, p_fp_info, &mac_fdd_dch_handle);
 
         /* QE (uplink only) */
         if (p_fp_info->is_uplink)
@@ -2315,7 +2344,7 @@ void dissect_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tre
         /* CRCI bits (uplink only) */
         if (p_fp_info->is_uplink)
         {
-            offset = dissect_crci_bits(tvb, pinfo, tree, num_tbs, offset);
+            offset = dissect_crci_bits(tvb, pinfo, tree, p_fp_info, offset);
         }
 
         /* Spare extension and payload CRC (optional) */
@@ -2363,6 +2392,7 @@ void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
         guint  bit_offset = 0;
         guint  total_pdus = 0;
         guint  total_bits = 0;
+        gboolean dissected = FALSE;
 
         /* FSN */
         proto_tree_add_item(tree, hf_fp_edch_fsn, tvb, offset, 1, FALSE);
@@ -2482,6 +2512,7 @@ void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
                 guint8      tsn;
                 guint       send_size;
                 proto_item  *ti;
+                               int                     macd_idx;
 
                 /* Look up mac-d pdu size for this ddi */
                 for (m=0; m < p_fp_info->no_ddi_entries; m++)
@@ -2526,11 +2557,20 @@ void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
                                            size, subframes[n].number_of_mac_d_pdus[i],
                                            send_size, n);
                 }
+                               for (macd_idx = 0; macd_idx < subframes[n].number_of_mac_d_pdus[i]; macd_idx++) {
+                                       tvbuff_t *next_tvb;
+                               pinfo->fd->subnum = macd_idx; /* set subframe number to current TB */
+                                       /* create new TVB and pass further on */
+                    next_tvb = tvb_new_subset(tvb, offset + bit_offset/8,
+                            ((bit_offset % 8) + size + 7) / 8, -1);
+                    call_dissector(mac_fdd_edch_handle, next_tvb, pinfo, top_level_tree);
+                                       bit_offset += size;
+                    dissected = TRUE;
+                               }
+
                 bits_in_subframe += send_size;
                 mac_d_pdus_in_subframe += subframes[n].number_of_mac_d_pdus[i];
 
-                bit_offset += send_size;
-
                 /* Pad out to next byte */
                 if (bit_offset % 8)
                 {
@@ -2542,7 +2582,6 @@ void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
             {
                 /* Tree should cover entire subframe */
                 proto_item_set_len(subframe_ti, bit_offset/8);
-
                 /* Append summary info to subframe label */
                 proto_item_append_text(subframe_ti, " (%u bits in %u MAC-d PDUs)",
                                        bits_in_subframe, mac_d_pdus_in_subframe);
@@ -2553,8 +2592,9 @@ void dissect_e_dch_channel_info(tvbuff_t *tvb, packet_info *pinfo, proto_tree *t
             offset += (bit_offset/8);
         }
 
-        /* Report number of subframes in info column */
-        if (check_col(pinfo->cinfo, COL_INFO))
+        /* Report number of subframes in info column
+         * do this only if no other dissector was called */
+        if (dissected == FALSE && check_col(pinfo->cinfo, COL_INFO))
         {
             col_append_fstr(pinfo->cinfo, COL_INFO,
                             " CFN = %03u   (%u bits in %u pdus in %u subframes)",
@@ -2917,6 +2957,8 @@ void dissect_fp(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
     ti = proto_tree_add_item(tree, proto_fp, tvb, offset, -1, FALSE);
     fp_tree = proto_item_add_subtree(ti, ett_fp);
 
+       top_level_tree = tree;
+
     /* Look for packet info! */
     p_fp_info = p_get_proto_data(pinfo->fd, proto_fp);
 
@@ -3879,5 +3921,11 @@ void proto_register_fp(void)
 
 void proto_reg_handoff_fp(void)
 {
+       mac_fdd_rach_handle = find_dissector("mac.fdd.rach");
+       mac_fdd_fach_handle = find_dissector("mac.fdd.fach");
+       mac_fdd_pch_handle = find_dissector("mac.fdd.pch");
+       mac_fdd_dch_handle = find_dissector("mac.fdd.dch");
+       mac_fdd_edch_handle = find_dissector("mac.fdd.edch");
+       mac_fdd_hsdsch_handle = find_dissector("mac.fdd.hsdsch");
 }
 
index e496229d7dea8b43580e5318114f973a8389559e..4c2fa4ba0ce0e85a758c3998628c78e5c42a1f16 100644 (file)
@@ -63,6 +63,13 @@ enum fp_hsdsch_entity
     ehs=2
 };
 
+enum fp_link_type
+{
+    FP_Link_Unknown,
+    FP_Link_ATM,
+    FP_Link_Ethernet,
+};
+
 /* Info attached to each FP packet */
 typedef struct fp_info
 {
@@ -85,6 +92,10 @@ typedef struct fp_info
     guint8 edch_ddi[MAX_EDCH_DDIS];
     guint  edch_macd_pdu_size[MAX_EDCH_DDIS];
 
+    gint cur_tb;       /* current transport block (required for dissecting of single TBs */
+    gint cur_chan;  /* current channel, required to retrieve the correct channel configuration for UMTS MAC */
+
     enum   fp_hsdsch_entity hsdsch_entity;
+    enum   fp_link_type link_type;
 } fp_info;
 
index 3ad7c60778a4dcd144b11c8c97c1e3dd1e26fcae..ad13fae12938bd2f4595352168ca992115803d07 100644 (file)
@@ -44,6 +44,7 @@ typedef struct _frame_data {
   guint32      pkt_len;     /* Packet length */
   guint32      cap_len;     /* Amount actually captured */
   guint32      cum_bytes;   /* Cumulative bytes into the capture */
+  guint16      subnum;      /* subframe number, for protocols that require this */
   gint64       file_off;    /* File offset */
   gint8        lnk_t;       /* Per-packet encapsulation/data-link type */
   struct {