From: Kriang Lerdsuwanakij
authorlego <lego@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 8 Feb 2007 17:35:03 +0000 (17:35 +0000)
committerlego <lego@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 8 Feb 2007 17:35:03 +0000 (17:35 +0000)
In the attached patch, the K12 wiretap now saves the content of record
after captured packet data. The K12 dissector then could extract them and provide
useful information to properly dissect FP frames (user plane of UTRAN Iub
interface).

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@20749 f5534014-38df-0310-8fa8-9805f1628bb7

epan/dissectors/packet-k12.c
epan/dissectors/packet-umts_fp.h
wiretap/k12.c
wiretap/wtap.h

index f0692697708d400991c2d094d75446982fbd727b..f6f2984587168fe95b6de3e691dcaad21235e661 100644 (file)
@@ -40,6 +40,7 @@
 #include <epan/expert.h>
 #include <epan/strutil.h>
 #include "packet-sscop.h"
+#include "packet-umts_fp.h"
 
 typedef struct _k12_hdls_t {
        char* match;
@@ -66,8 +67,10 @@ static gint ett_stack_item = -1;
 static dissector_handle_t k12_handle;
 static dissector_handle_t data_handle;
 static dissector_handle_t sscop_handle;
+static dissector_handle_t fp_handle;
 
 extern int proto_sscop;
+extern int proto_fp;
 
 static emem_tree_t* port_handles = NULL;
 static uat_t* k12_uat = NULL;
@@ -81,6 +84,85 @@ static const value_string  k12_port_types[] = {
        { 0,NULL}
 };
 
+static void fill_fp_info(fp_info *p_fp_info, guchar *extra_info, guint length) {
+                       /* 0x11=control frame 0x30=data frame */
+       guint info_type = pntohs(extra_info);
+                       /* 1=FDD, 2=TDD 3.84, 3=TDD 1.28 */
+       guchar radio_mode = extra_info[14];
+       guchar channel_type = 0;
+       guint i;
+
+       if (!p_fp_info || length < 22)
+               return;
+
+       p_fp_info->release = 0; /* dummy */
+       p_fp_info->dct2000_variant = 0; /* dummy */
+
+                               /* 1=UL, 2=DL */
+       if (extra_info[15] == 1)
+               p_fp_info->is_uplink = 1;
+       else
+               p_fp_info->is_uplink = 0;
+
+       if (info_type == 0x11) /* control frame */
+               channel_type = extra_info[21];
+       else if (info_type == 0x30) /* data frame */
+               channel_type = extra_info[22];
+       switch (channel_type) {
+               case 1:
+                       p_fp_info->channel = CHANNEL_BCH;
+                       break;
+               case 2:
+                       p_fp_info->channel = CHANNEL_PCH;
+                       p_fp_info->paging_indications = 0; /* dummy */
+                       break;
+               case 3:
+                       p_fp_info->channel = CHANNEL_CPCH;
+                       break;
+               case 4:
+                       if (radio_mode == 1)
+                               p_fp_info->channel = CHANNEL_RACH_FDD;
+                       else if (radio_mode == 2)
+                               p_fp_info->channel = CHANNEL_RACH_TDD;
+                       else
+                               p_fp_info->channel = CHANNEL_RACH_TDD_128;
+                       break;
+               case 5:
+                       if (radio_mode == 1)
+                               p_fp_info->channel = CHANNEL_FACH_FDD;
+                       else
+                               p_fp_info->channel = CHANNEL_FACH_TDD;
+                       break;
+               case 6:
+                       if (radio_mode == 2)
+                               p_fp_info->channel = CHANNEL_USCH_TDD_384;
+                       else
+                               p_fp_info->channel = CHANNEL_USCH_TDD_128;
+                       break;
+               case 7:
+                       if (radio_mode == 1)
+                               p_fp_info->channel = CHANNEL_DSCH_FDD;
+                       else
+                               p_fp_info->channel = CHANNEL_DSCH_TDD;
+                       break;
+               case 8:
+                       p_fp_info->channel = CHANNEL_DCH;
+                       break;
+       }
+                       
+       p_fp_info->dch_crc_present = 1; /* dummy */
+
+       if (info_type == 0x30) { /* data frame */
+               p_fp_info->num_chans = extra_info[23];
+               for (i = 0; i < (guint)p_fp_info->num_chans && (36+i*104) <= length; ++i) {
+                       p_fp_info->chan_tf_size[i] = pntohl(extra_info+28+i*104);
+                       if (p_fp_info->chan_tf_size[i])
+                               p_fp_info->chan_num_tbs[i] = pntohl(extra_info+32+i*104)
+                                                            / p_fp_info->chan_tf_size[i];
+               }
+       }
+}
+
 static void dissect_k12(tvbuff_t* tvb,packet_info* pinfo,proto_tree* tree) {
        static dissector_handle_t data_handles[] = {NULL,NULL};
        proto_item* k12_item;
@@ -165,26 +247,38 @@ static void dissect_k12(tvbuff_t* tvb,packet_info* pinfo,proto_tree* tree) {
                PROTO_ITEM_SET_GENERATED(item);
        }
        
-       sub_handle = handles[0];
-
        /* Setup subdissector information */
                
        for (i = 0; handles[i] && handles[i+1]; ++i) {
                if (handles[i] == sscop_handle) {
                        sscop_payload_info *p_sscop_info = p_get_proto_data(pinfo->fd, proto_sscop);
-                       if (p_sscop_info)
-                               p_sscop_info->subdissector = handles[i+1];
-                       else {
+                       if (!p_sscop_info) {
                                p_sscop_info = ep_alloc0(sizeof(sscop_payload_info));
-                               if (p_sscop_info) {
-                                       p_sscop_info->subdissector = handles[i+1];
+                               if (p_sscop_info)
                                        p_add_proto_data(pinfo->fd, proto_sscop, p_sscop_info);
-                               }
                        }
+                       if (p_sscop_info)
+                               p_sscop_info->subdissector = handles[i+1];
                }
                /* Add more protocols here */
        }
 
+       sub_handle = handles[0];
+
+       /* Setup information required by certain protocols */
+       if (sub_handle == fp_handle) {
+               fp_info *p_fp_info = p_get_proto_data(pinfo->fd, proto_fp);
+               if (!p_fp_info) {
+                       p_fp_info = ep_alloc0(sizeof(fp_info));
+                       if (p_fp_info)
+                               p_add_proto_data(pinfo->fd, proto_fp, p_fp_info);
+               }
+
+               fill_fp_info(p_fp_info,
+                            pinfo->pseudo_header->k12.extra_info,
+                            pinfo->pseudo_header->k12.extra_length);
+       }
+
        call_dissector(sub_handle, tvb, pinfo, tree);
 }
 
@@ -272,6 +366,7 @@ static void initialize_handles_once(void) {
                k12_handle = find_dissector("k12");
                data_handle = find_dissector("data");
                sscop_handle = find_dissector("sscop");
+               fp_handle = find_dissector("fp");
                initialized = TRUE;
        }
 }
index aec9697ede5871c3a219c73b60ee267602d2436b..c7013a7279fa221cac7802b2022720b23b990cd6 100644 (file)
@@ -63,3 +63,4 @@ struct _fp_info
     guint  edch_macd_pdu_size[MAX_EDCH_DDIS];
 };
 
+typedef struct _fp_info fp_info;
index 8e3cd93cc42a11de12da4ae6b913125b5f1c9158..0d21fec8a5af322497af76d2a8563f5f462261db 100644 (file)
@@ -120,6 +120,8 @@ struct _k12_t {
        
        GHashTable* src_by_id; /* k12_srcdsc_recs by input */
        GHashTable* src_by_name; /* k12_srcdsc_recs by stack_name */
+
+       Buffer extra_info; /* Buffer to hold per packet extra information */
 };
 
 typedef struct _k12_src_desc_t {
@@ -302,6 +304,7 @@ static gboolean k12_read(wtap *wth, int *err, gchar **err_info _U_, gint64 *data
        long len;
        guint32 type;
        guint64 ts;
+       guint32 extra_len;
        
        offset = wth->data_offset;
     
@@ -346,11 +349,19 @@ static gboolean k12_read(wtap *wth, int *err, gchar **err_info _U_, gint64 *data
 #endif
     
        wth->phdr.len = wth->phdr.caplen = pntohl(buffer + K12_RECORD_FRAME_LEN) & 0x00001FFF;
+       extra_len = len - K12_PACKET_FRAME - wth->phdr.caplen;
        
        /* the frame */
        buffer_assure_space(wth->frame_buffer, wth->phdr.caplen);
        memcpy(buffer_start_ptr(wth->frame_buffer), buffer + K12_PACKET_FRAME, wth->phdr.caplen);
        
+       /* extra information need by some protocols */
+       buffer_assure_space(&(wth->capture.k12->extra_info), extra_len);
+       memcpy(buffer_start_ptr(&(wth->capture.k12->extra_info)),
+              buffer + K12_PACKET_FRAME + wth->phdr.caplen, extra_len);
+       wth->pseudo_header.k12.extra_info = buffer_start_ptr(&(wth->capture.k12->extra_info));
+       wth->pseudo_header.k12.extra_length = extra_len;
+
        wth->pseudo_header.k12.input = pntohl(buffer + K12_RECORD_INPUT);
     
 #ifdef DEBUG_K12
@@ -403,7 +414,8 @@ static gboolean k12_seek_read(wtap *wth, gint64 seek_off, union wtap_pseudo_head
        k12_src_desc_t* src_desc;
        guint8 buffer[0x2000];
        long len;
-    guint32 input;
+       guint32 extra_len;
+       guint32 input;
     
 #ifdef DEBUG_K12
     k12_dbg(5,"k12_seek_read: ENTER");
@@ -424,6 +436,17 @@ static gboolean k12_seek_read(wtap *wth, gint64 seek_off, union wtap_pseudo_head
        }
        
        memcpy(pd, buffer + K12_PACKET_FRAME, length);
+
+       extra_len = len - K12_PACKET_FRAME - length;
+       buffer_assure_space(&(wth->capture.k12->extra_info), extra_len);
+       memcpy(buffer_start_ptr(&(wth->capture.k12->extra_info)),
+              buffer + K12_PACKET_FRAME + length, extra_len);
+       wth->pseudo_header.k12.extra_info = buffer_start_ptr(&(wth->capture.k12->extra_info));
+       wth->pseudo_header.k12.extra_length = extra_len;
+       if (pseudo_header) {
+               pseudo_header->k12.extra_info = buffer_start_ptr(&(wth->capture.k12->extra_info));
+               pseudo_header->k12.extra_length = extra_len;
+       }
        
     input = pntohl(buffer + K12_RECORD_INPUT);
 #ifdef DEBUG_K12
@@ -517,6 +540,8 @@ static k12_t* new_k12_file_data() {
        fd->num_of_records = 0;
        fd->src_by_name = g_hash_table_new(g_str_hash,g_str_equal);
        fd->src_by_id = g_hash_table_new(g_direct_hash,g_direct_equal);
+
+       buffer_init(&(fd->extra_info), 100);
        
        return fd;
 }
@@ -539,6 +564,7 @@ static void destroy_k12_file_data(k12_t* fd) {
        g_hash_table_destroy(fd->src_by_id);
        g_hash_table_foreach_remove(fd->src_by_name,destroy_srcdsc,NULL);       
        g_hash_table_destroy(fd->src_by_name);
+       buffer_free(&(fd->extra_info));
        g_free(fd);
 }
 
@@ -705,7 +731,7 @@ int k12_open(wtap *wth, int *err, gchar **err_info _U_) {
        wth->subtype_close = k12_close;
        wth->capture.k12 = file_data;
        wth->tsprecision = WTAP_FILE_TSPREC_NSEC;       
-       
+
        return 1;
 }
 
index 4b612863a287d96b720ddfa80b851ab6b1cd222c..1136d1d19277b6e7fd7cd76f969090823495c1d3 100644 (file)
@@ -520,6 +520,8 @@ struct k12_phdr {
        const gchar* stack_file;
        guint32 input_type;
        k12_input_info_t input_info;
+       gchar* extra_info;
+       guint32 extra_length;
        void* stuff;
 };