Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 9 Jul 2020 14:17:04 +0000 (UTC)
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r363043 - stable/12/sbin/ipfw
Message-ID:  <202007091417.069EH4Cr093584@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: markj
Date: Thu Jul  9 14:17:04 2020
New Revision: 363043
URL: https://svnweb.freebsd.org/changeset/base/363043

Log:
  MFC r362619:
  ipfw: Support the literal IPv6 address syntax in the fwd command.

Modified:
  stable/12/sbin/ipfw/ipfw2.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sbin/ipfw/ipfw2.c
==============================================================================
--- stable/12/sbin/ipfw/ipfw2.c	Thu Jul  9 13:19:00 2020	(r363042)
+++ stable/12/sbin/ipfw/ipfw2.c	Thu Jul  9 14:17:04 2020	(r363043)
@@ -3990,8 +3990,7 @@ chkarg:
 		 *	IPv4 a.b.c.d,port
 		 *	IPv4 a.b.c.d:port
 		 *	IPv6 w:x:y::z,port
-		 * The ':' can only be used with hostname and IPv4 address.
-		 * XXX-BZ Should we also support [w:x:y::z]:port?
+		 *	IPv6 [w:x:y::z]:port
 		 */
 		struct sockaddr_storage result;
 		struct addrinfo *res;
@@ -4001,33 +4000,45 @@ chkarg:
 
 		NEED1("missing forward address[:port]");
 
-		/*
-		 * locate the address-port separator (':' or ',')
-		 */
-		s = strchr(*av, ',');
-		if (s == NULL) {
-			/* Distinguish between IPv4:port and IPv6 cases. */
-			s = strchr(*av, ':');
-			if (s && strchr(s+1, ':'))
-				s = NULL; /* no port */
-		}
-
-		port_number = 0;
-		if (s != NULL) {
-			/* Terminate host portion and set s to start of port. */
-			*(s++) = '\0';
-			i = strtoport(s, &end, 0 /* base */, 0 /* proto */);
-			if (s == end)
-				errx(EX_DATAERR,
-				    "illegal forwarding port ``%s''", s);
-			port_number = (u_short)i;
-		}
-
 		if (_substrcmp(*av, "tablearg") == 0) {
 			family = PF_INET;
 			((struct sockaddr_in*)&result)->sin_addr.s_addr =
 			    INADDR_ANY;
 		} else {
+			/*
+			 * Are we an bracket-enclosed IPv6 address?
+			 */
+			if (strchr(*av, '['))
+				(*av)++;
+
+			/*
+			 * locate the address-port separator (':' or ',')
+			 */
+			s = strchr(*av, ',');
+			if (s == NULL) {
+				s = strchr(*av, ']');
+				/* Prevent erroneous parsing on brackets. */
+				if (s != NULL)
+					*(s++) = '\0';
+				else
+					s = *av;
+
+				/* Distinguish between IPv4:port and IPv6 cases. */
+				s = strchr(s, ':');
+				if (s && strchr(s+1, ':'))
+					s = NULL; /* no port */
+			}
+
+			if (s != NULL) {
+				/* Terminate host portion and set s to start of port. */
+				*(s++) = '\0';
+				i = strtoport(s, &end, 0 /* base */, 0 /* proto */);
+				if (s == end)
+					errx(EX_DATAERR,
+					    "illegal forwarding port ``%s''", s);
+				port_number = (u_short)i;
+			}
+
 			/*
 			 * Resolve the host name or address to a family and a
 			 * network representation of the address.



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202007091417.069EH4Cr093584>