summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
Diffstat (limited to 'sbin')
-rw-r--r--sbin/pfctl/parse.y78
1 files changed, 58 insertions, 20 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index 0e4adb19372..65c01be1fc0 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.145 2002/09/08 12:57:35 henning Exp $ */
+/* $OpenBSD: parse.y,v 1.146 2002/09/12 09:48:57 henning Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -66,6 +66,12 @@ enum {
PFCTL_STATE_FILTER = 4
};
+enum pfctl_iflookup_mode {
+ PFCTL_IFLOOKUP_HOST = 0,
+ PFCTL_IFLOOKUP_NET = 1,
+ PFCTL_IFLOOKUP_BCAST = 2
+};
+
struct node_if {
char ifname[IFNAMSIZ];
u_int8_t not;
@@ -80,6 +86,7 @@ struct node_proto {
struct node_host {
struct pf_addr_wrap addr;
struct pf_addr mask;
+ struct pf_addr bcast;
u_int8_t af;
u_int8_t not;
u_int8_t noroute;
@@ -176,7 +183,7 @@ char * symget(const char *);
void ifa_load(void);
int ifa_exists(char *);
-struct node_host *ifa_lookup(char *);
+struct node_host *ifa_lookup(char *, enum pfctl_iflookup_mode);
struct node_host *ifa_pick_ip(struct node_host *, u_int8_t);
typedef struct {
@@ -660,15 +667,7 @@ xhost : '!' host {
}
;
-host : address {
- struct node_host *n;
- for (n = $1; n; n = n->next)
- if (n->af == AF_INET)
- ipmask(&n->mask, 32);
- else
- ipmask(&n->mask, 128);
- $$ = $1;
- }
+host : address
| address '/' number {
struct node_host *n;
for (n = $1; n; n = n->next) {
@@ -716,7 +715,8 @@ address : '(' STRING ')' {
}
| SELF {
struct node_host *h = NULL;
- if ((h = ifa_lookup("all")) == NULL)
+ if ((h = ifa_lookup("all",
+ PFCTL_IFLOOKUP_HOST)) == NULL)
YYERROR;
else
$$ = h;
@@ -2472,6 +2472,9 @@ ipmask(struct pf_addr *m, u_int8_t b)
{
int i, j = 0;
+ for (i = 0; i < 4; i++)
+ m->addr32[i] = 0;
+
while (b >= 32) {
m->addr32[j++] = 0xffffffff;
b -= 32;
@@ -2558,14 +2561,28 @@ ifa_load(void)
}
#endif
n->ifindex = 0;
- if (n->af == AF_INET)
+ if (n->af == AF_INET) {
memcpy(&n->addr.addr, &((struct sockaddr_in *)
ifa->ifa_addr)->sin_addr.s_addr,
sizeof(struct in_addr));
- else if (n->af == AF_INET6) {
+ memcpy(&n->mask, &((struct sockaddr_in *)
+ ifa->ifa_netmask)->sin_addr.s_addr,
+ sizeof(struct in_addr));
+ if (ifa->ifa_broadaddr != NULL)
+ memcpy(&n->bcast, &((struct sockaddr_in *)
+ ifa->ifa_broadaddr)->sin_addr.s_addr,
+ sizeof(struct in_addr));
+ } else if (n->af == AF_INET6) {
memcpy(&n->addr.addr, &((struct sockaddr_in6 *)
ifa->ifa_addr)->sin6_addr.s6_addr,
sizeof(struct in6_addr));
+ memcpy(&n->mask, &((struct sockaddr_in6 *)
+ ifa->ifa_netmask)->sin6_addr.s6_addr,
+ sizeof(struct in6_addr));
+ if (ifa->ifa_broadaddr != NULL)
+ memcpy(&n->bcast, &((struct sockaddr_in6 *)
+ ifa->ifa_broadaddr)->sin6_addr.s6_addr,
+ sizeof(struct in6_addr));
n->ifindex = ((struct sockaddr_in6 *)
ifa->ifa_addr)->sin6_scope_id;
}
@@ -2596,7 +2613,7 @@ ifa_exists(char *ifa_name)
}
struct node_host *
-ifa_lookup(char *ifa_name)
+ifa_lookup(char *ifa_name, enum pfctl_iflookup_mode mode)
{
struct node_host *p = NULL, *h = NULL, *n = NULL;
int return_all = 0;
@@ -2611,17 +2628,34 @@ ifa_lookup(char *ifa_name)
if (!((p->af == AF_INET || p->af == AF_INET6)
&& (!strncmp(p->ifname, ifa_name, IFNAMSIZ) || return_all)))
continue;
+ if (mode == PFCTL_IFLOOKUP_BCAST && p->af != AF_INET)
+ continue;
+ if (mode == PFCTL_IFLOOKUP_NET && p->ifindex > 0)
+ continue;
n = calloc(1, sizeof(struct node_host));
if (n == NULL)
err(1, "address: calloc");
n->af = p->af;
n->addr.addr_dyn = NULL;
- memcpy(&n->addr.addr, &p->addr.addr, sizeof(struct pf_addr));
+ if (mode == PFCTL_IFLOOKUP_BCAST) {
+ memcpy(&n->addr.addr, &p->bcast,
+ sizeof(struct pf_addr));
+ } else
+ memcpy(&n->addr.addr, &p->addr.addr,
+ sizeof(struct pf_addr));
+ if (mode == PFCTL_IFLOOKUP_NET)
+ memcpy(&n->mask, &p->mask, sizeof(struct pf_addr));
+ else {
+ if (n->af == AF_INET)
+ ipmask(&n->mask, 32);
+ else
+ ipmask(&n->mask, 128);
+ }
n->ifindex = p->ifindex;
n->next = h;
h = n;
}
- if (h == NULL) {
+ if (h == NULL && mode == PFCTL_IFLOOKUP_HOST) {
yyerror("no IP address found for %s", ifa_name);
}
return (h);
@@ -2663,7 +2697,7 @@ host(char *s)
if (ifa_exists(s)) {
/* interface with this name exists */
- if ((h = ifa_lookup(s)) == NULL)
+ if ((h = ifa_lookup(s, PFCTL_IFLOOKUP_HOST)) == NULL)
return (NULL);
else
return (h);
@@ -2676,6 +2710,7 @@ host(char *s)
h->af = AF_INET;
h->addr.addr_dyn = NULL;
h->addr.addr.addr32[0] = ina.s_addr;
+ ipmask(&h->mask, 32);
return (h);
}
@@ -2693,6 +2728,7 @@ host(char *s)
&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
sizeof(n->addr.addr));
n->ifindex = ((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id;
+ ipmask(&n->mask, 128);
freeaddrinfo(res);
return (n);
}
@@ -2715,16 +2751,18 @@ host(char *s)
err(1, "address: calloc");
n->af = res->ai_family;
n->addr.addr_dyn = NULL;
- if (res->ai_family == AF_INET)
+ if (res->ai_family == AF_INET) {
memcpy(&n->addr.addr,
&((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr,
sizeof(struct in_addr));
- else {
+ ipmask(&n->mask, 32);
+ } else {
memcpy(&n->addr.addr,
&((struct sockaddr_in6 *)res->ai_addr)->sin6_addr.s6_addr,
sizeof(struct in6_addr));
n->ifindex =
((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id;
+ ipmask(&n->mask, 128);
}
n->next = h;
h = n;