mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-06 15:51:41 +00:00
Compare commits
23
Commits
v2.67test13
...
v2.67rc2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5c35a59b0 | ||
|
|
2f9fd1dcc5 | ||
|
|
8f3194f7ac | ||
|
|
10bd29265b | ||
|
|
42b44a591b | ||
|
|
a810559b24 | ||
|
|
861c89141a | ||
|
|
8939c95fd6 | ||
|
|
408c368fa5 | ||
|
|
b5d9a362b4 | ||
|
|
f1af2bb485 | ||
|
|
1b55190d3f | ||
|
|
f373a15b62 | ||
|
|
91543f4831 | ||
|
|
d81b42d067 | ||
|
|
724789de13 | ||
|
|
8f51a29137 | ||
|
|
c845f6eda5 | ||
|
|
89500e31f1 | ||
|
|
c8f2dd8b53 | ||
|
|
ceae52df15 | ||
|
|
c2d8d3ffc4 | ||
|
|
aa985beeef |
No files matched your search
@@ -2,6 +2,7 @@ src/*.o
|
|||||||
src/*.mo
|
src/*.mo
|
||||||
src/dnsmasq.pot
|
src/dnsmasq.pot
|
||||||
src/dnsmasq
|
src/dnsmasq
|
||||||
|
src/dnsmasq_baseline
|
||||||
src/.configured
|
src/.configured
|
||||||
contrib/wrt/dhcp_lease_time
|
contrib/wrt/dhcp_lease_time
|
||||||
contrib/wrt/dhcp_release
|
contrib/wrt/dhcp_release
|
||||||
|
|||||||
@@ -107,6 +107,24 @@ version 2.67
|
|||||||
Fix crash with empty tag: in --dhcp-range. Thanks to
|
Fix crash with empty tag: in --dhcp-range. Thanks to
|
||||||
Kaspar Schleiser for the bug report.
|
Kaspar Schleiser for the bug report.
|
||||||
|
|
||||||
|
Add "baseline" and "bloatcheck" makefile targets, for
|
||||||
|
revealing size changes during development. Thanks to
|
||||||
|
Vladislav Grishenko for the patch.
|
||||||
|
|
||||||
|
Cope with DHCPv6 clients which send REQUESTs without
|
||||||
|
address options - treat them as SOLICIT with rapid commit.
|
||||||
|
|
||||||
|
Support identification of clients by MAC address in
|
||||||
|
DHCPv6. When using a relay, the relay must support RFC
|
||||||
|
6939 for this to work. It always works for directly
|
||||||
|
connected clients. Thanks to Vladislav Grishenko
|
||||||
|
for prompting this feature.
|
||||||
|
|
||||||
|
Remove the rule for constructed DHCP ranges that the local
|
||||||
|
address must be either the first or last address in the
|
||||||
|
range. This was originally to avoid SLAAC addresses, but
|
||||||
|
we now explicitly autoconfig and privacy addresses instead.
|
||||||
|
|
||||||
|
|
||||||
version 2.66
|
version 2.66
|
||||||
Add the ability to act as an authoritative DNS
|
Add the ability to act as an authoritative DNS
|
||||||
|
|||||||
@@ -77,10 +77,14 @@ all : $(BUILDDIR)
|
|||||||
build_libs="$(dbus_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs)" \
|
build_libs="$(dbus_libs) $(idn_libs) $(ct_libs) $(lua_libs) $(sunos_libs)" \
|
||||||
-f $(top)/Makefile dnsmasq
|
-f $(top)/Makefile dnsmasq
|
||||||
|
|
||||||
clean :
|
mostly_clean :
|
||||||
rm -f *~ $(BUILDDIR)/*.mo contrib/*/*~ */*~ $(BUILDDIR)/*.pot
|
rm -f $(BUILDDIR)/*.mo $(BUILDDIR)/*.pot
|
||||||
rm -f $(BUILDDIR)/.configured $(BUILDDIR)/*.o $(BUILDDIR)/dnsmasq.a $(BUILDDIR)/dnsmasq
|
rm -f $(BUILDDIR)/.configured $(BUILDDIR)/*.o $(BUILDDIR)/dnsmasq.a $(BUILDDIR)/dnsmasq
|
||||||
rm -rf core */core
|
|
||||||
|
clean : mostly_clean
|
||||||
|
rm -f $(BUILDDIR)/dnsmasq_baseline
|
||||||
|
rm -f core */core
|
||||||
|
rm -f *~ contrib/*/*~ */*~
|
||||||
|
|
||||||
install : all install-common
|
install : all install-common
|
||||||
|
|
||||||
@@ -113,6 +117,16 @@ merge :
|
|||||||
$(BUILDDIR):
|
$(BUILDDIR):
|
||||||
mkdir -p $(BUILDDIR)
|
mkdir -p $(BUILDDIR)
|
||||||
|
|
||||||
|
# rules below are helpers for size tracking
|
||||||
|
|
||||||
|
baseline : mostly_clean all
|
||||||
|
@cd $(BUILDDIR) && \
|
||||||
|
mv dnsmasq dnsmasq_baseline
|
||||||
|
|
||||||
|
bloatcheck : $(BUILDDIR)/dnsmasq_baseline mostly_clean all
|
||||||
|
@cd $(BUILDDIR) && \
|
||||||
|
$(top)/bld/bloat-o-meter dnsmasq_baseline dnsmasq; \
|
||||||
|
size dnsmasq_baseline dnsmasq
|
||||||
|
|
||||||
# rules below are targets in recusive makes with cwd=$(BUILDDIR)
|
# rules below are targets in recusive makes with cwd=$(BUILDDIR)
|
||||||
|
|
||||||
@@ -126,7 +140,7 @@ $(objs:.o=.c) $(hdrs):
|
|||||||
.c.o:
|
.c.o:
|
||||||
$(CC) $(CFLAGS) $(COPTS) $(i18n) $(build_cflags) $(RPM_OPT_FLAGS) -c $<
|
$(CC) $(CFLAGS) $(COPTS) $(i18n) $(build_cflags) $(RPM_OPT_FLAGS) -c $<
|
||||||
|
|
||||||
dnsmasq : .configured $(hdrs) $(objs)
|
dnsmasq : .configured $(hdrs) $(objs)
|
||||||
$(CC) $(LDFLAGS) -o $@ $(objs) $(build_libs) $(LIBS)
|
$(CC) $(LDFLAGS) -o $@ $(objs) $(build_libs) $(LIBS)
|
||||||
|
|
||||||
dnsmasq.pot : $(objs:.o=.c) $(hdrs)
|
dnsmasq.pot : $(objs:.o=.c) $(hdrs)
|
||||||
@@ -135,5 +149,4 @@ dnsmasq.pot : $(objs:.o=.c) $(hdrs)
|
|||||||
%.mo : $(top)/$(PO)/%.po dnsmasq.pot
|
%.mo : $(top)/$(PO)/%.po dnsmasq.pot
|
||||||
$(MSGMERGE) -o - $(top)/$(PO)/$*.po dnsmasq.pot | $(MSGFMT) -o $*.mo -
|
$(MSGMERGE) -o - $(top)/$(PO)/$*.po dnsmasq.pot | $(MSGFMT) -o $*.mo -
|
||||||
|
|
||||||
|
.PHONY : all clean mostly_clean install install-common all-i18n install-i18n merge baseline bloatcheck
|
||||||
.PHONY : all clean install install-common all-i18n install-i18n merge
|
|
||||||
Executable
+130
@@ -0,0 +1,130 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
#
|
||||||
|
# Copyright 2004 Matt Mackall <mpm@selenic.com>
|
||||||
|
#
|
||||||
|
# Inspired by perl Bloat-O-Meter (c) 1997 by Andi Kleen
|
||||||
|
#
|
||||||
|
# This software may be used and distributed according to the terms
|
||||||
|
# of the GNU General Public License, incorporated herein by reference.
|
||||||
|
|
||||||
|
import sys, os#, re
|
||||||
|
|
||||||
|
def usage():
|
||||||
|
sys.stderr.write("usage: %s [-t] file1 file2\n" % sys.argv[0])
|
||||||
|
sys.exit(-1)
|
||||||
|
|
||||||
|
f1, f2 = (None, None)
|
||||||
|
flag_timing, dashes = (False, False)
|
||||||
|
|
||||||
|
for f in sys.argv[1:]:
|
||||||
|
if f.startswith("-"):
|
||||||
|
if f == "--": # sym_args
|
||||||
|
dashes = True
|
||||||
|
break
|
||||||
|
if f == "-t": # timings
|
||||||
|
flag_timing = True
|
||||||
|
else:
|
||||||
|
if not os.path.exists(f):
|
||||||
|
sys.stderr.write("Error: file '%s' does not exist\n" % f)
|
||||||
|
usage()
|
||||||
|
if f1 is None:
|
||||||
|
f1 = f
|
||||||
|
elif f2 is None:
|
||||||
|
f2 = f
|
||||||
|
if flag_timing:
|
||||||
|
import time
|
||||||
|
if f1 is None or f2 is None:
|
||||||
|
usage()
|
||||||
|
|
||||||
|
sym_args = " ".join(sys.argv[3 + flag_timing + dashes:])
|
||||||
|
def getsizes(file):
|
||||||
|
sym, alias, lut = {}, {}, {}
|
||||||
|
for l in os.popen("readelf -W -s %s %s" % (sym_args, file)).readlines():
|
||||||
|
l = l.strip()
|
||||||
|
if not (len(l) and l[0].isdigit() and len(l.split()) == 8):
|
||||||
|
continue
|
||||||
|
num, value, size, typ, bind, vis, ndx, name = l.split()
|
||||||
|
if ndx == "UND": continue # skip undefined
|
||||||
|
if typ in ["SECTION", "FILES"]: continue # skip sections and files
|
||||||
|
if "." in name: name = "static." + name.split(".")[0]
|
||||||
|
value = int(value, 16)
|
||||||
|
size = int(size, 16) if size.startswith('0x') else int(size)
|
||||||
|
if vis != "DEFAULT" and bind != "GLOBAL": # see if it is an alias
|
||||||
|
alias[(value, size)] = {"name" : name}
|
||||||
|
else:
|
||||||
|
sym[name] = {"addr" : value, "size": size}
|
||||||
|
lut[(value, size)] = 0
|
||||||
|
for addr, sz in iter(alias.keys()):
|
||||||
|
# If the non-GLOBAL sym has an implementation elsewhere then
|
||||||
|
# it's an alias, disregard it.
|
||||||
|
if not (addr, sz) in lut:
|
||||||
|
# If this non-GLOBAL sym does not have an implementation at
|
||||||
|
# another address, then treat it as a normal symbol.
|
||||||
|
sym[alias[(addr, sz)]["name"]] = {"addr" : addr, "size": sz}
|
||||||
|
for l in os.popen("readelf -W -S " + file).readlines():
|
||||||
|
x = l.split()
|
||||||
|
if len(x)<6: continue
|
||||||
|
# Should take these into account too!
|
||||||
|
#if x[1] not in [".text", ".rodata", ".symtab", ".strtab"]: continue
|
||||||
|
if x[1] not in [".rodata"]: continue
|
||||||
|
sym[x[1]] = {"addr" : int(x[3], 16), "size" : int(x[5], 16)}
|
||||||
|
return sym
|
||||||
|
|
||||||
|
if flag_timing:
|
||||||
|
start_t1 = int(time.time() * 1e9)
|
||||||
|
old = getsizes(f1)
|
||||||
|
if flag_timing:
|
||||||
|
end_t1 = int(time.time() * 1e9)
|
||||||
|
start_t2 = int(time.time() * 1e9)
|
||||||
|
new = getsizes(f2)
|
||||||
|
if flag_timing:
|
||||||
|
end_t2 = int(time.time() * 1e9)
|
||||||
|
start_t3 = int(time.time() * 1e9)
|
||||||
|
grow, shrink, add, remove, up, down = 0, 0, 0, 0, 0, 0
|
||||||
|
delta, common = [], {}
|
||||||
|
|
||||||
|
for name in iter(old.keys()):
|
||||||
|
if name in new:
|
||||||
|
common[name] = 1
|
||||||
|
|
||||||
|
for name in old:
|
||||||
|
if name not in common:
|
||||||
|
remove += 1
|
||||||
|
sz = old[name]["size"]
|
||||||
|
down += sz
|
||||||
|
delta.append((-sz, name))
|
||||||
|
|
||||||
|
for name in new:
|
||||||
|
if name not in common:
|
||||||
|
add += 1
|
||||||
|
sz = new[name]["size"]
|
||||||
|
up += sz
|
||||||
|
delta.append((sz, name))
|
||||||
|
|
||||||
|
for name in common:
|
||||||
|
d = new[name].get("size", 0) - old[name].get("size", 0)
|
||||||
|
if d>0: grow, up = grow+1, up+d
|
||||||
|
elif d<0: shrink, down = shrink+1, down-d
|
||||||
|
else:
|
||||||
|
continue
|
||||||
|
delta.append((d, name))
|
||||||
|
|
||||||
|
delta.sort()
|
||||||
|
delta.reverse()
|
||||||
|
if flag_timing:
|
||||||
|
end_t3 = int(time.time() * 1e9)
|
||||||
|
|
||||||
|
print("%-48s %7s %7s %+7s" % ("function", "old", "new", "delta"))
|
||||||
|
for d, n in delta:
|
||||||
|
if d:
|
||||||
|
old_sz = old.get(n, {}).get("size", "-")
|
||||||
|
new_sz = new.get(n, {}).get("size", "-")
|
||||||
|
print("%-48s %7s %7s %+7d" % (n, old_sz, new_sz, d))
|
||||||
|
print("-"*78)
|
||||||
|
total="(add/remove: %s/%s grow/shrink: %s/%s up/down: %s/%s)%%sTotal: %s bytes"\
|
||||||
|
% (add, remove, grow, shrink, up, -down, up-down)
|
||||||
|
print(total % (" "*(80-len(total))))
|
||||||
|
if flag_timing:
|
||||||
|
print("\n%d/%d; %d Parse origin/new; processing nsecs" %
|
||||||
|
(end_t1-start_t1, end_t2-start_t2, end_t3-start_t3))
|
||||||
|
print("total nsecs: %d" % (end_t3-start_t1))
|
||||||
Executable
+36
@@ -0,0 +1,36 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
STATUS_FILE="/tmp/dnsmasq-ip-mac.status"
|
||||||
|
|
||||||
|
# Script for dnsmasq lease-change hook.
|
||||||
|
# Maintains the above file with a IP address/MAC address pairs,
|
||||||
|
# one lease per line. Works with IPv4 and IPv6 leases, file is
|
||||||
|
# atomically updated, so no races for users of the data.
|
||||||
|
|
||||||
|
action="$1"
|
||||||
|
mac="$2" # IPv4
|
||||||
|
ip="$3"
|
||||||
|
|
||||||
|
# ensure it always exists.
|
||||||
|
|
||||||
|
if [ ! -f "$STATUS_FILE" ]; then
|
||||||
|
touch "$STATUS_FILE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -n "$DNSMASQ_IAID" ]; then
|
||||||
|
mac="$DNSMASQ_MAC" # IPv6
|
||||||
|
fi
|
||||||
|
|
||||||
|
# worry about an add or old action when the MAC address is not known:
|
||||||
|
# leave any old one in place in that case.
|
||||||
|
|
||||||
|
if [ "$action" = "add" -o "$action" = "old" -o "$action" = "del" ]; then
|
||||||
|
if [ -n "$mac" -o "$action" = "del" ]; then
|
||||||
|
sed "/^${ip//./\.} / d" "$STATUS_FILE" > "$STATUS_FILE".new
|
||||||
|
|
||||||
|
if [ "$action" = "add" -o "$action" = "old" ]; then
|
||||||
|
echo "$ip $mac" >> "$STATUS_FILE".new
|
||||||
|
fi
|
||||||
|
mv "$STATUS_FILE".new "$STATUS_FILE" # atomic update.
|
||||||
|
fi
|
||||||
|
fi
|
||||||
Vendored
+3
-3
@@ -25,7 +25,7 @@ DEB_BUILD_ARCH_OS := $(shell dpkg-architecture -qDEB_BUILD_ARCH_OS)
|
|||||||
|
|
||||||
# Force package version based on git tags.
|
# Force package version based on git tags.
|
||||||
ifneq (,$(filter gitversion,$(DEB_BUILD_OPTIONS)))
|
ifneq (,$(filter gitversion,$(DEB_BUILD_OPTIONS)))
|
||||||
PACKAGE_VERSION = $(shell bld/get-version `pwd` | sed 's/[a-z]/~&/; s/$$/-1/; s/^/-v/')
|
PACKAGE_VERSION = $(shell bld/get-version `pwd` | sed 's/[a-z]/~&/; s/-/./g; s/$$/-1/; s/^/-v/';)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq (,$(filter nodbus,$(DEB_BUILD_OPTIONS)))
|
ifeq (,$(filter nodbus,$(DEB_BUILD_OPTIONS)))
|
||||||
@@ -108,7 +108,7 @@ binary-indep: checkroot
|
|||||||
install -m 644 debian/insserv debian/daemon/etc/insserv.conf.d/dnsmasq
|
install -m 644 debian/insserv debian/daemon/etc/insserv.conf.d/dnsmasq
|
||||||
ln -s $(package) debian/daemon/usr/share/doc/dnsmasq
|
ln -s $(package) debian/daemon/usr/share/doc/dnsmasq
|
||||||
cd debian/daemon && find . -type f ! -regex '.*DEBIAN/.*' -printf '%P\0' | xargs -r0 md5sum > DEBIAN/md5sums
|
cd debian/daemon && find . -type f ! -regex '.*DEBIAN/.*' -printf '%P\0' | xargs -r0 md5sum > DEBIAN/md5sums
|
||||||
dpkg-gencontrol $(PACKAGE_VERSION) -pdnsmasq -Pdebian/daemon
|
dpkg-gencontrol $(PACKAGE_VERSION) -T -pdnsmasq -Pdebian/daemon
|
||||||
chown -R root.root debian/daemon
|
chown -R root.root debian/daemon
|
||||||
chmod -R g-ws debian/daemon
|
chmod -R g-ws debian/daemon
|
||||||
dpkg --build debian/daemon ..
|
dpkg --build debian/daemon ..
|
||||||
@@ -155,7 +155,7 @@ ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
|
|||||||
strip -R .note -R .comment debian/base/usr/sbin/dnsmasq
|
strip -R .note -R .comment debian/base/usr/sbin/dnsmasq
|
||||||
endif
|
endif
|
||||||
cd debian/base && find . -type f ! -regex '.*DEBIAN/.*' -printf '%P\0' | xargs -r0 md5sum > DEBIAN/md5sums
|
cd debian/base && find . -type f ! -regex '.*DEBIAN/.*' -printf '%P\0' | xargs -r0 md5sum > DEBIAN/md5sums
|
||||||
dpkg-shlibdeps debian/base/usr/sbin/dnsmasq
|
dpkg-shlibdeps --warnings=1 debian/base/usr/sbin/dnsmasq
|
||||||
dpkg-gencontrol $(PACKAGE_VERSION) -pdnsmasq-base -Pdebian/base
|
dpkg-gencontrol $(PACKAGE_VERSION) -pdnsmasq-base -Pdebian/base
|
||||||
chown -R root.root debian/base
|
chown -R root.root debian/base
|
||||||
chmod -R g-ws debian/base
|
chmod -R g-ws debian/base
|
||||||
|
|||||||
+12
-14
@@ -652,24 +652,20 @@ This forms a template which describes how to create ranges, based on the address
|
|||||||
|
|
||||||
.B --dhcp-range=::1,::400,constructor:eth0
|
.B --dhcp-range=::1,::400,constructor:eth0
|
||||||
|
|
||||||
will look for addresses of the form <network>::1 or <network>:400 on
|
will look for addresses on
|
||||||
eth0 and then create a range from <network>::1 to <network>::400. If
|
eth0 and then create a range from <network>::1 to <network>::400. If
|
||||||
the interface is assigned more than one network, then the
|
the interface is assigned more than one network, then the
|
||||||
corresponding ranges will be automatically created, and then
|
corresponding ranges will be automatically created, and then
|
||||||
deprecated and finally removed again as the address is deprecated and
|
deprecated and finally removed again as the address is deprecated and
|
||||||
then deleted. The interface name may have a final "*" wildcard. Note
|
then deleted. The interface name may have a final "*" wildcard. Note
|
||||||
that just any address on eth0 will not do: the non-prefix part must be
|
that just any address on eth0 will not do: it must not be an
|
||||||
equal either the start or end address given in the dhcp-range. This is
|
autoconfigured or privacy address, or be deprecated.
|
||||||
to prevent prefixes becoming perpetual if the interface
|
|
||||||
gains a SLAAC address for the prefix when it is advertised by dnsmasq.
|
|
||||||
|
|
||||||
If a dhcp-range is only being used for stateless DHCP and/or SLAAC,
|
If a dhcp-range is only being used for stateless DHCP and/or SLAAC,
|
||||||
then the address can be simply ::
|
then the address can be simply ::
|
||||||
|
|
||||||
.B --dhcp-range=::,constructor:eth0
|
.B --dhcp-range=::,constructor:eth0
|
||||||
|
|
||||||
This removes the condition above, and will pick up the prefix from any address on eth0 which is NOT
|
|
||||||
autoconfigured, slaac, temporary or deprecated.
|
|
||||||
|
|
||||||
There is a variant of the constructor: syntax using the keyword
|
There is a variant of the constructor: syntax using the keyword
|
||||||
.B constructor-noauth.
|
.B constructor-noauth.
|
||||||
@@ -766,7 +762,8 @@ the same subnet as some valid dhcp-range. For
|
|||||||
subnets which don't need a pool of dynamically allocated addresses,
|
subnets which don't need a pool of dynamically allocated addresses,
|
||||||
use the "static" keyword in the dhcp-range declaration.
|
use the "static" keyword in the dhcp-range declaration.
|
||||||
|
|
||||||
It is allowed to use client identifiers rather than
|
It is allowed to use client identifiers (called client
|
||||||
|
DUID in IPv6-land rather than
|
||||||
hardware addresses to identify hosts by prefixing with 'id:'. Thus:
|
hardware addresses to identify hosts by prefixing with 'id:'. Thus:
|
||||||
.B --dhcp-host=id:01:02:03:04,.....
|
.B --dhcp-host=id:01:02:03:04,.....
|
||||||
refers to the host with client identifier 01:02:03:04. It is also
|
refers to the host with client identifier 01:02:03:04. It is also
|
||||||
@@ -781,11 +778,12 @@ IPv6 addresses may contain only the host-identifier part:
|
|||||||
.B --dhcp-host=laptop,[::56]
|
.B --dhcp-host=laptop,[::56]
|
||||||
in which case they act as wildcards in constructed dhcp ranges, with
|
in which case they act as wildcards in constructed dhcp ranges, with
|
||||||
the appropriate network part inserted.
|
the appropriate network part inserted.
|
||||||
Note that in IPv6 DHCP, the hardware address is not normally
|
Note that in IPv6 DHCP, the hardware address may not be
|
||||||
available, so a client must be identified by client-id (called client
|
available, though it normally is for direct-connected clients, or
|
||||||
DUID in IPv6-land) or hostname.
|
clients using DHCP relays which support RFC 6939.
|
||||||
|
|
||||||
The special option id:* means "ignore any client-id
|
|
||||||
|
For DHCPv4, the special option id:* means "ignore any client-id
|
||||||
and use MAC addresses only." This is useful when a client presents a client-id sometimes
|
and use MAC addresses only." This is useful when a client presents a client-id sometimes
|
||||||
but not others.
|
but not others.
|
||||||
|
|
||||||
@@ -1033,7 +1031,7 @@ this to set a different printer server for hosts in the class
|
|||||||
"accounts" than for hosts in the class "engineering".
|
"accounts" than for hosts in the class "engineering".
|
||||||
.TP
|
.TP
|
||||||
.B \-4, --dhcp-mac=set:<tag>,<MAC address>
|
.B \-4, --dhcp-mac=set:<tag>,<MAC address>
|
||||||
(IPv4 only) Map from a MAC address to a tag. The MAC address may include
|
Map from a MAC address to a tag. The MAC address may include
|
||||||
wildcards. For example
|
wildcards. For example
|
||||||
.B --dhcp-mac=set:3com,01:34:23:*:*:*
|
.B --dhcp-mac=set:3com,01:34:23:*:*:*
|
||||||
will set the tag "3com" for any host whose MAC address matches the pattern.
|
will set the tag "3com" for any host whose MAC address matches the pattern.
|
||||||
@@ -1339,7 +1337,7 @@ every call to the script.
|
|||||||
DNSMASQ_IAID containing the IAID for the lease. If the lease is a
|
DNSMASQ_IAID containing the IAID for the lease. If the lease is a
|
||||||
temporary allocation, this is prefixed to 'T'.
|
temporary allocation, this is prefixed to 'T'.
|
||||||
|
|
||||||
|
DNSMASQ_MAC containing the MAC address of the client, if known.
|
||||||
|
|
||||||
Note that the supplied hostname, vendorclass and userclass data is
|
Note that the supplied hostname, vendorclass and userclass data is
|
||||||
only supplied for
|
only supplied for
|
||||||
|
|||||||
+516
-467
File diff suppressed because it is too large.
Load diff
@@ -160,9 +160,15 @@ int iface_enumerate(int family, void *parm, int (*callback)())
|
|||||||
if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DEPRECATED)
|
if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DEPRECATED)
|
||||||
flags |= IFACE_DEPRECATED;
|
flags |= IFACE_DEPRECATED;
|
||||||
|
|
||||||
|
#ifdef IN6_IFF_TEMPORARY
|
||||||
if (!(ifr6.ifr_ifru.ifru_flags6 & (IN6_IFF_AUTOCONF | IN6_IFF_TEMPORARY)))
|
if (!(ifr6.ifr_ifru.ifru_flags6 & (IN6_IFF_AUTOCONF | IN6_IFF_TEMPORARY)))
|
||||||
flags |= IFACE_PERMANENT;
|
flags |= IFACE_PERMANENT;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IN6_IFF_PRIVACY
|
||||||
|
if (!(ifr6.ifr_ifru.ifru_flags6 & (IN6_IFF_AUTOCONF | IN6_IFF_PRIVACY)))
|
||||||
|
flags |= IFACE_PERMANENT;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
ifr6.ifr_addr = *((struct sockaddr_in6 *) addrs->ifa_addr);
|
ifr6.ifr_addr = *((struct sockaddr_in6 *) addrs->ifa_addr);
|
||||||
|
|||||||
+109
-1
@@ -253,6 +253,110 @@ int match_bytes(struct dhcp_opt *o, unsigned char *p, int len)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int config_has_mac(struct dhcp_config *config, unsigned char *hwaddr, int len, int type)
|
||||||
|
{
|
||||||
|
struct hwaddr_config *conf_addr;
|
||||||
|
|
||||||
|
for (conf_addr = config->hwaddr; conf_addr; conf_addr = conf_addr->next)
|
||||||
|
if (conf_addr->wildcard_mask == 0 &&
|
||||||
|
conf_addr->hwaddr_len == len &&
|
||||||
|
(conf_addr->hwaddr_type == type || conf_addr->hwaddr_type == 0) &&
|
||||||
|
memcmp(conf_addr->hwaddr, hwaddr, len) == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int is_config_in_context(struct dhcp_context *context, struct dhcp_config *config)
|
||||||
|
{
|
||||||
|
if (!context) /* called via find_config() from lease_update_from_configs() */
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (!(context->flags & CONTEXT_V6))
|
||||||
|
{
|
||||||
|
if (!(config->flags & CONFIG_ADDR))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
for (; context; context = context->current)
|
||||||
|
if (is_same_net(config->addr, context->start, context->netmask))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#ifdef HAVE_DHCP6
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(config->flags & CONFIG_ADDR6) || (config->flags & CONFIG_WILDCARD))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
for (; context; context = context->current)
|
||||||
|
if (is_same_net6(&config->addr6, &context->start6, context->prefix))
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dhcp_config *find_config(struct dhcp_config *configs,
|
||||||
|
struct dhcp_context *context,
|
||||||
|
unsigned char *clid, int clid_len,
|
||||||
|
unsigned char *hwaddr, int hw_len,
|
||||||
|
int hw_type, char *hostname)
|
||||||
|
{
|
||||||
|
int count, new;
|
||||||
|
struct dhcp_config *config, *candidate;
|
||||||
|
struct hwaddr_config *conf_addr;
|
||||||
|
|
||||||
|
if (clid)
|
||||||
|
for (config = configs; config; config = config->next)
|
||||||
|
if (config->flags & CONFIG_CLID)
|
||||||
|
{
|
||||||
|
if (config->clid_len == clid_len &&
|
||||||
|
memcmp(config->clid, clid, clid_len) == 0 &&
|
||||||
|
is_config_in_context(context, config))
|
||||||
|
return config;
|
||||||
|
|
||||||
|
/* dhcpcd prefixes ASCII client IDs by zero which is wrong, but we try and
|
||||||
|
cope with that here */
|
||||||
|
if (!(context->flags & CONTEXT_V6) && *clid == 0 && config->clid_len == clid_len-1 &&
|
||||||
|
memcmp(config->clid, clid+1, clid_len-1) == 0 &&
|
||||||
|
is_config_in_context(context, config))
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (hwaddr)
|
||||||
|
for (config = configs; config; config = config->next)
|
||||||
|
if (config_has_mac(config, hwaddr, hw_len, hw_type) &&
|
||||||
|
is_config_in_context(context, config))
|
||||||
|
return config;
|
||||||
|
|
||||||
|
if (hostname && context)
|
||||||
|
for (config = configs; config; config = config->next)
|
||||||
|
if ((config->flags & CONFIG_NAME) &&
|
||||||
|
hostname_isequal(config->hostname, hostname) &&
|
||||||
|
is_config_in_context(context, config))
|
||||||
|
return config;
|
||||||
|
|
||||||
|
|
||||||
|
if (!hwaddr)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
/* use match with fewest wildcard octets */
|
||||||
|
for (candidate = NULL, count = 0, config = configs; config; config = config->next)
|
||||||
|
if (is_config_in_context(context, config))
|
||||||
|
for (conf_addr = config->hwaddr; conf_addr; conf_addr = conf_addr->next)
|
||||||
|
if (conf_addr->wildcard_mask != 0 &&
|
||||||
|
conf_addr->hwaddr_len == hw_len &&
|
||||||
|
(conf_addr->hwaddr_type == hw_type || conf_addr->hwaddr_type == 0) &&
|
||||||
|
(new = memcmp_masked(conf_addr->hwaddr, hwaddr, hw_len, conf_addr->wildcard_mask)) > count)
|
||||||
|
{
|
||||||
|
count = new;
|
||||||
|
candidate = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
return candidate;
|
||||||
|
}
|
||||||
|
|
||||||
void dhcp_update_configs(struct dhcp_config *configs)
|
void dhcp_update_configs(struct dhcp_config *configs)
|
||||||
{
|
{
|
||||||
/* Some people like to keep all static IP addresses in /etc/hosts.
|
/* Some people like to keep all static IP addresses in /etc/hosts.
|
||||||
@@ -523,6 +627,8 @@ int lookup_dhcp_opt(int prot, char *name)
|
|||||||
const struct opttab_t *t;
|
const struct opttab_t *t;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
(void)prot;
|
||||||
|
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
if (prot == AF_INET6)
|
if (prot == AF_INET6)
|
||||||
t = opttab6;
|
t = opttab6;
|
||||||
@@ -542,6 +648,8 @@ int lookup_dhcp_len(int prot, int val)
|
|||||||
const struct opttab_t *t;
|
const struct opttab_t *t;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
(void)prot;
|
||||||
|
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
if (prot == AF_INET6)
|
if (prot == AF_INET6)
|
||||||
t = opttab6;
|
t = opttab6;
|
||||||
@@ -719,7 +827,7 @@ void log_context(int family, struct dhcp_context *context)
|
|||||||
template = p;
|
template = p;
|
||||||
p += sprintf(p, ", ");
|
p += sprintf(p, ", ");
|
||||||
|
|
||||||
if (indextoname(daemon->doing_dhcp6 ? daemon->dhcp6fd : daemon->icmp6fd, context->if_index, ifrn_name))
|
if (indextoname(daemon->icmp6fd, context->if_index, ifrn_name))
|
||||||
sprintf(p, "%s for %s", (context->flags & CONTEXT_OLD) ? "old prefix" : "constructed", ifrn_name);
|
sprintf(p, "%s for %s", (context->flags & CONTEXT_OLD) ? "old prefix" : "constructed", ifrn_name);
|
||||||
}
|
}
|
||||||
else if (context->flags & CONTEXT_TEMPLATE)
|
else if (context->flags & CONTEXT_TEMPLATE)
|
||||||
|
|||||||
-83
@@ -749,89 +749,6 @@ int address_allocate(struct dhcp_context *context,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int is_addr_in_context(struct dhcp_context *context, struct dhcp_config *config)
|
|
||||||
{
|
|
||||||
if (!context) /* called via find_config() from lease_update_from_configs() */
|
|
||||||
return 1;
|
|
||||||
if (!(config->flags & CONFIG_ADDR))
|
|
||||||
return 1;
|
|
||||||
for (; context; context = context->current)
|
|
||||||
if (is_same_net(config->addr, context->start, context->netmask))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int config_has_mac(struct dhcp_config *config, unsigned char *hwaddr, int len, int type)
|
|
||||||
{
|
|
||||||
struct hwaddr_config *conf_addr;
|
|
||||||
|
|
||||||
for (conf_addr = config->hwaddr; conf_addr; conf_addr = conf_addr->next)
|
|
||||||
if (conf_addr->wildcard_mask == 0 &&
|
|
||||||
conf_addr->hwaddr_len == len &&
|
|
||||||
(conf_addr->hwaddr_type == type || conf_addr->hwaddr_type == 0) &&
|
|
||||||
memcmp(conf_addr->hwaddr, hwaddr, len) == 0)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct dhcp_config *find_config(struct dhcp_config *configs,
|
|
||||||
struct dhcp_context *context,
|
|
||||||
unsigned char *clid, int clid_len,
|
|
||||||
unsigned char *hwaddr, int hw_len,
|
|
||||||
int hw_type, char *hostname)
|
|
||||||
{
|
|
||||||
int count, new;
|
|
||||||
struct dhcp_config *config, *candidate;
|
|
||||||
struct hwaddr_config *conf_addr;
|
|
||||||
|
|
||||||
if (clid)
|
|
||||||
for (config = configs; config; config = config->next)
|
|
||||||
if (config->flags & CONFIG_CLID)
|
|
||||||
{
|
|
||||||
if (config->clid_len == clid_len &&
|
|
||||||
memcmp(config->clid, clid, clid_len) == 0 &&
|
|
||||||
is_addr_in_context(context, config))
|
|
||||||
return config;
|
|
||||||
|
|
||||||
/* dhcpcd prefixes ASCII client IDs by zero which is wrong, but we try and
|
|
||||||
cope with that here */
|
|
||||||
if (*clid == 0 && config->clid_len == clid_len-1 &&
|
|
||||||
memcmp(config->clid, clid+1, clid_len-1) == 0 &&
|
|
||||||
is_addr_in_context(context, config))
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
for (config = configs; config; config = config->next)
|
|
||||||
if (config_has_mac(config, hwaddr, hw_len, hw_type) &&
|
|
||||||
is_addr_in_context(context, config))
|
|
||||||
return config;
|
|
||||||
|
|
||||||
if (hostname && context)
|
|
||||||
for (config = configs; config; config = config->next)
|
|
||||||
if ((config->flags & CONFIG_NAME) &&
|
|
||||||
hostname_isequal(config->hostname, hostname) &&
|
|
||||||
is_addr_in_context(context, config))
|
|
||||||
return config;
|
|
||||||
|
|
||||||
/* use match with fewest wildcard octets */
|
|
||||||
for (candidate = NULL, count = 0, config = configs; config; config = config->next)
|
|
||||||
if (is_addr_in_context(context, config))
|
|
||||||
for (conf_addr = config->hwaddr; conf_addr; conf_addr = conf_addr->next)
|
|
||||||
if (conf_addr->wildcard_mask != 0 &&
|
|
||||||
conf_addr->hwaddr_len == hw_len &&
|
|
||||||
(conf_addr->hwaddr_type == hw_type || conf_addr->hwaddr_type == 0) &&
|
|
||||||
(new = memcmp_masked(conf_addr->hwaddr, hwaddr, hw_len, conf_addr->wildcard_mask)) > count)
|
|
||||||
{
|
|
||||||
count = new;
|
|
||||||
candidate = config;
|
|
||||||
}
|
|
||||||
|
|
||||||
return candidate;
|
|
||||||
}
|
|
||||||
|
|
||||||
void dhcp_read_ethers(void)
|
void dhcp_read_ethers(void)
|
||||||
{
|
{
|
||||||
FILE *f = fopen(ETHERSFILE, "r");
|
FILE *f = fopen(ETHERSFILE, "r");
|
||||||
|
|||||||
@@ -59,6 +59,7 @@
|
|||||||
#define OPTION6_REMOTE_ID 37
|
#define OPTION6_REMOTE_ID 37
|
||||||
#define OPTION6_SUBSCRIBER_ID 38
|
#define OPTION6_SUBSCRIBER_ID 38
|
||||||
#define OPTION6_FQDN 39
|
#define OPTION6_FQDN 39
|
||||||
|
#define OPTION6_CLIENT_MAC 79
|
||||||
|
|
||||||
/* replace this with the real number when allocated.
|
/* replace this with the real number when allocated.
|
||||||
defining this also enables the relevant code. */
|
defining this also enables the relevant code. */
|
||||||
|
|||||||
+100
-53
@@ -18,6 +18,8 @@
|
|||||||
|
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
|
|
||||||
|
#include <netinet/icmp6.h>
|
||||||
|
|
||||||
struct iface_param {
|
struct iface_param {
|
||||||
struct dhcp_context *current;
|
struct dhcp_context *current;
|
||||||
struct dhcp_relay *relay;
|
struct dhcp_relay *relay;
|
||||||
@@ -25,10 +27,17 @@ struct iface_param {
|
|||||||
int ind, addr_match;
|
int ind, addr_match;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mac_param {
|
||||||
|
struct in6_addr *target;
|
||||||
|
unsigned char *mac;
|
||||||
|
unsigned int maclen;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static int complete_context6(struct in6_addr *local, int prefix,
|
static int complete_context6(struct in6_addr *local, int prefix,
|
||||||
int scope, int if_index, int flags,
|
int scope, int if_index, int flags,
|
||||||
unsigned int preferred, unsigned int valid, void *vparam);
|
unsigned int preferred, unsigned int valid, void *vparam);
|
||||||
|
static int find_mac(int family, char *addrp, char *mac, size_t maclen, void *parmv);
|
||||||
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);
|
||||||
|
|
||||||
void dhcp6_init(void)
|
void dhcp6_init(void)
|
||||||
@@ -102,6 +111,9 @@ void dhcp6_packet(time_t now)
|
|||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
struct iname *tmp;
|
struct iname *tmp;
|
||||||
unsigned short port;
|
unsigned short port;
|
||||||
|
struct in6_addr dst_addr;
|
||||||
|
|
||||||
|
memset(&dst_addr, 0, sizeof(dst_addr));
|
||||||
|
|
||||||
msg.msg_control = control_u.control6;
|
msg.msg_control = control_u.control6;
|
||||||
msg.msg_controllen = sizeof(control_u);
|
msg.msg_controllen = sizeof(control_u);
|
||||||
@@ -124,6 +136,7 @@ void dhcp6_packet(time_t now)
|
|||||||
p.c = CMSG_DATA(cmptr);
|
p.c = CMSG_DATA(cmptr);
|
||||||
|
|
||||||
if_index = p.p->ipi6_ifindex;
|
if_index = p.p->ipi6_ifindex;
|
||||||
|
dst_addr = p.p->ipi6_addr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!indextoname(daemon->dhcp6fd, if_index, ifr.ifr_name))
|
if (!indextoname(daemon->dhcp6fd, if_index, ifr.ifr_name))
|
||||||
@@ -131,7 +144,6 @@ void dhcp6_packet(time_t now)
|
|||||||
|
|
||||||
if ((port = relay_reply6(&from, sz, ifr.ifr_name)) == 0)
|
if ((port = relay_reply6(&from, sz, ifr.ifr_name)) == 0)
|
||||||
{
|
{
|
||||||
|
|
||||||
for (tmp = daemon->if_except; tmp; tmp = tmp->next)
|
for (tmp = daemon->if_except; tmp; tmp = tmp->next)
|
||||||
if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
|
if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
|
||||||
return;
|
return;
|
||||||
@@ -166,7 +178,7 @@ void dhcp6_packet(time_t now)
|
|||||||
|
|
||||||
if (!iface_enumerate(AF_INET6, &parm, complete_context6))
|
if (!iface_enumerate(AF_INET6, &parm, complete_context6))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (daemon->if_names || daemon->if_addrs)
|
if (daemon->if_names || daemon->if_addrs)
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -180,7 +192,14 @@ void dhcp6_packet(time_t now)
|
|||||||
|
|
||||||
if (parm.relay)
|
if (parm.relay)
|
||||||
{
|
{
|
||||||
relay_upstream6(parm.relay, sz, &from.sin6_addr, from.sin6_scope_id);
|
/* Ignore requests sent to the ALL_SERVERS multicast address for relay when
|
||||||
|
we're listening there for DHCPv6 server reasons. */
|
||||||
|
struct in6_addr all_servers;
|
||||||
|
|
||||||
|
inet_pton(AF_INET6, ALL_SERVERS, &all_servers);
|
||||||
|
|
||||||
|
if (!IN6_ARE_ADDR_EQUAL(&dst_addr, &all_servers))
|
||||||
|
relay_upstream6(parm.relay, sz, &from.sin6_addr, from.sin6_scope_id);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,7 +210,7 @@ void dhcp6_packet(time_t now)
|
|||||||
lease_prune(NULL, now); /* lose any expired leases */
|
lease_prune(NULL, now); /* lose any expired leases */
|
||||||
|
|
||||||
port = dhcp6_reply(parm.current, if_index, ifr.ifr_name, &parm.fallback,
|
port = dhcp6_reply(parm.current, if_index, ifr.ifr_name, &parm.fallback,
|
||||||
sz, IN6_IS_ADDR_MULTICAST(&from.sin6_addr), now);
|
sz, &from.sin6_addr, now);
|
||||||
|
|
||||||
lease_update_file(now);
|
lease_update_file(now);
|
||||||
lease_update_dns(0);
|
lease_update_dns(0);
|
||||||
@@ -210,6 +229,73 @@ void dhcp6_packet(time_t now)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac, unsigned int *maclenp, unsigned int *mactypep)
|
||||||
|
{
|
||||||
|
/* Recieving a packet from a host does not populate the neighbour
|
||||||
|
cache, so we send a neighbour discovery request if we can't
|
||||||
|
find the sender. Repeat a few times in case of packet loss. */
|
||||||
|
|
||||||
|
struct neigh_packet neigh;
|
||||||
|
struct sockaddr_in6 addr;
|
||||||
|
struct mac_param mac_param;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
neigh.type = ND_NEIGHBOR_SOLICIT;
|
||||||
|
neigh.code = 0;
|
||||||
|
neigh.reserved = 0;
|
||||||
|
neigh.target = *client;
|
||||||
|
|
||||||
|
memset(&addr, 0, sizeof(addr));
|
||||||
|
#ifdef HAVE_SOCKADDR_SA_LEN
|
||||||
|
addr.sin6_len = sizeof(struct sockaddr_in6);
|
||||||
|
#endif
|
||||||
|
addr.sin6_family = AF_INET6;
|
||||||
|
addr.sin6_port = htons(IPPROTO_ICMPV6);
|
||||||
|
addr.sin6_addr = *client;
|
||||||
|
addr.sin6_scope_id = iface;
|
||||||
|
|
||||||
|
mac_param.target = client;
|
||||||
|
mac_param.maclen = 0;
|
||||||
|
mac_param.mac = mac;
|
||||||
|
|
||||||
|
for (i = 0; i < 5; i++)
|
||||||
|
{
|
||||||
|
struct timespec ts;
|
||||||
|
|
||||||
|
iface_enumerate(AF_UNSPEC, &mac_param, find_mac);
|
||||||
|
|
||||||
|
if (mac_param.maclen != 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
sendto(daemon->icmp6fd, &neigh, sizeof(neigh), 0, (struct sockaddr *)&addr, sizeof(addr));
|
||||||
|
|
||||||
|
ts.tv_sec = 0;
|
||||||
|
ts.tv_nsec = 100000000; /* 100ms */
|
||||||
|
nanosleep(&ts, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
*maclenp = mac_param.maclen;
|
||||||
|
*mactypep = ARPHRD_ETHER;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int find_mac(int family, char *addrp, char *mac, size_t maclen, void *parmv)
|
||||||
|
{
|
||||||
|
struct mac_param *parm = parmv;
|
||||||
|
|
||||||
|
if (family == AF_INET6 && IN6_ARE_ADDR_EQUAL(parm->target, (struct in6_addr *)addrp))
|
||||||
|
{
|
||||||
|
if (maclen <= DHCP_CHADDR_MAX)
|
||||||
|
{
|
||||||
|
parm->maclen = maclen;
|
||||||
|
memcpy(parm->mac, mac, maclen);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0; /* found, abort */
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int complete_context6(struct in6_addr *local, int prefix,
|
static int complete_context6(struct in6_addr *local, int prefix,
|
||||||
int scope, int if_index, int flags, unsigned int preferred,
|
int scope, int if_index, int flags, unsigned int preferred,
|
||||||
unsigned int valid, void *vparam)
|
unsigned int valid, void *vparam)
|
||||||
@@ -435,48 +521,6 @@ int config_valid(struct dhcp_config *config, struct dhcp_context *context, struc
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int is_config_in_context6(struct dhcp_context *context, struct dhcp_config *config)
|
|
||||||
{
|
|
||||||
if (!(config->flags & CONFIG_ADDR6) ||
|
|
||||||
(config->flags & CONFIG_WILDCARD))
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
for (; context; context = context->current)
|
|
||||||
if (is_same_net6(&config->addr6, &context->start6, context->prefix))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
struct dhcp_config *find_config6(struct dhcp_config *configs,
|
|
||||||
struct dhcp_context *context,
|
|
||||||
unsigned char *duid, int duid_len,
|
|
||||||
char *hostname)
|
|
||||||
{
|
|
||||||
struct dhcp_config *config;
|
|
||||||
|
|
||||||
if (duid)
|
|
||||||
for (config = configs; config; config = config->next)
|
|
||||||
if (config->flags & CONFIG_CLID)
|
|
||||||
{
|
|
||||||
if (config->clid_len == duid_len &&
|
|
||||||
memcmp(config->clid, duid, duid_len) == 0 &&
|
|
||||||
is_config_in_context6(context, config))
|
|
||||||
return config;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (hostname && context)
|
|
||||||
for (config = configs; config; config = config->next)
|
|
||||||
if ((config->flags & CONFIG_NAME) &&
|
|
||||||
hostname_isequal(config->hostname, hostname) &&
|
|
||||||
is_config_in_context6(context, config))
|
|
||||||
return config;
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void make_duid(time_t now)
|
void make_duid(time_t now)
|
||||||
{
|
{
|
||||||
if (daemon->duid_config)
|
if (daemon->duid_config)
|
||||||
@@ -510,6 +554,7 @@ static int make_duid1(int index, unsigned int type, char *mac, size_t maclen, vo
|
|||||||
|
|
||||||
unsigned char *p;
|
unsigned char *p;
|
||||||
(void)index;
|
(void)index;
|
||||||
|
(void)parm;
|
||||||
|
|
||||||
if (type >= 256)
|
if (type >= 256)
|
||||||
return 1;
|
return 1;
|
||||||
@@ -557,7 +602,13 @@ static int construct_worker(struct in6_addr *local, int prefix,
|
|||||||
IN6_IS_ADDR_MULTICAST(local))
|
IN6_IS_ADDR_MULTICAST(local))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (!indextoname(daemon->doing_dhcp6 ? daemon->dhcp6fd : daemon->icmp6fd, if_index, ifrn_name))
|
if (!(flags & IFACE_PERMANENT))
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (flags & IFACE_DEPRECATED)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (!indextoname(daemon->icmp6fd, if_index, ifrn_name))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
for (template = daemon->dhcp6; template; template = template->next)
|
for (template = daemon->dhcp6; template; template = template->next)
|
||||||
@@ -573,11 +624,7 @@ static int construct_worker(struct in6_addr *local, int prefix,
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else if ((addr6part(local) == addr6part(&template->start6) ||
|
else if (wildcard_match(template->template_interface, ifrn_name))
|
||||||
addr6part(local) == addr6part(&template->end6) ||
|
|
||||||
(IN6_IS_ADDR_UNSPECIFIED(&template->start6) &&
|
|
||||||
IFACE_PERMANENT == (flags & (IFACE_PERMANENT | IFACE_DEPRECATED)))) &&
|
|
||||||
wildcard_match(template->template_interface, ifrn_name))
|
|
||||||
{
|
{
|
||||||
start6 = *local;
|
start6 = *local;
|
||||||
setaddr6part(&start6, addr6part(&template->start6));
|
setaddr6part(&start6, addr6part(&template->start6));
|
||||||
|
|||||||
+5
-1
@@ -51,8 +51,10 @@ int main (int argc, char **argv)
|
|||||||
cap_user_header_t hdr = NULL;
|
cap_user_header_t hdr = NULL;
|
||||||
cap_user_data_t data = NULL;
|
cap_user_data_t data = NULL;
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(HAVE_DHCP) || defined(HAVE_DHCP6)
|
||||||
struct dhcp_context *context;
|
struct dhcp_context *context;
|
||||||
struct dhcp_relay *relay;
|
struct dhcp_relay *relay;
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef LOCALEDIR
|
#ifdef LOCALEDIR
|
||||||
setlocale(LC_ALL, "");
|
setlocale(LC_ALL, "");
|
||||||
@@ -202,7 +204,7 @@ int main (int argc, char **argv)
|
|||||||
dhcp_init();
|
dhcp_init();
|
||||||
|
|
||||||
# ifdef HAVE_DHCP6
|
# ifdef HAVE_DHCP6
|
||||||
if (daemon->doing_ra)
|
if (daemon->doing_ra || daemon->doing_dhcp6 || daemon->relay6)
|
||||||
ra_init(now);
|
ra_init(now);
|
||||||
|
|
||||||
if (daemon->doing_dhcp6 || daemon->relay6)
|
if (daemon->doing_dhcp6 || daemon->relay6)
|
||||||
@@ -1231,6 +1233,8 @@ void poll_resolv(int force, int do_reload, time_t now)
|
|||||||
|
|
||||||
void clear_cache_and_reload(time_t now)
|
void clear_cache_and_reload(time_t now)
|
||||||
{
|
{
|
||||||
|
(void)now;
|
||||||
|
|
||||||
if (daemon->port != 0)
|
if (daemon->port != 0)
|
||||||
cache_reload();
|
cache_reload();
|
||||||
|
|
||||||
|
|||||||
+34
-32
@@ -539,13 +539,15 @@ struct dhcp_lease {
|
|||||||
#ifdef HAVE_BROKEN_RTC
|
#ifdef HAVE_BROKEN_RTC
|
||||||
unsigned int length;
|
unsigned int length;
|
||||||
#endif
|
#endif
|
||||||
int hwaddr_len, hwaddr_type; /* hw_type used for iaid in v6 */
|
int hwaddr_len, hwaddr_type;
|
||||||
unsigned char hwaddr[DHCP_CHADDR_MAX]; /* also IPv6 address */
|
unsigned char hwaddr[DHCP_CHADDR_MAX];
|
||||||
struct in_addr addr, override, giaddr;
|
struct in_addr addr, override, giaddr;
|
||||||
unsigned char *extradata;
|
unsigned char *extradata;
|
||||||
unsigned int extradata_len, extradata_size;
|
unsigned int extradata_len, extradata_size;
|
||||||
int last_interface;
|
int last_interface;
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
|
struct in6_addr addr6;
|
||||||
|
int iaid;
|
||||||
struct slaac_address {
|
struct slaac_address {
|
||||||
struct in6_addr addr, local;
|
struct in6_addr addr, local;
|
||||||
time_t ping_time;
|
time_t ping_time;
|
||||||
@@ -717,24 +719,25 @@ struct dhcp_context {
|
|||||||
struct dhcp_context *next, *current;
|
struct dhcp_context *next, *current;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define CONTEXT_STATIC 1
|
#define CONTEXT_STATIC (1u<<0)
|
||||||
#define CONTEXT_NETMASK 2
|
#define CONTEXT_NETMASK (1u<<1)
|
||||||
#define CONTEXT_BRDCAST 4
|
#define CONTEXT_BRDCAST (1u<<2)
|
||||||
#define CONTEXT_PROXY 8
|
#define CONTEXT_PROXY (1u<<3)
|
||||||
#define CONTEXT_RA_ONLY 16
|
#define CONTEXT_RA_ONLY (1u<<4)
|
||||||
#define CONTEXT_RA_DONE 32
|
#define CONTEXT_RA_DONE (1u<<5)
|
||||||
#define CONTEXT_RA_NAME 64
|
#define CONTEXT_RA_NAME (1u<<6)
|
||||||
#define CONTEXT_RA_STATELESS 128
|
#define CONTEXT_RA_STATELESS (1u<<7)
|
||||||
#define CONTEXT_DHCP 256
|
#define CONTEXT_DHCP (1u<<8)
|
||||||
#define CONTEXT_DEPRECATE 512
|
#define CONTEXT_DEPRECATE (1u<<9)
|
||||||
#define CONTEXT_TEMPLATE 1024 /* create contexts using addresses */
|
#define CONTEXT_TEMPLATE (1u<<10) /* create contexts using addresses */
|
||||||
#define CONTEXT_CONSTRUCTED 2048
|
#define CONTEXT_CONSTRUCTED (1u<<11)
|
||||||
#define CONTEXT_GC 4096
|
#define CONTEXT_GC (1u<<12)
|
||||||
#define CONTEXT_RA 8192
|
#define CONTEXT_RA (1u<<13)
|
||||||
#define CONTEXT_CONF_USED 16384
|
#define CONTEXT_CONF_USED (1u<<14)
|
||||||
#define CONTEXT_USED 32768
|
#define CONTEXT_USED (1u<<15)
|
||||||
#define CONTEXT_NOAUTH 65536
|
#define CONTEXT_NOAUTH (1u<<16)
|
||||||
#define CONTEXT_OLD 131072
|
#define CONTEXT_OLD (1u<<17)
|
||||||
|
#define CONTEXT_V6 (1u<<18)
|
||||||
|
|
||||||
|
|
||||||
struct ping_result {
|
struct ping_result {
|
||||||
@@ -1072,12 +1075,6 @@ struct dhcp_context *narrow_context(struct dhcp_context *context,
|
|||||||
int address_allocate(struct dhcp_context *context,
|
int address_allocate(struct dhcp_context *context,
|
||||||
struct in_addr *addrp, unsigned char *hwaddr, int hw_len,
|
struct in_addr *addrp, unsigned char *hwaddr, int hw_len,
|
||||||
struct dhcp_netid *netids, time_t now);
|
struct dhcp_netid *netids, time_t now);
|
||||||
int config_has_mac(struct dhcp_config *config, unsigned char *hwaddr, int len, int type);
|
|
||||||
struct dhcp_config *find_config(struct dhcp_config *configs,
|
|
||||||
struct dhcp_context *context,
|
|
||||||
unsigned char *clid, int clid_len,
|
|
||||||
unsigned char *hwaddr, int hw_len,
|
|
||||||
int hw_type, char *hostname);
|
|
||||||
void dhcp_read_ethers(void);
|
void dhcp_read_ethers(void);
|
||||||
struct dhcp_config *config_find_by_address(struct dhcp_config *configs, struct in_addr addr);
|
struct dhcp_config *config_find_by_address(struct dhcp_config *configs, struct in_addr addr);
|
||||||
char *host_from_dns(struct in_addr addr);
|
char *host_from_dns(struct in_addr addr);
|
||||||
@@ -1099,6 +1096,7 @@ struct dhcp_lease *lease6_find_by_addr(struct in6_addr *net, int prefix, u64 add
|
|||||||
u64 lease_find_max_addr6(struct dhcp_context *context);
|
u64 lease_find_max_addr6(struct dhcp_context *context);
|
||||||
void lease_ping_reply(struct in6_addr *sender, unsigned char *packet, char *interface);
|
void lease_ping_reply(struct in6_addr *sender, unsigned char *packet, char *interface);
|
||||||
void lease_update_slaac(time_t now);
|
void lease_update_slaac(time_t now);
|
||||||
|
void lease_set_iaid(struct dhcp_lease *lease, int iaid);
|
||||||
#endif
|
#endif
|
||||||
void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
|
void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
|
||||||
unsigned char *clid, int hw_len, int hw_type, int clid_len, time_t now, int force);
|
unsigned char *clid, int hw_len, int hw_type, int clid_len, time_t now, int force);
|
||||||
@@ -1210,20 +1208,18 @@ struct dhcp_context *address6_valid(struct dhcp_context *context,
|
|||||||
struct in6_addr *taddr,
|
struct in6_addr *taddr,
|
||||||
struct dhcp_netid *netids,
|
struct dhcp_netid *netids,
|
||||||
int plain_range);
|
int plain_range);
|
||||||
struct dhcp_config *find_config6(struct dhcp_config *configs,
|
|
||||||
struct dhcp_context *context,
|
|
||||||
unsigned char *duid, int duid_len,
|
|
||||||
char *hostname);
|
|
||||||
struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct in6_addr *net,
|
struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct in6_addr *net,
|
||||||
int prefix, u64 addr);
|
int prefix, u64 addr);
|
||||||
void make_duid(time_t now);
|
void make_duid(time_t now);
|
||||||
void dhcp_construct_contexts(time_t now);
|
void dhcp_construct_contexts(time_t now);
|
||||||
|
void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac,
|
||||||
|
unsigned int *maclenp, unsigned int *mactypep);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* rfc3315.c */
|
/* rfc3315.c */
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name,
|
unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name,
|
||||||
struct in6_addr *fallback, size_t sz, int is_multicast, time_t now);
|
struct in6_addr *fallback, size_t sz, struct in6_addr *client_addr, time_t now);
|
||||||
void relay_upstream6(struct dhcp_relay *relay, ssize_t sz, struct in6_addr *peer_address, u32 scope_id);
|
void relay_upstream6(struct dhcp_relay *relay, ssize_t sz, struct in6_addr *peer_address, u32 scope_id);
|
||||||
|
|
||||||
unsigned short relay_reply6( struct sockaddr_in6 *peer, ssize_t sz, char *arrival_interface);
|
unsigned short relay_reply6( struct sockaddr_in6 *peer, ssize_t sz, char *arrival_interface);
|
||||||
@@ -1246,6 +1242,12 @@ int lookup_dhcp_opt(int prot, char *name);
|
|||||||
int lookup_dhcp_len(int prot, int val);
|
int lookup_dhcp_len(int prot, int val);
|
||||||
char *option_string(int prot, unsigned int opt, unsigned char *val,
|
char *option_string(int prot, unsigned int opt, unsigned char *val,
|
||||||
int opt_len, char *buf, int buf_len);
|
int opt_len, char *buf, int buf_len);
|
||||||
|
struct dhcp_config *find_config(struct dhcp_config *configs,
|
||||||
|
struct dhcp_context *context,
|
||||||
|
unsigned char *clid, int clid_len,
|
||||||
|
unsigned char *hwaddr, int hw_len,
|
||||||
|
int hw_type, char *hostname);
|
||||||
|
int config_has_mac(struct dhcp_config *config, unsigned char *hwaddr, int len, int type);
|
||||||
#ifdef HAVE_LINUX_NETWORK
|
#ifdef HAVE_LINUX_NETWORK
|
||||||
void bindtodevice(int fd);
|
void bindtodevice(int fd);
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+59
-54
@@ -60,10 +60,16 @@ struct script_data
|
|||||||
unsigned int length;
|
unsigned int length;
|
||||||
#else
|
#else
|
||||||
time_t expires;
|
time_t expires;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_TFTP
|
||||||
|
off_t file_len;
|
||||||
|
#endif
|
||||||
|
#ifdef HAVE_DHCP6
|
||||||
|
struct in6_addr addr6;
|
||||||
|
int iaid, vendorclass_count;
|
||||||
#endif
|
#endif
|
||||||
unsigned char hwaddr[DHCP_CHADDR_MAX];
|
unsigned char hwaddr[DHCP_CHADDR_MAX];
|
||||||
char interface[IF_NAMESIZE];
|
char interface[IF_NAMESIZE];
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct script_data *buf = NULL;
|
static struct script_data *buf = NULL;
|
||||||
@@ -215,20 +221,17 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
||||||
if (!is6)
|
/* stringify MAC into dhcp_buff */
|
||||||
|
p = daemon->dhcp_buff;
|
||||||
|
if (data.hwaddr_type != ARPHRD_ETHER || data.hwaddr_len == 0)
|
||||||
|
p += sprintf(p, "%.2x-", data.hwaddr_type);
|
||||||
|
for (i = 0; (i < data.hwaddr_len) && (i < DHCP_CHADDR_MAX); i++)
|
||||||
{
|
{
|
||||||
/* stringify MAC into dhcp_buff */
|
p += sprintf(p, "%.2x", data.hwaddr[i]);
|
||||||
p = daemon->dhcp_buff;
|
if (i != data.hwaddr_len - 1)
|
||||||
if (data.hwaddr_type != ARPHRD_ETHER || data.hwaddr_len == 0)
|
p += sprintf(p, ":");
|
||||||
p += sprintf(p, "%.2x-", data.hwaddr_type);
|
|
||||||
for (i = 0; (i < data.hwaddr_len) && (i < DHCP_CHADDR_MAX); i++)
|
|
||||||
{
|
|
||||||
p += sprintf(p, "%.2x", data.hwaddr[i]);
|
|
||||||
if (i != data.hwaddr_len - 1)
|
|
||||||
p += sprintf(p, ":");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* supplied data may just exceed normal buffer (unlikely) */
|
/* supplied data may just exceed normal buffer (unlikely) */
|
||||||
if ((data.hostname_len + data.ed_len + data.clid_len) > MAXDNAME &&
|
if ((data.hostname_len + data.ed_len + data.clid_len) > MAXDNAME &&
|
||||||
!(alloc_buff = buf = malloc(data.hostname_len + data.ed_len + data.clid_len)))
|
!(alloc_buff = buf = malloc(data.hostname_len + data.ed_len + data.clid_len)))
|
||||||
@@ -239,32 +242,25 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* CLID into packet */
|
/* CLID into packet */
|
||||||
if (!is6)
|
for (p = daemon->packet, i = 0; i < data.clid_len; i++)
|
||||||
for (p = daemon->packet, i = 0; i < data.clid_len; i++)
|
{
|
||||||
{
|
p += sprintf(p, "%.2x", buf[i]);
|
||||||
p += sprintf(p, "%.2x", buf[i]);
|
if (i != data.clid_len - 1)
|
||||||
if (i != data.clid_len - 1)
|
|
||||||
p += sprintf(p, ":");
|
p += sprintf(p, ":");
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
else
|
if (is6)
|
||||||
{
|
{
|
||||||
/* or IAID and server DUID for IPv6 */
|
/* or IAID and server DUID for IPv6 */
|
||||||
sprintf(daemon->dhcp_buff3, "%s%u", data.flags & LEASE_TA ? "T" : "", data.hwaddr_type);
|
sprintf(daemon->dhcp_buff3, "%s%u", data.flags & LEASE_TA ? "T" : "", data.iaid);
|
||||||
for (p = daemon->packet, i = 0; i < daemon->duid_len; i++)
|
for (p = daemon->dhcp_packet.iov_base, i = 0; i < daemon->duid_len; i++)
|
||||||
{
|
{
|
||||||
p += sprintf(p, "%.2x", daemon->duid[i]);
|
p += sprintf(p, "%.2x", daemon->duid[i]);
|
||||||
if (i != daemon->duid_len - 1)
|
if (i != daemon->duid_len - 1)
|
||||||
p += sprintf(p, ":");
|
p += sprintf(p, ":");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* duid not MAC for IPv6 */
|
|
||||||
for (p = daemon->dhcp_buff, i = 0; i < data.clid_len; i++)
|
|
||||||
{
|
|
||||||
p += sprintf(p, "%.2x", buf[i]);
|
|
||||||
if (i != data.clid_len - 1)
|
|
||||||
p += sprintf(p, ":");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -293,13 +289,15 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|||||||
inet_ntop(AF_INET, &data.addr, daemon->addrbuff, ADDRSTRLEN);
|
inet_ntop(AF_INET, &data.addr, daemon->addrbuff, ADDRSTRLEN);
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
else
|
else
|
||||||
inet_ntop(AF_INET6, &data.hwaddr, daemon->addrbuff, ADDRSTRLEN);
|
inet_ntop(AF_INET6, &data.addr6, daemon->addrbuff, ADDRSTRLEN);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_TFTP
|
||||||
/* file length */
|
/* file length */
|
||||||
if (data.action == ACTION_TFTP)
|
if (data.action == ACTION_TFTP)
|
||||||
sprintf(daemon->dhcp_buff, "%u", data.hwaddr_len);
|
sprintf(is6 ? daemon->packet : daemon->dhcp_buff, "%lu", (unsigned long)data.file_len);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_LUASCRIPT
|
#ifdef HAVE_LUASCRIPT
|
||||||
if (daemon->luascript)
|
if (daemon->luascript)
|
||||||
{
|
{
|
||||||
@@ -316,7 +314,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|||||||
lua_setfield(lua, -2, "destination_address");
|
lua_setfield(lua, -2, "destination_address");
|
||||||
lua_pushstring(lua, hostname);
|
lua_pushstring(lua, hostname);
|
||||||
lua_setfield(lua, -2, "file_name");
|
lua_setfield(lua, -2, "file_name");
|
||||||
lua_pushstring(lua, daemon->dhcp_buff);
|
lua_pushstring(lua, is6 ? daemon->packet : daemon->dhcp_buff);
|
||||||
lua_setfield(lua, -2, "file_size");
|
lua_setfield(lua, -2, "file_size");
|
||||||
lua_call(lua, 2, 0); /* pass 2 values, expect 0 */
|
lua_call(lua, 2, 0); /* pass 2 values, expect 0 */
|
||||||
}
|
}
|
||||||
@@ -329,9 +327,9 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|||||||
|
|
||||||
if (is6)
|
if (is6)
|
||||||
{
|
{
|
||||||
lua_pushstring(lua, daemon->dhcp_buff);
|
|
||||||
lua_setfield(lua, -2, "client_duid");
|
|
||||||
lua_pushstring(lua, daemon->packet);
|
lua_pushstring(lua, daemon->packet);
|
||||||
|
lua_setfield(lua, -2, "client_duid");
|
||||||
|
lua_pushstring(lua, daemon->dhcp_packet.iov_base);
|
||||||
lua_setfield(lua, -2, "server_duid");
|
lua_setfield(lua, -2, "server_duid");
|
||||||
lua_pushstring(lua, daemon->dhcp_buff3);
|
lua_pushstring(lua, daemon->dhcp_buff3);
|
||||||
lua_setfield(lua, -2, "iaid");
|
lua_setfield(lua, -2, "iaid");
|
||||||
@@ -375,12 +373,16 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|||||||
if (!is6)
|
if (!is6)
|
||||||
buf = grab_extradata_lua(buf, end, "vendor_class");
|
buf = grab_extradata_lua(buf, end, "vendor_class");
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
else
|
else if (data.vendorclass_count != 0)
|
||||||
for (i = 0; i < data.hwaddr_len; i++)
|
{
|
||||||
{
|
sprintf(daemon->dhcp_buff2, "vendor_class_id");
|
||||||
sprintf(daemon->dhcp_buff2, "vendor_class%i", i);
|
buf = grab_extradata_lua(buf, end, daemon->dhcp_buff2);
|
||||||
buf = grab_extradata_lua(buf, end, daemon->dhcp_buff2);
|
for (i = 0; i < data.vendorclass_count - 1; i++)
|
||||||
}
|
{
|
||||||
|
sprintf(daemon->dhcp_buff2, "vendor_class%i", i);
|
||||||
|
buf = grab_extradata_lua(buf, end, daemon->dhcp_buff2);
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
buf = grab_extradata_lua(buf, end, "supplied_hostname");
|
buf = grab_extradata_lua(buf, end, "supplied_hostname");
|
||||||
@@ -423,7 +425,7 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|||||||
lua_setfield(lua, -2, "old_hostname");
|
lua_setfield(lua, -2, "old_hostname");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is6)
|
if (!is6 || data.hwaddr_len != 0)
|
||||||
{
|
{
|
||||||
lua_pushstring(lua, daemon->dhcp_buff);
|
lua_pushstring(lua, daemon->dhcp_buff);
|
||||||
lua_setfield(lua, -2, "mac_address");
|
lua_setfield(lua, -2, "mac_address");
|
||||||
@@ -476,11 +478,15 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|||||||
|
|
||||||
if (data.action != ACTION_TFTP)
|
if (data.action != ACTION_TFTP)
|
||||||
{
|
{
|
||||||
|
#ifdef HAVE_DHCP6
|
||||||
if (is6)
|
if (is6)
|
||||||
{
|
{
|
||||||
my_setenv("DNSMASQ_IAID", daemon->dhcp_buff3, &err);
|
my_setenv("DNSMASQ_IAID", daemon->dhcp_buff3, &err);
|
||||||
my_setenv("DNSMASQ_SERVER_DUID", daemon->packet, &err);
|
my_setenv("DNSMASQ_SERVER_DUID", daemon->dhcp_packet.iov_base, &err);
|
||||||
|
if (data.hwaddr_len != 0)
|
||||||
|
my_setenv("DNSMASQ_MAC", daemon->dhcp_buff, &err);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!is6 && data.clid_len != 0)
|
if (!is6 && data.clid_len != 0)
|
||||||
my_setenv("DNSMASQ_CLIENT_ID", daemon->packet, &err);
|
my_setenv("DNSMASQ_CLIENT_ID", daemon->packet, &err);
|
||||||
@@ -507,10 +513,10 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (data.hwaddr_len != 0)
|
if (data.vendorclass_count != 0)
|
||||||
{
|
{
|
||||||
buf = grab_extradata(buf, end, "DNSMASQ_VENDOR_CLASS_ID", &err);
|
buf = grab_extradata(buf, end, "DNSMASQ_VENDOR_CLASS_ID", &err);
|
||||||
for (i = 0; i < data.hwaddr_len - 1; i++)
|
for (i = 0; i < data.vendorclass_count - 1; i++)
|
||||||
{
|
{
|
||||||
sprintf(daemon->dhcp_buff2, "DNSMASQ_VENDOR_CLASS%i", i);
|
sprintf(daemon->dhcp_buff2, "DNSMASQ_VENDOR_CLASS%i", i);
|
||||||
buf = grab_extradata(buf, end, daemon->dhcp_buff2, &err);
|
buf = grab_extradata(buf, end, daemon->dhcp_buff2, &err);
|
||||||
@@ -570,7 +576,8 @@ int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd)
|
|||||||
{
|
{
|
||||||
execl(daemon->lease_change_command,
|
execl(daemon->lease_change_command,
|
||||||
p ? p+1 : daemon->lease_change_command,
|
p ? p+1 : daemon->lease_change_command,
|
||||||
action_str, daemon->dhcp_buff, daemon->addrbuff, hostname, (char*)NULL);
|
action_str, is6 ? daemon->packet : daemon->dhcp_buff,
|
||||||
|
daemon->addrbuff, hostname, (char*)NULL);
|
||||||
err = errno;
|
err = errno;
|
||||||
}
|
}
|
||||||
/* failed, send event so the main process logs the problem */
|
/* failed, send event so the main process logs the problem */
|
||||||
@@ -656,8 +663,6 @@ void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t n
|
|||||||
unsigned int hostname_len = 0, clid_len = 0, ed_len = 0;
|
unsigned int hostname_len = 0, clid_len = 0, ed_len = 0;
|
||||||
int fd = daemon->dhcpfd;
|
int fd = daemon->dhcpfd;
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
int is6 = !!(lease->flags & (LEASE_TA | LEASE_NA));
|
|
||||||
|
|
||||||
if (!daemon->dhcp)
|
if (!daemon->dhcp)
|
||||||
fd = daemon->dhcp6fd;
|
fd = daemon->dhcp6fd;
|
||||||
#endif
|
#endif
|
||||||
@@ -678,11 +683,11 @@ void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t n
|
|||||||
buf->action = action;
|
buf->action = action;
|
||||||
buf->flags = lease->flags;
|
buf->flags = lease->flags;
|
||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
if (is6)
|
buf->vendorclass_count = lease->vendorclass_count;
|
||||||
buf->hwaddr_len = lease->vendorclass_count;
|
buf->addr6 = lease->addr6;
|
||||||
else
|
buf->iaid = lease->iaid;
|
||||||
#endif
|
#endif
|
||||||
buf->hwaddr_len = lease->hwaddr_len;
|
buf->hwaddr_len = lease->hwaddr_len;
|
||||||
buf->hwaddr_type = lease->hwaddr_type;
|
buf->hwaddr_type = lease->hwaddr_type;
|
||||||
buf->clid_len = clid_len;
|
buf->clid_len = clid_len;
|
||||||
buf->ed_len = ed_len;
|
buf->ed_len = ed_len;
|
||||||
@@ -739,13 +744,13 @@ void queue_tftp(off_t file_len, char *filename, union mysockaddr *peer)
|
|||||||
|
|
||||||
buf->action = ACTION_TFTP;
|
buf->action = ACTION_TFTP;
|
||||||
buf->hostname_len = filename_len;
|
buf->hostname_len = filename_len;
|
||||||
buf->hwaddr_len = file_len;
|
buf->file_len = file_len;
|
||||||
|
|
||||||
if ((buf->flags = peer->sa.sa_family) == AF_INET)
|
if ((buf->flags = peer->sa.sa_family) == AF_INET)
|
||||||
buf->addr = peer->in.sin_addr;
|
buf->addr = peer->in.sin_addr;
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
else
|
else
|
||||||
memcpy(buf->hwaddr, &peer->in6.sin6_addr, IN6ADDRSZ);
|
buf->addr6 = peer->in6.sin6_addr;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
memcpy((unsigned char *)(buf+1), filename, filename_len);
|
memcpy((unsigned char *)(buf+1), filename, filename_len);
|
||||||
|
|||||||
+54
-32
@@ -108,6 +108,7 @@ void lease_init(time_t now)
|
|||||||
{
|
{
|
||||||
char *s = daemon->dhcp_buff2;
|
char *s = daemon->dhcp_buff2;
|
||||||
int lease_type = LEASE_NA;
|
int lease_type = LEASE_NA;
|
||||||
|
int iaid;
|
||||||
|
|
||||||
if (s[0] == 'T')
|
if (s[0] == 'T')
|
||||||
{
|
{
|
||||||
@@ -115,12 +116,12 @@ void lease_init(time_t now)
|
|||||||
s++;
|
s++;
|
||||||
}
|
}
|
||||||
|
|
||||||
hw_type = strtoul(s, NULL, 10);
|
iaid = strtoul(s, NULL, 10);
|
||||||
|
|
||||||
if ((lease = lease6_allocate(&addr.addr.addr6, lease_type)))
|
if ((lease = lease6_allocate(&addr.addr.addr6, lease_type)))
|
||||||
{
|
{
|
||||||
lease_set_hwaddr(lease, NULL, (unsigned char *)daemon->packet, 0, hw_type, clid_len, now, 0);
|
lease_set_hwaddr(lease, NULL, (unsigned char *)daemon->packet, 0, 0, clid_len, now, 0);
|
||||||
|
lease_set_iaid(lease, iaid);
|
||||||
if (strcmp(daemon->dhcp_buff, "*") != 0)
|
if (strcmp(daemon->dhcp_buff, "*") != 0)
|
||||||
lease_set_hostname(lease, daemon->dhcp_buff, 0, get_domain6((struct in6_addr *)lease->hwaddr), NULL);
|
lease_set_hostname(lease, daemon->dhcp_buff, 0, get_domain6((struct in6_addr *)lease->hwaddr), NULL);
|
||||||
}
|
}
|
||||||
@@ -187,10 +188,12 @@ void lease_update_from_configs(void)
|
|||||||
char *name;
|
char *name;
|
||||||
|
|
||||||
for (lease = leases; lease; lease = lease->next)
|
for (lease = leases; lease; lease = lease->next)
|
||||||
if ((config = find_config(daemon->dhcp_conf, NULL, lease->clid, lease->clid_len,
|
if (lease->flags & (LEASE_TA | LEASE_NA))
|
||||||
lease->hwaddr, lease->hwaddr_len, lease->hwaddr_type, NULL)) &&
|
continue;
|
||||||
(config->flags & CONFIG_NAME) &&
|
else if ((config = find_config(daemon->dhcp_conf, NULL, lease->clid, lease->clid_len,
|
||||||
(!(config->flags & CONFIG_ADDR) || config->addr.s_addr == lease->addr.s_addr))
|
lease->hwaddr, lease->hwaddr_len, lease->hwaddr_type, NULL)) &&
|
||||||
|
(config->flags & CONFIG_NAME) &&
|
||||||
|
(!(config->flags & CONFIG_ADDR) || config->addr.s_addr == lease->addr.s_addr))
|
||||||
lease_set_hostname(lease, config->hostname, 1, get_domain(lease->addr), NULL);
|
lease_set_hostname(lease, config->hostname, 1, get_domain(lease->addr), NULL);
|
||||||
else if ((name = host_from_dns(lease->addr)))
|
else if ((name = host_from_dns(lease->addr)))
|
||||||
lease_set_hostname(lease, name, 1, get_domain(lease->addr), NULL); /* updates auth flag only */
|
lease_set_hostname(lease, name, 1, get_domain(lease->addr), NULL); /* updates auth flag only */
|
||||||
@@ -277,10 +280,10 @@ void lease_update_file(time_t now)
|
|||||||
ourprintf(&err, "%lu ", (unsigned long)lease->expires);
|
ourprintf(&err, "%lu ", (unsigned long)lease->expires);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inet_ntop(AF_INET6, lease->hwaddr, daemon->addrbuff, ADDRSTRLEN);
|
inet_ntop(AF_INET6, &lease->addr6, daemon->addrbuff, ADDRSTRLEN);
|
||||||
|
|
||||||
ourprintf(&err, "%s%u %s ", (lease->flags & LEASE_TA) ? "T" : "",
|
ourprintf(&err, "%s%u %s ", (lease->flags & LEASE_TA) ? "T" : "",
|
||||||
lease->hwaddr_type, daemon->addrbuff);
|
lease->iaid, daemon->addrbuff);
|
||||||
ourprintf(&err, "%s ", lease->hostname ? lease->hostname : "*");
|
ourprintf(&err, "%s ", lease->hostname ? lease->hostname : "*");
|
||||||
|
|
||||||
if (lease->clid && lease->clid_len != 0)
|
if (lease->clid && lease->clid_len != 0)
|
||||||
@@ -376,7 +379,7 @@ static int find_interface_v6(struct in6_addr *local, int prefix,
|
|||||||
|
|
||||||
for (lease = leases; lease; lease = lease->next)
|
for (lease = leases; lease; lease = lease->next)
|
||||||
if ((lease->flags & (LEASE_TA | LEASE_NA)))
|
if ((lease->flags & (LEASE_TA | LEASE_NA)))
|
||||||
if (is_same_net6(local, (struct in6_addr *)&lease->hwaddr, prefix))
|
if (is_same_net6(local, &lease->addr6, prefix))
|
||||||
lease_set_interface(lease, if_index, *((time_t *)vparam));
|
lease_set_interface(lease, if_index, *((time_t *)vparam));
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@@ -459,17 +462,24 @@ void lease_update_dns(int force)
|
|||||||
cache_add_dhcp_entry(lease->hostname, AF_INET6, (struct all_addr *)&slaac->addr, lease->expires);
|
cache_add_dhcp_entry(lease->hostname, AF_INET6, (struct all_addr *)&slaac->addr, lease->expires);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
if (lease->fqdn)
|
if (lease->fqdn)
|
||||||
cache_add_dhcp_entry(lease->fqdn, prot,
|
cache_add_dhcp_entry(lease->fqdn, prot,
|
||||||
prot == AF_INET ? (struct all_addr *)&lease->addr : (struct all_addr *)&lease->hwaddr,
|
prot == AF_INET ? (struct all_addr *)&lease->addr : (struct all_addr *)&lease->addr6,
|
||||||
lease->expires);
|
lease->expires);
|
||||||
|
|
||||||
if (!option_bool(OPT_DHCP_FQDN) && lease->hostname)
|
if (!option_bool(OPT_DHCP_FQDN) && lease->hostname)
|
||||||
cache_add_dhcp_entry(lease->hostname, prot,
|
cache_add_dhcp_entry(lease->hostname, prot,
|
||||||
prot == AF_INET ? (struct all_addr *)&lease->addr : (struct all_addr *)&lease->hwaddr,
|
prot == AF_INET ? (struct all_addr *)&lease->addr : (struct all_addr *)&lease->addr6,
|
||||||
lease->expires);
|
lease->expires);
|
||||||
|
|
||||||
|
#else
|
||||||
|
if (lease->fqdn)
|
||||||
|
cache_add_dhcp_entry(lease->fqdn, prot, (struct all_addr *)&lease->addr, lease->expires);
|
||||||
|
|
||||||
|
if (!option_bool(OPT_DHCP_FQDN) && lease->hostname)
|
||||||
|
cache_add_dhcp_entry(lease->hostname, prot, (struct all_addr *)&lease->addr, lease->expires);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
dns_dirty = 0;
|
dns_dirty = 0;
|
||||||
@@ -564,10 +574,10 @@ struct dhcp_lease *lease6_find(unsigned char *clid, int clid_len,
|
|||||||
|
|
||||||
for (lease = leases; lease; lease = lease->next)
|
for (lease = leases; lease; lease = lease->next)
|
||||||
{
|
{
|
||||||
if (!(lease->flags & lease_type) || lease->hwaddr_type != iaid)
|
if (!(lease->flags & lease_type) || lease->iaid != iaid)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (memcmp(lease->hwaddr, addr, IN6ADDRSZ) != 0)
|
if (!IN6_ARE_ADDR_EQUAL(&lease->addr6, addr))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((clid_len != lease->clid_len ||
|
if ((clid_len != lease->clid_len ||
|
||||||
@@ -604,7 +614,7 @@ struct dhcp_lease *lease6_find_by_client(struct dhcp_lease *first, int lease_typ
|
|||||||
if (lease->flags & LEASE_USED)
|
if (lease->flags & LEASE_USED)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!(lease->flags & lease_type) || lease->hwaddr_type != iaid)
|
if (!(lease->flags & lease_type) || lease->iaid != iaid)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((clid_len != lease->clid_len ||
|
if ((clid_len != lease->clid_len ||
|
||||||
@@ -626,8 +636,8 @@ struct dhcp_lease *lease6_find_by_addr(struct in6_addr *net, int prefix, u64 add
|
|||||||
if (!(lease->flags & (LEASE_TA | LEASE_NA)))
|
if (!(lease->flags & (LEASE_TA | LEASE_NA)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (is_same_net6((struct in6_addr *)lease->hwaddr, net, prefix) &&
|
if (is_same_net6(&lease->addr6, net, prefix) &&
|
||||||
(prefix == 128 || addr6part((struct in6_addr *)lease->hwaddr) == addr))
|
(prefix == 128 || addr6part(&lease->addr6) == addr))
|
||||||
return lease;
|
return lease;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -646,11 +656,11 @@ u64 lease_find_max_addr6(struct dhcp_context *context)
|
|||||||
if (!(lease->flags & (LEASE_TA | LEASE_NA)))
|
if (!(lease->flags & (LEASE_TA | LEASE_NA)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (is_same_net6((struct in6_addr *)lease->hwaddr, &context->start6, 64) &&
|
if (is_same_net6(&lease->addr6, &context->start6, 64) &&
|
||||||
addr6part((struct in6_addr *)lease->hwaddr) > addr6part(&context->start6) &&
|
addr6part(&lease->addr6) > addr6part(&context->start6) &&
|
||||||
addr6part((struct in6_addr *)lease->hwaddr) <= addr6part(&context->end6) &&
|
addr6part(&lease->addr6) <= addr6part(&context->end6) &&
|
||||||
addr6part((struct in6_addr *)lease->hwaddr) > addr)
|
addr6part(&lease->addr6) > addr)
|
||||||
addr = addr6part((struct in6_addr *)lease->hwaddr);
|
addr = addr6part(&lease->addr6);
|
||||||
}
|
}
|
||||||
|
|
||||||
return addr;
|
return addr;
|
||||||
@@ -692,6 +702,7 @@ static struct dhcp_lease *lease_allocate(void)
|
|||||||
#ifdef HAVE_BROKEN_RTC
|
#ifdef HAVE_BROKEN_RTC
|
||||||
lease->length = 0xffffffff; /* illegal value */
|
lease->length = 0xffffffff; /* illegal value */
|
||||||
#endif
|
#endif
|
||||||
|
lease->hwaddr_len = 256; /* illegal value */
|
||||||
lease->next = leases;
|
lease->next = leases;
|
||||||
leases = lease;
|
leases = lease;
|
||||||
|
|
||||||
@@ -705,11 +716,8 @@ struct dhcp_lease *lease4_allocate(struct in_addr addr)
|
|||||||
{
|
{
|
||||||
struct dhcp_lease *lease = lease_allocate();
|
struct dhcp_lease *lease = lease_allocate();
|
||||||
if (lease)
|
if (lease)
|
||||||
{
|
lease->addr = addr;
|
||||||
lease->addr = addr;
|
|
||||||
lease->hwaddr_len = 256; /* illegal value */
|
|
||||||
}
|
|
||||||
|
|
||||||
return lease;
|
return lease;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -720,8 +728,9 @@ struct dhcp_lease *lease6_allocate(struct in6_addr *addrp, int lease_type)
|
|||||||
|
|
||||||
if (lease)
|
if (lease)
|
||||||
{
|
{
|
||||||
memcpy(lease->hwaddr, addrp, sizeof(*addrp)) ;
|
lease->addr6 = *addrp;
|
||||||
lease->flags |= lease_type;
|
lease->flags |= lease_type;
|
||||||
|
lease->iaid = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return lease;
|
return lease;
|
||||||
@@ -758,6 +767,17 @@ void lease_set_expires(struct dhcp_lease *lease, unsigned int len, time_t now)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef HAVE_DHCP6
|
||||||
|
void lease_set_iaid(struct dhcp_lease *lease, int iaid)
|
||||||
|
{
|
||||||
|
if (lease->iaid != iaid)
|
||||||
|
{
|
||||||
|
lease->iaid = iaid;
|
||||||
|
lease->flags |= LEASE_CHANGED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
|
void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
|
||||||
unsigned char *clid, int hw_len, int hw_type, int clid_len,
|
unsigned char *clid, int hw_len, int hw_type, int clid_len,
|
||||||
time_t now, int force)
|
time_t now, int force)
|
||||||
@@ -768,6 +788,7 @@ void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
(void)force;
|
(void)force;
|
||||||
|
(void)now;
|
||||||
|
|
||||||
if (hw_len != lease->hwaddr_len ||
|
if (hw_len != lease->hwaddr_len ||
|
||||||
hw_type != lease->hwaddr_type ||
|
hw_type != lease->hwaddr_type ||
|
||||||
@@ -779,9 +800,6 @@ void lease_set_hwaddr(struct dhcp_lease *lease, unsigned char *hwaddr,
|
|||||||
lease->hwaddr_type = hw_type;
|
lease->hwaddr_type = hw_type;
|
||||||
lease->flags |= LEASE_CHANGED;
|
lease->flags |= LEASE_CHANGED;
|
||||||
file_dirty = 1; /* run script on change */
|
file_dirty = 1; /* run script on change */
|
||||||
#ifdef HAVE_DHCP6
|
|
||||||
change = 1;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* only update clid when one is available, stops packets
|
/* only update clid when one is available, stops packets
|
||||||
@@ -939,6 +957,8 @@ void lease_set_hostname(struct dhcp_lease *lease, char *name, int auth, char *do
|
|||||||
|
|
||||||
void lease_set_interface(struct dhcp_lease *lease, int interface, time_t now)
|
void lease_set_interface(struct dhcp_lease *lease, int interface, time_t now)
|
||||||
{
|
{
|
||||||
|
(void)now;
|
||||||
|
|
||||||
if (lease->last_interface == interface)
|
if (lease->last_interface == interface)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -967,6 +987,8 @@ int do_script_run(time_t now)
|
|||||||
{
|
{
|
||||||
struct dhcp_lease *lease;
|
struct dhcp_lease *lease;
|
||||||
|
|
||||||
|
(void)now;
|
||||||
|
|
||||||
#ifdef HAVE_DBUS
|
#ifdef HAVE_DBUS
|
||||||
/* If we're going to be sending DBus signals, but the connection is not yet up,
|
/* If we're going to be sending DBus signals, but the connection is not yet up,
|
||||||
delay everything until it is. */
|
delay everything until it is. */
|
||||||
|
|||||||
@@ -402,6 +402,8 @@ static int nl_async(struct nlmsghdr *h)
|
|||||||
|
|
||||||
static void nl_newaddress(time_t now)
|
static void nl_newaddress(time_t now)
|
||||||
{
|
{
|
||||||
|
(void)now;
|
||||||
|
|
||||||
if (option_bool(OPT_CLEVERBIND) || daemon->doing_dhcp6 || daemon->relay6 || daemon->doing_ra)
|
if (option_bool(OPT_CLEVERBIND) || daemon->doing_dhcp6 || daemon->relay6 || daemon->doing_ra)
|
||||||
enumerate_interfaces(0);
|
enumerate_interfaces(0);
|
||||||
|
|
||||||
|
|||||||
+8
-2
@@ -115,7 +115,9 @@ int iface_check(int family, struct all_addr *addr, char *name, int *auth)
|
|||||||
int ret = 1, match_addr = 0;
|
int ret = 1, match_addr = 0;
|
||||||
|
|
||||||
/* Note: have to check all and not bail out early, so that we set the
|
/* Note: have to check all and not bail out early, so that we set the
|
||||||
"used" flags. */
|
"used" flags.
|
||||||
|
|
||||||
|
May be called with family == AF_LOCALto check interface by name only. */
|
||||||
|
|
||||||
if (auth)
|
if (auth)
|
||||||
*auth = 0;
|
*auth = 0;
|
||||||
@@ -241,7 +243,7 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
|
|||||||
int tftp_ok = !!option_bool(OPT_TFTP);
|
int tftp_ok = !!option_bool(OPT_TFTP);
|
||||||
int dhcp_ok = 1;
|
int dhcp_ok = 1;
|
||||||
int auth_dns = 0;
|
int auth_dns = 0;
|
||||||
#ifdef HAVE_DHCP
|
#if defined(HAVE_DHCP) || defined(HAVE_TFTP)
|
||||||
struct iname *tmp;
|
struct iname *tmp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -360,6 +362,7 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_TFTP
|
||||||
if (daemon->tftp_interfaces)
|
if (daemon->tftp_interfaces)
|
||||||
{
|
{
|
||||||
/* dedicated tftp interface list */
|
/* dedicated tftp interface list */
|
||||||
@@ -368,6 +371,7 @@ static int iface_allowed(struct iface_param *param, int if_index, char *label,
|
|||||||
if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
|
if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
|
||||||
tftp_ok = 1;
|
tftp_ok = 1;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* add to list */
|
/* add to list */
|
||||||
if ((iface = whine_malloc(sizeof(struct irec))))
|
if ((iface = whine_malloc(sizeof(struct irec))))
|
||||||
@@ -705,6 +709,8 @@ static struct listener *create_listeners(union mysockaddr *addr, int do_tftp, in
|
|||||||
struct listener *l = NULL;
|
struct listener *l = NULL;
|
||||||
int fd = -1, tcpfd = -1, tftpfd = -1;
|
int fd = -1, tcpfd = -1, tftpfd = -1;
|
||||||
|
|
||||||
|
(void)do_tftp;
|
||||||
|
|
||||||
if (daemon->port != 0)
|
if (daemon->port != 0)
|
||||||
{
|
{
|
||||||
fd = make_sock(addr, SOCK_DGRAM, dienow);
|
fd = make_sock(addr, SOCK_DGRAM, dienow);
|
||||||
|
|||||||
@@ -1571,6 +1571,8 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef HAVE_AUTH
|
||||||
case LOPT_AUTHSERV: /* --auth-server */
|
case LOPT_AUTHSERV: /* --auth-server */
|
||||||
if (!(comma = split(arg)))
|
if (!(comma = split(arg)))
|
||||||
ret_err(gen_err);
|
ret_err(gen_err);
|
||||||
@@ -1693,6 +1695,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case 's': /* --domain */
|
case 's': /* --domain */
|
||||||
case LOPT_SYNTH: /* --synth-domain */
|
case LOPT_SYNTH: /* --synth-domain */
|
||||||
@@ -2404,6 +2407,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
|||||||
#ifdef HAVE_DHCP6
|
#ifdef HAVE_DHCP6
|
||||||
else if (inet_pton(AF_INET6, a[0], &new->start6))
|
else if (inet_pton(AF_INET6, a[0], &new->start6))
|
||||||
{
|
{
|
||||||
|
new->flags |= CONTEXT_V6;
|
||||||
new->prefix = 64; /* default */
|
new->prefix = 64; /* default */
|
||||||
new->end6 = new->start6;
|
new->end6 = new->start6;
|
||||||
new->next = daemon->dhcp6;
|
new->next = daemon->dhcp6;
|
||||||
|
|||||||
@@ -33,6 +33,13 @@ struct ra_packet {
|
|||||||
u32 retrans_time;
|
u32 retrans_time;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct neigh_packet {
|
||||||
|
u8 type, code;
|
||||||
|
u16 checksum;
|
||||||
|
u16 reserved;
|
||||||
|
struct in6_addr target;
|
||||||
|
};
|
||||||
|
|
||||||
struct prefix_opt {
|
struct prefix_opt {
|
||||||
u8 type, len, prefix_len, flags;
|
u8 type, len, prefix_len, flags;
|
||||||
u32 valid_lifetime, preferred_lifetime, reserved;
|
u32 valid_lifetime, preferred_lifetime, reserved;
|
||||||
|
|||||||
+16
-7
@@ -70,10 +70,15 @@ void ra_init(time_t now)
|
|||||||
if ((context->flags & CONTEXT_RA_NAME))
|
if ((context->flags & CONTEXT_RA_NAME))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* Need ICMP6 socket for transmission for DHCPv6 even when not doing RA. */
|
||||||
|
|
||||||
ICMP6_FILTER_SETBLOCKALL(&filter);
|
ICMP6_FILTER_SETBLOCKALL(&filter);
|
||||||
ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter);
|
if (daemon->doing_ra)
|
||||||
if (context)
|
{
|
||||||
ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &filter);
|
ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter);
|
||||||
|
if (context)
|
||||||
|
ICMP6_FILTER_SETPASS(ICMP6_ECHO_REPLY, &filter);
|
||||||
|
}
|
||||||
|
|
||||||
if ((fd = socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) == -1 ||
|
if ((fd = socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6)) == -1 ||
|
||||||
getsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hop_limit, &len) ||
|
getsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &hop_limit, &len) ||
|
||||||
@@ -89,7 +94,8 @@ void ra_init(time_t now)
|
|||||||
|
|
||||||
daemon->icmp6fd = fd;
|
daemon->icmp6fd = fd;
|
||||||
|
|
||||||
ra_start_unsolicted(now, NULL);
|
if (daemon->doing_ra)
|
||||||
|
ra_start_unsolicted(now, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ra_start_unsolicted(time_t now, struct dhcp_context *context)
|
void ra_start_unsolicted(time_t now, struct dhcp_context *context)
|
||||||
@@ -385,10 +391,13 @@ static void send_ra(time_t now, int iface, char *iface_name, struct in6_addr *de
|
|||||||
addr.sin6_scope_id = iface;
|
addr.sin6_scope_id = iface;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
inet_pton(AF_INET6, ALL_NODES, &addr.sin6_addr);
|
{
|
||||||
|
inet_pton(AF_INET6, ALL_NODES, &addr.sin6_addr);
|
||||||
|
setsockopt(daemon->icmp6fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &iface, sizeof(iface));
|
||||||
|
}
|
||||||
|
|
||||||
send_from(daemon->icmp6fd, 0, daemon->outpacket.iov_base, save_counter(0),
|
while (sendto(daemon->icmp6fd, daemon->outpacket.iov_base, save_counter(0), 0,
|
||||||
(union mysockaddr *)&addr, (struct all_addr *)&parm.link_local, iface);
|
(struct sockaddr *)&addr, sizeof(addr)) == -1 && retry_send());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+317
-253
File diff suppressed because it is too large.
Load diff
@@ -49,9 +49,7 @@ void tftp_request(struct listener *listen, time_t now)
|
|||||||
struct iovec iov;
|
struct iovec iov;
|
||||||
struct ifreq ifr;
|
struct ifreq ifr;
|
||||||
int is_err = 1, if_index = 0, mtu = 0;
|
int is_err = 1, if_index = 0, mtu = 0;
|
||||||
#ifdef HAVE_DHCP
|
|
||||||
struct iname *tmp;
|
struct iname *tmp;
|
||||||
#endif
|
|
||||||
struct tftp_transfer *transfer;
|
struct tftp_transfer *transfer;
|
||||||
int port = daemon->start_tftp_port; /* may be zero to use ephemeral port */
|
int port = daemon->start_tftp_port; /* may be zero to use ephemeral port */
|
||||||
#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
|
#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
|
||||||
|
|||||||
Reference in new issue
Block a user