Blame wireshark-0006-From-Peter-Lemenkov-via-https-bugs.wireshark.org-bug.patch

173888
From 1b67a9195503e6f22429a46e98def1dd31a05451 Mon Sep 17 00:00:00 2001
1444df
From: Evan Huus <eapache@gmail.com>
1444df
Date: Sun, 18 Aug 2013 19:49:08 +0000
173888
Subject: [PATCH] From Peter Lemenkov via
1444df
 https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8326
1444df
1444df
Dissector for the Sippy RTPproxy controlling protocol. RTPproxy is a well-known
1444df
(among SIP-engineers) application and it operates using its own simple
1444df
text-based protocol. There are several competing products but all of them
1444df
implements it (sometimes slightly extending).
1444df
1444df
svn path=/trunk/; revision=51417
1444df
1444df
Add a cast to try and fix
1444df
packet-rtpproxy.c:226: warning: implicit conversion shortens 64-bit value into
1444df
a 32-bit value
1444df
1444df
I'm not quite sure what's going on here, all the values in use are either gint
1444df
or guint so they should all be the same size?
1444df
1444df
svn path=/trunk/; revision=51419
1444df
1444df
Take another stab at
1444df
packet-rtpproxy.c:226: warning: implicit conversion shortens 64-bit value into a
1444df
32-bit value
1444df
1444df
svn path=/trunk/; revision=51420
1444df
1444df
One more 64/32-conversion fix for rtpproxy
1444df
1444df
svn path=/trunk/; revision=51421
1444df
1444df
Fix Coverity CID 1063335: Unused pointer value.
1444df
1444df
svn path=/trunk/; revision=51430
173888
173888
From Peter Lemenkov via https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9211 :
173888
Add basic conversation support for rtpproxy dissector
173888
173888
svn path=/trunk/; revision=52331
173888
173888
Let's please fix-encoding-args.pl
173888
173888
svn path=/trunk/; revision=52334
173888
173888
Make RTPProxy a newstyle dissector.
173888
173888
svn path=/trunk/; revision=52476
173888
173888
Try to fix
173888
packet-rtpproxy.c:217: warning: comparison between signed and unsigned
173888
173888
svn path=/trunk/; revision=52477
173888
173888
Fix signed vs. unsigned comparison warnings.
173888
173888
svn path=/trunk/; revision=52483
173888
173888
Add response time to the rtpproxy dissector. Bug 9380 (https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9380)
173888
173888
From Peter Lemenkov.
173888
173888
svn path=/trunk/; revision=53115
173888
173888
Decode more error replies in RTPproxy dissector.  Bug 9408 (https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9408)
173888
173888
From Peter Lemenkov
173888
173888
svn path=/trunk/; revision=53245
173888
173888
From Peter Lemenkov
173888
display a text description for the RTPProxy version request
173888
173888
https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=9416
173888
173888
svn path=/trunk/; revision=53249
173888
173888
replace proto_tree_add_string_format_value() with proto_tree_add_item()
173888
173888
svn path=/trunk/; revision=53261
1444df
1444df
diff --git a/AUTHORS b/AUTHORS
173888
index 10782b0..e7b3c18 100644
1444df
--- a/AUTHORS
1444df
+++ b/AUTHORS
173888
@@ -3733,6 +3733,7 @@ Max Baker		<max[AT]warped.org>
1444df
 Mike Garratt		<mg.wireshark[AT]evn.co.nz>
844b61
 Bart Van Assche		<bvanassche[AT]acm.org>
844b61
 Karl Beldan			<karl.beldan[AT]gmail.com>
1444df
+Peter Lemenkov		<lemenkov[AT]gmail.com>
c06811
 Masayuki Takemura	<masayuki.takemura[AT]gmail.com>
1444df
 
c06811
 
