Changeset View
Changeset View
Standalone View
Standalone View
head/sbin/ipfw/ipfw2.c
Show First 20 Lines • Show All 3,984 Lines • ▼ Show 20 Lines | chkarg: | ||||
case TOK_FORWARD: { | case TOK_FORWARD: { | ||||
/* | /* | ||||
* Locate the address-port separator (':' or ','). | * Locate the address-port separator (':' or ','). | ||||
* Could be one of the following: | * Could be one of the following: | ||||
* hostname:port | * hostname:port | ||||
* IPv4 a.b.c.d,port | * IPv4 a.b.c.d,port | ||||
* IPv4 a.b.c.d:port | * IPv4 a.b.c.d:port | ||||
* IPv6 w:x:y::z,port | * IPv6 w:x:y::z,port | ||||
* The ':' can only be used with hostname and IPv4 address. | * IPv6 [w:x:y::z]:port | ||||
* XXX-BZ Should we also support [w:x:y::z]:port? | |||||
*/ | */ | ||||
struct sockaddr_storage result; | struct sockaddr_storage result; | ||||
struct addrinfo *res; | struct addrinfo *res; | ||||
char *s, *end; | char *s, *end; | ||||
int family; | int family; | ||||
u_short port_number; | u_short port_number; | ||||
NEED1("missing forward address[:port]"); | NEED1("missing forward address[:port]"); | ||||
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 ',') | * locate the address-port separator (':' or ',') | ||||
*/ | */ | ||||
s = strchr(*av, ','); | s = strchr(*av, ','); | ||||
if (s == NULL) { | 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. */ | /* Distinguish between IPv4:port and IPv6 cases. */ | ||||
s = strchr(*av, ':'); | s = strchr(s, ':'); | ||||
if (s && strchr(s+1, ':')) | if (s && strchr(s+1, ':')) | ||||
s = NULL; /* no port */ | s = NULL; /* no port */ | ||||
} | } | ||||
port_number = 0; | |||||
if (s != NULL) { | if (s != NULL) { | ||||
/* Terminate host portion and set s to start of port. */ | /* Terminate host portion and set s to start of port. */ | ||||
*(s++) = '\0'; | *(s++) = '\0'; | ||||
i = strtoport(s, &end, 0 /* base */, 0 /* proto */); | i = strtoport(s, &end, 0 /* base */, 0 /* proto */); | ||||
if (s == end) | if (s == end) | ||||
errx(EX_DATAERR, | errx(EX_DATAERR, | ||||
"illegal forwarding port ``%s''", s); | "illegal forwarding port ``%s''", s); | ||||
port_number = (u_short)i; | port_number = (u_short)i; | ||||
} | } | ||||
if (_substrcmp(*av, "tablearg") == 0) { | |||||
family = PF_INET; | |||||
((struct sockaddr_in*)&result)->sin_addr.s_addr = | |||||
INADDR_ANY; | |||||
} else { | |||||
/* | /* | ||||
* Resolve the host name or address to a family and a | * Resolve the host name or address to a family and a | ||||
* network representation of the address. | * network representation of the address. | ||||
*/ | */ | ||||
if (getaddrinfo(*av, NULL, NULL, &res)) | if (getaddrinfo(*av, NULL, NULL, &res)) | ||||
errx(EX_DATAERR, NULL); | errx(EX_DATAERR, NULL); | ||||
/* Just use the first host in the answer. */ | /* Just use the first host in the answer. */ | ||||
family = res->ai_family; | family = res->ai_family; | ||||
▲ Show 20 Lines • Show All 1,574 Lines • Show Last 20 Lines |