]> git.ipfire.org Git - people/ms/dnsmasq.git/commitdiff
ipsets equivalent in *BSD, using pf tables.
authorSimon Kelley <simon@thekelleys.org.uk>
Mon, 2 Jun 2014 19:30:07 +0000 (20:30 +0100)
committerSimon Kelley <simon@thekelleys.org.uk>
Mon, 2 Jun 2014 19:30:07 +0000 (20:30 +0100)
CHANGELOG
Makefile
bld/Android.mk
src/config.h
src/ipset.c
src/tables.c [new file with mode: 0644]

index 70e5aa657fec0b6b0235df63d7abe5f9f9edea02..aba3a67755ad81f1469dd7a6a69989253fb8b19f 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,5 +1,8 @@
 version 2.72
-           Add ra-advrouter mode, for RFC-3775 mobile IPv6 support.
+            Add ra-advrouter mode, for RFC-3775 mobile IPv6 support.
+
+           Add support for "ipsets" in *BSD, using pf. Thanks to 
+           Sven Falempim for the patch.
 
 
 version 2.71
index 292c8bdbe8a16f648fbfe787c27ef18ce53b4881..fe299d990e039811ed73fc4b47c2684b60209560 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -69,7 +69,7 @@ objs = cache.o rfc1035.o util.o option.o forward.o network.o \
        dnsmasq.o dhcp.o lease.o rfc2131.o netlink.o dbus.o bpf.o \
        helper.o tftp.o log.o conntrack.o dhcp6.o rfc3315.o \
        dhcp-common.o outpacket.o radv.o slaac.o auth.o ipset.o \
-       domain.o dnssec.o blockdata.o
+       domain.o dnssec.o blockdata.o tables.c
 
 hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
        dns-protocol.h radv-protocol.h ip6addr.h
index 309d1789bfeb6fb386018ae64a16624b44f4fdf4..5255ec90a4312ba302a63e3e424baf6ad954d0cc 100644 (file)
@@ -9,7 +9,7 @@ LOCAL_SRC_FILES :=  bpf.c cache.c dbus.c dhcp.c dnsmasq.c \
                    rfc2131.c tftp.c util.c conntrack.c \
                    dhcp6.c rfc3315.c dhcp-common.c outpacket.c \
                    radv.c slaac.c auth.c ipset.c domain.c \
-                   dnssec.c dnssec-openssl.c blockdata.c
+                   dnssec.c dnssec-openssl.c blockdata.c tables.c
 
 LOCAL_MODULE := dnsmasq
 
index 1793e403cad9380da09e140b00496ecbc65523ca..21555440f851d8fc22da26e75dca6e253939d2e5 100644 (file)
@@ -330,7 +330,7 @@ HAVE_SOCKADDR_SA_LEN
 #undef HAVE_AUTH
 #endif
 
-#if defined(NO_IPSET) || !defined(HAVE_LINUX_NETWORK)
+#if defined(NO_IPSET)
 #undef HAVE_IPSET
 #endif
 
index 6de5952f447cba7c6d3aa9e0c5fa8c2c026b7b0b..8c5b727223710585449912bb9b33f5bc6c2ae680 100644 (file)
@@ -16,7 +16,7 @@
 
 #include "dnsmasq.h"
 
-#ifdef HAVE_IPSET
+#if defined(HAVE_IPSET) && defined(HAVE_LINUX_NETWORK)
 
 #include <string.h>
 #include <errno.h>
