[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: pf tables and interface groups



* Henning Brauer <lists-openbsd_(_at_)_bsws_(_dot_)_de> [2005-10-12 17:17]:
> no, I managed to miss implementing the static expansion, the way more 
> complicated dynamic expansion for interface groups works fine. I'll add 
> the static one asap.

so here's the diff for that.
disclaimer: I hacked that at a conference, beeing dead tired, careful 
reading & testing appreciated.

Index: pfctl_parser.c
===================================================================
RCS file: /cvs/src/sbin/pfctl/pfctl_parser.c,v
retrieving revision 1.220
diff -u -p -r1.220 pfctl_parser.c
--- pfctl_parser.c	13 Oct 2005 13:27:06 -0000	1.220
+++ pfctl_parser.c	13 Oct 2005 14:36:35 -0000
@@ -66,6 +66,7 @@ void		 print_fromto(struct pf_rule_addr 
 		    struct pf_rule_addr *, u_int8_t, u_int8_t, int);
 int		 ifa_skip_if(const char *filter, struct node_host *p);
 
+struct node_host	*ifa_grouplookup(const char *, int);
 struct node_host	*host_if(const char *, int);
 struct node_host	*host_v4(const char *, int);
 struct node_host	*host_v6(const char *, int);
@@ -1165,10 +1166,28 @@ struct node_host *
 ifa_exists(const char *ifa_name)
 {
 	struct node_host	*n;
+	struct ifgroupreq	ifgr;
+	int			s;
 
 	if (iftab == NULL)
 		ifa_load();
 
+	/* check wether this is a group */
+	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+		err(1, "socket");
+	bzero(&ifgr, sizeof(ifgr));
+	strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name));
+	if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == 0) {
+		/* fake a node_host */
+		if ((n = calloc(1, sizeof(*n))) == NULL)
+			err(1, "calloc");
+		if ((n->ifname = strdup(ifa_name)) == NULL)
+			err(1, "strdup");
+		close(s);
+		return (n);
+	}
+	close(s);
+
 	for (n = iftab; n; n = n->next) {
 		if (n->af == AF_LINK && !strncmp(n->ifname, ifa_name, IFNAMSIZ))
 			return (n);
@@ -1178,11 +1197,56 @@ ifa_exists(const char *ifa_name)
 }
 
 struct node_host *
+ifa_grouplookup(const char *ifa_name, int flags)
+{
+	struct ifg_req		*ifg;
+	struct ifgroupreq	 ifgr;
+	int			 s, len;
+	struct node_host	*n, *h = NULL, *hn;
+
+	if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
+		err(1, "socket");
+	bzero(&ifgr, sizeof(ifgr));
+	strlcpy(ifgr.ifgr_name, ifa_name, sizeof(ifgr.ifgr_name));
+	if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1) {
+		close(s);
+		return (NULL);
+	}
+
+	len = ifgr.ifgr_len;
+	if ((ifgr.ifgr_groups = calloc(1, len)) == NULL)
+		err(1, "calloc");
+	if (ioctl(s, SIOCGIFGMEMB, (caddr_t)&ifgr) == -1)
+		err(1, "SIOCGIFGMEMB");
+
+	for (ifg = ifgr.ifgr_groups; ifg && len >= sizeof(struct ifg_req);
+	    ifg++) {
+		len -= sizeof(struct ifg_req);
+		n = ifa_lookup(ifg->ifgrq_member, flags);
+		if (h == NULL)
+			h = n;
+		else {
+			for (hn = h; hn->next != NULL; hn = hn->next)
+				;	/* nothing */
+			hn->next = n;
+			n->tail = hn;
+		}
+	}
+	free(ifgr.ifgr_groups);	
+	close(s);
+
+	return (h);
+}
+
+struct node_host *
 ifa_lookup(const char *ifa_name, int flags)
 {
 	struct node_host	*p = NULL, *h = NULL, *n = NULL;
 	int			 got4 = 0, got6 = 0;
 	const char		 *last_if = NULL;
+
+	if ((h = ifa_grouplookup(ifa_name, flags)) != NULL)
+		return (h);
 
 	if (!strncmp(ifa_name, "self", IFNAMSIZ))
 		ifa_name = NULL;



Visit your host, monkey.org