import of dnsmasq-2.15.tar.gz

This commit is contained in:
Simon Kelley
2004-09-20 19:20:58 +01:00
parent 3be34541c2
commit 36717eeefc
10 changed files with 314 additions and 147 deletions

View File

@@ -1190,3 +1190,27 @@ version 2.14
Added "keep-in-foreground" option. Thanks to Sean
MacLennan for the patch.
version 2.15
Fixed NXDOMAIN/NODATA confusion for locally known
names. We now return a NODATA reponse for names which are
locally known. Now a query for (eg AAAA or MX) for a name
with an IPv4 address in /etc/hosts which fails upstream
will generate a NODATA response. Note that the query
is still tried upstream, but a NXDOMAIN reply gets
converted to NODATA. Thanks to Eric de Thouars, Eric
Spakman and Mike Mestnik for bug reports/testing.
Allow multiple dhcp-ranges within the same network. The
original intention was that there would be a dhcp-range
option for each network served, but there's no real reason
not to allow discontinuous ranges within a network so this
release adds support for that.
Check for dhcp-ranges which are inconsistent with their
netmask, and generate errors or warnings.
Improve error messages when there are problems with
configuration.

View File

@@ -5,7 +5,7 @@
###############################################################################
Name: dnsmasq
Version: 2.14
Version: 2.15
Release: 1
Copyright: GPL
Group: System Environment/Daemons

View File

@@ -5,7 +5,7 @@
###############################################################################
Name: dnsmasq
Version: 2.14
Version: 2.15
Release: 1
Copyright: GPL
Group: Productivity/Networking/DNS/Servers

View File

@@ -12,7 +12,7 @@
/* Author's email: simon@thekelleys.org.uk */
#define VERSION "2.14"
#define VERSION "2.15"
#define FTABSIZ 150 /* max number of outstanding requests */
#define MAX_PROCS 20 /* max no children for TCP requests */

View File

@@ -209,9 +209,19 @@ void dhcp_packet(struct daemon *daemon, time_t now)
iface_netmask = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
if (iface_netmask.s_addr &&
is_same_net(iface_addr, context->start, iface_netmask) &&
is_same_net(iface_addr, context->end, iface_netmask))
(is_same_net(iface_addr, context->start, iface_netmask) ||
is_same_net(iface_addr, context->end, iface_netmask)))
{
context->netmask = iface_netmask;
if (!(is_same_net(iface_addr, context->start, iface_netmask) &&
is_same_net(iface_addr, context->end, iface_netmask)))
{
strcpy(daemon->dhcp_buff, inet_ntoa(context->start));
strcpy(daemon->dhcp_buff2, inet_ntoa(context->end));
syslog(LOG_WARNING, "DHCP range %s -- %s is not consistent with netmask %s",
daemon->dhcp_buff, daemon->dhcp_buff2, inet_ntoa(iface_netmask));
}
}
}
/* Determine "default" default routes. These are to this server or the relay agent.
@@ -226,7 +236,8 @@ void dhcp_packet(struct daemon *daemon, time_t now)
{
if (!iface_broadcast.s_addr && ioctl(daemon->dhcpfd, SIOCGIFBRDADDR, &ifr) != -1)
iface_broadcast = ((struct sockaddr_in *) &ifr.ifr_addr)->sin_addr;
if (iface_broadcast.s_addr)
if (iface_broadcast.s_addr &&
is_same_net(iface_broadcast, context->start, context->netmask))
context->broadcast = iface_broadcast;
else
context->broadcast.s_addr = context->start.s_addr | ~context->netmask.s_addr;
@@ -361,28 +372,25 @@ void dhcp_packet(struct daemon *daemon, time_t now)
int address_available(struct dhcp_context *context, struct in_addr taddr)
{
/* Check is an address is OK for this network, ie
within allowable range and not in an existing lease */
/* Check is an address is OK for this network, check all
possible ranges. */
unsigned int addr, start, end;
unsigned int start, end, addr = ntohl(taddr.s_addr);
/* static leases only. */
if (context->static_only)
return 0;
addr = ntohl(taddr.s_addr);
for (; context; context = context->current)
{
start = ntohl(context->start.s_addr);
end = ntohl(context->end.s_addr);
if (addr < start)
return 0;
if (addr > end)
return 0;
if (!context->static_only &&
addr >= start &&
addr <= end)
return 1;
}
return 0;
}
struct dhcp_config *config_find_by_address(struct dhcp_config *configs, struct in_addr addr)
{
struct dhcp_config *config;
@@ -403,10 +411,9 @@ int address_allocate(struct dhcp_context *context, struct daemon *daemon,
struct in_addr start, addr ;
unsigned int i, j;
/* check if no dynamic leases. */
if (context->static_only)
return 0;
for (; context; context = context->current)
if (!context->static_only)
{
/* pick a seed based on hwaddr then iterate until we find a free address. */
for (j = context->addr_epoch, i = 0; i < ETHER_ADDR_LEN; i++)
j += hwaddr[i] + (hwaddr[i] << 8) + (hwaddr[i] << 16);
@@ -436,7 +443,7 @@ int address_allocate(struct dhcp_context *context, struct daemon *daemon,
addr = context->start;
} while (addr.s_addr != start.s_addr);
}
return 0;
}

View File

@@ -294,7 +294,7 @@ struct dhcp_context {
struct in_addr start, end; /* range of available addresses */
int static_only;
struct dhcp_netid netid;
struct dhcp_context *next;
struct dhcp_context *next, *current;
};
typedef unsigned char u8;
@@ -393,11 +393,15 @@ int setup_reply(HEADER *header, unsigned int qlen,
unsigned long local_ttl);
void extract_addresses(HEADER *header, unsigned int qlen, char *namebuff,
time_t now, struct doctor *doctors);
void extract_neg_addrs(HEADER *header, unsigned int qlen, char *namebuff, time_t now);
void extract_neg_addrs(HEADER *header, unsigned int qlen, char *namebuff, time_t now, unsigned short flags);
int answer_request(HEADER *header, char *limit, unsigned int qlen, struct daemon *daemon, time_t now);
int check_for_bogus_wildcard(HEADER *header, unsigned int qlen, char *name,
struct bogus_addr *addr, time_t now);
unsigned char *find_pseudoheader(HEADER *header, unsigned int plen);
unsigned char *find_pseudoheader(HEADER *header, unsigned int plen,
unsigned int *len, unsigned char **p);
int check_for_local_domain(char *name, time_t now, struct mx_record *mx);
int resize_packet(HEADER *header, unsigned int plen,
unsigned char *pheader, unsigned int hlen);
/* util.c */
unsigned short rand16(void);

View File

@@ -114,7 +114,7 @@ static void send_from(int fd, int nowild, char *packet, int len,
}
}
unsigned short search_servers(struct daemon *daemon, struct all_addr **addrpp,
static unsigned short search_servers(struct daemon *daemon, time_t now, struct all_addr **addrpp,
unsigned short qtype, char *qdomain, int *type, char **domain)
{
@@ -133,10 +133,11 @@ unsigned short search_servers(struct daemon *daemon, struct all_addr **addrpp,
{
unsigned short sflag = serv->addr.sa.sa_family == AF_INET ? F_IPV4 : F_IPV6;
*type = SERV_FOR_NODOTS;
flags = 0;
if (serv->flags & SERV_NO_ADDR)
flags = F_NXDOMAIN;
else if ((serv->flags & SERV_LITERAL_ADDRESS) && (sflag & qtype))
else if (serv->flags & SERV_LITERAL_ADDRESS)
{
if (sflag & qtype)
{
flags = sflag;
if (serv->addr.sa.sa_family == AF_INET)
@@ -146,6 +147,9 @@ unsigned short search_servers(struct daemon *daemon, struct all_addr **addrpp,
*addrpp = (struct all_addr *)&serv->addr.in6.sin6_addr;
#endif
}
else if (!flags)
flags = F_NOERR;
}
}
else if (serv->flags & SERV_HAS_DOMAIN)
{
@@ -158,10 +162,11 @@ unsigned short search_servers(struct daemon *daemon, struct all_addr **addrpp,
*type = SERV_HAS_DOMAIN;
*domain = serv->domain;
matchlen = domainlen;
flags = 0;
if (serv->flags & SERV_NO_ADDR)
flags = F_NXDOMAIN;
else if ((serv->flags & SERV_LITERAL_ADDRESS) && ((sflag | F_QUERY ) & qtype))
else if (serv->flags & SERV_LITERAL_ADDRESS)
{
if ((sflag | F_QUERY ) & qtype)
{
flags = qtype;
if (serv->addr.sa.sa_family == AF_INET)
@@ -171,10 +176,13 @@ unsigned short search_servers(struct daemon *daemon, struct all_addr **addrpp,
*addrpp = (struct all_addr *)&serv->addr.in6.sin6_addr;
#endif
}
else if (!flags)
flags = F_NOERR;
}
}
}
if (flags & ~F_NXDOMAIN) /* flags set here means a literal found */
if (flags & ~(F_NOERR | F_NXDOMAIN)) /* flags set here means a literal found */
{
if (flags & F_QUERY)
log_query(F_CONFIG | F_FORWARD | F_NEG, qdomain, NULL, 0);
@@ -182,9 +190,12 @@ unsigned short search_servers(struct daemon *daemon, struct all_addr **addrpp,
log_query(F_CONFIG | F_FORWARD | flags, qdomain, *addrpp, 0);
}
else if (qtype && (daemon->options & OPT_NODOTS_LOCAL) && !strchr(qdomain, '.'))
flags = F_NXDOMAIN;
if (flags == F_NXDOMAIN && check_for_local_domain(qdomain, now, daemon->mxnames))
flags = F_NOERR;
if (flags & (F_NOERR | F_NXDOMAIN))
if (flags == F_NXDOMAIN || flags == F_NOERR)
log_query(F_CONFIG | F_FORWARD | F_NEG | qtype | (flags & F_NXDOMAIN), qdomain, NULL, 0);
return flags;
@@ -223,7 +234,7 @@ static void forward_query(struct daemon *daemon, int udpfd, union mysockaddr *ud
else
{
if (gotname)
flags = search_servers(daemon, &addrp, gotname, daemon->namebuff, &type, &domain);
flags = search_servers(daemon, now, &addrp, gotname, daemon->namebuff, &type, &domain);
if (!flags && !(forward = get_new_frec(now)))
/* table full - server failure. */
@@ -316,20 +327,21 @@ static void forward_query(struct daemon *daemon, int udpfd, union mysockaddr *ud
}
static int process_reply(struct daemon *daemon, HEADER *header, time_t now,
union mysockaddr *serveraddr, int n)
union mysockaddr *serveraddr, unsigned int n)
{
unsigned char *pheader;
unsigned char *pheader, *sizep;
unsigned int plen;
/* If upstream is advertising a larger UDP packet size
than we allow, trim it so that we don't get overlarge
requests for the client. */
if ((pheader = find_pseudoheader(header, n)))
if ((pheader = find_pseudoheader(header, n, &plen, &sizep)))
{
unsigned short udpsz;
unsigned char *psave = pheader;
unsigned char *psave = sizep;
GETSHORT(udpsz, pheader);
GETSHORT(udpsz, sizep);
if (udpsz > daemon->edns_pktsz)
PUTSHORT(daemon->edns_pktsz, psave);
}
@@ -350,20 +362,52 @@ static int process_reply(struct daemon *daemon, HEADER *header, time_t now,
return 0;
}
if ((header->rcode == NOERROR || header->rcode == NXDOMAIN) && header->opcode == QUERY)
if (header->opcode != QUERY || (header->rcode != NOERROR && header->rcode != NXDOMAIN))
return n;
if (header->rcode == NOERROR && ntohs(header->ancount) != 0)
{
if (!(daemon->bogus_addr &&
header->rcode == NOERROR &&
check_for_bogus_wildcard(header, (unsigned int)n, daemon->namebuff, daemon->bogus_addr, now)))
check_for_bogus_wildcard(header, n, daemon->namebuff, daemon->bogus_addr, now)))
extract_addresses(header, n, daemon->namebuff, now, daemon->doctors);
}
else
{
if (header->rcode == NOERROR && ntohs(header->ancount) != 0)
extract_addresses(header, (unsigned int)n, daemon->namebuff, now, daemon->doctors);
else if (!(daemon->options & OPT_NO_NEG))
extract_neg_addrs(header, (unsigned int)n, daemon->namebuff, now);
unsigned short flags = F_NEG;
int munged = 0;
if (header->rcode == NXDOMAIN)
{
/* if we forwarded a query for a locally known name (because it was for
an unknown type) and the answer is NXDOMAIN, convert that to NODATA,
since we know that the domain exists, even if upstream doesn't */
if (extract_request(header, n, daemon->namebuff, NULL) &&
check_for_local_domain(daemon->namebuff, now, daemon->mxnames))
{
munged = 1;
header->rcode = NOERROR;
}
else
flags |= F_NXDOMAIN;
}
if (!(daemon->options & OPT_NO_NEG))
extract_neg_addrs(header, n, daemon->namebuff, now, flags);
/* do this after extract_neg_addrs. Ensure NODATA reply and remove
nameserver info. */
if (munged)
{
header->ancount = htons(0);
header->nscount = htons(0);
header->arcount = htons(0);
}
}
return 1;
/* the bogus-nxdomain stuff, doctor and NXDOMAIN->NODATA munging can all elide
sections of the packet. Find the new length here and put back pseudoheader
if it was removed. */
return resize_packet(header, n, pheader, plen);
}
/* sets new last_server */
@@ -401,7 +445,7 @@ void reply_query(struct serverfd *sfd, struct daemon *daemon, time_t now)
}
}
if (process_reply(daemon, header, now, &serveraddr, n))
if ((n = process_reply(daemon, header, now, &serveraddr, (unsigned int)n)))
{
header->id = htons(forward->orig_id);
send_from(forward->fd, daemon->options & OPT_NOWILD, daemon->packet, n,
@@ -654,7 +698,7 @@ char *tcp_request(struct daemon *daemon, int confd, time_t now)
char *domain = NULL;
if (gotname)
flags = search_servers(daemon, &addrp, gotname, daemon->namebuff, &type, &domain);
flags = search_servers(daemon, now, &addrp, gotname, daemon->namebuff, &type, &domain);
if (type != 0 || (daemon->options & OPT_ORDER) || !daemon->last_server)
last_server = daemon->servers;
@@ -729,7 +773,7 @@ char *tcp_request(struct daemon *daemon, int confd, time_t now)
/* There's no point in updating the cache, since this process will exit and
lose the information after one query. We make this call for the alias and
bogus-nxdomain side-effects. */
process_reply(daemon, header, now, &last_server->addr, m);
m = process_reply(daemon, header, now, &last_server->addr, (unsigned int)m);
break;
}

View File

@@ -161,7 +161,7 @@ static char *usage =
struct daemon *read_opts (int argc, char **argv)
{
struct daemon *daemon = safe_malloc(sizeof(struct daemon));
char *buff = safe_malloc(MAXDNAME);
char *problem = NULL, *buff = safe_malloc(MAXDNAME);
int option = 0, i;
FILE *file_save = NULL, *f = NULL;
char *file_name_save = NULL, *conffile = CONFFILE;
@@ -187,6 +187,8 @@ struct daemon *read_opts (int argc, char **argv)
while (1)
{
problem = NULL;
if (!f)
#ifdef HAVE_GETOPT_LONG
option = getopt_long(argc, argv, OPTSTRING, (struct option *)opts, NULL);
@@ -366,7 +368,10 @@ struct daemon *read_opts (int argc, char **argv)
if (comma)
*(comma++) = 0;
if (!canonicalise(optarg) || (comma && !canonicalise(comma)))
{
option = '?';
problem = "bad MX name";
}
else
{
struct mx_record *new = safe_malloc(sizeof(struct mx_record));
@@ -380,7 +385,10 @@ struct daemon *read_opts (int argc, char **argv)
case 't':
if (!canonicalise(optarg))
{
option = '?';
problem = "bad MX target";
}
else
daemon->mxtarget = safe_string_alloc(optarg);
break;
@@ -391,7 +399,10 @@ struct daemon *read_opts (int argc, char **argv)
case 'H':
if (daemon->addn_hosts)
{
option = '?';
problem = "only one addn hosts file allowed";
}
else
daemon->addn_hosts = safe_string_alloc(optarg);
break;
@@ -563,7 +574,10 @@ struct daemon *read_opts (int argc, char **argv)
{
*portno = 0;
if (!atoi_check(portno+1, &source_port))
{
option = '?';
problem = "bad port";
}
}
}
@@ -571,7 +585,10 @@ struct daemon *read_opts (int argc, char **argv)
{
*portno = 0;
if (!atoi_check(portno+1, &serv_port))
{
option = '?';
problem = "bad port";
}
}
#ifdef HAVE_IPV6
@@ -717,6 +734,8 @@ struct daemon *read_opts (int argc, char **argv)
new->netid.net = NULL;
new->static_only = 0;
problem = "bad dhcp-range";
for (cp = optarg; *cp; cp++)
if (!(*cp == ' ' || *cp == '.' || (*cp >='0' && *cp <= '9')))
break;
@@ -755,6 +774,17 @@ struct daemon *read_opts (int argc, char **argv)
new->end = tmp;
}
if (option != '?' && k >= 3 && strchr(a[2], '.') &&
((new->netmask.s_addr = inet_addr(a[2])) != (in_addr_t)-1))
{
leasepos = 3;
if (!is_same_net(new->start, new->end, new->netmask))
{
problem = "inconsistent DHCP range";
option = '?';
}
}
if (option == '?')
{
free(new);
@@ -763,10 +793,6 @@ struct daemon *read_opts (int argc, char **argv)
else
daemon->dhcp = new;
if (k >= 3 && strchr(a[2], '.') &&
((new->netmask.s_addr = inet_addr(a[2])) != (in_addr_t)-1))
leasepos = 3;
if (k >= 4 && strchr(a[3], '.') &&
((new->broadcast.s_addr = inet_addr(a[3])) != (in_addr_t)-1))
leasepos = 4;
@@ -955,6 +981,7 @@ struct daemon *read_opts (int argc, char **argv)
if (option == '?')
{
problem = "bad dhcp-host";
if (new->flags & CONFIG_NAME)
free(new->hostname);
if (new->flags & CONFIG_CLID)
@@ -1003,6 +1030,7 @@ struct daemon *read_opts (int argc, char **argv)
if ((new->opt = atoi(optarg)) == 0)
{
option = '?';
problem = "bad dhcp-opt";
if (new->netid)
free(new->netid);
free(new);
@@ -1203,11 +1231,12 @@ struct daemon *read_opts (int argc, char **argv)
{
if (f)
{
sprintf(buff, "error at line %d of %s ", lineno, conffile);
sprintf(buff, "%s at line %d of %s ",
problem ? problem : "error", lineno, conffile);
complain(buff, NULL);
}
else
die("bad command line options: try --help.", NULL);
die("bad command line options: %s.", problem ? problem : "try --help");
}
}

View File

@@ -306,9 +306,44 @@ static unsigned char *skip_questions(HEADER *header, unsigned int plen)
return ansp;
}
unsigned char *find_pseudoheader(HEADER *header, unsigned int plen)
int resize_packet(HEADER *header, unsigned int plen, unsigned char *pheader, unsigned int hlen)
{
/* See if packet has an RFC2671 pseudoheader, and if so return a pointer to it. */
int i;
unsigned char *ansp = skip_questions(header, plen);
unsigned short rdlen;
if (!ansp)
return 0;
for (i = 0;
i < (ntohs(header->ancount) + ntohs(header->nscount) + ntohs(header->arcount));
i++)
{
if (!(ansp = skip_name(ansp, header, plen)))
return 0;
ansp += 8; /* type, class, TTL */
GETSHORT(rdlen, ansp);
if ((unsigned int)(ansp + rdlen - (unsigned char *)header) > plen)
return 0;
ansp += rdlen;
}
/* restore pseudoheader */
if (pheader && ntohs(header->arcount) == 0)
{
/* must use memmove, may overlap */
memmove(ansp, pheader, hlen);
header->arcount = htons(1);
ansp += hlen;
}
return ansp - (unsigned char *)header;
}
unsigned char *find_pseudoheader(HEADER *header, unsigned int plen, unsigned int *len, unsigned char **p)
{
/* See if packet has an RFC2671 pseudoheader, and if so return a pointer to it.
also return length of pseudoheader in *len and pointer to the UDP size in *p */
int i, arcount = ntohs(header->arcount);
unsigned char *ansp;
@@ -330,7 +365,7 @@ unsigned char *find_pseudoheader(HEADER *header, unsigned int plen)
for (i = 0; i < arcount; i++)
{
unsigned char *save;
unsigned char *save, *start = ansp;
if (!(ansp = skip_name(ansp, header, plen)))
return NULL;
@@ -340,9 +375,15 @@ unsigned char *find_pseudoheader(HEADER *header, unsigned int plen)
GETSHORT(rdlen, ansp);
if ((unsigned int)(ansp + rdlen - (unsigned char *)header) > plen)
return NULL;
if (type == T_OPT)
return save;
ansp += rdlen;
if (type == T_OPT)
{
if (len)
*len = ansp - start;
if (p)
*p = save;
return start;
}
}
return NULL;
@@ -397,16 +438,12 @@ static unsigned char *add_text_record(unsigned int nameoffset, unsigned char *p,
/* On receiving an NXDOMAIN or NODATA reply, determine which names are known
not to exist for negative caching. name if a working buffer passed in. */
void extract_neg_addrs(HEADER *header, unsigned int qlen, char *name, time_t now)
void extract_neg_addrs(HEADER *header, unsigned int qlen, char *name, time_t now, unsigned short flags)
{
unsigned char *p;
int i, found_soa = 0;
int qtype, qclass, rdlen;
unsigned long ttl, minttl = 0;
unsigned short flags = F_NEG;
if (header->rcode == NXDOMAIN)
flags |= F_NXDOMAIN;
/* there may be more than one question with some questions
answered. We don't generate negative entries from those. */
@@ -736,6 +773,21 @@ int setup_reply(HEADER *header, unsigned int qlen,
return p - (unsigned char *)header;
}
/* check if name matches local names ie from /etc/hosts or DHCP or local mx names. */
int check_for_local_domain(char *name, time_t now, struct mx_record *mx)
{
struct crec *crecp;
if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4|F_IPV6)) &&
(crecp->flags & (F_HOSTS | F_DHCP)))
return 1;
for (; mx; mx = mx->next)
if (hostname_isequal(name, mx->mxname))
return 1;
return 0;
}
/* Is the packet a reply with the answer address equal to addr?
If so mung is into an NXDOMAIN reply and also put that information
@@ -811,7 +863,7 @@ int answer_request(HEADER *header, char *limit, unsigned int qlen, struct daemon
forward rather than answering from the cache, which doesn't include
security information. */
if ((pheader = find_pseudoheader(header, qlen)))
if (find_pseudoheader(header, qlen, NULL, &pheader))
{
unsigned short udpsz, ext_rcode, flags;
unsigned char *psave = pheader;

View File

@@ -80,7 +80,7 @@ static int have_config(struct dhcp_config *config, unsigned int mask)
int dhcp_reply(struct daemon *daemon, struct in_addr iface_addr, char *iface_name, unsigned int sz, time_t now)
{
struct dhcp_context *context;
struct dhcp_context *context, *context_tmp;
unsigned char *opt, *clid;
struct dhcp_lease *lease, *ltmp;
struct dhcp_vendor *vendor;
@@ -149,11 +149,24 @@ int dhcp_reply(struct daemon *daemon, struct in_addr iface_addr, char *iface_nam
(mess->giaddr.s_addr ? mess->giaddr :
(mess->ciaddr.s_addr ? mess->ciaddr : iface_addr));
for (context = daemon->dhcp; context; context = context->next)
if (context->netmask.s_addr &&
is_same_net(addr, context->start, context->netmask) &&
is_same_net(addr, context->end, context->netmask))
break;
/* More than one context may match, we build a chain of them all on ->current
Note that if netmasks, netid or lease times don't match, odd things may happen. */
for (context = NULL, context_tmp = daemon->dhcp; context_tmp; context_tmp = context_tmp->next)
if (context_tmp->netmask.s_addr &&
is_same_net(addr, context_tmp->start, context_tmp->netmask) &&
is_same_net(addr, context_tmp->end, context_tmp->netmask))
{
context_tmp->current = context;
context = context_tmp;
/* start to build netid chain */
if (context_tmp->netid.net)
{
context_tmp->netid.next = netid;
netid = &context_tmp->netid;
}
}
if (!context)
{
@@ -165,13 +178,6 @@ int dhcp_reply(struct daemon *daemon, struct in_addr iface_addr, char *iface_nam
mess->op = BOOTREPLY;
/* start to build netid chain */
if (context->netid.net)
{
context->netid.next = netid;
netid = &context->netid;
}
if (mess_type == 0)
{
/* BOOTP request */
@@ -268,8 +274,6 @@ int dhcp_reply(struct daemon *daemon, struct in_addr iface_addr, char *iface_nam
}
}
def_time = have_config(config, CONFIG_TIME) ? config->lease_time : context->lease_time;
if (have_config(config, CONFIG_NETID))
{
config->netid.next = netid;
@@ -326,6 +330,8 @@ int dhcp_reply(struct daemon *daemon, struct in_addr iface_addr, char *iface_nam
/* do we have a lease in store? */
lease = lease_find_by_client(clid, clid_len);
def_time = have_config(config, CONFIG_TIME) ? config->lease_time : context->lease_time;
if ((opt = option_find(mess, sz, OPTION_LEASE_TIME)))
{
unsigned int req_time = option_uint(opt, 4);
@@ -392,6 +398,7 @@ int dhcp_reply(struct daemon *daemon, struct in_addr iface_addr, char *iface_nam
}
else
/* make sure this host gets a different address next time. */
for (; context; context = context->current)
context->addr_epoch++;
return 0;