epan/dissectors/pidl/samr/samr.cnf cnf_dissect_lsa_BinaryString => lsarpc_dissect_str...
[wireshark-sm.git] / epan / dissectors / packet-nb_rtpmux.c
blob541eefb34226971588c7b875c4ddee256bb7d8cd
1 /* packet-nb_rtpmux.c
2 * Routines for 3GPP RTP Multiplex dissection, 3GPP TS 29.414
3 * Copyright 2009, ip.access ltd <amp@ipaccess.com>
5 * Wireshark - Network traffic analyzer
6 * By Gerald Combs <gerald@wireshark.org>
7 * Copyright 1998 Gerald Combs
9 * SPDX-License-Identifier: GPL-2.0-or-later
12 #include "config.h"
14 #include <epan/packet.h>
16 void proto_register_nb_rtpmux(void);
17 void proto_reg_handoff_nb_rtpmux(void);
19 /* Initialize the protocol and registered fields */
20 static int proto_nb_rtpmux;
21 static int hf_nb_rtpmux_compressed;
22 static int hf_nb_rtpmux_dstport;
23 static int hf_nb_rtpmux_length;
24 static int hf_nb_r_bit;
25 static int hf_nb_rtpmux_srcport;
26 static int hf_nb_rtpmux_data;
27 static int hf_nb_rtpmux_cmp_rtp_sequence_no;
28 static int hf_nb_rtpmux_cmp_rtp_timestamp;
29 static int hf_nb_rtpmux_cmp_rtp_data;
31 /* Initialize the subtree pointers */
32 static int ett_nb_rtpmux;
33 static int ett_nb_rtpmux_cmp_rtp_hdr;
35 static dissector_handle_t nb_rtpmux_handle;
36 static dissector_handle_t rtpdissector;
38 static int
39 dissect_nb_rtpmux(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
41 /* Set up structures needed to add the protocol subtree and manage it */
42 proto_item *ti;
43 proto_tree *nb_rtpmux_tree, *nb_rtpmux_cmp_rtp_tree;
44 unsigned int offset = 0;
45 bool first_rtp_payload_seen = false;
47 /* First, if at all possible, do some heuristics to check if the packet cannot
48 * possibly belong to your protocol. This is especially important for
49 * protocols directly on top of TCP or UDP where port collisions are
50 * common place (e.g., even though your protocol uses a well known port,
51 * someone else may set up, for example, a web server on that port which,
52 * if someone analyzed that web server's traffic in Wireshark, would result
53 * in Wireshark handing an HTTP packet to your dissector). For example:
57 * XXX - this is *FAR* too weak a heuristic; it could cause all sorts
58 * of stuff to be incorrectly identified as Nb_RTPmux. Either this
59 * needs a stronger heuristic, or it needs to have a preference to
60 * set the port on which to dissect it, or it needs to be a non-heuristic
61 * dissector and *require* that a user use "Decode As..." to decode
62 * traffic as Nb_RTPmux.
64 * Look for a payload that looks like an RTP packet, using the
65 * same (weakish) heuristics as RTP uses?
68 /* Check that there's enough data */
69 if (tvb_captured_length(tvb) < 6)
70 return 0;
72 /* Make entries in Protocol column and Info column on summary display */
73 col_set_str(pinfo->cinfo, COL_PROTOCOL, "NB_RTPMUX");
75 /* NOTE: The offset and length values in the call to
76 "proto_tree_add_item()" define what data bytes to highlight in the hex
77 display window when the line in the protocol tree display
78 corresponding to that item is selected.
80 Supplying a length of -1 is the way to highlight all data from the
81 offset to the end of the packet. */
83 /* create display subtree for the protocol */
84 while (offset < tvb_reported_length(tvb)-5)
86 uint16_t dstport, srcport;
87 unsigned int length;
88 int captured_length;
89 tvbuff_t *next_tvb;
90 bool tbit;
92 length = tvb_get_uint8(tvb, offset+2);
93 ti = proto_tree_add_item(tree, proto_nb_rtpmux, tvb, offset, length+5, ENC_NA);
94 nb_rtpmux_tree = proto_item_add_subtree(ti, ett_nb_rtpmux);
96 /* T bit */
97 proto_tree_add_item(nb_rtpmux_tree, hf_nb_rtpmux_compressed, tvb, offset, 2, ENC_BIG_ENDIAN);
98 tbit = tvb_get_uint8(tvb,offset)>>7;
99 if(tbit == 1){
100 /* 6.4.2.4 Transport Format for multiplexing with RTP header compression */
101 dstport = (tvb_get_ntohs(tvb, offset) & 0x7fff) << 1;
102 proto_tree_add_uint(nb_rtpmux_tree, hf_nb_rtpmux_dstport, tvb, offset, 2, dstport );
103 proto_tree_add_item(nb_rtpmux_tree, hf_nb_rtpmux_length, tvb, offset+2, 1, ENC_BIG_ENDIAN);
104 proto_tree_add_item(nb_rtpmux_tree, hf_nb_r_bit, tvb, offset+3, 2, ENC_BIG_ENDIAN);
105 srcport = (tvb_get_ntohs(tvb, offset+3) & 0x7fff) << 1;
106 proto_tree_add_uint(nb_rtpmux_tree, hf_nb_rtpmux_srcport, tvb, offset+3, 2, srcport );
107 nb_rtpmux_cmp_rtp_tree = proto_tree_add_subtree( nb_rtpmux_tree, tvb, offset+5, 3, ett_nb_rtpmux_cmp_rtp_hdr, NULL, "Compressed RTP header" );
108 /* Sequence Number (SN) */
109 proto_tree_add_item(nb_rtpmux_cmp_rtp_tree, hf_nb_rtpmux_cmp_rtp_sequence_no, tvb, offset+5, 1, ENC_BIG_ENDIAN);
110 /* Timestamp (TS) */
111 proto_tree_add_item(nb_rtpmux_cmp_rtp_tree, hf_nb_rtpmux_cmp_rtp_timestamp, tvb, offset+6, 2, ENC_BIG_ENDIAN);
112 if (length != 0)
113 proto_tree_add_item(nb_rtpmux_cmp_rtp_tree, hf_nb_rtpmux_cmp_rtp_data,tvb, offset+8, length-3, ENC_NA);
115 /* Not trying to decompress... */
117 /* Add summary to protocol root */
118 proto_item_append_text(ti, ", Src Port: %u, Dst Port: %u Length: %u", srcport, dstport, length);
120 }else{
121 /* 6.4.2.3 Transport Format for multiplexing without RTP Header Compression */
122 dstport = (tvb_get_ntohs(tvb, offset) & 0x7fff) << 1;
123 proto_tree_add_uint(nb_rtpmux_tree, hf_nb_rtpmux_dstport, tvb, offset, 2, dstport );
124 proto_tree_add_item(nb_rtpmux_tree,
125 hf_nb_rtpmux_length, tvb, offset+2, 1, ENC_BIG_ENDIAN);
126 proto_tree_add_item(nb_rtpmux_tree, hf_nb_r_bit, tvb, offset+3, 1, ENC_BIG_ENDIAN);
127 srcport = (tvb_get_ntohs(tvb, offset+3) & 0x7fff) << 1;
128 proto_tree_add_uint(nb_rtpmux_tree, hf_nb_rtpmux_srcport, tvb, offset+3, 2, srcport );
130 /* Add summary to protocol root */
131 proto_item_append_text(ti, ", Src Port: %u, Dst Port: %u Length: %u", srcport, dstport, length);
133 if (length != 0)
135 /* We have an RTP payload. */
136 if (rtpdissector)
138 captured_length = tvb_reported_length_remaining(tvb, offset + 5);
139 if (captured_length > (int)length)
140 captured_length = length;
141 next_tvb = tvb_new_subset_length_caplen(tvb, offset+5, captured_length,
142 length);
144 if (first_rtp_payload_seen)
146 /* Don't want to clear the column, instead show where multiple
147 RTP frames are being carried */
148 col_append_str(pinfo->cinfo, COL_INFO, " | ");
149 col_set_fence(pinfo->cinfo, COL_INFO);
152 call_dissector(rtpdissector, next_tvb, pinfo, nb_rtpmux_tree);
154 first_rtp_payload_seen = true;
156 else
158 proto_tree_add_item(nb_rtpmux_tree,
159 hf_nb_rtpmux_data, tvb, offset+5, length, ENC_NA);
162 } /* if tbit */
163 offset += 5+length;
166 /* Return the amount of data this dissector was able to dissect */
167 return tvb_reported_length(tvb);
171 /* Register the protocol with Wireshark */
173 void
174 proto_register_nb_rtpmux(void)
177 static hf_register_info hf[] = {
178 { &hf_nb_rtpmux_compressed,
179 { "Compressed headers(T bit)", "nb_rtpmux.compressed",
180 FT_BOOLEAN, 16, NULL, 0x8000,
181 NULL, HFILL }
183 { &hf_nb_rtpmux_dstport,
184 { "Dst port", "nb_rtpmux.dstport",
185 FT_UINT16, BASE_DEC, NULL, 0x0,
186 NULL, HFILL }
188 { &hf_nb_rtpmux_length,
189 { "Length", "nb_rtpmux.length",
190 FT_UINT8, BASE_DEC, NULL, 0x00,
191 NULL, HFILL }
193 { &hf_nb_r_bit,
194 { "R bit", "nb_rtpmux.r_bit",
195 FT_BOOLEAN, 16, NULL, 0x8000,
196 NULL, HFILL }
198 { &hf_nb_rtpmux_srcport,
199 { "Src port", "nb_rtpmux.srcport",
200 FT_UINT16, BASE_DEC, NULL, 0x0,
201 NULL, HFILL }
203 { &hf_nb_rtpmux_data,
204 { "RTP Packet", "nb_rtpmux.data",
205 FT_BYTES, BASE_NONE, NULL, 0x00,
206 NULL, HFILL }
208 { &hf_nb_rtpmux_cmp_rtp_sequence_no,
209 { "Sequence Number", "nb_rtpmux.cmp_rtp.sequence_no",
210 FT_UINT16, BASE_DEC, NULL, 0x00,
211 NULL, HFILL }
213 { &hf_nb_rtpmux_cmp_rtp_timestamp,
214 { "Timestamp", "nb_rtpmux.cmp_rtp.timestamp",
215 FT_UINT16, BASE_DEC, NULL, 0x00,
216 NULL, HFILL }
218 { &hf_nb_rtpmux_cmp_rtp_data,
219 { "RTP Data", "nb_rtpmux.cmp_rtp.data",
220 FT_BYTES, BASE_NONE, NULL, 0x00,
221 NULL,HFILL }
226 /* Setup protocol subtree array */
227 static int *ett[] = {
228 &ett_nb_rtpmux,
229 &ett_nb_rtpmux_cmp_rtp_hdr
232 /* Register the protocol name and description */
233 proto_nb_rtpmux = proto_register_protocol("3GPP Nb Interface RTP Multiplex", "NB_RTPMUX", "nb_rtpmux");
234 nb_rtpmux_handle = register_dissector("nb_rtpmux", dissect_nb_rtpmux, proto_nb_rtpmux);
236 /* Required function calls to register the header fields and subtrees used */
237 proto_register_field_array(proto_nb_rtpmux, hf, array_length(hf));
238 proto_register_subtree_array(ett, array_length(ett));
241 void
242 proto_reg_handoff_nb_rtpmux(void)
244 dissector_add_uint_range_with_preference("udp.port", "", nb_rtpmux_handle);
246 rtpdissector = find_dissector_add_dependency("rtp", proto_nb_rtpmux);
250 * Editor modelines - https://www.wireshark.org/tools/modelines.html
252 * Local variables:
253 * c-basic-offset: 4
254 * tab-width: 8
255 * indent-tabs-mode: nil
256 * End:
258 * vi: set shiftwidth=4 tabstop=8 expandtab:
259 * :indentSize=4:tabSize=8:noTabs=true: