Index: sbin/ipfw/ipfw2.c =================================================================== --- sbin/ipfw/ipfw2.c +++ sbin/ipfw/ipfw2.c @@ -3996,24 +3996,34 @@ * 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; char *s, *end; int family; + int v6brac = 0; u_short port_number; NEED1("missing forward address[:port]"); /* + * Are we an brakcet-enclosed IPv6 address? + */ + if (strchr(*av, '[')) + v6brac = 1; + + /* * locate the address-port separator (':' or ',') */ s = strchr(*av, ','); if (s == NULL) { + char *ptr = *av; + /* If we have an starting bracket, get the ending one */ + if (v6brac) + ptr = strchr(*av, ']'); /* Distinguish between IPv4:port and IPv6 cases. */ - s = strchr(*av, ':'); + s = strchr(ptr, ':'); if (s && strchr(s+1, ':')) s = NULL; /* no port */ } @@ -4038,7 +4048,7 @@ * Resolve the host name or address to a family and a * network representation of the address. */ - if (getaddrinfo(*av, NULL, NULL, &res)) + if (getaddrinfo(*av + v6brac, NULL, NULL, &res)) errx(EX_DATAERR, NULL); /* Just use the first host in the answer. */ family = res->ai_family;