Blame wireshark-0022-Fix-IP-types.patch

ab5f7c
From: Peter Lemenkov <lemenkov@gmail.com>
ab5f7c
Date: Fri, 13 Dec 2013 22:10:21 +0400
ab5f7c
Subject: [PATCH] Fix IP types
ab5f7c
ab5f7c
Signed-off-by: Peter Lemenkov <lemenkov@gmail.com>
ab5f7c
ab5f7c
diff --git a/epan/dissectors/packet-rtpproxy.c b/epan/dissectors/packet-rtpproxy.c
ab5f7c
index e8c5c95..6291de3 100644
ab5f7c
--- a/epan/dissectors/packet-rtpproxy.c
ab5f7c
+++ b/epan/dissectors/packet-rtpproxy.c
ab5f7c
@@ -40,6 +40,9 @@
ab5f7c
 #include <epan/expert.h>
ab5f7c
 #include <epan/rtp_pt.h>
ab5f7c
 
ab5f7c
+#include <epan/exceptions.h>
ab5f7c
+#include <epan/show_exception.h>
ab5f7c
+
ab5f7c
 #ifdef HAVE_ARPA_INET_H
ab5f7c
 #include <arpa/inet.h>
ab5f7c
 #endif
ab5f7c
@@ -69,8 +72,8 @@ static int hf_rtpproxy_command = -1;
ab5f7c
 static int hf_rtpproxy_command_parameters = -1;
ab5f7c
 static int hf_rtpproxy_command_parameter = -1;
ab5f7c
 static int hf_rtpproxy_command_parameter_codec = -1;
ab5f7c
-static int hf_rtpproxy_command_parameter_local = -1;
ab5f7c
-static int hf_rtpproxy_command_parameter_remote = -1;
ab5f7c
+static int hf_rtpproxy_command_parameter_local_ipv4 = -1;
ab5f7c
+static int hf_rtpproxy_command_parameter_remote_ipv4 = -1;
ab5f7c
 static int hf_rtpproxy_command_parameter_repacketize = -1;
ab5f7c
 static int hf_rtpproxy_command_parameter_dtmf = -1;
ab5f7c
 /* static int hf_rtpproxy_command_parameter_cmap = -1; TODO */
ab5f7c
@@ -294,8 +297,8 @@ rtpproxy_add_tag(proto_tree *rtpproxy_tree, tvbuff_t *tvb, guint begin, guint re
ab5f7c
 	return (end == realsize ? -1 : (gint)end);
ab5f7c
 }
ab5f7c
 
