2 * RTPproxy command protocol dissector
3 * Copyright 2013, Peter Lemenkov <lemenkov@gmail.com>
5 * This dissector tries to dissect rtpproxy control protocol. Please visit this
6 * link for brief details on the command format:
8 * http://www.rtpproxy.org/wiki/RTPproxy/Protocol
12 * Wireshark - Network traffic analyzer
13 * By Gerald Combs <gerald@wireshark.org>
14 * Copyright 1999 Gerald Combs
16 * This program is free software; you can redistribute it and/or
17 * modify it under the terms of the GNU General Public License
18 * as published by the Free Software Foundation; either version 2
19 * of the License, or (at your option) any later version.
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
35 #include <epan/packet.h>
36 #include <epan/prefs.h>
37 #include <epan/conversation.h>
39 static int proto_rtpproxy
= -1;
41 static int hf_rtpproxy_cookie
= -1;
42 static int hf_rtpproxy_error
= -1;
43 static int hf_rtpproxy_status
= -1;
44 static int hf_rtpproxy_ok
= -1;
45 static int hf_rtpproxy_ipv4
= -1;
46 static int hf_rtpproxy_ipv6
= -1;
47 static int hf_rtpproxy_port
= -1;
48 static int hf_rtpproxy_lf
= -1;
49 static int hf_rtpproxy_request
= -1;
50 static int hf_rtpproxy_command
= -1;
51 static int hf_rtpproxy_command_parameters
= -1;
52 static int hf_rtpproxy_callid
= -1;
53 static int hf_rtpproxy_copy_target
= -1;
54 static int hf_rtpproxy_playback_filename
= -1;
55 static int hf_rtpproxy_playback_codec
= -1;
56 static int hf_rtpproxy_notify
= -1;
57 static int hf_rtpproxy_notify_ipv4
= -1;
58 static int hf_rtpproxy_notify_port
= -1;
59 static int hf_rtpproxy_notify_tag
= -1;
60 static int hf_rtpproxy_tag
= -1;
61 static int hf_rtpproxy_mediaid
= -1;
62 static int hf_rtpproxy_reply
= -1;
63 static int hf_rtpproxy_version_request
= -1;
64 static int hf_rtpproxy_version_supported
= -1;
66 /* Request/response tracking */
67 static int hf_rtpproxy_request_in
= -1;
68 static int hf_rtpproxy_response_in
= -1;
69 static int hf_rtpproxy_response_time
= -1;
71 typedef struct _rtpproxy_info
{
77 typedef struct _rtpproxy_conv_info
{
79 } rtpproxy_conv_info_t
;
82 static const string_string versiontypenames
[] = {
83 { "20040107", "Basic RTP proxy functionality" },
84 { "20050322", "Support for multiple RTP streams and MOH" },
85 { "20060704", "Support for extra parameter in the V command" },
86 { "20071116", "Support for RTP re-packetization" },
87 { "20071218", "Support for forking (copying) RTP stream" },
88 { "20080403", "Support for RTP statistics querying" },
89 { "20081102", "Support for setting codecs in the update/lookup command" },
90 { "20081224", "Support for session timeout notifications" },
91 { "20090810", "Support for automatic bridging" },
95 static const value_string commandtypenames
[] = {
96 { 'V', "Handshake/Ping" },
97 { 'v', "Handshake/Ping" },
98 { 'U', "Offer/Update" },
99 { 'u', "Offer/Update" },
100 { 'L', "Answer/Lookup" },
101 { 'l', "Answer/Lookup" },
102 { 'I', "Information"},
103 { 'i', "Information"},
104 { 'X', "Close all active sessions"},
105 { 'x', "Close all active sessions"},
106 { 'D', "Delete an active session (Bye/Cancel/Error)"},
107 { 'd', "Delete an active session (Bye/Cancel/Error)"},
108 { 'P', "Start playback (music-on-hold)"},
109 { 'p', "Start playback (music-on-hold)"},
110 { 'S', "Stop playback (music-on-hold)"},
111 { 's', "Stop playback (music-on-hold)"},
112 { 'R', "Start recording"},
113 { 'r', "Start recording"},
114 { 'C', "Copy stream"},
115 { 'c', "Copy stream"},
116 { 'Q', "Query info about a session"},
117 { 'q', "Query info about a session"},
121 static const value_string oktypenames
[] = {
123 { '1', "Version Supported"},
127 static const string_string errortypenames
[] = {
128 { "E0", "Syntax error" },
129 { "E1", "Syntax error" },
130 { "E2", "Syntax error" },
131 { "E3", "Unknown command" },
132 { "E4", "Syntax error" },
133 { "E5", "Out of memory" },
134 { "E6", "<no description>" },
135 { "E7", "Software error (can't create listener)" },
136 { "E8", "Not Found" },
137 { "E10", "Software error (can't create listener)" },
138 { "E11", "Out of memory" },
139 { "E12", "Out of memory" },
140 { "E13", "Out of memory" },
141 { "E14", "Out of memory" },
145 static const value_string flowcontroltypenames
[] = {
150 static gint ett_rtpproxy
= -1;
152 static gint ett_rtpproxy_request
= -1;
153 static gint ett_rtpproxy_command
= -1;
154 static gint ett_rtpproxy_tag
= -1;
155 static gint ett_rtpproxy_notify
= -1;
157 static gint ett_rtpproxy_reply
= -1;
159 static guint rtpproxy_tcp_port
= 22222;
160 static guint rtpproxy_udp_port
= 22222;
162 void proto_reg_handoff_rtpproxy(void);
165 rtpptoxy_add_tag(proto_tree
*rtpproxy_tree
, tvbuff_t
*tvb
, guint begin
, guint realsize
)
167 proto_item
*ti
= NULL
;
168 proto_tree
*another_tree
= NULL
;
172 new_offset
= tvb_find_guint8(tvb
, begin
, -1, ' ');
174 end
= realsize
; /* No more parameters */
178 /* SER/OpenSER/OpenSIPS/Kamailio adds Media-ID right after the Tag
179 * separated by a semicolon
181 new_offset
= tvb_find_guint8(tvb
, begin
, end
, ';');
182 if(new_offset
== -1){
183 ti
= proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_tag
, tvb
, begin
, end
- begin
, ENC_ASCII
| ENC_NA
);
184 another_tree
= proto_item_add_subtree(ti
, ett_rtpproxy_tag
);
185 ti
= proto_tree_add_item(another_tree
, hf_rtpproxy_mediaid
, tvb
, new_offset
+1, 0, ENC_ASCII
| ENC_NA
);
186 proto_item_set_text(ti
, "Media-ID: <skipped>");
189 ti
= proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_tag
, tvb
, begin
, new_offset
- begin
, ENC_ASCII
| ENC_NA
);
190 another_tree
= proto_item_add_subtree(ti
, ett_rtpproxy_tag
);
191 proto_tree_add_item(another_tree
, hf_rtpproxy_mediaid
, tvb
, new_offset
+1, end
- (new_offset
+1), ENC_ASCII
| ENC_NA
);
193 return (end
== realsize
? -1 : (gint
)end
);
197 rtpproxy_add_tid(gboolean is_request
, tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*rtpproxy_tree
, rtpproxy_conv_info_t
*rtpproxy_conv
, gchar
* cookie
)
199 rtpproxy_info_t
*rtpproxy_info
;
202 if (!PINFO_FD_VISITED(pinfo
)) {
204 rtpproxy_info
= wmem_new(wmem_file_scope(), rtpproxy_info_t
);
205 rtpproxy_info
->req_frame
= PINFO_FD_NUM(pinfo
);
206 rtpproxy_info
->resp_frame
= 0;
207 rtpproxy_info
->req_time
= pinfo
->fd
->abs_ts
;
208 wmem_tree_insert_string(rtpproxy_conv
->trans
, cookie
, rtpproxy_info
, 0);
210 rtpproxy_info
= (rtpproxy_info_t
*)wmem_tree_lookup_string(rtpproxy_conv
->trans
, cookie
, 0);
212 rtpproxy_info
->resp_frame
= PINFO_FD_NUM(pinfo
);
216 rtpproxy_info
= (rtpproxy_info_t
*)wmem_tree_lookup_string(rtpproxy_conv
->trans
, cookie
, 0);
217 if (rtpproxy_info
&& (is_request
? rtpproxy_info
->resp_frame
: rtpproxy_info
->req_frame
)) {
220 pi
= proto_tree_add_uint(rtpproxy_tree
, is_request
? hf_rtpproxy_response_in
: hf_rtpproxy_request_in
, tvb
, 0, 0, is_request
? rtpproxy_info
->resp_frame
: rtpproxy_info
->req_frame
);
221 PROTO_ITEM_SET_GENERATED(pi
);
223 /* If reply then calculate response time */
225 nstime_delta(&ns
, &pinfo
->fd
->abs_ts
, &rtpproxy_info
->req_time
);
226 pi
= proto_tree_add_time(rtpproxy_tree
, hf_rtpproxy_response_time
, tvb
, 0, 0, &ns
);
227 PROTO_ITEM_SET_GENERATED(pi
);
234 dissect_rtpproxy(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void *data _U_
)
236 gboolean has_lf
= FALSE
;
244 proto_tree
*rtpproxy_tree
;
245 conversation_t
*conversation
;
246 rtpproxy_conv_info_t
*rtpproxy_conv
;
247 gchar
* cookie
= NULL
;
249 /* If it does not start with a printable character it's not RTPProxy */
250 if(!isprint(tvb_get_guint8(tvb
, 0)))
254 offset
= tvb_find_guint8(tvb
, offset
, -1, ' ');
258 /* Clear out stuff in the info column - we''l set it later */
259 col_clear(pinfo
->cinfo
, COL_INFO
);
261 ti
= proto_tree_add_item(tree
, proto_rtpproxy
, tvb
, 0, -1, ENC_NA
);
262 rtpproxy_tree
= proto_item_add_subtree(ti
, ett_rtpproxy
);
264 proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_cookie
, tvb
, 0, offset
, ENC_ASCII
| ENC_NA
);
265 cookie
= tvb_get_string(wmem_packet_scope(), tvb
, 0, offset
);
267 /* Skip whitespace */
268 offset
= tvb_skip_wsp(tvb
, offset
+1, -1);
270 /* Calculate size to prevent recalculation in the future */
271 realsize
= tvb_reported_length(tvb
);
273 /* Check for LF (required for TCP connection, optional for UDP) */
274 if (tvb_get_guint8(tvb
, realsize
- 1) == '\n'){
275 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "RTPproxy");
276 /* Don't count trailing LF */
281 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "RTPproxy (no LF)");
283 /* Try to create conversation */
284 conversation
= find_or_create_conversation(pinfo
);
285 rtpproxy_conv
= (rtpproxy_conv_info_t
*)conversation_get_proto_data(conversation
, proto_rtpproxy
);
286 if (!rtpproxy_conv
) {
287 rtpproxy_conv
= wmem_new(wmem_file_scope(), rtpproxy_conv_info_t
);
288 rtpproxy_conv
->trans
= wmem_tree_new(wmem_file_scope());
289 conversation_add_proto_data(conversation
, proto_rtpproxy
, rtpproxy_conv
);
292 /* Get payload string */
293 rawstr
= tvb_get_string(wmem_packet_scope(), tvb
, offset
, realsize
- offset
);
295 /* Extract command */
296 tmp
= g_ascii_tolower(tvb_get_guint8(tvb
, offset
));
300 /* A specific case - long statistics answer */
301 /* %COOKIE% sessions created %NUM0% active sessions: %NUM1% */
302 rtpproxy_add_tid(FALSE
, tvb
, pinfo
, rtpproxy_tree
, rtpproxy_conv
, cookie
);
303 if ('e' == tvb_get_guint8(tvb
, offset
+1)){
304 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Reply: %s", rawstr
);
305 ti
= proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_reply
, tvb
, offset
, -1, ENC_NA
);
307 rtpproxy_tree
= proto_item_add_subtree(ti
, ett_rtpproxy_reply
);
308 proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_status
, tvb
, offset
, realsize
- offset
, ENC_ASCII
| ENC_NA
);
321 rtpproxy_add_tid(TRUE
, tvb
, pinfo
, rtpproxy_tree
, rtpproxy_conv
, cookie
);
322 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Request: %s", rawstr
);
323 ti
= proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_request
, tvb
, offset
, -1, ENC_NA
);
324 rtpproxy_tree
= proto_item_add_subtree(ti
, ett_rtpproxy_request
);
326 /* A specific case - version request */
327 if ((tmp
== 'v') && (offset
+ (gint
)strlen("VF YYYMMDD") + 1 == realsize
)){
328 /* Skip whitespace */
329 new_offset
= tvb_skip_wsp(tvb
, offset
+ ((guint
)strlen("VF") + 1), -1);
330 ti
= proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_version_request
, tvb
, new_offset
, (gint
)strlen("YYYYMMDD"), ENC_ASCII
| ENC_NA
);
331 tmpstr
= tvb_get_string(wmem_packet_scope(), tvb
, new_offset
, (gint
)strlen("YYYYMMDD"));
332 proto_item_append_text(ti
, " (%s)", str_to_str(tmpstr
, versiontypenames
, "Unknown"));
336 /* All other commands */
337 ti
= proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_command
, tvb
, offset
, 1, ENC_NA
);
339 /* A specific case - handshake/ping */
341 break; /* No more parameters */
343 /* A specific case - close all calls */
345 break; /* No more parameters */
347 /* Extract parameters */
348 /* Parameters should be right after the command and before EOL (in case of Info command) or before whitespace */
349 new_offset
= (tmp
== 'i' ? (realsize
- 1 > offset
? offset
+ (gint
)strlen("Ib") : offset
+ (gint
)strlen("I")) : tvb_find_guint8(tvb
, offset
, -1, ' '));
351 if (new_offset
!= offset
+ 1){
352 rtpproxy_tree
= proto_item_add_subtree(ti
, ett_rtpproxy_command
);
353 proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_command_parameters
, tvb
, offset
+1, new_offset
- (offset
+1), ENC_ASCII
| ENC_NA
);
354 rtpproxy_tree
= proto_item_get_parent(ti
);
357 /* A specific case - query information */
359 break; /* No more parameters */
361 /* Skip whitespace */
362 offset
= tvb_skip_wsp(tvb
, new_offset
+1, -1);
364 /* Extract Call-ID */
365 new_offset
= tvb_find_guint8(tvb
, offset
, -1, ' ');
366 proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_callid
, tvb
, offset
, new_offset
- offset
, ENC_ASCII
| ENC_NA
);
367 /* Skip whitespace */
368 offset
= tvb_skip_wsp(tvb
, new_offset
+1, -1);
370 /* Extract IP and Port in case of Offer/Answer */
371 if ((tmp
== 'u') || (tmp
== 'l')){
373 new_offset
= tvb_find_guint8(tvb
, offset
, -1, ' ');
374 if (tvb_find_guint8(tvb
, offset
, new_offset
- offset
, ':') == -1)
375 proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_ipv4
, tvb
, offset
, new_offset
- offset
, ENC_ASCII
| ENC_NA
);
377 proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_ipv6
, tvb
, offset
, new_offset
- offset
, ENC_ASCII
| ENC_NA
);
378 /* Skip whitespace */
379 offset
= tvb_skip_wsp(tvb
, new_offset
+1, -1);
382 new_offset
= tvb_find_guint8(tvb
, offset
, -1, ' ');
383 proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_port
, tvb
, offset
, new_offset
- offset
, ENC_ASCII
| ENC_NA
);
384 /* Skip whitespace */
385 offset
= tvb_skip_wsp(tvb
, new_offset
+1, -1);
388 /* Extract Copy target */
390 new_offset
= tvb_find_guint8(tvb
, offset
, -1, ' ');
391 proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_copy_target
, tvb
, offset
, new_offset
- offset
, ENC_ASCII
| ENC_NA
);
392 /* Skip whitespace */
393 offset
= tvb_skip_wsp(tvb
, new_offset
+1, -1);
396 /* Extract Playback file and codecs */
398 /* Extract filename */
399 new_offset
= tvb_find_guint8(tvb
, offset
, -1, ' ');
400 proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_playback_filename
, tvb
, offset
, new_offset
- offset
, ENC_ASCII
| ENC_NA
);
401 /* Skip whitespace */
402 offset
= tvb_skip_wsp(tvb
, new_offset
+1, -1);
405 new_offset
= tvb_find_guint8(tvb
, offset
, -1, ' ');
406 proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_playback_codec
, tvb
, offset
, new_offset
- offset
, ENC_ASCII
| ENC_NA
);
407 /* Skip whitespace */
408 offset
= tvb_skip_wsp(tvb
, new_offset
+1, -1);
411 /* Extract first tag */
412 new_offset
= rtpptoxy_add_tag(rtpproxy_tree
, tvb
, offset
, realsize
);
414 break; /* No more parameters */
415 /* Skip whitespace */
416 offset
= tvb_skip_wsp(tvb
, new_offset
+1, -1);
418 /* Extract second tag */
419 new_offset
= rtpptoxy_add_tag(rtpproxy_tree
, tvb
, offset
, realsize
);
421 break; /* No more parameters */
422 /* Skip whitespace */
423 offset
= tvb_skip_wsp(tvb
, new_offset
+1, -1);
425 /* Extract Notification address */
427 new_offset
= tvb_find_guint8(tvb
, offset
, -1, ' ');
428 ti
= proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_notify
, tvb
, offset
, realsize
- offset
, ENC_ASCII
| ENC_NA
);
429 proto_item_set_text(ti
, "Notify");
430 rtpproxy_tree
= proto_item_add_subtree(ti
, ett_rtpproxy_notify
);
431 if(new_offset
== -1){
432 /* FIXME only IPv4 is supported */
433 new_offset
= tvb_find_guint8(tvb
, offset
, -1, ':');
434 proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_notify_ipv4
, tvb
, offset
, new_offset
- offset
, ENC_ASCII
| ENC_NA
);
435 proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_notify_port
, tvb
, new_offset
+1, realsize
- (new_offset
+1), ENC_ASCII
| ENC_NA
);
436 break; /* No more parameters */
438 if(new_offset
- offset
< 6){
439 /* Only port is supplied */
440 ti
= proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_notify_ipv4
, tvb
, offset
, 0, ENC_ASCII
| ENC_NA
);
441 proto_item_set_text(ti
, "Notification IPv4: <skipped>");
442 proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_notify_port
, tvb
, offset
, new_offset
- offset
, ENC_ASCII
| ENC_NA
);
445 proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_notify_ipv4
, tvb
, offset
, new_offset
- offset
, ENC_ASCII
| ENC_NA
);
446 proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_notify_port
, tvb
, new_offset
+1, realsize
- (new_offset
+1), ENC_ASCII
| ENC_NA
);
448 /* Skip whitespace */
449 offset
= tvb_skip_wsp(tvb
, new_offset
+1, -1);
451 proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_notify_tag
, tvb
, offset
, realsize
- offset
, ENC_ASCII
| ENC_NA
);
466 rtpproxy_add_tid(FALSE
, tvb
, pinfo
, rtpproxy_tree
, rtpproxy_conv
, cookie
);
468 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Error reply: %s", rawstr
);
470 col_add_fstr(pinfo
->cinfo
, COL_INFO
, "Reply: %s", rawstr
);
472 ti
= proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_reply
, tvb
, offset
, -1, ENC_NA
);
473 rtpproxy_tree
= proto_item_add_subtree(ti
, ett_rtpproxy_reply
);
476 tmp
= tvb_find_line_end(tvb
, offset
, -1, &new_offset
, FALSE
);
477 tmpstr
= tvb_get_string(wmem_packet_scope(), tvb
, offset
, tmp
);
478 ti
= proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_error
, tvb
, offset
, (gint
)strlen(tmpstr
), ENC_ASCII
| ENC_NA
);
479 proto_item_append_text(ti
, " (%s)", str_to_str(tmpstr
, errortypenames
, "Unknown"));
484 /* A specific case - short statistics answer */
485 /* %COOKIE% active sessions: %NUM1% */
486 proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_status
, tvb
, offset
, realsize
- offset
, ENC_ASCII
| ENC_NA
);
489 if ((tmp
== '0')&& ((tvb_reported_length(tvb
) == (guint
)(offset
+1))||(tvb_reported_length(tvb
) == (guint
)(offset
+2)))){
490 proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_ok
, tvb
, offset
, 1, ENC_ASCII
| ENC_NA
);
493 if ((tmp
== '1') && ((tvb_reported_length(tvb
) == (guint
)(offset
+1))||(tvb_reported_length(tvb
) == (guint
)(offset
+2)))){
494 proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_ok
, tvb
, offset
, 1, ENC_ASCII
| ENC_NA
);
497 if (tvb_reported_length(tvb
) == (guint
)(offset
+9)){
498 proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_version_supported
, tvb
, offset
, 8, ENC_ASCII
| ENC_NA
);
503 new_offset
= tvb_find_guint8(tvb
, offset
, -1, ' ');
504 proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_port
, tvb
, offset
, new_offset
- offset
, ENC_ASCII
| ENC_NA
);
505 /* Skip whitespace */
506 offset
= tvb_skip_wsp(tvb
, new_offset
+1, -1);
509 tmp
= tvb_find_line_end(tvb
, offset
, -1, &new_offset
, FALSE
);
510 if (tvb_find_guint8(tvb
, offset
, -1, ':') == -1)
511 proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_ipv4
, tvb
, offset
, tmp
, ENC_ASCII
| ENC_NA
);
513 proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_ipv6
, tvb
, offset
, tmp
, ENC_ASCII
| ENC_NA
);
519 proto_tree_add_item(rtpproxy_tree
, hf_rtpproxy_lf
, tvb
, realsize
, 1, ENC_NA
);
521 return tvb_length(tvb
);
525 proto_register_rtpproxy(void)
527 module_t
*rtpproxy_module
;
529 static hf_register_info hf
[] = {
544 &hf_rtpproxy_version_request
,
557 &hf_rtpproxy_version_supported
,
560 "rtpproxy.version_supported",
648 &hf_rtpproxy_request
,
661 &hf_rtpproxy_command
,
667 VALS(commandtypenames
),
674 &hf_rtpproxy_command_parameters
,
676 "Command parameters",
677 "rtpproxy.command_parameters",
687 &hf_rtpproxy_copy_target
,
690 "rtpproxy.copy_target",
700 &hf_rtpproxy_playback_filename
,
703 "rtpproxy.playback_filename",
713 &hf_rtpproxy_playback_codec
,
716 "rtpproxy.playback_codec",
765 &hf_rtpproxy_mediaid
,
778 &hf_rtpproxy_notify_ipv4
,
781 "rtpproxy.notify_ipv4",
791 &hf_rtpproxy_notify_port
,
794 "rtpproxy.notify_port",
804 &hf_rtpproxy_notify_tag
,
807 "rtpproxy.notify_tag",
836 VALS(flowcontroltypenames
),
843 &hf_rtpproxy_request_in
,
846 "rtpproxy.request_in",
857 &hf_rtpproxy_response_in
,
860 "rtpproxy.response_in",
870 &hf_rtpproxy_response_time
,
873 "rtpproxy.response_time",
878 "The time between the Request and the Reply",
884 /* Setup protocol subtree array */
885 static gint
*ett
[] = {
887 &ett_rtpproxy_request
,
888 &ett_rtpproxy_command
,
890 &ett_rtpproxy_notify
,
894 proto_rtpproxy
= proto_register_protocol (
895 "Sippy RTPproxy Protocol", /* name */
896 "RTPproxy", /* short name */
897 "rtpproxy" /* abbrev */
900 proto_register_field_array(proto_rtpproxy
, hf
, array_length(hf
));
901 proto_register_subtree_array(ett
, array_length(ett
));
903 rtpproxy_module
= prefs_register_protocol(proto_rtpproxy
, proto_reg_handoff_rtpproxy
);
904 prefs_register_uint_preference(rtpproxy_module
, "tcp.port",
905 "RTPproxy TCP Port", /* Title */
906 "RTPproxy TCP Port", /* Descr */
910 prefs_register_uint_preference(rtpproxy_module
, "udp.port",
911 "RTPproxy UDP Port", /* Title */
912 "RTPproxy UDP Port", /* Descr */
918 proto_reg_handoff_rtpproxy(void)
920 static guint old_rtpproxy_tcp_port
= 0;
921 static guint old_rtpproxy_udp_port
= 0;
923 static gboolean rtpproxy_initialized
= FALSE
;
925 static dissector_handle_t rtpproxy_tcp_handle
, rtpproxy_udp_handle
;
927 if(!rtpproxy_initialized
){
928 rtpproxy_tcp_handle
= new_create_dissector_handle(dissect_rtpproxy
, proto_rtpproxy
);
929 rtpproxy_udp_handle
= new_create_dissector_handle(dissect_rtpproxy
, proto_rtpproxy
);
930 rtpproxy_initialized
= TRUE
;
933 /* Register TCP port for dissection */
934 if(old_rtpproxy_tcp_port
!= 0 && old_rtpproxy_tcp_port
!= rtpproxy_tcp_port
)
935 dissector_delete_uint("tcp.port", old_rtpproxy_tcp_port
, rtpproxy_tcp_handle
);
936 if(rtpproxy_tcp_port
!= 0 && old_rtpproxy_tcp_port
!= rtpproxy_tcp_port
)
937 dissector_add_uint("tcp.port", rtpproxy_tcp_port
, rtpproxy_tcp_handle
);
938 old_rtpproxy_tcp_port
= rtpproxy_tcp_port
;
940 /* Register UDP port for dissection */
941 if(old_rtpproxy_udp_port
!= 0 && old_rtpproxy_udp_port
!= rtpproxy_udp_port
)
942 dissector_delete_uint("udp.port", old_rtpproxy_udp_port
, rtpproxy_udp_handle
);
943 if(rtpproxy_udp_port
!= 0 && old_rtpproxy_udp_port
!= rtpproxy_udp_port
)
944 dissector_add_uint("udp.port", rtpproxy_udp_port
, rtpproxy_udp_handle
);
945 old_rtpproxy_udp_port
= rtpproxy_udp_port
;
949 * Editor modelines - http://www.wireshark.org/tools/modelines.html
954 * indent-tabs-mode: t
957 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
958 * :indentSize=8:tabSize=8:noTabs=false: