mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-13 17:00:49 +00:00
Compare commits
18
Commits
v2.60
...
v2.61test2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dd88c17f15 | ||
|
|
8b37270410 | ||
|
|
760169fc43 | ||
|
|
7023e38294 | ||
|
|
a7cf58cc47 | ||
|
|
e25d1a2ea2 | ||
|
|
70969c1757 | ||
|
|
3803437dcc | ||
|
|
eabc6dd76a | ||
|
|
e28d2e2b77 | ||
|
|
96fafe2ed6 | ||
|
|
c81d390f84 | ||
|
|
08456c61f6 | ||
|
|
bc26f9a03f | ||
|
|
6ffeff86be | ||
|
|
f444cddbaf | ||
|
|
d13191a46c | ||
|
|
801ca9a7b7 |
No files matched your search
@@ -1,3 +1,15 @@
|
|||||||
|
version 2.61
|
||||||
|
Re-write interface discovery code on *BSD to use
|
||||||
|
getifaddrs. This is more portable, more straightforward,
|
||||||
|
and allows us to find the prefix length for IPv6
|
||||||
|
addresses.
|
||||||
|
|
||||||
|
Add ra-names DHCPv6 keyword which adds AAAA records
|
||||||
|
for dual-stack hosts which get IPv6 addresses via SLAAC.
|
||||||
|
|
||||||
|
Add --dhcp-duid to allow DUID-EN uids to be used.
|
||||||
|
|
||||||
|
|
||||||
version 2.60
|
version 2.60
|
||||||
Fix compilation problem in Mac OS X Lion. Thanks to Olaf
|
Fix compilation problem in Mac OS X Lion. Thanks to Olaf
|
||||||
Flebbe for the patch.
|
Flebbe for the patch.
|
||||||
|
|||||||
Vendored
+8
@@ -1,3 +1,11 @@
|
|||||||
|
dnsmasq (2.61-1) unstable; urgency=low
|
||||||
|
|
||||||
|
* New upstream.
|
||||||
|
* Provide "dump-stats" initscript method. (closes: #654656)
|
||||||
|
* Add (empty) build-indep and build-arch rules targets.
|
||||||
|
|
||||||
|
-- Simon Kelley <simon@thekelleys.org.uk> Tue, 6 Mar 2012 19:45:43 +0000
|
||||||
|
|
||||||
dnsmasq (2.60-1) unstable; urgency=low
|
dnsmasq (2.60-1) unstable; urgency=low
|
||||||
|
|
||||||
* New upstream.
|
* New upstream.
|
||||||
|
|||||||
Vendored
+4
-1
@@ -256,8 +256,11 @@ case "$1" in
|
|||||||
*) log_success_msg "(unknown)" ; exit 4 ;;
|
*) log_success_msg "(unknown)" ; exit 4 ;;
|
||||||
esac
|
esac
|
||||||
;;
|
;;
|
||||||
|
dump-stats)
|
||||||
|
kill -s USR1 `cat /var/run/dnsmasq/$NAME.pid`
|
||||||
|
;;
|
||||||
*)
|
*)
|
||||||
echo "Usage: /etc/init.d/$NAME {start|stop|restart|force-reload|status}" >&2
|
echo "Usage: /etc/init.d/$NAME {start|stop|restart|force-reload|dump-stats|status}" >&2
|
||||||
exit 3
|
exit 3
|
||||||
;;
|
;;
|
||||||
esac
|
esac
|
||||||
|
|||||||
Vendored
+3
@@ -184,7 +184,10 @@ endef
|
|||||||
# Below here is fairly generic really
|
# Below here is fairly generic really
|
||||||
|
|
||||||
binary: binary-arch binary-indep
|
binary: binary-arch binary-indep
|
||||||
|
|
||||||
build:
|
build:
|
||||||
|
build-arch:
|
||||||
|
build-indep:
|
||||||
|
|
||||||
checkroot:
|
checkroot:
|
||||||
test root = "`whoami`"
|
test root = "`whoami`"
|
||||||
|
|||||||
@@ -164,6 +164,15 @@
|
|||||||
# Do Router Advertisements, BUT NOT DHCP for this subnet.
|
# Do Router Advertisements, BUT NOT DHCP for this subnet.
|
||||||
#dhcp-range=1234::, ra-only
|
#dhcp-range=1234::, ra-only
|
||||||
|
|
||||||
|
# Do Router Advertisements, BUT NOT DHCP for this subnet, also try and
|
||||||
|
# add names to the DNS for the IPv6 address of SLAAC-configured dual-stack
|
||||||
|
# hosts. Use the DHCPv4 lease to derive the name, network segment and
|
||||||
|
# MAC address and assume that the host will also have an
|
||||||
|
# IPv6 address calculated using the SLAAC alogrithm.
|
||||||
|
# This will generate an erroneous AAAA record if a host is using privacy
|
||||||
|
# extensions or does not support IPv6. Use with care.
|
||||||
|
#dhcp-range=1234::, ra-names
|
||||||
|
|
||||||
# Do Router Advertisements, BUT NOT DHCP for this subnet.
|
# Do Router Advertisements, BUT NOT DHCP for this subnet.
|
||||||
# Set the lifetime to 46 hours. (Note: minimum lifetime is 2 hours.)
|
# Set the lifetime to 46 hours. (Note: minimum lifetime is 2 hours.)
|
||||||
#dhcp-range=1234::, ra-only, 48h
|
#dhcp-range=1234::, ra-only, 48h
|
||||||
|
|||||||
+23
-2
@@ -23,7 +23,7 @@ options. It includes a secure, read-only,
|
|||||||
TFTP server to allow net/PXE boot of DHCP hosts and also supports BOOTP.
|
TFTP server to allow net/PXE boot of DHCP hosts and also supports BOOTP.
|
||||||
.PP
|
.PP
|
||||||
Dnsmasq
|
Dnsmasq
|
||||||
supports IPv6 for DNS and TFTP, but not DHCP.
|
supports IPv6 for all functions and a minimal router-advertisemnet daemon.
|
||||||
.SH OPTIONS
|
.SH OPTIONS
|
||||||
Note that in general missing parameters are allowed and switch off
|
Note that in general missing parameters are allowed and switch off
|
||||||
functions, for instance "--pid-file" disables writing a PID file. On
|
functions, for instance "--pid-file" disables writing a PID file. On
|
||||||
@@ -556,7 +556,18 @@ the keyword
|
|||||||
which tells dnsmasq to offer Router Advertisement only on this subnet,
|
which tells dnsmasq to offer Router Advertisement only on this subnet,
|
||||||
and not DHCP. This applies to IPv6 only, see
|
and not DHCP. This applies to IPv6 only, see
|
||||||
.B enable-ra
|
.B enable-ra
|
||||||
for details.
|
for details. Instead, the keyword
|
||||||
|
.B ra-names
|
||||||
|
may be used. This does the same at ra-only, but also enables a mode
|
||||||
|
which gives DNS names to dual-stack hosts which do SLAAC for
|
||||||
|
IPv6. Dnsmasq uses the hosts IPv4 lease to derive the name, network
|
||||||
|
segment and MAC address and assumes that the host will also have an
|
||||||
|
IPv6 address calculated using the SLAAC alogrithm, on the same network
|
||||||
|
segment. An AAAA record is added to the DNS for this IPv6
|
||||||
|
address. Note that this is only happens for directly-connected
|
||||||
|
networks, (not one doing DHCP via a relay) and it will generate an
|
||||||
|
erroneous AAAA record if a host is using privacy extensions or does
|
||||||
|
not support IPv6. Use with care.
|
||||||
|
|
||||||
The interface:<interface name> section is not normally used. See the
|
The interface:<interface name> section is not normally used. See the
|
||||||
NOTES section for details of this.
|
NOTES section for details of this.
|
||||||
@@ -1031,6 +1042,16 @@ the tags used to determine them.
|
|||||||
.B \-l, --dhcp-leasefile=<path>
|
.B \-l, --dhcp-leasefile=<path>
|
||||||
Use the specified file to store DHCP lease information.
|
Use the specified file to store DHCP lease information.
|
||||||
.TP
|
.TP
|
||||||
|
.B --dhcp-duid=<enterprise-id>,<uid>
|
||||||
|
(IPv6 only) Specify the server persistent UID which the DHCPv6 server
|
||||||
|
will use. This option is not normally required as dnsmasq creates a
|
||||||
|
DUID automatically when it is first needed. When given, this option
|
||||||
|
provides dnsmasq the data required to create a DUID-EN type DUID. Note
|
||||||
|
that once set, the DUID is stored in the lease database, so to change between DUID-EN and
|
||||||
|
automatically created DUIDs or vice-versa, the lease database must be
|
||||||
|
re-intialised. The enterprise-id is assigned by IANA, and the uid is a
|
||||||
|
string of hex octets unique to a particular device.
|
||||||
|
.TP
|
||||||
.B \-6 --dhcp-script=<path>
|
.B \-6 --dhcp-script=<path>
|
||||||
Whenever a new DHCP lease is created, or an old one destroyed, the
|
Whenever a new DHCP lease is created, or an old one destroyed, the
|
||||||
executable specified by this option is run. <path>
|
executable specified by this option is run. <path>
|
||||||
|
|||||||
@@ -17,19 +17,9 @@
|
|||||||
#include "dnsmasq.h"
|
#include "dnsmasq.h"
|
||||||
|
|
||||||
#if defined(HAVE_BSD_NETWORK) || defined(HAVE_SOLARIS_NETWORK)
|
#if defined(HAVE_BSD_NETWORK) || defined(HAVE_SOLARIS_NETWORK)
|
||||||
|
#include <ifaddrs.h>
|
||||||
static struct iovec ifconf = {
|
|
||||||
.iov_base = NULL,
|
|
||||||
.iov_len = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
static struct iovec ifreq = {
|
|
||||||
.iov_base = NULL,
|
|
||||||
.iov_len = 0
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__)
|
#if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__)
|
||||||
|
|
||||||
#include <sys/sysctl.h>
|
#include <sys/sysctl.h>
|
||||||
#include <net/route.h>
|
#include <net/route.h>
|
||||||
#include <net/if_dl.h>
|
#include <net/if_dl.h>
|
||||||
@@ -50,8 +40,12 @@ int arp_enumerate(void *parm, int (*callback)())
|
|||||||
struct rt_msghdr *rtm;
|
struct rt_msghdr *rtm;
|
||||||
struct sockaddr_inarp *sin2;
|
struct sockaddr_inarp *sin2;
|
||||||
struct sockaddr_dl *sdl;
|
struct sockaddr_dl *sdl;
|
||||||
|
struct iovec buff;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
buff.iov_base = NULL;
|
||||||
|
buff.iov_len = 0;
|
||||||
|
|
||||||
mib[0] = CTL_NET;
|
mib[0] = CTL_NET;
|
||||||
mib[1] = PF_ROUTE;
|
mib[1] = PF_ROUTE;
|
||||||
mib[2] = 0;
|
mib[2] = 0;
|
||||||
@@ -67,9 +61,9 @@ int arp_enumerate(void *parm, int (*callback)())
|
|||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
if (!expand_buf(&ifconf, needed))
|
if (!expand_buf(&buff, needed))
|
||||||
return 0;
|
return 0;
|
||||||
if ((rc = sysctl(mib, 6, ifconf.iov_base, &needed, NULL, 0)) == 0 ||
|
if ((rc = sysctl(mib, 6, buff.iov_base, &needed, NULL, 0)) == 0 ||
|
||||||
errno != ENOMEM)
|
errno != ENOMEM)
|
||||||
break;
|
break;
|
||||||
needed += needed / 8;
|
needed += needed / 8;
|
||||||
@@ -77,7 +71,7 @@ int arp_enumerate(void *parm, int (*callback)())
|
|||||||
if (rc == -1)
|
if (rc == -1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (next = ifconf.iov_base ; next < (char *)ifconf.iov_base + needed; next += rtm->rtm_msglen)
|
for (next = buff.iov_base ; next < (char *)buff.iov_base + needed; next += rtm->rtm_msglen)
|
||||||
{
|
{
|
||||||
rtm = (struct rt_msghdr *)next;
|
rtm = (struct rt_msghdr *)next;
|
||||||
sin2 = (struct sockaddr_inarp *)(rtm + 1);
|
sin2 = (struct sockaddr_inarp *)(rtm + 1);
|
||||||
@@ -88,18 +82,13 @@ int arp_enumerate(void *parm, int (*callback)())
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
int iface_enumerate(int family, void *parm, int (*callback)())
|
int iface_enumerate(int family, void *parm, int (*callback)())
|
||||||
{
|
{
|
||||||
char *ptr;
|
struct ifaddrs *head, *addrs;
|
||||||
struct ifreq *ifr;
|
int errsav, ret = 0;
|
||||||
struct ifconf ifc;
|
|
||||||
int fd, errsav, ret = 0;
|
|
||||||
int lastlen = 0;
|
|
||||||
size_t len = 0;
|
|
||||||
|
|
||||||
if (family == AF_UNSPEC)
|
if (family == AF_UNSPEC)
|
||||||
#if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__)
|
#if defined(HAVE_BSD_NETWORK) && !defined(__APPLE__)
|
||||||
@@ -112,85 +101,52 @@ int iface_enumerate(int family, void *parm, int (*callback)())
|
|||||||
if (family == AF_LOCAL)
|
if (family == AF_LOCAL)
|
||||||
family = AF_LINK;
|
family = AF_LINK;
|
||||||
|
|
||||||
if ((fd = socket(PF_INET, SOCK_DGRAM, 0)) == -1)
|
if (getifaddrs(&head) == -1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
while(1)
|
for (addrs = head; addrs; addrs = addrs->ifa_next)
|
||||||
{
|
{
|
||||||
len += 10*sizeof(struct ifreq);
|
if (addrs->ifa_addr->sa_family == family)
|
||||||
|
|
||||||
if (!expand_buf(&ifconf, len))
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
ifc.ifc_len = len;
|
|
||||||
ifc.ifc_buf = ifconf.iov_base;
|
|
||||||
|
|
||||||
if (ioctl(fd, SIOCGIFCONF, &ifc) == -1)
|
|
||||||
{
|
{
|
||||||
if (errno != EINVAL || lastlen != 0)
|
int iface_index = if_nametoindex(addrs->ifa_name);
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (ifc.ifc_len == lastlen)
|
|
||||||
break; /* got a big enough buffer now */
|
|
||||||
lastlen = ifc.ifc_len;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (ptr = ifc.ifc_buf; ptr < (char *)(ifc.ifc_buf + ifc.ifc_len); ptr += len)
|
if (iface_index == 0)
|
||||||
{
|
continue;
|
||||||
/* subsequent entries may not be aligned, so copy into
|
|
||||||
an aligned buffer to avoid nasty complaints about
|
|
||||||
unaligned accesses. */
|
|
||||||
|
|
||||||
len = sizeof(struct ifreq);
|
|
||||||
|
|
||||||
#ifdef HAVE_SOCKADDR_SA_LEN
|
|
||||||
ifr = (struct ifreq *)ptr;
|
|
||||||
if (ifr->ifr_addr.sa_len > sizeof(ifr->ifr_ifru))
|
|
||||||
len = ifr->ifr_addr.sa_len + offsetof(struct ifreq, ifr_ifru);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!expand_buf(&ifreq, len))
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
ifr = (struct ifreq *)ifreq.iov_base;
|
|
||||||
memcpy(ifr, ptr, len);
|
|
||||||
|
|
||||||
if (ifr->ifr_addr.sa_family == family)
|
|
||||||
{
|
|
||||||
if (family == AF_INET)
|
if (family == AF_INET)
|
||||||
{
|
{
|
||||||
struct in_addr addr, netmask, broadcast;
|
struct in_addr addr, netmask, broadcast;
|
||||||
broadcast.s_addr = 0;
|
addr = ((struct sockaddr_in *) addrs->ifa_addr)->sin_addr;
|
||||||
addr = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr;
|
netmask = ((struct sockaddr_in *) addrs->ifa_netmask)->sin_addr;
|
||||||
if (ioctl(fd, SIOCGIFNETMASK, ifr) == -1)
|
broadcast = ((struct sockaddr_in *) addrs->ifa_broadaddr)->sin_addr;
|
||||||
continue;
|
if (!((*callback)(addr, iface_index, netmask, broadcast, parm)))
|
||||||
netmask = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr;
|
|
||||||
if (ioctl(fd, SIOCGIFBRDADDR, ifr) != -1)
|
|
||||||
broadcast = ((struct sockaddr_in *) &ifr->ifr_addr)->sin_addr;
|
|
||||||
if (!((*callback)(addr,
|
|
||||||
(int)if_nametoindex(ifr->ifr_name),
|
|
||||||
netmask, broadcast,
|
|
||||||
parm)))
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
else if (family == AF_INET6)
|
else if (family == AF_INET6)
|
||||||
{
|
{
|
||||||
struct in6_addr *addr = &((struct sockaddr_in6 *)&ifr->ifr_addr)->sin6_addr;
|
struct in6_addr *addr = &((struct sockaddr_in6 *) addrs->ifa_addr)->sin6_addr;
|
||||||
|
unsigned char *netmask = (unsigned char *) &((struct sockaddr_in6 *) addrs->ifa_netmask)->sin6_addr;
|
||||||
|
int scope_id = ((struct sockaddr_in6 *) addrs->ifa_addr)->sin6_scope_id;
|
||||||
|
int i, j, prefix = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < IN6ADDRSZ; i++, prefix += 8)
|
||||||
|
if (netmask[i] != 0xff)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (i != IN6ADDRSZ && netmask[i])
|
||||||
|
for (j = 7; j > 0; j--, prefix++)
|
||||||
|
if ((netmask[i] & (1 << j)) == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
/* voodoo to clear interface field in address */
|
/* voodoo to clear interface field in address */
|
||||||
if (!option_bool(OPT_NOWILD) && IN6_IS_ADDR_LINKLOCAL(addr))
|
if (!option_bool(OPT_NOWILD) && IN6_IS_ADDR_LINKLOCAL(addr))
|
||||||
{
|
{
|
||||||
addr->s6_addr[2] = 0;
|
addr->s6_addr[2] = 0;
|
||||||
addr->s6_addr[3] = 0;
|
addr->s6_addr[3] = 0;
|
||||||
}
|
}
|
||||||
/* We have no way to determine the prefix, so we assume it's 64 for now....... */
|
|
||||||
if (!((*callback)(addr, 64,
|
if (!((*callback)(addr, prefix, scope_id, iface_index, 0, parm)))
|
||||||
(int)((struct sockaddr_in6 *)&ifr->ifr_addr)->sin6_scope_id,
|
|
||||||
(int)if_nametoindex(ifr->ifr_name), 0,
|
|
||||||
parm)))
|
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -198,9 +154,9 @@ int iface_enumerate(int family, void *parm, int (*callback)())
|
|||||||
else if (family == AF_LINK)
|
else if (family == AF_LINK)
|
||||||
{
|
{
|
||||||
/* Assume ethernet again here */
|
/* Assume ethernet again here */
|
||||||
struct sockaddr_dl *sdl = (struct sockaddr_dl *)&ifr->ifr_addr;
|
struct sockaddr_dl *sdl = (struct sockaddr_dl *) addrs->ifa_addr;
|
||||||
if (sdl->sdl_alen != 0 && !((*callback)((int)if_nametoindex(ifr->ifr_name),
|
if (sdl->sdl_alen != 0 &&
|
||||||
ARPHRD_ETHER, LLADDR(sdl), sdl->sdl_alen, parm)))
|
!((*callback)(iface_index, ARPHRD_ETHER, LLADDR(sdl), sdl->sdl_alen, parm)))
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -211,7 +167,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
|
|||||||
|
|
||||||
err:
|
err:
|
||||||
errsav = errno;
|
errsav = errno;
|
||||||
close(fd);
|
freeifaddrs(head);
|
||||||
errno = errsav;
|
errno = errsav;
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
@@ -228,13 +184,10 @@ void init_bpf(void)
|
|||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/* useful size which happens to be sufficient */
|
sprintf(daemon->dhcp_buff, "/dev/bpf%d", i++);
|
||||||
if (expand_buf(&ifreq, sizeof(struct ifreq)))
|
if ((daemon->dhcp_raw_fd = open(daemon->dhcp_buff, O_RDWR, 0)) != -1)
|
||||||
{
|
|
||||||
sprintf(ifreq.iov_base, "/dev/bpf%d", i++);
|
|
||||||
if ((daemon->dhcp_raw_fd = open(ifreq.iov_base, O_RDWR, 0)) != -1)
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
if (errno != EBUSY)
|
if (errno != EBUSY)
|
||||||
die(_("cannot create DHCP BPF socket: %s"), NULL, EC_BADNET);
|
die(_("cannot create DHCP BPF socket: %s"), NULL, EC_BADNET);
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-4
@@ -396,7 +396,7 @@ void emit_dbus_signal(int action, struct dhcp_lease *lease, char *hostname)
|
|||||||
DBusConnection *connection = (DBusConnection *)daemon->dbus;
|
DBusConnection *connection = (DBusConnection *)daemon->dbus;
|
||||||
DBusMessage* message = NULL;
|
DBusMessage* message = NULL;
|
||||||
DBusMessageIter args;
|
DBusMessageIter args;
|
||||||
char *action_str, *addr, *mac = daemon->namebuff;
|
char *action_str, *mac = daemon->namebuff;
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -406,9 +406,20 @@ void emit_dbus_signal(int action, struct dhcp_lease *lease, char *hostname)
|
|||||||
if (!hostname)
|
if (!hostname)
|
||||||
hostname = "";
|
hostname = "";
|
||||||
|
|
||||||
|
#ifdef HAVE_DHCP6
|
||||||
|
if (lease->flags & (LEASE_TA | LEASE_NA))
|
||||||
|
{
|
||||||
|
print_mac(mac, lease->clid, lease->clid_len);
|
||||||
|
inet_ntop(AF_INET6, lease->hwaddr, daemon->addrbuff, ADDRSTRLEN);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
p = extended_hwaddr(lease->hwaddr_type, lease->hwaddr_len,
|
p = extended_hwaddr(lease->hwaddr_type, lease->hwaddr_len,
|
||||||
lease->hwaddr, lease->clid_len, lease->clid, &i);
|
lease->hwaddr, lease->clid_len, lease->clid, &i);
|
||||||
print_mac(mac, p, i);
|
print_mac(mac, p, i);
|
||||||
|
inet_ntop(AF_INET, &lease->addr, daemon->addrbuff, ADDRSTRLEN);
|
||||||
|
}
|
||||||
|
|
||||||
if (action == ACTION_DEL)
|
if (action == ACTION_DEL)
|
||||||
action_str = "DhcpLeaseDeleted";
|
action_str = "DhcpLeaseDeleted";
|
||||||
@@ -419,14 +430,12 @@ void emit_dbus_signal(int action, struct dhcp_lease *lease, char *hostname)
|
|||||||
else
|
else
|
||||||
return;
|
return;
|
||||||
|
|
||||||
addr = inet_ntoa(lease->addr);
|
|
||||||
|
|
||||||
if (!(message = dbus_message_new_signal(DNSMASQ_PATH, DNSMASQ_SERVICE, action_str)))
|
if (!(message = dbus_message_new_signal(DNSMASQ_PATH, DNSMASQ_SERVICE, action_str)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
dbus_message_iter_init_append(message, &args);
|
dbus_message_iter_init_append(message, &args);
|
||||||
|
|
||||||
if (dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &addr) &&
|
if (dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &daemon->addrbuff) &&
|
||||||
dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &mac) &&
|
dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &mac) &&
|
||||||
dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &hostname))
|
dbus_message_iter_append_basic(&args, DBUS_TYPE_STRING, &hostname))
|
||||||
dbus_connection_send(connection, message, NULL);
|
dbus_connection_send(connection, message, NULL);
|
||||||
|
|||||||
+13
@@ -364,6 +364,18 @@ struct dhcp_config *find_config6(struct dhcp_config *configs,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void make_duid(time_t now)
|
void make_duid(time_t now)
|
||||||
|
{
|
||||||
|
if (daemon->duid_config)
|
||||||
|
{
|
||||||
|
unsigned char *p;
|
||||||
|
|
||||||
|
daemon->duid = p = safe_malloc(daemon->duid_config_len + 6);
|
||||||
|
daemon->duid_len = daemon->duid_config_len + 6;
|
||||||
|
PUTSHORT(2, p); /* DUID_EN */
|
||||||
|
PUTLONG(daemon->duid_enterprise, p);
|
||||||
|
memcpy(p, daemon->duid_config, daemon->duid_config_len);
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
/* rebase epoch to 1/1/2000 */
|
/* rebase epoch to 1/1/2000 */
|
||||||
time_t newnow = now - 946684800;
|
time_t newnow = now - 946684800;
|
||||||
@@ -373,6 +385,7 @@ void make_duid(time_t now)
|
|||||||
if(!daemon->duid)
|
if(!daemon->duid)
|
||||||
die("Cannot create DHCPv6 server DUID: %s", NULL, EC_MISC);
|
die("Cannot create DHCPv6 server DUID: %s", NULL, EC_MISC);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int make_duid1(int index, unsigned int type, char *mac, size_t maclen, void *parm)
|
static int make_duid1(int index, unsigned int type, char *mac, size_t maclen, void *parm)
|
||||||
{
|
{
|
||||||
|
|||||||
+20
-5
@@ -106,17 +106,15 @@ int main (int argc, char **argv)
|
|||||||
else
|
else
|
||||||
open("/dev/null", O_RDWR);
|
open("/dev/null", O_RDWR);
|
||||||
|
|
||||||
#ifdef HAVE_LINUX_NETWORK
|
#ifndef HAVE_LINUX_NETWORK
|
||||||
netlink_init();
|
# if !(defined(IP_RECVDSTADDR) && defined(IP_RECVIF) && defined(IP_SENDSRCADDR))
|
||||||
#elif !(defined(IP_RECVDSTADDR) && \
|
|
||||||
defined(IP_RECVIF) && \
|
|
||||||
defined(IP_SENDSRCADDR))
|
|
||||||
if (!option_bool(OPT_NOWILD))
|
if (!option_bool(OPT_NOWILD))
|
||||||
{
|
{
|
||||||
bind_fallback = 1;
|
bind_fallback = 1;
|
||||||
set_option_bool(OPT_NOWILD);
|
set_option_bool(OPT_NOWILD);
|
||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef HAVE_TFTP
|
#ifndef HAVE_TFTP
|
||||||
if (daemon->tftp_unlimited || daemon->tftp_interfaces)
|
if (daemon->tftp_unlimited || daemon->tftp_interfaces)
|
||||||
@@ -180,10 +178,25 @@ int main (int argc, char **argv)
|
|||||||
if (daemon->dhcp6)
|
if (daemon->dhcp6)
|
||||||
dhcp6_init();
|
dhcp6_init();
|
||||||
|
|
||||||
|
# endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_LINUX_NETWORK
|
||||||
|
/* After lease_init */
|
||||||
|
netlink_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_DHCP6
|
||||||
|
/* after netlink_init */
|
||||||
if (daemon->ra_contexts || daemon->dhcp6)
|
if (daemon->ra_contexts || daemon->dhcp6)
|
||||||
join_multicast();
|
join_multicast();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_DHCP
|
||||||
|
/* after netlink_init */
|
||||||
|
if (daemon->dhcp || daemon->dhcp6)
|
||||||
|
lease_find_interfaces(now);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!enumerate_interfaces())
|
if (!enumerate_interfaces())
|
||||||
@@ -552,6 +565,8 @@ int main (int argc, char **argv)
|
|||||||
my_syslog(MS_DHCP | LOG_INFO,
|
my_syslog(MS_DHCP | LOG_INFO,
|
||||||
(dhcp_tmp->flags & CONTEXT_STATIC) ?
|
(dhcp_tmp->flags & CONTEXT_STATIC) ?
|
||||||
_("DHCP, static leases only on %.0s%s, lease time %s") :
|
_("DHCP, static leases only on %.0s%s, lease time %s") :
|
||||||
|
(dhcp_tmp->flags & CONTEXT_RA_NAME) ?
|
||||||
|
_("router advertisement with DHCPv4-derived names on %.0s%s, lifetime %s") :
|
||||||
(dhcp_tmp->flags & CONTEXT_RA_ONLY) ?
|
(dhcp_tmp->flags & CONTEXT_RA_ONLY) ?
|
||||||
_("router advertisement only on %.0s%s, lifetime %s") :
|
_("router advertisement only on %.0s%s, lifetime %s") :
|
||||||
(dhcp_tmp->flags & CONTEXT_PROXY) ?
|
(dhcp_tmp->flags & CONTEXT_PROXY) ?
|
||||||
|
|||||||
@@ -621,6 +621,7 @@ struct dhcp_context {
|
|||||||
#define CONTEXT_PROXY 8
|
#define CONTEXT_PROXY 8
|
||||||
#define CONTEXT_RA_ONLY 16
|
#define CONTEXT_RA_ONLY 16
|
||||||
#define CONTEXT_RA_DONE 32
|
#define CONTEXT_RA_DONE 32
|
||||||
|
#define CONTEXT_RA_NAME 64
|
||||||
|
|
||||||
struct ping_result {
|
struct ping_result {
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
@@ -629,6 +630,13 @@ struct ping_result {
|
|||||||
struct ping_result *next;
|
struct ping_result *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct subnet_map {
|
||||||
|
int iface;
|
||||||
|
struct in6_addr subnet;
|
||||||
|
struct subnet_map *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
struct tftp_file {
|
struct tftp_file {
|
||||||
int refcount, fd;
|
int refcount, fd;
|
||||||
off_t size;
|
off_t size;
|
||||||
@@ -723,6 +731,8 @@ extern struct daemon {
|
|||||||
struct tftp_prefix *if_prefix; /* per-interface TFTP prefixes */
|
struct tftp_prefix *if_prefix; /* per-interface TFTP prefixes */
|
||||||
struct interface_list *tftp_interfaces; /* interfaces for limited TFTP service */
|
struct interface_list *tftp_interfaces; /* interfaces for limited TFTP service */
|
||||||
int tftp_unlimited;
|
int tftp_unlimited;
|
||||||
|
unsigned int duid_enterprise, duid_config_len;
|
||||||
|
unsigned char *duid_config;
|
||||||
|
|
||||||
/* globally used stuff for DNS */
|
/* globally used stuff for DNS */
|
||||||
char *packet; /* packet buffer */
|
char *packet; /* packet buffer */
|
||||||
@@ -948,6 +958,7 @@ void lease_prune(struct dhcp_lease *target, time_t now);
|
|||||||
void lease_update_from_configs(void);
|
void lease_update_from_configs(void);
|
||||||
int do_script_run(time_t now);
|
int do_script_run(time_t now);
|
||||||
void rerun_scripts(void);
|
void rerun_scripts(void);
|
||||||
|
void lease_find_interfaces(time_t now);
|
||||||
#ifdef HAVE_SCRIPT
|
#ifdef HAVE_SCRIPT
|
||||||
void lease_add_extradata(struct dhcp_lease *lease, unsigned char *data,
|
void lease_add_extradata(struct dhcp_lease *lease, unsigned char *data,
|
||||||
unsigned int len, int delim);
|
unsigned int len, int delim);
|
||||||
@@ -1083,4 +1094,5 @@ void ra_init(time_t now);
|
|||||||
void icmp6_packet(void);
|
void icmp6_packet(void);
|
||||||
time_t periodic_ra(time_t now);
|
time_t periodic_ra(time_t now);
|
||||||
void ra_start_unsolicted(time_t now);
|
void ra_start_unsolicted(time_t now);
|
||||||
|
struct subnet_map *build_subnet_map(void);
|
||||||
#endif
|
#endif
|
||||||
+102
-10
@@ -175,16 +175,6 @@ void lease_init(time_t now)
|
|||||||
file_dirty = 0;
|
file_dirty = 0;
|
||||||
lease_prune(NULL, now);
|
lease_prune(NULL, now);
|
||||||
dns_dirty = 1;
|
dns_dirty = 1;
|
||||||
|
|
||||||
#ifdef HAVE_DHCP6
|
|
||||||
/* If we're not doing DHCPv6, and there are not v6 leases, don't add the DUID to the database */
|
|
||||||
if (!daemon->duid && daemon->dhcp6)
|
|
||||||
{
|
|
||||||
file_dirty = 1;
|
|
||||||
make_duid(now);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void lease_update_from_configs(void)
|
void lease_update_from_configs(void)
|
||||||
@@ -340,20 +330,122 @@ void lease_update_file(time_t now)
|
|||||||
alarm((unsigned)difftime(next_event, now));
|
alarm((unsigned)difftime(next_event, now));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static int find_interface_v4(struct in_addr local, int if_index,
|
||||||
|
struct in_addr netmask, struct in_addr broadcast, void *vparam)
|
||||||
|
{
|
||||||
|
struct dhcp_lease *lease;
|
||||||
|
|
||||||
|
(void) broadcast;
|
||||||
|
(void) vparam;
|
||||||
|
|
||||||
|
for (lease = leases; lease; lease = lease->next)
|
||||||
|
if (!(lease->flags & (LEASE_TA | LEASE_NA)))
|
||||||
|
if (is_same_net(local, lease->addr, netmask))
|
||||||
|
lease->last_interface = if_index;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_DHCP6
|
||||||
|
static int find_interface_v6(struct in6_addr *local, int prefix,
|
||||||
|
int scope, int if_index, int dad, void *vparam)
|
||||||
|
{
|
||||||
|
struct dhcp_lease *lease;
|
||||||
|
|
||||||
|
(void) scope;
|
||||||
|
(void) vparam;
|
||||||
|
(void)dad;
|
||||||
|
|
||||||
|
for (lease = leases; lease; lease = lease->next)
|
||||||
|
if ((lease->flags & (LEASE_TA | LEASE_NA)))
|
||||||
|
if (is_same_net6(local, (struct in6_addr *)&lease->hwaddr, prefix))
|
||||||
|
lease->last_interface = if_index;
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* Find interfaces associated with leases at start-up. This gets updated as
|
||||||
|
we do DHCP transactions, but information about directly-connected subnets
|
||||||
|
is useful from scrips and necessary for determining SLAAC addresses from
|
||||||
|
start-time. */
|
||||||
|
void lease_find_interfaces(time_t now)
|
||||||
|
{
|
||||||
|
iface_enumerate(AF_INET, NULL, find_interface_v4);
|
||||||
|
#ifdef HAVE_DHCP6
|
||||||
|
iface_enumerate(AF_INET6, NULL, find_interface_v6);
|
||||||
|
|
||||||
|
/* If we're not doing DHCPv6, and there are not v6 leases, don't add the DUID to the database */
|
||||||
|
if (!daemon->duid && daemon->dhcp6)
|
||||||
|
{
|
||||||
|
file_dirty = 1;
|
||||||
|
make_duid(now);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void lease_update_dns(void)
|
void lease_update_dns(void)
|
||||||
{
|
{
|
||||||
struct dhcp_lease *lease;
|
struct dhcp_lease *lease;
|
||||||
|
|
||||||
if (daemon->port != 0 && dns_dirty)
|
if (daemon->port != 0 && dns_dirty)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_DHCP6
|
||||||
|
struct subnet_map *subnets = build_subnet_map();
|
||||||
|
#endif
|
||||||
|
|
||||||
cache_unhash_dhcp();
|
cache_unhash_dhcp();
|
||||||
|
|
||||||
for (lease = leases; lease; lease = lease->next)
|
for (lease = leases; lease; lease = lease->next)
|
||||||
{
|
{
|
||||||
int prot = AF_INET;
|
int prot = AF_INET;
|
||||||
|
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
if (lease->flags & (LEASE_TA | LEASE_NA))
|
if (lease->flags & (LEASE_TA | LEASE_NA))
|
||||||
prot = AF_INET6;
|
prot = AF_INET6;
|
||||||
|
else if (lease->hostname || lease->fqdn)
|
||||||
|
{
|
||||||
|
struct subnet_map *map;
|
||||||
|
for (map = subnets; map; map = map->next)
|
||||||
|
if (lease->last_interface == map->iface)
|
||||||
|
{
|
||||||
|
struct in6_addr addr = map->subnet;
|
||||||
|
if (lease->hwaddr_len == 6 &&
|
||||||
|
(lease->hwaddr_type == ARPHRD_ETHER || lease->hwaddr_type == ARPHRD_IEEE802))
|
||||||
|
{
|
||||||
|
/* convert MAC address to EUI-64 */
|
||||||
|
memcpy(&addr.s6_addr[8], lease->hwaddr, 3);
|
||||||
|
memcpy(&addr.s6_addr[13], &lease->hwaddr[3], 3);
|
||||||
|
addr.s6_addr[11] = 0xff;
|
||||||
|
addr.s6_addr[12] = 0xfe;
|
||||||
|
}
|
||||||
|
#if defined(ARPHRD_EUI64)
|
||||||
|
else if (lease->hwaddr_len == 8 &&
|
||||||
|
lease->hwaddr_type == ARPHRD_EUI64)
|
||||||
|
memcpy(&addr.s6_addr[8], lease->hwaddr, 8);
|
||||||
|
#endif
|
||||||
|
#if defined(ARPHRD_IEEE1394) && defined(ARPHRD_EUI64)
|
||||||
|
else if (lease->clid_len == 9 &&
|
||||||
|
lease->clid[0] == ARPHRD_EUI64 &&
|
||||||
|
lease->hwaddr_type == ARPHRD_IEEE1394)
|
||||||
|
/* firewire has EUI-64 identifier as clid */
|
||||||
|
memcpy(&addr.s6_addr[8], &lease->clid[1], 8);
|
||||||
|
#endif
|
||||||
|
else
|
||||||
|
continue;
|
||||||
|
|
||||||
|
addr.s6_addr[8] ^= 0x02;
|
||||||
|
|
||||||
|
if (lease->fqdn)
|
||||||
|
cache_add_dhcp_entry(lease->fqdn, AF_INET6, (struct all_addr *)&addr, lease->expires);
|
||||||
|
if (!option_bool(OPT_DHCP_FQDN) && lease->hostname)
|
||||||
|
cache_add_dhcp_entry(lease->hostname, AF_INET6, (struct all_addr *)&addr, lease->expires);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (lease->fqdn)
|
if (lease->fqdn)
|
||||||
|
|||||||
+24
-1
@@ -115,6 +115,7 @@ struct myoption {
|
|||||||
#define LOPT_FQDN 304
|
#define LOPT_FQDN 304
|
||||||
#define LOPT_LUASCRIPT 305
|
#define LOPT_LUASCRIPT 305
|
||||||
#define LOPT_RA 306
|
#define LOPT_RA 306
|
||||||
|
#define LOPT_DUID 307
|
||||||
|
|
||||||
#ifdef HAVE_GETOPT_LONG
|
#ifdef HAVE_GETOPT_LONG
|
||||||
static const struct option opts[] =
|
static const struct option opts[] =
|
||||||
@@ -235,6 +236,7 @@ static const struct myoption opts[] =
|
|||||||
{ "dhcp-client-update", 0, 0, LOPT_FQDN },
|
{ "dhcp-client-update", 0, 0, LOPT_FQDN },
|
||||||
{ "dhcp-luascript", 1, 0, LOPT_LUASCRIPT },
|
{ "dhcp-luascript", 1, 0, LOPT_LUASCRIPT },
|
||||||
{ "enable-ra", 0, 0, LOPT_RA },
|
{ "enable-ra", 0, 0, LOPT_RA },
|
||||||
|
{ "dhcp-duid", 1, 0, LOPT_DUID },
|
||||||
{ NULL, 0, 0, 0 }
|
{ NULL, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -362,6 +364,7 @@ static struct {
|
|||||||
{ LOPT_CONNTRACK, OPT_CONNTRACK, NULL, gettext_noop("Copy connection-track mark from queries to upstream connections."), NULL },
|
{ LOPT_CONNTRACK, OPT_CONNTRACK, NULL, gettext_noop("Copy connection-track mark from queries to upstream connections."), NULL },
|
||||||
{ LOPT_FQDN, OPT_FQDN_UPDATE, NULL, gettext_noop("Allow DHCP clients to do their own DDNS updates."), NULL },
|
{ LOPT_FQDN, OPT_FQDN_UPDATE, NULL, gettext_noop("Allow DHCP clients to do their own DDNS updates."), NULL },
|
||||||
{ LOPT_RA, OPT_RA, NULL, gettext_noop("Send router-advertisements for interfaces doing DHCPv6"), NULL },
|
{ LOPT_RA, OPT_RA, NULL, gettext_noop("Send router-advertisements for interfaces doing DHCPv6"), NULL },
|
||||||
|
{ LOPT_DUID, ARG_ONE, "<enterprise>,<duid>", gettext_noop("Specify DUID_EN-type DHCPv6 server DUID"), NULL },
|
||||||
{ 0, 0, NULL, NULL, NULL }
|
{ 0, 0, NULL, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2345,6 +2348,11 @@ static char *one_opt(int option, char *arg, char *gen_prob, int command_line)
|
|||||||
memcpy(&new->end6, &new->start6, IN6ADDRSZ);
|
memcpy(&new->end6, &new->start6, IN6ADDRSZ);
|
||||||
new->flags |= CONTEXT_RA_ONLY;
|
new->flags |= CONTEXT_RA_ONLY;
|
||||||
}
|
}
|
||||||
|
else if (strcmp(a[1], "ra-names") == 0)
|
||||||
|
{
|
||||||
|
memcpy(&new->end6, &new->start6, IN6ADDRSZ);
|
||||||
|
new->flags |= CONTEXT_RA_NAME | CONTEXT_RA_ONLY;
|
||||||
|
}
|
||||||
else if (!inet_pton(AF_INET6, a[1], &new->end6))
|
else if (!inet_pton(AF_INET6, a[1], &new->end6))
|
||||||
option = '?';
|
option = '?';
|
||||||
|
|
||||||
@@ -2370,7 +2378,9 @@ static char *one_opt(int option, char *arg, char *gen_prob, int command_line)
|
|||||||
{
|
{
|
||||||
new->prefix = pref;
|
new->prefix = pref;
|
||||||
leasepos = 3;
|
leasepos = 3;
|
||||||
if (new->prefix < 64)
|
if ((new->flags & CONTEXT_RA_ONLY) && new->prefix != 64)
|
||||||
|
problem = _("prefix must be exactly 64 for RA subnets");
|
||||||
|
else if (new->prefix < 64)
|
||||||
problem = _("prefix must be at least 64");
|
problem = _("prefix must be at least 64");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -3040,6 +3050,19 @@ static char *one_opt(int option, char *arg, char *gen_prob, int command_line)
|
|||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_DHCP6
|
||||||
|
case LOPT_DUID: /* --dhcp-duid */
|
||||||
|
if (!(comma = split(arg)) || !atoi_check(arg, (int *)&daemon->duid_enterprise))
|
||||||
|
problem = _("bad DUID");
|
||||||
|
else
|
||||||
|
{
|
||||||
|
daemon->duid_config_len = parse_hex(comma,(unsigned char *)comma, strlen(comma), NULL, NULL);
|
||||||
|
daemon->duid_config = opt_malloc(daemon->duid_config_len);
|
||||||
|
memcpy(daemon->duid_config, comma, daemon->duid_config_len);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case 'V': /* --alias */
|
case 'V': /* --alias */
|
||||||
{
|
{
|
||||||
char *dash, *a[3] = { NULL, NULL, NULL };
|
char *dash, *a[3] = { NULL, NULL, NULL };
|
||||||
|
|||||||
+69
@@ -426,4 +426,73 @@ static int iface_search(struct in6_addr *local, int prefix,
|
|||||||
return 1; /* keep searching */
|
return 1; /* keep searching */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int add_subnet(struct in6_addr *local, int prefix,
|
||||||
|
int scope, int if_index, int dad, void *vparam)
|
||||||
|
{
|
||||||
|
struct dhcp_context *context;
|
||||||
|
struct subnet_map **subnets = vparam;
|
||||||
|
struct subnet_map *map;
|
||||||
|
|
||||||
|
(void)scope;
|
||||||
|
(void)dad;
|
||||||
|
|
||||||
|
for (context = daemon->ra_contexts; context; context = context->next)
|
||||||
|
if ((context->flags & CONTEXT_RA_NAME) &&
|
||||||
|
prefix == context->prefix &&
|
||||||
|
is_same_net6(local, &context->start6, prefix) &&
|
||||||
|
is_same_net6(local, &context->end6, prefix))
|
||||||
|
{
|
||||||
|
for (map = *subnets; map; map = map->next)
|
||||||
|
if (map->iface == 0 ||
|
||||||
|
(map->iface == if_index && is_same_net6(local, &map->subnet, prefix)))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* It's there already */
|
||||||
|
if (map && map->iface != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!map && (map = whine_malloc(sizeof(struct subnet_map))))
|
||||||
|
{
|
||||||
|
map->next = *subnets;
|
||||||
|
*subnets = map;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (map)
|
||||||
|
{
|
||||||
|
map->iface = if_index;
|
||||||
|
map->subnet = *local;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build a map from ra-names subnets to corresponding interfaces. This
|
||||||
|
is used to go from DHCPv4 leases to SLAAC addresses,
|
||||||
|
interface->IPv6-subnet, IPv6-subnet + MAC address -> SLAAC.
|
||||||
|
*/
|
||||||
|
struct subnet_map *build_subnet_map(void)
|
||||||
|
{
|
||||||
|
struct subnet_map *map;
|
||||||
|
struct dhcp_context *context;
|
||||||
|
static struct subnet_map *subnets = NULL;
|
||||||
|
|
||||||
|
for (context = daemon->ra_contexts; context; context = context->next)
|
||||||
|
if ((context->flags & CONTEXT_RA_NAME))
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* no ra-names, no need to go further. */
|
||||||
|
if (!context)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* mark unused */
|
||||||
|
for (map = subnets; map; map = map->next)
|
||||||
|
map->iface = 0;
|
||||||
|
|
||||||
|
if (iface_enumerate(AF_INET6, &subnets, add_subnet))
|
||||||
|
return subnets;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
+6
-1
@@ -737,6 +737,11 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
|||||||
{
|
{
|
||||||
if (address_assigned)
|
if (address_assigned)
|
||||||
{
|
{
|
||||||
|
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||||
|
put_opt6_short(DHCP6SUCCESS);
|
||||||
|
put_opt6_string("Oh hai from dnsmasq");
|
||||||
|
end_opt6(o1);
|
||||||
|
|
||||||
if (ia_type == OPTION6_IA_NA)
|
if (ia_type == OPTION6_IA_NA)
|
||||||
{
|
{
|
||||||
/* go back an fill in fields in IA_NA option */
|
/* go back an fill in fields in IA_NA option */
|
||||||
@@ -750,7 +755,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* no address, return erro */
|
/* no address, return error */
|
||||||
o1 = new_opt6(OPTION6_STATUS_CODE);
|
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||||
put_opt6_short(DHCP6NOADDRS);
|
put_opt6_short(DHCP6NOADDRS);
|
||||||
put_opt6_string("No addresses available");
|
put_opt6_string("No addresses available");
|
||||||
|
|||||||
Reference in new issue
Block a user