ab5f7c
-void
ab5f7c
-rtpproxy_add_parameter(proto_tree *rtpproxy_tree, tvbuff_t *tvb, guint begin, guint realsize)
ab5f7c
+static void
ab5f7c
+rtpproxy_add_parameter(tvbuff_t *tvb, packet_info *pinfo, proto_tree *rtpproxy_tree, guint begin, guint realsize)
ab5f7c
 {
ab5f7c
 	proto_item *ti;
ab5f7c
 	proto_tree *another_tree = NULL;
ab5f7c
@@ -306,6 +309,7 @@ rtpproxy_add_parameter(proto_tree *rtpproxy_tree, tvbuff_t *tvb, guint begin, gu
ab5f7c
 	gchar** codecs = NULL;
ab5f7c
 	guint codec_len;
ab5f7c
 	guint8* rawstr = NULL;
ab5f7c
+	guint32 ipaddr[4]; /* Enough room for IPv4 or IPv6 */
ab5f7c
 
ab5f7c
 	/* Extract the entire parameters line. */
ab5f7c
 	/* Something like "t4p1iic8,0,2,4,18,96,97,98,100,101" */
ab5f7c
@@ -338,13 +342,19 @@ rtpproxy_add_parameter(proto_tree *rtpproxy_tree, tvbuff_t *tvb, guint begin, gu
ab5f7c
 			case 'l':
ab5f7c
 				new_offset = (gint)strspn(rawstr+offset, "0123456789.");
ab5f7c
 				another_tree = proto_item_add_subtree(ti, ett_rtpproxy_command_parameters_local);
ab5f7c
-				proto_tree_add_item(another_tree, hf_rtpproxy_command_parameter_local, tvb, begin+offset, new_offset, ENC_ASCII | ENC_NA);
ab5f7c
+				if(inet_pton(AF_INET, (char*)tvb_get_ephemeral_string(tvb, begin+offset, new_offset), ipaddr))
ab5f7c
+					proto_tree_add_ipv4(another_tree, hf_rtpproxy_command_parameter_local_ipv4, tvb, begin+offset, new_offset, ipaddr[0]);
ab5f7c
+				else
ab5f7c
+					show_exception(tvb, pinfo, another_tree, DissectorError, "Bogus IPv4");
ab5f7c
 				offset += new_offset;
ab5f7c
 				break;
ab5f7c
 			case 'r':
ab5f7c
 				new_offset = (gint)strspn(rawstr+offset, "0123456789.");
ab5f7c
 				another_tree = proto_item_add_subtree(ti, ett_rtpproxy_command_parameters_remote);
ab5f7c
-				proto_tree_add_item(another_tree, hf_rtpproxy_command_parameter_remote, tvb, begin+offset, new_offset, ENC_ASCII | ENC_NA);
ab5f7c
+				if(inet_pton(AF_INET, (char*)tvb_get_ephemeral_string(tvb, begin+offset, new_offset), ipaddr))
ab5f7c
+					proto_tree_add_ipv4(another_tree, hf_rtpproxy_command_parameter_remote_ipv4, tvb, begin+offset, new_offset, ipaddr[0]);
ab5f7c
+				else
ab5f7c
+					show_exception(tvb, pinfo, another_tree, DissectorError, "Bogus IPv4");
ab5f7c
 				offset += new_offset;
ab5f7c
 				break;
ab5f7c
 			case 'z':
ab5f7c
@@ -437,12 +447,13 @@ rtpproxy_add_tid(gboolean is_request, tvbuff_t *tvb, packet_info *pinfo, proto_t
ab5f7c
 	return rtpproxy_info;
ab5f7c
 }
ab5f7c
 
ab5f7c
-void
ab5f7c
-rtpproxy_add_notify_addr(proto_tree *rtpproxy_tree, tvbuff_t *tvb, guint begin, guint end)
ab5f7c
+static void
ab5f7c
+rtpproxy_add_notify_addr(tvbuff_t *tvb, packet_info *pinfo, proto_tree *rtpproxy_tree, guint begin, guint end)
ab5f7c
 {
ab5f7c
 	gint offset = 0;
ab5f7c
 	gint tmp = 0;
ab5f7c
 	gboolean ipv6 = FALSE;
ab5f7c
+	guint32 ipaddr[4]; /* Enough room for IPv4 or IPv6 */
ab5f7c
 	proto_item *ti;
ab5f7c
 
ab5f7c
 	/* Check for at least one colon */
ab5f7c
@@ -454,17 +465,28 @@ rtpproxy_add_notify_addr(proto_tree *rtpproxy_tree, tvbuff_t *tvb, guint begin,
ab5f7c
 			offset = tmp;
ab5f7c
 		}
ab5f7c
 		/* We have ip:port */
ab5f7c
-		if(ipv6)
ab5f7c
-			proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_notify_ipv6, tvb, begin, offset - begin, ENC_ASCII | ENC_NA);
ab5f7c
-		else
ab5f7c
-			proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_notify_ipv4, tvb, begin, offset - begin, ENC_ASCII | ENC_NA);
ab5f7c
+		if(ipv6){
ab5f7c
+			if(inet_pton(AF_INET6, (char*)tvb_get_ephemeral_string(tvb, begin, offset - begin), ipaddr))
ab5f7c
+				proto_tree_add_ipv6(rtpproxy_tree, hf_rtpproxy_notify_ipv6, tvb, begin, offset - begin, (const guint8 *)ipaddr);
ab5f7c
+			else
ab5f7c
+				show_exception(tvb, pinfo, rtpproxy_tree, DissectorError, "Bogus IPv6");
ab5f7c
+		}
ab5f7c
+		else{
ab5f7c
+			if(inet_pton(AF_INET, (char*)tvb_get_ephemeral_string(tvb, begin, offset - begin), ipaddr))
ab5f7c
+				proto_tree_add_ipv4(rtpproxy_tree, hf_rtpproxy_notify_ipv4, tvb, begin, offset - begin, ipaddr[0]);
ab5f7c
+			else
ab5f7c
+				show_exception(tvb, pinfo, rtpproxy_tree, DissectorError, "Bogus IPv4");
ab5f7c
+		}
ab5f7c
 		proto_tree_add_uint(rtpproxy_tree, hf_rtpproxy_notify_port, tvb, offset+1, end - (offset+1),
ab5f7c
 			(guint16) g_ascii_strtoull((gchar*)tvb_get_ephemeral_string(tvb, offset+1, end - (offset+1)), NULL, 10));
ab5f7c
 	}
ab5f7c
 	else{
ab5f7c
-		/* Only port is supplied */
ab5f7c
-		ti = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_notify_ipv4, tvb, begin, 0, ENC_ASCII | ENC_NA);
ab5f7c
-		proto_item_append_text(ti, "<skipped>");
ab5f7c
+		/* Only port is supplied - take IPv4/IPv6 from  ip.src/ipv6.src respectively */
ab5f7c
+		expert_add_info_format(pinfo, rtpproxy_tree, PI_PROTOCOL, PI_WARN, "Only port is supplied - take IPv4/IPv6 from  ip.src/ipv6.src respectively");
ab5f7c
+		if (pinfo->src.type == AT_IPv4)
ab5f7c
+			ti = proto_tree_add_ipv4(rtpproxy_tree, hf_rtpproxy_notify_ipv4, tvb, begin, 0, ((guint32*)(pinfo->src.data))[0]);
ab5f7c
+		else
ab5f7c
+			ti = proto_tree_add_ipv6(rtpproxy_tree, hf_rtpproxy_notify_ipv6, tvb, begin, 0, (const guint8 *)(pinfo->src.data));
ab5f7c
 		PROTO_ITEM_SET_GENERATED(ti);
ab5f7c
 		proto_tree_add_uint(rtpproxy_tree, hf_rtpproxy_notify_port, tvb, begin, end - begin,
ab5f7c
 			(guint16) g_ascii_strtoull((gchar*)tvb_get_ephemeral_string(tvb, begin, end - begin), NULL, 10));
ab5f7c
@@ -490,7 +512,7 @@ dissect_rtpproxy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data
ab5f7c
 	/* For RT(C)P setup */
ab5f7c
 	address addr;
ab5f7c
 	guint16 port;
ab5f7c
-	guint32 ipaddr[4];
ab5f7c
+	guint32 ipaddr[4]; /* Enough room for IPv4 or IPv6 */
ab5f7c
 	rtpproxy_info_t *rtpproxy_info = NULL;
ab5f7c
 
ab5f7c
 	/* If it does not start with a printable character it's not RTPProxy */
ab5f7c
@@ -600,7 +622,7 @@ dissect_rtpproxy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data
ab5f7c
 			if (new_offset != offset + 1){
ab5f7c
 				rtpproxy_tree = proto_item_add_subtree(ti, ett_rtpproxy_command);
ab5f7c
 				ti2 = proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_command_parameters, tvb, offset+1, new_offset - (offset+1), ENC_ASCII | ENC_NA);
ab5f7c
-				rtpproxy_add_parameter(proto_item_add_subtree(ti2, ett_rtpproxy_command_parameters), tvb, offset+1, new_offset - (offset+1));
ab5f7c
+				rtpproxy_add_parameter(tvb, pinfo, proto_item_add_subtree(ti2, ett_rtpproxy_command_parameters), offset+1, new_offset - (offset+1));
ab5f7c
 				rtpproxy_tree = proto_item_get_parent(ti);
ab5f7c
 			}
ab5f7c
 
ab5f7c
@@ -623,10 +645,18 @@ dissect_rtpproxy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data
ab5f7c
 			if ((tmp == 'u') || (tmp == 'l')){
ab5f7c
 				/* Extract IP */
ab5f7c
 				new_offset = tvb_find_guint8(tvb, offset, -1, ' ');
ab5f7c
-				if (tvb_find_guint8(tvb, offset, new_offset - offset, ':') == -1)
ab5f7c
-					proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_ipv4, tvb, offset, new_offset - offset, ENC_ASCII | ENC_NA);
ab5f7c
-				else
ab5f7c
-					proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_ipv6, tvb, offset, new_offset - offset, ENC_ASCII | ENC_NA);
ab5f7c
+				if (tvb_find_guint8(tvb, offset, new_offset - offset, ':') == -1){
ab5f7c
+					if(inet_pton(AF_INET, (char*)tvb_get_ephemeral_string(tvb, offset, new_offset - offset), ipaddr))
ab5f7c
+						proto_tree_add_ipv4(rtpproxy_tree, hf_rtpproxy_ipv4, tvb, offset, new_offset - offset, ipaddr[0]);
ab5f7c
+					else
ab5f7c
+						show_exception(tvb, pinfo, rtpproxy_tree, DissectorError, "Bogus IPv4");
ab5f7c
+				}
ab5f7c
+				else{
ab5f7c
+					if(inet_pton(AF_INET6, (char*)tvb_get_ephemeral_string(tvb, offset, new_offset - offset), ipaddr))
ab5f7c
+						proto_tree_add_ipv6(rtpproxy_tree, hf_rtpproxy_ipv6, tvb, offset, new_offset - offset, (const guint8 *)ipaddr);
ab5f7c
+					else
ab5f7c
+						show_exception(tvb, pinfo, rtpproxy_tree, DissectorError, "Bogus IPv6");
ab5f7c
+				}
ab5f7c
 				/* Skip whitespace */
