Module Name:    src
Committed By:   christos
Date:           Sun Jan 25 20:59:39 UTC 2015

Modified Files:
        src/external/bsd/blacklist/bin: blacklistd.8 blacklistd.c conf.c
            internal.c internal.h

Log Message:
Handle interfaces in configuration files, requested by kardel@


To generate a diff of this commit:
cvs rdiff -u -r1.5 -r1.6 src/external/bsd/blacklist/bin/blacklistd.8
cvs rdiff -u -r1.28 -r1.29 src/external/bsd/blacklist/bin/blacklistd.c
cvs rdiff -u -r1.13 -r1.14 src/external/bsd/blacklist/bin/conf.c
cvs rdiff -u -r1.3 -r1.4 src/external/bsd/blacklist/bin/internal.c
cvs rdiff -u -r1.10 -r1.11 src/external/bsd/blacklist/bin/internal.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/external/bsd/blacklist/bin/blacklistd.8
diff -u src/external/bsd/blacklist/bin/blacklistd.8:1.5 src/external/bsd/blacklist/bin/blacklistd.8:1.6
--- src/external/bsd/blacklist/bin/blacklistd.8:1.5	Sat Jan 24 13:34:05 2015
+++ src/external/bsd/blacklist/bin/blacklistd.8	Sun Jan 25 15:59:39 2015
@@ -1,4 +1,4 @@
-.\" $NetBSD: blacklistd.8,v 1.5 2015/01/24 18:34:05 christos Exp $
+.\" $NetBSD: blacklistd.8,v 1.6 2015/01/25 20:59:39 christos Exp $
 .\" 
 .\" Copyright (c) 2015 The NetBSD Foundation, Inc.
 .\" All rights reserved.
@@ -130,7 +130,7 @@ and can be
 for all fields.
 The fields of the configuration file are as follows:
 .Bd -literal -offset indent
-[address:]service
+[address|interface:]service
 socket-type
 protocol
 user

