ipsets equivalent in *BSD, using pf tables.

This commit is contained in:
Simon Kelley
2014-06-02 20:30:07 +01:00
parent 2f4c4b6076
commit c4a0937683
6 changed files with 175 additions and 5 deletions

View File

@@ -1,6 +1,9 @@
version 2.72 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 version 2.71
Subtle change to error handling to help DNSSEC validation Subtle change to error handling to help DNSSEC validation

View File

@@ -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 \ 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 \ 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 \ 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 \ hdrs = dnsmasq.h config.h dhcp-protocol.h dhcp6-protocol.h \
dns-protocol.h radv-protocol.h ip6addr.h dns-protocol.h radv-protocol.h ip6addr.h

View 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 \ rfc2131.c tftp.c util.c conntrack.c \
dhcp6.c rfc3315.c dhcp-common.c outpacket.c \ dhcp6.c rfc3315.c dhcp-common.c outpacket.c \
radv.c slaac.c auth.c ipset.c domain.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 LOCAL_MODULE := dnsmasq

View File

@@ -330,7 +330,7 @@ HAVE_SOCKADDR_SA_LEN
#undef HAVE_AUTH #undef HAVE_AUTH
#endif #endif
#if defined(NO_IPSET) || !defined(HAVE_LINUX_NETWORK) #if defined(NO_IPSET)
#undef HAVE_IPSET #undef HAVE_IPSET
#endif #endif

View File

@@ -16,7 +16,7 @@
#include "dnsmasq.h" #include "dnsmasq.h"
#ifdef HAVE_IPSET #if defined(HAVE_IPSET) && defined(HAVE_LINUX_NETWORK)
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>

167
src/tables.c Normal file
View File

@@ -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