ab5f7c
 				offset = tvb_skip_wsp(tvb, new_offset+1, -1);
ab5f7c
 
ab5f7c
@@ -686,12 +716,12 @@ dissect_rtpproxy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data
ab5f7c
 				new_offset = tvb_find_guint8(tvb, offset, -1, ' ');
ab5f7c
 				if(new_offset == -1){
ab5f7c
 					/* NotifyTag wasn't found (we should re-use Call-ID instead) */
ab5f7c
-					rtpproxy_add_notify_addr(rtpproxy_tree, tvb, offset, realsize);
ab5f7c
+					rtpproxy_add_notify_addr(tvb, pinfo, rtpproxy_tree, offset, realsize);
ab5f7c
 					break; /* No more parameters */
ab5f7c
 				}
ab5f7c
 
ab5f7c
 				/* NotifyTag was found */
ab5f7c
-				rtpproxy_add_notify_addr(rtpproxy_tree, tvb, offset, new_offset);
ab5f7c
+				rtpproxy_add_notify_addr(tvb, pinfo, rtpproxy_tree, offset, new_offset);
ab5f7c
 				/* Skip whitespace */
ab5f7c
 				offset = tvb_skip_wsp(tvb, new_offset+1, -1);
ab5f7c
 
ab5f7c
@@ -760,29 +790,38 @@ dissect_rtpproxy(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data
ab5f7c
 			offset = tvb_skip_wsp(tvb, new_offset+1, -1);
ab5f7c
 
ab5f7c
 			/* Extract IP */
ab5f7c
+			memset(&addr, 0, sizeof(address));
ab5f7c
 			tmp = tvb_find_line_end(tvb, offset, -1, &new_offset, FALSE);
ab5f7c
 			if (tvb_find_guint8(tvb, offset, -1, ':') == -1){
ab5f7c
-				inet_pton(AF_INET, (char*)tvb_get_ephemeral_string(tvb, offset, tmp), ipaddr);
ab5f7c
-				addr.type = AT_IPv4;
ab5f7c
-				addr.len  = 4;
ab5f7c
-				addr.data = ep_memdup(ipaddr, 4);
ab5f7c
-				proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_ipv4, tvb, offset, tmp, ENC_ASCII | ENC_NA);
ab5f7c
+				if (inet_pton(AF_INET, (char*)tvb_get_ephemeral_string(tvb, offset, tmp), ipaddr)){
ab5f7c
+					addr.type = AT_IPv4;
ab5f7c
+					addr.len  = 4;
ab5f7c
+					addr.data = ep_memdup(ipaddr, 4);
ab5f7c
+					proto_tree_add_ipv4(rtpproxy_tree, hf_rtpproxy_ipv4, tvb, offset, tmp, ipaddr[0]);
ab5f7c
+				}
ab5f7c
+				else
ab5f7c
+					show_exception(tvb, pinfo, rtpproxy_tree, DissectorError, "Bogus IPv4");
ab5f7c
 			}
ab5f7c
 			else{
ab5f7c
-				inet_pton(AF_INET6, (char*)tvb_get_ephemeral_string(tvb, offset, tmp), ipaddr);
ab5f7c
-				addr.type = AT_IPv6;
ab5f7c
-				addr.len  = 16;
ab5f7c
-				addr.data = ep_memdup(ipaddr, 16);
ab5f7c
-				proto_tree_add_item(rtpproxy_tree, hf_rtpproxy_ipv6, tvb, offset, tmp, ENC_ASCII | ENC_NA);
ab5f7c
+				if (inet_pton(AF_INET6, (char*)tvb_get_ephemeral_string(tvb, offset, tmp), ipaddr)){
ab5f7c
+					addr.type = AT_IPv6;
ab5f7c
+					addr.len  = 16;
ab5f7c
+					addr.data = ep_memdup(ipaddr, 16);
ab5f7c
+					proto_tree_add_ipv6(rtpproxy_tree, hf_rtpproxy_ipv6, tvb, offset, tmp, (const guint8 *)ipaddr);
ab5f7c
+				}
ab5f7c
+				else
ab5f7c
+					show_exception(tvb, pinfo, rtpproxy_tree, DissectorError, "Bogus IPv6");
ab5f7c
 			}