Index: src/external/bsd/blacklist/bin/blacklistd.c
diff -u src/external/bsd/blacklist/bin/blacklistd.c:1.28 src/external/bsd/blacklist/bin/blacklistd.c:1.29
--- src/external/bsd/blacklist/bin/blacklistd.c:1.28	Sat Jan 24 02:46:20 2015
+++ src/external/bsd/blacklist/bin/blacklistd.c	Sun Jan 25 15:59:39 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: blacklistd.c,v 1.28 2015/01/24 07:46:20 christos Exp $	*/
+/*	$NetBSD: blacklistd.c,v 1.29 2015/01/25 20:59:39 christos Exp $	*/
 
 /*-
  * Copyright (c) 2015 The NetBSD Foundation, Inc.
@@ -32,7 +32,7 @@
 #include "config.h"
 #endif
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: blacklistd.c,v 1.28 2015/01/24 07:46:20 christos Exp $");
+__RCSID("$NetBSD: blacklistd.c,v 1.29 2015/01/25 20:59:39 christos Exp $");
 
 #include <sys/types.h>
 #include <sys/socket.h>
@@ -58,6 +58,7 @@ __RCSID("$NetBSD: blacklistd.c,v 1.28 20
 #include <stdlib.h>
 #include <unistd.h>
 #include <time.h>
+#include <ifaddrs.h>
 #include <netinet/in.h>
 
 #include "bl.h"
@@ -101,7 +102,8 @@ sigdone(int n __unused)
 static __dead void
 usage(int c)
 {
-	warnx("Unknown option `%c'", (char)c);
+	if (c)
+		warnx("Unknown option `%c'", (char)c);
 	fprintf(stderr, "Usage: %s [-vdf] [-c <config>] [-r <rulename>] "
 	    "[-P <sockpathsfile>] [-C <controlprog>] [-D <dbfile>] "
 	    "[-t <timeout>]\n", getprogname());
@@ -249,6 +251,21 @@ out:
 }
 
 static void
+update_interfaces(void)
+{
+	struct ifaddrs *oifas, *nifas;
+
+	if (getifaddrs(&nifas) == -1)
+		return;
+
+	oifas = ifas;
+	ifas = nifas;
+
+	if (oifas)
+		freeifaddrs(oifas);
+}
+
+static void
 update(void)
 {
 	struct timespec ts;
@@ -359,6 +376,10 @@ main(int argc, char *argv[])
 		}
 	}
 
+	argc -= optind;
+	if (argc)
+		usage(0);
+
 	signal(SIGHUP, sighup);
 	signal(SIGINT, sigdone);
 	signal(SIGQUIT, sigdone);
@@ -377,6 +398,7 @@ main(int argc, char *argv[])
 			tout = 15000;
 	}
 
+	update_interfaces();
 	conf_parse(configfile);
 	if (reset) {
 		for (size_t i = 0; i < nconf; i++)
@@ -436,6 +458,8 @@ main(int argc, char *argv[])
 		}
 		if (t % 100 == 0)
 			state_sync(state);
+		if (t % 10000 == 0)
+			update_interfaces();
 		update();
 	}
 	state_close(state);

Index: src/external/bsd/blacklist/bin/conf.c
diff -u src/external/bsd/blacklist/bin/conf.c:1.13 src/external/bsd/blacklist/bin/conf.c:1.14
--- src/external/bsd/blacklist/bin/conf.c:1.13	Thu Jan 22 11:19:53 2015
+++ src/external/bsd/blacklist/bin/conf.c	Sun Jan 25 15:59:39 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: conf.c,v 1.13 2015/01/22 16:19:53 christos Exp $	*/
+/*	$NetBSD: conf.c,v 1.14 2015/01/25 20:59:39 christos Exp $	*/
 
 /*-
  * Copyright (c) 2015 The NetBSD Foundation, Inc.
@@ -33,7 +33,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: conf.c,v 1.13 2015/01/22 16:19:53 christos Exp $");
+__RCSID("$NetBSD: conf.c,v 1.14 2015/01/25 20:59:39 christos Exp $");
 
 #include <stdio.h>
 #include <string.h>
@@ -48,14 +48,29 @@ __RCSID("$NetBSD: conf.c,v 1.13 2015/01/
 #endif
 #include <stdlib.h>
 #include <limits.h>
+#include <ifaddrs.h>
 #include <arpa/inet.h>
 #include <netinet/in.h>
+#include <net/if.h>
 #include <sys/socket.h>
 
 #include "bl.h"
 #include "internal.h"
 #include "conf.h"
 
+
+struct sockaddr_if {
+        uint8_t         sif_len;
+	sa_family_t     sif_family;
+	in_port_t       sif_port;
+	char		sif_name[16];
+};
+
+#define SIF_NAME(a) \
+    ((const struct sockaddr_if *)(const void *)(a))->sif_name
+
+static int conf_is_interface(const char *);
+
 static void
 advance(char **p)
 {
@@ -164,34 +179,45 @@ gethostport(const char *f, size_t l, voi
 	struct conf *c = v;
 
 	if ((d = strstr(p, "]:")) != NULL) {
-		struct sockaddr_in6 *s6 = (void *)&c->c_ss;
+		struct sockaddr_in6 *sin6 = (void *)&c->c_ss;
 		*d++ = '\0';
 		p++;
 		if (debug)
 			(*lfun)(LOG_DEBUG, "%s: host6 %s", __func__, p);
 		if (strcmp(p, "*") != 0) {
-			if (inet_pton(AF_INET6, p, &s6->sin6_addr) == -1)
+			if (inet_pton(AF_INET6, p, &sin6->sin6_addr) == -1)
 				goto out;
-			s6->sin6_family = AF_INET6;
+			sin6->sin6_family = AF_INET6;
 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
-			s6->sin6_len = sizeof(*s6);
+			sin6->sin6_len = sizeof(*sin6);
 #endif
-			port = &s6->sin6_port;
+			port = &sin6->sin6_port;
 		} 
 		p = ++d;
 	} else if ((d = strrchr(p, ':')) != NULL) {
-		struct sockaddr_in *s = (void *)&c->c_ss;
+		struct sockaddr_in *sin = (void *)&c->c_ss;
+		struct sockaddr_if *sif = (void *)&c->c_ss;
 		*d++ = '\0';
 		if (debug)
 			(*lfun)(LOG_DEBUG, "%s: host4 %s", __func__, p);
 		if (strcmp(p, "*") != 0) {
-			if (inet_pton(AF_INET, p, &s->sin_addr) == -1)
-				goto out;
-			s->sin_family = AF_INET;
+			if (conf_is_interface(p)) {
+				sif->sif_family = AF_MAX;
+				strlcpy(sif->sif_name, p,
+				    sizeof(sif->sif_name));
+#ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
+				sif->sif_len = sizeof(*sif);
+#endif
+				port = &sif->sif_port;
+			} else if (inet_pton(AF_INET, p, &sin->sin_addr) != -1)
+			{
+				sin->sin_family = AF_INET;
 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
-			s->sin_len = sizeof(*s);
+				sin->sin_len = sizeof(*sin);
 #endif
-			port = &s->sin_port;
+				port = &sif->sif_port;
+			} else
+				goto out;
 		}
 		p = d;
 	}
@@ -332,15 +358,85 @@ conf_sort(const void *v1, const void *v2
 }
 
 static int
-conf_eq(const struct conf *c1, const struct conf *c2)
+conf_is_interface(const char *name)
 {
-	if (c2->c_ss.ss_family != 0 &&
-	    memcmp(&c1->c_ss, &c2->c_ss, sizeof(c1->c_ss))) {
-		if (debug > 1)
-			(*lfun)(LOG_DEBUG, "%s: c_ss fail", __func__);
-		return 0;
+	const struct ifaddrs *ifa;
+
+	for (ifa = ifas; ifas; ifa = ifa->ifa_next)
+		if (strcmp(ifa->ifa_name, name) == 0)
+			return 1;
+	return 0;
+}
+
+static int
+conf_addr_in_interface(const struct sockaddr_storage *s1,
+    const struct sockaddr_storage *s2)
+{
+	const char *name = SIF_NAME(s2);
+	const struct ifaddrs *ifa;
+	socklen_t slen;
+	const struct sockaddr_in *sin = (const void *)s1;
+	const struct sockaddr_in6 *sin6 = (const void *)s1;
+
+	for (ifa = ifas; ifa; ifa = ifa->ifa_next) {
+		if ((ifa->ifa_flags & IFF_UP) == 0)
+			continue;
+
+		if (strcmp(ifa->ifa_name, name) != 0)
+			continue;
+
+		if (s1->ss_family != ifa->ifa_addr->sa_family)
+			continue;
+
+		const void *v = ifa->ifa_addr;
+		const void *p1, *p2;
+		switch (s1->ss_family) {
+		case AF_INET:
+			p1 = &sin->sin_addr;
+			p2 = &((const struct sockaddr_in *)v)->sin_addr;
+			slen = sizeof(sin->sin_addr);
+			break;
+		case AF_INET6:
+			p1 = &sin6->sin6_addr;
+			p2 = &((const struct sockaddr_in6 *)v)->sin6_addr;
+			slen = sizeof(sin6->sin6_addr);
+			break;
+		default:
+			(*lfun)(LOG_ERR, "Bad family %u", s1->ss_family);
+			continue;
+		}
+		if (memcmp(p1, p2, slen) == 0)
+			return 1;
 	}
+	return 0;
+}
+
+static int
+conf_addr_eq(const struct sockaddr_storage *s1,
+    const struct sockaddr_storage *s2)
+{
+	switch (s2->ss_family) {
+	case 0:
+		return 1;
+	case AF_MAX:
+		return conf_addr_in_interface(s1, s2);
+	default:
+	    	if (memcmp(s1, s2, sizeof(*s2))) {
+			if (debug > 1)
+				(*lfun)(LOG_DEBUG, "%s: c_ss fail", __func__);
+			return 0;
+		}
+		return 1;
+	}
+}
+
+static int
+conf_eq(const struct conf *c1, const struct conf *c2)
+{
 		
+	if (!conf_addr_eq(&c1->c_ss, &c2->c_ss))
+		return 0;
+
 #define CMP(a, b, f) \
 	if ((a)->f != (b)->f && (b)->f != -1) { \
 		if (debug > 1) \
@@ -388,18 +484,28 @@ conf_print(char *buf, size_t len, const 
 
 #define N(n, v) conf_num(b[n], sizeof(b[n]), (v))
 
-	if (c->c_ss.ss_family) {
+	switch (c->c_ss.ss_family) {
+	case 0:
+		if (c->c_port == -1)
+			snprintf(hb, sizeof(hb), "*");
+		else
+			snprintf(hb, sizeof(hb), "%d", c->c_port);
+		break;
+	case AF_MAX:
+		if (c->c_port == -1)
+			snprintf(hb, sizeof(hb), "%s:*", SIF_NAME(&c->c_ss));
+		else
+			snprintf(hb, sizeof(hb), "%s:%d", SIF_NAME(&c->c_ss),
+			    c->c_port);
+		break;
+	default:
 		if (c->c_port == -1)
 			sockaddr_snprintf(hb, sizeof(hb), "%a:*",
 			    (const void *)&c->c_ss);
 		else 
 			sockaddr_snprintf(hb, sizeof(hb), "%a:%p",
 			    (const void *)&c->c_ss);
-	} else {
-		if (c->c_port == -1)
-			snprintf(hb, sizeof(hb), "*");
-		else
-			snprintf(hb, sizeof(hb), "%d", c->c_port);
+		break;
 	}
 	
 	sp = *delim == '\t' ? 20 : -1;

Index: src/external/bsd/blacklist/bin/internal.c
diff -u src/external/bsd/blacklist/bin/internal.c:1.3 src/external/bsd/blacklist/bin/internal.c:1.4
--- src/external/bsd/blacklist/bin/internal.c:1.3	Wed Jan 21 22:10:49 2015
+++ src/external/bsd/blacklist/bin/internal.c	Sun Jan 25 15:59:39 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: internal.c,v 1.3 2015/01/22 03:10:49 christos Exp $	*/
+/*	$NetBSD: internal.c,v 1.4 2015/01/25 20:59:39 christos Exp $	*/
 
 /*-
  * Copyright (c) 2015 The NetBSD Foundation, Inc.
@@ -33,7 +33,7 @@
 #endif
 
 #include <sys/cdefs.h>
-__RCSID("$NetBSD: internal.c,v 1.3 2015/01/22 03:10:49 christos Exp $");
+__RCSID("$NetBSD: internal.c,v 1.4 2015/01/25 20:59:39 christos Exp $");
 
 #include <stdio.h>
 #include <syslog.h>
@@ -43,5 +43,6 @@ int debug;
 const char *rulename = "blacklistd";
 const char *controlprog = _PATH_BLCONTROL;
 struct conf *conf;
+struct ifaddrs *ifas;
 size_t nconf;
 void (*lfun)(int, const char *, ...) = syslog;

Index: src/external/bsd/blacklist/bin/internal.h
diff -u src/external/bsd/blacklist/bin/internal.h:1.10 src/external/bsd/blacklist/bin/internal.h:1.11
--- src/external/bsd/blacklist/bin/internal.h:1.10	Thu Jan 22 16:32:30 2015
+++ src/external/bsd/blacklist/bin/internal.h	Sun Jan 25 15:59:39 2015
@@ -1,4 +1,4 @@
-/*	$NetBSD: internal.h,v 1.10 2015/01/22 21:32:30 christos Exp $	*/
+/*	$NetBSD: internal.h,v 1.11 2015/01/25 20:59:39 christos Exp $	*/
 
 /*-
  * Copyright (c) 2015 The NetBSD Foundation, Inc.
@@ -46,6 +46,7 @@ extern size_t nconf;
 extern int debug;
 extern const char *rulename;
 extern const char *controlprog;
+extern struct ifaddrs *ifas;
 
 void (*lfun)(int, const char *, ...);
 

Reply via email to