diff options
author | Simon Kelley <simon@thekelleys.org.uk> | 2014-06-02 20:30:07 +0100 |
---|---|---|
committer | Simon Kelley <simon@thekelleys.org.uk> | 2014-06-02 20:30:07 +0100 |
commit | c4a093768380afcf1d2d4def50380392295b36b8 (patch) | |
tree | 12bcf2e29ced28414eb68afc5a75e2dfda1228e4 | |
parent | 2f4c4b6076885536839fb16942b10f2c4efa8f44 (diff) | |
download | dnsmasq-c4a093768380afcf1d2d4def50380392295b36b8.tar.gz |
ipsets equivalent in *BSD, using pf tables.
-rw-r--r-- | CHANGELOG | 5 | ||||
-rw-r--r-- | Makefile | 2 | ||||
-rw-r--r-- | bld/Android.mk | 2 | ||||
-rw-r--r-- | src/config.h | 2 | ||||
-rw-r--r-- | src/ipset.c | 2 | ||||
-rw-r--r-- | src/tables.c | 167 |
6 files changed, 175 insertions, 5 deletions
@@ -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 @@ -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 diff --git a/bld/Android.mk b/bld/Android.mk index 309d178..5255ec9 100644 --- a/bld/Android.mk +++ b/bld/Android.mk @@ -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 diff --git a/src/config.h b/src/config.h index 1793e40..2155544 100644 --- a/src/config.h +++ b/src/config.h @@ -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 diff --git a/src/ipset.c b/src/ipset.c index 6de5952..8c5b727 100644 --- a/src/ipset.c +++ b/src/ipset.c @@ -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 index 0000000..fead11e --- /dev/null +++ b/src/tables.c @@ -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 |