ab5f7c
 
ab5f7c
 			if(rtpproxy_establish_conversation){
ab5f7c
 				if (rtp_handle) {
ab5f7c
 					/* FIXME tell if isn't a video stream, and setup codec mapping */
ab5f7c
-					rtp_add_address(pinfo, &addr, port, 0, "RTPproxy", pinfo->fd->num, 0, NULL);
ab5f7c
+					if (addr.len)
ab5f7c
+						rtp_add_address(pinfo, &addr, port, 0, "RTPproxy", pinfo->fd->num, 0, NULL);
ab5f7c
 				}
ab5f7c
 				if (rtcp_handle) {
ab5f7c
-					rtcp_add_address(pinfo, &addr, port+1, 0, "RTPproxy", pinfo->fd->num);
ab5f7c
+					if (addr.len)
ab5f7c
+						rtcp_add_address(pinfo, &addr, port+1, 0, "RTPproxy", pinfo->fd->num);
ab5f7c
 				}
ab5f7c
 			}
ab5f7c
 			break;
ab5f7c
@@ -884,7 +923,7 @@ proto_register_rtpproxy(void)
ab5f7c
 			{
ab5f7c
 				"IPv4",
ab5f7c
 				"rtpproxy.ipv4",
ab5f7c
-				FT_STRING,
ab5f7c
+				FT_IPv4,
ab5f7c
 				BASE_NONE,
ab5f7c
 				NULL,
ab5f7c
 				0x0,
ab5f7c
@@ -897,7 +936,7 @@ proto_register_rtpproxy(void)
ab5f7c
 			{
ab5f7c
 				"IPv6",
ab5f7c
 				"rtpproxy.ipv6",
ab5f7c
-				FT_STRING,
ab5f7c
+				FT_IPv6,
ab5f7c
 				BASE_NONE,
ab5f7c
 				NULL,
ab5f7c
 				0x0,
ab5f7c
@@ -984,11 +1023,11 @@ proto_register_rtpproxy(void)
ab5f7c
 			}
ab5f7c
 		},
ab5f7c
 		{
ab5f7c
-			&hf_rtpproxy_command_parameter_local,
ab5f7c
+			&hf_rtpproxy_command_parameter_local_ipv4,
ab5f7c
 			{
ab5f7c
-				"Local IP address",
ab5f7c
-				"rtpproxy.command_parameter_local",
ab5f7c
-				FT_STRING,
ab5f7c
+				"Local IPv4 address",
ab5f7c
+				"rtpproxy.command_parameter_local_ipv4",
ab5f7c
+				FT_IPv4, /* FIXME - is it ever possible to see IPv6 here? */
ab5f7c
 				BASE_NONE,
ab5f7c
 				NULL,
ab5f7c
 				0x0,
ab5f7c
@@ -997,11 +1036,11 @@ proto_register_rtpproxy(void)
ab5f7c
 			}
ab5f7c
 		},
ab5f7c
 		{
ab5f7c
-			&hf_rtpproxy_command_parameter_remote,
ab5f7c
+			&hf_rtpproxy_command_parameter_remote_ipv4,
ab5f7c
 			{
ab5f7c
-				"Remote IP address",
ab5f7c
-				"rtpproxy.command_parameter_remote",
ab5f7c
-				FT_STRING,
ab5f7c
+				"Remote IPv4 address",
ab5f7c
+				"rtpproxy.command_parameter_remote_ipv4",
ab5f7c
+				FT_IPv4, /* FIXME - is it ever possible to see IPv6 here? */
ab5f7c
 				BASE_NONE,
ab5f7c
 				NULL,
ab5f7c
 				0x0,
ab5f7c
@@ -1170,7 +1209,7 @@ proto_register_rtpproxy(void)
ab5f7c
 			{
ab5f7c
 				"Notification IPv4",
ab5f7c
 				"rtpproxy.notify_ipv4",
ab5f7c
-				FT_STRING,
ab5f7c
+				FT_IPv4,
ab5f7c
 				BASE_NONE,
ab5f7c
 				NULL,
ab5f7c
 				0x0,
ab5f7c
@@ -1183,7 +1222,7 @@ proto_register_rtpproxy(void)
ab5f7c
 			{
ab5f7c
 				"Notification IPv6",
ab5f7c
 				"rtpproxy.notify_ipv6",
ab5f7c
-				FT_STRING,
ab5f7c
+				FT_IPv6,
ab5f7c
 				BASE_NONE,
ab5f7c
 				NULL,
ab5f7c
 				0x0,