Compare commits

..
10 Commits
16 changed files with 254 additions and 26 deletions

No files matched your search

+7
View File
@@ -1,3 +1,10 @@
version 2.72
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
when servers fail to provide NODATA answers for when servers fail to provide NODATA answers for
+1 -1
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
+1 -1
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
+6
View File
@@ -1,3 +1,9 @@
dnsmasq (2.72-1) unstable; urgency=low
* New upstream.
-- Simon Kelley <simon@thekelleys.org.uk> Fri, 20 May 2014 21:01:11 +0000
dnsmasq (2.71-1) unstable; urgency=low dnsmasq (2.71-1) unstable; urgency=low
* New upstream. * New upstream.
Vendored
+7
View File
@@ -277,8 +277,15 @@ case "$1" in
stop_resolvconf stop_resolvconf
;; ;;
systemd-exec) systemd-exec)
# /var/run may be volatile, so we need to ensure that
# /var/run/dnsmasq exists here as well as in postinst
if [ ! -d /var/run/dnsmasq ]; then
mkdir /var/run/dnsmasq || return 2
chown dnsmasq:nogroup /var/run/dnsmasq || return 2
fi
# Enable DBus by default because we use DBus activation with systemd. # Enable DBus by default because we use DBus activation with systemd.
exec $DAEMON --keep-in-foreground --enable-dbus \ exec $DAEMON --keep-in-foreground --enable-dbus \
-x /var/run/dnsmasq/$NAME.pid \
${MAILHOSTNAME:+ -m $MAILHOSTNAME} \ ${MAILHOSTNAME:+ -m $MAILHOSTNAME} \
${MAILTARGET:+ -t $MAILTARGET} \ ${MAILTARGET:+ -t $MAILTARGET} \
${DNSMASQ_USER:+ -u $DNSMASQ_USER} \ ${DNSMASQ_USER:+ -u $DNSMASQ_USER} \
+5 -7
View File
@@ -11,18 +11,16 @@
package=dnsmasq-base package=dnsmasq-base
CFLAGS = $(shell export DEB_BUILD_OPTIONS=$(DEB_BUILD_OPTIONS); dpkg-buildflags --get CFLAGS) dpkg_buildflags := DEB_BUILD_MAINT_OPTIONS="hardening=+all" dpkg-buildflags
CFLAGS += $(shell dpkg-buildflags --get CPPFLAGS)
CFLAGS = $(shell $(dpkg_buildflags) --get CFLAGS)
CFLAGS += $(shell $(dpkg_buildflags) --get CPPFLAGS)
CFLAGS += -Wall -W CFLAGS += -Wall -W
LDFLAGS = $(shell dpkg-buildflags --get LDFLAGS) LDFLAGS = $(shell $(dpkg_buildflags) --get LDFLAGS)
DEB_COPTS = $(COPTS) DEB_COPTS = $(COPTS)
# The nettle library in Debian is too old to include
# ECC support.
DEB_COPTS += -DNO_NETTLE_ECC
TARGET = install-i18n TARGET = install-i18n
DEB_BUILD_ARCH_OS := $(shell dpkg-architecture -qDEB_BUILD_ARCH_OS) DEB_BUILD_ARCH_OS := $(shell dpkg-architecture -qDEB_BUILD_ARCH_OS)
+6 -1
View File
@@ -794,7 +794,7 @@ and
for details.) for details.)
For IPv6, the mode may be some combination of For IPv6, the mode may be some combination of
.B ra-only, slaac, ra-names, ra-stateless. .B ra-only, slaac, ra-names, ra-stateless, ra-advrouter.
.B ra-only .B ra-only
tells dnsmasq to offer Router Advertisement only on this subnet, tells dnsmasq to offer Router Advertisement only on this subnet,
@@ -829,6 +829,11 @@ can be combined with
and and
.B slaac. .B slaac.
.B ra-advrouter
enables a mode where router address(es) rather than prefix(es) are included in the advertisements.
This is described in RFC-3775 section 7.2 and is used in mobile IPv6. In this mode the interval option
is also included, as described in RFC-3775 section 7.3.
.TP .TP
.B \-G, --dhcp-host=[<hwaddr>][,id:<client_id>|*][,set:<tag>][,<ipaddr>][,<hostname>][,<lease_time>][,ignore] .B \-G, --dhcp-host=[<hwaddr>][,id:<client_id>|*][,set:<tag>][,<ipaddr>][,<hostname>][,<lease_time>][,ignore]
Specify per host parameters for the DHCP server. This allows a machine Specify per host parameters for the DHCP server. This allows a machine
+1 -1
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
+2 -1
View File
@@ -404,7 +404,8 @@ void dhcp_packet(time_t now, int pxe_fd)
memcpy(arp_req.arp_ha.sa_data, mess->chaddr, mess->hlen); memcpy(arp_req.arp_ha.sa_data, mess->chaddr, mess->hlen);
/* interface name already copied in */ /* interface name already copied in */
arp_req.arp_flags = ATF_COM; arp_req.arp_flags = ATF_COM;
ioctl(daemon->dhcpfd, SIOCSARP, &arp_req); if (ioctl(daemon->dhcpfd, SIOCSARP, &arp_req) == -1)
my_syslog(MS_DHCP | LOG_ERR, _("ARP-cache injection failed: %s"), strerror(errno));
} }
#elif defined(HAVE_SOLARIS_NETWORK) #elif defined(HAVE_SOLARIS_NETWORK)
else if ((ntohs(mess->flags) & 0x8000) || mess->hlen != ETHER_ADDR_LEN || mess->htype != ARPHRD_ETHER) else if ((ntohs(mess->flags) & 0x8000) || mess->hlen != ETHER_ADDR_LEN || mess->htype != ARPHRD_ETHER)
+11 -2
View File
@@ -708,12 +708,20 @@ static int construct_worker(struct in6_addr *local, int prefix,
void dhcp_construct_contexts(time_t now) void dhcp_construct_contexts(time_t now)
{ {
static int active = 0;
struct dhcp_context *context, *tmp, **up; struct dhcp_context *context, *tmp, **up;
struct cparam param; struct cparam param;
param.newone = 0; param.newone = 0;
param.newname = 0; param.newname = 0;
param.now = now; param.now = now;
/* Various calls that we make may end up calling iface_enumerate(), which can then
call us again, We're NOT re-entrant, so ignore a second invokation. */
if (active)
return;
active = 1;
for (context = daemon->dhcp6; context; context = context->next) for (context = daemon->dhcp6; context; context = context->next)
if (context->flags & CONTEXT_CONSTRUCTED) if (context->flags & CONTEXT_CONSTRUCTED)
context->flags |= CONTEXT_GC; context->flags |= CONTEXT_GC;
@@ -727,8 +735,7 @@ void dhcp_construct_contexts(time_t now)
if (context->flags & CONTEXT_GC && !(context->flags & CONTEXT_OLD)) if (context->flags & CONTEXT_GC && !(context->flags & CONTEXT_OLD))
{ {
if ((context->flags & (CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS)) || if ((context->flags & CONTEXT_RA) || option_bool(OPT_RA))
option_bool(OPT_RA))
{ {
/* previously constructed context has gone. advertise it's demise */ /* previously constructed context has gone. advertise it's demise */
context->flags |= CONTEXT_OLD; context->flags |= CONTEXT_OLD;
@@ -772,6 +779,8 @@ void dhcp_construct_contexts(time_t now)
/* Not doing DHCP, so no lease system, manage alarms for ra only */ /* Not doing DHCP, so no lease system, manage alarms for ra only */
send_alarm(periodic_ra(now), now); send_alarm(periodic_ra(now), now);
} }
active = 0;
} }
#endif #endif
+1 -2
View File
@@ -823,7 +823,7 @@ struct dhcp_context {
#define CONTEXT_NETMASK (1u<<1) #define CONTEXT_NETMASK (1u<<1)
#define CONTEXT_BRDCAST (1u<<2) #define CONTEXT_BRDCAST (1u<<2)
#define CONTEXT_PROXY (1u<<3) #define CONTEXT_PROXY (1u<<3)
#define CONTEXT_RA_ONLY (1u<<4) #define CONTEXT_RA_ROUTER (1u<<4)
#define CONTEXT_RA_DONE (1u<<5) #define CONTEXT_RA_DONE (1u<<5)
#define CONTEXT_RA_NAME (1u<<6) #define CONTEXT_RA_NAME (1u<<6)
#define CONTEXT_RA_STATELESS (1u<<7) #define CONTEXT_RA_STATELESS (1u<<7)
@@ -838,7 +838,6 @@ struct dhcp_context {
#define CONTEXT_OLD (1u<<16) #define CONTEXT_OLD (1u<<16)
#define CONTEXT_V6 (1u<<17) #define CONTEXT_V6 (1u<<17)
struct ping_result { struct ping_result {
struct in_addr addr; struct in_addr addr;
time_t time; time_t time;
+1 -1
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>
+4 -2
View File
@@ -2583,9 +2583,11 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
if (strcmp(a[leasepos], "static") == 0) if (strcmp(a[leasepos], "static") == 0)
new->flags |= CONTEXT_STATIC | CONTEXT_DHCP; new->flags |= CONTEXT_STATIC | CONTEXT_DHCP;
else if (strcmp(a[leasepos], "ra-only") == 0 || strcmp(a[leasepos], "slaac") == 0 ) else if (strcmp(a[leasepos], "ra-only") == 0 || strcmp(a[leasepos], "slaac") == 0 )
new->flags |= CONTEXT_RA_ONLY | CONTEXT_RA; new->flags |= CONTEXT_RA;
else if (strcmp(a[leasepos], "ra-names") == 0) else if (strcmp(a[leasepos], "ra-names") == 0)
new->flags |= CONTEXT_RA_NAME | CONTEXT_RA; new->flags |= CONTEXT_RA_NAME | CONTEXT_RA;
else if (strcmp(a[leasepos], "ra-advrouter") == 0)
new->flags |= CONTEXT_RA_ROUTER | CONTEXT_RA;
else if (strcmp(a[leasepos], "ra-stateless") == 0) else if (strcmp(a[leasepos], "ra-stateless") == 0)
new->flags |= CONTEXT_RA_STATELESS | CONTEXT_DHCP | CONTEXT_RA; new->flags |= CONTEXT_RA_STATELESS | CONTEXT_DHCP | CONTEXT_RA;
else if (leasepos == 1 && inet_pton(AF_INET6, a[leasepos], &new->end6)) else if (leasepos == 1 && inet_pton(AF_INET6, a[leasepos], &new->end6))
@@ -2615,7 +2617,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
if (new->prefix != 64) if (new->prefix != 64)
{ {
if ((new->flags & (CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS))) if (new->flags & CONTEXT_RA)
ret_err(_("prefix length must be exactly 64 for RA subnets")); ret_err(_("prefix length must be exactly 64 for RA subnets"));
else if (new->flags & CONTEXT_TEMPLATE) else if (new->flags & CONTEXT_TEMPLATE)
ret_err(_("prefix length must be exactly 64 for subnet constructors")); ret_err(_("prefix length must be exactly 64 for subnet constructors"));
+1
View File
@@ -49,6 +49,7 @@ struct prefix_opt {
#define ICMP6_OPT_SOURCE_MAC 1 #define ICMP6_OPT_SOURCE_MAC 1
#define ICMP6_OPT_PREFIX 3 #define ICMP6_OPT_PREFIX 3
#define ICMP6_OPT_MTU 5 #define ICMP6_OPT_MTU 5
#define ICMP6_OPT_ADV_INTERVAL 7
#define ICMP6_OPT_RDNSS 25 #define ICMP6_OPT_RDNSS 25
#define ICMP6_OPT_DNSSL 31 #define ICMP6_OPT_DNSSL 31
+33 -7
View File
@@ -28,7 +28,7 @@
struct ra_param { struct ra_param {
time_t now; time_t now;
int ind, managed, other, found_context, first; int ind, managed, other, found_context, first, adv_router;
char *if_name; char *if_name;
struct dhcp_netid *tags; struct dhcp_netid *tags;
struct in6_addr link_local, link_global, ula; struct in6_addr link_local, link_global, ula;
@@ -226,6 +226,7 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
parm.managed = 0; parm.managed = 0;
parm.other = 0; parm.other = 0;
parm.found_context = 0; parm.found_context = 0;
parm.adv_router = 0;
parm.if_name = iface_name; parm.if_name = iface_name;
parm.first = 1; parm.first = 1;
parm.now = now; parm.now = now;
@@ -286,8 +287,7 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
setaddr6part(&local, addr6part(&local) & ~((context->prefix == 64) ? (u64)-1LL : (1LLU << (128 - context->prefix)) - 1LLU)); setaddr6part(&local, addr6part(&local) & ~((context->prefix == 64) ? (u64)-1LL : (1LLU << (128 - context->prefix)) - 1LLU));
if ((context->flags & if (context->flags & CONTEXT_RA)
(CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS)))
{ {
do_slaac = 1; do_slaac = 1;
if (context->flags & CONTEXT_DHCP) if (context->flags & CONTEXT_DHCP)
@@ -339,6 +339,17 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
if (!old_prefix && !parm.found_context) if (!old_prefix && !parm.found_context)
return; return;
/* If we're sending router address instead of prefix in at least on prefix,
include the advertisement interval option. */
if (parm.adv_router)
{
put_opt6_char(ICMP6_OPT_ADV_INTERVAL);
put_opt6_char(1);
put_opt6_short(0);
/* interval value is in milliseconds */
put_opt6_long(1000 * calc_interval(find_iface_param(iface_name)));
}
#ifdef HAVE_LINUX_NETWORK #ifdef HAVE_LINUX_NETWORK
/* Note that IPv6 MTU is not necessarilly the same as the IPv4 MTU /* Note that IPv6 MTU is not necessarilly the same as the IPv4 MTU
available from SIOCGIFMTU */ available from SIOCGIFMTU */
@@ -500,6 +511,7 @@ static int add_prefixes(struct in6_addr *local, int prefix,
int do_slaac = 0; int do_slaac = 0;
int deprecate = 0; int deprecate = 0;
int constructed = 0; int constructed = 0;
int adv_router = 0;
unsigned int time = 0xffffffff; unsigned int time = 0xffffffff;
struct dhcp_context *context; struct dhcp_context *context;
@@ -511,8 +523,7 @@ static int add_prefixes(struct in6_addr *local, int prefix,
{ {
context->saved_valid = valid; context->saved_valid = valid;
if ((context->flags & if (context->flags & CONTEXT_RA)
(CONTEXT_RA_ONLY | CONTEXT_RA_NAME | CONTEXT_RA_STATELESS)))
{ {
do_slaac = 1; do_slaac = 1;
if (context->flags & CONTEXT_DHCP) if (context->flags & CONTEXT_DHCP)
@@ -531,6 +542,16 @@ static int add_prefixes(struct in6_addr *local, int prefix,
param->other = 1; param->other = 1;
} }
/* Configured to advertise router address, not prefix. See RFC 3775 7.2
In this case we do all addresses associated with a context,
hence the real_prefix setting here. */
if (context->flags & CONTEXT_RA_ROUTER)
{
adv_router = 1;
param->adv_router = 1;
real_prefix = context->prefix;
}
/* find floor time, don't reduce below 3 * RA interval. */ /* find floor time, don't reduce below 3 * RA interval. */
if (time > context->lease_time) if (time > context->lease_time)
{ {
@@ -556,7 +577,7 @@ static int add_prefixes(struct in6_addr *local, int prefix,
/* subsequent prefixes on the same interface /* subsequent prefixes on the same interface
and subsequent instances of this prefix don't need timers. and subsequent instances of this prefix don't need timers.
Be careful not to find the same prefix twice with different Be careful not to find the same prefix twice with different
addresses. */ addresses unless we're advertising the actual addresses. */
if (!(context->flags & CONTEXT_RA_DONE)) if (!(context->flags & CONTEXT_RA_DONE))
{ {
if (!param->first) if (!param->first)
@@ -607,13 +628,18 @@ static int add_prefixes(struct in6_addr *local, int prefix,
if ((opt = expand(sizeof(struct prefix_opt)))) if ((opt = expand(sizeof(struct prefix_opt))))
{ {
/* zero net part of address */ /* zero net part of address */
if (!adv_router)
setaddr6part(local, addr6part(local) & ~((real_prefix == 64) ? (u64)-1LL : (1LLU << (128 - real_prefix)) - 1LLU)); setaddr6part(local, addr6part(local) & ~((real_prefix == 64) ? (u64)-1LL : (1LLU << (128 - real_prefix)) - 1LLU));
opt->type = ICMP6_OPT_PREFIX; opt->type = ICMP6_OPT_PREFIX;
opt->len = 4; opt->len = 4;
opt->prefix_len = real_prefix; opt->prefix_len = real_prefix;
/* autonomous only if we're not doing dhcp, always set "on-link" */ /* autonomous only if we're not doing dhcp, always set "on-link" */
opt->flags = do_slaac ? 0xC0 : 0x80; opt->flags = 0x80;
if (do_slaac)
opt->flags |= 0x40;
if (adv_router)
opt->flags |= 0x20;
opt->valid_lifetime = htonl(valid); opt->valid_lifetime = htonl(valid);
opt->preferred_lifetime = htonl(preferred); opt->preferred_lifetime = htonl(preferred);
opt->reserved = 0; opt->reserved = 0;
+167
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