summaryrefslogtreecommitdiff
path: root/sbin/pfctl
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2003-01-14 21:58:13 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2003-01-14 21:58:13 +0000
commit0483320cc2bd3bd941b2b7b29ab9c37b1e05eb47 (patch)
tree98dfc33c34fae3108a13893cc07adf2ad85a2fee /sbin/pfctl
parentb17b2726dbea15de0f41eb62e24c7e199c77384f (diff)
unified IP parser:
-move host(), set_ipmask and the ifa_* functions to pfctl_parser.[c|h] -extend host() to handle /mask itself, plus minor adjustments -use that in pfctl_table.c instead of coding the same shit again discussed w/ cedric@ ok cedric@ dhartmei@
Diffstat (limited to 'sbin/pfctl')
-rw-r--r--sbin/pfctl/parse.y330
-rw-r--r--sbin/pfctl/pfctl_parser.c331
-rw-r--r--sbin/pfctl/pfctl_parser.h34
-rw-r--r--sbin/pfctl/pfctl_table.c93
4 files changed, 402 insertions, 386 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y
index ec54698609f..a9ca033366e 100644
--- a/sbin/pfctl/parse.y
+++ b/sbin/pfctl/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.288 2003/01/13 08:17:47 camield Exp $ */
+/* $OpenBSD: parse.y,v 1.289 2003/01/14 21:58:11 henning Exp $ */
/*
* Copyright (c) 2001 Markus Friedl. All rights reserved.
@@ -43,7 +43,6 @@
#include <stdio.h>
#include <stdlib.h>
-#include <ifaddrs.h>
#include <netdb.h>
#include <stdarg.h>
#include <errno.h>
@@ -79,38 +78,12 @@ enum {
PFCTL_STATE_FILTER
};
-enum pfctl_iflookup_mode {
- PFCTL_IFLOOKUP_HOST,
- PFCTL_IFLOOKUP_NET,
- PFCTL_IFLOOKUP_BCAST
-};
-
-struct node_if {
- char ifname[IFNAMSIZ];
- u_int8_t not;
- u_int ifa_flags;
- struct node_if *next;
- struct node_if *tail;
-};
-
struct node_proto {
u_int8_t proto;
struct node_proto *next;
struct node_proto *tail;
};
-struct node_host {
- struct pf_addr_wrap addr;
- struct pf_addr bcast;
- sa_family_t af;
- u_int8_t not;
- u_int32_t ifindex; /* link-local IPv6 addrs */
- char *ifname;
- u_int ifa_flags;
- struct node_host *next;
- struct node_host *tail;
-};
-
struct node_port {
u_int16_t port[2];
u_int8_t op;
@@ -242,7 +215,6 @@ int rule_consistent(struct pf_rule *);
int nat_consistent(struct pf_rule *);
int rdr_consistent(struct pf_rule *);
int yyparse(void);
-void set_ipmask(struct node_host *, u_int8_t);
void expand_rdr(struct pf_rule *, struct node_if *, struct node_proto *,
struct node_host *, struct node_host *, struct node_host *);
void expand_nat(struct pf_rule *, struct node_if *, struct node_proto *,
@@ -272,7 +244,6 @@ int lgetc(FILE *);
int lungetc(int);
int findeol(void);
int yylex(void);
-struct node_host *host(char *, int);
int atoul(char *, u_long *);
int getservice(char *);
@@ -287,9 +258,6 @@ struct sym *symhead = NULL;
int symset(const char *, const char *);
char *symget(const char *);
-void ifa_load(void);
-struct node_host *ifa_exists(char *);
-struct node_host *ifa_lookup(char *, enum pfctl_iflookup_mode);
void decide_address_family(struct node_host *,
sa_family_t *);
void remove_invalid_hosts(struct node_host **,
@@ -3901,32 +3869,6 @@ parse_rules(FILE *input, struct pfctl *xpf, int opts)
return (errors ? -1 : 0);
}
-void
-set_ipmask(struct node_host *h, u_int8_t b)
-{
- struct pf_addr *m, *n;
- int i, j = 0;
-
- m = &h->addr.v.a.mask;
-
- for (i = 0; i < 4; i++)
- m->addr32[i] = 0;
-
- while (b >= 32) {
- m->addr32[j++] = 0xffffffff;
- b -= 32;
- }
- for (i = 31; i > 31-b; --i)
- m->addr32[j] |= (1 << i);
- if (b)
- m->addr32[j] = htonl(m->addr32[j]);
-
- /* Mask off bits of the address that will never be used. */
- n = &h->addr.v.a.addr;
- for (i = 0; i < 4; i++)
- n->addr32[i] = n->addr32[i] & m->addr32[i];
-}
-
/*
* Over-designed efficiency is a French and German concept, so how about
* we wait until they discover this ugliness and make it all fancy.
@@ -3969,160 +3911,6 @@ symget(const char *nam)
return (NULL);
}
-/* interface lookup routines */
-
-struct node_host *iftab;
-
-void
-ifa_load(void)
-{
- struct ifaddrs *ifap, *ifa;
- struct node_host *n = NULL, *h = NULL;
-
- if (getifaddrs(&ifap) < 0)
- err(1, "getifaddrs");
-
- for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
- if (!(ifa->ifa_addr->sa_family == AF_INET ||
- ifa->ifa_addr->sa_family == AF_INET6 ||
- ifa->ifa_addr->sa_family == AF_LINK))
- continue;
- n = calloc(1, sizeof(struct node_host));
- if (n == NULL)
- err(1, "address: calloc");
- n->af = ifa->ifa_addr->sa_family;
- n->ifa_flags = ifa->ifa_flags;
-#ifdef __KAME__
- if (n->af == AF_INET6 &&
- IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)
- ifa->ifa_addr)->sin6_addr) &&
- ((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_scope_id == 0) {
- struct sockaddr_in6 *sin6;
-
- sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
- sin6->sin6_scope_id = sin6->sin6_addr.s6_addr[2] << 8 |
- sin6->sin6_addr.s6_addr[3];
- sin6->sin6_addr.s6_addr[2] = 0;
- sin6->sin6_addr.s6_addr[3] = 0;
- }
-#endif
- n->ifindex = 0;
- if (n->af == AF_INET) {
- memcpy(&n->addr.v.a.addr, &((struct sockaddr_in *)
- ifa->ifa_addr)->sin_addr.s_addr,
- sizeof(struct in_addr));
- memcpy(&n->addr.v.a.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.v.a.addr, &((struct sockaddr_in6 *)
- ifa->ifa_addr)->sin6_addr.s6_addr,
- sizeof(struct in6_addr));
- memcpy(&n->addr.v.a.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;
- }
- if ((n->ifname = strdup(ifa->ifa_name)) == NULL)
- err(1, "ifa_load: strdup");
- n->next = NULL;
- n->tail = n;
- if (h == NULL)
- h = n;
- else {
- h->tail->next = n;
- h->tail = n;
- }
- }
- iftab = h;
- freeifaddrs(ifap);
-}
-
-struct node_host *
-ifa_exists(char *ifa_name)
-{
- struct node_host *n;
-
- if (iftab == NULL)
- ifa_load();
-
- for (n = iftab; n; n = n->next) {
- if (n->af == AF_LINK && !strncmp(n->ifname, ifa_name, IFNAMSIZ))
- return (n);
- }
- return (NULL);
-}
-
-struct node_host *
-ifa_lookup(char *ifa_name, enum pfctl_iflookup_mode mode)
-{
- struct node_host *p = NULL, *h = NULL, *n = NULL;
- int return_all = 0;
-
- if (!strncmp(ifa_name, "self", IFNAMSIZ))
- return_all = 1;
-
- if (iftab == NULL)
- ifa_load();
-
- for (p = iftab; p; p = p->next) {
- 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;
- if (mode == PFCTL_IFLOOKUP_BCAST)
- memcpy(&n->addr.v.a.addr, &p->bcast,
- sizeof(struct pf_addr));
- else
- memcpy(&n->addr.v.a.addr, &p->addr.v.a.addr,
- sizeof(struct pf_addr));
- if (mode == PFCTL_IFLOOKUP_NET)
- set_ipmask(n, unmask(&p->addr.v.a.mask, n->af));
- else {
- if (n->af == AF_INET) {
- if (p->ifa_flags & IFF_LOOPBACK &&
- p->ifa_flags & IFF_LINK1)
- memcpy(&n->addr.v.a.mask,
- &p->addr.v.a.mask,
- sizeof(struct pf_addr));
- else
- set_ipmask(n, 32);
- } else
- set_ipmask(n, 128);
- }
- n->ifindex = p->ifindex;
-
- n->next = NULL;
- n->tail = n;
- if (h == NULL)
- h = n;
- else {
- h->tail->next = n;
- h->tail = n;
- }
- }
- if (h == NULL && mode == PFCTL_IFLOOKUP_HOST) {
- yyerror("no IP address found for %s", ifa_name);
- }
- return (h);
-}
-
void
decide_address_family(struct node_host *n, sa_family_t *af)
{
@@ -4180,122 +3968,6 @@ remove_invalid_hosts(struct node_host **nh, sa_family_t *af)
"found.");
}
-struct node_host *
-host(char *s, int mask)
-{
- struct node_host *h = NULL, *n;
- struct in_addr ina;
- struct addrinfo hints, *res0, *res;
- int bits, error, v4mask, v6mask;
- char *buf = NULL;
-
- if (ifa_exists(s) || !strncmp(s, "self", IFNAMSIZ)) {
- /* interface with this name exists */
- h = ifa_lookup(s, PFCTL_IFLOOKUP_HOST);
- for (n = h; n != NULL && mask > -1; n = n->next)
- set_ipmask(n, mask);
- return (h);
- }
-
- if (mask == -1) {
- if (asprintf(&buf, "%s", s) == -1)
- err(1, "host: asprintf");
- v4mask = 32;
- v6mask = 128;
- } else if (mask <= 128) {
- if (asprintf(&buf, "%s/%d", s, mask) == -1)
- err(1, "host: asprintf");
- v4mask = v6mask = mask;
- } else {
- yyerror("illegal mask");
- return (NULL);
- }
-
- memset(&ina, 0, sizeof(struct in_addr));
- if ((bits = inet_net_pton(AF_INET, buf, &ina, sizeof(&ina))) > -1) {
- h = calloc(1, sizeof(struct node_host));
- if (h == NULL)
- err(1, "address: calloc");
- h->ifname = NULL;
- h->af = AF_INET;
- h->addr.v.a.addr.addr32[0] = ina.s_addr;
- set_ipmask(h, bits);
- h->next = NULL;
- h->tail = h;
- free(buf);
- return (h);
- }
- free(buf);
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_INET6;
- hints.ai_socktype = SOCK_DGRAM; /*dummy*/
- hints.ai_flags = AI_NUMERICHOST;
- if (getaddrinfo(s, "0", &hints, &res) == 0) {
- n = calloc(1, sizeof(struct node_host));
- if (n == NULL)
- err(1, "address: calloc");
- n->ifname = NULL;
- n->af = AF_INET6;
- memcpy(&n->addr.v.a.addr,
- &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
- sizeof(n->addr.v.a.addr));
- n->ifindex = ((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id;
- set_ipmask(n, v6mask);
- freeaddrinfo(res);
- n->next = NULL;
- n->tail = n;
- return (n);
- }
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = PF_UNSPEC;
- hints.ai_socktype = SOCK_STREAM; /* DUMMY */
- error = getaddrinfo(s, NULL, &hints, &res0);
- if (error) {
- yyerror("cannot resolve %s: %s",
- s, gai_strerror(error));
- return (NULL);
- }
- for (res = res0; res; res = res->ai_next) {
- if (res->ai_family != AF_INET &&
- res->ai_family != AF_INET6)
- continue;
- n = calloc(1, sizeof(struct node_host));
- if (n == NULL)
- err(1, "address: calloc");
- n->ifname = NULL;
- n->af = res->ai_family;
- if (res->ai_family == AF_INET) {
- memcpy(&n->addr.v.a.addr,
- &((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr,
- sizeof(struct in_addr));
- set_ipmask(n, v4mask);
- } else {
- memcpy(&n->addr.v.a.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;
- set_ipmask(n, v6mask);
- }
- n->next = NULL;
- n->tail = n;
- if (h == NULL)
- h = n;
- else {
- h->tail->next = n;
- h->tail = n;
- }
- }
- freeaddrinfo(res0);
- if (h == NULL) {
- yyerror("no IP address found for %s", s);
- return (NULL);
- }
- return (h);
-}
-
int
atoul(char *s, u_long *ulvalp)
{
diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c
index ad0d6774e86..b38a5d2affb 100644
--- a/sbin/pfctl/pfctl_parser.c
+++ b/sbin/pfctl/pfctl_parser.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_parser.c,v 1.127 2003/01/05 22:14:23 dhartmei Exp $ */
+/* $OpenBSD: pfctl_parser.c,v 1.128 2003/01/14 21:58:12 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -49,6 +49,7 @@
#include <stdarg.h>
#include <errno.h>
#include <err.h>
+#include <ifaddrs.h>
#include "pfctl_parser.h"
#include "pfctl.h"
@@ -944,3 +945,331 @@ parse_flags(char *s)
}
return (f ? f : PF_TH_ALL);
}
+
+void
+set_ipmask(struct node_host *h, u_int8_t b)
+{
+ struct pf_addr *m, *n;
+ int i, j = 0;
+
+ m = &h->addr.v.a.mask;
+
+ for (i = 0; i < 4; i++)
+ m->addr32[i] = 0;
+
+ while (b >= 32) {
+ m->addr32[j++] = 0xffffffff;
+ b -= 32;
+ }
+ for (i = 31; i > 31-b; --i)
+ m->addr32[j] |= (1 << i);
+ if (b)
+ m->addr32[j] = htonl(m->addr32[j]);
+
+ /* Mask off bits of the address that will never be used. */
+ n = &h->addr.v.a.addr;
+ for (i = 0; i < 4; i++)
+ n->addr32[i] = n->addr32[i] & m->addr32[i];
+}
+
+/* interface lookup routines */
+
+struct node_host *iftab;
+
+void
+ifa_load(void)
+{
+ struct ifaddrs *ifap, *ifa;
+ struct node_host *n = NULL, *h = NULL;
+
+ if (getifaddrs(&ifap) < 0)
+ err(1, "getifaddrs");
+
+ for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
+ if (!(ifa->ifa_addr->sa_family == AF_INET ||
+ ifa->ifa_addr->sa_family == AF_INET6 ||
+ ifa->ifa_addr->sa_family == AF_LINK))
+ continue;
+ n = calloc(1, sizeof(struct node_host));
+ if (n == NULL)
+ err(1, "address: calloc");
+ n->af = ifa->ifa_addr->sa_family;
+ n->ifa_flags = ifa->ifa_flags;
+#ifdef __KAME__
+ if (n->af == AF_INET6 &&
+ IN6_IS_ADDR_LINKLOCAL(&((struct sockaddr_in6 *)
+ ifa->ifa_addr)->sin6_addr) &&
+ ((struct sockaddr_in6 *)ifa->ifa_addr)->sin6_scope_id == 0) {
+ struct sockaddr_in6 *sin6;
+
+ sin6 = (struct sockaddr_in6 *)ifa->ifa_addr;
+ sin6->sin6_scope_id = sin6->sin6_addr.s6_addr[2] << 8 |
+ sin6->sin6_addr.s6_addr[3];
+ sin6->sin6_addr.s6_addr[2] = 0;
+ sin6->sin6_addr.s6_addr[3] = 0;
+ }
+#endif
+ n->ifindex = 0;
+ if (n->af == AF_INET) {
+ memcpy(&n->addr.v.a.addr, &((struct sockaddr_in *)
+ ifa->ifa_addr)->sin_addr.s_addr,
+ sizeof(struct in_addr));
+ memcpy(&n->addr.v.a.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.v.a.addr, &((struct sockaddr_in6 *)
+ ifa->ifa_addr)->sin6_addr.s6_addr,
+ sizeof(struct in6_addr));
+ memcpy(&n->addr.v.a.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;
+ }
+ if ((n->ifname = strdup(ifa->ifa_name)) == NULL)
+ err(1, "ifa_load: strdup");
+ n->next = NULL;
+ n->tail = n;
+ if (h == NULL)
+ h = n;
+ else {
+ h->tail->next = n;
+ h->tail = n;
+ }
+ }
+ iftab = h;
+ freeifaddrs(ifap);
+}
+
+struct node_host *
+ifa_exists(char *ifa_name)
+{
+ struct node_host *n;
+
+ if (iftab == NULL)
+ ifa_load();
+
+ for (n = iftab; n; n = n->next) {
+ if (n->af == AF_LINK && !strncmp(n->ifname, ifa_name, IFNAMSIZ))
+ return (n);
+ }
+ return (NULL);
+}
+
+struct node_host *
+ifa_lookup(char *ifa_name, enum pfctl_iflookup_mode mode)
+{
+ struct node_host *p = NULL, *h = NULL, *n = NULL;
+ int return_all = 0;
+
+ if (!strncmp(ifa_name, "self", IFNAMSIZ))
+ return_all = 1;
+
+ if (iftab == NULL)
+ ifa_load();
+
+ for (p = iftab; p; p = p->next) {
+ 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;
+ if (mode == PFCTL_IFLOOKUP_BCAST)
+ memcpy(&n->addr.v.a.addr, &p->bcast,
+ sizeof(struct pf_addr));
+ else
+ memcpy(&n->addr.v.a.addr, &p->addr.v.a.addr,
+ sizeof(struct pf_addr));
+ if (mode == PFCTL_IFLOOKUP_NET)
+ set_ipmask(n, unmask(&p->addr.v.a.mask, n->af));
+ else {
+ if (n->af == AF_INET) {
+ if (p->ifa_flags & IFF_LOOPBACK &&
+ p->ifa_flags & IFF_LINK1)
+ memcpy(&n->addr.v.a.mask,
+ &p->addr.v.a.mask,
+ sizeof(struct pf_addr));
+ else
+ set_ipmask(n, 32);
+ } else
+ set_ipmask(n, 128);
+ }
+ n->ifindex = p->ifindex;
+
+ n->next = NULL;
+ n->tail = n;
+ if (h == NULL)
+ h = n;
+ else {
+ h->tail->next = n;
+ h->tail = n;
+ }
+ }
+ if (h == NULL && mode == PFCTL_IFLOOKUP_HOST) {
+ fprintf(stderr, "no IP address found for %s\n", ifa_name);
+ }
+ return (h);
+}
+
+struct node_host *
+host(char *s, int mask)
+{
+ struct node_host *h = NULL, *n;
+ struct in_addr ina;
+ struct addrinfo hints, *res0, *res;
+ int bits, error, v4mask, v6mask;
+ char *buf = NULL, *p, *q, *ps;
+
+ if (ifa_exists(s) || !strncmp(s, "self", IFNAMSIZ)) {
+ /* interface with this name exists */
+ h = ifa_lookup(s, PFCTL_IFLOOKUP_HOST);
+ for (n = h; n != NULL && mask > -1; n = n->next)
+ set_ipmask(n, mask);
+ return (h);
+ }
+
+ if ((p = strrchr(s, '/')) != NULL) {
+ if (mask != -1) {
+ fprintf(stderr, "address with netmask specified"
+ "and extra netmask supplied\n");
+ return (NULL);
+ }
+ mask = strtol(p+1, &q, 0);
+ if (!q || *q) {
+ fprintf(stderr, "invalid netmask\n");
+ return (NULL);
+ }
+ if (asprintf(&buf, "%s", s) == -1)
+ err(1, "host: asprintf");
+ if ((ps = malloc(strlen(s) + 1)) == NULL)
+ err(1, "host: malloc");
+ strlcpy(ps, s, strlen(s) - strlen(p) + 1);
+ v4mask = v6mask = mask;
+ } else {
+ if (asprintf(&ps, "%s", s) == -1)
+ err(1, "host: asprintf");
+ if (mask == -1) {
+ if (asprintf(&buf, "%s", s) == -1)
+ err(1, "host: asprintf");
+ v4mask = 32;
+ v6mask = 128;
+ } else if (mask <= 128) {
+ if (asprintf(&buf, "%s/%d", s, mask) == -1)
+ err(1, "host: asprintf");
+ v4mask = v6mask = mask;
+ } else {
+ fprintf(stderr, "illegal mask\n");
+ return (NULL);
+ }
+ }
+
+ memset(&ina, 0, sizeof(struct in_addr));
+ if ((bits = inet_net_pton(AF_INET, buf, &ina, sizeof(&ina))) > -1) {
+ h = calloc(1, sizeof(struct node_host));
+ if (h == NULL)
+ err(1, "address: calloc");
+ h->ifname = NULL;
+ h->af = AF_INET;
+ h->addr.v.a.addr.addr32[0] = ina.s_addr;
+ set_ipmask(h, bits);
+ h->next = NULL;
+ h->tail = h;
+ free(buf);
+ free(ps);
+ if (mask > -1 && mask != bits) {
+ fprintf(stderr, "illegal netmask %d\n", mask);
+ free (h);
+ return (NULL);
+ }
+ return (h);
+ }
+ free(buf);
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = AF_INET6;
+ hints.ai_socktype = SOCK_DGRAM; /*dummy*/
+ hints.ai_flags = AI_NUMERICHOST;
+ if (getaddrinfo(ps, "0", &hints, &res) == 0) {
+ n = calloc(1, sizeof(struct node_host));
+ if (n == NULL)
+ err(1, "address: calloc");
+ n->ifname = NULL;
+ n->af = AF_INET6;
+ memcpy(&n->addr.v.a.addr,
+ &((struct sockaddr_in6 *)res->ai_addr)->sin6_addr,
+ sizeof(n->addr.v.a.addr));
+ n->ifindex = ((struct sockaddr_in6 *)res->ai_addr)->sin6_scope_id;
+ set_ipmask(n, v6mask);
+ freeaddrinfo(res);
+ n->next = NULL;
+ n->tail = n;
+ free(ps);
+ return (n);
+ }
+
+ memset(&hints, 0, sizeof(hints));
+ hints.ai_family = PF_UNSPEC;
+ hints.ai_socktype = SOCK_STREAM; /* DUMMY */
+ error = getaddrinfo(ps, NULL, &hints, &res0);
+ if (error) {
+ fprintf(stderr, "cannot resolve %s: %s\n",
+ s, gai_strerror(error));
+ free(ps);
+ return (NULL);
+ }
+ for (res = res0; res; res = res->ai_next) {
+ if (res->ai_family != AF_INET &&
+ res->ai_family != AF_INET6)
+ continue;
+ n = calloc(1, sizeof(struct node_host));
+ if (n == NULL)
+ err(1, "address: calloc");
+ n->ifname = NULL;
+ n->af = res->ai_family;
+ if (res->ai_family == AF_INET) {
+ memcpy(&n->addr.v.a.addr,
+ &((struct sockaddr_in *)res->ai_addr)->sin_addr.s_addr,
+ sizeof(struct in_addr));
+ set_ipmask(n, v4mask);
+ } else {
+ memcpy(&n->addr.v.a.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;
+ set_ipmask(n, v6mask);
+ }
+ n->next = NULL;
+ n->tail = n;
+ if (h == NULL)
+ h = n;
+ else {
+ h->tail->next = n;
+ h->tail = n;
+ }
+ }
+ freeaddrinfo(res0);
+ free(ps);
+
+ if (h == NULL) {
+ fprintf(stderr, "no IP address found for %s\n", s);
+ return (NULL);
+ }
+ return (h);
+}
+
diff --git a/sbin/pfctl/pfctl_parser.h b/sbin/pfctl/pfctl_parser.h
index 07fd09c1c24..09c1a3cfa7d 100644
--- a/sbin/pfctl/pfctl_parser.h
+++ b/sbin/pfctl/pfctl_parser.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_parser.h,v 1.39 2003/01/09 10:40:44 cedric Exp $ */
+/* $OpenBSD: pfctl_parser.h,v 1.40 2003/01/14 21:58:12 henning Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -64,6 +64,32 @@ struct pfctl {
struct pfioc_queue *pqueue;
};
+enum pfctl_iflookup_mode {
+ PFCTL_IFLOOKUP_HOST,
+ PFCTL_IFLOOKUP_NET,
+ PFCTL_IFLOOKUP_BCAST
+};
+
+struct node_if {
+ char ifname[IFNAMSIZ];
+ u_int8_t not;
+ u_int ifa_flags;
+ struct node_if *next;
+ struct node_if *tail;
+};
+
+struct node_host {
+ struct pf_addr_wrap addr;
+ struct pf_addr bcast;
+ sa_family_t af;
+ u_int8_t not;
+ u_int32_t ifindex; /* link-local IPv6 addrs */
+ char *ifname;
+ u_int ifa_flags;
+ struct node_host *next;
+ struct node_host *tail;
+};
+
int pfctl_add_rule(struct pfctl *, struct pf_rule *);
int pfctl_add_altq(struct pfctl *, struct pf_altq *);
int pfctl_add_pool(struct pfctl *, struct pf_pool *, sa_family_t);
@@ -124,4 +150,10 @@ struct pf_timeout {
extern const struct pf_timeout pf_timeouts[];
extern int loadopt;
+void set_ipmask(struct node_host *, u_int8_t);
+void ifa_load(void);
+struct node_host *ifa_exists(char *);
+struct node_host *ifa_lookup(char *, enum pfctl_iflookup_mode);
+struct node_host *host(char *, int);
+
#endif /* _PFCTL_PARSER_H_ */
diff --git a/sbin/pfctl/pfctl_table.c b/sbin/pfctl/pfctl_table.c
index 25fda8e2a68..108b12564ee 100644
--- a/sbin/pfctl/pfctl_table.c
+++ b/sbin/pfctl/pfctl_table.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfctl_table.c,v 1.20 2003/01/14 10:42:32 cedric Exp $ */
+/* $OpenBSD: pfctl_table.c,v 1.21 2003/01/14 21:58:12 henning Exp $ */
/*
* Copyright (c) 2002 Cedric Berger
@@ -57,7 +57,7 @@
#define BUF_SIZE 256
-extern void usage(void);
+extern void usage(void);
static int pfctl_table(int, char *[], char *, char *, char *, int);
static void grow_buffer(int, int);
static void print_table(struct pfr_table *, int);
@@ -445,74 +445,57 @@ next_token(char buf[BUF_SIZE], FILE *fp)
void
append_addr(char *s, int test)
{
- char buf[BUF_SIZE], *p, *q, *r;
- struct addrinfo *res, *ai, hints;
- int not = 0, net = -1, rv;
- struct in_addr ina;
+ char buf[BUF_SIZE], *r;
+ int not = 0;
+ struct node_host *n, *h;
for (r = s; *r == '!'; r++)
not = !not;
if (strlcpy(buf, r, sizeof(buf)) >= sizeof(buf))
errx(1, "address too long");
- p = strrchr(buf, '/');
- if (test && (not || p))
- errx(1, "illegal test address");
-
- memset(&ina, 0, sizeof(struct in_addr));
- if ((net = inet_net_pton(AF_INET, buf, &ina, sizeof(&ina))) > -1) {
- if (test && net != 32)
- errx(1, "illegal test address");
+
+ if ((n = host(buf, -1)) == NULL)
+ exit (1);
+
+ do {
if (size >= msize)
grow_buffer(sizeof(struct pfr_addr), 0);
- buffer.addrs[size].pfra_ip4addr.s_addr = ina.s_addr;
buffer.addrs[size].pfra_not = not;
- buffer.addrs[size].pfra_net = net;
- buffer.addrs[size].pfra_af = AF_INET;
- size++;
- return;
- }
-
- if (p) {
- net = strtol(p+1, &q, 0);
- if (!q || *q)
- errx(1, "illegal network: \"%s\"", p+1);
- *p++ = '\0';
- }
-
- bzero(&hints, sizeof(hints));
- hints.ai_socktype = SOCK_DGRAM;
- rv = getaddrinfo(buf, NULL, &hints, &res);
- if (rv)
- errx(1, "illegal address: \"%s\"", buf);
- for (ai = res; ai; ai = ai->ai_next) {
- switch (ai->ai_family) {
+ switch (n->af) {
case AF_INET:
- if (net > 32)
- errx(1, "illegal netmask: \"%d\"", net);
- if (size >= msize)
- grow_buffer(sizeof(struct pfr_addr), 0);
- buffer.addrs[size].pfra_ip4addr =
- ((struct sockaddr_in *)ai->ai_addr)->sin_addr;
- buffer.addrs[size].pfra_not = not;
- buffer.addrs[size].pfra_net = (net >= 0) ? net : 32;
buffer.addrs[size].pfra_af = AF_INET;
- size++;
+ buffer.addrs[size].pfra_ip4addr.s_addr =
+ n->addr.v.a.addr.addr32[0];
+ buffer.addrs[size].pfra_net =
+ unmask(&n->addr.v.a.mask, AF_INET);
+ if (test && (not || buffer.addrs[size].pfra_net != 32))
+ errx(1, "illegal test address");
+ if (buffer.addrs[size].pfra_net > 32)
+ errx(1, "illegal netmask %d",
+ buffer.addrs[size].pfra_net);
break;
case AF_INET6:
- if (net > 128)
- errx(1, "illegal netmask: \"%d\"", net);
- if (size >= msize)
- grow_buffer(sizeof(struct pfr_addr), 0);
- buffer.addrs[size].pfra_ip6addr =
- ((struct sockaddr_in6 *)ai->ai_addr)->sin6_addr;
- buffer.addrs[size].pfra_not = not;
- buffer.addrs[size].pfra_net = (net >= 0) ? net : 128;
buffer.addrs[size].pfra_af = AF_INET6;
- size++;
+ memcpy(&buffer.addrs[size].pfra_ip6addr,
+ &n->addr.v.a.addr.v6, sizeof(struct in6_addr));
+ buffer.addrs[size].pfra_net =
+ unmask(&n->addr.v.a.mask, AF_INET6);
+ if (test && (not || buffer.addrs[size].pfra_net != 128))
+ errx(1, "illegal test address");
+ if (buffer.addrs[size].pfra_net > 128)
+ errx(1, "illegal netmask %d",
+ buffer.addrs[size].pfra_net);
+ break;
+ break;
+ default:
+ errx(1, "unknown address family %d", n->af);
break;
}
- }
- freeaddrinfo(res);
+ size++;
+ h = n;
+ n = n->next;
+ free(h);
+ } while (n != NULL);
}
void