1444df
diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt
844b61
index 69eb75f..610cea7 100644
1444df
--- a/epan/CMakeLists.txt
1444df
+++ b/epan/CMakeLists.txt
1444df
@@ -1083,6 +1083,7 @@ set(DISSECTOR_SRC
1444df
 	dissectors/packet-rtp-events.c
1444df
 	dissectors/packet-rtp-midi.c
1444df
 	dissectors/packet-rtp.c
1444df
+	dissectors/packet-rtpproxy.c
1444df
 	dissectors/packet-rtps.c
1444df
 	dissectors/packet-rtsp.c
1444df
 	dissectors/packet-rudp.c
1444df
diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common
1444df
index 937f522..73217d7 100644
1444df
--- a/epan/dissectors/Makefile.common
1444df
+++ b/epan/dissectors/Makefile.common
1444df
@@ -1004,6 +1004,7 @@ DISSECTOR_SRC = \
1444df
 	packet-rtp-events.c	\
1444df
 	packet-rtp-midi.c	\
1444df
 	packet-rtp.c		\
1444df
+	packet-rtpproxy.c	\
1444df
 	packet-rtps.c		\
1444df
 	packet-rtsp.c		\
1444df
 	packet-rudp.c		\
1444df
diff --git a/epan/dissectors/packet-rtpproxy.c b/epan/dissectors/packet-rtpproxy.c
1444df
new file mode 100644
173888
index 0000000..f606abb
1444df
--- /dev/null
1444df
+++ b/epan/dissectors/packet-rtpproxy.c
173888
@@ -0,0 +1,959 @@
1444df
+/* packet-rtpproxy.c
1444df
+ * RTPproxy command protocol dissector
1444df
+ * Copyright 2013, Peter Lemenkov <lemenkov@gmail.com>
1444df
+ *
1444df
+ * This dissector tries to dissect rtpproxy control protocol. Please visit this
1444df
+ * link for brief details on the command format:
1444df
+ *
1444df
+ * http://www.rtpproxy.org/wiki/RTPproxy/Protocol
1444df
+ *
1444df
+ * $Id$
1444df
+ *
1444df
+ * Wireshark - Network traffic analyzer
1444df
+ * By Gerald Combs <gerald@wireshark.org>
1444df
+ * Copyright 1999 Gerald Combs
1444df
+ *
1444df
+ * This program is free software; you can redistribute it and/or
1444df
+ * modify it under the terms of the GNU General Public License
1444df
+ * as published by the Free Software Foundation; either version 2
1444df
+ * of the License, or (at your option) any later version.
1444df
+ *
1444df
+ * This program is distributed in the hope that it will be useful,
1444df
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
1444df
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
1444df
+ * GNU General Public License for more details.
1444df
+ *
1444df
+ * You should have received a copy of the GNU General Public License
1444df
+ * along with this program; if not, write to the Free Software
1444df
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1444df
+ */
1444df
+
1444df
+#include "config.h"
1444df
+
173888
+#include <ctype.h>
173888
+
1444df
+#include <epan/packet.h>
1444df
+#include <epan/prefs.h>
173888
+#include <epan/conversation.h>
1444df
+
1444df
+static int proto_rtpproxy = -1;
1444df
+
1444df
+static int hf_rtpproxy_cookie = -1;
1444df
+static int hf_rtpproxy_error = -1;
1444df
+static int hf_rtpproxy_status = -1;
1444df
+static int hf_rtpproxy_ok = -1;
1444df
+static int hf_rtpproxy_ipv4 = -1;
1444df
+static int hf_rtpproxy_ipv6 = -1;
1444df
+static int hf_rtpproxy_port = -1;
1444df
+static int hf_rtpproxy_lf = -1;
1444df
+static int hf_rtpproxy_request = -1;
1444df
+static int hf_rtpproxy_command = -1;
1444df
+static int hf_rtpproxy_command_parameters = -1;
1444df
+static int hf_rtpproxy_callid = -1;
1444df
+static int hf_rtpproxy_copy_target = -1;
1444df
+static int hf_rtpproxy_playback_filename = -1;
1444df
+static int hf_rtpproxy_playback_codec = -1;
1444df
+static int hf_rtpproxy_notify = -1;
1444df
+static int hf_rtpproxy_notify_ipv4 = -1;
1444df
+static int hf_rtpproxy_notify_port = -1;
1444df
+static int hf_rtpproxy_notify_tag = -1;
1444df
+static int hf_rtpproxy_tag = -1;
1444df
+static int hf_rtpproxy_mediaid = -1;
1444df
+static int hf_rtpproxy_reply = -1;
1444df
+static int hf_rtpproxy_version_request = -1;
1444df
+static int hf_rtpproxy_version_supported = -1;
1444df
+
173888
+/* Request/response tracking */
173888
+static int hf_rtpproxy_request_in = -1;
173888
+static int hf_rtpproxy_response_in = -1;
173888
+static int hf_rtpproxy_response_time = -1;
173888
+
173888
+typedef struct _rtpproxy_info {
173888
+	guint32 req_frame;
173888
+	guint32 resp_frame;
173888
+	nstime_t req_time;
173888
+} rtpproxy_info_t;
173888
+
173888
+typedef struct _rtpproxy_conv_info {
173888
+	emem_tree_t *trans;
173888
+} rtpproxy_conv_info_t;
173888
+
173888
+
173888
+static const string_string versiontypenames[] = {
173888
+	{ "20040107", "Basic RTP proxy functionality" },
173888
+	{ "20050322", "Support for multiple RTP streams and MOH" },
173888
+	{ "20060704", "Support for extra parameter in the V command" },
173888
+	{ "20071116", "Support for RTP re-packetization" },
173888
+	{ "20071218", "Support for forking (copying) RTP stream" },
173888
+	{ "20080403", "Support for RTP statistics querying" },
173888
+	{ "20081102", "Support for setting codecs in the update/lookup command" },
173888
+	{ "20081224", "Support for session timeout notifications" },
173888
+	{ "20090810", "Support for automatic bridging" },
173888
+	{ 0, NULL }
173888
+};
173888
+
1444df
+static const value_string commandtypenames[] = {
1444df
+	{ 'V', "Handshake/Ping" },
1444df
+	{ 'v', "Handshake/Ping" },
1444df
+	{ 'U', "Offer/Update" },
1444df
+	{ 'u', "Offer/Update" },
1444df
+	{ 'L', "Answer/Lookup" },
1444df
+	{ 'l', "Answer/Lookup" },
1444df
+	{ 'I', "Information"},
1444df
+	{ 'i', "Information"},
1444df
+	{ 'X', "Close all active sessions"},
1444df
+	{ 'x', "Close all active sessions"},
1444df
+	{ 'D', "Delete an active session (Bye/Cancel/Error)"},
1444df
+	{ 'd', "Delete an active session (Bye/Cancel/Error)"},
1444df
+	{ 'P', "Start playback (music-on-hold)"},
1444df
+	{ 'p', "Start playback (music-on-hold)"},
1444df
+	{ 'S', "Stop playback (music-on-hold)"},
1444df
+	{ 's', "Stop playback (music-on-hold)"},
1444df
+	{ 'R', "Start recording"},
1444df
+	{ 'r', "Start recording"},
1444df
+	{ 'C', "Copy stream"},
1444df
+	{ 'c', "Copy stream"},
1444df
+	{ 'Q', "Query info about a session"},
1444df
+	{ 'q', "Query info about a session"},
1444df
+	{ 0, NULL }
1444df
+};
1444df
+
1444df
+static const value_string oktypenames[] = {
1444df
+	{ '0', "Ok"},
1444df
+	{ '1', "Version Supported"},
1444df
+	{ 0, NULL }
1444df
+};
1444df
+
173888
+static const string_string errortypenames[] = {
173888
+	{ "E0", "Syntax error" },
173888
+	{ "E1", "Syntax error" },
173888
+	{ "E2", "Syntax error" },
173888
+	{ "E3", "Unknown command" },
173888
+	{ "E4", "Syntax error" },
173888
+	{ "E5", "Out of memory" },
173888
+	{ "E6", "<no description>" },
173888
+	{ "E7", "Software error (can't create listener)" },
173888
+	{ "E8", "Not Found" },
173888
+	{ "E10", "Software error (can't create listener)" },
173888
+	{ "E11", "Out of memory" },
173888
+	{ "E12", "Out of memory" },
173888
+	{ "E13", "Out of memory" },
173888
+	{ "E14", "Out of memory" },
1444df
+	{ 0, NULL }
1444df
+};
1444df
+
1444df
+static const value_string flowcontroltypenames[] = {
1444df
+	{ '\n', "Yes"},
1444df
+	{ 0, NULL }
1444df
+};
1444df
+
1444df
+static gint ett_rtpproxy = -1;
1444df
+
1444df
+static gint ett_rtpproxy_request = -1;
1444df
+static gint ett_rtpproxy_command = -1;
1444df
+static gint ett_rtpproxy_tag = -1;
1444df
+static gint ett_rtpproxy_notify = -1;
1444df
+
1444df
+static gint ett_rtpproxy_reply = -1;
1444df
+
1444df
+static guint rtpproxy_tcp_port = 22222;
1444df
+static guint rtpproxy_udp_port = 22222;
1444df
+
1444df
+void proto_reg_handoff_rtpproxy(void);
1444df
+
1444df
+gint
1444df
+rtpptoxy_add_tag(proto_tree *rtpproxy_tree, tvbuff_t *tvb, guint begin, guint realsize)
1444df
+{
1444df
+	proto_item *ti = NULL;
1444df
+	proto_tree *another_tree = NULL;
1444df
+	gint new_offset;
1444df
+	guint end;
1444df
+
1444df
+	new_offset = tvb_find_guint8(tvb, begin, -1, ' ');
1444df
+	if(new_offset < 0)
1444df
+		end = realsize; /* No more parameters */
1444df
+	else
1444df
+		end = new_offset;
1444df
+
1444df
+	/* SER/OpenSER/OpenSIPS/Kamailio adds Media-ID right after the Tag
1444df
+	 * separated by a semicolon
1444df
+	 */
1444df
+	new_offset = tvb_find_guint8(tvb, begin, end, ';');
1444df
+	if(new_offset == -1){
1444df
+		ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_tag, tvb, begin, end - begin, ENC_ASCII | ENC_NA);
1444df
+		another_tree = proto_item_add_subtree(ti, ett_rtpproxy_tag);
1444df
+		ti = proto_tree_add_item(another_tree, hf_rtpproxy_mediaid, tvb, new_offset+1, 0, ENC_ASCII | ENC_NA);
1444df
+		proto_item_set_text(ti, "Media-ID: <skipped>");
1444df
+	}
1444df
+	else{
1444df
+		ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_tag, tvb, begin, new_offset - begin, ENC_ASCII | ENC_NA);
1444df
+		another_tree = proto_item_add_subtree(ti, ett_rtpproxy_tag);
1444df
+		proto_tree_add_item(another_tree, hf_rtpproxy_mediaid, tvb, new_offset+1, end - (new_offset+1), ENC_ASCII | ENC_NA);
1444df
+	}
1444df
+	return (end == realsize ? -1 : (gint)end);
1444df
+}
1444df
+
173888
+void
173888
+rtpproxy_add_tid(gboolean is_request, tvbuff_t *tvb, packet_info *pinfo, proto_tree *rtpproxy_tree, rtpproxy_conv_info_t *rtpproxy_conv, gchar* cookie)
173888
+{
173888
+	rtpproxy_info_t *rtpproxy_info;
173888
+	proto_item *pi;
173888
+
173888
+	if (!PINFO_FD_VISITED(pinfo)) {
173888
+		if (is_request){
173888
+			rtpproxy_info = se_new(rtpproxy_info_t);
173888
+			rtpproxy_info->req_frame = PINFO_FD_NUM(pinfo);
173888
+			rtpproxy_info->resp_frame = 0;
173888
+			rtpproxy_info->req_time = pinfo->fd->abs_ts;
173888
+			se_tree_insert_string(rtpproxy_conv->trans, cookie, rtpproxy_info, 0);
173888
+		} else {
173888
+			rtpproxy_info = (rtpproxy_info_t *)se_tree_lookup_string(rtpproxy_conv->trans, cookie, 0);
173888
+			if (rtpproxy_info) {
173888
+				rtpproxy_info->resp_frame = PINFO_FD_NUM(pinfo);
173888
+			}
173888
+		}
173888
+	} else {
173888
+		rtpproxy_info = (rtpproxy_info_t *)se_tree_lookup_string(rtpproxy_conv->trans, cookie, 0);
173888
+		if (rtpproxy_info && (is_request ? rtpproxy_info->resp_frame : rtpproxy_info->req_frame)) {
173888
+			nstime_t ns;
173888
+
173888
+			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);
173888
+			PROTO_ITEM_SET_GENERATED(pi);
173888
+
173888
+			/* If reply then calculate response time */
173888
+			if (!is_request){
173888
+				nstime_delta(&ns, &pinfo->fd->abs_ts, &rtpproxy_info->req_time);
173888
+				pi = proto_tree_add_time(rtpproxy_tree, hf_rtpproxy_response_time, tvb, 0, 0, &ns);
173888
+				PROTO_ITEM_SET_GENERATED(pi);
173888
+			}
173888
+		}
173888
+	}
173888
+}
173888
+
173888
+static int
173888
+dissect_rtpproxy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data _U_)
1444df
+{
1444df
+	gboolean has_lf = FALSE;
173888
+	gint offset = 0;
1444df
+	gint new_offset = 0;
1444df
+	guint tmp;
173888
+	gint realsize = 0;
1444df
+	guint8* rawstr;
173888
+	guint8* tmpstr;
1444df
+	proto_item *ti;
1444df
+	proto_tree *rtpproxy_tree;
173888
+	conversation_t *conversation;
173888
+	rtpproxy_conv_info_t *rtpproxy_conv;
173888
+	gchar* cookie = NULL;
173888
+
173888
+	/* If it does not start with a printable character it's not RTPProxy */
173888
+	if(!isprint(tvb_get_guint8(tvb, 0)))
173888
+		return 0;
173888
+
173888
+	/* Extract Cookie */
173888
+	offset = tvb_find_guint8(tvb, offset, -1, ' ');
173888
+	if(offset == -1)
173888
+		return 0;
1444df
+
1444df
+	/* Clear out stuff in the info column - we''l set it later */
1444df
+	col_clear(pinfo->cinfo, COL_INFO);
1444df
+
1444df
+	ti = proto_tree_add_item(tree, proto_rtpproxy, tvb, 0, -1, ENC_NA);
1444df
+	rtpproxy_tree = proto_item_add_subtree(ti, ett_rtpproxy);
1444df
+
1444df
+	proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_cookie, tvb, 0, offset, ENC_ASCII | ENC_NA);
173888
+	cookie = tvb_get_ephemeral_string(tvb, 0, offset);
1444df
+
1444df
+	/* Skip whitespace */
1444df
+	offset = tvb_skip_wsp(tvb, offset+1, -1);
1444df
+
1444df
+	/* Calculate size to prevent recalculation in the future */
1444df
+	realsize = tvb_reported_length(tvb);
1444df
+
1444df
+	/* Check for LF (required for TCP connection, optional for UDP) */
1444df
+	if (tvb_get_guint8(tvb, realsize - 1) == '\n'){
1444df
+		col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTPproxy");
1444df
+		/* Don't count trailing LF */
1444df
+		realsize -= 1;
1444df
+		has_lf = TRUE;
1444df
+	}
1444df
+	else
1444df
+		col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTPproxy (no LF)");
1444df
+
173888
+	/* Try to create conversation */
173888
+	conversation = find_or_create_conversation(pinfo);
173888
+	rtpproxy_conv = (rtpproxy_conv_info_t *)conversation_get_proto_data(conversation, proto_rtpproxy);
173888
+	if (!rtpproxy_conv) {
173888
+		rtpproxy_conv = se_new(rtpproxy_conv_info_t);
173888
+		rtpproxy_conv->trans = se_tree_create_non_persistent(EMEM_TREE_TYPE_RED_BLACK, "rtpproxy transactions");;
173888
+		conversation_add_proto_data(conversation, proto_rtpproxy, rtpproxy_conv);
173888
+	}
173888
+
1444df
+	/* Get payload string */
1444df
+	rawstr = tvb_get_ephemeral_string(tvb, offset, realsize - offset);
1444df
+
1444df
+	/* Extract command */
1444df
+	tmp = g_ascii_tolower(tvb_get_guint8(tvb, offset));
1444df
+	switch (tmp)
1444df
+	{
1444df
+		case 's':
1444df
+			/* A specific case - long statistics answer */
1444df
+			/* %COOKIE% sessions created %NUM0% active sessions: %NUM1% */
173888
+			rtpproxy_add_tid(FALSE, tvb, pinfo, rtpproxy_tree, rtpproxy_conv, cookie);
1444df
+			if ('e' == tvb_get_guint8(tvb, offset+1)){
1444df
+				col_add_fstr(pinfo->cinfo, COL_INFO, "Reply: %s", rawstr);
1444df
+				ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_reply, tvb, offset, -1, ENC_NA);
1444df
+
1444df
+				rtpproxy_tree = proto_item_add_subtree(ti, ett_rtpproxy_reply);
173888
+				proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_status, tvb, offset, realsize - offset, ENC_ASCII | ENC_NA);
1444df
+				break;
1444df
+			}
1444df
+		case 'i':
1444df
+		case 'x':
1444df
+		case 'u':
1444df
+		case 'l':
1444df
+		case 'd':
1444df
+		case 'p':
1444df
+		case 'v':
1444df
+		case 'r':
1444df
+		case 'c':
1444df
+		case 'q':
173888
+			rtpproxy_add_tid(TRUE, tvb, pinfo, rtpproxy_tree, rtpproxy_conv, cookie);
1444df
+			col_add_fstr(pinfo->cinfo, COL_INFO, "Request: %s", rawstr);
1444df
+			ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_request, tvb, offset, -1, ENC_NA);
1444df
+			rtpproxy_tree = proto_item_add_subtree(ti, ett_rtpproxy_request);
1444df
+
1444df
+			/* A specific case - version request */
173888
+			if ((tmp == 'v') && (offset + (gint)strlen("VF YYYMMDD") + 1 == realsize)){
1444df
+				/* Skip whitespace */
1444df
+				new_offset = tvb_skip_wsp(tvb, offset + ((guint)strlen("VF") + 1), -1);
173888
+				ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_version_request, tvb, new_offset, (gint)strlen("YYYYMMDD"), ENC_ASCII | ENC_NA);
173888
+				tmpstr = tvb_get_ephemeral_string(tvb, new_offset, (gint)strlen("YYYYMMDD"));
173888
+				proto_item_append_text(ti, " (%s)", str_to_str(tmpstr, versiontypenames, "Unknown"));
1444df
+				break;
1444df
+			}
1444df
+
1444df
+			/* All other commands */
1444df
+			ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_command, tvb, offset, 1, ENC_NA);
1444df
+
1444df
+			/* A specific case - handshake/ping */
1444df
+			if (tmp == 'v')
1444df
+				break; /* No more parameters */
1444df
+
1444df
+			/* A specific case - close all calls */
1444df
+			if (tmp == 'x')
1444df
+				break; /* No more parameters */
1444df
+
1444df
+			/* Extract parameters */
1444df
+			/* Parameters should be right after the command and before EOL (in case of Info command) or before whitespace */
173888
+			new_offset = (tmp == 'i' ? (realsize - 1 > offset ? offset + (gint)strlen("Ib") : offset + (gint)strlen("I")) : tvb_find_guint8(tvb, offset, -1, ' '));
1444df
+
173888
+			if (new_offset != offset + 1){
1444df
+				rtpproxy_tree = proto_item_add_subtree(ti, ett_rtpproxy_command);
1444df
+				proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_command_parameters, tvb, offset+1, new_offset - (offset+1), ENC_ASCII | ENC_NA);
1444df
+				rtpproxy_tree = proto_item_get_parent(ti);
1444df
+			}
1444df
+
1444df
+			/* A specific case - query information */
1444df
+			if (tmp == 'i')
1444df
+				break; /* No more parameters */
1444df
+
1444df
+			/* Skip whitespace */
1444df
+			offset = tvb_skip_wsp(tvb, new_offset+1, -1);
1444df
+
1444df
+			/* Extract Call-ID */
1444df
+			new_offset = tvb_find_guint8(tvb, offset, -1, ' ');
1444df
+			proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_callid, tvb, offset, new_offset - offset, ENC_ASCII | ENC_NA);
1444df
+			/* Skip whitespace */
1444df
+			offset = tvb_skip_wsp(tvb, new_offset+1, -1);
1444df
+
1444df
+			/* Extract IP and Port in case of Offer/Answer */
1444df
+			if ((tmp == 'u') || (tmp == 'l')){
1444df
+				/* Extract IP */
1444df
+				new_offset = tvb_find_guint8(tvb, offset, -1, ' ');
1444df
+				if (tvb_find_guint8(tvb, offset, new_offset - offset, ':') == -1)
1444df
+					proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_ipv4, tvb, offset, new_offset - offset, ENC_ASCII | ENC_NA);
1444df
+				else
1444df
+					proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_ipv6, tvb, offset, new_offset - offset, ENC_ASCII | ENC_NA);
1444df
+				/* Skip whitespace */
1444df
+				offset = tvb_skip_wsp(tvb, new_offset+1, -1);
1444df
+
1444df
+				/* Extract Port */
1444df
+				new_offset = tvb_find_guint8(tvb, offset, -1, ' ');
1444df
+				proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_port, tvb, offset, new_offset - offset, ENC_ASCII | ENC_NA);
1444df
+				/* Skip whitespace */
1444df
+				offset = tvb_skip_wsp(tvb, new_offset+1, -1);
1444df
+			}
1444df
+
1444df
+			/* Extract Copy target */
1444df
+			if (tmp == 'c'){
1444df
+				new_offset = tvb_find_guint8(tvb, offset, -1, ' ');
1444df
+				proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_copy_target, tvb, offset, new_offset - offset, ENC_ASCII | ENC_NA);
1444df
+				/* Skip whitespace */
1444df
+				offset = tvb_skip_wsp(tvb, new_offset+1, -1);
1444df
+			}
1444df
+
1444df
+			/* Extract Playback file and codecs */
1444df
+			if (tmp == 'p'){
1444df
+				/* Extract filename */
1444df
+				new_offset = tvb_find_guint8(tvb, offset, -1, ' ');
1444df
+				proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_playback_filename, tvb, offset, new_offset - offset, ENC_ASCII | ENC_NA);
1444df
+				/* Skip whitespace */
1444df
+				offset = tvb_skip_wsp(tvb, new_offset+1, -1);
1444df
+
1444df
+				/* Extract codec */
1444df
+				new_offset = tvb_find_guint8(tvb, offset, -1, ' ');
1444df
+				proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_playback_codec, tvb, offset, new_offset - offset, ENC_ASCII | ENC_NA);
1444df
+				/* Skip whitespace */
1444df
+				offset = tvb_skip_wsp(tvb, new_offset+1, -1);
1444df
+			}
1444df
+
1444df
+			/* Extract first tag */
1444df
+			new_offset = rtpptoxy_add_tag(rtpproxy_tree, tvb, offset, realsize);
1444df
+			if(new_offset == -1)
1444df
+				break; /* No more parameters */
1444df
+			/* Skip whitespace */
1444df
+			offset = tvb_skip_wsp(tvb, new_offset+1, -1);
1444df
+
1444df
+			/* Extract second tag */
1444df
+			new_offset = rtpptoxy_add_tag(rtpproxy_tree, tvb, offset, realsize);
1444df
+			if(new_offset == -1)
1444df
+				break; /* No more parameters */
1444df
+			/* Skip whitespace */
1444df
+			offset = tvb_skip_wsp(tvb, new_offset+1, -1);
1444df
+
1444df
+			/* Extract Notification address */
1444df
+			if (tmp == 'u'){
1444df
+				new_offset = tvb_find_guint8(tvb, offset, -1, ' ');
173888
+				ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_notify, tvb, offset, realsize - offset, ENC_ASCII | ENC_NA);
1444df
+				proto_item_set_text(ti, "Notify");
1444df
+				rtpproxy_tree = proto_item_add_subtree(ti, ett_rtpproxy_notify);
1444df
+				if(new_offset == -1){
1444df
+					/* FIXME only IPv4 is supported */
1444df
+					new_offset = tvb_find_guint8(tvb, offset, -1, ':');
1444df
+					proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_notify_ipv4, tvb, offset, new_offset - offset, ENC_ASCII | ENC_NA);
1444df
+					proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_notify_port, tvb, new_offset+1, realsize - (new_offset+1), ENC_ASCII | ENC_NA);
1444df
+					break; /* No more parameters */
1444df
+				}
1444df
+				if(new_offset - offset < 6){
1444df
+					/* Only port is supplied */
1444df
+					ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_notify_ipv4, tvb, offset, 0, ENC_ASCII | ENC_NA);
1444df
+					proto_item_set_text(ti, "Notification IPv4: <skipped>");
1444df
+					proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_notify_port, tvb, offset, new_offset - offset, ENC_ASCII | ENC_NA);
1444df
+				}
1444df
+				else{
1444df
+					proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_notify_ipv4, tvb, offset, new_offset - offset, ENC_ASCII | ENC_NA);
1444df
+					proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_notify_port, tvb, new_offset+1, realsize - (new_offset+1), ENC_ASCII | ENC_NA);
1444df
+				}
1444df
+				/* Skip whitespace */
1444df
+				offset = tvb_skip_wsp(tvb, new_offset+1, -1);
1444df
+
1444df
+				proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_notify_tag, tvb, offset, realsize - offset, ENC_ASCII | ENC_NA);
1444df
+			}
1444df
+			break;
1444df
+		case 'a':
1444df
+		case 'e':
1444df
+		case '0':
1444df
+		case '1':
1444df
+		case '2':
1444df
+		case '3':
1444df
+		case '4':
1444df
+		case '5':
1444df
+		case '6':
1444df
+		case '7':
1444df
+		case '8':
1444df
+		case '9':
173888
+			rtpproxy_add_tid(FALSE, tvb, pinfo, rtpproxy_tree, rtpproxy_conv, cookie);
1444df
+			if (tmp == 'e')
1444df
+				col_add_fstr(pinfo->cinfo, COL_INFO, "Error reply: %s", rawstr);
1444df
+			else
1444df
+				col_add_fstr(pinfo->cinfo, COL_INFO, "Reply: %s", rawstr);
1444df
+
1444df
+			ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_reply, tvb, offset, -1, ENC_NA);
1444df
+			rtpproxy_tree = proto_item_add_subtree(ti, ett_rtpproxy_reply);
1444df
+
1444df
+			if (tmp == 'e'){
173888
+				tmp = tvb_find_line_end(tvb, offset, -1, &new_offset, FALSE);
173888
+				tmpstr = tvb_get_ephemeral_string(tvb, offset, tmp);
173888
+				ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_error, tvb, offset, (gint)strlen(tmpstr), ENC_ASCII | ENC_NA);
173888
+				proto_item_append_text(ti, " (%s)", str_to_str(tmpstr, errortypenames, "Unknown"));
1444df
+				break;
1444df
+			}
1444df
+
1444df
+			if (tmp == 'a'){
1444df
+				/* A specific case - short statistics answer */
1444df
+				/* %COOKIE% active sessions: %NUM1% */
173888
+				proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_status, tvb, offset, realsize - offset, ENC_ASCII | ENC_NA);
1444df
+				break;
1444df
+			}
173888
+			if ((tmp == '0')&& ((tvb_reported_length(tvb) == (guint)(offset+1))||(tvb_reported_length(tvb) == (guint)(offset+2)))){
1444df
+				proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_ok, tvb, offset, 1, ENC_ASCII | ENC_NA);
1444df
+				break;
1444df
+			}
173888
+			if ((tmp == '1') && ((tvb_reported_length(tvb) == (guint)(offset+1))||(tvb_reported_length(tvb) == (guint)(offset+2)))){
1444df
+				proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_ok, tvb, offset, 1, ENC_ASCII | ENC_NA);
1444df
+				break;
1444df
+			}
173888
+			if (tvb_reported_length(tvb) == (guint)(offset+9)){
1444df
+				proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_version_supported, tvb, offset, 8, ENC_ASCII | ENC_NA);
1444df
+				break;
1444df
+			}
1444df
+
1444df
+			/* Extract Port */
1444df
+			new_offset = tvb_find_guint8(tvb, offset, -1, ' ');
1444df
+			proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_port, tvb, offset, new_offset - offset, ENC_ASCII | ENC_NA);
1444df
+			/* Skip whitespace */
1444df
+			offset = tvb_skip_wsp(tvb, new_offset+1, -1);
1444df
+
1444df
+			/* Extract IP */
1444df
+			tmp = tvb_find_line_end(tvb, offset, -1, &new_offset, FALSE);
1444df
+			if (tvb_find_guint8(tvb, offset, -1, ':') == -1)
1444df
+				proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_ipv4, tvb, offset, tmp, ENC_ASCII | ENC_NA);
1444df
+			else
1444df
+				proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_ipv6, tvb, offset, tmp, ENC_ASCII | ENC_NA);
1444df
+			break;
1444df
+		default:
1444df
+			break;
1444df
+	}
1444df
+	if (has_lf)
1444df
+		proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_lf, tvb, realsize, 1, ENC_NA);
173888
+
173888
+	return tvb_length(tvb);
1444df
+}
1444df
+
1444df
+void
1444df
+proto_register_rtpproxy(void)
1444df
+{
1444df
+	module_t *rtpproxy_module;
1444df
+
1444df
+	static hf_register_info hf[] = {
1444df
+		{
1444df
+			&hf_rtpproxy_cookie,
1444df
+			{
1444df
+				"Cookie",
1444df
+				"rtpproxy.cookie",
1444df
+				FT_STRING,
1444df
+				BASE_NONE,
1444df
+				NULL,
1444df
+				0x0,
1444df
+				NULL,
1444df
+				HFILL
1444df
+			}
1444df
+		},
1444df
+		{
1444df
+			&hf_rtpproxy_version_request,
1444df
+			{
1444df
+				"Version Request",
1444df
+				"rtpproxy.version",
1444df
+				FT_STRING,
1444df
+				BASE_NONE,
1444df
+				NULL,
1444df
+				0x0,
1444df
+				NULL,
1444df
+				HFILL
1444df
+			}
1444df
+		},
1444df
+		{
1444df
+			&hf_rtpproxy_version_supported,
1444df
+			{
1444df
+				"Version Supported",
1444df
+				"rtpproxy.version_supported",
1444df
+				FT_STRING,
1444df
+				BASE_NONE,
1444df
+				NULL,
1444df
+				0x0,
1444df
+				NULL,
1444df
+				HFILL
1444df
+			}
1444df
+		},
1444df
+		{
1444df
+			&hf_rtpproxy_error,
1444df
+			{
1444df
+				"Error",
1444df
+				"rtpproxy.error",
173888
+				FT_STRING,
173888
+				BASE_NONE,
173888
+				NULL,
1444df
+				0x0,
1444df
+				NULL,
1444df
+				HFILL
1444df
+			}
1444df
+		},
1444df
+		{
1444df
+			&hf_rtpproxy_ok,
1444df
+			{
1444df
+				"Ok",
1444df
+				"rtpproxy.ok",
1444df
+				FT_UINT8,
1444df
+				BASE_DEC,
1444df
+				VALS(oktypenames),
1444df
+				0x0,
1444df
+				NULL,
1444df
+				HFILL
1444df
+			}
1444df
+		},
1444df
+		{
1444df
+			&hf_rtpproxy_status,
1444df
+			{
1444df
+				"Status",
1444df
+				"rtpproxy.status",
1444df
+				FT_STRING,
1444df
+				BASE_NONE,
1444df
+				NULL,
1444df
+				0x0,
1444df
+				NULL,
1444df
+				HFILL
1444df
+			}
1444df
+		},
1444df
+		{
1444df
+			&hf_rtpproxy_ipv4,
1444df
+			{
1444df
+				"IPv4",
1444df
+				"rtpproxy.ipv4",
1444df
+				FT_STRING,
1444df
+				BASE_NONE,
1444df
+				NULL,
1444df
+				0x0,
1444df
+				NULL,
1444df
+				HFILL
1444df
+			}
1444df
+		},
1444df
+		{
1444df
+			&hf_rtpproxy_ipv6,
1444df
+			{
1444df
+				"IPv6",
1444df
+				"rtpproxy.ipv6",
1444df
+				FT_STRING,
1444df
+				BASE_NONE,
1444df
+				NULL,
1444df
+				0x0,
1444df
+				NULL,
1444df
+				HFILL
1444df
+			}
1444df
+		},
1444df
+		{
1444df
+			&hf_rtpproxy_port,
1444df
+			{
1444df
+				"Port",
1444df
+				"rtpproxy.port",
1444df
+				FT_STRING,
1444df
+				BASE_NONE,
1444df
+				NULL,
1444df
+				0x0,
1444df
+				NULL,
1444df
+				HFILL
1444df
+			}
1444df
+		},
1444df
+		{
1444df
+			&hf_rtpproxy_request,
1444df
+			{
1444df
+				"Request",
1444df
+				"rtpproxy.request",
1444df
+				FT_NONE,
1444df
+				BASE_NONE,
1444df
+				NULL,
1444df
+				0x0,
1444df
+				NULL,
1444df
+				HFILL
1444df
+			}
1444df
+		},
1444df
+		{
1444df
+			&hf_rtpproxy_command,
1444df
+			{
1444df
+				"Command",
1444df
+				"rtpproxy.command",
1444df
+				FT_UINT8,
1444df
+				BASE_DEC,
1444df
+				VALS(commandtypenames),
1444df
+				0x0,
1444df
+				NULL,
1444df
+				HFILL
1444df
+			}
1444df
+		},
1444df
+		{
1444df
+			&hf_rtpproxy_command_parameters,
1444df
+			{
1444df
+				"Command parameters",
1444df
+				"rtpproxy.command_parameters",
1444df
+				FT_STRING,
1444df
+				BASE_NONE,
1444df
+				NULL,
1444df
+				0x0,
1444df
+				NULL,
1444df
+				HFILL
1444df
+			}
1444df
+		},
1444df
+		{
1444df
+			&hf_rtpproxy_copy_target,
1444df
+			{
1444df
+				"Copy target",
1444df
+				"rtpproxy.copy_target",
1444df
+				FT_STRING,
1444df
+				BASE_NONE,
1444df
+				NULL,
1444df
+				0x0,
1444df
+				NULL,
1444df
+				HFILL
1444df
+			}
1444df
+		},
1444df
+		{
1444df
+			&hf_rtpproxy_playback_filename,
1444df
+			{
1444df
+				"Playback filename",
1444df
+				"rtpproxy.playback_filename",
1444df
+				FT_STRING,
1444df
+				BASE_NONE,
1444df
+				NULL,
1444df
+				0x0,
1444df
+				NULL,
1444df
+				HFILL
1444df
+			}
1444df
+		},
1444df
+		{
1444df
+			&hf_rtpproxy_playback_codec,
1444df
+			{
1444df
+				"Playback codec",
1444df
+				"rtpproxy.playback_codec",
1444df
+				FT_STRING,
1444df
+				BASE_NONE,
1444df
+				NULL,
1444df
+				0x0,
1444df
+				NULL,
1444df
+				HFILL
1444df
+			}
1444df
+		},
1444df
+		{
1444df
+			&hf_rtpproxy_callid,
1444df
+			{
1444df
+				"Call-ID",
1444df
+				"rtpproxy.callid",
1444df
+				FT_STRING,
1444df
+				BASE_NONE,
1444df
+				NULL,
1444df
+				0x0,
1444df
+				NULL,
1444df
+				HFILL
1444df
+			}
1444df
+		},
1444df
+		{
1444df
+			&hf_rtpproxy_notify,
1444df
+			{
1444df
+				"Notify",
1444df
+				"rtpproxy.notify",
1444df
+				FT_STRING,
1444df
+				BASE_NONE,
1444df
+				NULL,
1444df
+				0x0,
1444df
+				NULL,
1444df
+				HFILL
1444df
+			}
1444df
+		},
1444df
+		{
1444df
+			&hf_rtpproxy_tag,
1444df
+			{
1444df
+				"Tag",
1444df
+				"rtpproxy.tag",
1444df
+				FT_STRING,
1444df
+				BASE_NONE,
1444df
+				NULL,
1444df
+				0x0,
1444df
+				NULL,
1444df
+				HFILL
1444df
+			}
1444df
+		},
1444df
+		{
1444df
+			&hf_rtpproxy_mediaid,
1444df
+			{
1444df
+				"Media-ID",
1444df
+				"rtpproxy.mediaid",
1444df
+				FT_STRING,
1444df
+				BASE_NONE,
1444df
+				NULL,
1444df
+				0x0,
1444df
+				NULL,
1444df
+				HFILL
1444df
+			}
1444df
+		},
1444df
+		{
1444df
+			&hf_rtpproxy_notify_ipv4,
1444df
+			{
1444df
+				"Notification IPv4",
1444df
+				"rtpproxy.notify_ipv4",
1444df
+				FT_STRING,
1444df
+				BASE_NONE,
1444df
+				NULL,
1444df
+				0x0,
1444df
+				NULL,
1444df
+				HFILL
1444df
+			}
1444df
+		},
1444df
+		{
1444df
+			&hf_rtpproxy_notify_port,
1444df
+			{
1444df
+				"Notification Port",
1444df
+				"rtpproxy.notify_port",
1444df
+				FT_STRING,
1444df
+				BASE_NONE,
1444df
+				NULL,
1444df
+				0x0,
1444df
+				NULL,
1444df
+				HFILL
1444df
+			}
1444df
+		},
1444df
+		{
1444df
+			&hf_rtpproxy_notify_tag,
1444df
+			{
1444df
+				"Notification Tag",
1444df
+				"rtpproxy.notify_tag",
1444df
+				FT_STRING,
1444df
+				BASE_NONE,
1444df
+				NULL,
1444df
+				0x0,
1444df
+				NULL,
1444df
+				HFILL
1444df
+			}
1444df
+		},
1444df
+		{
1444df
+			&hf_rtpproxy_reply,
1444df
+			{
1444df
+				"Reply",
1444df
+				"rtpproxy.reply",
1444df
+				FT_NONE,
1444df
+				BASE_NONE,
1444df
+				NULL,
1444df
+				0x0,
1444df
+				NULL,
1444df
+				HFILL
1444df
+			}
1444df
+		},
1444df
+		{
1444df
+			&hf_rtpproxy_lf,
1444df
+			{
1444df
+				"LF",
1444df
+				"rtpproxy.lf",
1444df
+				FT_UINT8,
1444df
+				BASE_DEC,
1444df
+				VALS(flowcontroltypenames),
1444df
+				0x0,
1444df
+				NULL,
1444df
+				HFILL
1444df
+			}
1444df
+		},
173888
+		{
173888
+			&hf_rtpproxy_request_in,
173888
+			{
173888
+				"Request In",
173888
+				"rtpproxy.request_in",
173888
+				FT_FRAMENUM,
173888
+				BASE_NONE,
173888
+				NULL,
173888
+				0x0,
173888
+				NULL,
173888
+				HFILL
173888
+			}
173888
+
173888
+		},
173888
+		{
173888
+			&hf_rtpproxy_response_in,
173888
+			{
173888
+				"Response In",
173888
+				"rtpproxy.response_in",
173888
+				FT_FRAMENUM,
173888
+				BASE_NONE,
173888
+				NULL,
173888
+				0x0,
173888
+				NULL,
173888
+				HFILL
173888
+			}
173888
+		},
173888
+		{
173888
+			&hf_rtpproxy_response_time,
173888
+			{
173888
+				"Response Time",
173888
+				"rtpproxy.response_time",
173888
+				FT_RELATIVE_TIME,
173888
+				BASE_NONE,
173888
+				NULL,
173888
+				0x0,
173888
+				"The time between the Request and the Reply",
173888
+				HFILL
173888
+			 }
173888
+		}
1444df
+	};
1444df
+
1444df
+	/* Setup protocol subtree array */
1444df
+	static gint *ett[] = {
1444df
+		&ett_rtpproxy,
1444df
+		&ett_rtpproxy_request,
1444df
+		&ett_rtpproxy_command,
1444df
+		&ett_rtpproxy_tag,
1444df
+		&ett_rtpproxy_notify,
1444df
+		&ett_rtpproxy_reply
1444df
+	};
1444df
+
1444df
+	proto_rtpproxy = proto_register_protocol (
1444df
+			"Sippy RTPproxy Protocol", /* name       */
1444df
+			"RTPproxy",      /* short name */
1444df
+			"rtpproxy"       /* abbrev     */
1444df
+			);
1444df
+
1444df
+	proto_register_field_array(proto_rtpproxy, hf, array_length(hf));
1444df
+	proto_register_subtree_array(ett, array_length(ett));
1444df
+
1444df
+	rtpproxy_module = prefs_register_protocol(proto_rtpproxy, proto_reg_handoff_rtpproxy);
1444df
+	prefs_register_uint_preference(rtpproxy_module, "tcp.port",
1444df
+								 "RTPproxy TCP Port", /* Title */
1444df
+								 "RTPproxy TCP Port", /* Descr */
1444df
+								 10,
1444df
+								 &rtpproxy_tcp_port);
1444df
+
1444df
+	prefs_register_uint_preference(rtpproxy_module, "udp.port",
1444df
+								 "RTPproxy UDP Port", /* Title */
1444df
+								 "RTPproxy UDP Port", /* Descr */
1444df
+								 10,
1444df
+								 &rtpproxy_udp_port);
1444df
+}
1444df
+
1444df
+void
1444df
+proto_reg_handoff_rtpproxy(void)
1444df
+{
1444df
+	static guint old_rtpproxy_tcp_port = 0;
1444df
+	static guint old_rtpproxy_udp_port = 0;
1444df
+
1444df
+	static gboolean rtpproxy_initialized = FALSE;
1444df
+
1444df
+	static dissector_handle_t rtpproxy_tcp_handle, rtpproxy_udp_handle;
1444df
+
1444df
+	if(!rtpproxy_initialized){
173888
+		rtpproxy_tcp_handle = new_create_dissector_handle(dissect_rtpproxy, proto_rtpproxy);
173888
+		rtpproxy_udp_handle = new_create_dissector_handle(dissect_rtpproxy, proto_rtpproxy);
1444df
+		rtpproxy_initialized = TRUE;
1444df
+	}
1444df
+
1444df
+	/* Register TCP port for dissection */
1444df
+	if(old_rtpproxy_tcp_port != 0 && old_rtpproxy_tcp_port != rtpproxy_tcp_port)
1444df
+		dissector_delete_uint("tcp.port", old_rtpproxy_tcp_port, rtpproxy_tcp_handle);
1444df
+	if(rtpproxy_tcp_port != 0 && old_rtpproxy_tcp_port != rtpproxy_tcp_port)
1444df
+		dissector_add_uint("tcp.port", rtpproxy_tcp_port, rtpproxy_tcp_handle);
1444df
+	old_rtpproxy_tcp_port = rtpproxy_tcp_port;
1444df
+
1444df
+	/* Register UDP port for dissection */
1444df
+	if(old_rtpproxy_udp_port != 0 && old_rtpproxy_udp_port != rtpproxy_udp_port)
1444df
+		dissector_delete_uint("udp.port", old_rtpproxy_udp_port, rtpproxy_udp_handle);
1444df
+	if(rtpproxy_udp_port != 0 && old_rtpproxy_udp_port != rtpproxy_udp_port)
1444df
+		dissector_add_uint("udp.port", rtpproxy_udp_port, rtpproxy_udp_handle);
1444df
+	old_rtpproxy_udp_port = rtpproxy_udp_port;
1444df
+}
1444df
+
1444df
+/*
1444df
+ * Editor modelines  -  http://www.wireshark.org/tools/modelines.html
1444df
+ *
1444df
+ * Local variables:
1444df
+ * c-basic-offset: 8
1444df
+ * tab-width: 8
1444df
+ * indent-tabs-mode: t
1444df
+ * End:
1444df
+ *
1444df
+ * vi: set shiftwidth=8 tabstop=8 noexpandtab:
1444df
+ * :indentSize=8:tabSize=8:noTabs=false:
1444df
+ */