diff options
-rw-r--r-- | epan/dissectors/packet-k12.c | 111 | ||||
-rw-r--r-- | epan/dissectors/packet-umts_fp.h | 1 | ||||
-rw-r--r-- | wiretap/k12.c | 30 | ||||
-rw-r--r-- | wiretap/wtap.h | 2 |
4 files changed, 134 insertions, 10 deletions
diff --git a/epan/dissectors/packet-k12.c b/epan/dissectors/packet-k12.c index f069269770..f6f2984587 100644 --- a/epan/dissectors/packet-k12.c +++ b/epan/dissectors/packet-k12.c @@ -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; } } diff --git a/epan/dissectors/packet-umts_fp.h b/epan/dissectors/packet-umts_fp.h index aec9697ede..c7013a7279 100644 --- a/epan/dissectors/packet-umts_fp.h +++ b/epan/dissectors/packet-umts_fp.h @@ -63,3 +63,4 @@ struct _fp_info guint edch_macd_pdu_size[MAX_EDCH_DDIS]; }; +typedef struct _fp_info fp_info; diff --git a/wiretap/k12.c b/wiretap/k12.c index 8e3cd93cc4..0d21fec8a5 100644 --- a/wiretap/k12.c +++ b/wiretap/k12.c @@ -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; } diff --git a/wiretap/wtap.h b/wiretap/wtap.h index 4b612863a2..1136d1d192 100644 --- a/wiretap/wtap.h +++ b/wiretap/wtap.h @@ -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; }; |