aboutsummaryrefslogtreecommitdiff
path: root/sbin/ipfw/ipfw2.c
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2020-06-25 19:27:22 +0000
committerMark Johnston <markj@FreeBSD.org>2020-06-25 19:27:22 +0000
commita3349dd906b67b532bbba7072fc76eede546a680 (patch)
tree002bfe154769ce3ee3a4bf23c82247ccc140128c /sbin/ipfw/ipfw2.c
parent90297b64718e77a8cf10ad64afe1c0e0695129f0 (diff)
downloadsrc-a3349dd906b67b532bbba7072fc76eede546a680.tar.gz
src-a3349dd906b67b532bbba7072fc76eede546a680.zip
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
Notes
Notes: svn path=/head/; revision=362619
Diffstat (limited to 'sbin/ipfw/ipfw2.c')
-rw-r--r--sbin/ipfw/ipfw2.c59
1 files changed, 35 insertions, 24 deletions
diff --git a/sbin/ipfw/ipfw2.c b/sbin/ipfw/ipfw2.c
index 3858d27710c1..da28bb6a9db4 100644
--- a/sbin/ipfw/ipfw2.c
+++ b/sbin/ipfw/ipfw2.c
@@ -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,34 +4000,46 @@ 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.
*/