diff --git a/src/tables.c b/src/tables.c
new file mode 100644 (file)
index 0000000..fead11e
--- /dev/null
@@ -0,0 +1,167 @@
+/* tables.c is Copyright (c) 2014 Dohnuts All Rights Reserved.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; version 2 dated June, 1991, or
+   (at your option) version 3 dated 29 June, 2007.
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+     
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "dnsmasq.h"
+
+#if defined(HAVE_IPSET) && defined(HAVE_BSD_NETWORK)
+
+#include <sys/types.h>
+#include <sys/ioctl.h>
+
+#include <net/if.h>
+#include <netinet/in.h>
+#include <net/pfvar.h>
+
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+
+#define UNUSED(x) (void)(x)
+
+static char *pf_device = "/dev/pf";
+static int dev = -1;
+
+static char *pfr_strerror(int errnum)
+{
+  switch (errnum) 
+    {
+    case ESRCH:
+      return "Table does not exist";
+    case ENOENT:
+      return "Anchor or Ruleset does not exist";
+    default:
+      return strerror(errnum);
+    }
+}
+
+static int pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags)
+{
+  struct pfioc_table io;
+  
+  if (size < 0 || (size && tbl == NULL)) 
+    {
+      errno = EINVAL;
+      return (-1);
+    }
+  bzero(&io, sizeof io);
+  io.pfrio_flags = flags;
+  io.pfrio_buffer = tbl;
+  io.pfrio_esize = sizeof(*tbl);
+  io.pfrio_size = size;
+  if (ioctl(dev, DIOCRADDTABLES, &io))
+    return (-1);
+  if (nadd != NULL)
+    *nadd = io.pfrio_nadd;
+  return (0);
+}
+
+static int fill_addr(const struct all_addr *ipaddr, int flags, struct pfr_addr* addr) {
+  if ( !addr || !ipaddr)
+    {
+      my_syslog(LOG_ERR, _("error: fill_addr missused"));
+      return -1;
+    }
+  bzero(addr, sizeof(*addr));
+#ifdef HAVE_IPV6
+  if (flags & F_IPV6) 
+    {
+      addr->pfra_af = AF_INET6;
+      addr->pfra_net = 0x80;
+      memcpy(&(addr->pfra_ip6addr), &(ipaddr->addr), sizeof(struct in6_addr));
+    } 
+  else 
+#endif
+    {
+      addr->pfra_af = AF_INET;
+      addr->pfra_net = 0x20;
+      addr->pfra_ip4addr.s_addr = ipaddr->addr.addr4.s_addr;
+    }
+  return 1;
+}
+
+/*****************************************************************************/
+
+void ipset_init(void) 
+{
+  dev = open( pf_device, O_RDWR);
+  if (dev == -1)
+    {
+      err(1, "%s", pf_device);
+      die (_("failed to access pf devices: %s"), NULL, EC_MISC);
+    }
+}
+
+int add_to_ipset(const char *setname, const struct all_addr *ipaddr,
+                     int flags, int remove)
+{
+  struct pfr_addr addr;
+  struct pfioc_table io;
+  struct pfr_table table;
+  int n = 0, rc = 0;
+
+  if ( dev == -1 ) 
+    {
+      my_syslog(LOG_ERR, _("warning: no opened pf devices %s"), pf_device);
+      return -1;
+    }
+
+  bzero(&table, sizeof(struct pfr_table));
+  table.pfrt_flags |= PFR_TFLAG_PERSIST;
+  if ( strlen(setname) >= PF_TABLE_NAME_SIZE )
+    {
+      my_syslog(LOG_ERR, _("error: cannot use table name %s"), setname);
+      errno = ENAMETOOLONG;
+      return -1;
+    }
+  
+  if ( strlcpy(table.pfrt_name, setname,
+               sizeof(table.pfrt_name)) >= sizeof(table.pfrt_name)) 
+    {
+      my_syslog(LOG_ERR, _("error: cannot strlcpy table name %s"), setname);
+      return -1;
+    }
+  
+  if (rc = pfr_add_tables(&table, 1, &n, 0)) 
+    {
+      my_syslog(LOG_WARNING, _("warning: pfr_add_tables: %s(%d)"),
+               pfr_strerror(errno),rc);
+      return -1;
+    }
+  table.pfrt_flags &= ~PFR_TFLAG_PERSIST;
+  if (n)
+    my_syslog(LOG_INFO, _("info: table created"));
+  
+  fill_addr(ipaddr,flags,&addr);
+  bzero(&io, sizeof(io));
+  io.pfrio_flags = 0;
+  io.pfrio_table = table;
+  io.pfrio_buffer = &addr;
+  io.pfrio_esize = sizeof(addr);
+  io.pfrio_size = 1;
+  if (ioctl(dev, ( remove ? DIOCRDELADDRS : DIOCRADDADDRS ), &io)) 
+    {
+      my_syslog(LOG_WARNING, _("warning: DIOCR%sADDRS: %s"), ( remove ? "DEL" : "ADD" ), pfr_strerror(errno));
+      return -1;
+    }
+  
+  my_syslog(LOG_INFO, _("%d addresses %s"),
+            io.pfrio_nadd, ( remove ? "removed" : "added" ));
+  
+  return io.pfrio_nadd;
+}
+
+
+#endif