aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--epan/dissectors/packet-k12.c111
-rw-r--r--epan/dissectors/packet-umts_fp.h1
-rw-r--r--wiretap/k12.c30
-rw-r--r--wiretap/wtap.h2
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;
};