HACK: pinfo->private_data points to smb_info again
[wireshark-wip.git] / epan / dissectors / packet-rtpproxy.c
blobcf1667a7ef8449e1ba996afa2d09b10b820b87e8
1 /* packet-rtpproxy.c
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
10 * $Id$
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.
31 #include "config.h"
33 #include <ctype.h>
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 {
72 guint32 req_frame;
73 guint32 resp_frame;
74 nstime_t req_time;
75 } rtpproxy_info_t;
77 typedef struct _rtpproxy_conv_info {
78 wmem_tree_t *trans;
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" },
92 { 0, NULL }
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"},
118 { 0, NULL }
121 static const value_string oktypenames[] = {
122 { '0', "Ok"},
123 { '1', "Version Supported"},
124 { 0, NULL }
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" },
142 { 0, NULL }
145 static const value_string flowcontroltypenames[] = {
146 { '\n', "Yes"},
147 { 0, NULL }
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);
164 gint
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;
169 gint new_offset;
170 guint end;
172 new_offset = tvb_find_guint8(tvb, begin, -1, ' ');
173 if(new_offset < 0)
174 end = realsize; /* No more parameters */
175 else
176 end = new_offset;
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>");
188 else{
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);
196 void
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;
200 proto_item *pi;
202 if (!PINFO_FD_VISITED(pinfo)) {
203 if (is_request){
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);
209 } else {
210 rtpproxy_info = (rtpproxy_info_t *)wmem_tree_lookup_string(rtpproxy_conv->trans, cookie, 0);
211 if (rtpproxy_info) {
212 rtpproxy_info->resp_frame = PINFO_FD_NUM(pinfo);
215 } else {
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)) {
218 nstime_t ns;
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 */
224 if (!is_request){
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);
233 static int
234 dissect_rtpproxy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
236 gboolean has_lf = FALSE;
237 gint offset = 0;
238 gint new_offset = 0;
239 guint tmp;
240 gint realsize = 0;
241 guint8* rawstr;
242 guint8* tmpstr;
243 proto_item *ti;
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)))
251 return 0;
253 /* Extract Cookie */
254 offset = tvb_find_guint8(tvb, offset, -1, ' ');
255 if(offset == -1)
256 return 0;
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 */
277 realsize -= 1;
278 has_lf = TRUE;
280 else
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));
297 switch (tmp)
299 case 's':
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);
309 break;
311 case 'i':
312 case 'x':
313 case 'u':
314 case 'l':
315 case 'd':
316 case 'p':
317 case 'v':
318 case 'r':
319 case 'c':
320 case 'q':
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"));
333 break;
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 */
340 if (tmp == 'v')
341 break; /* No more parameters */
343 /* A specific case - close all calls */
344 if (tmp == 'x')
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 */
358 if (tmp == 'i')
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')){
372 /* Extract IP */
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);
376 else
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);
381 /* Extract Port */
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 */
389 if (tmp == 'c'){
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 */
397 if (tmp == 'p'){
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);
404 /* Extract codec */
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);
413 if(new_offset == -1)
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);
420 if(new_offset == -1)
421 break; /* No more parameters */
422 /* Skip whitespace */
423 offset = tvb_skip_wsp(tvb, new_offset+1, -1);
425 /* Extract Notification address */
426 if (tmp == 'u'){
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);
444 else{
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);
453 break;
454 case 'a':
455 case 'e':
456 case '0':
457 case '1':
458 case '2':
459 case '3':
460 case '4':
461 case '5':
462 case '6':
463 case '7':
464 case '8':
465 case '9':
466 rtpproxy_add_tid(FALSE, tvb, pinfo, rtpproxy_tree, rtpproxy_conv, cookie);
467 if (tmp == 'e')
468 col_add_fstr(pinfo->cinfo, COL_INFO, "Error reply: %s", rawstr);
469 else
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);
475 if (tmp == 'e'){
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"));
480 break;
483 if (tmp == 'a'){
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);
487 break;
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);
491 break;
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);
495 break;
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);
499 break;
502 /* Extract Port */
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);
508 /* Extract IP */
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);
512 else
513 proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_ipv6, tvb, offset, tmp, ENC_ASCII | ENC_NA);
514 break;
515 default:
516 break;
518 if (has_lf)
519 proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_lf, tvb, realsize, 1, ENC_NA);
521 return tvb_length(tvb);
524 void
525 proto_register_rtpproxy(void)
527 module_t *rtpproxy_module;
529 static hf_register_info hf[] = {
531 &hf_rtpproxy_cookie,
533 "Cookie",
534 "rtpproxy.cookie",
535 FT_STRING,
536 BASE_NONE,
537 NULL,
538 0x0,
539 NULL,
540 HFILL
544 &hf_rtpproxy_version_request,
546 "Version Request",
547 "rtpproxy.version",
548 FT_STRING,
549 BASE_NONE,
550 NULL,
551 0x0,
552 NULL,
553 HFILL
557 &hf_rtpproxy_version_supported,
559 "Version Supported",
560 "rtpproxy.version_supported",
561 FT_STRING,
562 BASE_NONE,
563 NULL,
564 0x0,
565 NULL,
566 HFILL
570 &hf_rtpproxy_error,
572 "Error",
573 "rtpproxy.error",
574 FT_STRING,
575 BASE_NONE,
576 NULL,
577 0x0,
578 NULL,
579 HFILL
583 &hf_rtpproxy_ok,
585 "Ok",
586 "rtpproxy.ok",
587 FT_UINT8,
588 BASE_DEC,
589 VALS(oktypenames),
590 0x0,
591 NULL,
592 HFILL
596 &hf_rtpproxy_status,
598 "Status",
599 "rtpproxy.status",
600 FT_STRING,
601 BASE_NONE,
602 NULL,
603 0x0,
604 NULL,
605 HFILL
609 &hf_rtpproxy_ipv4,
611 "IPv4",
612 "rtpproxy.ipv4",
613 FT_STRING,
614 BASE_NONE,
615 NULL,
616 0x0,
617 NULL,
618 HFILL
622 &hf_rtpproxy_ipv6,
624 "IPv6",
625 "rtpproxy.ipv6",
626 FT_STRING,
627 BASE_NONE,
628 NULL,
629 0x0,
630 NULL,
631 HFILL
635 &hf_rtpproxy_port,
637 "Port",
638 "rtpproxy.port",
639 FT_STRING,
640 BASE_NONE,
641 NULL,
642 0x0,
643 NULL,
644 HFILL
648 &hf_rtpproxy_request,
650 "Request",
651 "rtpproxy.request",
652 FT_NONE,
653 BASE_NONE,
654 NULL,
655 0x0,
656 NULL,
657 HFILL
661 &hf_rtpproxy_command,
663 "Command",
664 "rtpproxy.command",
665 FT_UINT8,
666 BASE_DEC,
667 VALS(commandtypenames),
668 0x0,
669 NULL,
670 HFILL
674 &hf_rtpproxy_command_parameters,
676 "Command parameters",
677 "rtpproxy.command_parameters",
678 FT_STRING,
679 BASE_NONE,
680 NULL,
681 0x0,
682 NULL,
683 HFILL
687 &hf_rtpproxy_copy_target,
689 "Copy target",
690 "rtpproxy.copy_target",
691 FT_STRING,
692 BASE_NONE,
693 NULL,
694 0x0,
695 NULL,
696 HFILL
700 &hf_rtpproxy_playback_filename,
702 "Playback filename",
703 "rtpproxy.playback_filename",
704 FT_STRING,
705 BASE_NONE,
706 NULL,
707 0x0,
708 NULL,
709 HFILL
713 &hf_rtpproxy_playback_codec,
715 "Playback codec",
716 "rtpproxy.playback_codec",
717 FT_STRING,
718 BASE_NONE,
719 NULL,
720 0x0,
721 NULL,
722 HFILL
726 &hf_rtpproxy_callid,
728 "Call-ID",
729 "rtpproxy.callid",
730 FT_STRING,
731 BASE_NONE,
732 NULL,
733 0x0,
734 NULL,
735 HFILL
739 &hf_rtpproxy_notify,
741 "Notify",
742 "rtpproxy.notify",
743 FT_STRING,
744 BASE_NONE,
745 NULL,
746 0x0,
747 NULL,
748 HFILL
752 &hf_rtpproxy_tag,
754 "Tag",
755 "rtpproxy.tag",
756 FT_STRING,
757 BASE_NONE,
758 NULL,
759 0x0,
760 NULL,
761 HFILL
765 &hf_rtpproxy_mediaid,
767 "Media-ID",
768 "rtpproxy.mediaid",
769 FT_STRING,
770 BASE_NONE,
771 NULL,
772 0x0,
773 NULL,
774 HFILL
778 &hf_rtpproxy_notify_ipv4,
780 "Notification IPv4",
781 "rtpproxy.notify_ipv4",
782 FT_STRING,
783 BASE_NONE,
784 NULL,
785 0x0,
786 NULL,
787 HFILL
791 &hf_rtpproxy_notify_port,
793 "Notification Port",
794 "rtpproxy.notify_port",
795 FT_STRING,
796 BASE_NONE,
797 NULL,
798 0x0,
799 NULL,
800 HFILL
804 &hf_rtpproxy_notify_tag,
806 "Notification Tag",
807 "rtpproxy.notify_tag",
808 FT_STRING,
809 BASE_NONE,
810 NULL,
811 0x0,
812 NULL,
813 HFILL
817 &hf_rtpproxy_reply,
819 "Reply",
820 "rtpproxy.reply",
821 FT_NONE,
822 BASE_NONE,
823 NULL,
824 0x0,
825 NULL,
826 HFILL
830 &hf_rtpproxy_lf,
832 "LF",
833 "rtpproxy.lf",
834 FT_UINT8,
835 BASE_DEC,
836 VALS(flowcontroltypenames),
837 0x0,
838 NULL,
839 HFILL
843 &hf_rtpproxy_request_in,
845 "Request In",
846 "rtpproxy.request_in",
847 FT_FRAMENUM,
848 BASE_NONE,
849 NULL,
850 0x0,
851 NULL,
852 HFILL
857 &hf_rtpproxy_response_in,
859 "Response In",
860 "rtpproxy.response_in",
861 FT_FRAMENUM,
862 BASE_NONE,
863 NULL,
864 0x0,
865 NULL,
866 HFILL
870 &hf_rtpproxy_response_time,
872 "Response Time",
873 "rtpproxy.response_time",
874 FT_RELATIVE_TIME,
875 BASE_NONE,
876 NULL,
877 0x0,
878 "The time between the Request and the Reply",
879 HFILL
884 /* Setup protocol subtree array */
885 static gint *ett[] = {
886 &ett_rtpproxy,
887 &ett_rtpproxy_request,
888 &ett_rtpproxy_command,
889 &ett_rtpproxy_tag,
890 &ett_rtpproxy_notify,
891 &ett_rtpproxy_reply
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 */
908 &rtpproxy_tcp_port);
910 prefs_register_uint_preference(rtpproxy_module, "udp.port",
911 "RTPproxy UDP Port", /* Title */
912 "RTPproxy UDP Port", /* Descr */
914 &rtpproxy_udp_port);
917 void
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
951 * Local variables:
952 * c-basic-offset: 8
953 * tab-width: 8
954 * indent-tabs-mode: t
955 * End:
957 * vi: set shiftwidth=8 tabstop=8 noexpandtab:
958 * :indentSize=8:tabSize=8:noTabs=false: