SAToP: Add optional RTP header handling
This commit is contained in:
parent
46a7f4c17f
commit
c38e6ecbf6
|
@ -14,7 +14,6 @@
|
|||
* 14.08.2009 added: support for IP/UDP demultiplexing
|
||||
* Not supported yet:
|
||||
* - Decoding of PW payload
|
||||
* - Optional RTP Headers (RFC3550)
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
@ -24,6 +23,9 @@
|
|||
|
||||
#include "packet-mpls.h"
|
||||
#include "packet-pw-common.h"
|
||||
#include "packet-rtp.h"
|
||||
|
||||
#define SIZEOF_RTP 12
|
||||
|
||||
void proto_register_pw_satop(void);
|
||||
void proto_reg_handoff_pw_satop(void);
|
||||
|
@ -53,9 +55,12 @@ static dissector_handle_t pw_padding_handle;
|
|||
static dissector_handle_t pw_satop_udp_handle;
|
||||
static dissector_handle_t pw_satop_mpls_handle;
|
||||
|
||||
const char pwc_longname_pw_satop[] = "SAToP";
|
||||
static const char shortname[] = "SAToP";
|
||||
|
||||
const char pwc_longname_pw_satop[] = "SAToP (no RTP support)";
|
||||
static const char shortname[] = "SAToP (no RTP)";
|
||||
/* Preferences */
|
||||
static gboolean pref_has_rtp_header = FALSE;
|
||||
static gboolean pref_heuristic_rtp_header = TRUE;
|
||||
|
||||
|
||||
static
|
||||
|
@ -64,11 +69,16 @@ void dissect_pw_satop(tvbuff_t * tvb_original
|
|||
,proto_tree * tree
|
||||
,pwc_demux_type_t demux)
|
||||
{
|
||||
const int encaps_size = 4; /*RTP header in encapsulation is not supported yet*/
|
||||
int min_packet_size_this_dissector = PWC_SIZEOF_CW;
|
||||
int encaps_size;
|
||||
gint packet_size;
|
||||
gint rtp_header_offset;
|
||||
gint cw_offset;
|
||||
gint payload_size;
|
||||
gint padding_size;
|
||||
int properties;
|
||||
guint16 sn;
|
||||
gboolean has_rtp_header;
|
||||
|
||||
enum {
|
||||
PAY_NO_IDEA = 0
|
||||
|
@ -78,24 +88,6 @@ void dissect_pw_satop(tvbuff_t * tvb_original
|
|||
,PAY_LIKE_OCTET_ALIGNED_T1
|
||||
} payload_properties;
|
||||
|
||||
packet_size = tvb_reported_length_remaining(tvb_original, 0);
|
||||
/*
|
||||
* FIXME
|
||||
* "4" below should be replaced by something like "min_packet_size_this_dissector"
|
||||
* Also call to dissect_try_cw_first_nibble() should be moved before this block
|
||||
*/
|
||||
if (packet_size < 4) /* 4 is smallest size which may be sensible (for PWACH dissector) */
|
||||
{
|
||||
proto_item *item;
|
||||
item = proto_tree_add_item(tree, proto, tvb_original, 0, -1, ENC_NA);
|
||||
expert_add_info_format(pinfo, item, &ei_cw_packet_size_too_small,
|
||||
"PW packet size (%d) is too small to carry sensible information"
|
||||
,(int)packet_size);
|
||||
col_set_str(pinfo->cinfo, COL_PROTOCOL, shortname);
|
||||
col_set_str(pinfo->cinfo, COL_INFO, "Malformed: PW packet is too small");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (demux)
|
||||
{
|
||||
case PWC_DEMUX_MPLS:
|
||||
|
@ -111,18 +103,79 @@ void dissect_pw_satop(tvbuff_t * tvb_original
|
|||
return;
|
||||
}
|
||||
|
||||
packet_size = tvb_reported_length_remaining(tvb_original, 0);
|
||||
if (pref_has_rtp_header) {
|
||||
min_packet_size_this_dissector += SIZEOF_RTP;
|
||||
}
|
||||
|
||||
if (packet_size < min_packet_size_this_dissector)
|
||||
{
|
||||
proto_item *item;
|
||||
item = proto_tree_add_item(tree, proto, tvb_original, 0, -1, ENC_NA);
|
||||
expert_add_info_format(pinfo, item, &ei_cw_packet_size_too_small,
|
||||
"PW packet size (%d) is too small to carry sensible information"
|
||||
,(int)packet_size);
|
||||
col_set_str(pinfo->cinfo, COL_PROTOCOL, shortname);
|
||||
col_set_str(pinfo->cinfo, COL_INFO, "Malformed: PW packet is too small");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (demux)
|
||||
{
|
||||
case PWC_DEMUX_MPLS:
|
||||
rtp_header_offset = PWC_SIZEOF_CW;
|
||||
sn = tvb_get_guint16(tvb_original, 2, ENC_BIG_ENDIAN);
|
||||
break;
|
||||
case PWC_DEMUX_UDP:
|
||||
rtp_header_offset = 0;
|
||||
sn = tvb_get_guint16(tvb_original, SIZEOF_RTP + 2, ENC_BIG_ENDIAN);
|
||||
break;
|
||||
default:
|
||||
DISSECTOR_ASSERT_NOT_REACHED();
|
||||
return;
|
||||
}
|
||||
|
||||
if ((pref_has_rtp_header) ||
|
||||
((pref_heuristic_rtp_header) &&
|
||||
/* Check for RTP version 2, the other fields must be zero */
|
||||
(tvb_get_guint8(tvb_original, rtp_header_offset) == 0x80) &&
|
||||
/* Check the marker is zero. Unfortnately PT is not always from the dynamic range */
|
||||
((tvb_get_guint8(tvb_original, rtp_header_offset + 1) & 0x80) == 0) &&
|
||||
/* The sequence numbers from cw and RTP header must match */
|
||||
(tvb_get_ntohs(tvb_original, rtp_header_offset + 2) == sn)))
|
||||
{
|
||||
switch (demux)
|
||||
{
|
||||
case PWC_DEMUX_MPLS:
|
||||
cw_offset = 0;
|
||||
break;
|
||||
case PWC_DEMUX_UDP:
|
||||
cw_offset = SIZEOF_RTP;
|
||||
break;
|
||||
default:
|
||||
DISSECTOR_ASSERT_NOT_REACHED();
|
||||
return;
|
||||
}
|
||||
encaps_size = PWC_SIZEOF_CW + SIZEOF_RTP;
|
||||
has_rtp_header = TRUE;
|
||||
} else {
|
||||
cw_offset = 0;
|
||||
encaps_size = PWC_SIZEOF_CW;
|
||||
has_rtp_header = FALSE;
|
||||
}
|
||||
|
||||
/* check how "good" is this packet */
|
||||
/* also decide payload length from packet size and CW */
|
||||
/* also decide payload length from packet size, CW and optional RTP header */
|
||||
properties = 0;
|
||||
if (0 != (tvb_get_guint8(tvb_original, 0) & 0xf0 /*bits03*/))
|
||||
if (0 != (tvb_get_guint8(tvb_original, cw_offset) & 0xf0 /*bits03*/))
|
||||
{
|
||||
properties |= PWC_CW_BAD_BITS03;
|
||||
}
|
||||
if (0 != (tvb_get_guint8(tvb_original, 0) & 0x03 /*rsv*/))
|
||||
if (0 != (tvb_get_guint8(tvb_original, cw_offset) & 0x03 /*rsv*/))
|
||||
{
|
||||
properties |= PWC_CW_BAD_RSV;
|
||||
}
|
||||
if (0 != (tvb_get_guint8(tvb_original, 1) & 0xc0 /*frag*/))
|
||||
if (0 != (tvb_get_guint8(tvb_original, cw_offset + 1) & 0xc0 /*frag*/))
|
||||
{
|
||||
properties |= PWC_CW_BAD_FRAG;
|
||||
}
|
||||
|
@ -142,7 +195,7 @@ void dissect_pw_satop(tvbuff_t * tvb_original
|
|||
int cw_len;
|
||||
gint payload_size_from_packet;
|
||||
|
||||
cw_len = tvb_get_guint8(tvb_original, 1) & 0x3f;
|
||||
cw_len = tvb_get_guint8(tvb_original, cw_offset + 1) & 0x3f;
|
||||
payload_size_from_packet = packet_size - encaps_size;
|
||||
if (cw_len != 0)
|
||||
{
|
||||
|
@ -186,7 +239,7 @@ void dissect_pw_satop(tvbuff_t * tvb_original
|
|||
* not blame packets with bad payload (including "bad" or "strange" SIZE of
|
||||
* payload) when L bit is set.
|
||||
*/
|
||||
if (0 == (tvb_get_guint8(tvb_original, 0) & 0x08 /*L bit*/))
|
||||
if (0 == (tvb_get_guint8(tvb_original, cw_offset) & 0x08 /*L bit*/))
|
||||
{
|
||||
properties |= PWC_PAY_SIZE_BAD;
|
||||
}
|
||||
|
@ -240,17 +293,22 @@ void dissect_pw_satop(tvbuff_t * tvb_original
|
|||
{
|
||||
proto_item* item;
|
||||
item = proto_tree_add_item(tree, proto, tvb_original, 0, -1, ENC_NA);
|
||||
pwc_item_append_cw(item,tvb_get_ntohl(tvb_original, 0),TRUE);
|
||||
pwc_item_append_text_n_items(item,(int)payload_size,"octet");
|
||||
pwc_item_append_cw(item, tvb_get_ntohl(tvb_original, cw_offset), TRUE);
|
||||
pwc_item_append_text_n_items(item, (int)payload_size, "octet");
|
||||
{
|
||||
proto_tree* tree2;
|
||||
tree2 = proto_item_add_subtree(item, ett_pw_satop);
|
||||
if (has_rtp_header && demux == PWC_DEMUX_UDP)
|
||||
{
|
||||
dissect_rtp_shim_header(tvb_original, 0, pinfo, tree2, NULL);
|
||||
}
|
||||
|
||||
{
|
||||
tvbuff_t* tvb;
|
||||
proto_item* item2;
|
||||
tvb = tvb_new_subset_length(tvb_original, 0, PWC_SIZEOF_CW);
|
||||
tvb = tvb_new_subset_length(tvb_original, cw_offset, PWC_SIZEOF_CW);
|
||||
item2 = proto_tree_add_item(tree2, hf_cw, tvb, 0, -1, ENC_NA);
|
||||
pwc_item_append_cw(item2, tvb_get_ntohl(tvb, 0),FALSE);
|
||||
pwc_item_append_cw(item2, tvb_get_ntohl(tvb, 0), FALSE);
|
||||
{
|
||||
proto_tree* tree3;
|
||||
tree3 = proto_item_add_subtree(item2, ett_pw_satop);
|
||||
|
@ -262,8 +320,8 @@ void dissect_pw_satop(tvbuff_t * tvb_original
|
|||
expert_add_info(pinfo, item3, &ei_cw_bits03);
|
||||
}
|
||||
|
||||
proto_tree_add_item(tree3, hf_cw_l , tvb, 0, 1, ENC_BIG_ENDIAN);
|
||||
proto_tree_add_item(tree3, hf_cw_r , tvb, 0, 1, ENC_BIG_ENDIAN);
|
||||
proto_tree_add_item(tree3, hf_cw_l, tvb, 0, 1, ENC_BIG_ENDIAN);
|
||||
proto_tree_add_item(tree3, hf_cw_r, tvb, 0, 1, ENC_BIG_ENDIAN);
|
||||
|
||||
item3 = proto_tree_add_item(tree3, hf_cw_rsv, tvb, 0, 1, ENC_BIG_ENDIAN);
|
||||
if (properties & PWC_CW_BAD_RSV)
|
||||
|
@ -301,6 +359,11 @@ void dissect_pw_satop(tvbuff_t * tvb_original
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (has_rtp_header && demux != PWC_DEMUX_UDP)
|
||||
{
|
||||
dissect_rtp_shim_header(tvb_original, PWC_SIZEOF_CW, pinfo, tree2, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/* payload */
|
||||
|
@ -321,9 +384,9 @@ void dissect_pw_satop(tvbuff_t * tvb_original
|
|||
{
|
||||
proto_item* item2;
|
||||
tvbuff_t* tvb;
|
||||
tvb = tvb_new_subset_length(tvb_original, PWC_SIZEOF_CW, payload_size);
|
||||
tvb = tvb_new_subset_length(tvb_original, encaps_size, payload_size);
|
||||
item2 = proto_tree_add_item(tree2, hf_payload, tvb, 0, -1, ENC_NA);
|
||||
pwc_item_append_text_n_items(item2,(int)payload_size,"octet");
|
||||
pwc_item_append_text_n_items(item2, (int)payload_size, "octet");
|
||||
{
|
||||
proto_tree* tree3;
|
||||
const char* s;
|
||||
|
@ -443,6 +506,8 @@ void proto_register_pw_satop(void)
|
|||
{ &ei_payload_size_invalid, { "pwsatop.payload.size_invalid", PI_MALFORMED, PI_ERROR, "Bad Length: too small", EXPFILL }},
|
||||
{ &ei_payload_size_invalid_undecoded, { "pwsatop.payload.undecoded", PI_UNDECODED, PI_NOTE, "SAToP payload: omitted to conserve bandwidth", EXPFILL }},
|
||||
};
|
||||
|
||||
module_t *pwsatop_module;
|
||||
expert_module_t* expert_pwsatop;
|
||||
|
||||
proto = proto_register_protocol(pwc_longname_pw_satop, shortname, "pwsatopcw");
|
||||
|
@ -450,6 +515,11 @@ void proto_register_pw_satop(void)
|
|||
proto_register_subtree_array(ett_array, array_length(ett_array));
|
||||
expert_pwsatop = expert_register_protocol(proto);
|
||||
expert_register_field_array(expert_pwsatop, ei, array_length(ei));
|
||||
pwsatop_module = prefs_register_protocol(proto, NULL);
|
||||
prefs_register_bool_preference(pwsatop_module, "rtp_header", "RTP header in SAToP header",
|
||||
"Whether or not the RTP header is present in the SAToP header.", &pref_has_rtp_header);
|
||||
prefs_register_bool_preference(pwsatop_module, "rtp_header_heuristic", "Try to find RTP header in SAToP header",
|
||||
"Heuristically determine if an RTP header is present in the SAToP header.", &pref_heuristic_rtp_header);
|
||||
pw_satop_mpls_handle = register_dissector("pw_satop_mpls", dissect_pw_satop_mpls, proto);
|
||||
pw_satop_udp_handle = register_dissector("pw_satop_udp", dissect_pw_satop_udp, proto);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue