From Tobias Witek:

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
This commit is contained in:
Anders Broman 2009-11-05 21:54:06 +00:00
parent 110a5be310
commit 54aa776069
10 changed files with 243 additions and 57 deletions

View File

@ -54,13 +54,17 @@
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");
}

View File

@ -25,6 +25,22 @@
#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 */

View 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 \

View 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 } },

View 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 } },

View File

@ -62,6 +62,10 @@
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");
}

View 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 */

View 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");
}

View 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;

View 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 {