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

c06811
From b516cc6516b505b264bd75ef5e574490f22912e5 Mon Sep 17 00:00:00 2001
1444df
From: Evan Huus <eapache@gmail.com>
1444df
Date: Sun, 18 Aug 2013 19:49:08 +0000
c06811
Subject: [PATCH 06/13] 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
1444df
---
c06811
 AUTHORS                           |   2 +-
1444df
 epan/CMakeLists.txt               |   1 +
1444df
 epan/dissectors/Makefile.common   |   1 +
1444df
 epan/dissectors/packet-rtpproxy.c | 808 ++++++++++++++++++++++++++++++++++++++
c06811
 4 files changed, 811 insertions(+), 1 deletion(-)
1444df
 create mode 100644 epan/dissectors/packet-rtpproxy.c
1444df
1444df
diff --git a/AUTHORS b/AUTHORS
c06811
index 10782b0..4c77f60 100644
1444df
--- a/AUTHORS
1444df
+++ b/AUTHORS
c06811
@@ -3733,9 +3733,9 @@ 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
 Dan Lasley <dlasley[AT]promus.com> gave permission for his
844b61
 dumpit() hex-dump routine to be used.
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
1444df
index 0000000..7148d58
1444df
--- /dev/null
1444df
+++ b/epan/dissectors/packet-rtpproxy.c
1444df
@@ -0,0 +1,808 @@
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
+
1444df
+#include <epan/packet.h>
1444df
+#include <epan/prefs.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
+
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
+
1444df
+static const value_string errortypenames[] = {
1444df
+	{ '1', "Syntax" },	/* E1 */
1444df
+	{ '7', "Software" },	/* E7 */
1444df
+	{ '8', "Not Found" },	/* E8 */
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
+
1444df
+static void
1444df
+dissect_rtpproxy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
1444df
+{
1444df
+	gboolean has_lf = FALSE;
1444df
+	guint offset = 0;
1444df
+	gint new_offset = 0;
1444df
+	guint tmp;
1444df
+	guint realsize = 0;
1444df
+	guint8* rawstr;
1444df
+	proto_item *ti;
1444df
+	proto_tree *rtpproxy_tree;
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
+	/* Extract Cookie */
1444df
+	offset = tvb_find_guint8(tvb, offset, -1, ' ');
1444df
+	proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_cookie, tvb, 0, offset, ENC_ASCII | ENC_NA);
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
+
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% */
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);
1444df
+				proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_status, tvb, offset, realsize - offset, 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':
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 */
1444df
+			if ((tmp == 'v') && (offset + strlen("VF YYYMMDD") + 1 == realsize)){
1444df
+				/* Skip whitespace */
1444df
+				new_offset = tvb_skip_wsp(tvb, offset + ((guint)strlen("VF") + 1), -1);
1444df
+				proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_version_request, tvb, new_offset, (gint)strlen("YYYYMMDD"), ENC_ASCII | ENC_NA);
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 */
1444df
+			new_offset = (tmp == 'i' ? (gint)(realsize - 1 > offset ? offset + strlen("Ib") : offset + strlen("I")) : tvb_find_guint8(tvb, offset, -1, ' '));
1444df
+
1444df
+			if (new_offset != (gint)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, ' ');
1444df
+				ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_notify, tvb, offset, realsize - offset, 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':
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'){
1444df
+				proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_error, tvb, offset+1, 1, ENC_ASCII | ENC_NA);
1444df
+				break;
1444df
+			}
1444df
+
1444df
+			if (tmp == 'a'){
1444df
+				/* A specific case - short statistics answer */
1444df
+				/* %COOKIE% active sessions: %NUM1% */
1444df
+				proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_status, tvb, offset, realsize - offset, ENC_NA);
1444df
+				break;
1444df
+			}
1444df
+			if ((tmp == '0')&& ((tvb_reported_length(tvb) == offset+1)||(tvb_reported_length(tvb) == offset+2))){
1444df
+				proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_ok, tvb, offset, 1, ENC_ASCII | ENC_NA);
1444df
+				break;
1444df
+			}
1444df
+			if ((tmp == '1') && ((tvb_reported_length(tvb) == offset+1)||(tvb_reported_length(tvb) == offset+2))){
1444df
+				proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_ok, tvb, offset, 1, ENC_ASCII | ENC_NA);
1444df
+				break;
1444df
+			}
1444df
+			if (tvb_reported_length(tvb) == 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);
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",
1444df
+				FT_UINT8,
1444df
+				BASE_DEC,
1444df
+				VALS(errortypenames),
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
+		},
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){
1444df
+		rtpproxy_tcp_handle = create_dissector_handle(dissect_rtpproxy, proto_rtpproxy);
1444df
+		rtpproxy_udp_handle = 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
+ */
1444df
-- 
1444df
1.8.3.1
1444df