svn commit: r362619 - head/sbin/ipfw

Mark Johnston markj at FreeBSD.org
Thu Jun 25 19:27:22 UTC 2020


Author: markj
Date: Thu Jun 25 19:27:22 2020
New Revision: 362619
URL: https://svnweb.freebsd.org/changeset/base/362619

Log:
  ipfw: Support the literal IPv6 address syntax in the fwd command.
  
  Discussed with:	rgrimes, Lutz Donnerhacke
  Submitted by:	Neel Chauhan <neel AT neelc DOT org>
  MFC after:	2 weeks
  Differential Revision:	https://reviews.freebsd.org/D24011

Modified:
  head/sbin/ipfw/ipfw2.c

Modified: head/sbin/ipfw/ipfw2.c
==============================================================================
--- head/sbin/ipfw/ipfw2.c	Thu Jun 25 19:12:27 2020	(r362618)
+++ head/sbin/ipfw/ipfw2.c	Thu Jun 25 19:27:22 2020	(r362619)
@@ -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.


More information about the svn-src-head mailing list