From Martin Kaiser via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=6890 :
The attached patch for the DVB-CI dissector creates a circuit for each DVB-CI session, using the session number as circuit id. The DVB-CI session commands are: - open_session_request(resource_id) - session_opened(resource_id, newly assigned session number) - payload transfer(session_number, payload data) - close session(session_number) For now, the circuit will store the resource id and make it available (as a generated item) to subsequent packets that contain only the session number. Doing this, the resource id (which is like a tcp/udp port) can be used for filtering. svn path=/trunk/; revision=41253
This commit is contained in:
parent
767ec314a0
commit
7c55e4513a
|
@ -165,7 +165,8 @@ typedef enum {
|
|||
CT_ISUP, /* ISDN User Part CIC */
|
||||
CT_IAX2, /* IAX2 call id */
|
||||
CT_H223, /* H.223 logical channel number */
|
||||
CT_BICC /* BICC Circuit identifier */
|
||||
CT_BICC, /* BICC Circuit identifier */
|
||||
CT_DVBCI /* DVB-CI session number */
|
||||
/* Could also have ATM VPI/VCI pairs */
|
||||
} circuit_type;
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@
|
|||
|
||||
#include <glib.h>
|
||||
#include <epan/addr_resolv.h>
|
||||
#include <epan/circuit.h>
|
||||
#include <epan/packet.h>
|
||||
#include <epan/reassemble.h>
|
||||
#include <epan/prefs.h>
|
||||
|
@ -800,6 +801,10 @@ static int hf_dvbci_spdu_tag = -1;
|
|||
static int hf_dvbci_sess_status = -1;
|
||||
static int hf_dvbci_sess_nb = -1;
|
||||
static int hf_dvbci_close_sess_status = -1;
|
||||
static int hf_dvbci_res_id_type = -1;
|
||||
static int hf_dvbci_res_class = -1;
|
||||
static int hf_dvbci_res_type = -1;
|
||||
static int hf_dvbci_res_ver = -1;
|
||||
static int hf_dvbci_apdu_tag = -1;
|
||||
static int hf_dvbci_app_type = -1;
|
||||
static int hf_dvbci_app_manf = -1;
|
||||
|
@ -2143,13 +2148,34 @@ dissect_dvbci_text(const gchar *title, tvbuff_t *tvb, gint offset,
|
|||
}
|
||||
|
||||
|
||||
static void
|
||||
dissect_dvbci_res_id(tvbuff_t *tvb, gint offset,
|
||||
packet_info *pinfo, proto_tree *tree, guint32 res_id,
|
||||
gboolean show_col_info)
|
||||
static proto_item *
|
||||
dissect_res_id(tvbuff_t *tvb, gint offset, packet_info *pinfo,
|
||||
proto_tree *tree, guint32 res_id, gboolean show_col_info)
|
||||
{
|
||||
proto_item *ti = NULL;
|
||||
proto_tree *res_tree = NULL;
|
||||
gint tvb_data_len;
|
||||
|
||||
/* there's two possible inputs for this function
|
||||
the resource id is either in a tvbuff_t (tvb!=NULL, res_id==0)
|
||||
or in a guint32 (tvb==NULL, res_id!=0) */
|
||||
|
||||
if (tvb) {
|
||||
/* resource id comes in via tvbuff */
|
||||
if (res_id!=0)
|
||||
return NULL;
|
||||
res_id = tvb_get_ntohl(tvb, offset);
|
||||
tvb_data_len = RES_ID_LEN;
|
||||
}
|
||||
else {
|
||||
/* resource id comes in via guint32 */
|
||||
if (res_id==0)
|
||||
return NULL;
|
||||
/* we'll call proto_tree_add_...( tvb==NULL, offset==0, length==0 )
|
||||
this creates a filterable item without any reference to a tvb */
|
||||
offset = 0;
|
||||
tvb_data_len = 0;
|
||||
}
|
||||
|
||||
if (show_col_info) {
|
||||
col_append_sep_fstr(pinfo->cinfo, COL_INFO, NULL, "%s Version %d",
|
||||
|
@ -2159,24 +2185,33 @@ dissect_dvbci_res_id(tvbuff_t *tvb, gint offset,
|
|||
}
|
||||
|
||||
if (tree) {
|
||||
ti = proto_tree_add_text(
|
||||
tree, tvb, offset, RES_ID_LEN, "Resource ID: 0x%04x", res_id);
|
||||
|
||||
ti = proto_tree_add_text(tree, tvb, offset, tvb_data_len,
|
||||
"Resource ID: 0x%04x", res_id);
|
||||
res_tree = proto_item_add_subtree(ti, ett_dvbci_res);
|
||||
|
||||
proto_tree_add_text(res_tree, tvb, 0, 0, "%s",
|
||||
/* parameter "value" == complete resource id,
|
||||
RES_..._MASK will be applied by the hf definition */
|
||||
proto_tree_add_uint_format(res_tree, hf_dvbci_res_id_type,
|
||||
tvb, offset, tvb_data_len, res_id, "%s",
|
||||
decode_numeric_bitfield(res_id, RES_ID_TYPE_MASK, 32,
|
||||
"Resource ID Type: 0x%x"));
|
||||
proto_tree_add_text(res_tree, tvb, 0, 0, "%s",
|
||||
decode_enumerated_bitfield_shifted(res_id, RES_CLASS_MASK, 32,
|
||||
dvbci_res_class, "Resource Class: %s"));
|
||||
proto_tree_add_text(res_tree, tvb, 0, 0, "%s",
|
||||
proto_tree_add_uint_format(res_tree, hf_dvbci_res_class,
|
||||
tvb, offset, tvb_data_len, res_id, "%s (%s)",
|
||||
decode_numeric_bitfield(res_id, RES_CLASS_MASK, 32,
|
||||
"Resource Class: 0x%x"),
|
||||
val_to_str_const(RES_CLASS(res_id), dvbci_res_class,
|
||||
"Invalid Resource class"));
|
||||
proto_tree_add_uint_format(res_tree, hf_dvbci_res_type,
|
||||
tvb, offset, tvb_data_len, res_id, "%s",
|
||||
decode_numeric_bitfield(res_id, RES_TYPE_MASK, 32,
|
||||
"Resource Type: 0x%x"));
|
||||
proto_tree_add_text(res_tree, tvb, 0, 0, "%s",
|
||||
proto_tree_add_uint_format(res_tree, hf_dvbci_res_ver,
|
||||
tvb, offset, tvb_data_len, res_id, "%s",
|
||||
decode_numeric_bitfield(res_id, RES_VER_MASK, 32,
|
||||
"Resource Version: 0x%x"));
|
||||
}
|
||||
|
||||
return ti;
|
||||
}
|
||||
|
||||
/* dissect the body of a resource manager apdu */
|
||||
|
@ -2187,7 +2222,6 @@ dissect_dvbci_payload_rm(guint32 tag, gint len_field,
|
|||
{
|
||||
const gchar *tag_str;
|
||||
proto_item *pi;
|
||||
guint32 res_id;
|
||||
|
||||
if (tag==T_PROFILE) {
|
||||
if (len_field % RES_ID_LEN) {
|
||||
|
@ -2201,8 +2235,7 @@ dissect_dvbci_payload_rm(guint32 tag, gint len_field,
|
|||
}
|
||||
|
||||
while (tvb_reported_length_remaining(tvb, offset) > 0) {
|
||||
res_id = tvb_get_ntohl(tvb, offset);
|
||||
dissect_dvbci_res_id(tvb, offset, pinfo, tree, res_id, FALSE);
|
||||
dissect_res_id(tvb, offset, pinfo, tree, 0, FALSE);
|
||||
offset += RES_ID_LEN;
|
||||
}
|
||||
}
|
||||
|
@ -3583,11 +3616,14 @@ dissect_dvbci_spdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|||
proto_tree *sess_tree = NULL;
|
||||
guint8 tag;
|
||||
const gchar *tag_str;
|
||||
gint offset;
|
||||
circuit_t *circuit = NULL;
|
||||
proto_item *pi;
|
||||
gint offset;
|
||||
guint32 len_field;
|
||||
const spdu_info_t *si;
|
||||
proto_item *res_id_it = NULL;
|
||||
guint32 res_id;
|
||||
guint16 ssnb = 0; /* session numbers start with 1, 0 is invalid */
|
||||
guint8 sess_stat;
|
||||
tvbuff_t *payload_tvb = NULL;
|
||||
gint payload_len;
|
||||
|
@ -3644,33 +3680,40 @@ dissect_dvbci_spdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|||
switch(tag)
|
||||
{
|
||||
case T_OPEN_SESSION_REQUEST:
|
||||
res_id = tvb_get_ntohl(tvb, offset); /* get 32bit big-endian */
|
||||
dissect_dvbci_res_id(tvb, offset, pinfo, sess_tree, res_id, TRUE);
|
||||
res_id_it = dissect_res_id(tvb, offset, pinfo, sess_tree, 0, TRUE);
|
||||
break;
|
||||
case T_CREATE_SESSION:
|
||||
res_id = tvb_get_ntohl(tvb, offset);
|
||||
dissect_dvbci_res_id(tvb, offset, pinfo, sess_tree, res_id, TRUE);
|
||||
res_id_it = dissect_res_id(tvb, offset, pinfo, sess_tree, 0, TRUE);
|
||||
/* DVB-CI uses network byte order == big endian */
|
||||
proto_tree_add_item(
|
||||
sess_tree, hf_dvbci_sess_nb, tvb,
|
||||
offset+4, 2, ENC_BIG_ENDIAN);
|
||||
ssnb = tvb_get_ntohs(tvb, offset+RES_ID_LEN);
|
||||
proto_tree_add_item(sess_tree, hf_dvbci_sess_nb,
|
||||
tvb, offset+RES_ID_LEN, 2, ENC_BIG_ENDIAN);
|
||||
break;
|
||||
case T_OPEN_SESSION_RESPONSE:
|
||||
case T_CREATE_SESSION_RESPONSE:
|
||||
sess_stat = tvb_get_guint8(tvb, offset);
|
||||
proto_tree_add_item(
|
||||
sess_tree, hf_dvbci_sess_status, tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
proto_tree_add_item(sess_tree, hf_dvbci_sess_status,
|
||||
tvb, offset, 1, ENC_BIG_ENDIAN);
|
||||
res_id = tvb_get_ntohl(tvb, offset+1);
|
||||
dissect_dvbci_res_id(tvb, offset+1, pinfo, sess_tree, res_id, TRUE);
|
||||
res_id_it = dissect_res_id(tvb, offset+1, pinfo, sess_tree, 0, TRUE);
|
||||
ssnb = tvb_get_ntohs(tvb, offset+1+RES_ID_LEN);
|
||||
proto_tree_add_item(sess_tree, hf_dvbci_sess_nb, tvb,
|
||||
offset+1+RES_ID_LEN, 2, ENC_BIG_ENDIAN);
|
||||
if (sess_stat == SESS_OPENED)
|
||||
col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
|
||||
"Session opened");
|
||||
else
|
||||
if (sess_stat != SESS_OPENED) {
|
||||
col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Error");
|
||||
break;
|
||||
}
|
||||
col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Session opened");
|
||||
circuit = circuit_new(CT_DVBCI, (guint32)ssnb, pinfo->fd->num);
|
||||
if (circuit) {
|
||||
/* we always add the resource id immediately after the circuit
|
||||
was created */
|
||||
circuit_add_proto_data(
|
||||
circuit, proto_dvbci, GUINT_TO_POINTER(res_id));
|
||||
}
|
||||
break;
|
||||
case T_CLOSE_SESSION_REQUEST:
|
||||
ssnb = tvb_get_ntohs(tvb, offset);
|
||||
proto_tree_add_item(
|
||||
sess_tree, hf_dvbci_sess_nb, tvb,
|
||||
offset, 2, ENC_BIG_ENDIAN);
|
||||
|
@ -3680,17 +3723,17 @@ dissect_dvbci_spdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|||
proto_tree_add_item(
|
||||
sess_tree, hf_dvbci_close_sess_status, tvb,
|
||||
offset, 1, ENC_BIG_ENDIAN);
|
||||
proto_tree_add_item(
|
||||
sess_tree, hf_dvbci_sess_nb, tvb,
|
||||
offset+1, 2, ENC_BIG_ENDIAN);
|
||||
if (sess_stat == SESS_CLOSED) {
|
||||
col_append_sep_str(pinfo->cinfo, COL_INFO, NULL,
|
||||
"Session closed");
|
||||
}
|
||||
else
|
||||
col_append_sep_str(pinfo->cinfo, COL_INFO, NULL, "Error");
|
||||
sess_stat==SESS_CLOSED ? "Session closed" : "Error");
|
||||
ssnb = tvb_get_ntohs(tvb, offset+1);
|
||||
proto_tree_add_item(sess_tree, hf_dvbci_sess_nb,
|
||||
tvb, offset+1, 2, ENC_BIG_ENDIAN);
|
||||
circuit = find_circuit(CT_DVBCI, (guint32)ssnb, pinfo->fd->num);
|
||||
if (circuit)
|
||||
close_circuit(circuit, pinfo->fd->num);
|
||||
break;
|
||||
case T_SESSION_NUMBER:
|
||||
ssnb = tvb_get_ntohs(tvb, offset);
|
||||
proto_tree_add_item(
|
||||
sess_tree, hf_dvbci_sess_nb, tvb,
|
||||
offset, 2, ENC_BIG_ENDIAN);
|
||||
|
@ -3702,6 +3745,19 @@ dissect_dvbci_spdu(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
|
|||
break;
|
||||
}
|
||||
|
||||
if (ssnb && !circuit)
|
||||
circuit = find_circuit(CT_DVBCI, (guint32)ssnb, pinfo->fd->num);
|
||||
|
||||
/* if the packet contains no resource id, we add the cached id from
|
||||
the circuit so that each packet has a resource id that can be
|
||||
used for filtering */
|
||||
if (circuit && !res_id_it) {
|
||||
/* when a circuit is found, it always contains a valid resource id */
|
||||
res_id = GPOINTER_TO_UINT(circuit_get_proto_data(circuit, proto_dvbci));
|
||||
res_id_it = dissect_res_id(NULL, 0, pinfo, sess_tree, res_id, TRUE);
|
||||
PROTO_ITEM_SET_GENERATED(res_id_it);
|
||||
}
|
||||
|
||||
if (payload_tvb) {
|
||||
proto_item_set_len(ti, spdu_len-tvb_reported_length(payload_tvb));
|
||||
dissect_dvbci_apdu(payload_tvb, pinfo, tree, direction);
|
||||
|
@ -4379,6 +4435,18 @@ proto_register_dvbci(void)
|
|||
{ &hf_dvbci_close_sess_status,
|
||||
{ "Session Status", "dvb-ci.close_session_status", FT_UINT8,
|
||||
BASE_HEX, VALS(dvbci_close_sess_status), 0, NULL, HFILL } },
|
||||
{ &hf_dvbci_res_id_type,
|
||||
{ "Resource ID Type", "dvb-ci.res.id_type", FT_UINT32,
|
||||
BASE_HEX, NULL, RES_ID_TYPE_MASK, NULL, HFILL } },
|
||||
{ &hf_dvbci_res_class,
|
||||
{ "Resource Class", "dvb-ci.res.class", FT_UINT32,
|
||||
BASE_HEX, NULL, RES_CLASS_MASK, NULL, HFILL } },
|
||||
{ &hf_dvbci_res_type,
|
||||
{ "Resource Type", "dvb-ci.res.type", FT_UINT32,
|
||||
BASE_HEX, NULL, RES_TYPE_MASK, NULL, HFILL } },
|
||||
{ &hf_dvbci_res_ver,
|
||||
{ "Resource Version", "dvb-ci.res.version", FT_UINT32,
|
||||
BASE_HEX, NULL, RES_VER_MASK, NULL, HFILL } },
|
||||
{ &hf_dvbci_apdu_tag,
|
||||
{ "APDU Tag", "dvb-ci.apdu_tag", FT_UINT24, BASE_HEX,
|
||||
VALS(dvbci_apdu_tag), 0, NULL, HFILL } },
|
||||
|
|
Loading…
Reference in New Issue