844b610048
Signed-off-by: Peter Lemenkov <lemenkov@gmail.com>
897 lines
24 KiB
Diff
897 lines
24 KiB
Diff
From 3c9d2b8cefb0204bf2b83ac925e80e775945e57f Mon Sep 17 00:00:00 2001
|
|
From: Evan Huus <eapache@gmail.com>
|
|
Date: Sun, 18 Aug 2013 19:49:08 +0000
|
|
Subject: [PATCH 6/6] From Peter Lemenkov via
|
|
https://bugs.wireshark.org/bugzilla/show_bug.cgi?id=8326
|
|
|
|
Dissector for the Sippy RTPproxy controlling protocol. RTPproxy is a well-known
|
|
(among SIP-engineers) application and it operates using its own simple
|
|
text-based protocol. There are several competing products but all of them
|
|
implements it (sometimes slightly extending).
|
|
|
|
svn path=/trunk/; revision=51417
|
|
|
|
Add a cast to try and fix
|
|
packet-rtpproxy.c:226: warning: implicit conversion shortens 64-bit value into
|
|
a 32-bit value
|
|
|
|
I'm not quite sure what's going on here, all the values in use are either gint
|
|
or guint so they should all be the same size?
|
|
|
|
svn path=/trunk/; revision=51419
|
|
|
|
Take another stab at
|
|
packet-rtpproxy.c:226: warning: implicit conversion shortens 64-bit value into a
|
|
32-bit value
|
|
|
|
svn path=/trunk/; revision=51420
|
|
|
|
One more 64/32-conversion fix for rtpproxy
|
|
|
|
svn path=/trunk/; revision=51421
|
|
|
|
Fix Coverity CID 1063335: Unused pointer value.
|
|
|
|
svn path=/trunk/; revision=51430
|
|
---
|
|
AUTHORS | 1 +
|
|
epan/CMakeLists.txt | 1 +
|
|
epan/dissectors/Makefile.common | 1 +
|
|
epan/dissectors/packet-rtpproxy.c | 808 ++++++++++++++++++++++++++++++++++++++
|
|
4 files changed, 811 insertions(+)
|
|
create mode 100644 epan/dissectors/packet-rtpproxy.c
|
|
|
|
diff --git a/AUTHORS b/AUTHORS
|
|
index aa446db..ac40c25 100644
|
|
--- a/AUTHORS
|
|
+++ b/AUTHORS
|
|
@@ -3733,6 +3733,7 @@ Max Baker <max[AT]warped.org>
|
|
Mike Garratt <mg.wireshark[AT]evn.co.nz>
|
|
Bart Van Assche <bvanassche[AT]acm.org>
|
|
Karl Beldan <karl.beldan[AT]gmail.com>
|
|
+Peter Lemenkov <lemenkov[AT]gmail.com>
|
|
|
|
Dan Lasley <dlasley[AT]promus.com> gave permission for his
|
|
dumpit() hex-dump routine to be used.
|
|
diff --git a/epan/CMakeLists.txt b/epan/CMakeLists.txt
|
|
index 69eb75f..610cea7 100644
|
|
--- a/epan/CMakeLists.txt
|
|
+++ b/epan/CMakeLists.txt
|
|
@@ -1083,6 +1083,7 @@ set(DISSECTOR_SRC
|
|
dissectors/packet-rtp-events.c
|
|
dissectors/packet-rtp-midi.c
|
|
dissectors/packet-rtp.c
|
|
+ dissectors/packet-rtpproxy.c
|
|
dissectors/packet-rtps.c
|
|
dissectors/packet-rtsp.c
|
|
dissectors/packet-rudp.c
|
|
diff --git a/epan/dissectors/Makefile.common b/epan/dissectors/Makefile.common
|
|
index 937f522..73217d7 100644
|
|
--- a/epan/dissectors/Makefile.common
|
|
+++ b/epan/dissectors/Makefile.common
|
|
@@ -1004,6 +1004,7 @@ DISSECTOR_SRC = \
|
|
packet-rtp-events.c \
|
|
packet-rtp-midi.c \
|
|
packet-rtp.c \
|
|
+ packet-rtpproxy.c \
|
|
packet-rtps.c \
|
|
packet-rtsp.c \
|
|
packet-rudp.c \
|
|
diff --git a/epan/dissectors/packet-rtpproxy.c b/epan/dissectors/packet-rtpproxy.c
|
|
new file mode 100644
|
|
index 0000000..7148d58
|
|
--- /dev/null
|
|
+++ b/epan/dissectors/packet-rtpproxy.c
|
|
@@ -0,0 +1,808 @@
|
|
+/* packet-rtpproxy.c
|
|
+ * RTPproxy command protocol dissector
|
|
+ * Copyright 2013, Peter Lemenkov <lemenkov@gmail.com>
|
|
+ *
|
|
+ * This dissector tries to dissect rtpproxy control protocol. Please visit this
|
|
+ * link for brief details on the command format:
|
|
+ *
|
|
+ * http://www.rtpproxy.org/wiki/RTPproxy/Protocol
|
|
+ *
|
|
+ * $Id$
|
|
+ *
|
|
+ * Wireshark - Network traffic analyzer
|
|
+ * By Gerald Combs <gerald@wireshark.org>
|
|
+ * Copyright 1999 Gerald Combs
|
|
+ *
|
|
+ * This program is free software; you can redistribute it and/or
|
|
+ * modify it under the terms of the GNU General Public License
|
|
+ * as published by the Free Software Foundation; either version 2
|
|
+ * of the License, or (at your option) any later version.
|
|
+ *
|
|
+ * This program is distributed in the hope that it will be useful,
|
|
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
+ * GNU General Public License for more details.
|
|
+ *
|
|
+ * You should have received a copy of the GNU General Public License
|
|
+ * along with this program; if not, write to the Free Software
|
|
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
+ */
|
|
+
|
|
+#include "config.h"
|
|
+
|
|
+#include <epan/packet.h>
|
|
+#include <epan/prefs.h>
|
|
+
|
|
+static int proto_rtpproxy = -1;
|
|
+
|
|
+static int hf_rtpproxy_cookie = -1;
|
|
+static int hf_rtpproxy_error = -1;
|
|
+static int hf_rtpproxy_status = -1;
|
|
+static int hf_rtpproxy_ok = -1;
|
|
+static int hf_rtpproxy_ipv4 = -1;
|
|
+static int hf_rtpproxy_ipv6 = -1;
|
|
+static int hf_rtpproxy_port = -1;
|
|
+static int hf_rtpproxy_lf = -1;
|
|
+static int hf_rtpproxy_request = -1;
|
|
+static int hf_rtpproxy_command = -1;
|
|
+static int hf_rtpproxy_command_parameters = -1;
|
|
+static int hf_rtpproxy_callid = -1;
|
|
+static int hf_rtpproxy_copy_target = -1;
|
|
+static int hf_rtpproxy_playback_filename = -1;
|
|
+static int hf_rtpproxy_playback_codec = -1;
|
|
+static int hf_rtpproxy_notify = -1;
|
|
+static int hf_rtpproxy_notify_ipv4 = -1;
|
|
+static int hf_rtpproxy_notify_port = -1;
|
|
+static int hf_rtpproxy_notify_tag = -1;
|
|
+static int hf_rtpproxy_tag = -1;
|
|
+static int hf_rtpproxy_mediaid = -1;
|
|
+static int hf_rtpproxy_reply = -1;
|
|
+static int hf_rtpproxy_version_request = -1;
|
|
+static int hf_rtpproxy_version_supported = -1;
|
|
+
|
|
+static const value_string commandtypenames[] = {
|
|
+ { 'V', "Handshake/Ping" },
|
|
+ { 'v', "Handshake/Ping" },
|
|
+ { 'U', "Offer/Update" },
|
|
+ { 'u', "Offer/Update" },
|
|
+ { 'L', "Answer/Lookup" },
|
|
+ { 'l', "Answer/Lookup" },
|
|
+ { 'I', "Information"},
|
|
+ { 'i', "Information"},
|
|
+ { 'X', "Close all active sessions"},
|
|
+ { 'x', "Close all active sessions"},
|
|
+ { 'D', "Delete an active session (Bye/Cancel/Error)"},
|
|
+ { 'd', "Delete an active session (Bye/Cancel/Error)"},
|
|
+ { 'P', "Start playback (music-on-hold)"},
|
|
+ { 'p', "Start playback (music-on-hold)"},
|
|
+ { 'S', "Stop playback (music-on-hold)"},
|
|
+ { 's', "Stop playback (music-on-hold)"},
|
|
+ { 'R', "Start recording"},
|
|
+ { 'r', "Start recording"},
|
|
+ { 'C', "Copy stream"},
|
|
+ { 'c', "Copy stream"},
|
|
+ { 'Q', "Query info about a session"},
|
|
+ { 'q', "Query info about a session"},
|
|
+ { 0, NULL }
|
|
+};
|
|
+
|
|
+static const value_string oktypenames[] = {
|
|
+ { '0', "Ok"},
|
|
+ { '1', "Version Supported"},
|
|
+ { 0, NULL }
|
|
+};
|
|
+
|
|
+static const value_string errortypenames[] = {
|
|
+ { '1', "Syntax" }, /* E1 */
|
|
+ { '7', "Software" }, /* E7 */
|
|
+ { '8', "Not Found" }, /* E8 */
|
|
+ { 0, NULL }
|
|
+};
|
|
+
|
|
+static const value_string flowcontroltypenames[] = {
|
|
+ { '\n', "Yes"},
|
|
+ { 0, NULL }
|
|
+};
|
|
+
|
|
+static gint ett_rtpproxy = -1;
|
|
+
|
|
+static gint ett_rtpproxy_request = -1;
|
|
+static gint ett_rtpproxy_command = -1;
|
|
+static gint ett_rtpproxy_tag = -1;
|
|
+static gint ett_rtpproxy_notify = -1;
|
|
+
|
|
+static gint ett_rtpproxy_reply = -1;
|
|
+
|
|
+static guint rtpproxy_tcp_port = 22222;
|
|
+static guint rtpproxy_udp_port = 22222;
|
|
+
|
|
+void proto_reg_handoff_rtpproxy(void);
|
|
+
|
|
+gint
|
|
+rtpptoxy_add_tag(proto_tree *rtpproxy_tree, tvbuff_t *tvb, guint begin, guint realsize)
|
|
+{
|
|
+ proto_item *ti = NULL;
|
|
+ proto_tree *another_tree = NULL;
|
|
+ gint new_offset;
|
|
+ guint end;
|
|
+
|
|
+ new_offset = tvb_find_guint8(tvb, begin, -1, ' ');
|
|
+ if(new_offset < 0)
|
|
+ end = realsize; /* No more parameters */
|
|
+ else
|
|
+ end = new_offset;
|
|
+
|
|
+ /* SER/OpenSER/OpenSIPS/Kamailio adds Media-ID right after the Tag
|
|
+ * separated by a semicolon
|
|
+ */
|
|
+ new_offset = tvb_find_guint8(tvb, begin, end, ';');
|
|
+ if(new_offset == -1){
|
|
+ ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_tag, tvb, begin, end - begin, ENC_ASCII | ENC_NA);
|
|
+ another_tree = proto_item_add_subtree(ti, ett_rtpproxy_tag);
|
|
+ ti = proto_tree_add_item(another_tree, hf_rtpproxy_mediaid, tvb, new_offset+1, 0, ENC_ASCII | ENC_NA);
|
|
+ proto_item_set_text(ti, "Media-ID: <skipped>");
|
|
+ }
|
|
+ else{
|
|
+ ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_tag, tvb, begin, new_offset - begin, ENC_ASCII | ENC_NA);
|
|
+ another_tree = proto_item_add_subtree(ti, ett_rtpproxy_tag);
|
|
+ proto_tree_add_item(another_tree, hf_rtpproxy_mediaid, tvb, new_offset+1, end - (new_offset+1), ENC_ASCII | ENC_NA);
|
|
+ }
|
|
+ return (end == realsize ? -1 : (gint)end);
|
|
+}
|
|
+
|
|
+static void
|
|
+dissect_rtpproxy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
|
|
+{
|
|
+ gboolean has_lf = FALSE;
|
|
+ guint offset = 0;
|
|
+ gint new_offset = 0;
|
|
+ guint tmp;
|
|
+ guint realsize = 0;
|
|
+ guint8* rawstr;
|
|
+ proto_item *ti;
|
|
+ proto_tree *rtpproxy_tree;
|
|
+
|
|
+ /* Clear out stuff in the info column - we''l set it later */
|
|
+ col_clear(pinfo->cinfo, COL_INFO);
|
|
+
|
|
+ ti = proto_tree_add_item(tree, proto_rtpproxy, tvb, 0, -1, ENC_NA);
|
|
+ rtpproxy_tree = proto_item_add_subtree(ti, ett_rtpproxy);
|
|
+
|
|
+ /* Extract Cookie */
|
|
+ offset = tvb_find_guint8(tvb, offset, -1, ' ');
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_cookie, tvb, 0, offset, ENC_ASCII | ENC_NA);
|
|
+
|
|
+ /* Skip whitespace */
|
|
+ offset = tvb_skip_wsp(tvb, offset+1, -1);
|
|
+
|
|
+ /* Calculate size to prevent recalculation in the future */
|
|
+ realsize = tvb_reported_length(tvb);
|
|
+
|
|
+ /* Check for LF (required for TCP connection, optional for UDP) */
|
|
+ if (tvb_get_guint8(tvb, realsize - 1) == '\n'){
|
|
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTPproxy");
|
|
+ /* Don't count trailing LF */
|
|
+ realsize -= 1;
|
|
+ has_lf = TRUE;
|
|
+ }
|
|
+ else
|
|
+ col_set_str(pinfo->cinfo, COL_PROTOCOL, "RTPproxy (no LF)");
|
|
+
|
|
+ /* Get payload string */
|
|
+ rawstr = tvb_get_ephemeral_string(tvb, offset, realsize - offset);
|
|
+
|
|
+ /* Extract command */
|
|
+ tmp = g_ascii_tolower(tvb_get_guint8(tvb, offset));
|
|
+ switch (tmp)
|
|
+ {
|
|
+ case 's':
|
|
+ /* A specific case - long statistics answer */
|
|
+ /* %COOKIE% sessions created %NUM0% active sessions: %NUM1% */
|
|
+ if ('e' == tvb_get_guint8(tvb, offset+1)){
|
|
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Reply: %s", rawstr);
|
|
+ ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_reply, tvb, offset, -1, ENC_NA);
|
|
+
|
|
+ rtpproxy_tree = proto_item_add_subtree(ti, ett_rtpproxy_reply);
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_status, tvb, offset, realsize - offset, ENC_NA);
|
|
+ break;
|
|
+ }
|
|
+ case 'i':
|
|
+ case 'x':
|
|
+ case 'u':
|
|
+ case 'l':
|
|
+ case 'd':
|
|
+ case 'p':
|
|
+ case 'v':
|
|
+ case 'r':
|
|
+ case 'c':
|
|
+ case 'q':
|
|
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Request: %s", rawstr);
|
|
+ ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_request, tvb, offset, -1, ENC_NA);
|
|
+ rtpproxy_tree = proto_item_add_subtree(ti, ett_rtpproxy_request);
|
|
+
|
|
+ /* A specific case - version request */
|
|
+ if ((tmp == 'v') && (offset + strlen("VF YYYMMDD") + 1 == realsize)){
|
|
+ /* Skip whitespace */
|
|
+ new_offset = tvb_skip_wsp(tvb, offset + ((guint)strlen("VF") + 1), -1);
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_version_request, tvb, new_offset, (gint)strlen("YYYYMMDD"), ENC_ASCII | ENC_NA);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /* All other commands */
|
|
+ ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_command, tvb, offset, 1, ENC_NA);
|
|
+
|
|
+ /* A specific case - handshake/ping */
|
|
+ if (tmp == 'v')
|
|
+ break; /* No more parameters */
|
|
+
|
|
+ /* A specific case - close all calls */
|
|
+ if (tmp == 'x')
|
|
+ break; /* No more parameters */
|
|
+
|
|
+ /* Extract parameters */
|
|
+ /* Parameters should be right after the command and before EOL (in case of Info command) or before whitespace */
|
|
+ new_offset = (tmp == 'i' ? (gint)(realsize - 1 > offset ? offset + strlen("Ib") : offset + strlen("I")) : tvb_find_guint8(tvb, offset, -1, ' '));
|
|
+
|
|
+ if (new_offset != (gint)offset + 1){
|
|
+ rtpproxy_tree = proto_item_add_subtree(ti, ett_rtpproxy_command);
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_command_parameters, tvb, offset+1, new_offset - (offset+1), ENC_ASCII | ENC_NA);
|
|
+ rtpproxy_tree = proto_item_get_parent(ti);
|
|
+ }
|
|
+
|
|
+ /* A specific case - query information */
|
|
+ if (tmp == 'i')
|
|
+ break; /* No more parameters */
|
|
+
|
|
+ /* Skip whitespace */
|
|
+ offset = tvb_skip_wsp(tvb, new_offset+1, -1);
|
|
+
|
|
+ /* Extract Call-ID */
|
|
+ new_offset = tvb_find_guint8(tvb, offset, -1, ' ');
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_callid, tvb, offset, new_offset - offset, ENC_ASCII | ENC_NA);
|
|
+ /* Skip whitespace */
|
|
+ offset = tvb_skip_wsp(tvb, new_offset+1, -1);
|
|
+
|
|
+ /* Extract IP and Port in case of Offer/Answer */
|
|
+ if ((tmp == 'u') || (tmp == 'l')){
|
|
+ /* Extract IP */
|
|
+ new_offset = tvb_find_guint8(tvb, offset, -1, ' ');
|
|
+ if (tvb_find_guint8(tvb, offset, new_offset - offset, ':') == -1)
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_ipv4, tvb, offset, new_offset - offset, ENC_ASCII | ENC_NA);
|
|
+ else
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_ipv6, tvb, offset, new_offset - offset, ENC_ASCII | ENC_NA);
|
|
+ /* Skip whitespace */
|
|
+ offset = tvb_skip_wsp(tvb, new_offset+1, -1);
|
|
+
|
|
+ /* Extract Port */
|
|
+ new_offset = tvb_find_guint8(tvb, offset, -1, ' ');
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_port, tvb, offset, new_offset - offset, ENC_ASCII | ENC_NA);
|
|
+ /* Skip whitespace */
|
|
+ offset = tvb_skip_wsp(tvb, new_offset+1, -1);
|
|
+ }
|
|
+
|
|
+ /* Extract Copy target */
|
|
+ if (tmp == 'c'){
|
|
+ new_offset = tvb_find_guint8(tvb, offset, -1, ' ');
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_copy_target, tvb, offset, new_offset - offset, ENC_ASCII | ENC_NA);
|
|
+ /* Skip whitespace */
|
|
+ offset = tvb_skip_wsp(tvb, new_offset+1, -1);
|
|
+ }
|
|
+
|
|
+ /* Extract Playback file and codecs */
|
|
+ if (tmp == 'p'){
|
|
+ /* Extract filename */
|
|
+ new_offset = tvb_find_guint8(tvb, offset, -1, ' ');
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_playback_filename, tvb, offset, new_offset - offset, ENC_ASCII | ENC_NA);
|
|
+ /* Skip whitespace */
|
|
+ offset = tvb_skip_wsp(tvb, new_offset+1, -1);
|
|
+
|
|
+ /* Extract codec */
|
|
+ new_offset = tvb_find_guint8(tvb, offset, -1, ' ');
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_playback_codec, tvb, offset, new_offset - offset, ENC_ASCII | ENC_NA);
|
|
+ /* Skip whitespace */
|
|
+ offset = tvb_skip_wsp(tvb, new_offset+1, -1);
|
|
+ }
|
|
+
|
|
+ /* Extract first tag */
|
|
+ new_offset = rtpptoxy_add_tag(rtpproxy_tree, tvb, offset, realsize);
|
|
+ if(new_offset == -1)
|
|
+ break; /* No more parameters */
|
|
+ /* Skip whitespace */
|
|
+ offset = tvb_skip_wsp(tvb, new_offset+1, -1);
|
|
+
|
|
+ /* Extract second tag */
|
|
+ new_offset = rtpptoxy_add_tag(rtpproxy_tree, tvb, offset, realsize);
|
|
+ if(new_offset == -1)
|
|
+ break; /* No more parameters */
|
|
+ /* Skip whitespace */
|
|
+ offset = tvb_skip_wsp(tvb, new_offset+1, -1);
|
|
+
|
|
+ /* Extract Notification address */
|
|
+ if (tmp == 'u'){
|
|
+ new_offset = tvb_find_guint8(tvb, offset, -1, ' ');
|
|
+ ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_notify, tvb, offset, realsize - offset, ENC_NA);
|
|
+ proto_item_set_text(ti, "Notify");
|
|
+ rtpproxy_tree = proto_item_add_subtree(ti, ett_rtpproxy_notify);
|
|
+ if(new_offset == -1){
|
|
+ /* FIXME only IPv4 is supported */
|
|
+ new_offset = tvb_find_guint8(tvb, offset, -1, ':');
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_notify_ipv4, tvb, offset, new_offset - offset, ENC_ASCII | ENC_NA);
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_notify_port, tvb, new_offset+1, realsize - (new_offset+1), ENC_ASCII | ENC_NA);
|
|
+ break; /* No more parameters */
|
|
+ }
|
|
+ if(new_offset - offset < 6){
|
|
+ /* Only port is supplied */
|
|
+ ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_notify_ipv4, tvb, offset, 0, ENC_ASCII | ENC_NA);
|
|
+ proto_item_set_text(ti, "Notification IPv4: <skipped>");
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_notify_port, tvb, offset, new_offset - offset, ENC_ASCII | ENC_NA);
|
|
+ }
|
|
+ else{
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_notify_ipv4, tvb, offset, new_offset - offset, ENC_ASCII | ENC_NA);
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_notify_port, tvb, new_offset+1, realsize - (new_offset+1), ENC_ASCII | ENC_NA);
|
|
+ }
|
|
+ /* Skip whitespace */
|
|
+ offset = tvb_skip_wsp(tvb, new_offset+1, -1);
|
|
+
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_notify_tag, tvb, offset, realsize - offset, ENC_ASCII | ENC_NA);
|
|
+ }
|
|
+ break;
|
|
+ case 'a':
|
|
+ case 'e':
|
|
+ case '0':
|
|
+ case '1':
|
|
+ case '2':
|
|
+ case '3':
|
|
+ case '4':
|
|
+ case '5':
|
|
+ case '6':
|
|
+ case '7':
|
|
+ case '8':
|
|
+ case '9':
|
|
+ if (tmp == 'e')
|
|
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Error reply: %s", rawstr);
|
|
+ else
|
|
+ col_add_fstr(pinfo->cinfo, COL_INFO, "Reply: %s", rawstr);
|
|
+
|
|
+ ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_reply, tvb, offset, -1, ENC_NA);
|
|
+ rtpproxy_tree = proto_item_add_subtree(ti, ett_rtpproxy_reply);
|
|
+
|
|
+ if (tmp == 'e'){
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_error, tvb, offset+1, 1, ENC_ASCII | ENC_NA);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ if (tmp == 'a'){
|
|
+ /* A specific case - short statistics answer */
|
|
+ /* %COOKIE% active sessions: %NUM1% */
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_status, tvb, offset, realsize - offset, ENC_NA);
|
|
+ break;
|
|
+ }
|
|
+ if ((tmp == '0')&& ((tvb_reported_length(tvb) == offset+1)||(tvb_reported_length(tvb) == offset+2))){
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_ok, tvb, offset, 1, ENC_ASCII | ENC_NA);
|
|
+ break;
|
|
+ }
|
|
+ if ((tmp == '1') && ((tvb_reported_length(tvb) == offset+1)||(tvb_reported_length(tvb) == offset+2))){
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_ok, tvb, offset, 1, ENC_ASCII | ENC_NA);
|
|
+ break;
|
|
+ }
|
|
+ if (tvb_reported_length(tvb) == offset+9){
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_version_supported, tvb, offset, 8, ENC_ASCII | ENC_NA);
|
|
+ break;
|
|
+ }
|
|
+
|
|
+ /* Extract Port */
|
|
+ new_offset = tvb_find_guint8(tvb, offset, -1, ' ');
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_port, tvb, offset, new_offset - offset, ENC_ASCII | ENC_NA);
|
|
+ /* Skip whitespace */
|
|
+ offset = tvb_skip_wsp(tvb, new_offset+1, -1);
|
|
+
|
|
+ /* Extract IP */
|
|
+ tmp = tvb_find_line_end(tvb, offset, -1, &new_offset, FALSE);
|
|
+ if (tvb_find_guint8(tvb, offset, -1, ':') == -1)
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_ipv4, tvb, offset, tmp, ENC_ASCII | ENC_NA);
|
|
+ else
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_ipv6, tvb, offset, tmp, ENC_ASCII | ENC_NA);
|
|
+ break;
|
|
+ default:
|
|
+ break;
|
|
+ }
|
|
+ if (has_lf)
|
|
+ proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_lf, tvb, realsize, 1, ENC_NA);
|
|
+}
|
|
+
|
|
+void
|
|
+proto_register_rtpproxy(void)
|
|
+{
|
|
+ module_t *rtpproxy_module;
|
|
+
|
|
+ static hf_register_info hf[] = {
|
|
+ {
|
|
+ &hf_rtpproxy_cookie,
|
|
+ {
|
|
+ "Cookie",
|
|
+ "rtpproxy.cookie",
|
|
+ FT_STRING,
|
|
+ BASE_NONE,
|
|
+ NULL,
|
|
+ 0x0,
|
|
+ NULL,
|
|
+ HFILL
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ &hf_rtpproxy_version_request,
|
|
+ {
|
|
+ "Version Request",
|
|
+ "rtpproxy.version",
|
|
+ FT_STRING,
|
|
+ BASE_NONE,
|
|
+ NULL,
|
|
+ 0x0,
|
|
+ NULL,
|
|
+ HFILL
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ &hf_rtpproxy_version_supported,
|
|
+ {
|
|
+ "Version Supported",
|
|
+ "rtpproxy.version_supported",
|
|
+ FT_STRING,
|
|
+ BASE_NONE,
|
|
+ NULL,
|
|
+ 0x0,
|
|
+ NULL,
|
|
+ HFILL
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ &hf_rtpproxy_error,
|
|
+ {
|
|
+ "Error",
|
|
+ "rtpproxy.error",
|
|
+ FT_UINT8,
|
|
+ BASE_DEC,
|
|
+ VALS(errortypenames),
|
|
+ 0x0,
|
|
+ NULL,
|
|
+ HFILL
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ &hf_rtpproxy_ok,
|
|
+ {
|
|
+ "Ok",
|
|
+ "rtpproxy.ok",
|
|
+ FT_UINT8,
|
|
+ BASE_DEC,
|
|
+ VALS(oktypenames),
|
|
+ 0x0,
|
|
+ NULL,
|
|
+ HFILL
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ &hf_rtpproxy_status,
|
|
+ {
|
|
+ "Status",
|
|
+ "rtpproxy.status",
|
|
+ FT_STRING,
|
|
+ BASE_NONE,
|
|
+ NULL,
|
|
+ 0x0,
|
|
+ NULL,
|
|
+ HFILL
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ &hf_rtpproxy_ipv4,
|
|
+ {
|
|
+ "IPv4",
|
|
+ "rtpproxy.ipv4",
|
|
+ FT_STRING,
|
|
+ BASE_NONE,
|
|
+ NULL,
|
|
+ 0x0,
|
|
+ NULL,
|
|
+ HFILL
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ &hf_rtpproxy_ipv6,
|
|
+ {
|
|
+ "IPv6",
|
|
+ "rtpproxy.ipv6",
|
|
+ FT_STRING,
|
|
+ BASE_NONE,
|
|
+ NULL,
|
|
+ 0x0,
|
|
+ NULL,
|
|
+ HFILL
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ &hf_rtpproxy_port,
|
|
+ {
|
|
+ "Port",
|
|
+ "rtpproxy.port",
|
|
+ FT_STRING,
|
|
+ BASE_NONE,
|
|
+ NULL,
|
|
+ 0x0,
|
|
+ NULL,
|
|
+ HFILL
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ &hf_rtpproxy_request,
|
|
+ {
|
|
+ "Request",
|
|
+ "rtpproxy.request",
|
|
+ FT_NONE,
|
|
+ BASE_NONE,
|
|
+ NULL,
|
|
+ 0x0,
|
|
+ NULL,
|
|
+ HFILL
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ &hf_rtpproxy_command,
|
|
+ {
|
|
+ "Command",
|
|
+ "rtpproxy.command",
|
|
+ FT_UINT8,
|
|
+ BASE_DEC,
|
|
+ VALS(commandtypenames),
|
|
+ 0x0,
|
|
+ NULL,
|
|
+ HFILL
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ &hf_rtpproxy_command_parameters,
|
|
+ {
|
|
+ "Command parameters",
|
|
+ "rtpproxy.command_parameters",
|
|
+ FT_STRING,
|
|
+ BASE_NONE,
|
|
+ NULL,
|
|
+ 0x0,
|
|
+ NULL,
|
|
+ HFILL
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ &hf_rtpproxy_copy_target,
|
|
+ {
|
|
+ "Copy target",
|
|
+ "rtpproxy.copy_target",
|
|
+ FT_STRING,
|
|
+ BASE_NONE,
|
|
+ NULL,
|
|
+ 0x0,
|
|
+ NULL,
|
|
+ HFILL
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ &hf_rtpproxy_playback_filename,
|
|
+ {
|
|
+ "Playback filename",
|
|
+ "rtpproxy.playback_filename",
|
|
+ FT_STRING,
|
|
+ BASE_NONE,
|
|
+ NULL,
|
|
+ 0x0,
|
|
+ NULL,
|
|
+ HFILL
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ &hf_rtpproxy_playback_codec,
|
|
+ {
|
|
+ "Playback codec",
|
|
+ "rtpproxy.playback_codec",
|
|
+ FT_STRING,
|
|
+ BASE_NONE,
|
|
+ NULL,
|
|
+ 0x0,
|
|
+ NULL,
|
|
+ HFILL
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ &hf_rtpproxy_callid,
|
|
+ {
|
|
+ "Call-ID",
|
|
+ "rtpproxy.callid",
|
|
+ FT_STRING,
|
|
+ BASE_NONE,
|
|
+ NULL,
|
|
+ 0x0,
|
|
+ NULL,
|
|
+ HFILL
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ &hf_rtpproxy_notify,
|
|
+ {
|
|
+ "Notify",
|
|
+ "rtpproxy.notify",
|
|
+ FT_STRING,
|
|
+ BASE_NONE,
|
|
+ NULL,
|
|
+ 0x0,
|
|
+ NULL,
|
|
+ HFILL
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ &hf_rtpproxy_tag,
|
|
+ {
|
|
+ "Tag",
|
|
+ "rtpproxy.tag",
|
|
+ FT_STRING,
|
|
+ BASE_NONE,
|
|
+ NULL,
|
|
+ 0x0,
|
|
+ NULL,
|
|
+ HFILL
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ &hf_rtpproxy_mediaid,
|
|
+ {
|
|
+ "Media-ID",
|
|
+ "rtpproxy.mediaid",
|
|
+ FT_STRING,
|
|
+ BASE_NONE,
|
|
+ NULL,
|
|
+ 0x0,
|
|
+ NULL,
|
|
+ HFILL
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ &hf_rtpproxy_notify_ipv4,
|
|
+ {
|
|
+ "Notification IPv4",
|
|
+ "rtpproxy.notify_ipv4",
|
|
+ FT_STRING,
|
|
+ BASE_NONE,
|
|
+ NULL,
|
|
+ 0x0,
|
|
+ NULL,
|
|
+ HFILL
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ &hf_rtpproxy_notify_port,
|
|
+ {
|
|
+ "Notification Port",
|
|
+ "rtpproxy.notify_port",
|
|
+ FT_STRING,
|
|
+ BASE_NONE,
|
|
+ NULL,
|
|
+ 0x0,
|
|
+ NULL,
|
|
+ HFILL
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ &hf_rtpproxy_notify_tag,
|
|
+ {
|
|
+ "Notification Tag",
|
|
+ "rtpproxy.notify_tag",
|
|
+ FT_STRING,
|
|
+ BASE_NONE,
|
|
+ NULL,
|
|
+ 0x0,
|
|
+ NULL,
|
|
+ HFILL
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ &hf_rtpproxy_reply,
|
|
+ {
|
|
+ "Reply",
|
|
+ "rtpproxy.reply",
|
|
+ FT_NONE,
|
|
+ BASE_NONE,
|
|
+ NULL,
|
|
+ 0x0,
|
|
+ NULL,
|
|
+ HFILL
|
|
+ }
|
|
+ },
|
|
+ {
|
|
+ &hf_rtpproxy_lf,
|
|
+ {
|
|
+ "LF",
|
|
+ "rtpproxy.lf",
|
|
+ FT_UINT8,
|
|
+ BASE_DEC,
|
|
+ VALS(flowcontroltypenames),
|
|
+ 0x0,
|
|
+ NULL,
|
|
+ HFILL
|
|
+ }
|
|
+ },
|
|
+ };
|
|
+
|
|
+ /* Setup protocol subtree array */
|
|
+ static gint *ett[] = {
|
|
+ &ett_rtpproxy,
|
|
+ &ett_rtpproxy_request,
|
|
+ &ett_rtpproxy_command,
|
|
+ &ett_rtpproxy_tag,
|
|
+ &ett_rtpproxy_notify,
|
|
+ &ett_rtpproxy_reply
|
|
+ };
|
|
+
|
|
+ proto_rtpproxy = proto_register_protocol (
|
|
+ "Sippy RTPproxy Protocol", /* name */
|
|
+ "RTPproxy", /* short name */
|
|
+ "rtpproxy" /* abbrev */
|
|
+ );
|
|
+
|
|
+ proto_register_field_array(proto_rtpproxy, hf, array_length(hf));
|
|
+ proto_register_subtree_array(ett, array_length(ett));
|
|
+
|
|
+ rtpproxy_module = prefs_register_protocol(proto_rtpproxy, proto_reg_handoff_rtpproxy);
|
|
+ prefs_register_uint_preference(rtpproxy_module, "tcp.port",
|
|
+ "RTPproxy TCP Port", /* Title */
|
|
+ "RTPproxy TCP Port", /* Descr */
|
|
+ 10,
|
|
+ &rtpproxy_tcp_port);
|
|
+
|
|
+ prefs_register_uint_preference(rtpproxy_module, "udp.port",
|
|
+ "RTPproxy UDP Port", /* Title */
|
|
+ "RTPproxy UDP Port", /* Descr */
|
|
+ 10,
|
|
+ &rtpproxy_udp_port);
|
|
+}
|
|
+
|
|
+void
|
|
+proto_reg_handoff_rtpproxy(void)
|
|
+{
|
|
+ static guint old_rtpproxy_tcp_port = 0;
|
|
+ static guint old_rtpproxy_udp_port = 0;
|
|
+
|
|
+ static gboolean rtpproxy_initialized = FALSE;
|
|
+
|
|
+ static dissector_handle_t rtpproxy_tcp_handle, rtpproxy_udp_handle;
|
|
+
|
|
+ if(!rtpproxy_initialized){
|
|
+ rtpproxy_tcp_handle = create_dissector_handle(dissect_rtpproxy, proto_rtpproxy);
|
|
+ rtpproxy_udp_handle = create_dissector_handle(dissect_rtpproxy, proto_rtpproxy);
|
|
+ rtpproxy_initialized = TRUE;
|
|
+ }
|
|
+
|
|
+ /* Register TCP port for dissection */
|
|
+ if(old_rtpproxy_tcp_port != 0 && old_rtpproxy_tcp_port != rtpproxy_tcp_port)
|
|
+ dissector_delete_uint("tcp.port", old_rtpproxy_tcp_port, rtpproxy_tcp_handle);
|
|
+ if(rtpproxy_tcp_port != 0 && old_rtpproxy_tcp_port != rtpproxy_tcp_port)
|
|
+ dissector_add_uint("tcp.port", rtpproxy_tcp_port, rtpproxy_tcp_handle);
|
|
+ old_rtpproxy_tcp_port = rtpproxy_tcp_port;
|
|
+
|
|
+ /* Register UDP port for dissection */
|
|
+ if(old_rtpproxy_udp_port != 0 && old_rtpproxy_udp_port != rtpproxy_udp_port)
|
|
+ dissector_delete_uint("udp.port", old_rtpproxy_udp_port, rtpproxy_udp_handle);
|
|
+ if(rtpproxy_udp_port != 0 && old_rtpproxy_udp_port != rtpproxy_udp_port)
|
|
+ dissector_add_uint("udp.port", rtpproxy_udp_port, rtpproxy_udp_handle);
|
|
+ old_rtpproxy_udp_port = rtpproxy_udp_port;
|
|
+}
|
|
+
|
|
+/*
|
|
+ * Editor modelines - http://www.wireshark.org/tools/modelines.html
|
|
+ *
|
|
+ * Local variables:
|
|
+ * c-basic-offset: 8
|
|
+ * tab-width: 8
|
|
+ * indent-tabs-mode: t
|
|
+ * End:
|
|
+ *
|
|
+ * vi: set shiftwidth=8 tabstop=8 noexpandtab:
|
|
+ * :indentSize=8:tabSize=8:noTabs=false:
|
|
+ */
|
|
--
|
|
1.8.3.1
|
|
|