mirror of
http://thekelleys.org.uk/git/dnsmasq.git
synced 2026-11-04 13:48:30 +00:00
Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e44ddcac63 | ||
|
|
00e9ad5217 | ||
|
|
96c3879bed |
No files matched your search
Vendored
+2
-2
@@ -33,8 +33,8 @@ ifeq ($(DEB_BUILD_ARCH_OS),linux)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq (,$(filter nodhcp6,$(DEB_BUILD_OPTIONS)))
|
||||
COPTS += -DHAVE_DHCP6
|
||||
ifneq (,$(filter nodhcp6,$(DEB_BUILD_OPTIONS)))
|
||||
COPTS += -DNO_DHCP6
|
||||
endif
|
||||
|
||||
ifneq (,$(filter noipv6,$(DEB_BUILD_OPTIONS)))
|
||||
|
||||
+2
-2
@@ -332,9 +332,9 @@ void dhcp_update_configs(struct dhcp_config *configs)
|
||||
}
|
||||
|
||||
#ifdef HAVE_DHCP6
|
||||
if (prot == AF_INET6 && !config_find_by_address6(configs, &crec->addr.addr.addr.addr6, 129, 0))
|
||||
if (prot == AF_INET6 && !config_find_by_address6(configs, &crec->addr.addr.addr.addr6, 128, 0))
|
||||
{
|
||||
memcpy(config->hwaddr, &crec->addr.addr.addr.addr6, IN6ADDRSZ);
|
||||
memcpy(&config->addr6, &crec->addr.addr.addr.addr6, IN6ADDRSZ);
|
||||
config->flags |= CONFIG_ADDR6 | CONFIG_ADDR_HOSTS;
|
||||
continue;
|
||||
}
|
||||
|
||||
+34
-20
@@ -20,6 +20,7 @@
|
||||
|
||||
struct iface_param {
|
||||
struct dhcp_context *current;
|
||||
struct in6_addr fallback;
|
||||
int ind;
|
||||
};
|
||||
|
||||
@@ -200,10 +201,14 @@ void dhcp6_packet(time_t now)
|
||||
|
||||
/* unlinked contexts are marked by context->current == context */
|
||||
for (context = daemon->dhcp6; context; context = context->next)
|
||||
context->current = context;
|
||||
|
||||
{
|
||||
context->current = context;
|
||||
memset(&context->local6, 0, IN6ADDRSZ);
|
||||
}
|
||||
|
||||
parm.current = NULL;
|
||||
parm.ind = if_index;
|
||||
memset(&parm.fallback, 0, IN6ADDRSZ);
|
||||
|
||||
if (!iface_enumerate(AF_INET6, &parm, complete_context6))
|
||||
return;
|
||||
@@ -211,7 +216,7 @@ void dhcp6_packet(time_t now)
|
||||
lease_prune(NULL, now); /* lose any expired leases */
|
||||
|
||||
msg.msg_iov = &daemon->dhcp_packet;
|
||||
sz = dhcp6_reply(parm.current, if_index, ifr.ifr_name, sz, IN6_IS_ADDR_MULTICAST(&from.in6.sin6_addr), now);
|
||||
sz = dhcp6_reply(parm.current, if_index, ifr.ifr_name, &parm.fallback, sz, IN6_IS_ADDR_MULTICAST(&from.in6.sin6_addr), now);
|
||||
|
||||
lease_update_file(now);
|
||||
lease_update_dns();
|
||||
@@ -229,23 +234,32 @@ static int complete_context6(struct in6_addr *local, int prefix,
|
||||
|
||||
(void)scope; /* warning */
|
||||
(void)dad;
|
||||
|
||||
for (context = daemon->dhcp6; context; context = context->next)
|
||||
|
||||
if (if_index == param->ind &&
|
||||
!IN6_IS_ADDR_LOOPBACK(local) &&
|
||||
!IN6_IS_ADDR_LINKLOCAL(local) &&
|
||||
!IN6_IS_ADDR_MULTICAST(local))
|
||||
{
|
||||
if (prefix == context->prefix &&
|
||||
!IN6_IS_ADDR_LOOPBACK(local) &&
|
||||
!IN6_IS_ADDR_LINKLOCAL(local) &&
|
||||
!IN6_IS_ADDR_MULTICAST(local) &&
|
||||
is_same_net6(local, &context->start6, prefix) &&
|
||||
is_same_net6(local, &context->end6, prefix))
|
||||
{
|
||||
/* link it onto the current chain if we've not seen it before */
|
||||
if (if_index == param->ind && context->current == context)
|
||||
{
|
||||
context->current = param->current;
|
||||
param->current = context;
|
||||
context->local6 = *local;
|
||||
}
|
||||
/* Determine a globally address on the arrival interface, even
|
||||
if we have no matching dhcp-context, because we're only
|
||||
allocating on remote subnets via relays. This
|
||||
is used as a default for the DNS server option. */
|
||||
memcpy(¶m->fallback, &local, IN6ADDRSZ);
|
||||
|
||||
for (context = daemon->dhcp6; context; context = context->next)
|
||||
{
|
||||
if (prefix == context->prefix &&
|
||||
is_same_net6(local, &context->start6, prefix) &&
|
||||
is_same_net6(local, &context->end6, prefix))
|
||||
{
|
||||
/* link it onto the current chain if we've not seen it before */
|
||||
if (context->current == context)
|
||||
{
|
||||
context->current = param->current;
|
||||
param->current = context;
|
||||
context->local6 = *local;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
@@ -305,7 +319,7 @@ int address6_allocate(struct dhcp_context *context, unsigned char *clid, int cl
|
||||
do {
|
||||
/* eliminate addresses in use by the server. */
|
||||
for (d = context; d; d = d->current)
|
||||
if (addr == addr6part(&d->router6))
|
||||
if (addr == addr6part(&d->local6))
|
||||
break;
|
||||
|
||||
if (!d &&
|
||||
|
||||
+3
-2
@@ -603,7 +603,7 @@ struct dhcp_context {
|
||||
struct in_addr start, end; /* range of available addresses */
|
||||
#ifdef HAVE_DHCP6
|
||||
struct in6_addr start6, end6; /* range of available addresses */
|
||||
struct in6_addr local6, router6;
|
||||
struct in6_addr local6;
|
||||
int prefix;
|
||||
#endif
|
||||
int flags;
|
||||
@@ -1036,7 +1036,8 @@ void make_duid(time_t now);
|
||||
|
||||
/* rfc3315.c */
|
||||
#ifdef HAVE_DHCP6
|
||||
size_t dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name, size_t sz, int is_multicast, time_t now);
|
||||
size_t dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name,
|
||||
struct in6_addr *fallback, size_t sz, int is_multicast, time_t now);
|
||||
#endif
|
||||
|
||||
/* dhcp-common.c */
|
||||
|
||||
+10
-9
@@ -136,6 +136,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
|
||||
struct nlmsghdr *h;
|
||||
ssize_t len;
|
||||
static unsigned int seq = 0;
|
||||
int callback_ok = 1;
|
||||
|
||||
struct {
|
||||
struct nlmsghdr nlh;
|
||||
@@ -186,7 +187,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
|
||||
else if (h->nlmsg_type == NLMSG_ERROR)
|
||||
nl_err(h);
|
||||
else if (h->nlmsg_type == NLMSG_DONE)
|
||||
return 1;
|
||||
return callback_ok;
|
||||
else if (h->nlmsg_type == RTM_NEWADDR && family != AF_UNSPEC && family != AF_LOCAL)
|
||||
{
|
||||
struct ifaddrmsg *ifa = NLMSG_DATA(h);
|
||||
@@ -213,9 +214,9 @@ int iface_enumerate(int family, void *parm, int (*callback)())
|
||||
rta = RTA_NEXT(rta, len1);
|
||||
}
|
||||
|
||||
if (addr.s_addr)
|
||||
if (addr.s_addr && callback_ok)
|
||||
if (!((*callback)(addr, ifa->ifa_index, netmask, broadcast, parm)))
|
||||
return 0;
|
||||
callback_ok = 0;
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else if (ifa->ifa_family == AF_INET6)
|
||||
@@ -229,10 +230,10 @@ int iface_enumerate(int family, void *parm, int (*callback)())
|
||||
rta = RTA_NEXT(rta, len1);
|
||||
}
|
||||
|
||||
if (addrp)
|
||||
if (addrp && callback_ok)
|
||||
if (!((*callback)(addrp, (int)(ifa->ifa_prefixlen), (int)(ifa->ifa_scope),
|
||||
(int)(ifa->ifa_index), (int)(ifa->ifa_flags & IFA_F_TENTATIVE), parm)))
|
||||
return 0;
|
||||
callback_ok = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -258,9 +259,9 @@ int iface_enumerate(int family, void *parm, int (*callback)())
|
||||
rta = RTA_NEXT(rta, len1);
|
||||
}
|
||||
|
||||
if (inaddr && mac)
|
||||
if (inaddr && mac && callback_ok)
|
||||
if (!((*callback)(neigh->ndm_family, inaddr, mac, maclen, parm)))
|
||||
return 0;
|
||||
callback_ok = 0;
|
||||
}
|
||||
#ifdef HAVE_DHCP6
|
||||
else if (h->nlmsg_type == RTM_NEWLINK && family == AF_LOCAL)
|
||||
@@ -282,9 +283,9 @@ int iface_enumerate(int family, void *parm, int (*callback)())
|
||||
rta = RTA_NEXT(rta, len1);
|
||||
}
|
||||
|
||||
if (mac && !((link->ifi_flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) &&
|
||||
if (mac && callback_ok && !((link->ifi_flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) &&
|
||||
!((*callback)((unsigned int)link->ifi_type, mac, maclen, parm)))
|
||||
return 0;
|
||||
callback_ok = 0;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
+70
-33
@@ -31,9 +31,9 @@ static void put_opt6_long(unsigned int val);
|
||||
static void put_opt6_string(char *s);
|
||||
|
||||
static int dhcp6_maybe_relay(struct in6_addr *link_address, struct dhcp_netid **relay_tagsp, struct dhcp_context *context,
|
||||
int interface, char *iface_name, void *inbuff, size_t sz, int is_unicast, time_t now);
|
||||
int interface, char *iface_name, struct in6_addr *fallback, void *inbuff, size_t sz, int is_unicast, time_t now);
|
||||
static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dhcp_netid *tags, struct dhcp_context *context,
|
||||
int interface, char *iface_name, void *inbuff, size_t sz, int is_unicast, time_t now);
|
||||
int interface, char *iface_name, struct in6_addr *fallback, void *inbuff, size_t sz, int is_unicast, time_t now);
|
||||
static void log6_packet(char *type, unsigned char *clid, int clid_len, struct in6_addr *addr, int xid, char *iface, char *string);
|
||||
|
||||
static void *opt6_find (void *opts, void *end, unsigned int search, unsigned int minsize);
|
||||
@@ -45,7 +45,8 @@ static unsigned int opt6_uint(unsigned char *opt, int offset, int size);
|
||||
#define opt6_ptr(opt, i) ((void *)&(((unsigned char *)(opt))[4+(i)]))
|
||||
|
||||
|
||||
size_t dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name, size_t sz, int is_unicast, time_t now)
|
||||
size_t dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name,
|
||||
struct in6_addr *fallback, size_t sz, int is_unicast, time_t now)
|
||||
{
|
||||
struct dhcp_netid *relay_tags = NULL;
|
||||
struct dhcp_vendor *vendor;
|
||||
@@ -56,7 +57,7 @@ size_t dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name
|
||||
|
||||
outpacket_counter = 0;
|
||||
|
||||
if (dhcp6_maybe_relay(NULL, &relay_tags, context, interface, iface_name, daemon->dhcp_packet.iov_base, sz, is_unicast, now))
|
||||
if (dhcp6_maybe_relay(NULL, &relay_tags, context, interface, iface_name, fallback, daemon->dhcp_packet.iov_base, sz, is_unicast, now))
|
||||
return outpacket_counter;
|
||||
|
||||
return 0;
|
||||
@@ -64,7 +65,7 @@ size_t dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name
|
||||
|
||||
/* This cost me blood to write, it will probably cost you blood to understand - srk. */
|
||||
static int dhcp6_maybe_relay(struct in6_addr *link_address, struct dhcp_netid **relay_tagsp, struct dhcp_context *context,
|
||||
int interface, char *iface_name, void *inbuff, size_t sz, int is_unicast, time_t now)
|
||||
int interface, char *iface_name, struct in6_addr *fallback, void *inbuff, size_t sz, int is_unicast, time_t now)
|
||||
{
|
||||
void *end = inbuff + sz;
|
||||
void *opts = inbuff + 34;
|
||||
@@ -114,7 +115,7 @@ static int dhcp6_maybe_relay(struct in6_addr *link_address, struct dhcp_netid **
|
||||
return 0;
|
||||
}
|
||||
|
||||
return dhcp6_no_relay(msg_type, link_address, *relay_tagsp, context, interface, iface_name, inbuff, sz, is_unicast, now);
|
||||
return dhcp6_no_relay(msg_type, link_address, *relay_tagsp, context, interface, iface_name, fallback, inbuff, sz, is_unicast, now);
|
||||
}
|
||||
|
||||
/* must have at least msg_type+hopcount+link_address+peer_address+minimal size option
|
||||
@@ -159,7 +160,7 @@ static int dhcp6_maybe_relay(struct in6_addr *link_address, struct dhcp_netid **
|
||||
memcpy(&link_address, inbuff + 2, IN6ADDRSZ);
|
||||
/* Not, zero is_unicast since that is now known to refer to the
|
||||
relayed packet, not the original sent by the client */
|
||||
if (!dhcp6_maybe_relay(&link_address, relay_tagsp, context, interface, iface_name, opt6_ptr(opt, 0), opt6_len(opt), 0, now))
|
||||
if (!dhcp6_maybe_relay(&link_address, relay_tagsp, context, interface, iface_name, fallback, opt6_ptr(opt, 0), opt6_len(opt), 0, now))
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
@@ -171,7 +172,7 @@ static int dhcp6_maybe_relay(struct in6_addr *link_address, struct dhcp_netid **
|
||||
}
|
||||
|
||||
static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dhcp_netid *tags, struct dhcp_context *context,
|
||||
int interface, char *iface_name, void *inbuff, size_t sz, int is_unicast, time_t now)
|
||||
int interface, char *iface_name, struct in6_addr *fallback, void *inbuff, size_t sz, int is_unicast, time_t now)
|
||||
{
|
||||
void *packet_options = inbuff + 4;
|
||||
void *end = inbuff + sz;
|
||||
@@ -394,7 +395,7 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
if (!config)
|
||||
{
|
||||
/* Search again now we have a hostname.
|
||||
Only accept configs without CLID and HWADDR here, (they won't match)
|
||||
Only accept configs without CLID here, (it won't match)
|
||||
to avoid impersonation by name. */
|
||||
struct dhcp_config *new = find_config6(daemon->dhcp_conf, context, NULL, 0, hostname);
|
||||
if (new && !have_config(new, CONFIG_CLID) && !new->hwaddr)
|
||||
@@ -422,18 +423,31 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
if (have_config(config, CONFIG_DISABLE))
|
||||
ignore = 1;
|
||||
}
|
||||
|
||||
tagif = run_tag_if(tags);
|
||||
|
||||
/* if all the netids in the ignore list are present, ignore this client */
|
||||
if (daemon->dhcp_ignore)
|
||||
{
|
||||
struct dhcp_netid_list *id_list;
|
||||
|
||||
tagif = run_tag_if(tags);
|
||||
|
||||
for (id_list = daemon->dhcp_ignore; id_list; id_list = id_list->next)
|
||||
if (match_netid(id_list->list, tagif, 0))
|
||||
ignore = 1;
|
||||
}
|
||||
|
||||
/* if all the netids in the ignore_name list are present, ignore client-supplied name */
|
||||
if (!hostname_auth)
|
||||
{
|
||||
struct dhcp_netid_list *id_list;
|
||||
|
||||
for (id_list = daemon->dhcp_ignore_names; id_list; id_list = id_list->next)
|
||||
if ((!id_list->list) || match_netid(id_list->list, tagif, 0))
|
||||
break;
|
||||
if (id_list)
|
||||
hostname = NULL;
|
||||
}
|
||||
|
||||
|
||||
switch (msg_type)
|
||||
{
|
||||
@@ -508,7 +522,8 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
struct in6_addr *req_addr = opt6_ptr(ia_option, 0);
|
||||
preferred_time = opt6_uint(ia_option, 16, 4);
|
||||
|
||||
if (!address6_available(context, req_addr, tags))
|
||||
if (!address6_available(context, req_addr, tags) &&
|
||||
(!have_config(config, CONFIG_ADDR6) || memcmp(&config->addr6, req_addr, IN6ADDRSZ) != 0))
|
||||
{
|
||||
if (msg_type == DHCP6REQUEST)
|
||||
{
|
||||
@@ -584,13 +599,23 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
address_assigned = 1;
|
||||
|
||||
/* shouldn't ever fail */
|
||||
if ((this_context = narrow_context6(context, addrp, tags)))
|
||||
if ((this_context = narrow_context6(context, addrp, tagif)))
|
||||
{
|
||||
/* get tags from context if we've not used it before */
|
||||
if (this_context->netid.next != &this_context->netid && this_context->netid.net)
|
||||
if (this_context->netid.next == &this_context->netid && this_context->netid.net)
|
||||
{
|
||||
this_context->netid.next = context_tags;
|
||||
context_tags = &this_context->netid;
|
||||
if (!hostname_auth)
|
||||
{
|
||||
struct dhcp_netid_list *id_list;
|
||||
|
||||
for (id_list = daemon->dhcp_ignore_names; id_list; id_list = id_list->next)
|
||||
if ((!id_list->list) || match_netid(id_list->list, &this_context->netid, 0))
|
||||
break;
|
||||
if (id_list)
|
||||
hostname = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
lease_time = have_config(valid_config, CONFIG_TIME) ? valid_config->lease_time : this_context->lease_time;
|
||||
@@ -653,13 +678,18 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
client_hostname ? strlen(client_hostname) : 0, 0);
|
||||
|
||||
/* space-concat tag set */
|
||||
if (!tags)
|
||||
if (!tagif && !context_tags)
|
||||
lease_add_extradata(lease, NULL, 0, 0);
|
||||
else
|
||||
{
|
||||
struct dhcp_netid *n;
|
||||
struct dhcp_netid *n, *l;
|
||||
|
||||
for (n = run_tag_if(tags); n; n = n->next)
|
||||
/* link temporarily */
|
||||
for (n = context_tags; n && n->next; n = n->next);
|
||||
if ((l = n))
|
||||
l->next = tags;
|
||||
|
||||
for (n = run_tag_if(context_tags); n; n = n->next)
|
||||
{
|
||||
struct dhcp_netid *n1;
|
||||
/* kill dupes */
|
||||
@@ -669,6 +699,10 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
if (!n1)
|
||||
lease_add_extradata(lease, (unsigned char *)n->net, strlen(n->net), n->next ? ' ' : 0);
|
||||
}
|
||||
|
||||
/* unlink again */
|
||||
if (l)
|
||||
l->next = NULL;
|
||||
}
|
||||
|
||||
if (link_address)
|
||||
@@ -820,17 +854,27 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
break;
|
||||
}
|
||||
|
||||
tagif = run_tag_if(tags);
|
||||
|
||||
if (!address6_available(context, req_addr, tagif) ||
|
||||
!(this_context = narrow_context6(context, req_addr, tagif)))
|
||||
lease_time = 0;
|
||||
else
|
||||
{
|
||||
/* get tags from context if we've not used it before */
|
||||
if (this_context->netid.next != &this_context->netid && this_context->netid.net)
|
||||
if (this_context->netid.next == &this_context->netid && this_context->netid.net)
|
||||
{
|
||||
this_context->netid.next = context_tags;
|
||||
context_tags = &this_context->netid;
|
||||
if (!hostname_auth)
|
||||
{
|
||||
struct dhcp_netid_list *id_list;
|
||||
|
||||
for (id_list = daemon->dhcp_ignore_names; id_list; id_list = id_list->next)
|
||||
if ((!id_list->list) || match_netid(id_list->list, &this_context->netid, 0))
|
||||
break;
|
||||
if (id_list)
|
||||
hostname = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
lease_time = have_config(valid_config, CONFIG_TIME) ? valid_config->lease_time : this_context->lease_time;
|
||||
@@ -1148,10 +1192,15 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
|
||||
}
|
||||
|
||||
if (!done_dns)
|
||||
if (!done_dns &&
|
||||
(!IN6_IS_ADDR_UNSPECIFIED(&context->local6) ||
|
||||
!IN6_IS_ADDR_UNSPECIFIED(fallback)))
|
||||
{
|
||||
o = new_opt6(OPTION6_DNS_SERVER);
|
||||
put_opt6(&context->local6, IN6ADDRSZ);
|
||||
if (IN6_IS_ADDR_UNSPECIFIED(&context->local6))
|
||||
put_opt6(fallback, IN6ADDRSZ);
|
||||
else
|
||||
put_opt6(&context->local6, IN6ADDRSZ);
|
||||
end_opt6(o);
|
||||
}
|
||||
|
||||
@@ -1213,18 +1262,6 @@ static int dhcp6_no_relay(int msg_type, struct in6_addr *link_address, struct dh
|
||||
}
|
||||
|
||||
|
||||
/* if all the netids in the ignore_name list are present, ignore client-supplied name */
|
||||
if (!hostname_auth)
|
||||
{
|
||||
struct dhcp_netid_list *id_list;
|
||||
|
||||
for (id_list = daemon->dhcp_ignore_names; id_list; id_list = id_list->next)
|
||||
if ((!id_list->list) || match_netid(id_list->list, tagif, 0))
|
||||
break;
|
||||
if (id_list)
|
||||
hostname = NULL;
|
||||
}
|
||||
|
||||
if (hostname)
|
||||
{
|
||||
unsigned char *p;
|
||||
|
||||
Reference in new issue
Block a user