mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
import of dnsmasq-2.11.tar.gz
This commit is contained in:
19
CHANGELOG
19
CHANGELOG
@@ -1123,4 +1123,23 @@ release 2.10
|
|||||||
support was added. Thanks to Michael Hamilton for
|
support was added. Thanks to Michael Hamilton for
|
||||||
assistance with this.
|
assistance with this.
|
||||||
|
|
||||||
|
version 2.11
|
||||||
|
Fixed DHCP problem which could result in two leases in the
|
||||||
|
database with the same address. This looked much more
|
||||||
|
alarming then it was, since it could only happen when a
|
||||||
|
machine changes MAC address but kept the same name. The
|
||||||
|
old lease would persist until it timed out but things
|
||||||
|
would still work OK.
|
||||||
|
|
||||||
|
Check that IP addresses in all dhcp-host directives are
|
||||||
|
unique and die horribly if they are not, since otherwise
|
||||||
|
endless protocol loops can occur.
|
||||||
|
|
||||||
|
Use IPV6_RECVPKTINFO as socket option rather than
|
||||||
|
IPV6_PKTINFO where available. This keeps late-model FreeBSD
|
||||||
|
happy.
|
||||||
|
|
||||||
|
Set source interface when replying to IPv6 UDP
|
||||||
|
queries. This is needed to cope with link-local addresses.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
Name: dnsmasq
|
Name: dnsmasq
|
||||||
Version: 2.10
|
Version: 2.11
|
||||||
Release: 1
|
Release: 1
|
||||||
Copyright: GPL
|
Copyright: GPL
|
||||||
Group: System Environment/Daemons
|
Group: System Environment/Daemons
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
Name: dnsmasq
|
Name: dnsmasq
|
||||||
Version: 2.10
|
Version: 2.11
|
||||||
Release: 1
|
Release: 1
|
||||||
Copyright: GPL
|
Copyright: GPL
|
||||||
Group: Productivity/Networking/DNS/Servers
|
Group: Productivity/Networking/DNS/Servers
|
||||||
|
|||||||
4
doc.html
4
doc.html
@@ -112,7 +112,9 @@ bzip2 dnsmasq-zzz.tar
|
|||||||
</PRE>
|
</PRE>
|
||||||
|
|
||||||
<H2>Links.</H2>
|
<H2>Links.</H2>
|
||||||
Ulrich Ivens has a nice HOWTO in German on installing dnsmasq at <A HREF="http://howto.linux-hardware-shop.de/dnsmasq.html">http://howto.linux-hardware-shop.de/dnsmasq.html</A>
|
Ulrich Ivens has a nice HOWTO in German on installing dnsmasq at <A
|
||||||
|
HREF="http://howto.linux-hardware-shop.de/dnsmasq.html">http://howto.linux-hardware-shop.de/dnsmasq.html</A>
|
||||||
|
and Damien Raude-Morvan has one in French at <A HREF="http://www.drazzib.com/docs-dnsmasq.html">http://www.drazzib.com/docs-dnsmasq.html</A>
|
||||||
|
|
||||||
<H2>License.</H2>
|
<H2>License.</H2>
|
||||||
Dnsmasq is distributed under the GPL. See the file COPYING in the distribution
|
Dnsmasq is distributed under the GPL. See the file COPYING in the distribution
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
|
|
||||||
/* Author's email: simon@thekelleys.org.uk */
|
/* Author's email: simon@thekelleys.org.uk */
|
||||||
|
|
||||||
#define VERSION "2.10"
|
#define VERSION "2.11"
|
||||||
|
|
||||||
#define FTABSIZ 150 /* max number of outstanding requests */
|
#define FTABSIZ 150 /* max number of outstanding requests */
|
||||||
#define MAX_PROCS 20 /* max no children for TCP requests */
|
#define MAX_PROCS 20 /* max no children for TCP requests */
|
||||||
|
|||||||
38
src/dhcp.c
38
src/dhcp.c
@@ -14,12 +14,13 @@
|
|||||||
|
|
||||||
#include "dnsmasq.h"
|
#include "dnsmasq.h"
|
||||||
|
|
||||||
void dhcp_init(int *fdp, int* rfdp)
|
void dhcp_init(int *fdp, int* rfdp, struct dhcp_config *configs)
|
||||||
{
|
{
|
||||||
int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
|
||||||
struct sockaddr_in saddr;
|
struct sockaddr_in saddr;
|
||||||
int opt = 1;
|
int opt = 1;
|
||||||
|
struct dhcp_config *cp;
|
||||||
|
|
||||||
if (fd == -1)
|
if (fd == -1)
|
||||||
die ("cannot create DHCP socket : %s", NULL);
|
die ("cannot create DHCP socket : %s", NULL);
|
||||||
|
|
||||||
@@ -57,6 +58,14 @@ void dhcp_init(int *fdp, int* rfdp)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
*rfdp = fd;
|
*rfdp = fd;
|
||||||
|
|
||||||
|
/* If the same IP appears in more than one host config, then DISCOVER
|
||||||
|
for one of the hosts will get the address, but REQUEST will be NAKed,
|
||||||
|
since the address is reserved by the other one -> protocol loop. */
|
||||||
|
for (; configs; configs = configs->next)
|
||||||
|
for (cp = configs->next; cp; cp = cp->next)
|
||||||
|
if ((configs->flags & cp->flags & CONFIG_ADDR) && configs->addr.s_addr == cp->addr.s_addr)
|
||||||
|
die("Duplicate IP address %s in dhcp-config directive.", inet_ntoa(cp->addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
void dhcp_packet(struct dhcp_context *contexts, char *packet,
|
void dhcp_packet(struct dhcp_context *contexts, char *packet,
|
||||||
@@ -370,6 +379,17 @@ int address_available(struct dhcp_context *context, struct in_addr taddr)
|
|||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct dhcp_config *config_find_by_address(struct dhcp_config *configs, struct in_addr addr)
|
||||||
|
{
|
||||||
|
struct dhcp_config *config;
|
||||||
|
|
||||||
|
for (config = configs; config; config = config->next)
|
||||||
|
if ((config->flags & CONFIG_ADDR) && config->addr.s_addr == addr.s_addr)
|
||||||
|
return config;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int address_allocate(struct dhcp_context *context, struct dhcp_config *configs,
|
int address_allocate(struct dhcp_context *context, struct dhcp_config *configs,
|
||||||
struct in_addr *addrp, unsigned char *hwaddr)
|
struct in_addr *addrp, unsigned char *hwaddr)
|
||||||
@@ -377,7 +397,6 @@ int address_allocate(struct dhcp_context *context, struct dhcp_config *configs,
|
|||||||
/* Find a free address: exclude anything in use and anything allocated to
|
/* Find a free address: exclude anything in use and anything allocated to
|
||||||
a particular hwaddr/clientid/hostname in our configuration */
|
a particular hwaddr/clientid/hostname in our configuration */
|
||||||
|
|
||||||
struct dhcp_config *config;
|
|
||||||
struct in_addr start, addr ;
|
struct in_addr start, addr ;
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
|
|
||||||
@@ -400,17 +419,10 @@ int address_allocate(struct dhcp_context *context, struct dhcp_config *configs,
|
|||||||
addr.s_addr = htonl(ntohl(addr.s_addr) + 1);
|
addr.s_addr = htonl(ntohl(addr.s_addr) + 1);
|
||||||
|
|
||||||
|
|
||||||
if (!lease_find_by_addr(addr))
|
if (!lease_find_by_addr(addr) && !config_find_by_address(configs, addr))
|
||||||
{
|
{
|
||||||
for (config = configs; config; config = config->next)
|
*addrp = addr;
|
||||||
if ((config->flags & CONFIG_ADDR) && config->addr.s_addr == addr.s_addr)
|
return 1;
|
||||||
break;
|
|
||||||
|
|
||||||
if (!config)
|
|
||||||
{
|
|
||||||
*addrp = addr;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} while (addr.s_addr != start.s_addr);
|
} while (addr.s_addr != start.s_addr);
|
||||||
|
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ int main (int argc, char **argv)
|
|||||||
if (c != 1)
|
if (c != 1)
|
||||||
die("must set exactly one interface on broken systems without IP_RECVIF", NULL);
|
die("must set exactly one interface on broken systems without IP_RECVIF", NULL);
|
||||||
#endif
|
#endif
|
||||||
dhcp_init(&dhcpfd, &dhcp_raw_fd);
|
dhcp_init(&dhcpfd, &dhcp_raw_fd, dhcp_configs);
|
||||||
leasefd = lease_init(lease_file, domain_suffix, dnamebuff, packet, now, maxleases);
|
leasefd = lease_init(lease_file, domain_suffix, dnamebuff, packet, now, maxleases);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -230,6 +230,7 @@ struct frec {
|
|||||||
union mysockaddr source;
|
union mysockaddr source;
|
||||||
struct all_addr dest;
|
struct all_addr dest;
|
||||||
struct server *sentto;
|
struct server *sentto;
|
||||||
|
unsigned int iface;
|
||||||
unsigned short orig_id, new_id;
|
unsigned short orig_id, new_id;
|
||||||
int fd;
|
int fd;
|
||||||
time_t time;
|
time_t time;
|
||||||
@@ -412,7 +413,7 @@ struct irec *enumerate_interfaces(struct iname **names,
|
|||||||
struct listener *create_wildcard_listeners(int port);
|
struct listener *create_wildcard_listeners(int port);
|
||||||
struct listener *create_bound_listeners(struct irec *interfaces, int port);
|
struct listener *create_bound_listeners(struct irec *interfaces, int port);
|
||||||
/* dhcp.c */
|
/* dhcp.c */
|
||||||
void dhcp_init(int *fdp, int* rfdp);
|
void dhcp_init(int *fdp, int* rfdp, struct dhcp_config *configs);
|
||||||
void dhcp_packet(struct dhcp_context *contexts, char *packet,
|
void dhcp_packet(struct dhcp_context *contexts, char *packet,
|
||||||
struct dhcp_opt *dhcp_opts, struct dhcp_config *dhcp_configs,
|
struct dhcp_opt *dhcp_opts, struct dhcp_config *dhcp_configs,
|
||||||
struct dhcp_vendor *vendors,
|
struct dhcp_vendor *vendors,
|
||||||
@@ -430,7 +431,7 @@ struct dhcp_config *find_config(struct dhcp_config *configs,
|
|||||||
struct dhcp_config *read_ethers(struct dhcp_config *configs, char *buff);
|
struct dhcp_config *read_ethers(struct dhcp_config *configs, char *buff);
|
||||||
void dhcp_update_configs(struct dhcp_config *configs);
|
void dhcp_update_configs(struct dhcp_config *configs);
|
||||||
struct dhcp_config *dhcp_read_ethers(struct dhcp_config *configs, char *buff);
|
struct dhcp_config *dhcp_read_ethers(struct dhcp_config *configs, char *buff);
|
||||||
|
struct dhcp_config *config_find_by_address(struct dhcp_config *configs, struct in_addr addr);
|
||||||
/* lease.c */
|
/* lease.c */
|
||||||
void lease_update_file(int force, time_t now);
|
void lease_update_file(int force, time_t now);
|
||||||
void lease_update_dns(void);
|
void lease_update_dns(void);
|
||||||
|
|||||||
@@ -36,7 +36,8 @@ void forward_init(int first)
|
|||||||
/* Send a UDP packet with it's source address set as "source"
|
/* Send a UDP packet with it's source address set as "source"
|
||||||
unless nowild is true, when we just send it with the kernel default */
|
unless nowild is true, when we just send it with the kernel default */
|
||||||
static void send_from(int fd, int nowild, char *packet, int len,
|
static void send_from(int fd, int nowild, char *packet, int len,
|
||||||
union mysockaddr *to, struct all_addr *source)
|
union mysockaddr *to, struct all_addr *source,
|
||||||
|
unsigned int iface)
|
||||||
{
|
{
|
||||||
struct msghdr msg;
|
struct msghdr msg;
|
||||||
struct iovec iov[1];
|
struct iovec iov[1];
|
||||||
@@ -94,7 +95,7 @@ static void send_from(int fd, int nowild, char *packet, int len,
|
|||||||
{
|
{
|
||||||
struct cmsghdr *cmptr = CMSG_FIRSTHDR(&msg);
|
struct cmsghdr *cmptr = CMSG_FIRSTHDR(&msg);
|
||||||
struct in6_pktinfo *pkt = (struct in6_pktinfo *)CMSG_DATA(cmptr);
|
struct in6_pktinfo *pkt = (struct in6_pktinfo *)CMSG_DATA(cmptr);
|
||||||
pkt->ipi6_ifindex = 0;
|
pkt->ipi6_ifindex = iface; /* Need iface for IPv6 to handle link-local addrs */
|
||||||
pkt->ipi6_addr = source->addr.addr6;
|
pkt->ipi6_addr = source->addr.addr6;
|
||||||
msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
|
msg.msg_controllen = cmptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
|
||||||
cmptr->cmsg_type = IPV6_PKTINFO;
|
cmptr->cmsg_type = IPV6_PKTINFO;
|
||||||
@@ -191,8 +192,8 @@ unsigned short search_servers(struct server *servers, unsigned int options, stru
|
|||||||
|
|
||||||
/* returns new last_server */
|
/* returns new last_server */
|
||||||
static struct server *forward_query(int udpfd, union mysockaddr *udpaddr,
|
static struct server *forward_query(int udpfd, union mysockaddr *udpaddr,
|
||||||
struct all_addr *dst_addr, HEADER *header,
|
struct all_addr *dst_addr, unsigned int dst_iface,
|
||||||
int plen, unsigned int options, char *dnamebuff,
|
HEADER *header, int plen, unsigned int options, char *dnamebuff,
|
||||||
struct server *servers, struct server *last_server,
|
struct server *servers, struct server *last_server,
|
||||||
time_t now, unsigned long local_ttl)
|
time_t now, unsigned long local_ttl)
|
||||||
{
|
{
|
||||||
@@ -246,6 +247,7 @@ static struct server *forward_query(int udpfd, union mysockaddr *udpaddr,
|
|||||||
|
|
||||||
forward->source = *udpaddr;
|
forward->source = *udpaddr;
|
||||||
forward->dest = *dst_addr;
|
forward->dest = *dst_addr;
|
||||||
|
forward->iface = dst_iface;
|
||||||
forward->new_id = get_id();
|
forward->new_id = get_id();
|
||||||
forward->fd = udpfd;
|
forward->fd = udpfd;
|
||||||
forward->orig_id = ntohs(header->id);
|
forward->orig_id = ntohs(header->id);
|
||||||
@@ -310,7 +312,7 @@ static struct server *forward_query(int udpfd, union mysockaddr *udpaddr,
|
|||||||
|
|
||||||
/* could not send on, return empty answer or address if known for whole domain */
|
/* could not send on, return empty answer or address if known for whole domain */
|
||||||
plen = setup_reply(header, (unsigned int)plen, addrp, flags, local_ttl);
|
plen = setup_reply(header, (unsigned int)plen, addrp, flags, local_ttl);
|
||||||
send_from(udpfd, options & OPT_NOWILD, (char *)header, plen, udpaddr, dst_addr);
|
send_from(udpfd, options & OPT_NOWILD, (char *)header, plen, udpaddr, dst_addr, dst_iface);
|
||||||
|
|
||||||
return last_server;
|
return last_server;
|
||||||
}
|
}
|
||||||
@@ -405,7 +407,7 @@ struct server *reply_query(struct serverfd *sfd, int options, char *packet, time
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
header->id = htons(forward->orig_id);
|
header->id = htons(forward->orig_id);
|
||||||
send_from(forward->fd, options & OPT_NOWILD, packet, n, &forward->source, &forward->dest);
|
send_from(forward->fd, options & OPT_NOWILD, packet, n, &forward->source, &forward->dest, forward->iface);
|
||||||
forward->new_id = 0; /* cancel */
|
forward->new_id = 0; /* cancel */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -564,9 +566,9 @@ struct server *receive_query(struct listener *listen, char *packet, struct mx_re
|
|||||||
m = answer_request (header, ((char *) header) + PACKETSZ, (unsigned int)n,
|
m = answer_request (header, ((char *) header) + PACKETSZ, (unsigned int)n,
|
||||||
mxnames, mxtarget, options, now, local_ttl, namebuff, edns_pcktsz);
|
mxnames, mxtarget, options, now, local_ttl, namebuff, edns_pcktsz);
|
||||||
if (m >= 1)
|
if (m >= 1)
|
||||||
send_from(listen->fd, options & OPT_NOWILD, (char *)header, m, &source_addr, &dst_addr);
|
send_from(listen->fd, options & OPT_NOWILD, (char *)header, m, &source_addr, &dst_addr, if_index);
|
||||||
else
|
else
|
||||||
last_server = forward_query(listen->fd, &source_addr, &dst_addr,
|
last_server = forward_query(listen->fd, &source_addr, &dst_addr, if_index,
|
||||||
header, n, options, namebuff, servers,
|
header, n, options, namebuff, servers,
|
||||||
last_server, now, local_ttl);
|
last_server, now, local_ttl);
|
||||||
return last_server;
|
return last_server;
|
||||||
|
|||||||
@@ -263,7 +263,11 @@ static int create_ipv6_listener(struct listener **link, int port)
|
|||||||
setsockopt(tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
|
setsockopt(tcpfd, IPV6_LEVEL, IPV6_V6ONLY, &opt, sizeof(opt)) == -1 ||
|
||||||
(flags = fcntl(tcpfd, F_GETFL, 0)) == -1 ||
|
(flags = fcntl(tcpfd, F_GETFL, 0)) == -1 ||
|
||||||
fcntl(tcpfd, F_SETFL, flags | O_NONBLOCK) == -1 ||
|
fcntl(tcpfd, F_SETFL, flags | O_NONBLOCK) == -1 ||
|
||||||
|
#ifdef IPV6_RECVPKTINFO
|
||||||
|
setsockopt(fd, IPV6_LEVEL, IPV6_RECVPKTINFO, &opt, sizeof(opt)) == -1 ||
|
||||||
|
#else
|
||||||
setsockopt(fd, IPV6_LEVEL, IPV6_PKTINFO, &opt, sizeof(opt)) == -1 ||
|
setsockopt(fd, IPV6_LEVEL, IPV6_PKTINFO, &opt, sizeof(opt)) == -1 ||
|
||||||
|
#endif
|
||||||
bind(tcpfd, (struct sockaddr *)&addr, sa_len(&addr)) == -1 ||
|
bind(tcpfd, (struct sockaddr *)&addr, sa_len(&addr)) == -1 ||
|
||||||
listen(tcpfd, 5) == -1 ||
|
listen(tcpfd, 5) == -1 ||
|
||||||
bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == -1)
|
bind(fd, (struct sockaddr *)&addr, sa_len(&addr)) == -1)
|
||||||
|
|||||||
@@ -152,8 +152,9 @@ int dhcp_reply(struct dhcp_context *context,
|
|||||||
clid_len = 0;
|
clid_len = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((config = find_config(dhcp_configs, context, clid, clid_len, mess->chaddr, NULL)) &&
|
config = find_config(dhcp_configs, context, clid, clid_len, mess->chaddr, NULL);
|
||||||
have_config(config, CONFIG_NAME))
|
|
||||||
|
if (have_config(config, CONFIG_NAME))
|
||||||
hostname = config->hostname;
|
hostname = config->hostname;
|
||||||
else if ((opt = option_find(mess, sz, OPTION_HOSTNAME)))
|
else if ((opt = option_find(mess, sz, OPTION_HOSTNAME)))
|
||||||
{
|
{
|
||||||
@@ -184,8 +185,16 @@ int dhcp_reply(struct dhcp_context *context,
|
|||||||
hostname = NULL; /* nothing left */
|
hostname = NULL; /* nothing left */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* search again now we have a hostname */
|
|
||||||
config = find_config(dhcp_configs, context, clid, clid_len, mess->chaddr, hostname);
|
/* Search again now we have a hostname.
|
||||||
|
Only accept configs without CLID and HWADDR here, (they won't match)
|
||||||
|
to avoid impersonation by name. */
|
||||||
|
if (!config)
|
||||||
|
{
|
||||||
|
struct dhcp_config *new = find_config(dhcp_configs, context, NULL, 0, mess->chaddr, hostname);
|
||||||
|
if (!have_config(new, CONFIG_CLID) && !have_config(new, CONFIG_HWADDR))
|
||||||
|
config = new;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -347,7 +356,8 @@ int dhcp_reply(struct dhcp_context *context,
|
|||||||
mess->yiaddr = config->addr;
|
mess->yiaddr = config->addr;
|
||||||
else if (lease && address_available(context, lease->addr))
|
else if (lease && address_available(context, lease->addr))
|
||||||
mess->yiaddr = lease->addr;
|
mess->yiaddr = lease->addr;
|
||||||
else if (opt && address_available(context, addr) && !lease_find_by_addr(addr))
|
else if (opt && address_available(context, addr) && !lease_find_by_addr(addr) &&
|
||||||
|
!config_find_by_address(dhcp_configs, addr))
|
||||||
mess->yiaddr = addr;
|
mess->yiaddr = addr;
|
||||||
else if (!address_allocate(context, dhcp_configs, &mess->yiaddr, mess->chaddr))
|
else if (!address_allocate(context, dhcp_configs, &mess->yiaddr, mess->chaddr))
|
||||||
message = "no address available";
|
message = "no address available";
|
||||||
@@ -400,12 +410,11 @@ int dhcp_reply(struct dhcp_context *context,
|
|||||||
|
|
||||||
if (!lease)
|
if (!lease)
|
||||||
{
|
{
|
||||||
if ((!address_available(context, mess->yiaddr) || lease_find_by_addr(mess->yiaddr)) &&
|
if (lease_find_by_addr(mess->yiaddr))
|
||||||
(!have_config(config, CONFIG_ADDR) || config->addr.s_addr != mess->yiaddr.s_addr))
|
message = "address in use";
|
||||||
message = "address unavailable";
|
|
||||||
else if (!(lease = lease_allocate(clid, clid_len, mess->yiaddr)))
|
else if (!(lease = lease_allocate(clid, clid_len, mess->yiaddr)))
|
||||||
message = "no leases left";
|
message = "no leases left";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -424,29 +433,38 @@ int dhcp_reply(struct dhcp_context *context,
|
|||||||
fuzz = fuzz/2;
|
fuzz = fuzz/2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If a machine moves networks whilst it has a lease, we catch that here. */
|
if (!message)
|
||||||
if (!message && !is_same_net(mess->yiaddr, context->start, context->netmask))
|
{
|
||||||
message = "wrong network";
|
struct dhcp_config *addr_config;
|
||||||
|
/* If a machine moves networks whilst it has a lease, we catch that here. */
|
||||||
|
if (!is_same_net(mess->yiaddr, context->start, context->netmask))
|
||||||
|
message = "wrong network";
|
||||||
|
|
||||||
/* Check for renewal of a lease which is now outside the allowed range. */
|
/* Check for renewal of a lease which is now outside the allowed range. */
|
||||||
if (!message && !address_available(context, mess->yiaddr) &&
|
else if (!address_available(context, mess->yiaddr) &&
|
||||||
(!have_config(config, CONFIG_ADDR) || config->addr.s_addr != mess->yiaddr.s_addr))
|
(!have_config(config, CONFIG_ADDR) || config->addr.s_addr != mess->yiaddr.s_addr))
|
||||||
message = "address no longer available";
|
message = "address no longer available";
|
||||||
|
|
||||||
|
/* Check if a new static address has been configured. Be very sure that
|
||||||
|
when the client does DISCOVER, it will get the static address, otherwise
|
||||||
|
an endless protocol loop will ensue. */
|
||||||
|
|
||||||
|
else if (have_config(config, CONFIG_ADDR) && !lease_find_by_addr(config->addr))
|
||||||
|
message = "static lease available";
|
||||||
|
|
||||||
|
/* Check to see if the address is reserved as a static address for another host */
|
||||||
|
else if ((addr_config = config_find_by_address(dhcp_configs, mess->yiaddr)) && addr_config != config)
|
||||||
|
message ="address reserved";
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if a new static address has been configured. Be very sure that
|
|
||||||
when the client does DISCOVER, it will get the static address, otherwise
|
|
||||||
an endless protocol loop will ensue. */
|
|
||||||
if (!message && have_config(config, CONFIG_ADDR) &&
|
|
||||||
!have_config(config, CONFIG_DISABLE) &&
|
|
||||||
!lease_find_by_addr(config->addr))
|
|
||||||
message = "static lease available";
|
|
||||||
|
|
||||||
log_packet("REQUEST", &mess->yiaddr, mess->chaddr, iface_name, NULL);
|
log_packet("REQUEST", &mess->yiaddr, mess->chaddr, iface_name, NULL);
|
||||||
|
|
||||||
if (message)
|
if (message)
|
||||||
{
|
{
|
||||||
log_packet("NAK", &mess->yiaddr, mess->chaddr, iface_name, message);
|
log_packet("NAK", &mess->yiaddr, mess->chaddr, iface_name, message);
|
||||||
|
|
||||||
|
lease_prune(lease, now);
|
||||||
|
|
||||||
mess->siaddr.s_addr = mess->yiaddr.s_addr = mess->ciaddr.s_addr = 0;
|
mess->siaddr.s_addr = mess->yiaddr.s_addr = mess->ciaddr.s_addr = 0;
|
||||||
bootp_option_put(mess, NULL, NULL);
|
bootp_option_put(mess, NULL, NULL);
|
||||||
p = option_put(p, end, OPTION_MESSAGE_TYPE, 1, DHCPNAK);
|
p = option_put(p, end, OPTION_MESSAGE_TYPE, 1, DHCPNAK);
|
||||||
|
|||||||
Reference in New Issue
Block a user