mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-04 13:48:30 +00:00
Compare commits
20
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9de1aa9b7f | ||
|
|
6f9aaa93e9 | ||
|
|
7e5664bdbc | ||
|
|
83f28bef6c | ||
|
|
96c727fda6 | ||
|
|
49dc570a72 | ||
|
|
cd1e04a234 | ||
|
|
27cb314e54 | ||
|
|
56a1142f03 | ||
|
|
5b37aa8c19 | ||
|
|
8ac9787350 | ||
|
|
9f9bd08af8 | ||
|
|
4c985dac39 | ||
|
|
3d77c0460d | ||
|
|
3ddad24608 | ||
|
|
6e37ab595c | ||
|
|
a1a79edaea | ||
|
|
49333cbdbe | ||
|
|
de92b479d9 | ||
|
|
0f128eb58c |
No files matched your search
@@ -33,7 +33,7 @@ version 2.66
|
||||
|
||||
Add DNSMASQ_CIRCUIT_ID, DNSMASQ_SUBCRIBER_ID,
|
||||
DNSMASQ_REMOTE_ID variables to the environment of the
|
||||
lease-change script (and the correponding Lua). These hold
|
||||
lease-change script (and the corresponding Lua). These hold
|
||||
information inserted into the DHCP request by a DHCP relay
|
||||
agent. Thanks to Lakefield Communications for providing a
|
||||
bounty for this addition.
|
||||
@@ -47,9 +47,19 @@ version 2.66
|
||||
patch.
|
||||
|
||||
Don't erroneously reject some option names in --dhcp-match
|
||||
options. Thnaks to Benedikt Hochstrasser for the bug report.
|
||||
options. Thanks to Benedikt Hochstrasser for the bug report.
|
||||
|
||||
Allow a trailing '*' wildcard in all interface-name
|
||||
configurations. Thanks to Christian Parpart for the patch.
|
||||
|
||||
Handle the situation where libc headers define
|
||||
SO_REUSEPORT, but the kernel in use doesn't, to cope with
|
||||
the introduction of this option to Linux. Thanks to Rich
|
||||
Felker for the bug report.
|
||||
|
||||
Update Polish translation. Thanks to Jan Psota.
|
||||
|
||||
|
||||
version 2.65
|
||||
Fix regression which broke forwarding of queries sent via
|
||||
TCP which are not for A and AAAA and which were directed to
|
||||
|
||||
Vendored
+2
-4
@@ -33,10 +33,8 @@ ifeq ($(DEB_BUILD_ARCH_OS),linux)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq (,$(filter noipset,$(DEB_BUILD_OPTIONS)))
|
||||
ifeq ($(DEB_BUILD_ARCH_OS),linux)
|
||||
COPTS += -DHAVE_IPSET
|
||||
endif
|
||||
ifneq (,$(filter noipset,$(DEB_BUILD_OPTIONS)))
|
||||
COPTS += -DNO_IPSET
|
||||
endif
|
||||
|
||||
ifneq (,$(filter nodhcp6,$(DEB_BUILD_OPTIONS)))
|
||||
|
||||
+27
-9
@@ -171,7 +171,12 @@ options. IP alias interfaces (eg "eth1:0") cannot be used with
|
||||
.B --interface
|
||||
or
|
||||
.B --except-interface
|
||||
options, use --listen-address instead.
|
||||
options, use --listen-address instead. A simple wildcard, consisting
|
||||
of a trailing '*', can be used in
|
||||
.B \--interface
|
||||
and
|
||||
.B \--except-interface
|
||||
options.
|
||||
.TP
|
||||
.B \-I, --except-interface=<interface name>
|
||||
Do not listen on the specified interface. Note that the order of
|
||||
@@ -553,7 +558,8 @@ Define a DNS zone for which dnsmasq acts as authoritative server. Locally define
|
||||
will be served, except that A and AAAA records must be in one of the
|
||||
specified subnets, or in a subnet corresponding to a contructed DHCP
|
||||
range. The subnet(s) are also used to define in-addr.arpa and
|
||||
ipv6.arpa domains which are served for reverse-DNS queries.
|
||||
ipv6.arpa domains which are served for reverse-DNS queries. For IPv4
|
||||
subnets, the prefix length is limited to the values 8, 16 or 24.
|
||||
.TP
|
||||
.B --auth-soa=<serial>[,<hostmaster>[,<refresh>[,<retry>[,<expiry>]]]]
|
||||
Specify fields in the SOA record associated with authoritative
|
||||
@@ -581,9 +587,9 @@ compiled in and the kernel must have conntrack support
|
||||
included and configured. This option cannot be combined with
|
||||
--query-port.
|
||||
.TP
|
||||
.B \-F, --dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag],]<start-addr>[,<end-addr>][,<mode>][,<netmask>[,<broadcast>]][,<lease time>]
|
||||
.B \-F, --dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag>,]<start-addr>[,<end-addr>][,<mode>][,<netmask>[,<broadcast>]][,<lease time>]
|
||||
.TP
|
||||
.B \-F, --dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag],]<start-IPv6addr>[,<end-IPv6addr>|constuctor:<interface>][,<mode>][,<prefix-len>][,<lease time>]
|
||||
.B \-F, --dhcp-range=[tag:<tag>[,tag:<tag>],][set:<tag>,]<start-IPv6addr>[,<end-IPv6addr>|constructor:<interface>][,<mode>][,<prefix-len>][,<lease time>]
|
||||
|
||||
Enable the DHCP server. Addresses will be given out from the range
|
||||
<start-addr> to <end-addr> and from statically defined addresses given
|
||||
@@ -619,7 +625,7 @@ IPv6 (only) supports another type of range. In this, the start address and optio
|
||||
.B constructor:<interface>.
|
||||
This forms a template which describes how to create ranges, based on the addresses assigned to the interface. For instance
|
||||
|
||||
.B --dhcp-range=::1,::4,constructor:eth0
|
||||
.B --dhcp-range=::1,::400,constructor:eth0
|
||||
|
||||
will look for addreses of the form <network>::1 on eth0 and then create a range from <network>::1 to <network>::400. If the interface is assigned more than one network, then the corresponding ranges will be automatically created, and then deprecated and finally removed again as the address is deprecated and then deleted. The interface name may have a final "*" wildcard.
|
||||
|
||||
@@ -1753,7 +1759,7 @@ we have
|
||||
.fi
|
||||
|
||||
.nf
|
||||
our.zone.com A 192.0.43.10
|
||||
our.zone.com A 1.2.3.4
|
||||
our.zone.com NS our.zone.com
|
||||
.fi
|
||||
|
||||
@@ -1766,11 +1772,23 @@ record. If the external address is static, this can be done with an
|
||||
.B /etc/hosts
|
||||
entry or
|
||||
.B --host-record.
|
||||
If the external address is dynamic,
|
||||
then it must be done using something like
|
||||
|
||||
.nf
|
||||
.B --interface-name=our.zone.com,eth0
|
||||
.B auth-server=our.zone.com,eth0
|
||||
.B host-record=our.zone.com,1.2.3.4
|
||||
.B auth-zone=our.zone.com,1.2.3.0/24
|
||||
.fi
|
||||
|
||||
If the external address is dynamic, the address
|
||||
associated with our.zone.com must be derived from the address of the
|
||||
relvant interface. This is done using
|
||||
.B interface-name
|
||||
Something like:
|
||||
|
||||
.nf
|
||||
.B auth-server=our.zone.com,eth0
|
||||
.B interface-name=our.zone.com,eth0
|
||||
.B auth-zone=our.zone.com,1.2.3.0/24
|
||||
.fi
|
||||
|
||||
Our final configuration builds on that above, but also adds a
|
||||
|
||||
+600
-405
File diff suppressed because it is too large.
Load diff
+3
-3
@@ -721,10 +721,10 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
||||
daemon->soa_retry, daemon->soa_expiry,
|
||||
daemon->auth_ttl))
|
||||
anscount++;
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* done all questions, set up header and return length of result */
|
||||
/* clear authoritative and truncated flags, set QR flag */
|
||||
|
||||
+2
-2
@@ -135,12 +135,12 @@ RESOLVFILE
|
||||
#define HAVE_TFTP
|
||||
#define HAVE_SCRIPT
|
||||
#define HAVE_AUTH
|
||||
#define HAVE_IPSET
|
||||
/* #define HAVE_LUASCRIPT */
|
||||
/* #define HAVE_BROKEN_RTC */
|
||||
/* #define HAVE_DBUS */
|
||||
/* #define HAVE_IDN */
|
||||
/* #define HAVE_CONNTRACK */
|
||||
/* #define HAVE_IPSET */
|
||||
|
||||
|
||||
/* Default locations for important system files. */
|
||||
@@ -327,7 +327,7 @@ HAVE_SOCKADDR_SA_LEN
|
||||
#undef HAVE_AUTH
|
||||
#endif
|
||||
|
||||
#ifndef HAVE_LINUX_NETWORK
|
||||
#if defined(NO_IPSET) || !defined(HAVE_LINUX_NETWORK)
|
||||
#undef HAVE_IPSET
|
||||
#endif
|
||||
|
||||
|
||||
+9
-3
@@ -91,6 +91,7 @@ struct dhcp_netid *option_filter(struct dhcp_netid *tags, struct dhcp_netid *con
|
||||
{
|
||||
struct dhcp_netid *tagif = run_tag_if(tags);
|
||||
struct dhcp_opt *opt;
|
||||
struct dhcp_opt *tmp;
|
||||
|
||||
/* flag options which are valid with the current tag set (sans context tags) */
|
||||
for (opt = opts; opt; opt = opt->next)
|
||||
@@ -135,7 +136,6 @@ struct dhcp_netid *option_filter(struct dhcp_netid *tags, struct dhcp_netid *con
|
||||
for (opt = opts; opt; opt = opt->next)
|
||||
if (!(opt->flags & (DHOPT_ENCAPSULATE | DHOPT_VENDOR | DHOPT_RFC3925 | DHOPT_TAGOK)) && !opt->netid)
|
||||
{
|
||||
struct dhcp_opt *tmp;
|
||||
for (tmp = opts; tmp; tmp = tmp->next)
|
||||
if (tmp->opt == opt->opt && (tmp->flags & DHOPT_TAGOK))
|
||||
break;
|
||||
@@ -145,6 +145,13 @@ struct dhcp_netid *option_filter(struct dhcp_netid *tags, struct dhcp_netid *con
|
||||
my_syslog(MS_DHCP | LOG_WARNING, _("Ignoring duplicate dhcp-option %d"), tmp->opt);
|
||||
}
|
||||
|
||||
/* Finally, eliminate duplicate options later in the chain, and therefore earlier in the config file. */
|
||||
for (opt = opts; opt; opt = opt->next)
|
||||
if (opt->flags & DHOPT_TAGOK)
|
||||
for (tmp = opt->next; tmp; tmp = tmp->next)
|
||||
if (tmp->opt == opt->opt)
|
||||
tmp->flags &= ~DHOPT_TAGOK;
|
||||
|
||||
return tagif;
|
||||
}
|
||||
|
||||
@@ -714,8 +721,7 @@ void log_context(int family, struct dhcp_context *context)
|
||||
template = p;
|
||||
p += sprintf(p, ", ");
|
||||
|
||||
sprintf(p, "template for %s%s", context->template_interface,
|
||||
(context->flags & CONTEXT_WILDCARD) ? "*" : "");
|
||||
sprintf(p, "template for %s", context->template_interface);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
+13
-5
@@ -65,14 +65,22 @@ static int make_fd(int port)
|
||||
|
||||
/* When bind-interfaces is set, there might be more than one dnmsasq
|
||||
instance binding port 67. That's OK if they serve different networks.
|
||||
Need to set REUSEADDR to make this posible, or REUSEPORT on *BSD. */
|
||||
Need to set REUSEADDR|REUSEPORT to make this posible.
|
||||
Handle the case that REUSEPORT is defined, but the kernel doesn't
|
||||
support it. This handles the introduction of REUSEPORT on Linux. */
|
||||
if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND))
|
||||
{
|
||||
int rc = -1, porterr = 0;
|
||||
|
||||
#ifdef SO_REUSEPORT
|
||||
int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, sizeof(oneopt));
|
||||
#else
|
||||
int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &oneopt, sizeof(oneopt));
|
||||
if ((rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, sizeof(oneopt))) == -1 &&
|
||||
errno != ENOPROTOOPT)
|
||||
porterr = 1;
|
||||
#endif
|
||||
|
||||
if (rc == -1 && !porterr)
|
||||
rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &oneopt, sizeof(oneopt));
|
||||
|
||||
if (rc == -1)
|
||||
die(_("failed to set SO_REUSE{ADDR|PORT} on DHCP socket: %s"), NULL, EC_BADNET);
|
||||
}
|
||||
@@ -252,7 +260,7 @@ void dhcp_packet(time_t now, int pxe_fd)
|
||||
}
|
||||
|
||||
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
||||
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
|
||||
if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
|
||||
return;
|
||||
|
||||
/* unlinked contexts are marked by context->current == context */
|
||||
|
||||
+40
-27
@@ -48,16 +48,24 @@ void dhcp6_init(void)
|
||||
!set_ipv6pktinfo(fd))
|
||||
die (_("cannot create DHCPv6 socket: %s"), NULL, EC_BADNET);
|
||||
|
||||
/* When bind-interfaces is set, there might be more than one dnmsasq
|
||||
/* When bind-interfaces is set, there might be more than one dnmsasq
|
||||
instance binding port 547. That's OK if they serve different networks.
|
||||
Need to set REUSEADDR to make this posible, or REUSEPORT on *BSD. */
|
||||
Need to set REUSEADDR|REUSEPORT to make this posible.
|
||||
Handle the case that REUSEPORT is defined, but the kernel doesn't
|
||||
support it. This handles the introduction of REUSEPORT on Linux. */
|
||||
if (option_bool(OPT_NOWILD) || option_bool(OPT_CLEVERBIND))
|
||||
{
|
||||
int rc = -1, porterr = 0;
|
||||
|
||||
#ifdef SO_REUSEPORT
|
||||
int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, sizeof(oneopt));
|
||||
#else
|
||||
int rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &oneopt, sizeof(oneopt));
|
||||
if ((rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, sizeof(oneopt))) == -1 &&
|
||||
errno != ENOPROTOOPT)
|
||||
porterr = 1;
|
||||
#endif
|
||||
|
||||
if (rc == -1 && !porterr)
|
||||
rc = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &oneopt, sizeof(oneopt));
|
||||
|
||||
if (rc == -1)
|
||||
die(_("failed to set SO_REUSE{ADDR|PORT} on DHCPv6 socket: %s"), NULL, EC_BADNET);
|
||||
}
|
||||
@@ -120,11 +128,11 @@ void dhcp6_packet(time_t now)
|
||||
return;
|
||||
|
||||
for (tmp = daemon->if_except; tmp; tmp = tmp->next)
|
||||
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
|
||||
if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
|
||||
return;
|
||||
|
||||
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
||||
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
|
||||
if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
|
||||
return;
|
||||
|
||||
parm.current = NULL;
|
||||
@@ -153,7 +161,7 @@ void dhcp6_packet(time_t now)
|
||||
{
|
||||
|
||||
for (tmp = daemon->if_names; tmp; tmp = tmp->next)
|
||||
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
|
||||
if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
|
||||
break;
|
||||
|
||||
if (!tmp && !parm.addr_match)
|
||||
@@ -326,7 +334,7 @@ struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned c
|
||||
} while (addr != start);
|
||||
}
|
||||
|
||||
return 0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* can dynamically allocate addr */
|
||||
@@ -371,31 +379,38 @@ struct dhcp_context *address6_valid(struct dhcp_context *context,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int is_config_in_context6(struct dhcp_context *context, struct dhcp_config *config)
|
||||
int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr)
|
||||
{
|
||||
/* expand wildcard on contructed contexts */
|
||||
if ((config->flags & CONFIG_WILDCARD) &&
|
||||
(context->flags & CONTEXT_CONSTRUCTED))
|
||||
if (!config || !(config->flags & CONFIG_ADDR6))
|
||||
return 0;
|
||||
|
||||
if ((config->flags & CONFIG_WILDCARD) && context->prefix == 64)
|
||||
{
|
||||
u64 addrpart = addr6part(&config->addr6);
|
||||
config->addr6 = context->start6;
|
||||
setaddr6part(&config->addr6, addrpart);
|
||||
*addr = context->start6;
|
||||
setaddr6part(addr, addr6part(&config->addr6));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (is_same_net6(&context->start6, &config->addr6, context->prefix))
|
||||
{
|
||||
*addr = config->addr6;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!(config->flags & CONFIG_ADDR6) || is_addr_in_context6(context, &config->addr6))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int is_addr_in_context6(struct dhcp_context *context, struct in6_addr *addr)
|
||||
static int is_config_in_context6(struct dhcp_context *context, struct dhcp_config *config)
|
||||
{
|
||||
for (; context; context = context->current)
|
||||
if (is_same_net6(addr, &context->start6, context->prefix))
|
||||
return 1;
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -523,9 +538,7 @@ static int construct_worker(struct in6_addr *local, int prefix,
|
||||
}
|
||||
|
||||
}
|
||||
else if (addr6part(local) == addr6part(&template->start6) &&
|
||||
strncmp(template->template_interface, ifrn_name, strlen(template->template_interface)) == 0 &&
|
||||
(strlen(template->template_interface) == strlen(ifrn_name) || (template->flags & CONTEXT_WILDCARD)))
|
||||
else if (addr6part(local) == addr6part(&template->start6) && wildcard_match(template->template_interface, ifrn_name))
|
||||
{
|
||||
start6 = *local;
|
||||
setaddr6part(&start6, addr6part(&template->start6));
|
||||
|
||||
+5
-2
@@ -543,6 +543,7 @@ struct dhcp_lease {
|
||||
int backoff; /* zero -> confirmed */
|
||||
struct slaac_address *next;
|
||||
} *slaac_address;
|
||||
int vendorclass_count;
|
||||
#endif
|
||||
struct dhcp_lease *next;
|
||||
};
|
||||
@@ -721,7 +722,7 @@ struct dhcp_context {
|
||||
#define CONTEXT_CONSTRUCTED 2048
|
||||
#define CONTEXT_GC 4096
|
||||
#define CONTEXT_RA 8192
|
||||
#define CONTEXT_WILDCARD 16384
|
||||
#define CONTEXT_CONF_USED 16384
|
||||
#define CONTEXT_USED 32768
|
||||
|
||||
struct ping_result {
|
||||
@@ -979,6 +980,8 @@ char *print_mac(char *buff, unsigned char *mac, int len);
|
||||
void bump_maxfd(int fd, int *max);
|
||||
int read_write(int fd, unsigned char *packet, int size, int rw);
|
||||
|
||||
int wildcard_match(const char* wildcard, const char* match);
|
||||
|
||||
/* log.c */
|
||||
void die(char *message, char *arg1, int exit_code);
|
||||
int log_start(struct passwd *ent_pw, int errfd);
|
||||
@@ -1175,7 +1178,7 @@ void dhcp6_init(void);
|
||||
void dhcp6_packet(time_t now);
|
||||
struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned char *clid, int clid_len,
|
||||
int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans);
|
||||
int is_addr_in_context6(struct dhcp_context *context, struct in6_addr *addr);
|
||||
int config_valid(struct dhcp_config *config, struct dhcp_context *context, struct in6_addr *addr);
|
||||
struct dhcp_context *address6_available(struct dhcp_context *context,
|
||||
struct in6_addr *taddr,
|
||||
struct dhcp_netid *netids,
|
||||
|
||||
+1
-1
@@ -680,7 +680,7 @@ void receive_query(struct listener *listen, time_t now)
|
||||
dst_addr_4.s_addr = 0;
|
||||
netmask.s_addr = 0;
|
||||
|
||||
if (listen->iface && option_bool(OPT_NOWILD))
|
||||
if (option_bool(OPT_NOWILD) && listen->iface)
|
||||
{
|
||||
auth_dns = listen->iface->dns_auth;
|
||||
|
||||
|
||||
+8
-2
@@ -655,8 +655,9 @@ void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t n
|
||||
unsigned char *p;
|
||||
unsigned int hostname_len = 0, clid_len = 0, ed_len = 0;
|
||||
int fd = daemon->dhcpfd;
|
||||
#ifdef HAVE_DHCP6
|
||||
int is6 = !!(lease->flags & (LEASE_TA | LEASE_NA));
|
||||
|
||||
#ifdef HAVE_DHCP6
|
||||
if (!daemon->dhcp)
|
||||
fd = daemon->dhcp6fd;
|
||||
#endif
|
||||
@@ -676,7 +677,12 @@ void queue_script(int action, struct dhcp_lease *lease, char *hostname, time_t n
|
||||
|
||||
buf->action = action;
|
||||
buf->flags = lease->flags;
|
||||
buf->hwaddr_len = lease->hwaddr_len;
|
||||
#ifdef HAVE_DHCP6
|
||||
if (is6)
|
||||
buf->hwaddr_len = lease->vendorclass_count;
|
||||
else
|
||||
#endif
|
||||
buf->hwaddr_len = lease->hwaddr_len;
|
||||
buf->hwaddr_type = lease->hwaddr_type;
|
||||
buf->clid_len = clid_len;
|
||||
buf->ed_len = ed_len;
|
||||
|
||||
+3
-1
@@ -115,7 +115,7 @@ void lease_init(time_t now)
|
||||
s++;
|
||||
}
|
||||
|
||||
hw_type = atoi(s);
|
||||
hw_type = strtoul(s, NULL, 10);
|
||||
|
||||
if ((lease = lease6_allocate(&addr.addr.addr6, lease_type)))
|
||||
{
|
||||
@@ -595,6 +595,8 @@ struct dhcp_lease *lease6_find_by_client(struct dhcp_lease *first, int lease_typ
|
||||
|
||||
if (!first)
|
||||
first = leases;
|
||||
else
|
||||
first = first->next;
|
||||
|
||||
for (lease = first; lease; lease = lease->next)
|
||||
{
|
||||
|
||||
+3
-3
@@ -123,7 +123,7 @@ int iface_check(int family, struct all_addr *addr, char *name, int *auth)
|
||||
ret = 0;
|
||||
|
||||
for (tmp = daemon->if_names; tmp; tmp = tmp->next)
|
||||
if (tmp->name && (strcmp(tmp->name, name) == 0))
|
||||
if (tmp->name && wildcard_match(tmp->name, name))
|
||||
ret = tmp->used = 1;
|
||||
|
||||
if (addr)
|
||||
@@ -143,7 +143,7 @@ int iface_check(int family, struct all_addr *addr, char *name, int *auth)
|
||||
}
|
||||
|
||||
for (tmp = daemon->if_except; tmp; tmp = tmp->next)
|
||||
if (tmp->name && (strcmp(tmp->name, name) == 0))
|
||||
if (tmp->name && wildcard_match(tmp->name, name))
|
||||
ret = 0;
|
||||
|
||||
|
||||
@@ -291,7 +291,7 @@ static int iface_allowed(struct irec **irecp, int if_index,
|
||||
}
|
||||
else
|
||||
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
||||
if (tmp->name && (strcmp(tmp->name, ifr.ifr_name) == 0))
|
||||
if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
|
||||
{
|
||||
tftp_ok = 0;
|
||||
dhcp_ok = 0;
|
||||
|
||||
@@ -2375,11 +2375,6 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma
|
||||
new->flags |= CONTEXT_DHCP;
|
||||
else if (strstr(a[leasepos], "constructor:") == a[leasepos])
|
||||
{
|
||||
if (a[leasepos][strlen(a[leasepos])-1] == '*')
|
||||
{
|
||||
a[leasepos][strlen(a[leasepos])-1] = 0;
|
||||
new->flags |= CONTEXT_WILDCARD;
|
||||
}
|
||||
new->template_interface = opt_string_alloc(a[leasepos] + 12);
|
||||
new->flags |= CONTEXT_TEMPLATE;
|
||||
}
|
||||
|
||||
+2
-2
@@ -158,7 +158,7 @@ void icmp6_packet(time_t now)
|
||||
return;
|
||||
|
||||
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
||||
if (tmp->name && (strcmp(tmp->name, interface) == 0))
|
||||
if (tmp->name && wildcard_match(tmp->name, interface))
|
||||
return;
|
||||
|
||||
if (packet[1] != 0)
|
||||
@@ -533,7 +533,7 @@ time_t periodic_ra(time_t now)
|
||||
{
|
||||
struct iname *tmp;
|
||||
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
||||
if (tmp->name && (strcmp(tmp->name, interface) == 0))
|
||||
if (tmp->name && wildcard_match(tmp->name, interface))
|
||||
break;
|
||||
if (!tmp)
|
||||
send_ra(now, param.iface, interface, NULL);
|
||||
|
||||
+183
-135
@@ -52,11 +52,15 @@ static void end_ia(int t1cntr, unsigned int min_time, int do_fuzz);
|
||||
static struct prefix_class *prefix_class_from_context(struct dhcp_context *context);
|
||||
#endif
|
||||
static void mark_context_used(struct state *state, struct dhcp_context *context, struct in6_addr *addr);
|
||||
static void mark_config_used(struct dhcp_context *context, struct in6_addr *addr);
|
||||
static int check_address(struct state *state, struct in6_addr *addr);
|
||||
static void add_address(struct state *state, struct dhcp_context *context, unsigned int lease_time, unsigned int requested_time,
|
||||
unsigned int *min_time, struct in6_addr *addr, int update_lease, time_t now);
|
||||
static void update_leases(struct state *state, struct dhcp_context *context, struct in6_addr *addr, unsigned int lease_time, time_t now);
|
||||
static int add_local_addrs(struct dhcp_context *context);
|
||||
struct dhcp_netid *add_options(struct state *state, struct in6_addr *fallback, struct dhcp_context *context);
|
||||
static void calculate_times(struct dhcp_context *context, unsigned int *min_time, unsigned int *valid_timep,
|
||||
unsigned int *preferred_timep, unsigned int lease_time, unsigned int requested_time);
|
||||
|
||||
#define opt6_len(opt) ((int)(opt6_uint(opt, -2, 2)))
|
||||
#define opt6_type(opt) (opt6_uint(opt, -4, 2))
|
||||
@@ -120,6 +124,7 @@ static int dhcp6_maybe_relay(struct in6_addr *link_address, struct dhcp_netid **
|
||||
is_same_net6(link_address, &c->start6, c->prefix) &&
|
||||
is_same_net6(link_address, &c->end6, c->prefix))
|
||||
{
|
||||
c->preferred = c->valid = 0xffffffff;
|
||||
c->current = context;
|
||||
context = c;
|
||||
}
|
||||
@@ -212,7 +217,8 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
unsigned int ignore = 0;
|
||||
struct state state;
|
||||
#ifdef OPTION6_PREFIX_CLASS
|
||||
struct prefix_class *p;
|
||||
struct prefix_class *p;
|
||||
int dump_all_prefix_classes = 0;
|
||||
#endif
|
||||
|
||||
state.packet_options = inbuff + 4;
|
||||
@@ -474,21 +480,32 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
ignore = 1;
|
||||
}
|
||||
|
||||
tagif = state.tags;
|
||||
|
||||
#ifdef OPTION6_PREFIX_CLASS
|
||||
/* Add the tags associated with prefix classes so we can use the DHCP ranges.
|
||||
These are removed and added back one-at-time for SOLICITs
|
||||
Neccessary to allow REQUEST or RENEW of addresses ADVERTISED under
|
||||
specific classes. */
|
||||
for (p = daemon->prefix_classes; p ; p = p->next)
|
||||
/* OPTION_PREFIX_CLASS in ORO, send addresses in all prefix classes */
|
||||
if (daemon->prefix_classes && (msg_type == DHCP6SOLICIT || msg_type == DHCP6REQUEST))
|
||||
{
|
||||
p->tag.next = tagif;
|
||||
tagif = &p->tag;
|
||||
}
|
||||
void *oro;
|
||||
|
||||
if ((oro = opt6_find(state.packet_options, state.end, OPTION6_ORO, 0)))
|
||||
for (i = 0; i < opt6_len(oro) - 1; i += 2)
|
||||
if (opt6_uint(oro, i, 2) == OPTION6_PREFIX_CLASS)
|
||||
{
|
||||
dump_all_prefix_classes = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (msg_type != DHCP6SOLICIT || dump_all_prefix_classes)
|
||||
/* Add the tags associated with prefix classes so we can use the DHCP ranges.
|
||||
Not done for SOLICIT as we add them one-at-time. */
|
||||
for (p = daemon->prefix_classes; p ; p = p->next)
|
||||
{
|
||||
p->tag.next = state.tags;
|
||||
state.tags = &p->tag;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
tagif = run_tag_if(tagif);
|
||||
tagif = run_tag_if(state.tags);
|
||||
|
||||
/* if all the netids in the ignore list are present, ignore this client */
|
||||
if (daemon->dhcp_ignore)
|
||||
@@ -522,9 +539,10 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
case DHCP6SOLICIT:
|
||||
{
|
||||
void *rapid_commit = opt6_find(state.packet_options, state.end, OPTION6_RAPID_COMMIT, 0);
|
||||
int used_config = 0, address_assigned = 0;
|
||||
int address_assigned = 0;
|
||||
/* tags without all prefix-class tags */
|
||||
struct dhcp_netid *solicit_tags = run_tag_if(state.tags);
|
||||
struct dhcp_netid *solicit_tags = tagif;
|
||||
struct dhcp_context *c;
|
||||
|
||||
if (rapid_commit)
|
||||
{
|
||||
@@ -535,49 +553,35 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
/* set reply message type */
|
||||
*outmsgtypep = rapid_commit ? DHCP6REPLY : DHCP6ADVERTISE;
|
||||
|
||||
log6_packet(&state, "DHCPSOLICIT", NULL, ignore ? "ignored" : NULL);
|
||||
log6_packet(&state, "DHCPSOLICIT", NULL, ignore ? _("ignored") : NULL);
|
||||
|
||||
if (ignore)
|
||||
return 0;
|
||||
|
||||
/* reset USED bits in leases */
|
||||
lease6_reset();
|
||||
|
||||
|
||||
/* Can use configured address max once per prefix */
|
||||
for (c = context; c; c = c->current)
|
||||
c->flags &= ~CONTEXT_CONF_USED;
|
||||
|
||||
for (opt = state.packet_options; opt; opt = opt6_next(opt, state.end))
|
||||
{
|
||||
void *ia_option, *ia_end;
|
||||
unsigned int min_time = 0xffffffff;
|
||||
int t1cntr;
|
||||
int config_ok = 0;
|
||||
int ia_counter;
|
||||
/* set unless we're sending a particular prefix-class, when we
|
||||
want only dhcp-ranges with the correct tags set and not those without any tags. */
|
||||
int plain_range = 1;
|
||||
struct dhcp_context *c;
|
||||
u32 lease_time, requested_time;
|
||||
struct dhcp_lease *ltmp;
|
||||
struct in6_addr *req_addr;
|
||||
struct in6_addr addr;
|
||||
#ifdef OPTION6_PREFIX_CLASS
|
||||
int dump_all_prefix_classes = 0;
|
||||
#endif
|
||||
|
||||
if (!check_ia(&state, opt, &ia_end, &ia_option))
|
||||
continue;
|
||||
|
||||
if (have_config(config, CONFIG_ADDR6))
|
||||
{
|
||||
struct dhcp_lease *config_lease = lease6_find_by_addr(&config->addr6, 128, 0);
|
||||
|
||||
config_ok = 1;
|
||||
|
||||
if (config_lease &&
|
||||
(config_lease->clid_len != state.clid_len ||
|
||||
memcmp(config_lease->clid, state.clid, state.clid_len) != 0 ||
|
||||
config_lease->hwaddr_type != state.iaid))
|
||||
config_ok = 0; /* configured address leased elsewhere */
|
||||
}
|
||||
|
||||
/* reset USED bits in contexts - one address per prefix per IAID */
|
||||
for (c = context; c; c = c->current)
|
||||
c->flags &= ~CONTEXT_USED;
|
||||
@@ -585,20 +589,12 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
#ifdef OPTION6_PREFIX_CLASS
|
||||
if (daemon->prefix_classes && state.ia_type == OPTION6_IA_NA)
|
||||
{
|
||||
void *prefix_opt, *oro;
|
||||
void *prefix_opt;
|
||||
int prefix_class;
|
||||
|
||||
if ((oro = opt6_find(state.packet_options, state.end, OPTION6_ORO, 0)))
|
||||
for (i = 0; i < opt6_len(oro) - 1; i += 2)
|
||||
if (opt6_uint(oro, i, 2) == OPTION6_PREFIX_CLASS)
|
||||
break;
|
||||
|
||||
if (oro && (i < opt6_len(oro) - 1))
|
||||
{
|
||||
/* OPTION_PREFIX_CLASS in ORO, send addresses in all prefix classes */
|
||||
plain_range = 0;
|
||||
dump_all_prefix_classes = 1;
|
||||
}
|
||||
if (dump_all_prefix_classes)
|
||||
/* OPTION_PREFIX_CLASS in ORO, send addresses in all prefix classes */
|
||||
plain_range = 0;
|
||||
else
|
||||
{
|
||||
if ((prefix_opt = opt6_find(opt6_ptr(opt, 12), ia_end, OPTION6_PREFIX_CLASS, 2)))
|
||||
@@ -649,33 +645,29 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
for (ia_counter = 0; ia_option; ia_counter++, ia_option = opt6_find(opt6_next(ia_option, ia_end), ia_end, OPTION6_IAADDR, 24))
|
||||
{
|
||||
req_addr = opt6_ptr(ia_option, 0);
|
||||
ltmp = lease6_find_by_addr(req_addr, 128, 0);
|
||||
requested_time = opt6_uint(ia_option, 16, 4);
|
||||
|
||||
|
||||
if ((c = address6_valid(context, req_addr, solicit_tags, plain_range)))
|
||||
{
|
||||
lease_time = c->lease_time;
|
||||
/* If the client asks for an address on the same network as a configured address,
|
||||
offer the configured address instead, to make moving to newly-configured
|
||||
addresses automatic. */
|
||||
if (!used_config && config_ok && is_same_net6(req_addr, &config->addr6, c->prefix))
|
||||
if (!(c->flags & CONTEXT_CONF_USED) && config_valid(config, c, &addr) && check_address(&state, &addr))
|
||||
{
|
||||
req_addr = &config->addr6;
|
||||
used_config = 1;
|
||||
req_addr = &addr;
|
||||
mark_config_used(c, &addr);
|
||||
if (have_config(config, CONFIG_TIME))
|
||||
lease_time = config->lease_time;
|
||||
}
|
||||
else if (!(c = address6_available(context, req_addr, solicit_tags, plain_range)))
|
||||
continue; /* not an address we're allowed */
|
||||
else if (ltmp &&
|
||||
(ltmp->clid_len != state.clid_len ||
|
||||
memcmp(ltmp->clid, state.clid, state.clid_len) != 0 ||
|
||||
ltmp->hwaddr_type != state.iaid))
|
||||
else if (!check_address(&state, req_addr))
|
||||
continue; /* address leased elsewhere */
|
||||
|
||||
/* add address to output packet */
|
||||
#ifdef OPTION6_PREFIX_CLASS
|
||||
if (dump_all_prefix_classes)
|
||||
if (dump_all_prefix_classes && state.ia_type == OPTION6_IA_NA)
|
||||
state.send_prefix_class = prefix_class_from_context(c);
|
||||
#endif
|
||||
add_address(&state, c, lease_time, requested_time, &min_time, req_addr, rapid_commit != NULL, now);
|
||||
@@ -685,23 +677,29 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
}
|
||||
}
|
||||
|
||||
/* Suggest configured address */
|
||||
if (!used_config && config_ok && (c = address6_valid(context, &config->addr6, solicit_tags, plain_range)))
|
||||
{
|
||||
used_config = 1;
|
||||
if (have_config(config, CONFIG_TIME))
|
||||
lease_time = config->lease_time;
|
||||
/* add address to output packet */
|
||||
/* Suggest configured address(es) */
|
||||
for (c = context; c; c = c->current)
|
||||
if (!(c->flags & CONTEXT_CONF_USED) &&
|
||||
match_netid(c->filter, solicit_tags, plain_range) &&
|
||||
config_valid(config, c, &addr) &&
|
||||
check_address(&state, &addr))
|
||||
{
|
||||
mark_config_used(context, &addr);
|
||||
if (have_config(config, CONFIG_TIME))
|
||||
lease_time = config->lease_time;
|
||||
else
|
||||
lease_time = c->lease_time;
|
||||
/* add address to output packet */
|
||||
#ifdef OPTION6_PREFIX_CLASS
|
||||
if (dump_all_prefix_classes)
|
||||
state.send_prefix_class = prefix_class_from_context(c);
|
||||
if (dump_all_prefix_classes && state.ia_type == OPTION6_IA_NA)
|
||||
state.send_prefix_class = prefix_class_from_context(c);
|
||||
#endif
|
||||
add_address(&state, c, lease_time, requested_time, &min_time, &config->addr6, rapid_commit != NULL, now);
|
||||
mark_context_used(&state, context, &config->addr6);
|
||||
get_context_tag(&state, c);
|
||||
address_assigned = 1;
|
||||
}
|
||||
|
||||
add_address(&state, c, lease_time, lease_time, &min_time, &addr, rapid_commit != NULL, now);
|
||||
mark_context_used(&state, context, &addr);
|
||||
get_context_tag(&state, c);
|
||||
address_assigned = 1;
|
||||
}
|
||||
|
||||
/* return addresses for existing leases */
|
||||
ltmp = NULL;
|
||||
while ((ltmp = lease6_find_by_client(ltmp, state.ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA, state.clid, state.clid_len, state.iaid)))
|
||||
@@ -710,7 +708,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
if ((c = address6_available(context, req_addr, solicit_tags, plain_range)))
|
||||
{
|
||||
#ifdef OPTION6_PREFIX_CLASS
|
||||
if (dump_all_prefix_classes)
|
||||
if (dump_all_prefix_classes && state.ia_type == OPTION6_IA_NA)
|
||||
state.send_prefix_class = prefix_class_from_context(c);
|
||||
#endif
|
||||
add_address(&state, c, c->lease_time, c->lease_time, &min_time, req_addr, rapid_commit != NULL, now);
|
||||
@@ -724,7 +722,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
while ((c = address6_allocate(context, state.clid, state.clid_len, state.iaid, ia_counter, solicit_tags, plain_range, &addr)))
|
||||
{
|
||||
#ifdef OPTION6_PREFIX_CLASS
|
||||
if (dump_all_prefix_classes)
|
||||
if (dump_all_prefix_classes && state.ia_type == OPTION6_IA_NA)
|
||||
state.send_prefix_class = prefix_class_from_context(c);
|
||||
#endif
|
||||
add_address(&state, c, c->lease_time, c->lease_time, &min_time, &addr, rapid_commit != NULL, now);
|
||||
@@ -741,7 +739,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
{
|
||||
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||
put_opt6_short(DHCP6SUCCESS);
|
||||
put_opt6_string("Oh hai from dnsmasq");
|
||||
put_opt6_string(_("success"));
|
||||
end_opt6(o1);
|
||||
|
||||
/* If --dhcp-authoritative is set, we can tell client not to wait for
|
||||
@@ -756,9 +754,9 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
/* no address, return error */
|
||||
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||
put_opt6_short(DHCP6NOADDRS);
|
||||
put_opt6_string("No addresses available");
|
||||
put_opt6_string(_("no addresses available"));
|
||||
end_opt6(o1);
|
||||
log6_packet(&state, "DHCPADVERTISE", NULL, _("No addresses available"));
|
||||
log6_packet(&state, "DHCPADVERTISE", NULL, _("no addresses available"));
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -771,7 +769,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
/* set reply message type */
|
||||
*outmsgtypep = DHCP6REPLY;
|
||||
|
||||
log6_packet(&state, "DHCPREQUEST", NULL, ignore ? "ignored" : NULL);
|
||||
log6_packet(&state, "DHCPREQUEST", NULL, ignore ? _("ignored") : NULL);
|
||||
|
||||
if (ignore)
|
||||
return 0;
|
||||
@@ -793,24 +791,28 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
u32 requested_time = opt6_uint(ia_option, 16, 4);
|
||||
struct dhcp_context *dynamic, *c;
|
||||
unsigned int lease_time;
|
||||
|
||||
if ((dynamic = address6_available(context, req_addr, tagif, 1)) || (c = address6_valid(context, req_addr, tagif, 1)))
|
||||
struct in6_addr addr;
|
||||
int config_ok = 0;
|
||||
|
||||
if ((c = address6_valid(context, req_addr, tagif, 1)))
|
||||
config_ok = config_valid(config, c, &addr) && IN6_ARE_ADDR_EQUAL(&addr, req_addr);
|
||||
|
||||
if ((dynamic = address6_available(context, req_addr, tagif, 1)) || c)
|
||||
{
|
||||
if (!dynamic && !(have_config(config, CONFIG_ADDR6) || !IN6_ARE_ADDR_EQUAL(&config->addr6, req_addr)))
|
||||
if (!dynamic && !config_ok)
|
||||
{
|
||||
/* Static range, not configured. */
|
||||
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||
put_opt6_short(DHCP6UNSPEC);
|
||||
put_opt6_string("Address unavailable");
|
||||
put_opt6_string(_("address unavailable"));
|
||||
end_opt6(o1);
|
||||
}
|
||||
else if (lease6_find_by_addr(req_addr, 128, 0) &&
|
||||
!lease6_find(state.clid, state.clid_len, state.ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA, state.iaid, req_addr))
|
||||
else if (!check_address(&state, req_addr))
|
||||
{
|
||||
/* Address leased to another DUID/IAID */
|
||||
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||
put_opt6_short(DHCP6UNSPEC);
|
||||
put_opt6_string("Address in use");
|
||||
put_opt6_string(_("address in use"));
|
||||
end_opt6(o1);
|
||||
}
|
||||
else
|
||||
@@ -820,22 +822,24 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
|
||||
lease_time = dynamic->lease_time;
|
||||
|
||||
if (have_config(config, CONFIG_ADDR6) &&
|
||||
IN6_ARE_ADDR_EQUAL(&config->addr6, req_addr) &&
|
||||
have_config(config, CONFIG_TIME))
|
||||
if (config_ok && have_config(config, CONFIG_TIME))
|
||||
lease_time = config->lease_time;
|
||||
|
||||
#ifdef OPTION6_PREFIX_CLASS
|
||||
if (dump_all_prefix_classes && state.ia_type == OPTION6_IA_NA)
|
||||
state.send_prefix_class = prefix_class_from_context(c);
|
||||
#endif
|
||||
add_address(&state, dynamic, lease_time, requested_time, &min_time, req_addr, 1, now);
|
||||
get_context_tag(&state, dynamic);
|
||||
address_assigned = 1;
|
||||
}
|
||||
}
|
||||
else if (msg_type == DHCP6REQUEST)
|
||||
else
|
||||
{
|
||||
/* requested address not on the correct link */
|
||||
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||
put_opt6_short(DHCP6NOTONLINK);
|
||||
put_opt6_string("Not on link");
|
||||
put_opt6_string(_("not on link"));
|
||||
end_opt6(o1);
|
||||
}
|
||||
}
|
||||
@@ -848,7 +852,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
{
|
||||
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||
put_opt6_short(DHCP6SUCCESS);
|
||||
put_opt6_string("Oh hai from dnsmasq");
|
||||
put_opt6_string(_("success"));
|
||||
end_opt6(o1);
|
||||
}
|
||||
else
|
||||
@@ -856,9 +860,9 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
/* no address, return error */
|
||||
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||
put_opt6_short(DHCP6NOADDRS);
|
||||
put_opt6_string("No addresses available");
|
||||
put_opt6_string(_("no addresses available"));
|
||||
end_opt6(o1);
|
||||
log6_packet(&state, "DHCPREPLY", NULL, _("No addresses available"));
|
||||
log6_packet(&state, "DHCPREPLY", NULL, _("no addresses available"));
|
||||
}
|
||||
|
||||
tagif = add_options(&state, fallback, context);
|
||||
@@ -890,14 +894,11 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
struct dhcp_lease *lease = NULL;
|
||||
struct in6_addr *req_addr = opt6_ptr(ia_option, 0);
|
||||
u32 requested_time = opt6_uint(ia_option, 16, 4);
|
||||
unsigned int lease_time;
|
||||
unsigned int preferred_time = 0; /* in case renewal inappropriate */
|
||||
unsigned int valid_time = 0;
|
||||
char *message = NULL;
|
||||
struct dhcp_context *this_context;
|
||||
struct dhcp_config *valid_config = config;
|
||||
|
||||
/* don't use a config to set lease time if it specifies an address which isn't this. */
|
||||
if (have_config(config, CONFIG_ADDR6) && !IN6_ARE_ADDR_EQUAL(&config->addr6, req_addr))
|
||||
valid_config = NULL;
|
||||
|
||||
if (!(lease = lease6_find(state.clid, state.clid_len,
|
||||
state.ia_type == OPTION6_IA_NA ? LEASE_NA : LEASE_TA,
|
||||
state.iaid, req_addr)))
|
||||
@@ -908,11 +909,11 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
save_counter(iacntr);
|
||||
t1cntr = 0;
|
||||
|
||||
log6_packet(&state, "DHCPREPLY", req_addr, "lease not found");
|
||||
log6_packet(&state, "DHCPREPLY", req_addr, _("lease not found"));
|
||||
|
||||
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||
put_opt6_short(DHCP6NOBINDING);
|
||||
put_opt6_string("No binding found");
|
||||
put_opt6_string(_("no binding found"));
|
||||
end_opt6(o1);
|
||||
break;
|
||||
}
|
||||
@@ -921,35 +922,41 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
if ((this_context = address6_available(context, req_addr, tagif, 1)) ||
|
||||
(this_context = address6_valid(context, req_addr, tagif, 1)))
|
||||
{
|
||||
struct in6_addr addr;
|
||||
unsigned int lease_time;
|
||||
|
||||
get_context_tag(&state, this_context);
|
||||
|
||||
lease_time = have_config(valid_config, CONFIG_TIME) ? valid_config->lease_time : this_context->lease_time;
|
||||
if (config_valid(config, this_context, &addr) && IN6_ARE_ADDR_EQUAL(&addr, req_addr) && have_config(config, CONFIG_TIME))
|
||||
lease_time = config->lease_time;
|
||||
else
|
||||
lease_time = this_context->lease_time;
|
||||
|
||||
if (requested_time < 120u )
|
||||
requested_time = 120u; /* sanity */
|
||||
if (lease_time == 0xffffffff || (requested_time != 0xffffffff && requested_time < lease_time))
|
||||
lease_time = requested_time;
|
||||
calculate_times(this_context, &min_time, &valid_time, &preferred_time, lease_time, requested_time);
|
||||
|
||||
lease_set_expires(lease, lease_time, now);
|
||||
lease_set_expires(lease, valid_time, now);
|
||||
if (state.ia_type == OPTION6_IA_NA && state.hostname)
|
||||
{
|
||||
char *addr_domain = get_domain6(req_addr);
|
||||
if (!state.send_domain)
|
||||
state.send_domain = addr_domain;
|
||||
lease_set_hostname(lease, state.hostname, state.hostname_auth, addr_domain, state.domain);
|
||||
lease_set_hostname(lease, state.hostname, state.hostname_auth, addr_domain, state.domain);
|
||||
message = state.hostname;
|
||||
}
|
||||
|
||||
if (lease_time < min_time)
|
||||
min_time = lease_time;
|
||||
|
||||
if (preferred_time == 0)
|
||||
message = _("deprecated");
|
||||
}
|
||||
else
|
||||
message = _("address invalid");
|
||||
|
||||
log6_packet(&state, "DHCPREPLY", req_addr, state.hostname);
|
||||
log6_packet(&state, "DHCPREPLY", req_addr, message);
|
||||
|
||||
o1 = new_opt6(OPTION6_IAADDR);
|
||||
put_opt6(req_addr, sizeof(*req_addr));
|
||||
/* preferred lifetime */
|
||||
put_opt6_long(!this_context || (this_context->flags & CONTEXT_DEPRECATE) ? 0 : lease_time);
|
||||
put_opt6_long(!this_context ? 0 : lease_time); /* valid lifetime */
|
||||
put_opt6_long(preferred_time);
|
||||
put_opt6_long(valid_time);
|
||||
end_opt6(o1);
|
||||
}
|
||||
|
||||
@@ -983,7 +990,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
{
|
||||
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||
put_opt6_short(DHCP6NOTONLINK);
|
||||
put_opt6_string("Confirm failed");
|
||||
put_opt6_string(_("confirm failed"));
|
||||
end_opt6(o1);
|
||||
return 1;
|
||||
}
|
||||
@@ -994,7 +1001,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
|
||||
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||
put_opt6_short(DHCP6SUCCESS );
|
||||
put_opt6_string("All addresses still on link");
|
||||
put_opt6_string(_("all addresses still on link"));
|
||||
end_opt6(o1);
|
||||
break;
|
||||
}
|
||||
@@ -1008,7 +1015,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
context->netid.next = NULL;
|
||||
state.context_tags = &context->netid;
|
||||
}
|
||||
log6_packet(&state, "DHCPINFORMATION-REQUEST", NULL, ignore ? "ignored" : state.hostname);
|
||||
log6_packet(&state, "DHCPINFORMATION-REQUEST", NULL, ignore ? _("ignored") : state.hostname);
|
||||
if (ignore)
|
||||
return 0;
|
||||
*outmsgtypep = DHCP6REPLY;
|
||||
@@ -1064,7 +1071,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
{
|
||||
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||
put_opt6_short(DHCP6NOBINDING);
|
||||
put_opt6_string("No binding found");
|
||||
put_opt6_string(_("no binding found"));
|
||||
end_opt6(o1);
|
||||
|
||||
end_opt6(o);
|
||||
@@ -1073,7 +1080,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
|
||||
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||
put_opt6_short(DHCP6SUCCESS);
|
||||
put_opt6_string("Release received");
|
||||
put_opt6_string(_("release received"));
|
||||
end_opt6(o1);
|
||||
|
||||
break;
|
||||
@@ -1141,7 +1148,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
{
|
||||
o1 = new_opt6(OPTION6_STATUS_CODE);
|
||||
put_opt6_short(DHCP6NOBINDING);
|
||||
put_opt6_string("No binding found");
|
||||
put_opt6_string(_("no binding found"));
|
||||
end_opt6(o1);
|
||||
|
||||
end_opt6(o);
|
||||
@@ -1459,24 +1466,16 @@ static void end_ia(int t1cntr, unsigned int min_time, int do_fuzz)
|
||||
static void add_address(struct state *state, struct dhcp_context *context, unsigned int lease_time, unsigned int requested_time,
|
||||
unsigned int *min_time, struct in6_addr *addr, int do_update, time_t now)
|
||||
{
|
||||
unsigned int valid_time = (context->valid < lease_time) ? context->valid : lease_time;
|
||||
unsigned int valid_time, preferred_time;
|
||||
int o = new_opt6(OPTION6_IAADDR);
|
||||
struct dhcp_lease *lease;
|
||||
|
||||
calculate_times(context, min_time, &valid_time, &preferred_time, lease_time, requested_time);
|
||||
|
||||
put_opt6(addr, sizeof(*addr));
|
||||
put_opt6_long(preferred_time);
|
||||
put_opt6_long(valid_time);
|
||||
|
||||
/* preferred lifetime */
|
||||
if (requested_time < 120u )
|
||||
requested_time = 120u; /* sanity */
|
||||
if (lease_time == 0xffffffff || (requested_time != 0xffffffff && requested_time < lease_time))
|
||||
lease_time = requested_time;
|
||||
|
||||
if (lease_time < *min_time)
|
||||
*min_time = lease_time;
|
||||
|
||||
put_opt6_long((context->preferred < lease_time) ? context->preferred : lease_time);
|
||||
put_opt6_long(valid_time); /* valid lifetime */
|
||||
|
||||
#ifdef OPTION6_PREFIX_CLASS
|
||||
if (state->send_prefix_class)
|
||||
{
|
||||
@@ -1532,6 +1531,55 @@ static void mark_context_used(struct state *state, struct dhcp_context *context,
|
||||
#endif
|
||||
}
|
||||
|
||||
static void mark_config_used(struct dhcp_context *context, struct in6_addr *addr)
|
||||
{
|
||||
for (; context; context = context->current)
|
||||
if (is_same_net6(addr, &context->start6, context->prefix))
|
||||
context->flags |= CONTEXT_CONF_USED;
|
||||
}
|
||||
|
||||
/* make sure address not leased to another CLID/IAID */
|
||||
static int check_address(struct state *state, struct in6_addr *addr)
|
||||
{
|
||||
struct dhcp_lease *lease;
|
||||
|
||||
if (!(lease = lease6_find_by_addr(addr, 128, 0)))
|
||||
return 1;
|
||||
|
||||
if (lease->clid_len != state->clid_len ||
|
||||
memcmp(lease->clid, state->clid, state->clid_len) != 0 ||
|
||||
lease->hwaddr_type != state->iaid)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void calculate_times(struct dhcp_context *context, unsigned int *min_time, unsigned int *valid_timep,
|
||||
unsigned int *preferred_timep, unsigned int lease_time, unsigned int requested_time)
|
||||
{
|
||||
unsigned int preferred_time, valid_time;
|
||||
|
||||
if (requested_time < 120u )
|
||||
requested_time = 120u; /* sanity */
|
||||
if (lease_time == 0xffffffff || (requested_time != 0xffffffff && requested_time < lease_time))
|
||||
lease_time = requested_time;
|
||||
|
||||
valid_time = (context->valid < lease_time) ? context->valid : lease_time;
|
||||
preferred_time = (context->preferred < lease_time) ? context->preferred : lease_time;
|
||||
|
||||
if (context->flags & CONTEXT_DEPRECATE)
|
||||
preferred_time = 0;
|
||||
|
||||
if (preferred_time != 0 && preferred_time < *min_time)
|
||||
*min_time = preferred_time;
|
||||
|
||||
if (valid_time != 0 && valid_time < *min_time)
|
||||
*min_time = valid_time;
|
||||
|
||||
*valid_timep = valid_time;
|
||||
*preferred_timep = preferred_time;
|
||||
}
|
||||
|
||||
static void update_leases(struct state *state, struct dhcp_context *context, struct in6_addr *addr, unsigned int lease_time, time_t now)
|
||||
{
|
||||
struct dhcp_lease *lease = lease6_find_by_addr(addr, 128, 0);
|
||||
@@ -1561,12 +1609,12 @@ static void update_leases(struct state *state, struct dhcp_context *context, str
|
||||
free(lease->extradata);
|
||||
lease->extradata = NULL;
|
||||
lease->extradata_size = lease->extradata_len = 0;
|
||||
lease->hwaddr_len = 0; /* surrogate for no of vendor classes */
|
||||
lease->vendorclass_count = 0;
|
||||
|
||||
if ((class_opt = opt6_find(state->packet_options, state->end, OPTION6_VENDOR_CLASS, 4)))
|
||||
{
|
||||
void *enc_opt, *enc_end = opt6_ptr(class_opt, opt6_len(class_opt));
|
||||
lease->hwaddr_len++;
|
||||
lease->vendorclass_count++;
|
||||
/* send enterprise number first */
|
||||
sprintf(daemon->dhcp_buff2, "%u", opt6_uint(class_opt, 0, 4));
|
||||
lease_add_extradata(lease, (unsigned char *)daemon->dhcp_buff2, strlen(daemon->dhcp_buff2), 0);
|
||||
@@ -1574,7 +1622,7 @@ static void update_leases(struct state *state, struct dhcp_context *context, str
|
||||
if (opt6_len(class_opt) >= 6)
|
||||
for (enc_opt = opt6_ptr(class_opt, 4); enc_opt; enc_opt = opt6_next(enc_opt, enc_end))
|
||||
{
|
||||
lease->hwaddr_len++;
|
||||
lease->vendorclass_count++;
|
||||
lease_add_extradata(lease, opt6_ptr(enc_opt, 0), opt6_len(enc_opt), 0);
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -209,7 +209,7 @@ void tftp_request(struct listener *listen, time_t now)
|
||||
#ifdef HAVE_DHCP
|
||||
/* allowed interfaces are the same as for DHCP */
|
||||
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
|
||||
if (tmp->name && (strcmp(tmp->name, name) == 0))
|
||||
if (tmp->name && wildcard_match(tmp->name, name))
|
||||
return;
|
||||
#endif
|
||||
|
||||
|
||||
+17
@@ -581,3 +581,20 @@ int read_write(int fd, unsigned char *packet, int size, int rw)
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Basically match a string value against a wildcard pattern. */
|
||||
int wildcard_match(const char* wildcard, const char* match)
|
||||
{
|
||||
while (*wildcard && *match)
|
||||
{
|
||||
if (*wildcard == '*')
|
||||
return 1;
|
||||
|
||||
if (*wildcard != *match)
|
||||
return 0;
|
||||
|
||||
++wildcard;
|
||||
++match;
|
||||
}
|
||||
|
||||
return *wildcard == *match;
|
||||
}
|
||||
Reference in new issue
Block a user