aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-pw-satop.c
diff options
context:
space:
mode:
authorJaap Keuter <jaap.keuter@xs4all.nl>2023-10-03 06:07:56 +0000
committerAlexis La Goutte <alexis.lagoutte@gmail.com>2023-10-03 06:07:56 +0000
commitc38e6ecbf6d5e637070453cbfca49b3b104f0094 (patch)
tree082e655a810b7e5e09bf9e802f0a054a4c446de2 /epan/dissectors/packet-pw-satop.c
parent46a7f4c17f5563c9f3c54c6f588bbc73d4496926 (diff)
SAToP: Add optional RTP header handling
Diffstat (limited to 'epan/dissectors/packet-pw-satop.c')
-rw-r--r--epan/dissectors/packet-pw-satop.c126
1 files changed, 98 insertions, 28 deletions
diff --git a/epan/dissectors/packet-pw-satop.c b/epan/dissectors/packet-pw-satop.c
index 6cfe7f7768..1c81483713 100644
--- a/epan/dissectors/packet-pw-satop.c
+++ b/epan/dissectors/packet-pw-satop.c
@@ -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,13 +88,27 @@ void dissect_pw_satop(tvbuff_t * tvb_original
,PAY_LIKE_OCTET_ALIGNED_T1
} payload_properties;
+ switch (demux)
+ {
+ case PWC_DEMUX_MPLS:
+ if (dissect_try_cw_first_nibble(tvb_original, pinfo, tree))
+ {
+ return;
+ }
+ break;
+ case PWC_DEMUX_UDP:
+ break;
+ default:
+ DISSECTOR_ASSERT_NOT_REACHED();
+ return;
+ }
+
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) */
+ 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);
@@ -99,30 +123,59 @@ void dissect_pw_satop(tvbuff_t * tvb_original
switch (demux)
{
case PWC_DEMUX_MPLS:
- if (dissect_try_cw_first_nibble(tvb_original, pinfo, tree))
- {
- return;
- }
+ 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);
}