Reinstall useless spaces/tabs as are present in the original dnsmasq source code. This will allow us to apply patches much more straightforward. There is no other change in this commit. git diff --ignore-space-change shows an empty difference.

Signed-off-by: DL6ER <dl6er@dl6er.de>
This commit is contained in:
DL6ER
2019-08-31 13:25:28 +02:00
parent adf4fa3714
commit 2cfd632ff8
29 changed files with 3927 additions and 3927 deletions
+165 -165
View File
@@ -4,12 +4,12 @@
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991, or
(at your option) version 3 dated 29 June, 2007.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -24,12 +24,12 @@ static struct addrlist *find_addrlist(struct addrlist *list, int flag, struct al
if (!(list->flags & ADDRLIST_IPV6))
{
struct in_addr netmask, addr = addr_u->addr.addr4;
if (!(flag & F_IPV4))
continue;
netmask.s_addr = htonl(~(in_addr_t)0 << (32 - list->prefixlen));
if (is_same_net(addr, list->addr.addr.addr4, netmask))
return list;
}
@@ -37,9 +37,9 @@ static struct addrlist *find_addrlist(struct addrlist *list, int flag, struct al
else if (is_same_net6(&(addr_u->addr.addr6), &list->addr.addr.addr6, list->prefixlen))
return list;
#endif
} while ((list = list->next));
return NULL;
}
@@ -47,7 +47,7 @@ static struct addrlist *find_subnet(struct auth_zone *zone, int flag, struct all
{
if (!zone->subnet)
return NULL;
return find_addrlist(zone->subnet, flag, addr_u);
}
@@ -55,7 +55,7 @@ static struct addrlist *find_exclude(struct auth_zone *zone, int flag, struct al
{
if (!zone->exclude)
return NULL;
return find_addrlist(zone->exclude, flag, addr_u);
}
@@ -67,7 +67,7 @@ static int filter_zone(struct auth_zone *zone, int flag, struct all_addr *addr_u
/* No subnets specified, no filter */
if (!zone->subnet)
return 1;
return find_subnet(zone, flag, addr_u) != NULL;
}
@@ -78,18 +78,18 @@ int in_zone(struct auth_zone *zone, char *name, char **cut)
if (cut)
*cut = NULL;
if (namelen >= domainlen &&
if (namelen >= domainlen &&
hostname_isequal(zone->domain, &name[namelen - domainlen]))
{
if (namelen == domainlen)
return 1;
if (name[namelen - domainlen - 1] == '.')
{
if (cut)
*cut = &name[namelen - domainlen - 1];
*cut = &name[namelen - domainlen - 1];
return 1;
}
}
@@ -98,8 +98,8 @@ int in_zone(struct auth_zone *zone, char *name, char **cut)
}
size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t now, union mysockaddr *peer_addr,
int local_query, int do_bit, int have_pseudoheader)
size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t now, union mysockaddr *peer_addr,
int local_query, int do_bit, int have_pseudoheader)
{
char *name = daemon->namebuff;
unsigned char *p, *ansp;
@@ -118,14 +118,14 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
struct all_addr addr;
struct cname *a, *candidate;
unsigned int wclen;
if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY )
return 0;
/* determine end of question section (we put answers there) */
if (!(ansp = skip_questions(header, qlen)))
return 0; /* bad packet */
/* now process each question, answers go in RRs after the question */
p = (unsigned char *)(header+1);
@@ -134,17 +134,17 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
unsigned short flag = 0;
int found = 0;
int cname_wildcard = 0;
/* save pointer to name for copying into answers */
nameoffset = p - (unsigned char *)header;
/* now extract name as .-concatenated string into name */
if (!extract_name(header, qlen, &p, name, 1, 4))
return 0; /* bad packet */
GETSHORT(qtype, p);
GETSHORT(qtype, p);
GETSHORT(qclass, p);
if (qclass != C_IN)
{
auth = 0;
@@ -158,7 +158,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
for (zone = daemon->auth_zones; zone; zone = zone->next)
if ((subnet = find_subnet(zone, flag, &addr)))
break;
if (!zone)
{
auth = 0;
@@ -178,11 +178,11 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
for (intr = daemon->int_names; intr; intr = intr->next)
{
struct addrlist *addrlist;
for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
if (!(addrlist->flags & ADDRLIST_IPV6) && addr.addr.addr4.s_addr == addrlist->addr.addr.addr4.s_addr)
break;
if (addrlist)
break;
else
@@ -194,11 +194,11 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
for (intr = daemon->int_names; intr; intr = intr->next)
{
struct addrlist *addrlist;
for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
if ((addrlist->flags & ADDRLIST_IPV6) && IN6_ARE_ADDR_EQUAL(&addr.addr.addr6, &addrlist->addr.addr.addr6))
break;
if (addrlist)
break;
else
@@ -206,30 +206,30 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
intr = intr->next;
}
#endif
if (intr)
{
if (local_query || in_zone(zone, intr->name, NULL))
{
{
found = 1;
log_query(flag | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL,
T_PTR, C_IN, "d", intr->name))
anscount++;
}
}
if ((crecp = cache_find_by_addr(NULL, &addr, now, flag)))
do {
do {
strcpy(name, cache_get_name(crecp));
if (crecp->flags & F_DHCP && !option_bool(OPT_DHCP_FQDN))
{
char *p = strchr(name, '.');
if (p)
*p = 0; /* must be bare name */
/* add external domain */
if (zone)
{
@@ -238,7 +238,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
}
log_query(flag | F_DHCP | F_REVERSE, name, &addr, record_source(crecp->uid));
found = 1;
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL,
T_PTR, C_IN, "d", name))
anscount++;
@@ -247,14 +247,14 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
{
log_query(crecp->flags & ~F_FORWARD, name, &addr, record_source(crecp->uid));
found = 1;
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL,
T_PTR, C_IN, "d", name))
anscount++;
}
else
continue;
} while ((crecp = cache_find_by_addr(crecp, &addr, now, flag)));
if (found)
@@ -264,7 +264,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
continue;
}
cname_restart:
if (found)
/* NS and SOA .arpa requests have set found above. */
@@ -274,7 +274,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
for (zone = daemon->auth_zones; zone; zone = zone->next)
if (in_zone(zone, name, &cut))
break;
if (!zone)
{
auth = 0;
@@ -286,33 +286,33 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
if (!rec->issrv && (rc = hostname_issubdomain(name, rec->name)))
{
nxdomain = 0;
if (rc == 2 && qtype == T_MX)
{
found = 1;
log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>");
log_query(F_CONFIG | F_RRNAME, name, NULL, "<MX>");
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
NULL, T_MX, C_IN, "sd", rec->weight, rec->target))
anscount++;
}
}
for (move = NULL, up = &daemon->mxnames, rec = daemon->mxnames; rec; rec = rec->next)
if (rec->issrv && (rc = hostname_issubdomain(name, rec->name)))
{
nxdomain = 0;
if (rc == 2 && qtype == T_SRV)
{
found = 1;
log_query(F_CONFIG | F_RRNAME, name, NULL, "<SRV>");
log_query(F_CONFIG | F_RRNAME, name, NULL, "<SRV>");
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
NULL, T_SRV, C_IN, "sssd",
NULL, T_SRV, C_IN, "sssd",
rec->priority, rec->weight, rec->srvport, rec->target))
anscount++;
}
}
/* unlink first SRV record found */
if (!move)
{
@@ -320,11 +320,11 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
*up = rec->next;
}
else
up = &rec->next;
up = &rec->next;
}
else
up = &rec->next;
/* put first SRV record back at the end. */
if (move)
{
@@ -339,13 +339,13 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
if (rc == 2 && txt->class == qtype)
{
found = 1;
log_query(F_CONFIG | F_RRNAME, name, NULL, querystr(NULL, txt->class));
log_query(F_CONFIG | F_RRNAME, name, NULL, querystr(NULL, txt->class));
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
NULL, txt->class, C_IN, "t", txt->len, txt->txt))
anscount++;
}
}
for (txt = daemon->txt; txt; txt = txt->next)
if (txt->class == C_IN && (rc = hostname_issubdomain(name, txt->name)))
{
@@ -353,7 +353,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
if (rc == 2 && qtype == T_TXT)
{
found = 1;
log_query(F_CONFIG | F_RRNAME, name, NULL, "<TXT>");
log_query(F_CONFIG | F_RRNAME, name, NULL, "<TXT>");
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
NULL, T_TXT, C_IN, "t", txt->len, txt->txt))
anscount++;
@@ -368,30 +368,30 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
{
found = 1;
log_query(F_CONFIG | F_RRNAME, name, NULL, "<NAPTR>");
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
NULL, T_NAPTR, C_IN, "sszzzd",
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp, daemon->auth_ttl,
NULL, T_NAPTR, C_IN, "sszzzd",
na->order, na->pref, na->flags, na->services, na->regexp, na->replace))
anscount++;
}
}
if (qtype == T_A)
flag = F_IPV4;
#ifdef HAVE_IPV6
if (qtype == T_AAAA)
flag = F_IPV6;
#endif
for (intr = daemon->int_names; intr; intr = intr->next)
if ((rc = hostname_issubdomain(name, intr->name)))
{
struct addrlist *addrlist;
nxdomain = 0;
if (rc == 2 && flag)
for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
if (((addrlist->flags & ADDRLIST_IPV6) ? T_AAAA : T_A) == qtype &&
(local_query || filter_zone(zone, flag, &addrlist->addr)))
{
@@ -401,17 +401,17 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
#endif
found = 1;
log_query(F_FORWARD | F_CONFIG | flag, name, &addrlist->addr, NULL);
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL, qtype, C_IN,
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL, qtype, C_IN,
qtype == T_A ? "4" : "6", &addrlist->addr))
anscount++;
}
}
if (!cut)
{
nxdomain = 0;
if (qtype == T_SOA)
{
auth = soa = 1; /* inhibits auth section */
@@ -421,36 +421,36 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
else if (qtype == T_AXFR)
{
struct iname *peers;
if (peer_addr->sa.sa_family == AF_INET)
peer_addr->in.sin_port = 0;
#ifdef HAVE_IPV6
else
{
peer_addr->in6.sin6_port = 0;
peer_addr->in6.sin6_port = 0;
peer_addr->in6.sin6_scope_id = 0;
}
#endif
for (peers = daemon->auth_peers; peers; peers = peers->next)
if (sockaddr_isequal(peer_addr, &peers->addr))
break;
/* Refuse all AXFR unless --auth-sec-servers or auth-peers is set */
if ((!daemon->secondary_forward_server && !daemon->auth_peers) ||
(daemon->auth_peers && !peers))
(daemon->auth_peers && !peers))
{
if (peer_addr->sa.sa_family == AF_INET)
inet_ntop(AF_INET, &peer_addr->in.sin_addr, daemon->addrbuff, ADDRSTRLEN);
#ifdef HAVE_IPV6
else
inet_ntop(AF_INET6, &peer_addr->in6.sin6_addr, daemon->addrbuff, ADDRSTRLEN);
inet_ntop(AF_INET6, &peer_addr->in6.sin6_addr, daemon->addrbuff, ADDRSTRLEN);
#endif
my_syslog(LOG_WARNING, _("ignoring zone transfer request from %s"), daemon->addrbuff);
return 0;
}
auth = 1;
soa = 1; /* inhibits auth section */
ns = 1; /* ensure we include NS records! */
@@ -464,70 +464,70 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
auth = 1;
ns = 1; /* inhibits auth section */
found = 1;
log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<NS>");
log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<NS>");
}
}
if (!option_bool(OPT_DHCP_FQDN) && cut)
{
{
*cut = 0; /* remove domain part */
if (!strchr(name, '.') && (crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6)))
{
if (crecp->flags & F_DHCP)
do
{
{
nxdomain = 0;
if ((crecp->flags & flag) &&
if ((crecp->flags & flag) &&
(local_query || filter_zone(zone, flag, &(crecp->addr.addr))))
{
*cut = '.'; /* restore domain part */
log_query(crecp->flags, name, &crecp->addr.addr, record_source(crecp->uid));
*cut = 0; /* remove domain part */
found = 1;
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL, qtype, C_IN,
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL, qtype, C_IN,
qtype == T_A ? "4" : "6", &crecp->addr))
anscount++;
}
} while ((crecp = cache_find_by_name(crecp, name, now, F_IPV4 | F_IPV6)));
}
*cut = '.'; /* restore domain part */
*cut = '.'; /* restore domain part */
}
if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6)))
{
if ((crecp->flags & F_HOSTS) || (((crecp->flags & F_DHCP) && option_bool(OPT_DHCP_FQDN))))
do
{
{
nxdomain = 0;
if ((crecp->flags & flag) && (local_query || filter_zone(zone, flag, &(crecp->addr.addr))))
{
log_query(crecp->flags, name, &crecp->addr.addr, record_source(crecp->uid));
found = 1;
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL, qtype, C_IN,
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, NULL, qtype, C_IN,
qtype == T_A ? "4" : "6", &crecp->addr))
anscount++;
}
} while ((crecp = cache_find_by_name(crecp, name, now, F_IPV4 | F_IPV6)));
}
/* Only supply CNAME if no record for any type is known. */
if (nxdomain)
{
/* Check for possible wildcard match against *.domain
/* Check for possible wildcard match against *.domain
return length of match, to get longest.
Note that if return length of wildcard section, so
we match b.simon to _both_ *.simon and b.simon
but return a longer (better) match to b.simon.
*/
*/
for (wclen = 0, candidate = NULL, a = daemon->cnames; a; a = a->next)
if (a->alias[0] == '*')
{
char *test = name;
while ((test = strchr(test+1, '.')))
{
if (hostname_isequal(test, &(a->alias[1])))
@@ -541,7 +541,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
break;
}
}
}
else if (hostname_isequal(a->alias, name) && strlen(a->alias) > wclen)
{
@@ -549,7 +549,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
wclen = strlen(a->alias);
candidate = a;
}
if (candidate)
{
log_query(F_CONFIG | F_CNAME, name, NULL, NULL);
@@ -560,11 +560,11 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
strcat(name, zone->domain);
}
found = 1;
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
daemon->auth_ttl, &nameoffset,
T_CNAME, C_IN, "d", name))
anscount++;
goto cname_restart;
}
else if (cache_find_non_terminal(name, now))
@@ -572,9 +572,9 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
log_query(flag | F_NEG | (nxdomain ? F_NXDOMAIN : 0) | F_FORWARD | F_AUTH, name, NULL, NULL);
}
}
/* Add auth section */
if (auth && zone)
{
@@ -586,14 +586,14 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
else
{
/* handle NS and SOA for PTR records */
authname = name;
if (!(subnet->flags & ADDRLIST_IPV6))
{
in_addr_t a = ntohl(subnet->addr.addr.addr4.s_addr) >> 8;
char *p = name;
if (subnet->prefixlen >= 24)
p += sprintf(p, "%u.", a & 0xff);
a = a >> 8;
@@ -601,33 +601,33 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
p += sprintf(p, "%u.", a & 0xff);
a = a >> 8;
p += sprintf(p, "%u.in-addr.arpa", a & 0xff);
}
#ifdef HAVE_IPV6
else
{
char *p = name;
int i;
for (i = subnet->prefixlen-1; i >= 0; i -= 4)
{
{
int dig = ((unsigned char *)&subnet->addr.addr.addr6)[i>>3];
p += sprintf(p, "%.1x.", (i>>2) & 1 ? dig & 15 : dig >> 4);
}
p += sprintf(p, "ip6.arpa");
}
#endif
}
/* handle NS and SOA in auth section or for explicit queries */
newoffset = ansp - (unsigned char *)header;
if (((anscount == 0 && !ns) || soa) &&
add_resource_record(header, limit, &trunc, 0, &ansp,
add_resource_record(header, limit, &trunc, 0, &ansp,
daemon->auth_ttl, NULL, T_SOA, C_IN, "ddlllll",
authname, daemon->authserver, daemon->hostmaster,
daemon->soa_sn, daemon->soa_refresh,
daemon->soa_retry, daemon->soa_expiry,
daemon->soa_sn, daemon->soa_refresh,
daemon->soa_retry, daemon->soa_expiry,
daemon->auth_ttl))
{
offset = newoffset;
@@ -636,18 +636,18 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
else
authcount++;
}
if (anscount != 0 || ns)
{
struct name_list *secondary;
newoffset = ansp - (unsigned char *)header;
if (add_resource_record(header, limit, &trunc, -offset, &ansp,
if (add_resource_record(header, limit, &trunc, -offset, &ansp,
daemon->auth_ttl, NULL, T_NS, C_IN, "d", offset == 0 ? authname : NULL, daemon->authserver))
{
if (offset == 0)
if (offset == 0)
offset = newoffset;
if (ns)
if (ns)
anscount++;
else
authcount++;
@@ -655,16 +655,16 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
if (!subnet)
for (secondary = daemon->secondary_forward_server; secondary; secondary = secondary->next)
if (add_resource_record(header, limit, &trunc, offset, &ansp,
if (add_resource_record(header, limit, &trunc, offset, &ansp,
daemon->auth_ttl, NULL, T_NS, C_IN, "d", secondary->name))
{
if (ns)
if (ns)
anscount++;
else
authcount++;
}
}
if (axfr)
{
for (rec = daemon->mxnames; rec; rec = rec->next)
@@ -678,7 +678,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
if (add_resource_record(header, limit, &trunc, -axfroffset, &ansp, daemon->auth_ttl,
NULL, T_SRV, C_IN, "sssd", cut ? rec->name : NULL,
rec->priority, rec->weight, rec->srvport, rec->target))
anscount++;
}
else
@@ -687,87 +687,87 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
NULL, T_MX, C_IN, "sd", cut ? rec->name : NULL, rec->weight, rec->target))
anscount++;
}
/* restore config data */
if (cut)
*cut = '.';
}
for (txt = daemon->rr; txt; txt = txt->next)
if (in_zone(zone, txt->name, &cut))
{
if (cut)
*cut = 0;
if (add_resource_record(header, limit, &trunc, -axfroffset, &ansp, daemon->auth_ttl,
NULL, txt->class, C_IN, "t", cut ? txt->name : NULL, txt->len, txt->txt))
anscount++;
/* restore config data */
if (cut)
*cut = '.';
}
for (txt = daemon->txt; txt; txt = txt->next)
if (txt->class == C_IN && in_zone(zone, txt->name, &cut))
{
if (cut)
*cut = 0;
if (add_resource_record(header, limit, &trunc, -axfroffset, &ansp, daemon->auth_ttl,
NULL, T_TXT, C_IN, "t", cut ? txt->name : NULL, txt->len, txt->txt))
anscount++;
/* restore config data */
if (cut)
*cut = '.';
}
for (na = daemon->naptr; na; na = na->next)
if (in_zone(zone, na->name, &cut))
{
if (cut)
*cut = 0;
if (add_resource_record(header, limit, &trunc, -axfroffset, &ansp, daemon->auth_ttl,
if (add_resource_record(header, limit, &trunc, -axfroffset, &ansp, daemon->auth_ttl,
NULL, T_NAPTR, C_IN, "sszzzd", cut ? na->name : NULL,
na->order, na->pref, na->flags, na->services, na->regexp, na->replace))
anscount++;
/* restore config data */
if (cut)
*cut = '.';
*cut = '.';
}
for (intr = daemon->int_names; intr; intr = intr->next)
if (in_zone(zone, intr->name, &cut))
{
struct addrlist *addrlist;
if (cut)
*cut = 0;
for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
if (!(addrlist->flags & ADDRLIST_IPV6) &&
(local_query || filter_zone(zone, F_IPV4, &addrlist->addr)) &&
add_resource_record(header, limit, &trunc, -axfroffset, &ansp,
(local_query || filter_zone(zone, F_IPV4, &addrlist->addr)) &&
add_resource_record(header, limit, &trunc, -axfroffset, &ansp,
daemon->auth_ttl, NULL, T_A, C_IN, "4", cut ? intr->name : NULL, &addrlist->addr))
anscount++;
#ifdef HAVE_IPV6
for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
if ((addrlist->flags & ADDRLIST_IPV6) &&
for (addrlist = intr->addr; addrlist; addrlist = addrlist->next)
if ((addrlist->flags & ADDRLIST_IPV6) &&
(local_query || filter_zone(zone, F_IPV6, &addrlist->addr)) &&
add_resource_record(header, limit, &trunc, -axfroffset, &ansp,
add_resource_record(header, limit, &trunc, -axfroffset, &ansp,
daemon->auth_ttl, NULL, T_AAAA, C_IN, "6", cut ? intr->name : NULL, &addrlist->addr))
anscount++;
#endif
#endif
/* restore config data */
if (cut)
*cut = '.';
*cut = '.';
}
for (a = daemon->cnames; a; a = a->next)
if (in_zone(zone, a->alias, &cut))
{
@@ -777,16 +777,16 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
strcat(name, ".");
strcat(name, zone->domain);
}
if (cut)
*cut = 0;
if (add_resource_record(header, limit, &trunc, -axfroffset, &ansp,
if (add_resource_record(header, limit, &trunc, -axfroffset, &ansp,
daemon->auth_ttl, NULL,
T_CNAME, C_IN, "d", cut ? a->alias : NULL, name))
anscount++;
}
cache_enumerate(1);
while ((crecp = cache_enumerate(0)))
{
@@ -797,7 +797,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
if ((crecp->flags & F_DHCP) && !option_bool(OPT_DHCP_FQDN))
{
char *cache_name = cache_get_name(crecp);
if (!strchr(cache_name, '.') &&
if (!strchr(cache_name, '.') &&
(local_query || filter_zone(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr.addr))))
{
qtype = T_A;
@@ -805,17 +805,17 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
if (crecp->flags & F_IPV6)
qtype = T_AAAA;
#endif
if (add_resource_record(header, limit, &trunc, -axfroffset, &ansp,
daemon->auth_ttl, NULL, qtype, C_IN,
if (add_resource_record(header, limit, &trunc, -axfroffset, &ansp,
daemon->auth_ttl, NULL, qtype, C_IN,
(crecp->flags & F_IPV4) ? "4" : "6", cache_name, &crecp->addr))
anscount++;
}
}
if ((crecp->flags & F_HOSTS) || (((crecp->flags & F_DHCP) && option_bool(OPT_DHCP_FQDN))))
{
strcpy(name, cache_get_name(crecp));
if (in_zone(zone, name, &cut) &&
if (in_zone(zone, name, &cut) &&
(local_query || filter_zone(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr.addr))))
{
qtype = T_A;
@@ -826,28 +826,28 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
if (cut)
*cut = 0;
if (add_resource_record(header, limit, &trunc, -axfroffset, &ansp,
daemon->auth_ttl, NULL, qtype, C_IN,
if (add_resource_record(header, limit, &trunc, -axfroffset, &ansp,
daemon->auth_ttl, NULL, qtype, C_IN,
(crecp->flags & F_IPV4) ? "4" : "6", cut ? name : NULL, &crecp->addr))
anscount++;
}
}
}
}
/* repeat SOA as last record */
if (add_resource_record(header, limit, &trunc, axfroffset, &ansp,
if (add_resource_record(header, limit, &trunc, axfroffset, &ansp,
daemon->auth_ttl, NULL, T_SOA, C_IN, "ddlllll",
daemon->authserver, daemon->hostmaster,
daemon->soa_sn, daemon->soa_refresh,
daemon->soa_retry, daemon->soa_expiry,
daemon->soa_sn, daemon->soa_refresh,
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 */
header->hb3 = (header->hb3 & ~(HB3_AA | HB3_TC)) | HB3_QR;
@@ -866,11 +866,11 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
/* authoritative */
if (auth)
header->hb3 |= HB3_AA;
/* truncation */
if (trunc)
header->hb3 |= HB3_TC;
if ((auth || local_query) && nxdomain)
SET_RCODE(header, NXDOMAIN);
else
@@ -885,8 +885,8 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
return ansp - (unsigned char *)header;
}
#endif
#endif
+3 -3
View File
@@ -24,11 +24,11 @@ static unsigned int blockdata_count, blockdata_hwm, blockdata_alloced;
static void blockdata_expand(int n)
{
struct blockdata *new = whine_malloc(n * sizeof(struct blockdata));
if (new)
{
int i;
new[n-1].next = keyblock_free;
keyblock_free = new;
@@ -47,7 +47,7 @@ void blockdata_init(void)
blockdata_count = 0;
blockdata_hwm = 0;
/* Note that daemon->cachesize is enforced to have non-zero size if OPT_DNSSEC_VALID is set */
/* Note that daemon->cachesize is enforced to have non-zero size if OPT_DNSSEC_VALID is set */
if (option_bool(OPT_DNSSEC_VALID))
blockdata_expand(daemon->cachesize);
}
+56 -56
View File
@@ -4,12 +4,12 @@
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991, or
(at your option) version 3 dated 29 June, 2007.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -28,7 +28,7 @@
#include <net/if_dl.h>
#include <netinet/if_ether.h>
#if defined(__FreeBSD__)
# include <net/if_var.h>
# include <net/if_var.h>
#endif
#include <netinet/in_var.h>
#ifdef HAVE_IPV6
@@ -72,11 +72,11 @@ int arp_enumerate(void *parm, int (*callback)())
mib[5] = RTF_LLINFO;
#else
mib[5] = 0;
#endif
#endif
if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1 || needed == 0)
return 0;
while (1)
while (1)
{
if (!expand_buf(&buff, needed))
return 0;
@@ -87,7 +87,7 @@ int arp_enumerate(void *parm, int (*callback)())
}
if (rc == -1)
return 0;
for (next = buff.iov_base ; next < (char *)buff.iov_base + needed; next += rtm->rtm_msglen)
{
rtm = (struct rt_msghdr *)next;
@@ -125,14 +125,14 @@ int iface_enumerate(int family, void *parm, int (*callback)())
if (family == AF_INET6)
fd = socket(PF_INET6, SOCK_DGRAM, 0);
#endif
for (addrs = head; addrs; addrs = addrs->ifa_next)
{
if (addrs->ifa_addr->sa_family == family)
{
int iface_index = if_nametoindex(addrs->ifa_name);
if (iface_index == 0 || !addrs->ifa_addr ||
if (iface_index == 0 || !addrs->ifa_addr ||
(!addrs->ifa_netmask && family != AF_LINK))
continue;
@@ -146,9 +146,9 @@ int iface_enumerate(int family, void *parm, int (*callback)())
#endif
netmask = ((struct sockaddr_in *) addrs->ifa_netmask)->sin_addr;
if (addrs->ifa_broadaddr)
broadcast = ((struct sockaddr_in *) addrs->ifa_broadaddr)->sin_addr;
else
broadcast.s_addr = 0;
broadcast = ((struct sockaddr_in *) addrs->ifa_broadaddr)->sin_addr;
else
broadcast.s_addr = 0;
if (!((*callback)(addr, iface_index, NULL, netmask, broadcast, parm)))
goto err;
}
@@ -170,13 +170,13 @@ int iface_enumerate(int family, void *parm, int (*callback)())
memset(&ifr6, 0, sizeof(ifr6));
safe_strncpy(ifr6.ifr_name, addrs->ifa_name, sizeof(ifr6.ifr_name));
ifr6.ifr_addr = *((struct sockaddr_in6 *) addrs->ifa_addr);
if (fd != -1 && ioctl(fd, SIOCGIFAFLAG_IN6, &ifr6) != -1)
{
if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_TENTATIVE)
flags |= IFACE_TENTATIVE;
if (ifr6.ifr_ifru.ifru_flags6 & IN6_IFF_DEPRECATED)
flags |= IFACE_DEPRECATED;
@@ -190,7 +190,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
flags |= IFACE_PERMANENT;
#endif
}
ifr6.ifr_addr = *((struct sockaddr_in6 *) addrs->ifa_addr);
if (fd != -1 && ioctl(fd, SIOCGIFALIFETIME_IN6, &ifr6) != -1)
{
@@ -198,47 +198,47 @@ int iface_enumerate(int family, void *parm, int (*callback)())
preferred = ifr6.ifr_ifru.ifru_lifetime.ia6t_pltime;
}
#endif
for (i = 0; i < IN6ADDRSZ; i++, prefix += 8)
for (i = 0; i < IN6ADDRSZ; i++, prefix += 8)
if (netmask[i] != 0xff)
break;
if (i != IN6ADDRSZ && netmask[i])
for (j = 7; j > 0; j--, prefix++)
if (i != IN6ADDRSZ && netmask[i])
for (j = 7; j > 0; j--, prefix++)
if ((netmask[i] & (1 << j)) == 0)
break;
/* voodoo to clear interface field in address */
if (!option_bool(OPT_NOWILD) && IN6_IS_ADDR_LINKLOCAL(addr))
{
addr->s6_addr[2] = 0;
addr->s6_addr[3] = 0;
}
}
if (!((*callback)(addr, prefix, scope_id, iface_index, flags,
(int) preferred, (int)valid, parm)))
goto err;
goto err;
}
#endif /* HAVE_IPV6 */
#ifdef HAVE_DHCP6
#ifdef HAVE_DHCP6
else if (family == AF_LINK)
{
{
/* Assume ethernet again here */
struct sockaddr_dl *sdl = (struct sockaddr_dl *) addrs->ifa_addr;
if (sdl->sdl_alen != 0 &&
if (sdl->sdl_alen != 0 &&
!((*callback)(iface_index, ARPHRD_ETHER, LLADDR(sdl), sdl->sdl_alen, parm)))
goto err;
}
#endif
#endif
}
}
ret = 1;
err:
errsave = errno;
freeifaddrs(head);
freeifaddrs(head);
if (fd != -1)
close(fd);
errno = errsave;
@@ -255,7 +255,7 @@ void init_bpf(void)
{
int i = 0;
while (1)
while (1)
{
sprintf(daemon->dhcp_buff, "/dev/bpf%d", i++);
if ((daemon->dhcp_raw_fd = open(daemon->dhcp_buff, O_RDWR, 0)) != -1)
@@ -263,7 +263,7 @@ void init_bpf(void)
if (errno != EBUSY)
die(_("cannot create DHCP BPF socket: %s"), NULL, EC_BADNET);
}
}
}
void send_via_bpf(struct dhcp_packet *mess, size_t len,
@@ -271,11 +271,11 @@ void send_via_bpf(struct dhcp_packet *mess, size_t len,
{
/* Hairy stuff, packet either has to go to the
net broadcast or the destination can't reply to ARP yet,
but we do know the physical address.
but we do know the physical address.
Build the packet by steam, and send directly, bypassing
the kernel IP stack */
struct ether_header ether;
struct ether_header ether;
struct ip ip;
struct udphdr {
u16 uh_sport; /* source port */
@@ -283,25 +283,25 @@ void send_via_bpf(struct dhcp_packet *mess, size_t len,
u16 uh_ulen; /* udp length */
u16 uh_sum; /* udp checksum */
} udp;
u32 i, sum;
struct iovec iov[4];
/* Only know how to do ethernet on *BSD */
if (mess->htype != ARPHRD_ETHER || mess->hlen != ETHER_ADDR_LEN)
{
my_syslog(MS_DHCP | LOG_WARNING, _("DHCP request for unsupported hardware type (%d) received on %s"),
my_syslog(MS_DHCP | LOG_WARNING, _("DHCP request for unsupported hardware type (%d) received on %s"),
mess->htype, ifr->ifr_name);
return;
}
ifr->ifr_addr.sa_family = AF_LINK;
if (ioctl(daemon->dhcpfd, SIOCGIFADDR, ifr) < 0)
return;
memcpy(ether.ether_shost, LLADDR((struct sockaddr_dl *)&ifr->ifr_addr), ETHER_ADDR_LEN);
ether.ether_type = htons(ETHERTYPE_IP);
if (ntohs(mess->flags) & 0x8000)
{
memset(ether.ether_dhost, 255, ETHER_ADDR_LEN);
@@ -309,13 +309,13 @@ void send_via_bpf(struct dhcp_packet *mess, size_t len,
}
else
{
memcpy(ether.ether_dhost, mess->chaddr, ETHER_ADDR_LEN);
memcpy(ether.ether_dhost, mess->chaddr, ETHER_ADDR_LEN);
ip.ip_dst.s_addr = mess->yiaddr.s_addr;
}
ip.ip_p = IPPROTO_UDP;
ip.ip_src.s_addr = iface_addr.s_addr;
ip.ip_len = htons(sizeof(struct ip) +
ip.ip_len = htons(sizeof(struct ip) +
sizeof(struct udphdr) +
len) ;
ip.ip_hl = sizeof(struct ip) / 4;
@@ -328,9 +328,9 @@ void send_via_bpf(struct dhcp_packet *mess, size_t len,
for (sum = 0, i = 0; i < sizeof(struct ip) / 2; i++)
sum += ((u16 *)&ip)[i];
while (sum>>16)
sum = (sum & 0xffff) + (sum >> 16);
sum = (sum & 0xffff) + (sum >> 16);
ip.ip_sum = (sum == 0xffff) ? sum : ~sum;
udp.uh_sport = htons(daemon->dhcp_server_port);
udp.uh_dport = htons(daemon->dhcp_client_port);
if (len & 1)
@@ -349,9 +349,9 @@ void send_via_bpf(struct dhcp_packet *mess, size_t len,
while (sum>>16)
sum = (sum & 0xffff) + (sum >> 16);
udp.uh_sum = (sum == 0xffff) ? sum : ~sum;
ioctl(daemon->dhcp_raw_fd, BIOCSETIF, ifr);
iov[0].iov_base = &ether;
iov[0].iov_len = sizeof(ether);
iov[1].iov_base = &ip;
@@ -365,7 +365,7 @@ void send_via_bpf(struct dhcp_packet *mess, size_t len,
}
#endif /* defined(HAVE_BSD_NETWORK) && defined(HAVE_DHCP) */
#ifdef HAVE_BSD_NETWORK
@@ -373,7 +373,7 @@ void route_init(void)
{
/* AF_UNSPEC: all addr families */
daemon->routefd = socket(PF_ROUTE, SOCK_RAW, AF_UNSPEC);
if (daemon->routefd == -1 || !fix_fd(daemon->routefd))
die(_("cannot create PF_ROUTE socket: %s"), NULL, EC_BADNET);
}
@@ -387,7 +387,7 @@ void route_sock(void)
return;
msg = (struct if_msghdr *)daemon->packet;
if (rc < msg->ifm_msglen)
return;
@@ -415,13 +415,13 @@ void route_sock(void)
RTA_IFP, RTA_IFA, RTA_AUTHOR, RTA_BRD };
int of;
unsigned int i;
for (i = 0, of = sizeof(struct ifa_msghdr); of < rc && i < sizeof(maskvec)/sizeof(maskvec[0]); i++)
if (mask & maskvec[i])
for (i = 0, of = sizeof(struct ifa_msghdr); of < rc && i < sizeof(maskvec)/sizeof(maskvec[0]); i++)
if (mask & maskvec[i])
{
struct sockaddr *sa = (struct sockaddr *)((char *)msg + of);
size_t diff = (sa->sa_len != 0) ? sa->sa_len : sizeof(long);
if (maskvec[i] == RTA_IFA)
{
del_family = sa->sa_family;
@@ -434,13 +434,13 @@ void route_sock(void)
else
del_family = 0;
}
of += diff;
/* round up as needed */
if (diff & (sizeof(long) - 1))
if (diff & (sizeof(long) - 1))
of += sizeof(long) - (diff & (sizeof(long) - 1));
}
queue_event(EVENT_NEWADDR);
}
}
+189 -189
View File
File diff suppressed because it is too large Load Diff
+29 -29
View File
@@ -4,12 +4,12 @@
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991, or
(at your option) version 3 dated 29 June, 2007.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -58,7 +58,7 @@
#define SOA_EXPIRY 1209600 /* SOA expiry default */
#define LOOP_TEST_DOMAIN "test" /* domain for loop testing, "test" is reserved by RFC 2606 and won't therefore clash */
#define LOOP_TEST_TYPE T_TXT
/* compile-time options: uncomment below to enable or do eg.
make COPTS=-DHAVE_BROKEN_RTC
@@ -68,9 +68,9 @@ HAVE_BROKEN_RTC
for timing, and keep lease lengths rather than expiry times
in its leases file. This also make dnsmasq "flash disk friendly".
Normally, dnsmasq tries very hard to keep the on-disk leases file
up-to-date: rewriting it after every renewal. When HAVE_BROKEN_RTC
is in effect, the lease file is only written when a new lease is
created, or an old one destroyed. (Because those are the only times
up-to-date: rewriting it after every renewal. When HAVE_BROKEN_RTC
is in effect, the lease file is only written when a new lease is
created, or an old one destroyed. (Because those are the only times
it changes.) This vastly reduces the number of file writes, and makes
it viable to keep the lease file on a flash filesystem.
NOTE: when enabling or disabling this, be sure to delete any old
@@ -89,11 +89,11 @@ HAVE_SCRIPT
define this to get the ability to call scripts on lease-change.
HAVE_LUASCRIPT
define this to get the ability to call Lua script on lease-change. (implies HAVE_SCRIPT)
define this to get the ability to call Lua script on lease-change. (implies HAVE_SCRIPT)
HAVE_DBUS
define this if you want to link against libdbus, and have dnsmasq
support some methods to allow (re)configuration of the upstream DNS
support some methods to allow (re)configuration of the upstream DNS
servers via DBus.
HAVE_UBUS
@@ -101,7 +101,7 @@ HAVE_UBUS
HAVE_IDN
define this if you want international domain name 2003 support.
HAVE_LIBIDN2
define this if you want international domain name 2008 support.
@@ -142,8 +142,8 @@ NO_LARGEFILE
NO_AUTH
NO_DUMPFILE
NO_INOTIFY
these are available to explicitly disable compile time options which would
otherwise be enabled automatically (HAVE_IPV6, >2Gb file sizes) or
these are available to explicitly disable compile time options which would
otherwise be enabled automatically (HAVE_IPV6, >2Gb file sizes) or
which are enabled by default in the distributed source tree. Building dnsmasq
with something like "make COPTS=-DNO_SCRIPT" will do the trick.
NO_GMP
@@ -152,13 +152,13 @@ NO_GMP
LEASEFILE
CONFFILE
RESOLVFILE
the default locations of these files are determined below, but may be overridden
the default locations of these files are determined below, but may be overridden
in a build command line using COPTS.
*/
/* Defining this builds a binary which handles time differently and works better on a system without a
stable RTC (it uses uptime, not epoch time) and writes the DHCP leases file less often to avoid flash wear.
/* Defining this builds a binary which handles time differently and works better on a system without a
stable RTC (it uses uptime, not epoch time) and writes the DHCP leases file less often to avoid flash wear.
*/
/* #define HAVE_BROKEN_RTC */
@@ -167,16 +167,16 @@ RESOLVFILE
has no library dependencies other than libc */
#define HAVE_DHCP
#define HAVE_DHCP6
#define HAVE_DHCP6
#define HAVE_TFTP
#define HAVE_SCRIPT
#define HAVE_AUTH
#define HAVE_IPSET
#define HAVE_IPSET
#define HAVE_LOOP
#define HAVE_DUMPFILE
/* Build options which require external libraries.
Defining HAVE_<opt>_STATIC as _well_ as HAVE_<opt> will link the library statically.
You can use "make COPTS=-DHAVE_<opt>" instead of editing these.
@@ -236,10 +236,10 @@ HAVE_SOLARIS_NETWORK
define exactly one of these to alter interaction with kernel networking.
HAVE_GETOPT_LONG
defined when GNU-style getopt_long available.
defined when GNU-style getopt_long available.
HAVE_SOCKADDR_SA_LEN
defined if struct sockaddr has sa_len field (*BSD)
defined if struct sockaddr has sa_len field (*BSD)
*/
/* Must precede __linux__ since uClinux defines __linux__ too. */
@@ -248,7 +248,7 @@ HAVE_SOCKADDR_SA_LEN
#define HAVE_GETOPT_LONG
#undef HAVE_SOCKADDR_SA_LEN
/* Never use fork() on uClinux. Note that this is subtly different from the
--keep-in-foreground option, since it also suppresses forking new
--keep-in-foreground option, since it also suppresses forking new
processes for TCP connections and disables the call-a-script on leasechange
system. It's intended for use on MMU-less kernels. */
#define NO_FORK
@@ -292,9 +292,9 @@ HAVE_SOCKADDR_SA_LEN
#define HAVE_SOCKADDR_SA_LEN
/* Define before sys/socket.h is included so we get socklen_t */
#define _BSD_SOCKLEN_T_
/* Select the RFC_3542 version of the IPv6 socket API.
/* Select the RFC_3542 version of the IPv6 socket API.
Define before netinet6/in6.h is included. */
#define __APPLE_USE_RFC_3542
#define __APPLE_USE_RFC_3542
#define NO_IPSET
#elif defined(__NetBSD__)
@@ -306,8 +306,8 @@ HAVE_SOCKADDR_SA_LEN
#define HAVE_SOLARIS_NETWORK
#define HAVE_GETOPT_LONG
#undef HAVE_SOCKADDR_SA_LEN
#define ETHER_ADDR_LEN 6
#define ETHER_ADDR_LEN 6
#endif
/* Decide if we're going to support IPv6 */
@@ -326,7 +326,7 @@ HAVE_SOCKADDR_SA_LEN
#endif
/* rules to implement compile-time option dependencies and
/* rules to implement compile-time option dependencies and
the NO_XXX flags */
#ifdef NO_IPV6
@@ -386,7 +386,7 @@ HAVE_SOCKADDR_SA_LEN
#ifdef DNSMASQ_COMPILE_OPTS
static char *compile_opts =
static char *compile_opts =
#ifndef HAVE_IPV6
"no-"
#endif
@@ -414,8 +414,8 @@ static char *compile_opts =
#else
#if !defined(HAVE_IDN)
"no-"
#endif
"IDN "
#endif
"IDN "
#endif
#ifndef HAVE_DHCP
"no-"
@@ -424,7 +424,7 @@ static char *compile_opts =
#if defined(HAVE_DHCP)
# if !defined (HAVE_DHCP6)
"no-"
# endif
# endif
"DHCPv6 "
#endif
#if !defined(HAVE_SCRIPT)
+66 -66
View File
@@ -4,12 +4,12 @@
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991, or
(at your option) version 3 dated 29 June, 2007.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -29,7 +29,7 @@
/* Implement a "hash-function" to the nettle API, which simply returns
the input data, concatenated into a single, statically maintained, buffer.
Used for the EdDSA sigs, which operate on the whole message, rather
Used for the EdDSA sigs, which operate on the whole message, rather
than a digest. */
struct null_hash_digest
@@ -56,11 +56,11 @@ static void null_hash_update(void *ctxv, size_t length, const uint8_t *src)
{
struct null_hash_ctx *ctx = ctxv;
size_t new_len = ctx->len + length;
if (new_len > null_hash_buff_sz)
{
uint8_t *new;
if (!(new = whine_malloc(new_len + BUFF_INCR)))
return;
@@ -70,7 +70,7 @@ static void null_hash_update(void *ctxv, size_t length, const uint8_t *src)
memcpy(new, null_hash_buff, ctx->len);
free(null_hash_buff);
}
null_hash_buff_sz = new_len + BUFF_INCR;
null_hash_buff = new;
}
@@ -78,12 +78,12 @@ static void null_hash_update(void *ctxv, size_t length, const uint8_t *src)
memcpy(null_hash_buff + ctx->len, src, length);
ctx->len += length;
}
static void null_hash_digest(void *ctx, size_t length, uint8_t *dst)
{
(void)length;
((struct null_hash_digest *)dst)->buff = null_hash_buff;
((struct null_hash_digest *)dst)->len = ((struct null_hash_ctx *)ctx)->len;
}
@@ -103,7 +103,7 @@ const struct nettle_hash *hash_find(char *name)
{
if (!name)
return NULL;
/* We provide a "null" hash which returns the input data as digest. */
if (strcmp(null_hash.name, name) == 0)
return &null_hash;
@@ -112,7 +112,7 @@ const struct nettle_hash *hash_find(char *name)
incompatibilities if sizeof(nettle_hashes) changes between library
versions. It also #defines nettle_hashes, so use that to tell
if we have the new facilities. */
#ifdef nettle_hashes
return nettle_lookup_hash(name);
#else
@@ -123,7 +123,7 @@ const struct nettle_hash *hash_find(char *name)
if (strcmp(nettle_hashes[i]->name, name) == 0)
return nettle_hashes[i];
}
return NULL;
#endif
}
@@ -147,7 +147,7 @@ int hash_init(const struct nettle_hash *hash, void **ctxp, unsigned char **diges
ctx = new;
ctx_sz = hash->context_size;
}
if (digest_sz < hash->digest_size)
{
if (!(new = whine_malloc(hash->digest_size)))
@@ -165,46 +165,46 @@ int hash_init(const struct nettle_hash *hash, void **ctxp, unsigned char **diges
return 1;
}
static int dnsmasq_rsa_verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
unsigned char *digest, size_t digest_len, int algo)
{
unsigned char *p;
size_t exp_len;
static struct rsa_public_key *key = NULL;
static mpz_t sig_mpz;
(void)digest_len;
if (key == NULL)
{
if (!(key = whine_malloc(sizeof(struct rsa_public_key))))
return 0;
nettle_rsa_public_key_init(key);
mpz_init(sig_mpz);
}
if ((key_len < 3) || !(p = blockdata_retrieve(key_data, key_len, NULL)))
return 0;
key_len--;
if ((exp_len = *p++) == 0)
{
GETSHORT(exp_len, p);
key_len -= 2;
}
if (exp_len >= key_len)
return 0;
key->size = key_len - exp_len;
mpz_import(key->e, exp_len, 1, 1, 0, 0, p);
mpz_import(key->n, key->size, 1, 1, 0, 0, p + exp_len);
mpz_import(sig_mpz, sig_len, 1, 1, 0, 0, sig);
switch (algo)
{
case 1:
@@ -218,7 +218,7 @@ static int dnsmasq_rsa_verify(struct blockdata *key_data, unsigned int key_len,
}
return 0;
}
}
static int dnsmasq_dsa_verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
unsigned char *digest, size_t digest_len, int algo)
@@ -229,42 +229,42 @@ static int dnsmasq_dsa_verify(struct blockdata *key_data, unsigned int key_len,
static mpz_t y;
static struct dsa_params *params = NULL;
static struct dsa_signature *sig_struct;
(void)digest_len;
if (params == NULL)
{
if (!(sig_struct = whine_malloc(sizeof(struct dsa_signature))) ||
!(params = whine_malloc(sizeof(struct dsa_params))))
if (!(sig_struct = whine_malloc(sizeof(struct dsa_signature))) ||
!(params = whine_malloc(sizeof(struct dsa_params))))
return 0;
mpz_init(y);
nettle_dsa_params_init(params);
nettle_dsa_signature_init(sig_struct);
}
if ((sig_len < 41) || !(p = blockdata_retrieve(key_data, key_len, NULL)))
return 0;
t = *p++;
if (key_len < (213 + (t * 24)))
return 0;
mpz_import(params->q, 20, 1, 1, 0, 0, p); p += 20;
mpz_import(params->p, 64 + (t*8), 1, 1, 0, 0, p); p += 64 + (t*8);
mpz_import(params->g, 64 + (t*8), 1, 1, 0, 0, p); p += 64 + (t*8);
mpz_import(y, 64 + (t*8), 1, 1, 0, 0, p); p += 64 + (t*8);
mpz_import(sig_struct->r, 20, 1, 1, 0, 0, sig+1);
mpz_import(sig_struct->s, 20, 1, 1, 0, 0, sig+21);
(void)algo;
return nettle_dsa_verify(params, y, digest_len, digest, sig_struct);
}
static int dnsmasq_ecdsa_verify(struct blockdata *key_data, unsigned int key_len,
}
static int dnsmasq_ecdsa_verify(struct blockdata *key_data, unsigned int key_len,
unsigned char *sig, size_t sig_len,
unsigned char *digest, size_t digest_len, int algo)
{
@@ -275,17 +275,17 @@ static int dnsmasq_ecdsa_verify(struct blockdata *key_data, unsigned int key_len
static struct ecc_point *key_256 = NULL, *key_384 = NULL;
static mpz_t x, y;
static struct dsa_signature *sig_struct;
if (!sig_struct)
{
if (!(sig_struct = whine_malloc(sizeof(struct dsa_signature))))
return 0;
nettle_dsa_signature_init(sig_struct);
mpz_init(x);
mpz_init(y);
}
switch (algo)
{
case 13:
@@ -293,63 +293,63 @@ static int dnsmasq_ecdsa_verify(struct blockdata *key_data, unsigned int key_len
{
if (!(key_256 = whine_malloc(sizeof(struct ecc_point))))
return 0;
nettle_ecc_point_init(key_256, &nettle_secp_256r1);
}
key = key_256;
t = 32;
break;
case 14:
if (!key_384)
{
if (!(key_384 = whine_malloc(sizeof(struct ecc_point))))
return 0;
nettle_ecc_point_init(key_384, &nettle_secp_384r1);
}
key = key_384;
t = 48;
break;
default:
return 0;
}
if (sig_len != 2*t || key_len != 2*t ||
!(p = blockdata_retrieve(key_data, key_len, NULL)))
return 0;
mpz_import(x, t , 1, 1, 0, 0, p);
mpz_import(y, t , 1, 1, 0, 0, p + t);
if (!ecc_point_set(key, x, y))
return 0;
mpz_import(sig_struct->r, t, 1, 1, 0, 0, sig);
mpz_import(sig_struct->s, t, 1, 1, 0, 0, sig + t);
return nettle_ecdsa_verify(key, digest_len, digest, sig_struct);
}
static int dnsmasq_eddsa_verify(struct blockdata *key_data, unsigned int key_len,
static int dnsmasq_eddsa_verify(struct blockdata *key_data, unsigned int key_len,
unsigned char *sig, size_t sig_len,
unsigned char *digest, size_t digest_len, int algo)
{
unsigned char *p;
if (key_len != ED25519_KEY_SIZE ||
sig_len != ED25519_SIGNATURE_SIZE ||
digest_len != sizeof(struct null_hash_digest) ||
!(p = blockdata_retrieve(key_data, key_len, NULL)))
return 0;
/* The "digest" returned by the null_hash function is simply a struct null_hash_digest
which has a pointer to the actual data and a length, because the buffer
may need to be extended during "hashing". */
switch (algo)
{
case 15:
@@ -368,27 +368,27 @@ static int dnsmasq_eddsa_verify(struct blockdata *key_data, unsigned int key_len
static int (*verify_func(int algo))(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
unsigned char *digest, size_t digest_len, int algo)
{
/* Enure at runtime that we have support for this digest */
if (!hash_find(algo_digest_name(algo)))
return NULL;
/* This switch defines which sig algorithms we support, can't introspect Nettle for that. */
switch (algo)
{
case 1: case 5: case 7: case 8: case 10:
return dnsmasq_rsa_verify;
case 3: case 6:
case 3: case 6:
return dnsmasq_dsa_verify;
case 13: case 14:
return dnsmasq_ecdsa_verify;
case 15: case 16:
return dnsmasq_eddsa_verify;
}
return NULL;
}
@@ -398,9 +398,9 @@ int verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig,
int (*func)(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
unsigned char *digest, size_t digest_len, int algo);
func = verify_func(algo);
if (!func)
return 0;
@@ -409,7 +409,7 @@ int verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig,
/* Note the ds_digest_name(), algo_digest_name() and nsec3_digest_name()
define which algo numbers we support. If algo_digest_name() returns
non-NULL for an algorithm number, we assume that algorithm is
non-NULL for an algorithm number, we assume that algorithm is
supported by verify(). */
/* http://www.iana.org/assignments/ds-rr-types/ds-rr-types.xhtml */
@@ -424,7 +424,7 @@ char *ds_digest_name(int digest)
default: return NULL;
}
}
/* http://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml */
char *algo_digest_name(int algo)
{
@@ -432,7 +432,7 @@ char *algo_digest_name(int algo)
{
case 1: return NULL; /* RSA/MD5 - Must Not Implement. RFC 6944 para 2.3. */
case 2: return NULL; /* Diffie-Hellman */
case 3: return "sha1"; /* DSA/SHA1 */
case 3: return "sha1"; /* DSA/SHA1 */
case 5: return "sha1"; /* RSA/SHA1 */
case 6: return "sha1"; /* DSA-NSEC3-SHA1 */
case 7: return "sha1"; /* RSASHA1-NSEC3-SHA1 */
@@ -440,13 +440,13 @@ char *algo_digest_name(int algo)
case 10: return "sha512"; /* RSA/SHA-512 */
case 12: return NULL; /* ECC-GOST */
case 13: return "sha256"; /* ECDSAP256SHA256 */
case 14: return "sha384"; /* ECDSAP384SHA384 */
case 14: return "sha384"; /* ECDSAP384SHA384 */
case 15: return "null_hash"; /* ED25519 */
case 16: return NULL; /* ED448 */
default: return NULL;
}
}
/* http://www.iana.org/assignments/dnssec-nsec3-parameters/dnssec-nsec3-parameters.xhtml */
char *nsec3_digest_name(int digest)
{
+1 -1
View File
@@ -482,7 +482,7 @@ char *whichdevice(void)
return NULL;
}
void bindtodevice(char *device, int fd)
{
size_t len = strlen(device)+1;
+140 -140
View File
@@ -4,12 +4,12 @@
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991, or
(at your option) version 3 dated 29 June, 2007.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -51,7 +51,7 @@ static int make_fd(int port)
if (fd == -1)
die (_("cannot create DHCP socket: %s"), NULL, EC_BADNET);
if (!fix_fd(fd) ||
#if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT)
setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, &mtu, sizeof(mtu)) == -1 ||
@@ -64,31 +64,31 @@ static int make_fd(int port)
#else
setsockopt(fd, IPPROTO_IP, IP_RECVIF, &oneopt, sizeof(oneopt)) == -1 ||
#endif
setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &oneopt, sizeof(oneopt)) == -1)
setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &oneopt, sizeof(oneopt)) == -1)
die(_("failed to set options on DHCP socket: %s"), NULL, EC_BADNET);
/* When bind-interfaces is set, there might be more than one dnsmasq
instance binding port 67. That's OK if they serve different networks.
Need to set REUSEADDR|REUSEPORT to make this possible.
Handle the case that REUSEPORT is defined, but the kernel doesn't
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 = 0;
#ifdef SO_REUSEPORT
if ((rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, sizeof(oneopt))) == -1 &&
if ((rc = setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &oneopt, sizeof(oneopt))) == -1 &&
errno == ENOPROTOOPT)
rc = 0;
#endif
if (rc != -1)
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);
}
memset(&saddr, 0, sizeof(saddr));
saddr.sin_family = AF_INET;
saddr.sin_port = htons(port);
@@ -119,16 +119,16 @@ void dhcp_init(void)
/* When we're not using capabilities, we need to do this here before
we drop root. Also, set buffer size small, to avoid wasting
kernel buffers */
if (option_bool(OPT_NO_PING))
daemon->dhcp_icmp_fd = -1;
else if ((daemon->dhcp_icmp_fd = make_icmp_sock()) == -1 ||
setsockopt(daemon->dhcp_icmp_fd, SOL_SOCKET, SO_RCVBUF, &oneopt, sizeof(oneopt)) == -1 )
die(_("cannot create ICMP raw socket: %s."), NULL, EC_BADNET);
/* Make BPF raw send socket */
init_bpf();
#endif
#endif
}
void dhcp_packet(time_t now, int pxe_fd)
@@ -144,7 +144,7 @@ void dhcp_packet(time_t now, int pxe_fd)
struct sockaddr_in dest;
struct cmsghdr *cmptr;
struct iovec iov;
ssize_t sz;
ssize_t sz;
int iface_index = 0, unicast_dest = 0, is_inform = 0, loopback = 0;
int rcvd_iface_index;
struct in_addr iface_addr;
@@ -154,14 +154,14 @@ void dhcp_packet(time_t now, int pxe_fd)
struct arpreq arp_req;
struct timeval tv;
#endif
union {
struct cmsghdr align; /* this ensures alignment */
#if defined(HAVE_LINUX_NETWORK)
char control[CMSG_SPACE(sizeof(struct in_pktinfo))];
#elif defined(HAVE_SOLARIS_NETWORK)
char control[CMSG_SPACE(sizeof(unsigned int))];
#elif defined(HAVE_BSD_NETWORK)
#elif defined(HAVE_BSD_NETWORK)
char control[CMSG_SPACE(sizeof(struct sockaddr_dl))];
#endif
} control_u;
@@ -173,11 +173,11 @@ void dhcp_packet(time_t now, int pxe_fd)
msg.msg_namelen = sizeof(dest);
msg.msg_iov = &daemon->dhcp_packet;
msg.msg_iovlen = 1;
if ((sz = recv_dhcp_packet(fd, &msg)) == -1 ||
(sz < (ssize_t)(sizeof(*mess) - sizeof(mess->options))))
if ((sz = recv_dhcp_packet(fd, &msg)) == -1 ||
(sz < (ssize_t)(sizeof(*mess) - sizeof(mess->options))))
return;
#if defined (HAVE_LINUX_NETWORK)
if (ioctl(fd, SIOCGSTAMP, &tv) == 0)
recvtime = tv.tv_sec;
@@ -196,7 +196,7 @@ void dhcp_packet(time_t now, int pxe_fd)
unicast_dest = 1;
}
#elif defined(HAVE_BSD_NETWORK)
#elif defined(HAVE_BSD_NETWORK)
if (msg.msg_controllen >= sizeof(struct cmsghdr))
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
@@ -208,8 +208,8 @@ void dhcp_packet(time_t now, int pxe_fd)
p.c = CMSG_DATA(cmptr);
iface_index = p.s->sdl_index;
}
#elif defined(HAVE_SOLARIS_NETWORK)
#elif defined(HAVE_SOLARIS_NETWORK)
if (msg.msg_controllen >= sizeof(struct cmsghdr))
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVIF)
@@ -222,18 +222,18 @@ void dhcp_packet(time_t now, int pxe_fd)
iface_index = *(p.i);
}
#endif
if (!indextoname(daemon->dhcpfd, iface_index, ifr.ifr_name) ||
ioctl(daemon->dhcpfd, SIOCGIFFLAGS, &ifr) != 0)
return;
mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base;
loopback = !mess->giaddr.s_addr && (ifr.ifr_flags & IFF_LOOPBACK);
#ifdef HAVE_LINUX_NETWORK
/* ARP fiddling uses original interface even if we pretend to use a different one. */
safe_strncpy(arp_req.arp_dev, ifr.ifr_name, sizeof(arp_req.arp_dev));
#endif
#endif
/* If the interface on which the DHCP request was received is an
alias of some other interface (as specified by the
@@ -253,13 +253,13 @@ void dhcp_packet(time_t now, int pxe_fd)
bridge->iface);
return;
}
else
else
{
safe_strncpy(ifr.ifr_name, bridge->iface, sizeof(ifr.ifr_name));
break;
}
}
if (alias)
break;
}
@@ -269,18 +269,18 @@ void dhcp_packet(time_t now, int pxe_fd)
if (!(msg.msg_flags & MSG_BCAST))
unicast_dest = 1;
#endif
if ((relay = relay_reply4((struct dhcp_packet *)daemon->dhcp_packet.iov_base, ifr.ifr_name)))
{
/* Reply from server, using us as relay. */
rcvd_iface_index = relay->iface_index;
if (!indextoname(daemon->dhcpfd, rcvd_iface_index, ifr.ifr_name))
return;
is_relay_reply = 1;
is_relay_reply = 1;
iov.iov_len = sz;
#ifdef HAVE_LINUX_NETWORK
safe_strncpy(arp_req.arp_dev, ifr.ifr_name, sizeof(arp_req.arp_dev));
#endif
#endif
}
else
{
@@ -293,43 +293,43 @@ void dhcp_packet(time_t now, int pxe_fd)
my_syslog(MS_DHCP | LOG_WARNING, _("DHCP packet received on %s which has no address"), ifr.ifr_name);
return;
}
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
return;
/* unlinked contexts/relays are marked by context->current == context */
for (context = daemon->dhcp; context; context = context->next)
context->current = context;
for (relay = daemon->relay4; relay; relay = relay->next)
relay->current = relay;
parm.current = NULL;
parm.relay = NULL;
parm.relay_local.s_addr = 0;
parm.ind = iface_index;
if (!iface_check(AF_INET, (struct all_addr *)&iface_addr, ifr.ifr_name, NULL))
{
/* If we failed to match the primary address of the interface, see if we've got a --listen-address
for a secondary */
struct match_param match;
match.matched = 0;
match.ind = iface_index;
if (!daemon->if_addrs ||
!iface_enumerate(AF_INET, &match, check_listen_addrs) ||
!match.matched)
return;
iface_addr = match.addr;
/* make sure secondary address gets priority in case
there is more than one address on the interface in the same subnet */
complete_context(match.addr, iface_index, NULL, match.netmask, match.broadcast, &parm);
}
}
if (!iface_enumerate(AF_INET, &parm, complete_context))
return;
@@ -343,11 +343,11 @@ void dhcp_packet(time_t now, int pxe_fd)
return;
lease_prune(NULL, now); /* lose any expired leases */
iov.iov_len = dhcp_reply(parm.current, ifr.ifr_name, iface_index, (size_t)sz,
iov.iov_len = dhcp_reply(parm.current, ifr.ifr_name, iface_index, (size_t)sz,
now, unicast_dest, loopback, &is_inform, pxe_fd, iface_addr, recvtime);
lease_update_file(now);
lease_update_dns(0);
if (iov.iov_len == 0)
return;
}
@@ -358,16 +358,16 @@ void dhcp_packet(time_t now, int pxe_fd)
msg.msg_controllen = 0;
msg.msg_iov = &iov;
iov.iov_base = daemon->dhcp_packet.iov_base;
/* packet buffer may have moved */
mess = (struct dhcp_packet *)daemon->dhcp_packet.iov_base;
#ifdef HAVE_SOCKADDR_SA_LEN
dest.sin_len = sizeof(struct sockaddr_in);
#endif
if (pxe_fd)
{
{
if (mess->ciaddr.s_addr != 0)
dest.sin_addr = mess->ciaddr;
}
@@ -375,21 +375,21 @@ void dhcp_packet(time_t now, int pxe_fd)
{
/* Send to BOOTP relay */
dest.sin_port = htons(daemon->dhcp_server_port);
dest.sin_addr = mess->giaddr;
dest.sin_addr = mess->giaddr;
}
else if (mess->ciaddr.s_addr)
{
/* If the client's idea of its own address tallys with
the source address in the request packet, we believe the
source port too, and send back to that. If we're replying
source port too, and send back to that. If we're replying
to a DHCPINFORM, trust the source address always. */
if ((!is_inform && dest.sin_addr.s_addr != mess->ciaddr.s_addr) ||
dest.sin_port == 0 || dest.sin_addr.s_addr == 0 || is_relay_reply)
{
dest.sin_port = htons(daemon->dhcp_client_port);
dest.sin_port = htons(daemon->dhcp_client_port);
dest.sin_addr = mess->ciaddr;
}
}
}
#if defined(HAVE_LINUX_NETWORK)
else
{
@@ -438,9 +438,9 @@ void dhcp_packet(time_t now, int pxe_fd)
}
else
{
/* unicast to unconfigured client. Inject mac address direct into ARP cache.
/* unicast to unconfigured client. Inject mac address direct into ARP cache.
Note that this only works for ethernet on solaris, because we use SIOCSARP
and not SIOCSXARP, which would be perfect, except that it returns ENXIO
and not SIOCSXARP, which would be perfect, except that it returns ENXIO
mysteriously. Bah. Fall back to broadcast for other net types. */
struct arpreq req;
dest.sin_addr = mess->yiaddr;
@@ -452,17 +452,17 @@ void dhcp_packet(time_t now, int pxe_fd)
ioctl(daemon->dhcpfd, SIOCSARP, &req);
}
#elif defined(HAVE_BSD_NETWORK)
else
else
{
send_via_bpf(mess, iov.iov_len, iface_addr, &ifr);
return;
}
#endif
#ifdef HAVE_SOLARIS_NETWORK
setsockopt(fd, IPPROTO_IP, IP_BOUND_IF, &iface_index, sizeof(iface_index));
#endif
while(retry_send(sendmsg(fd, &msg, 0)));
/* This can fail when, eg, iptables DROPS destination 255.255.255.255 */
@@ -493,11 +493,11 @@ static int check_listen_addrs(struct in_addr local, int if_index, char *label,
break;
}
}
return 1;
}
/* This is a complex routine: it gets called with each (address,netmask,broadcast) triple
/* This is a complex routine: it gets called with each (address,netmask,broadcast) triple
of each interface (and any relay address) and does the following things:
1) Discards stuff for interfaces other than the one on which a DHCP packet just arrived.
@@ -515,13 +515,13 @@ static int complete_context(struct in_addr local, int if_index, char *label,
struct iface_param *param = vparam;
(void)label;
for (context = daemon->dhcp; context; context = context->next)
{
if (!(context->flags & CONTEXT_NETMASK) &&
(is_same_net(local, context->start, netmask) ||
is_same_net(local, context->end, netmask)))
{
{
if (context->netmask.s_addr != netmask.s_addr &&
!(is_same_net(local, context->start, netmask) &&
is_same_net(local, context->end, netmask)))
@@ -530,10 +530,10 @@ static int complete_context(struct in_addr local, int if_index, char *label,
strcpy(daemon->dhcp_buff2, inet_ntoa(context->end));
my_syslog(MS_DHCP | LOG_WARNING, _("DHCP range %s -- %s is not consistent with netmask %s"),
daemon->dhcp_buff, daemon->dhcp_buff2, inet_ntoa(netmask));
}
}
context->netmask = netmask;
}
if (context->netmask.s_addr != 0 &&
is_same_net(local, context->start, context->netmask) &&
is_same_net(local, context->end, context->netmask))
@@ -546,15 +546,15 @@ static int complete_context(struct in_addr local, int if_index, char *label,
context->current = param->current;
param->current = context;
}
if (!(context->flags & CONTEXT_BRDCAST))
{
if (is_same_net(broadcast, context->start, context->netmask))
context->broadcast = broadcast;
else
else
context->broadcast.s_addr = context->start.s_addr | ~context->netmask.s_addr;
}
}
}
}
for (relay = daemon->relay4; relay; relay = relay->next)
@@ -563,27 +563,27 @@ static int complete_context(struct in_addr local, int if_index, char *label,
{
relay->current = param->relay;
param->relay = relay;
param->relay_local = local;
param->relay_local = local;
}
return 1;
}
struct dhcp_context *address_available(struct dhcp_context *context,
struct dhcp_context *address_available(struct dhcp_context *context,
struct in_addr taddr,
struct dhcp_netid *netids)
{
/* Check is an address is OK for this network, check all
possible ranges. Make sure that the address isn't in use
by the server itself. */
unsigned int start, end, addr = ntohl(taddr.s_addr);
struct dhcp_context *tmp;
for (tmp = context; tmp; tmp = tmp->current)
if (taddr.s_addr == context->router.s_addr)
return NULL;
for (tmp = context; tmp; tmp = tmp->current)
{
start = ntohl(tmp->start.s_addr);
@@ -599,7 +599,7 @@ struct dhcp_context *address_available(struct dhcp_context *context,
return NULL;
}
struct dhcp_context *narrow_context(struct dhcp_context *context,
struct dhcp_context *narrow_context(struct dhcp_context *context,
struct in_addr taddr,
struct dhcp_netid *netids)
{
@@ -608,19 +608,19 @@ struct dhcp_context *narrow_context(struct dhcp_context *context,
Here we have an address, and return the actual context corresponding to that
address. Note that none may fit, if the address came a dhcp-host and is outside
any dhcp-range. In that case we return a static range if possible, or failing that,
any context on the correct subnet. (If there's more than one, this is a dodgy
any context on the correct subnet. (If there's more than one, this is a dodgy
configuration: maybe there should be a warning.) */
struct dhcp_context *tmp;
if (!(tmp = address_available(context, taddr, netids)))
{
for (tmp = context; tmp; tmp = tmp->current)
if (match_netid(tmp->filter, netids, 1) &&
is_same_net(taddr, tmp->start, tmp->netmask) &&
is_same_net(taddr, tmp->start, tmp->netmask) &&
(tmp->flags & CONTEXT_STATIC))
break;
if (!tmp)
for (tmp = context; tmp; tmp = tmp->current)
if (match_netid(tmp->filter, netids, 1) &&
@@ -628,18 +628,18 @@ struct dhcp_context *narrow_context(struct dhcp_context *context,
!(tmp->flags & CONTEXT_PROXY))
break;
}
/* Only one context allowed now */
if (tmp)
tmp->current = NULL;
return tmp;
}
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;
@@ -662,18 +662,18 @@ struct ping_result *do_icmp_ping(time_t now, struct in_addr addr, unsigned int h
PING_CACHE_TIME seconds. If so, assume the same situation still exists.
This avoids problems when a stupid client bangs
on us repeatedly. As a final check, if we did more
than 60% of the possible ping checks in the last
than 60% of the possible ping checks in the last
PING_CACHE_TIME, we are in high-load mode, so don't do any more. */
for (count = 0, r = daemon->ping_results; r; r = r->next)
if (difftime(now, r->time) > (float)PING_CACHE_TIME)
victim = r; /* old record */
else
else
{
count++;
if (r->addr.s_addr == addr.s_addr)
return r;
}
/* didn't find cached entry */
if ((count >= max) || option_bool(OPT_NO_PING) || loopback)
{
@@ -694,8 +694,8 @@ struct ping_result *do_icmp_ping(time_t now, struct in_addr addr, unsigned int h
daemon->ping_results = victim;
}
}
/* record that this address is OK for 30s
/* record that this address is OK for 30s
without more ping checks */
if (victim)
{
@@ -708,8 +708,8 @@ struct ping_result *do_icmp_ping(time_t now, struct in_addr addr, unsigned int h
}
int address_allocate(struct dhcp_context *context,
struct in_addr *addrp, unsigned char *hwaddr, int hw_len,
struct dhcp_netid *netids, time_t now, int loopback)
struct in_addr *addrp, unsigned char *hwaddr, int hw_len,
struct dhcp_netid *netids, time_t now, int loopback)
{
/* Find a free address: exclude anything in use and anything allocated to
a particular hwaddr/clientid/hostname in our configuration.
@@ -718,17 +718,17 @@ int address_allocate(struct dhcp_context *context,
struct in_addr start, addr;
struct dhcp_context *c, *d;
int i, pass;
unsigned int j;
unsigned int j;
/* hash hwaddr: use the SDBM hashing algorithm. Seems to give good
dispersal even with similarly-valued "strings". */
dispersal even with similarly-valued "strings". */
for (j = 0, i = 0; i < hw_len; i++)
j = hwaddr[i] + (j << 6) + (j << 16) - j;
/* j == 0 is marker */
if (j == 0)
j = 1;
for (pass = 0; pass <= 1; pass++)
for (c = context; c; c = c->current)
if (c->flags & (CONTEXT_STATIC | CONTEXT_PROXY))
@@ -742,31 +742,31 @@ int address_allocate(struct dhcp_context *context,
start = lease_find_max_addr(c);
else
/* pick a seed based on hwaddr */
start.s_addr = htonl(ntohl(c->start.s_addr) +
start.s_addr = htonl(ntohl(c->start.s_addr) +
((j + c->addr_epoch) % (1 + ntohl(c->end.s_addr) - ntohl(c->start.s_addr))));
/* iterate until we find a free address. */
addr = start;
do {
/* eliminate addresses in use by the server. */
for (d = context; d; d = d->current)
if (addr.s_addr == d->router.s_addr)
break;
/* Addresses which end in .255 and .0 are broken in Windows even when using
/* Addresses which end in .255 and .0 are broken in Windows even when using
supernetting. ie dhcp-range=192.168.0.1,192.168.1.254,255,255,254.0
then 192.168.0.255 is a valid IP address, but not for Windows as it's
in the class C range. See KB281579. We therefore don't allocate these
addresses to avoid hard-to-diagnose problems. Thanks Bill. */
in the class C range. See KB281579. We therefore don't allocate these
addresses to avoid hard-to-diagnose problems. Thanks Bill. */
if (!d &&
!lease_find_by_addr(addr) &&
!lease_find_by_addr(addr) &&
!config_find_by_address(daemon->dhcp_conf, addr) &&
(!IN_CLASSC(ntohl(addr.s_addr)) ||
(!IN_CLASSC(ntohl(addr.s_addr)) ||
((ntohl(addr.s_addr) & 0xff) != 0xff && ((ntohl(addr.s_addr) & 0xff) != 0x0))))
{
struct ping_result *r;
if ((r = do_icmp_ping(now, addr, j, loopback)))
{
/* consec-ip mode: we offered this address for another client
@@ -785,12 +785,12 @@ int address_allocate(struct dhcp_context *context,
c->addr_epoch++;
}
}
addr.s_addr = htonl(ntohl(addr.s_addr) + 1);
if (addr.s_addr == htonl(ntohl(c->end.s_addr) + 1))
addr = c->start;
} while (addr.s_addr != start.s_addr);
}
@@ -810,7 +810,7 @@ void dhcp_read_ethers(void)
int count = 0, lineno = 0;
addr.s_addr = 0; /* eliminate warning */
if (!f)
{
my_syslog(MS_DHCP | LOG_ERR, _("failed to read %s: %s"), ETHERSFILE, strerror(errno));
@@ -837,54 +837,54 @@ void dhcp_read_ethers(void)
while (fgets(buff, MAXDNAME, f))
{
char *host = NULL;
lineno++;
while (strlen(buff) > 0 && isspace((int)buff[strlen(buff)-1]))
buff[strlen(buff)-1] = 0;
if ((*buff == '#') || (*buff == '+') || (*buff == 0))
continue;
for (ip = buff; *ip && !isspace((int)*ip); ip++);
for(; *ip && isspace((int)*ip); ip++)
*ip = 0;
if (!*ip || parse_hex(buff, hwaddr, ETHER_ADDR_LEN, NULL, NULL) != ETHER_ADDR_LEN)
{
my_syslog(MS_DHCP | LOG_ERR, _("bad line at %s line %d"), ETHERSFILE, lineno);
my_syslog(MS_DHCP | LOG_ERR, _("bad line at %s line %d"), ETHERSFILE, lineno);
continue;
}
/* check for name or dotted-quad */
for (cp = ip; *cp; cp++)
if (!(*cp == '.' || (*cp >='0' && *cp <= '9')))
break;
if (!*cp)
{
if ((addr.s_addr = inet_addr(ip)) == (in_addr_t)-1)
{
my_syslog(MS_DHCP | LOG_ERR, _("bad address at %s line %d"), ETHERSFILE, lineno);
my_syslog(MS_DHCP | LOG_ERR, _("bad address at %s line %d"), ETHERSFILE, lineno);
continue;
}
flags = CONFIG_ADDR;
for (config = daemon->dhcp_conf; config; config = config->next)
if ((config->flags & CONFIG_ADDR) && config->addr.s_addr == addr.s_addr)
break;
}
else
else
{
int nomem;
if (!(host = canonicalise(ip, &nomem)) || !legal_hostname(host))
{
if (!nomem)
my_syslog(MS_DHCP | LOG_ERR, _("bad name at %s line %d"), ETHERSFILE, lineno);
my_syslog(MS_DHCP | LOG_ERR, _("bad name at %s line %d"), ETHERSFILE, lineno);
free(host);
continue;
}
flags = CONFIG_NAME;
for (config = daemon->dhcp_conf; config; config = config->next)
@@ -894,24 +894,24 @@ void dhcp_read_ethers(void)
if (config && (config->flags & CONFIG_FROM_ETHERS))
{
my_syslog(MS_DHCP | LOG_ERR, _("ignoring %s line %d, duplicate name or IP address"), ETHERSFILE, lineno);
my_syslog(MS_DHCP | LOG_ERR, _("ignoring %s line %d, duplicate name or IP address"), ETHERSFILE, lineno);
continue;
}
if (!config)
{
{
for (config = daemon->dhcp_conf; config; config = config->next)
{
struct hwaddr_config *conf_addr = config->hwaddr;
if (conf_addr &&
conf_addr->next == NULL &&
if (conf_addr &&
conf_addr->next == NULL &&
conf_addr->wildcard_mask == 0 &&
conf_addr->hwaddr_len == ETHER_ADDR_LEN &&
(conf_addr->hwaddr_type == ARPHRD_ETHER || conf_addr->hwaddr_type == 0) &&
memcmp(conf_addr->hwaddr, hwaddr, ETHER_ADDR_LEN) == 0)
break;
}
if (!config)
{
if (!(config = whine_malloc(sizeof(struct dhcp_config))))
@@ -923,19 +923,19 @@ void dhcp_read_ethers(void)
config->next = daemon->dhcp_conf;
daemon->dhcp_conf = config;
}
config->flags |= flags;
if (flags & CONFIG_NAME)
{
config->hostname = host;
host = NULL;
}
if (flags & CONFIG_ADDR)
config->addr = addr;
}
config->flags |= CONFIG_NOCLID;
if (!config->hwaddr)
config->hwaddr = whine_malloc(sizeof(struct hwaddr_config));
@@ -948,11 +948,11 @@ void dhcp_read_ethers(void)
config->hwaddr->next = NULL;
}
count++;
free(host);
}
fclose(f);
my_syslog(MS_DHCP | LOG_INFO, _("read %s - %d addresses"), ETHERSFILE, count);
@@ -962,7 +962,7 @@ void dhcp_read_ethers(void)
/* If we've not found a hostname any other way, try and see if there's one in /etc/hosts
for this address. If it has a domain part, that must match the set domain and
it gets stripped. The set of legal domain names is bigger than the set of legal hostnames
so check here that the domain name is legal as a hostname.
so check here that the domain name is legal as a hostname.
NOTE: we're only allowed to overwrite daemon->dhcp_buff if we succeed. */
char *host_from_dns(struct in_addr addr)
{
@@ -970,14 +970,14 @@ char *host_from_dns(struct in_addr addr)
if (daemon->port == 0)
return NULL; /* DNS disabled. */
lookup = cache_find_by_addr(NULL, (struct all_addr *)&addr, 0, F_IPV4);
if (lookup && (lookup->flags & F_HOSTS))
{
char *dot, *hostname = cache_get_name(lookup);
dot = strchr(hostname, '.');
if (dot && strlen(dot+1) != 0)
{
char *d2 = get_domain(addr);
@@ -987,13 +987,13 @@ char *host_from_dns(struct in_addr addr)
if (!legal_hostname(hostname))
return NULL;
safe_strncpy(daemon->dhcp_buff, hostname, 256);
strip_hostname(daemon->dhcp_buff);
return daemon->dhcp_buff;
}
return NULL;
}
@@ -1001,13 +1001,13 @@ static int relay_upstream4(struct dhcp_relay *relay, struct dhcp_packet *mess,
{
/* ->local is same value for all relays on ->current chain */
struct all_addr from;
if (mess->op != BOOTREQUEST)
return 0;
/* source address == relay address */
from.addr.addr4 = relay->local.addr.addr4;
/* already gatewayed ? */
if (mess->giaddr.s_addr)
{
@@ -1027,23 +1027,23 @@ static int relay_upstream4(struct dhcp_relay *relay, struct dhcp_packet *mess,
for (; relay; relay = relay->current)
{
union mysockaddr to;
to.sa.sa_family = AF_INET;
to.in.sin_addr = relay->server.addr.addr4;
to.in.sin_port = htons(daemon->dhcp_server_port);
send_from(daemon->dhcpfd, 0, (char *)mess, sz, &to, &from, 0);
if (option_bool(OPT_LOG_OPTS))
{
inet_ntop(AF_INET, &relay->local, daemon->addrbuff, ADDRSTRLEN);
my_syslog(MS_DHCP | LOG_INFO, _("DHCP relay %s -> %s"), daemon->addrbuff, inet_ntoa(relay->server.addr.addr4));
}
/* Save this for replies */
relay->iface_index = iface_index;
}
return 1;
}
@@ -1063,8 +1063,8 @@ static struct dhcp_relay *relay_reply4(struct dhcp_packet *mess, char *arrival_i
return relay->iface_index != 0 ? relay : NULL;
}
}
return NULL;
}
return NULL;
}
#endif
+112 -112
View File
@@ -4,12 +4,12 @@
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991, or
(at your option) version 3 dated 29 June, 2007.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -29,9 +29,9 @@ struct iface_param {
static int complete_context6(struct in6_addr *local, int prefix,
int scope, int if_index, int flags,
int scope, int if_index, int flags,
unsigned int preferred, unsigned int valid, void *vparam);
static int make_duid1(int index, unsigned int type, char *mac, size_t maclen, void *parm);
static int make_duid1(int index, unsigned int type, char *mac, size_t maclen, void *parm);
void dhcp6_init(void)
{
@@ -50,11 +50,11 @@ void dhcp6_init(void)
!fix_fd(fd) ||
!set_ipv6pktinfo(fd))
die (_("cannot create DHCPv6 socket: %s"), NULL, EC_BADNET);
/* When bind-interfaces is set, there might be more than one dnsmasq
instance binding port 547. That's OK if they serve different networks.
Need to set REUSEADDR|REUSEPORT to make this possible.
Handle the case that REUSEPORT is defined, but the kernel doesn't
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))
{
@@ -65,14 +65,14 @@ void dhcp6_init(void)
errno == ENOPROTOOPT)
rc = 0;
#endif
if (rc != -1)
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);
}
memset(&saddr, 0, sizeof(saddr));
#ifdef HAVE_SOCKADDR_SA_LEN
saddr.sin6_len = sizeof(struct sockaddr_in6);
@@ -80,10 +80,10 @@ void dhcp6_init(void)
saddr.sin6_family = AF_INET6;
saddr.sin6_addr = in6addr_any;
saddr.sin6_port = htons(DHCPV6_SERVER_PORT);
if (bind(fd, (struct sockaddr *)&saddr, sizeof(struct sockaddr_in6)))
die(_("failed to bind DHCPv6 server socket: %s"), NULL, EC_BADNET);
daemon->dhcp6fd = fd;
}
@@ -100,7 +100,7 @@ void dhcp6_packet(time_t now)
char control6[CMSG_SPACE(sizeof(struct in6_pktinfo))];
} control_u;
struct sockaddr_in6 from;
ssize_t sz;
ssize_t sz;
struct ifreq ifr;
struct iname *tmp;
unsigned short port;
@@ -115,10 +115,10 @@ void dhcp6_packet(time_t now)
msg.msg_namelen = sizeof(from);
msg.msg_iov = &daemon->dhcp_packet;
msg.msg_iovlen = 1;
if ((sz = recv_dhcp_packet(daemon->dhcp6fd, &msg)) == -1)
return;
for (cmptr = CMSG_FIRSTHDR(&msg); cmptr; cmptr = CMSG_NXTHDR(&msg, cmptr))
if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == daemon->v6pktinfo)
{
@@ -127,7 +127,7 @@ void dhcp6_packet(time_t now)
struct in6_pktinfo *p;
} p;
p.c = CMSG_DATA(cmptr);
if_index = p.p->ipi6_ifindex;
dst_addr = p.p->ipi6_addr;
}
@@ -142,11 +142,11 @@ void dhcp6_packet(time_t now)
for (tmp = daemon->if_except; tmp; tmp = tmp->next)
if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
return;
for (tmp = daemon->dhcp_except; tmp; tmp = tmp->next)
if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
return;
parm.current = NULL;
parm.relay = NULL;
memset(&parm.relay_local, 0, IN6ADDRSZ);
@@ -179,7 +179,7 @@ void dhcp6_packet(time_t now)
if (alias)
break;
}
for (context = daemon->dhcp6; context; context = context->next)
if (IN6_IS_ADDR_UNSPECIFIED(&context->start6) && context->prefix == 0)
{
@@ -196,47 +196,47 @@ void dhcp6_packet(time_t now)
for (relay = daemon->relay6; relay; relay = relay->next)
relay->current = relay;
if (!iface_enumerate(AF_INET6, &parm, complete_context6))
return;
if (daemon->if_names || daemon->if_addrs)
{
for (tmp = daemon->if_names; tmp; tmp = tmp->next)
if (tmp->name && wildcard_match(tmp->name, ifr.ifr_name))
break;
if (!tmp && !parm.addr_match)
return;
}
if (parm.relay)
{
/* Ignore requests sent to the ALL_SERVERS multicast address for relay when
we're listening there for DHCPv6 server reasons. */
struct in6_addr all_servers;
inet_pton(AF_INET6, ALL_SERVERS, &all_servers);
if (!IN6_ARE_ADDR_EQUAL(&dst_addr, &all_servers))
relay_upstream6(parm.relay, sz, &from.sin6_addr, from.sin6_scope_id, now);
return;
}
/* May have configured relay, but not DHCP server */
if (!daemon->doing_dhcp6)
return;
lease_prune(NULL, now); /* lose any expired leases */
port = dhcp6_reply(parm.current, if_index, ifr.ifr_name, &parm.fallback,
port = dhcp6_reply(parm.current, if_index, ifr.ifr_name, &parm.fallback,
&parm.ll_addr, &parm.ula_addr, sz, &from.sin6_addr, now);
lease_update_file(now);
lease_update_dns(0);
}
/* The port in the source address of the original request should
be correct, but at least once client sends from the server port,
so we explicitly send to the client port to a client, and the
@@ -244,8 +244,8 @@ void dhcp6_packet(time_t now)
if (port != 0)
{
from.sin6_port = htons(port);
while (retry_send(sendto(daemon->dhcp6fd, daemon->outpacket.iov_base,
save_counter(0), 0, (struct sockaddr *)&from,
while (retry_send(sendto(daemon->dhcp6fd, daemon->outpacket.iov_base,
save_counter(0), 0, (struct sockaddr *)&from,
sizeof(from))));
}
}
@@ -253,9 +253,9 @@ void dhcp6_packet(time_t now)
void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac, unsigned int *maclenp, unsigned int *mactypep, time_t now)
{
/* Receiving a packet from a host does not populate the neighbour
cache, so we send a neighbour discovery request if we can't
cache, so we send a neighbour discovery request if we can't
find the sender. Repeat a few times in case of packet loss. */
struct neigh_packet neigh;
union mysockaddr addr;
int i, maclen;
@@ -266,7 +266,7 @@ void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac, unsi
neigh.target = *client;
/* RFC4443 section-2.3: checksum has to be zero to be calculated */
neigh.checksum = 0;
memset(&addr, 0, sizeof(addr));
#ifdef HAVE_SOCKADDR_SA_LEN
addr.in6.sin6_len = sizeof(struct sockaddr_in6);
@@ -275,16 +275,16 @@ void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac, unsi
addr.in6.sin6_port = htons(IPPROTO_ICMPV6);
addr.in6.sin6_addr = *client;
addr.in6.sin6_scope_id = iface;
for (i = 0; i < 5; i++)
{
struct timespec ts;
if ((maclen = find_mac(&addr, mac, 0, now)) != 0)
break;
sendto(daemon->icmp6fd, &neigh, sizeof(neigh), 0, &addr.sa, sizeof(addr));
ts.tv_sec = 0;
ts.tv_nsec = 100000000; /* 100ms */
nanosleep(&ts, NULL);
@@ -293,18 +293,18 @@ void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac, unsi
*maclenp = maclen;
*mactypep = ARPHRD_ETHER;
}
static int complete_context6(struct in6_addr *local, int prefix,
int scope, int if_index, int flags, unsigned int preferred,
int scope, int if_index, int flags, unsigned int preferred,
unsigned int valid, void *vparam)
{
struct dhcp_context *context;
struct dhcp_relay *relay;
struct iface_param *param = vparam;
struct iname *tmp;
(void)scope; /* warning */
if (if_index == param->ind)
{
if (IN6_IS_ADDR_LINKLOCAL(local))
@@ -316,19 +316,19 @@ static int complete_context6(struct in6_addr *local, int prefix,
!IN6_IS_ADDR_LINKLOCAL(local) &&
!IN6_IS_ADDR_MULTICAST(local))
{
/* if we have --listen-address config, see if the
/* if we have --listen-address config, see if the
arrival interface has a matching address. */
for (tmp = daemon->if_addrs; tmp; tmp = tmp->next)
if (tmp->addr.sa.sa_family == AF_INET6 &&
IN6_ARE_ADDR_EQUAL(&tmp->addr.in6.sin6_addr, local))
param->addr_match = 1;
/* 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. */
param->fallback = *local;
for (context = daemon->dhcp6; context; context = context->next)
{
if ((context->flags & CONTEXT_DHCP) &&
@@ -337,29 +337,29 @@ static int complete_context6(struct in6_addr *local, int prefix,
is_same_net6(local, &context->start6, context->prefix) &&
is_same_net6(local, &context->end6, context->prefix))
{
/* link it onto the current chain if we've not seen it before */
if (context->current == context)
{
struct dhcp_context *tmp, **up;
/* use interface values only for constructed contexts */
if (!(context->flags & CONTEXT_CONSTRUCTED))
preferred = valid = 0xffffffff;
else if (flags & IFACE_DEPRECATED)
preferred = 0;
if (context->flags & CONTEXT_DEPRECATE)
preferred = 0;
/* order chain, longest preferred time first */
for (up = &param->current, tmp = param->current; tmp; tmp = tmp->current)
if (tmp->preferred <= preferred)
break;
else
up = &tmp->current;
context->current = *up;
*up = context;
context->local6 = *local;
@@ -378,32 +378,32 @@ static int complete_context6(struct in6_addr *local, int prefix,
param->relay = relay;
param->relay_local = *local;
}
}
}
return 1;
}
struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct in6_addr *net, int prefix, u64 addr)
{
struct dhcp_config *config;
for (config = configs; config; config = config->next)
if ((config->flags & CONFIG_ADDR6) &&
is_same_net6(&config->addr6, net, prefix) &&
(prefix == 128 || addr6part(&config->addr6) == addr))
return config;
return NULL;
}
struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned char *clid, int clid_len, int temp_addr,
int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans)
int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans)
{
/* Find a free address: exclude anything in use and anything allocated to
a particular hwaddr/clientid/hostname in our configuration.
Try to return from contexts which match netids first.
Try to return from contexts which match netids first.
Note that we assume the address prefix lengths are 64 or greater, so we can
get by with 64 bit arithmetic.
*/
@@ -411,17 +411,17 @@ struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned c
u64 start, addr;
struct dhcp_context *c, *d;
int i, pass;
u64 j;
u64 j;
/* hash hwaddr: use the SDBM hashing algorithm. This works
for MAC addresses, let's see how it manages with client-ids!
for MAC addresses, let's see how it manages with client-ids!
For temporary addresses, we generate a new random one each time. */
if (temp_addr)
j = rand64();
else
for (j = iaid, i = 0; i < clid_len; i++)
j = clid[i] + (j << 6) + (j << 16) - j;
for (pass = 0; pass <= plain_range ? 1 : 0; pass++)
for (c = context; c; c = c->current)
if (c->flags & (CONTEXT_DEPRECATE | CONTEXT_STATIC | CONTEXT_RA_STATELESS | CONTEXT_USED))
@@ -429,7 +429,7 @@ struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned c
else if (!match_netid(c->filter, netids, pass))
continue;
else
{
{
if (!temp_addr && option_bool(OPT_CONSEC_ADDR))
/* seed is largest extant lease addr in this context */
start = lease_find_max_addr6(c) + serial;
@@ -447,7 +447,7 @@ struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned c
/* iterate until we find a free address. */
addr = start;
do {
/* eliminate addresses in use by the server. */
for (d = context; d; d = d->current)
@@ -455,34 +455,34 @@ struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned c
break;
if (!d &&
!lease6_find_by_addr(&c->start6, c->prefix, addr) &&
!lease6_find_by_addr(&c->start6, c->prefix, addr) &&
!config_find_by_address6(daemon->dhcp_conf, &c->start6, c->prefix, addr))
{
*ans = c->start6;
setaddr6part (ans, addr);
return c;
}
addr++;
if (addr == addr6part(&c->end6) + 1)
addr = addr6part(&c->start6);
} while (addr != start);
}
return NULL;
}
/* can dynamically allocate addr */
struct dhcp_context *address6_available(struct dhcp_context *context,
struct dhcp_context *address6_available(struct dhcp_context *context,
struct in6_addr *taddr,
struct dhcp_netid *netids,
int plain_range)
{
u64 start, end, addr = addr6part(taddr);
struct dhcp_context *tmp;
for (tmp = context; tmp; tmp = tmp->current)
{
start = addr6part(&tmp->start6);
@@ -501,13 +501,13 @@ struct dhcp_context *address6_available(struct dhcp_context *context,
}
/* address OK if configured */
struct dhcp_context *address6_valid(struct dhcp_context *context,
struct dhcp_context *address6_valid(struct dhcp_context *context,
struct in6_addr *taddr,
struct dhcp_netid *netids,
int plain_range)
{
struct dhcp_context *tmp;
for (tmp = context; tmp; tmp = tmp->current)
if (is_same_net6(&tmp->start6, taddr, tmp->prefix) &&
match_netid(tmp->filter, netids, plain_range))
@@ -527,13 +527,13 @@ int config_valid(struct dhcp_config *config, struct dhcp_context *context, struc
setaddr6part(addr, addr6part(&config->addr6));
return 1;
}
if (is_same_net6(&context->start6, &config->addr6, context->prefix))
{
*addr = config->addr6;
return 1;
}
return 0;
}
@@ -544,7 +544,7 @@ void make_duid(time_t now)
if (daemon->duid_config)
{
unsigned char *p;
daemon->duid = p = safe_malloc(daemon->duid_config_len + 6);
daemon->duid_len = daemon->duid_config_len + 6;
PUTSHORT(2, p); /* DUID_EN */
@@ -554,16 +554,16 @@ void make_duid(time_t now)
else
{
time_t newnow = 0;
/* If we have no persistent lease database, or a non-stable RTC, use DUID_LL (newnow == 0) */
#ifndef HAVE_BROKEN_RTC
/* rebase epoch to 1/1/2000 */
if (!option_bool(OPT_LEASE_RO) || daemon->lease_change_command)
newnow = now - 946684800;
#endif
#endif
iface_enumerate(AF_LOCAL, &newnow, make_duid1);
if(!daemon->duid)
die("Cannot create DHCPv6 server DUID: %s", NULL, EC_MISC);
}
@@ -573,14 +573,14 @@ static int make_duid1(int index, unsigned int type, char *mac, size_t maclen, vo
{
/* create DUID as specified in RFC3315. We use the MAC of the
first interface we find that isn't loopback or P-to-P and
has address-type < 256. Address types above 256 are things like
has address-type < 256. Address types above 256 are things like
tunnels which don't have usable MAC addresses. */
unsigned char *p;
(void)index;
(void)parm;
time_t newnow = *((time_t *)parm);
if (type >= 256)
return 1;
@@ -599,7 +599,7 @@ static int make_duid1(int index, unsigned int type, char *mac, size_t maclen, vo
PUTSHORT(type, p); /* address type */
PUTLONG(*((time_t *)parm), p); /* time */
}
memcpy(p, mac, maclen);
return 0;
@@ -610,8 +610,8 @@ struct cparam {
int newone, newname;
};
static int construct_worker(struct in6_addr *local, int prefix,
int scope, int if_index, int flags,
static int construct_worker(struct in6_addr *local, int prefix,
int scope, int if_index, int flags,
int preferred, int valid, void *vparam)
{
char ifrn_name[IFNAMSIZ];
@@ -638,7 +638,7 @@ static int construct_worker(struct in6_addr *local, int prefix,
if (!indextoname(daemon->icmp6fd, if_index, ifrn_name))
return 0;
for (template = daemon->dhcp6; template; template = template->next)
if (!(template->flags & (CONTEXT_TEMPLATE | CONTEXT_CONSTRUCTED)))
{
@@ -653,11 +653,11 @@ static int construct_worker(struct in6_addr *local, int prefix,
ra_start_unsolicited(param->now, template);
param->newone = 1;
}
template->if_index = if_index;
template->local6 = *local;
}
}
else if (wildcard_match(template->template_interface, ifrn_name) &&
template->prefix >= prefix)
@@ -666,7 +666,7 @@ static int construct_worker(struct in6_addr *local, int prefix,
setaddr6part(&start6, addr6part(&template->start6));
end6 = *local;
setaddr6part(&end6, addr6part(&template->end6));
for (context = daemon->dhcp6; context; context = context->next)
if (!(context->flags & CONTEXT_TEMPLATE) &&
IN6_ARE_ADDR_EQUAL(&start6, &context->start6) &&
@@ -676,7 +676,7 @@ static int construct_worker(struct in6_addr *local, int prefix,
then don't construct one as well. */
if (!(context->flags & CONTEXT_CONSTRUCTED))
break;
if (context->if_index == if_index)
{
int cflags = context->flags;
@@ -684,19 +684,19 @@ static int construct_worker(struct in6_addr *local, int prefix,
if (cflags & CONTEXT_OLD)
{
/* address went, now it's back, and on the same interface */
log_context(AF_INET6, context);
log_context(AF_INET6, context);
/* fast RAs for a while */
ra_start_unsolicited(param->now, context);
param->newone = 1;
param->newone = 1;
/* Add address to name again */
if (context->flags & CONTEXT_RA_NAME)
param->newname = 1;
}
break;
}
}
if (!context && (context = whine_malloc(sizeof (struct dhcp_context))))
{
*context = *template;
@@ -707,28 +707,28 @@ static int construct_worker(struct in6_addr *local, int prefix,
context->if_index = if_index;
context->local6 = *local;
context->saved_valid = 0;
context->next = daemon->dhcp6;
daemon->dhcp6 = context;
ra_start_unsolicited(param->now, context);
/* we created a new one, need to call
lease_update_file to get periodic functions called */
param->newone = 1;
param->newone = 1;
/* Will need to add new putative SLAAC addresses to existing leases */
if (context->flags & CONTEXT_RA_NAME)
param->newname = 1;
log_context(AF_INET6, context);
}
}
}
return 1;
}
void dhcp_construct_contexts(time_t now)
{
{
struct dhcp_context *context, *tmp, **up;
struct cparam param;
param.newone = 0;
@@ -738,14 +738,14 @@ void dhcp_construct_contexts(time_t now)
for (context = daemon->dhcp6; context; context = context->next)
if (context->flags & CONTEXT_CONSTRUCTED)
context->flags |= CONTEXT_GC;
iface_enumerate(AF_INET6, &param, construct_worker);
for (up = &daemon->dhcp6, context = daemon->dhcp6; context; context = tmp)
{
tmp = context->next;
tmp = context->next;
if (context->flags & CONTEXT_GC && !(context->flags & CONTEXT_OLD))
{
if ((context->flags & CONTEXT_RA) || option_bool(OPT_RA))
@@ -760,13 +760,13 @@ void dhcp_construct_contexts(time_t now)
if (context->saved_valid > 7200) /* 2 hours */
context->saved_valid = 7200;
ra_start_unsolicited(now, context);
param.newone = 1; /* include deletion */
param.newone = 1; /* include deletion */
if (context->flags & CONTEXT_RA_NAME)
param.newname = 1;
param.newname = 1;
log_context(AF_INET6, context);
up = &context->next;
}
else
@@ -779,7 +779,7 @@ void dhcp_construct_contexts(time_t now)
else
up = &context->next;
}
if (param.newone)
{
if (daemon->dhcp || daemon->doing_dhcp6)
@@ -788,7 +788,7 @@ void dhcp_construct_contexts(time_t now)
lease_update_slaac(now);
lease_update_file(now);
}
else
else
/* Not doing DHCP, so no lease system, manage alarms for ra only */
send_alarm(periodic_ra(now), now);
}
+257 -257
View File
File diff suppressed because it is too large Load Diff
+78 -78
View File
@@ -1,15 +1,15 @@
/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991, or
(at your option) version 3 dated 29 June, 2007.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -20,7 +20,7 @@
if included too early. */
#ifdef _STDIO_H
# error "Header file stdio.h included too early!"
#endif
#endif
#ifndef NO_LARGEFILE
/* Ensure we can use files >2GB (log files may grow this big) */
@@ -33,7 +33,7 @@
# ifndef __ANDROID__
# define _GNU_SOURCE
# endif
# include <features.h>
# include <features.h>
#endif
/* Need these defined early */
@@ -49,7 +49,7 @@
#endif
/* get these before config.h for IPv6 stuff... */
#include <sys/types.h>
#include <sys/types.h>
#include <sys/socket.h>
#ifdef __APPLE__
@@ -85,7 +85,7 @@ typedef unsigned long long u64;
# define _(S) (S)
#else
# include <libintl.h>
# include <locale.h>
# include <locale.h>
# define _(S) gettext(S)
#endif
@@ -142,7 +142,7 @@ typedef unsigned long long u64;
#if defined(HAVE_LINUX_NETWORK)
#include <linux/capability.h>
/* There doesn't seem to be a universally-available
/* There doesn't seem to be a universally-available
userspace header for these. */
extern int capset(cap_user_header_t header, cap_user_data_t data);
extern int capget(cap_user_header_t header, cap_user_data_t data);
@@ -231,7 +231,7 @@ struct event_desc {
#define OPT_LEASE_RO 22
#define OPT_ALL_SERVERS 23
#define OPT_RELOAD 24
#define OPT_LOCAL_REBIND 25
#define OPT_LOCAL_REBIND 25
#define OPT_TFTP_SECURE 26
#define OPT_TFTP_NOBLOCK 27
#define OPT_LOG_OPTS 28
@@ -254,7 +254,7 @@ struct event_desc {
#define OPT_DNSSEC_VALID 45
#define OPT_DNSSEC_TIME 46
#define OPT_DNSSEC_DEBUG 47
#define OPT_DNSSEC_IGN_NS 48
#define OPT_DNSSEC_IGN_NS 48
#define OPT_LOCAL_SERVICE 49
#define OPT_LOOP_DETECT 50
#define OPT_EXTRALOG 51
@@ -267,7 +267,7 @@ struct event_desc {
#define OPT_UBUS 58
#define OPT_LAST 59
/* extra flags for my_syslog, we use a couple of facilities since they are known
/* extra flags for my_syslog, we use a couple of facilities since they are known
not to occupy the same bits as priorities, no matter how syslog.h is set up. */
#define MS_TFTP LOG_USER
#define MS_DHCP LOG_DAEMON
@@ -290,7 +290,7 @@ struct all_addr {
/* for cache_insert of DNSKEY, DS */
struct {
unsigned short class, type;
} dnssec;
} dnssec;
} addr;
};
@@ -348,7 +348,7 @@ struct cname {
int ttl, flag;
char *alias, *target;
struct cname *next, *targetp;
};
};
struct ds_config {
char *name, *digest;
@@ -362,7 +362,7 @@ struct ds_config {
struct addrlist {
struct all_addr addr;
int flags, prefixlen;
int flags, prefixlen;
struct addrlist *next;
};
@@ -413,7 +413,7 @@ struct blockdata {
unsigned char key[KEYBLOCK_LEN];
};
struct crec {
struct crec {
struct crec *next, *prev, *hash_next;
/* union is 16 bytes when doing IPv6, 8 bytes on 32 bit machines without IPv6 */
union {
@@ -429,17 +429,17 @@ struct crec {
struct blockdata *keydata;
unsigned short keylen, flags, keytag;
unsigned char algo;
} key;
} key;
struct {
struct blockdata *keydata;
unsigned short keylen, keytag;
unsigned char algo;
unsigned char digest;
} ds;
unsigned char digest;
} ds;
} addr;
time_t ttd; /* time to die */
/* used as class if DNSKEY/DS, index to source for F_HOSTS */
unsigned int uid;
unsigned int uid;
unsigned short flags;
union {
char sname[SMALLDNAME];
@@ -456,7 +456,7 @@ struct crec {
#define F_REVERSE (1u<<2)
#define F_FORWARD (1u<<3)
#define F_DHCP (1u<<4)
#define F_NEG (1u<<5)
#define F_NEG (1u<<5)
#define F_HOSTS (1u<<6)
#define F_IPV4 (1u<<7)
#define F_IPV6 (1u<<8)
@@ -526,7 +526,7 @@ union mysockaddr {
#define SERV_FROM_RESOLV 1 /* 1 for servers from resolv, 0 for command line. */
#define SERV_NO_ADDR 2 /* no server, this domain is local only */
#define SERV_LITERAL_ADDRESS 4 /* addr is the answer, not the server */
#define SERV_LITERAL_ADDRESS 4 /* addr is the answer, not the server */
#define SERV_HAS_DOMAIN 8 /* server for one domain only */
#define SERV_HAS_SOURCE 16 /* source address defined */
#define SERV_FOR_NODOTS 32 /* server for names with no domain part only */
@@ -554,19 +554,19 @@ struct randfd {
int fd;
unsigned short refcount, family;
};
struct server {
union mysockaddr addr, source_addr;
char interface[IF_NAMESIZE+1];
struct serverfd *sfd;
char *domain; /* set if this server only handles a domain. */
struct serverfd *sfd;
char *domain; /* set if this server only handles a domain. */
int flags, tcpfd, edns_pktsz;
time_t pktsz_reduced;
unsigned int queries, failed_queries;
#ifdef HAVE_LOOP
u32 uid;
#endif
struct server *next;
struct server *next;
};
struct ipsets {
@@ -579,7 +579,7 @@ struct irec {
union mysockaddr addr;
struct in_addr netmask; /* only valid for IPv4 */
int tftp_ok, dhcp_ok, mtu, done, warned, dad, dns_auth, index, multicast_done, found, label;
char *name;
char *name;
struct irec *next;
};
@@ -664,7 +664,7 @@ struct hostsfile {
#define FREC_DO_QUESTION 64
#define FREC_ADDED_PHEADER 128
#define FREC_TEST_PKTSZ 256
#define FREC_HAS_EXTRADATA 512
#define FREC_HAS_EXTRADATA 512
#ifdef HAVE_DNSSEC
#define HASH_SIZE 20 /* SHA-1 digest size */
@@ -685,7 +685,7 @@ struct frec {
int log_id, fd, forwardall, flags;
time_t time;
unsigned char *hash[HASH_SIZE];
#ifdef HAVE_DNSSEC
#ifdef HAVE_DNSSEC
int class, work_counter;
struct blockdata *stash; /* Saved reply, whilst we validate */
size_t stash_len;
@@ -701,7 +701,7 @@ struct frec {
#define OT_INTERNAL 0x2000
#define OT_NAME 0x1000
#define OT_CSTRING 0x0800
#define OT_DEC 0x0400
#define OT_DEC 0x0400
#define OT_TIME 0x0200
/* actions in the daemon->helper RPC */
@@ -733,7 +733,7 @@ struct dhcp_lease {
unsigned int length;
#endif
int hwaddr_len, hwaddr_type;
unsigned char hwaddr[DHCP_CHADDR_MAX];
unsigned char hwaddr[DHCP_CHADDR_MAX];
struct in_addr addr, override, giaddr;
unsigned char *extradata;
unsigned int extradata_len, extradata_size;
@@ -799,7 +799,7 @@ struct dhcp_config {
struct dhcp_config *next;
};
#define have_config(config, mask) ((config) && ((config)->flags & (mask)))
#define have_config(config, mask) ((config) && ((config)->flags & (mask)))
#define CONFIG_DISABLE 1
#define CONFIG_CLID 2
@@ -856,7 +856,7 @@ struct dhcp_match_name {
};
struct pxe_service {
unsigned short CSA, type;
unsigned short CSA, type;
char *menu, *basename, *sname;
struct in_addr server;
struct dhcp_netid *netid;
@@ -899,9 +899,9 @@ struct cond_domain {
#endif
int is6, indexed;
struct cond_domain *next;
};
};
#ifdef OPTION6_PREFIX_CLASS
#ifdef OPTION6_PREFIX_CLASS
struct prefix_class {
int class;
struct dhcp_netid tag;
@@ -1001,7 +1001,7 @@ struct dhcp_relay {
};
extern struct daemon {
/* datastuctures representing the command-line and
/* datastuctures representing the command-line and
config file arguments. All set (including defaults)
in option.c */
@@ -1029,7 +1029,7 @@ extern struct daemon {
int group_set, osport;
char *domain_suffix;
struct cond_domain *cond_domain, *synth_domains;
char *runfile;
char *runfile;
char *lease_change_command;
struct iname *if_names, *if_addrs, *if_except, *dhcp_except, *auth_peers, *tftp_interfaces;
struct bogus_addr *bogus_addr, *ignore_addr;
@@ -1052,23 +1052,23 @@ extern struct daemon {
struct dhcp_mac *dhcp_macs;
struct dhcp_boot *boot_config;
struct pxe_service *pxe_services;
struct tag_if *tag_if;
struct tag_if *tag_if;
struct addr_list *override_relays;
struct dhcp_relay *relay4, *relay6;
struct delay_config *delay_conf;
int override;
int enable_pxe;
int doing_ra, doing_dhcp6;
struct dhcp_netid_list *dhcp_ignore, *dhcp_ignore_names, *dhcp_gen_names;
struct dhcp_netid_list *dhcp_ignore, *dhcp_ignore_names, *dhcp_gen_names;
struct dhcp_netid_list *force_broadcast, *bootp_dynamic;
struct hostsfile *dhcp_hosts_file, *dhcp_opts_file, *dynamic_dirs;
int dhcp_max, tftp_max, tftp_mtu;
int dhcp_server_port, dhcp_client_port;
int start_tftp_port, end_tftp_port;
int start_tftp_port, end_tftp_port;
unsigned int min_leasetime;
struct doctor *doctors;
unsigned short edns_pktsz;
char *tftp_prefix;
char *tftp_prefix;
struct tftp_prefix *if_prefix; /* per-interface TFTP prefixes */
unsigned int duid_enterprise, duid_config_len;
unsigned char *duid_config;
@@ -1077,7 +1077,7 @@ extern struct daemon {
int dump_mask;
unsigned long soa_sn, soa_refresh, soa_retry, soa_expiry;
u32 metrics[__METRIC_MAX];
#ifdef OPTION6_PREFIX_CLASS
#ifdef OPTION6_PREFIX_CLASS
struct prefix_class *prefix_classes;
#endif
#ifdef HAVE_DNSSEC
@@ -1109,13 +1109,13 @@ extern struct daemon {
struct randfd *rfd_save; /* " " */
pid_t tcp_pids[MAX_PROCS];
struct randfd randomsocks[RANDOM_SOCKS];
int v6pktinfo;
int v6pktinfo;
struct addrlist *interface_addrs; /* list of all addresses/prefix lengths associated with all local interfaces */
int log_id, log_display_id; /* ids of transactions for logging */
union mysockaddr *log_source_addr;
/* DHCP state */
int dhcpfd, helperfd, pxefd;
int dhcpfd, helperfd, pxefd;
#ifdef HAVE_INOTIFY
int inotifyfd;
#endif
@@ -1158,14 +1158,14 @@ extern struct daemon {
/* cache.c */
void cache_init(void);
void next_uid(struct crec *crecp);
void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg);
void log_query(unsigned int flags, char *name, struct all_addr *addr, char *arg);
char *record_source(unsigned int index);
char *querystr(char *desc, unsigned short type);
int cache_find_non_terminal(char *name, time_t now);
struct crec *cache_find_by_addr(struct crec *crecp,
struct all_addr *addr, time_t now,
struct all_addr *addr, time_t now,
unsigned int prot);
struct crec *cache_find_by_name(struct crec *crecp,
struct crec *cache_find_by_name(struct crec *crecp,
char *name, time_t now, unsigned int prot);
void cache_end_insert(void);
void cache_start_insert(void);
@@ -1182,7 +1182,7 @@ int cache_make_stat(struct txt_record *t);
char *cache_get_name(struct crec *crecp);
char *cache_get_cname_target(struct crec *crecp);
struct crec *cache_enumerate(int init);
int read_hostsfile(char *filename, unsigned int index, int cache_size,
int read_hostsfile(char *filename, unsigned int index, int cache_size,
struct crec **rhash, int hashsz);
/* blockdata.c */
@@ -1203,12 +1203,12 @@ int is_name_synthetic(int flags, char *name, struct all_addr *addr);
int is_rev_synth(int flag, struct all_addr *addr, char *name);
/* rfc1035.c */
int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
int extract_name(struct dns_header *header, size_t plen, unsigned char **pp,
char *name, int isExtract, int extrabytes);
unsigned char *skip_name(unsigned char *ansp, struct dns_header *header, size_t plen, int extrabytes);
unsigned char *skip_questions(struct dns_header *header, size_t plen);
unsigned char *skip_section(unsigned char *ansp, int count, struct dns_header *header, size_t plen);
unsigned int extract_request(struct dns_header *header, size_t qlen,
unsigned int extract_request(struct dns_header *header, size_t qlen,
char *name, unsigned short *typep);
size_t setup_reply(struct dns_header *header, size_t qlen,
struct all_addr *addrp, unsigned int flags,
@@ -1216,25 +1216,25 @@ size_t setup_reply(struct dns_header *header, size_t qlen,
int extract_addresses(struct dns_header *header, size_t qlen, char *name,
time_t now, char **ipsets, int is_sign, int check_rebind,
int no_cache_dnssec, int secure, int *doctored);
size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
struct in_addr local_addr, struct in_addr local_netmask,
size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
struct in_addr local_addr, struct in_addr local_netmask,
time_t now, int ad_reqd, int do_bit, int have_pseudoheader);
int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
struct bogus_addr *baddr, time_t now);
int check_for_ignored_address(struct dns_header *header, size_t qlen, struct bogus_addr *baddr);
int check_for_local_domain(char *name, time_t now);
unsigned int questions_crc(struct dns_header *header, size_t plen, char *name);
size_t resize_packet(struct dns_header *header, size_t plen,
size_t resize_packet(struct dns_header *header, size_t plen,
unsigned char *pheader, size_t hlen);
int add_resource_record(struct dns_header *header, char *limit, int *truncp,
int nameoffset, unsigned char **pp, unsigned long ttl,
int nameoffset, unsigned char **pp, unsigned long ttl,
int *offset, unsigned short type, unsigned short class, char *format, ...);
int in_arpa_name_2_addr(char *namein, struct all_addr *addrp);
int private_net(struct in_addr addr, int ban_localhost);
/* auth.c */
#ifdef HAVE_AUTH
size_t answer_auth(struct dns_header *header, char *limit, size_t qlen,
size_t answer_auth(struct dns_header *header, char *limit, size_t qlen,
time_t now, union mysockaddr *peer_addr, int local_query,
int do_bit, int have_pseudoheader);
int in_zone(struct auth_zone *zone, char *name, char **cut);
@@ -1287,9 +1287,9 @@ void setaddr6part(struct in6_addr *addr, u64 host);
int retry_send(ssize_t rc);
void prettyprint_time(char *buf, unsigned int t);
int prettyprint_addr(union mysockaddr *addr, char *buf);
int parse_hex(char *in, unsigned char *out, int maxlen,
int parse_hex(char *in, unsigned char *out, int maxlen,
unsigned int *wildcard_mask, int *mac_type);
int memcmp_masked(unsigned char *a, unsigned char *b, int len,
int memcmp_masked(unsigned char *a, unsigned char *b, int len,
unsigned int mask);
int expand_buf(struct iovec *iov, size_t size);
char *print_mac(char *buff, unsigned char *mac, int len);
@@ -1311,14 +1311,14 @@ void flush_log(void);
/* option.c */
void read_opts (int argc, char **argv, char *compile_opts);
char *option_string(int prot, unsigned int opt, unsigned char *val,
char *option_string(int prot, unsigned int opt, unsigned char *val,
int opt_len, char *buf, int buf_len);
void reread_dhcp(void);
void read_servers_file(void);
void set_option_bool(unsigned int opt);
void reset_option_bool(unsigned int opt);
struct hostsfile *expand_filelist(struct hostsfile *list);
char *parse_server(char *arg, union mysockaddr *addr,
char *parse_server(char *arg, union mysockaddr *addr,
union mysockaddr *source_addr, char *interface, int *flags);
int option_read_dynfile(char *file, int flags);
@@ -1329,7 +1329,7 @@ unsigned char *tcp_request(int confd, time_t now,
union mysockaddr *local_addr, struct in_addr netmask, int auth_dns);
void server_gone(struct server *server);
struct frec *get_new_frec(time_t now, int *wait, int force);
int send_from(int fd, int nowild, char *packet, size_t len,
int send_from(int fd, int nowild, char *packet, size_t len,
union mysockaddr *to, struct all_addr *source,
unsigned int iface);
void resend_query(void);
@@ -1377,10 +1377,10 @@ void newaddress(time_t now);
#ifdef HAVE_DHCP
void dhcp_init(void);
void dhcp_packet(time_t now, int pxe_fd);
struct dhcp_context *address_available(struct dhcp_context *context,
struct dhcp_context *address_available(struct dhcp_context *context,
struct in_addr taddr,
struct dhcp_netid *netids);
struct dhcp_context *narrow_context(struct dhcp_context *context,
struct dhcp_context *narrow_context(struct dhcp_context *context,
struct in_addr taddr,
struct dhcp_netid *netids);
struct ping_result *do_icmp_ping(time_t now, struct in_addr addr,
@@ -1401,7 +1401,7 @@ void lease_init(time_t now);
struct dhcp_lease *lease4_allocate(struct in_addr addr);
#ifdef HAVE_DHCP6
struct dhcp_lease *lease6_allocate(struct in6_addr *addrp, int lease_type);
struct dhcp_lease *lease6_find(unsigned char *clid, int clid_len,
struct dhcp_lease *lease6_find(unsigned char *clid, int clid_len,
int lease_type, int iaid, struct in6_addr *addr);
void lease6_reset(void);
struct dhcp_lease *lease6_find_by_client(struct dhcp_lease *first, int lease_type, unsigned char *clid, int clid_len, int iaid);
@@ -1418,7 +1418,7 @@ void lease_set_hwaddr(struct dhcp_lease *lease, const unsigned char *hwaddr,
void lease_set_hostname(struct dhcp_lease *lease, const char *name, int auth, char *domain, char *config_domain);
void lease_set_expires(struct dhcp_lease *lease, unsigned int len, time_t now);
void lease_set_interface(struct dhcp_lease *lease, int interface, time_t now);
struct dhcp_lease *lease_find_by_client(unsigned char *hwaddr, int hw_len, int hw_type,
struct dhcp_lease *lease_find_by_client(unsigned char *hwaddr, int hw_len, int hw_type,
unsigned char *clid, int clid_len);
struct dhcp_lease *lease_find_by_addr(struct in_addr addr);
struct in_addr lease_find_max_addr(struct dhcp_context *context);
@@ -1428,7 +1428,7 @@ int do_script_run(time_t now);
void rerun_scripts(void);
void lease_find_interfaces(time_t now);
#ifdef HAVE_SCRIPT
void lease_add_extradata(struct dhcp_lease *lease, unsigned char *data,
void lease_add_extradata(struct dhcp_lease *lease, unsigned char *data,
unsigned int len, int delim);
#endif
#endif
@@ -1438,7 +1438,7 @@ void lease_add_extradata(struct dhcp_lease *lease, unsigned char *data,
size_t dhcp_reply(struct dhcp_context *context, char *iface_name, int int_index,
size_t sz, time_t now, int unicast_dest, int loopback,
int *is_inform, int pxe, struct in_addr fallback, time_t recvtime);
unsigned char *extended_hwaddr(int hwtype, int hwlen, unsigned char *hwaddr,
unsigned char *extended_hwaddr(int hwtype, int hwlen, unsigned char *hwaddr,
int clid_len, unsigned char *clid, int *len_out);
#endif
@@ -1509,7 +1509,7 @@ int add_to_ipset(const char *setname, const struct all_addr *ipaddr, int flags,
#if defined(HAVE_SCRIPT)
int create_helper(int event_fd, int err_fd, uid_t uid, gid_t gid, long max_fd);
void helper_write(void);
void queue_script(int action, struct dhcp_lease *lease,
void queue_script(int action, struct dhcp_lease *lease,
char *hostname, time_t now);
#ifdef HAVE_TFTP
void queue_tftp(off_t file_len, char *filename, union mysockaddr *peer);
@@ -1539,28 +1539,28 @@ void dhcp6_packet(time_t now);
struct dhcp_context *address6_allocate(struct dhcp_context *context, unsigned char *clid, int clid_len, int temp_addr,
int iaid, int serial, struct dhcp_netid *netids, int plain_range, struct in6_addr *ans);
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 dhcp_context *address6_available(struct dhcp_context *context,
struct in6_addr *taddr,
struct dhcp_netid *netids,
int plain_range);
struct dhcp_context *address6_valid(struct dhcp_context *context,
struct dhcp_context *address6_valid(struct dhcp_context *context,
struct in6_addr *taddr,
struct dhcp_netid *netids,
int plain_range);
struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct in6_addr *net,
struct dhcp_config *config_find_by_address6(struct dhcp_config *configs, struct in6_addr *net,
int prefix, u64 addr);
void make_duid(time_t now);
void dhcp_construct_contexts(time_t now);
void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac,
void get_client_mac(struct in6_addr *client, int iface, unsigned char *mac,
unsigned int *maclenp, unsigned int *mactypep, time_t now);
#endif
/* rfc3315.c */
#ifdef HAVE_DHCP6
unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name,
unsigned short dhcp6_reply(struct dhcp_context *context, int interface, char *iface_name,
struct in6_addr *fallback, struct in6_addr *ll_addr, struct in6_addr *ula_addr,
size_t sz, struct in6_addr *client_addr, time_t now);
void relay_upstream6(struct dhcp_relay *relay, ssize_t sz, struct in6_addr *peer_address,
void relay_upstream6(struct dhcp_relay *relay, ssize_t sz, struct in6_addr *peer_address,
u32 scope_id, time_t now);
unsigned short relay_reply6( struct sockaddr_in6 *peer, ssize_t sz, char *arrival_interface);
@@ -1584,7 +1584,7 @@ int lookup_dhcp_len(int prot, int val);
struct dhcp_config *find_config(struct dhcp_config *configs,
struct dhcp_context *context,
unsigned char *clid, int clid_len,
unsigned char *hwaddr, int hw_len,
unsigned char *hwaddr, int hw_len,
int hw_type, char *hostname);
int config_has_mac(struct dhcp_config *config, unsigned char *hwaddr, int len, int type);
#ifdef HAVE_LINUX_NETWORK
@@ -1620,7 +1620,7 @@ time_t periodic_ra(time_t now);
void ra_start_unsolicited(time_t now, struct dhcp_context *context);
#endif
/* slaac.c */
/* slaac.c */
#ifdef HAVE_DHCP6
void slaac_add_addrs(struct dhcp_lease *lease, time_t now, int force);
time_t periodic_slaac(time_t now, struct dhcp_lease *leases);
@@ -1654,10 +1654,10 @@ int expand_workspace(unsigned char ***wkspc, int *szp, int new);
/* edns0.c */
unsigned char *find_pseudoheader(struct dns_header *header, size_t plen,
size_t *len, unsigned char **p, int *is_sign, int *is_last);
size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *limit,
size_t add_pseudoheader(struct dns_header *header, size_t plen, unsigned char *limit,
unsigned short udp_sz, int optno, unsigned char *opt, size_t optlen, int set_do, int replace);
size_t add_do_bit(struct dns_header *header, size_t plen, unsigned char *limit);
size_t add_edns0_config(struct dns_header *header, size_t plen, unsigned char *limit,
size_t add_edns0_config(struct dns_header *header, size_t plen, unsigned char *limit,
union mysockaddr *source, time_t now, int *check_subnet);
int check_source(struct dns_header *header, size_t plen, unsigned char *pseudoheader, union mysockaddr *peer);
+342 -342
View File
File diff suppressed because it is too large Load Diff
+28 -28
View File
@@ -52,7 +52,7 @@ int is_name_synthetic(int flags, char *name, struct all_addr *addr)
if (c1 != c2)
break;
}
if (pref && *pref != 0)
continue; /* prefix match fail */
@@ -61,16 +61,16 @@ int is_name_synthetic(int flags, char *name, struct all_addr *addr)
for (p = tail; *p; p++)
{
char c = *p;
if (c < '0' || c > '9')
break;
}
if (*p != '.')
continue;
*p = 0;
if (hostname_isequal(c->domain, p+1))
{
if (prot == AF_INET)
@@ -84,11 +84,11 @@ int is_name_synthetic(int flags, char *name, struct all_addr *addr)
found = 1;
}
}
#ifdef HAVE_IPV6
#ifdef HAVE_IPV6
else
{
u64 index = atoll(tail);
if (c->is6 &&
index <= addr6part(&c->end6) - addr6part(&c->start6))
{
@@ -107,23 +107,23 @@ int is_name_synthetic(int flags, char *name, struct all_addr *addr)
for (p = tail; *p; p++)
{
char c = *p;
if ((c >='0' && c <= '9') || c == '-')
continue;
#ifdef HAVE_IPV6
if (prot == AF_INET6 && ((c >='A' && c <= 'F') || (c >='a' && c <= 'f')))
if (prot == AF_INET6 && ((c >='A' && c <= 'F') || (c >='a' && c <= 'f')))
continue;
#endif
break;
}
if (*p != '.')
continue;
*p = 0;
*p = 0;
#ifdef HAVE_IPV6
if (prot == AF_INET6 && strstr(tail, "--ffff-") == tail)
{
@@ -148,7 +148,7 @@ int is_name_synthetic(int flags, char *name, struct all_addr *addr)
#endif
}
}
if (hostname_isequal(c->domain, p+1) && inet_pton(prot, tail, addr))
{
if (prot == AF_INET)
@@ -162,7 +162,7 @@ int is_name_synthetic(int flags, char *name, struct all_addr *addr)
else
{
u64 addrpart = addr6part(&addr->addr.addr6);
if (c->is6 &&
is_same_net6(&addr->addr.addr6, &c->start6, 64) &&
addrpart >= addr6part(&c->start6) &&
@@ -178,10 +178,10 @@ int is_name_synthetic(int flags, char *name, struct all_addr *addr)
for (p = tail; *p; p++)
if (*p == '.' || *p == ':')
*p = '-';
*p = '.';
if (found)
return 1;
}
@@ -197,7 +197,7 @@ int is_rev_synth(int flag, struct all_addr *addr, char *name)
if (flag & F_IPV4 && (c = search_domain(addr->addr.addr4, daemon->synth_domains)))
{
char *p;
*name = 0;
if (c->indexed)
{
@@ -208,13 +208,13 @@ int is_rev_synth(int flag, struct all_addr *addr, char *name)
{
if (c->prefix)
strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
inet_ntop(AF_INET, &addr->addr.addr4, name + strlen(name), ADDRSTRLEN);
inet_ntop(AF_INET, &addr->addr.addr4, name + strlen(name), ADDRSTRLEN);
for (p = name; *p; p++)
if (*p == '.')
*p = '-';
}
strncat(name, ".", MAXDNAME);
strncat(name, c->domain, MAXDNAME);
@@ -225,7 +225,7 @@ int is_rev_synth(int flag, struct all_addr *addr, char *name)
if (flag & F_IPV6 && (c = search_domain6(&addr->addr.addr6, daemon->synth_domains)))
{
char *p;
*name = 0;
if (c->indexed)
{
@@ -236,7 +236,7 @@ int is_rev_synth(int flag, struct all_addr *addr, char *name)
{
if (c->prefix)
strncpy(name, c->prefix, MAXDNAME - ADDRSTRLEN);
inet_ntop(AF_INET6, &addr->addr.addr6, name + strlen(name), ADDRSTRLEN);
/* IPv6 presentation address can start with ":", but valid domain names
@@ -246,12 +246,12 @@ int is_rev_synth(int flag, struct all_addr *addr, char *name)
*name = '0';
inet_ntop(AF_INET6, &addr->addr.addr6, name+1, ADDRSTRLEN);
}
/* V4-mapped have periods.... */
for (p = name; *p; p++)
if (*p == ':' || *p == '.')
*p = '-';
}
strncat(name, ".", MAXDNAME);
+16 -16
View File
@@ -4,12 +4,12 @@
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991, or
(at your option) version 3 dated 29 June, 2007.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -46,7 +46,7 @@ void dump_init(void)
struct pcaprec_hdr_s pcap_header;
packet_count = 0;
if (stat(daemon->dump_file, &buf) == -1)
{
/* doesn't exist, create and add header */
@@ -98,10 +98,10 @@ void dump_packet(int mask, void *packet, size_t len, union mysockaddr *src, unio
void *iphdr;
size_t ipsz;
int rc;
if (daemon->dumpfd == -1 || !(mask & daemon->dump_mask))
return;
/* So wireshark can Id the packet. */
udp.uh_sport = udp.uh_dport = htons(NAMESERVER_PORT);
@@ -116,7 +116,7 @@ void dump_packet(int mask, void *packet, size_t len, union mysockaddr *src, unio
iphdr = &ip6;
ipsz = sizeof(ip6);
memset(&ip6, 0, sizeof(ip6));
ip6.ip6_vfc = 6 << 4;
ip6.ip6_plen = htons(sizeof(struct udphdr) + len);
ip6.ip6_nxt = IPPROTO_UDP;
@@ -127,13 +127,13 @@ void dump_packet(int mask, void *packet, size_t len, union mysockaddr *src, unio
memcpy(&ip6.ip6_src, &src->in6.sin6_addr, IN6ADDRSZ);
udp.uh_sport = src->in6.sin6_port;
}
if (dst)
{
memcpy(&ip6.ip6_dst, &dst->in6.sin6_addr, IN6ADDRSZ);
udp.uh_dport = dst->in6.sin6_port;
}
/* start UDP checksum */
for (sum = 0, i = 0; i < IN6ADDRSZ; i++)
sum += ((u16 *)&ip6.ip6_src)[i];
@@ -144,13 +144,13 @@ void dump_packet(int mask, void *packet, size_t len, union mysockaddr *src, unio
iphdr = &ip;
ipsz = sizeof(ip);
memset(&ip, 0, sizeof(ip));
ip.ip_v = IPVERSION;
ip.ip_hl = sizeof(struct ip) / 4;
ip.ip_len = htons(sizeof(struct ip) + sizeof(struct udphdr) + len);
ip.ip_len = htons(sizeof(struct ip) + sizeof(struct udphdr) + len);
ip.ip_ttl = IPDEFTTL;
ip.ip_p = IPPROTO_UDP;
if (src)
{
ip.ip_src = src->in.sin_addr;
@@ -162,21 +162,21 @@ void dump_packet(int mask, void *packet, size_t len, union mysockaddr *src, unio
ip.ip_dst = dst->in.sin_addr;
udp.uh_dport = dst->in.sin_port;
}
ip.ip_sum = 0;
for (sum = 0, i = 0; i < sizeof(struct ip) / 2; i++)
sum += ((u16 *)&ip)[i];
while (sum >> 16)
sum = (sum & 0xffff) + (sum >> 16);
sum = (sum & 0xffff) + (sum >> 16);
ip.ip_sum = (sum == 0xffff) ? sum : ~sum;
/* start UDP checksum */
sum = ip.ip_src.s_addr & 0xffff;
sum += (ip.ip_src.s_addr >> 16) & 0xffff;
sum += ip.ip_dst.s_addr & 0xffff;
sum += (ip.ip_dst.s_addr >> 16) & 0xffff;
}
if (len & 1)
((unsigned char *)packet)[len] = 0; /* for checksum, in case length is odd. */
@@ -196,7 +196,7 @@ void dump_packet(int mask, void *packet, size_t len, union mysockaddr *src, unio
pcap_header.ts_sec = time.tv_sec;
pcap_header.ts_usec = time.tv_usec;
pcap_header.incl_len = pcap_header.orig_len = ipsz + sizeof(udp) + len;
if (rc == -1 ||
!read_write(daemon->dumpfd, (void *)&pcap_header, sizeof(pcap_header), 0) ||
!read_write(daemon->dumpfd, iphdr, ipsz, 0) ||
+336 -336
View File
File diff suppressed because it is too large Load Diff
+37 -37
View File
@@ -1,15 +1,15 @@
/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991, or
(at your option) version 3 dated 29 June, 2007.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -21,16 +21,16 @@
#include <sys/param.h> /* For MAXSYMLINKS */
/* the strategy is to set an inotify on the directories containing
resolv files, for any files in the directory which are close-write
resolv files, for any files in the directory which are close-write
or moved into the directory.
When either of those happen, we look to see if the file involved
is actually a resolv-file, and if so, call poll-resolv with
the "force" argument, to ensure it's read.
This adds one new error condition: the directories containing
all specified resolv-files must exist at start-up, even if the actual
files don't.
files don't.
*/
static char *inotify_buffer;
@@ -49,7 +49,7 @@ static char *my_readlink(char *path)
{
buf = safe_malloc(size);
rc = readlink(path, buf, (size_t)size);
if (rc == -1)
{
/* Not link or doesn't exist. */
@@ -64,7 +64,7 @@ static char *my_readlink(char *path)
else if (rc < size-1)
{
char *d;
buf[rc] = 0;
if (buf[0] != '/' && ((d = strrchr(path, '/'))))
{
@@ -90,13 +90,13 @@ void inotify_dnsmasq_init()
struct resolvc *res;
inotify_buffer = safe_malloc(INOTIFY_SZ);
daemon->inotifyfd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
if (daemon->inotifyfd == -1)
die(_("failed to create inotify: %s"), NULL, EC_MISC);
if (option_bool(OPT_NO_RESOLV))
return;
for (res = daemon->resolv_files; res; res = res->next)
{
char *d, *new_path, *path = safe_malloc(strlen(res->name) + 1);
@@ -122,14 +122,14 @@ void inotify_dnsmasq_init()
res->file = d+1; /* pointer to filename */
*d = '/';
if (res->wd == -1 && errno == ENOENT)
die(_("directory %s for resolv-file is missing, cannot poll"), res->name, EC_MISC);
}
}
if (res->wd == -1)
die(_("failed to create inotify for %s: %s"), res->name, EC_MISC);
}
}
@@ -138,23 +138,23 @@ void inotify_dnsmasq_init()
void set_dynamic_inotify(int flag, int total_size, struct crec **rhash, int revhashsz)
{
struct hostsfile *ah;
for (ah = daemon->dynamic_dirs; ah; ah = ah->next)
{
DIR *dir_stream = NULL;
struct dirent *ent;
struct stat buf;
if (!(ah->flags & flag))
continue;
if (stat(ah->fname, &buf) == -1 || !(S_ISDIR(buf.st_mode)))
{
my_syslog(LOG_ERR, _("bad dynamic directory %s: %s"),
my_syslog(LOG_ERR, _("bad dynamic directory %s: %s"),
ah->fname, strerror(errno));
continue;
}
if (!(ah->flags & AH_WD_DONE))
{
ah->wd = inotify_add_watch(daemon->inotifyfd, ah->fname, IN_CLOSE_WRITE | IN_MOVED_TO);
@@ -175,20 +175,20 @@ void set_dynamic_inotify(int flag, int total_size, struct crec **rhash, int revh
size_t lendir = strlen(ah->fname);
size_t lenfile = strlen(ent->d_name);
char *path;
/* ignore emacs backups and dotfiles */
if (lenfile == 0 ||
if (lenfile == 0 ||
ent->d_name[lenfile - 1] == '~' ||
(ent->d_name[0] == '#' && ent->d_name[lenfile - 1] == '#') ||
ent->d_name[0] == '.')
continue;
if ((path = whine_malloc(lendir + lenfile + 2)))
{
strcpy(path, ah->fname);
strcat(path, "/");
strcat(path, ent->d_name);
/* ignore non-regular files */
if (stat(path, &buf) != -1 && S_ISREG(buf.st_mode))
{
@@ -197,7 +197,7 @@ void set_dynamic_inotify(int flag, int total_size, struct crec **rhash, int revh
#ifdef HAVE_DHCP
else if (ah->flags & (AH_DHCP_HST | AH_DHCP_OPT))
option_read_dynfile(path, ah->flags);
#endif
#endif
}
free(path);
@@ -221,16 +221,16 @@ int inotify_check(time_t now)
struct inotify_event *in;
while ((rc = read(daemon->inotifyfd, inotify_buffer, INOTIFY_SZ)) == -1 && errno == EINTR);
if (rc <= 0)
break;
for (p = inotify_buffer; rc - (p - inotify_buffer) >= (int)sizeof(struct inotify_event); p += sizeof(struct inotify_event) + in->len)
for (p = inotify_buffer; rc - (p - inotify_buffer) >= (int)sizeof(struct inotify_event); p += sizeof(struct inotify_event) + in->len)
{
size_t namelen;
in = (struct inotify_event*)p;
/* ignore emacs backups and dotfiles */
if (in->len == 0 || (namelen = strlen(in->name)) == 0 ||
in->name[namelen - 1] == '~' ||
@@ -247,25 +247,25 @@ int inotify_check(time_t now)
{
size_t lendir = strlen(ah->fname);
char *path;
if ((path = whine_malloc(lendir + in->len + 2)))
{
strcpy(path, ah->fname);
strcat(path, "/");
strcat(path, in->name);
my_syslog(LOG_INFO, _("inotify, new or changed file %s"), path);
if (ah->flags & AH_HOSTS)
{
read_hostsfile(path, ah->index, 0, NULL, 0);
#ifdef HAVE_DHCP
if (daemon->dhcp || daemon->doing_dhcp6)
if (daemon->dhcp || daemon->doing_dhcp6)
{
/* Propagate the consequences of loading a new dhcp-host */
dhcp_update_configs(daemon->dhcp_conf);
lease_update_from_configs();
lease_update_file(now);
lease_update_from_configs();
lease_update_file(now);
lease_update_dns(1);
}
#endif
@@ -277,15 +277,15 @@ int inotify_check(time_t now)
{
/* Propagate the consequences of loading a new dhcp-host */
dhcp_update_configs(daemon->dhcp_conf);
lease_update_from_configs();
lease_update_file(now);
lease_update_from_configs();
lease_update_file(now);
lease_update_dns(1);
}
}
else if (ah->flags & AH_DHCP_OPT)
option_read_dynfile(path, AH_DHCP_OPT);
#endif
free(path);
}
}
@@ -295,4 +295,4 @@ int inotify_check(time_t now)
}
#endif /* INOTIFY */
+134 -134
View File
@@ -4,12 +4,12 @@
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991, or
(at your option) version 3 dated 29 June, 2007.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -45,7 +45,7 @@ static int read_leases(time_t now, FILE *leasestream)
{
*daemon->namebuff = *daemon->dhcp_buff = *daemon->packet = '\0';
hw_len = hw_type = clid_len = 0;
#ifdef HAVE_DHCP6
if (strcmp(daemon->dhcp_buff3, "duid") == 0)
{
@@ -57,20 +57,20 @@ static int read_leases(time_t now, FILE *leasestream)
continue;
}
#endif
if (fscanf(leasestream, " %64s %255s %764s",
daemon->namebuff, daemon->dhcp_buff, daemon->packet) != 3)
return 0;
if (inet_pton(AF_INET, daemon->namebuff, &addr.addr.addr4))
{
if ((lease = lease4_allocate(addr.addr.addr4)))
domain = get_domain(lease->addr);
hw_len = parse_hex(daemon->dhcp_buff2, (unsigned char *)daemon->dhcp_buff2, DHCP_CHADDR_MAX, NULL, &hw_type);
/* For backwards compatibility, no explicit MAC address type means ether. */
if (hw_type == 0 && hw_len != 0)
hw_type = ARPHRD_ETHER;
hw_type = ARPHRD_ETHER;
}
#ifdef HAVE_DHCP6
else if (inet_pton(AF_INET6, daemon->namebuff, &addr.addr.addr6))
@@ -83,7 +83,7 @@ static int read_leases(time_t now, FILE *leasestream)
lease_type = LEASE_TA;
s++;
}
if ((lease = lease6_allocate(&addr.addr.addr6, lease_type)))
{
lease_set_iaid(lease, strtoul(s, NULL, 10));
@@ -99,10 +99,10 @@ static int read_leases(time_t now, FILE *leasestream)
if (strcmp(daemon->packet, "*") != 0)
clid_len = parse_hex(daemon->packet, (unsigned char *)daemon->packet, 255, NULL, NULL);
lease_set_hwaddr(lease, (unsigned char *)daemon->dhcp_buff2, (unsigned char *)daemon->packet,
lease_set_hwaddr(lease, (unsigned char *)daemon->dhcp_buff2, (unsigned char *)daemon->packet,
hw_len, hw_type, clid_len, now, 0);
if (strcmp(daemon->dhcp_buff, "*") != 0)
lease_set_hostname(lease, daemon->dhcp_buff, 0, domain, NULL);
@@ -119,14 +119,14 @@ static int read_leases(time_t now, FILE *leasestream)
even when sizeof(time_t) == 8 */
lease->expires = (time_t)ei;
#endif
/* set these correctly: the "old" events are generated later from
the startup synthesised SIGHUP. */
lease->flags &= ~(LEASE_NEW | LEASE_CHANGED);
*daemon->dhcp_buff3 = *daemon->dhcp_buff2 = '\0';
}
return (items == 0 || items == EOF);
}
@@ -179,7 +179,7 @@ void lease_init(time_t now)
if (ferror(leasestream))
die(_("failed to read lease file %s: %s"), daemon->lease_file, EC_FILE);
}
#ifdef HAVE_SCRIPT
if (!daemon->lease_stream)
{
@@ -195,7 +195,7 @@ void lease_init(time_t now)
die(_("cannot run lease-init script %s: %s"), daemon->lease_change_command, EC_FILE);
}
if (WEXITSTATUS(rc) != 0)
{
sprintf(daemon->dhcp_buff, "%d", WEXITSTATUS(rc));
@@ -213,16 +213,16 @@ void lease_init(time_t now)
void lease_update_from_configs(void)
{
/* changes to the config may change current leases. */
struct dhcp_lease *lease;
struct dhcp_config *config;
char *name;
for (lease = leases; lease; lease = lease->next)
if (lease->flags & (LEASE_TA | LEASE_NA))
continue;
else if ((config = find_config(daemon->dhcp_conf, NULL, lease->clid, lease->clid_len,
lease->hwaddr, lease->hwaddr_len, lease->hwaddr_type, NULL)) &&
else if ((config = find_config(daemon->dhcp_conf, NULL, lease->clid, lease->clid_len,
lease->hwaddr, lease->hwaddr_len, lease->hwaddr_type, NULL)) &&
(config->flags & CONFIG_NAME) &&
(!(config->flags & CONFIG_ADDR) || config->addr.s_addr == lease->addr.s_addr))
lease_set_hostname(lease, config->hostname, 1, get_domain(lease->addr), NULL);
@@ -233,7 +233,7 @@ void lease_update_from_configs(void)
static void ourprintf(int *errp, char *format, ...)
{
va_list ap;
va_start(ap, format);
if (!(*errp) && vfprintf(daemon->lease_stream, format, ap) < 0)
*errp = errno;
@@ -252,7 +252,7 @@ void lease_update_file(time_t now)
rewind(daemon->lease_stream);
if (errno != 0 || ftruncate(fileno(daemon->lease_stream), 0) != 0)
err = errno;
for (lease = leases; lease; lease = lease->next)
{
@@ -267,7 +267,7 @@ void lease_update_file(time_t now)
ourprintf(&err, "%lu ", (unsigned long)lease->expires);
#endif
if (lease->hwaddr_type != ARPHRD_ETHER || lease->hwaddr_len == 0)
if (lease->hwaddr_type != ARPHRD_ETHER || lease->hwaddr_len == 0)
ourprintf(&err, "%.2x-", lease->hwaddr_type);
for (i = 0; i < lease->hwaddr_len; i++)
{
@@ -275,12 +275,12 @@ void lease_update_file(time_t now)
if (i != lease->hwaddr_len - 1)
ourprintf(&err, ":");
}
inet_ntop(AF_INET, &lease->addr, daemon->addrbuff, ADDRSTRLEN);
inet_ntop(AF_INET, &lease->addr, daemon->addrbuff, ADDRSTRLEN);
ourprintf(&err, " %s ", daemon->addrbuff);
ourprintf(&err, "%s ", lease->hostname ? lease->hostname : "*");
if (lease->clid && lease->clid_len != 0)
{
for (i = 0; i < lease->clid_len - 1; i++)
@@ -288,20 +288,20 @@ void lease_update_file(time_t now)
ourprintf(&err, "%.2x\n", lease->clid[i]);
}
else
ourprintf(&err, "*\n");
ourprintf(&err, "*\n");
}
#ifdef HAVE_DHCP6
#ifdef HAVE_DHCP6
if (daemon->duid)
{
ourprintf(&err, "duid ");
for (i = 0; i < daemon->duid_len - 1; i++)
ourprintf(&err, "%.2x:", daemon->duid[i]);
ourprintf(&err, "%.2x\n", daemon->duid[i]);
for (lease = leases; lease; lease = lease->next)
{
if (!(lease->flags & (LEASE_TA | LEASE_NA)))
continue;
@@ -310,13 +310,13 @@ void lease_update_file(time_t now)
#else
ourprintf(&err, "%lu ", (unsigned long)lease->expires);
#endif
inet_ntop(AF_INET6, &lease->addr6, daemon->addrbuff, ADDRSTRLEN);
ourprintf(&err, "%s%u %s ", (lease->flags & LEASE_TA) ? "T" : "",
lease->iaid, daemon->addrbuff);
ourprintf(&err, "%s ", lease->hostname ? lease->hostname : "*");
if (lease->clid && lease->clid_len != 0)
{
for (i = 0; i < lease->clid_len - 1; i++)
@@ -324,19 +324,19 @@ void lease_update_file(time_t now)
ourprintf(&err, "%.2x\n", lease->clid[i]);
}
else
ourprintf(&err, "*\n");
ourprintf(&err, "*\n");
}
}
#endif
#endif
if (fflush(daemon->lease_stream) != 0 ||
fsync(fileno(daemon->lease_stream)) < 0)
err = errno;
if (!err)
file_dirty = 0;
}
/* Set alarm for when the first lease expires. */
next_event = 0;
@@ -345,13 +345,13 @@ void lease_update_file(time_t now)
if (daemon->doing_ra)
{
time_t event;
if ((event = periodic_slaac(now, leases)) != 0)
{
if (next_event == 0 || difftime(next_event, event) > 0.0)
next_event = event;
}
if ((event = periodic_ra(now)) != 0)
{
if (next_event == 0 || difftime(next_event, event) > 0.0)
@@ -364,13 +364,13 @@ void lease_update_file(time_t now)
if (lease->expires != 0 &&
(next_event == 0 || difftime(next_event, lease->expires) > 0.0))
next_event = lease->expires;
if (err)
{
if (next_event == 0 || difftime(next_event, LEASE_RETRY + now) > 0.0)
next_event = LEASE_RETRY + now;
my_syslog(MS_DHCP | LOG_ERR, _("failed to write %s: %s (retry in %us)"),
my_syslog(MS_DHCP | LOG_ERR, _("failed to write %s: %s (retry in %us)"),
daemon->lease_file, strerror(err),
(unsigned int)difftime(next_event, now));
}
@@ -391,8 +391,8 @@ static int find_interface_v4(struct in_addr local, int if_index, char *label,
for (lease = leases; lease; lease = lease->next)
if (!(lease->flags & (LEASE_TA | LEASE_NA)) &&
is_same_net(local, lease->addr, netmask) &&
prefix > lease->new_prefixlen)
is_same_net(local, lease->addr, netmask) &&
prefix > lease->new_prefixlen)
{
lease->new_interface = if_index;
lease->new_prefixlen = prefix;
@@ -403,7 +403,7 @@ static int find_interface_v4(struct in_addr local, int if_index, char *label,
#ifdef HAVE_DHCP6
static int find_interface_v6(struct in6_addr *local, int prefix,
int scope, int if_index, int flags,
int scope, int if_index, int flags,
int preferred, int valid, void *vparam)
{
struct dhcp_lease *lease;
@@ -441,7 +441,7 @@ void lease_update_slaac(time_t now)
new SLAAC addresses to existing leases. */
struct dhcp_lease *lease;
if (daemon->dhcp)
for (lease = leases; lease; lease = lease->next)
slaac_add_addrs(lease, now, 0);
@@ -457,7 +457,7 @@ void lease_update_slaac(time_t now)
void lease_find_interfaces(time_t now)
{
struct dhcp_lease *lease;
for (lease = leases; lease; lease = lease->next)
lease->new_prefixlen = lease->new_interface = 0;
@@ -467,7 +467,7 @@ void lease_find_interfaces(time_t now)
#endif
for (lease = leases; lease; lease = lease->next)
if (lease->new_interface != 0)
if (lease->new_interface != 0)
lease_set_interface(lease, lease->new_interface, now);
}
@@ -496,13 +496,13 @@ void lease_update_dns(int force)
/* force transfer to authoritative secondaries */
daemon->soa_sn++;
#endif
cache_unhash_dhcp();
for (lease = leases; lease; lease = lease->next)
{
int prot = AF_INET;
#ifdef HAVE_DHCP6
if (lease->flags & (LEASE_TA | LEASE_NA))
prot = AF_INET6;
@@ -519,26 +519,26 @@ void lease_update_dns(int force)
cache_add_dhcp_entry(lease->hostname, AF_INET6, (struct all_addr *)&slaac->addr, lease->expires);
}
}
if (lease->fqdn)
cache_add_dhcp_entry(lease->fqdn, prot,
cache_add_dhcp_entry(lease->fqdn, prot,
prot == AF_INET ? (struct all_addr *)&lease->addr : (struct all_addr *)&lease->addr6,
lease->expires);
if (!option_bool(OPT_DHCP_FQDN) && lease->hostname)
cache_add_dhcp_entry(lease->hostname, prot,
prot == AF_INET ? (struct all_addr *)&lease->addr : (struct all_addr *)&lease->addr6,
cache_add_dhcp_entry(lease->hostname, prot,
prot == AF_INET ? (struct all_addr *)&lease->addr : (struct all_addr *)&lease->addr6,
lease->expires);
#else
if (lease->fqdn)
cache_add_dhcp_entry(lease->fqdn, prot, (struct all_addr *)&lease->addr, lease->expires);
if (!option_bool(OPT_DHCP_FQDN) && lease->hostname)
cache_add_dhcp_entry(lease->hostname, prot, (struct all_addr *)&lease->addr, lease->expires);
#endif
}
dns_dirty = 0;
}
}
@@ -559,20 +559,20 @@ void lease_prune(struct dhcp_lease *target, time_t now)
daemon->metrics[lease->addr.s_addr ? METRIC_LEASES_PRUNED_4 : METRIC_LEASES_PRUNED_6]++;
*up = lease->next; /* unlink */
/* Put on old_leases list 'till we
can run the script */
lease->next = old_leases;
old_leases = lease;
leases_left++;
}
else
up = &lease->next;
}
}
}
struct dhcp_lease *lease_find_by_client(unsigned char *hwaddr, int hw_len, int hw_type,
unsigned char *clid, int clid_len)
{
@@ -589,15 +589,15 @@ struct dhcp_lease *lease_find_by_client(unsigned char *hwaddr, int hw_len, int h
memcmp(clid, lease->clid, clid_len) == 0)
return lease;
}
for (lease = leases; lease; lease = lease->next)
for (lease = leases; lease; lease = lease->next)
{
#ifdef HAVE_DHCP6
if (lease->flags & (LEASE_TA | LEASE_NA))
continue;
#endif
if ((!lease->clid || !clid) &&
hw_len != 0 &&
#endif
if ((!lease->clid || !clid) &&
hw_len != 0 &&
lease->hwaddr_len == hw_len &&
lease->hwaddr_type == hw_type &&
memcmp(hwaddr, lease->hwaddr, hw_len) == 0)
@@ -616,7 +616,7 @@ struct dhcp_lease *lease_find_by_addr(struct in_addr addr)
#ifdef HAVE_DHCP6
if (lease->flags & (LEASE_TA | LEASE_NA))
continue;
#endif
#endif
if (lease->addr.s_addr == addr.s_addr)
return lease;
}
@@ -626,11 +626,11 @@ struct dhcp_lease *lease_find_by_addr(struct in_addr addr)
#ifdef HAVE_DHCP6
/* find address for {CLID, IAID, address} */
struct dhcp_lease *lease6_find(unsigned char *clid, int clid_len,
struct dhcp_lease *lease6_find(unsigned char *clid, int clid_len,
int lease_type, int iaid, struct in6_addr *addr)
{
struct dhcp_lease *lease;
for (lease = leases; lease; lease = lease->next)
{
if (!(lease->flags & lease_type) || lease->iaid != iaid)
@@ -638,14 +638,14 @@ struct dhcp_lease *lease6_find(unsigned char *clid, int clid_len,
if (!IN6_ARE_ADDR_EQUAL(&lease->addr6, addr))
continue;
if ((clid_len != lease->clid_len ||
memcmp(clid, lease->clid, clid_len) != 0))
continue;
return lease;
}
return NULL;
}
@@ -653,7 +653,7 @@ struct dhcp_lease *lease6_find(unsigned char *clid, int clid_len,
void lease6_reset(void)
{
struct dhcp_lease *lease;
for (lease = leases; lease; lease = lease->next)
lease->flags &= ~LEASE_USED;
}
@@ -675,40 +675,40 @@ struct dhcp_lease *lease6_find_by_client(struct dhcp_lease *first, int lease_typ
if (!(lease->flags & lease_type) || lease->iaid != iaid)
continue;
if ((clid_len != lease->clid_len ||
memcmp(clid, lease->clid, clid_len) != 0))
continue;
return lease;
}
return NULL;
}
struct dhcp_lease *lease6_find_by_addr(struct in6_addr *net, int prefix, u64 addr)
{
struct dhcp_lease *lease;
for (lease = leases; lease; lease = lease->next)
{
if (!(lease->flags & (LEASE_TA | LEASE_NA)))
continue;
if (is_same_net6(&lease->addr6, net, prefix) &&
(prefix == 128 || addr6part(&lease->addr6) == addr))
return lease;
}
return NULL;
}
}
/* Find largest assigned address in context */
u64 lease_find_max_addr6(struct dhcp_context *context)
{
struct dhcp_lease *lease;
u64 addr = addr6part(&context->start6);
if (!(context->flags & (CONTEXT_STATIC | CONTEXT_PROXY)))
for (lease = leases; lease; lease = lease->next)
{
@@ -721,7 +721,7 @@ u64 lease_find_max_addr6(struct dhcp_context *context)
addr6part(&lease->addr6) > addr)
addr = addr6part(&lease->addr6);
}
return addr;
}
@@ -732,7 +732,7 @@ struct in_addr lease_find_max_addr(struct dhcp_context *context)
{
struct dhcp_lease *lease;
struct in_addr addr = context->start;
if (!(context->flags & (CONTEXT_STATIC | CONTEXT_PROXY)))
for (lease = leases; lease; lease = lease->next)
{
@@ -745,7 +745,7 @@ struct in_addr lease_find_max_addr(struct dhcp_context *context)
((unsigned)ntohl(lease->addr.s_addr)) > ((unsigned)ntohl(addr.s_addr)))
addr = lease->addr;
}
return addr;
}
@@ -764,7 +764,7 @@ static struct dhcp_lease *lease_allocate(void)
lease->hwaddr_len = 256; /* illegal value */
lease->next = leases;
leases = lease;
file_dirty = 1;
leases_left--;
@@ -779,7 +779,7 @@ struct dhcp_lease *lease4_allocate(struct in_addr addr)
lease->addr = addr;
daemon->metrics[METRIC_LEASES_ALLOCATED_4]++;
}
return lease;
}
@@ -829,16 +829,16 @@ void lease_set_expires(struct dhcp_lease *lease, unsigned int len, time_t now)
file_dirty = 1;
#endif
}
#ifdef HAVE_BROKEN_RTC
if (len != lease->length)
{
lease->length = len;
lease->flags |= LEASE_AUX_CHANGED;
file_dirty = 1;
file_dirty = 1;
}
#endif
}
}
#ifdef HAVE_DHCP6
void lease_set_iaid(struct dhcp_lease *lease, int iaid)
@@ -864,7 +864,7 @@ void lease_set_hwaddr(struct dhcp_lease *lease, const unsigned char *hwaddr,
(void)now;
if (hw_len != lease->hwaddr_len ||
hw_type != lease->hwaddr_type ||
hw_type != lease->hwaddr_type ||
(hw_len != 0 && memcmp(lease->hwaddr, hwaddr, hw_len) != 0))
{
if (hw_len != 0)
@@ -892,7 +892,7 @@ void lease_set_hwaddr(struct dhcp_lease *lease, const unsigned char *hwaddr,
return;
#ifdef HAVE_DHCP6
change = 1;
#endif
#endif
}
else if (memcmp(lease->clid, clid, clid_len) != 0)
{
@@ -900,13 +900,13 @@ void lease_set_hwaddr(struct dhcp_lease *lease, const unsigned char *hwaddr,
file_dirty = 1;
#ifdef HAVE_DHCP6
change = 1;
#endif
#endif
}
lease->clid_len = clid_len;
memcpy(lease->clid, clid, clid_len);
}
#ifdef HAVE_DHCP6
if (change)
slaac_add_addrs(lease, now, force);
@@ -916,11 +916,11 @@ void lease_set_hwaddr(struct dhcp_lease *lease, const unsigned char *hwaddr,
static void kill_name(struct dhcp_lease *lease)
{
/* run script to say we lost our old name */
/* this shouldn't happen unless updates are very quick and the
script very slow, we just avoid a memory leak if it does. */
free(lease->old_hostname);
/* If we know the fqdn, pass that. The helper will derive the
unqualified name from it, free the unqualified name here. */
@@ -942,25 +942,25 @@ void lease_set_hostname(struct dhcp_lease *lease, const char *name, int auth, ch
if (config_domain && (!domain || !hostname_isequal(domain, config_domain)))
my_syslog(MS_DHCP | LOG_WARNING, _("Ignoring domain %s for DHCP host name %s"), config_domain, name);
if (lease->hostname && name && hostname_isequal(lease->hostname, name))
{
if (auth)
lease->flags |= LEASE_AUTH_NAME;
return;
}
if (!name && !lease->hostname)
return;
/* If a machine turns up on a new net without dropping the old lease,
or two machines claim the same name, then we end up with two interfaces with
the same name. Check for that here and remove the name from the old lease.
Note that IPv6 leases are different. All the leases to the same DUID are
Note that IPv6 leases are different. All the leases to the same DUID are
allowed the same name.
Don't allow a name from the client to override a name from dnsmasq config. */
if (name)
{
if ((new_name = whine_malloc(strlen(name) + 1)))
@@ -973,7 +973,7 @@ void lease_set_hostname(struct dhcp_lease *lease, const char *name, int auth, ch
strcat(new_fqdn, domain);
}
}
/* Depending on mode, we check either unqualified name or FQDN. */
for (lease_tmp = leases; lease_tmp; lease_tmp = lease_tmp->next)
{
@@ -985,7 +985,7 @@ void lease_set_hostname(struct dhcp_lease *lease, const char *name, int auth, ch
else
{
if (!new_name || !lease_tmp->hostname || !hostname_isequal(lease_tmp->hostname, new_name) )
continue;
continue;
}
if (lease->flags & (LEASE_TA | LEASE_NA))
@@ -997,18 +997,18 @@ void lease_set_hostname(struct dhcp_lease *lease, const char *name, int auth, ch
if (lease->clid_len == lease_tmp->clid_len &&
lease->clid && lease_tmp->clid &&
memcmp(lease->clid, lease_tmp->clid, lease->clid_len) == 0)
continue;
continue;
}
else if (lease_tmp->flags & (LEASE_TA | LEASE_NA))
continue;
if ((lease_tmp->flags & LEASE_AUTH_NAME) && !auth)
{
free(new_name);
free(new_fqdn);
return;
}
kill_name(lease_tmp);
break;
}
@@ -1019,12 +1019,12 @@ void lease_set_hostname(struct dhcp_lease *lease, const char *name, int auth, ch
lease->hostname = new_name;
lease->fqdn = new_fqdn;
if (auth)
lease->flags |= LEASE_AUTH_NAME;
file_dirty = 1;
dns_dirty = 1;
dns_dirty = 1;
lease->flags |= LEASE_CHANGED; /* run script on change */
}
@@ -1036,7 +1036,7 @@ void lease_set_interface(struct dhcp_lease *lease, int interface, time_t now)
return;
lease->last_interface = interface;
lease->flags |= LEASE_CHANGED;
lease->flags |= LEASE_CHANGED;
#ifdef HAVE_DHCP6
slaac_add_addrs(lease, now, 0);
@@ -1046,9 +1046,9 @@ void lease_set_interface(struct dhcp_lease *lease, int interface, time_t now)
void rerun_scripts(void)
{
struct dhcp_lease *lease;
for (lease = leases; lease; lease = lease->next)
lease->flags |= LEASE_CHANGED;
lease->flags |= LEASE_CHANGED;
}
/* deleted leases get transferred to the old_leases list.
@@ -1072,7 +1072,7 @@ int do_script_run(time_t now)
if (old_leases)
{
lease = old_leases;
/* If the lease still has an old_hostname, do the "old" action on that first */
if (lease->old_hostname)
{
@@ -1083,7 +1083,7 @@ int do_script_run(time_t now)
lease->old_hostname = NULL;
return 1;
}
else
else
{
#ifdef HAVE_DHCP6
struct slaac_address *slaac, *tmp;
@@ -1101,20 +1101,20 @@ int do_script_run(time_t now)
emit_dbus_signal(ACTION_DEL, lease, lease->old_hostname);
#endif
old_leases = lease->next;
free(lease->old_hostname);
free(lease->old_hostname);
free(lease->clid);
free(lease->extradata);
free(lease);
return 1;
return 1;
}
}
/* make sure we announce the loss of a hostname before its new location. */
for (lease = leases; lease; lease = lease->next)
if (lease->old_hostname)
{
{
#ifdef HAVE_SCRIPT
queue_script(ACTION_OLD_HOSTNAME, lease, lease->old_hostname, now);
#endif
@@ -1122,13 +1122,13 @@ int do_script_run(time_t now)
lease->old_hostname = NULL;
return 1;
}
for (lease = leases; lease; lease = lease->next)
if ((lease->flags & (LEASE_NEW | LEASE_CHANGED)) ||
if ((lease->flags & (LEASE_NEW | LEASE_CHANGED)) ||
((lease->flags & LEASE_AUX_CHANGED) && option_bool(OPT_LEASE_RO)))
{
#ifdef HAVE_SCRIPT
queue_script((lease->flags & LEASE_NEW) ? ACTION_ADD : ACTION_OLD, lease,
queue_script((lease->flags & LEASE_NEW) ? ACTION_ADD : ACTION_OLD, lease,
lease->fqdn ? lease->fqdn : lease->hostname, now);
#endif
#ifdef HAVE_DBUS
@@ -1136,11 +1136,11 @@ int do_script_run(time_t now)
lease->fqdn ? lease->fqdn : lease->hostname);
#endif
lease->flags &= ~(LEASE_NEW | LEASE_CHANGED | LEASE_AUX_CHANGED);
/* this is used for the "add" call, then junked, since they're not in the database */
free(lease->extradata);
lease->extradata = NULL;
return 1;
}
@@ -1152,7 +1152,7 @@ int do_script_run(time_t now)
void lease_add_extradata(struct dhcp_lease *lease, unsigned char *data, unsigned int len, int delim)
{
unsigned int i;
if (delim == -1)
delim = 0;
else
@@ -1163,15 +1163,15 @@ void lease_add_extradata(struct dhcp_lease *lease, unsigned char *data, unsigned
len = i;
break;
}
if ((lease->extradata_size - lease->extradata_len) < (len + 1))
{
size_t newsz = lease->extradata_len + len + 100;
unsigned char *new = whine_malloc(newsz);
if (!new)
return;
if (lease->extradata)
{
memcpy(new, lease->extradata, lease->extradata_len);
@@ -1185,12 +1185,12 @@ void lease_add_extradata(struct dhcp_lease *lease, unsigned char *data, unsigned
if (len != 0)
memcpy(lease->extradata + lease->extradata_len, data, len);
lease->extradata[lease->extradata_len + len] = delim;
lease->extradata_len += len + 1;
lease->extradata_len += len + 1;
}
#endif
#endif
+63 -63
View File
@@ -4,12 +4,12 @@
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991, or
(at your option) version 3 dated 29 June, 2007.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -20,10 +20,10 @@
# include <android/log.h>
#endif
/* Implement logging to /dev/log asynchronously. If syslogd is
/* Implement logging to /dev/log asynchronously. If syslogd is
making DNS lookups through dnsmasq, and dnsmasq blocks awaiting
syslogd, then the two daemons can deadlock. We get around this
by not blocking when talking to syslog, instead we queue up to
by not blocking when talking to syslog, instead we queue up to
MAX_LOGS messages. If more are queued, they will be dropped,
and the drop event itself logged. */
@@ -69,7 +69,7 @@ int log_start(struct passwd *ent_pw, int errfd)
#endif
if (daemon->log_file)
{
{
log_to_file = 1;
daemon->max_logs = 0;
if (strcmp(daemon->log_file, "-") == 0)
@@ -79,7 +79,7 @@ int log_start(struct passwd *ent_pw, int errfd)
log_fd = dup(STDERR_FILENO);
}
}
max_logs = daemon->max_logs;
if (!log_reopen(daemon->log_file))
@@ -91,7 +91,7 @@ int log_start(struct passwd *ent_pw, int errfd)
/* if queuing is inhibited, make sure we allocate
the one required buffer now. */
if (max_logs == 0)
{
{
free_entries = safe_malloc(sizeof(struct log_entry));
free_entries->next = NULL;
entries_alloced = 1;
@@ -101,7 +101,7 @@ int log_start(struct passwd *ent_pw, int errfd)
change the ownership here so that the file is always owned by
the dnsmasq user. Then logrotate can just copy the owner.
Failure of the chown call is OK, (for instance when started as non-root) */
if (log_to_file && !log_stderr && ent_pw && ent_pw->pw_uid != 0 &&
if (log_to_file && !log_stderr && ent_pw && ent_pw->pw_uid != 0 &&
fchown(log_fd, ent_pw->pw_uid, -1) != 0)
ret = errno;
@@ -111,14 +111,14 @@ int log_start(struct passwd *ent_pw, int errfd)
int log_reopen(char *log_file)
{
if (!log_stderr)
{
{
if (log_fd != -1)
close(log_fd);
/* NOTE: umask is set to 022 by the time this gets called */
if (log_file)
log_fd = open(log_file, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP);
log_fd = open(log_file, O_WRONLY|O_CREAT|O_APPEND, S_IRUSR|S_IWUSR|S_IRGRP);
else
{
#if defined(HAVE_SOLARIS_NETWORK) || defined(__ANDROID__)
@@ -129,14 +129,14 @@ int log_reopen(char *log_file)
#else
int flags;
log_fd = socket(AF_UNIX, connection_type, 0);
/* if max_logs is zero, leave the socket blocking */
if (log_fd != -1 && max_logs != 0 && (flags = fcntl(log_fd, F_GETFL)) != -1)
fcntl(log_fd, F_SETFL, flags | O_NONBLOCK);
#endif
}
}
return log_fd != -1;
}
@@ -146,19 +146,19 @@ static void free_entry(void)
entries = tmp->next;
tmp->next = free_entries;
free_entries = tmp;
}
}
static void log_write(void)
{
ssize_t rc;
while (entries)
{
/* The data in the payload is written with a terminating zero character
and the length reflects this. For a stream connection we need to
send the zero as a record terminator, but this isn't done for a
datagram connection, so treat the length as one less than reality
to elide the zero. If we're logging to a file, turn the zero into
/* The data in the payload is written with a terminating zero character
and the length reflects this. For a stream connection we need to
send the zero as a record terminator, but this isn't done for a
datagram connection, so treat the length as one less than reality
to elide the zero. If we're logging to a file, turn the zero into
a newline, and leave the length alone. */
int len_adjust = 0;
@@ -188,24 +188,24 @@ static void log_write(void)
int e = entries_lost;
entries_lost = 0; /* avoid wild recursion */
my_syslog(LOG_WARNING, _("overflow: %d log entries lost"), e);
}
}
}
continue;
}
if (errno == EINTR)
continue;
if (errno == EAGAIN || errno == EWOULDBLOCK)
return; /* syslogd busy, go again when select() or poll() says so */
if (errno == ENOBUFS)
{
connection_good = 0;
return;
}
/* errors handling after this assumes sockets */
/* errors handling after this assumes sockets */
if (!log_to_file)
{
/* Once a stream socket hits EPIPE, we have to close and re-open
@@ -215,43 +215,43 @@ static void log_write(void)
if (log_reopen(NULL))
continue;
}
else if (errno == ECONNREFUSED ||
errno == ENOTCONN ||
errno == EDESTADDRREQ ||
else if (errno == ECONNREFUSED ||
errno == ENOTCONN ||
errno == EDESTADDRREQ ||
errno == ECONNRESET)
{
/* socket went (syslogd down?), try and reconnect. If we fail,
stop trying until the next call to my_syslog()
stop trying until the next call to my_syslog()
ECONNREFUSED -> connection went down
ENOTCONN -> nobody listening
(ECONNRESET, EDESTADDRREQ are *BSD equivalents) */
struct sockaddr_un logaddr;
#ifdef HAVE_SOCKADDR_SA_LEN
logaddr.sun_len = sizeof(logaddr) - sizeof(logaddr.sun_path) + strlen(_PATH_LOG) + 1;
logaddr.sun_len = sizeof(logaddr) - sizeof(logaddr.sun_path) + strlen(_PATH_LOG) + 1;
#endif
logaddr.sun_family = AF_UNIX;
safe_strncpy(logaddr.sun_path, _PATH_LOG, sizeof(logaddr.sun_path));
/* Got connection back? try again. */
if (connect(log_fd, (struct sockaddr *)&logaddr, sizeof(logaddr)) != -1)
continue;
/* errors from connect which mean we should keep trying */
if (errno == ENOENT ||
errno == EALREADY ||
if (errno == ENOENT ||
errno == EALREADY ||
errno == ECONNREFUSED ||
errno == EISCONN ||
errno == EISCONN ||
errno == EINTR ||
errno == EAGAIN ||
errno == EAGAIN ||
errno == EWOULDBLOCK)
{
/* try again on next syslog() call */
connection_good = 0;
return;
}
/* try the other sort of socket... */
if (errno == EPROTOTYPE)
{
@@ -290,7 +290,7 @@ void my_syslog(int priority, const char *format, ...)
func = "-dhcp";
else if ((LOG_FACMASK & priority) == MS_SCRIPT)
func = "-script";
#ifdef LOG_PRI
priority = LOG_PRI(priority);
#else
@@ -298,7 +298,7 @@ void my_syslog(int priority, const char *format, ...)
priority &= LOG_PRIMASK;
#endif
if (echo_stderr)
if (echo_stderr)
{
fprintf(stderr, "dnsmasq%s: ", func);
va_start(ap, format);
@@ -310,10 +310,10 @@ void my_syslog(int priority, const char *format, ...)
if (log_fd == -1)
{
#ifdef __ANDROID__
/* do android-specific logging.
/* do android-specific logging.
log_fd is always -1 on Android except when logging to a file. */
int alog_lvl;
if (priority <= LOG_ERR)
alog_lvl = ANDROID_LOG_ERROR;
else if (priority == LOG_WARNING)
@@ -327,7 +327,7 @@ void my_syslog(int priority, const char *format, ...)
__android_log_vprint(alog_lvl, "dnsmasq", format, ap);
va_end(ap);
#else
/* fall-back to syslog if we die during startup or
/* fall-back to syslog if we die during startup or
fail during running (always on Solaris). */
static int isopen = 0;
@@ -336,19 +336,19 @@ void my_syslog(int priority, const char *format, ...)
openlog("dnsmasq", LOG_PID, log_fac);
isopen = 1;
}
va_start(ap, format);
va_start(ap, format);
vsyslog(priority, format, ap);
va_end(ap);
#endif
return;
}
if ((entry = free_entries))
free_entries = entry->next;
else if (entries_alloced < max_logs && (entry = malloc(sizeof(struct log_entry))))
entries_alloced++;
if (!entry)
entries_lost++;
else
@@ -363,36 +363,36 @@ void my_syslog(int priority, const char *format, ...)
for (tmp = entries; tmp->next; tmp = tmp->next);
tmp->next = entry;
}
time(&time_now);
p = entry->payload;
if (!log_to_file)
p += sprintf(p, "<%d>", priority | log_fac);
/* Omit timestamp for default daemontools situation */
if (!log_stderr || !option_bool(OPT_NO_FORK))
if (!log_stderr || !option_bool(OPT_NO_FORK))
p += sprintf(p, "%.15s ", ctime(&time_now) + 4);
p += sprintf(p, "dnsmasq%s[%d]: ", func, (int)pid);
len = p - entry->payload;
va_start(ap, format);
va_start(ap, format);
len += vsnprintf(p, MAX_MESSAGE - len, format, ap) + 1; /* include zero-terminator */
va_end(ap);
entry->length = len > MAX_MESSAGE ? MAX_MESSAGE : len;
entry->offset = 0;
entry->pid = pid;
}
/* almost always, logging won't block, so try and write this now,
to save collecting too many log messages during a select loop. */
log_write();
/* Since we're doing things asynchronously, a cache-dump, for instance,
can now generate log lines very fast. With a small buffer (desirable),
that means it can overflow the log-buffer very quickly,
so that the cache dump becomes mainly a count of how many lines
overflowed. To avoid this, we delay here, the delay is controlled
so that the cache dump becomes mainly a count of how many lines
overflowed. To avoid this, we delay here, the delay is controlled
by queue-occupancy, and grows exponentially. The delay is limited to (2^8)ms.
The scaling stuff ensures that when the queue is bigger than 8, the delay
only occurs for the last 8 entries. Once the queue is full, we stop delaying
@@ -402,9 +402,9 @@ void my_syslog(int priority, const char *format, ...)
if (entries && max_logs != 0)
{
int d;
for (d = 0,entry = entries; entry; entry = entry->next, d++);
if (d == max_logs)
d = 0;
else if (max_logs > 8)
@@ -416,11 +416,11 @@ void my_syslog(int priority, const char *format, ...)
waiter.tv_sec = 0;
waiter.tv_nsec = 1000000 << (d - 1); /* 1 ms */
nanosleep(&waiter, NULL);
/* Have another go now */
log_write();
}
}
}
}
void set_log_writer(void)
@@ -445,7 +445,7 @@ void flush_log(void)
log_write();
if (!entries || !connection_good)
{
close(log_fd);
close(log_fd);
break;
}
waiter.tv_sec = 0;
@@ -457,7 +457,7 @@ void flush_log(void)
void die(char *message, char *arg1, int exit_code)
{
char *errmess = strerror(errno);
if (!arg1)
arg1 = errmess;
@@ -470,6 +470,6 @@ void die(char *message, char *arg1, int exit_code)
echo_stderr = 0;
my_syslog(LOG_CRIT, _("FAILED to start up"));
flush_log();
exit(exit_code);
}
+4 -4
View File
@@ -1,15 +1,15 @@
/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991, or
(at your option) version 3 dated 29 June, 2007.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -36,7 +36,7 @@ enum {
METRIC_LEASES_PRUNED_4,
METRIC_LEASES_ALLOCATED_6,
METRIC_LEASES_PRUNED_6,
__METRIC_MAX,
};
+52 -52
View File
@@ -4,12 +4,12 @@
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991, or
(at your option) version 3 dated 29 June, 2007.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -22,7 +22,7 @@
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
/* linux 2.6.19 buggers up the headers, patch it up here. */
/* linux 2.6.19 buggers up the headers, patch it up here. */
#ifndef IFA_RTA
# define IFA_RTA(r) \
((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ifaddrmsg))))
@@ -31,8 +31,8 @@
#endif
#ifndef NDA_RTA
# define NDA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg))))
#endif
# define NDA_RTA(r) ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct ndmsg))))
#endif
static struct iovec iov;
@@ -50,7 +50,7 @@ void netlink_init(void)
addr.nl_pid = 0; /* autobind */
addr.nl_groups = RTMGRP_IPV4_ROUTE;
if (option_bool(OPT_CLEVERBIND))
addr.nl_groups |= RTMGRP_IPV4_IFADDR;
addr.nl_groups |= RTMGRP_IPV4_IFADDR;
#ifdef HAVE_IPV6
addr.nl_groups |= RTMGRP_IPV6_ROUTE;
if (option_bool(OPT_CLEVERBIND))
@@ -60,7 +60,7 @@ void netlink_init(void)
if (daemon->doing_ra || daemon->doing_dhcp6)
addr.nl_groups |= RTMGRP_IPV6_IFADDR;
#endif
/* May not be able to have permission to set multicast groups don't die in that case */
if ((daemon->netlinkfd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE)) != -1)
{
@@ -71,14 +71,14 @@ void netlink_init(void)
daemon->netlinkfd = -1;
}
}
if (daemon->netlinkfd == -1 ||
if (daemon->netlinkfd == -1 ||
getsockname(daemon->netlinkfd, (struct sockaddr *)&addr, &slen) == -1)
die(_("cannot create netlink socket: %s"), NULL, EC_MISC);
/* save pid assigned by bind() and retrieved by getsockname() */
/* save pid assigned by bind() and retrieved by getsockname() */
netlink_pid = addr.nl_pid;
iov.iov_len = 100;
iov.iov_base = safe_malloc(iov.iov_len);
}
@@ -98,9 +98,9 @@ static ssize_t netlink_recv(void)
msg.msg_iov = &iov;
msg.msg_iovlen = 1;
msg.msg_flags = 0;
while ((rc = recvmsg(daemon->netlinkfd, &msg, MSG_PEEK | MSG_TRUNC)) == -1 && errno == EINTR);
/* make buffer big enough */
if (rc != -1 && (msg.msg_flags & MSG_TRUNC))
{
@@ -117,22 +117,22 @@ static ssize_t netlink_recv(void)
/* read it for real */
msg.msg_flags = 0;
while ((rc = recvmsg(daemon->netlinkfd, &msg, 0)) == -1 && errno == EINTR);
/* Make sure this is from the kernel */
if (rc == -1 || nladdr.nl_pid == 0)
break;
}
/* discard stuff which is truncated at this point (expand_buf() may fail) */
if (msg.msg_flags & MSG_TRUNC)
{
rc = -1;
errno = ENOMEM;
}
return rc;
}
/* family = AF_UNSPEC finds ARP table entries.
family = AF_LOCAL finds MAC addresses. */
@@ -146,15 +146,15 @@ int iface_enumerate(int family, void *parm, int (*callback)())
struct {
struct nlmsghdr nlh;
struct rtgenmsg g;
struct rtgenmsg g;
} req;
memset(&req, 0, sizeof(req));
memset(&addr, 0, sizeof(addr));
addr.nl_family = AF_NETLINK;
again:
again:
if (family == AF_UNSPEC)
req.nlh.nlmsg_type = RTM_GETNEIGH;
else if (family == AF_LOCAL)
@@ -163,18 +163,18 @@ int iface_enumerate(int family, void *parm, int (*callback)())
req.nlh.nlmsg_type = RTM_GETADDR;
req.nlh.nlmsg_len = sizeof(req);
req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST | NLM_F_ACK;
req.nlh.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST | NLM_F_ACK;
req.nlh.nlmsg_pid = 0;
req.nlh.nlmsg_seq = ++seq;
req.g.rtgen_family = family;
req.g.rtgen_family = family;
/* Don't block in recvfrom if send fails */
while(retry_send(sendto(daemon->netlinkfd, (void *)&req, sizeof(req), 0,
while(retry_send(sendto(daemon->netlinkfd, (void *)&req, sizeof(req), 0,
(struct sockaddr *)&addr, sizeof(addr))));
if (errno != 0)
return 0;
while (1)
{
if ((len = netlink_recv()) == -1)
@@ -203,10 +203,10 @@ int iface_enumerate(int family, void *parm, int (*callback)())
return callback_ok;
else if (h->nlmsg_type == RTM_NEWADDR && family != AF_UNSPEC && family != AF_LOCAL)
{
struct ifaddrmsg *ifa = NLMSG_DATA(h);
struct ifaddrmsg *ifa = NLMSG_DATA(h);
struct rtattr *rta = IFA_RTA(ifa);
unsigned int len1 = h->nlmsg_len - NLMSG_LENGTH(sizeof(*ifa));
if (ifa->ifa_family == family)
{
if (ifa->ifa_family == AF_INET)
@@ -218,7 +218,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
addr.s_addr = 0;
broadcast.s_addr = 0;
while (RTA_OK(rta, len1))
{
if (rta->rta_type == IFA_LOCAL)
@@ -227,10 +227,10 @@ int iface_enumerate(int family, void *parm, int (*callback)())
broadcast = *((struct in_addr *)(rta+1));
else if (rta->rta_type == IFA_LABEL)
label = RTA_DATA(rta);
rta = RTA_NEXT(rta, len1);
}
if (addr.s_addr && callback_ok)
if (!((*callback)(addr, ifa->ifa_index, label, netmask, broadcast, parm)))
callback_ok = 0;
@@ -241,11 +241,11 @@ int iface_enumerate(int family, void *parm, int (*callback)())
struct in6_addr *addrp = NULL;
u32 valid = 0, preferred = 0;
int flags = 0;
while (RTA_OK(rta, len1))
{
if (rta->rta_type == IFA_ADDRESS)
addrp = ((struct in6_addr *)(rta+1));
addrp = ((struct in6_addr *)(rta+1));
else if (rta->rta_type == IFA_CACHEINFO)
{
struct ifa_cacheinfo *ifc = (struct ifa_cacheinfo *)(rta+1);
@@ -254,19 +254,19 @@ int iface_enumerate(int family, void *parm, int (*callback)())
}
rta = RTA_NEXT(rta, len1);
}
if (ifa->ifa_flags & IFA_F_TENTATIVE)
flags |= IFACE_TENTATIVE;
if (ifa->ifa_flags & IFA_F_DEPRECATED)
flags |= IFACE_DEPRECATED;
if (!(ifa->ifa_flags & IFA_F_TEMPORARY))
flags |= IFACE_PERMANENT;
if (addrp && callback_ok)
if (!((*callback)(addrp, (int)(ifa->ifa_prefixlen), (int)(ifa->ifa_scope),
(int)(ifa->ifa_index), flags,
if (!((*callback)(addrp, (int)(ifa->ifa_prefixlen), (int)(ifa->ifa_scope),
(int)(ifa->ifa_index), flags,
(int) preferred, (int)valid, parm)))
callback_ok = 0;
}
@@ -275,12 +275,12 @@ int iface_enumerate(int family, void *parm, int (*callback)())
}
else if (h->nlmsg_type == RTM_NEWNEIGH && family == AF_UNSPEC)
{
struct ndmsg *neigh = NLMSG_DATA(h);
struct ndmsg *neigh = NLMSG_DATA(h);
struct rtattr *rta = NDA_RTA(neigh);
unsigned int len1 = h->nlmsg_len - NLMSG_LENGTH(sizeof(*neigh));
size_t maclen = 0;
char *inaddr = NULL, *mac = NULL;
while (RTA_OK(rta, len1))
{
if (rta->rta_type == NDA_DST)
@@ -290,7 +290,7 @@ int iface_enumerate(int family, void *parm, int (*callback)())
maclen = rta->rta_len - sizeof(struct rtattr);
mac = (char *)(rta+1);
}
rta = RTA_NEXT(rta, len1);
}
@@ -315,11 +315,11 @@ int iface_enumerate(int family, void *parm, int (*callback)())
maclen = rta->rta_len - sizeof(struct rtattr);
mac = (char *)(rta+1);
}
rta = RTA_NEXT(rta, len1);
}
if (mac && callback_ok && !((link->ifi_flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) &&
if (mac && callback_ok && !((link->ifi_flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) &&
!((*callback)((int)link->ifi_index, (unsigned int)link->ifi_type, mac, maclen, parm)))
callback_ok = 0;
}
@@ -332,16 +332,16 @@ void netlink_multicast(void)
ssize_t len;
struct nlmsghdr *h;
int flags;
/* don't risk blocking reading netlink messages here. */
if ((flags = fcntl(daemon->netlinkfd, F_GETFL)) == -1 ||
fcntl(daemon->netlinkfd, F_SETFL, flags | O_NONBLOCK) == -1)
fcntl(daemon->netlinkfd, F_SETFL, flags | O_NONBLOCK) == -1)
return;
if ((len = netlink_recv()) != -1)
for (h = (struct nlmsghdr *)iov.iov_base; NLMSG_OK(h, (size_t)len); h = NLMSG_NEXT(h, len))
nl_async(h);
/* restore non-blocking status */
fcntl(daemon->netlinkfd, F_SETFL, flags);
}
@@ -354,21 +354,21 @@ static void nl_async(struct nlmsghdr *h)
if (err->error != 0)
my_syslog(LOG_ERR, _("netlink returns error: %s"), strerror(-(err->error)));
}
else if (h->nlmsg_pid == 0 && h->nlmsg_type == RTM_NEWROUTE)
else if (h->nlmsg_pid == 0 && h->nlmsg_type == RTM_NEWROUTE)
{
/* We arrange to receive netlink multicast messages whenever the network route is added.
If this happens and we still have a DNS packet in the buffer, we re-send it.
This helps on DoD links, where frequently the packet which triggers dialling is
a DNS query, which then gets lost. By re-sending, we can avoid the lookup
failing. */
failing. */
struct rtmsg *rtm = NLMSG_DATA(h);
if (rtm->rtm_type == RTN_UNICAST && rtm->rtm_scope == RT_SCOPE_LINK)
queue_event(EVENT_NEWROUTE);
}
else if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR)
else if (h->nlmsg_type == RTM_NEWADDR || h->nlmsg_type == RTM_DELADDR)
queue_event(EVENT_NEWADDR);
}
#endif
+213 -213
View File
File diff suppressed because it is too large Load Diff
+498 -498
View File
File diff suppressed because it is too large Load Diff
+271 -271
View File
File diff suppressed because it is too large Load Diff
+388 -388
View File
File diff suppressed because it is too large Load Diff
+335 -335
View File
File diff suppressed because it is too large Load Diff
+2 -2
View File
@@ -14,7 +14,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* Code to safely remove RRs from a DNS answer */
/* Code to safely remove RRs from a DNS answer */
#include "dnsmasq.h"
@@ -244,7 +244,7 @@ size_t rrfilter(struct dns_header *header, size_t plen, int mode)
check_name(&p, header, plen, 1, rrs, rr_found);
p += 4; /* qclass, qtype */
check_rrs(p, header, plen, 1, rrs, rr_found);
/* Fourth pass, elide records */
+25 -25
View File
@@ -4,12 +4,12 @@
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991, or
(at your option) version 3 dated 29 June, 2007.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -27,18 +27,18 @@ void slaac_add_addrs(struct dhcp_lease *lease, time_t now, int force)
struct slaac_address *slaac, *old, **up;
struct dhcp_context *context;
int dns_dirty = 0;
if (!(lease->flags & LEASE_HAVE_HWADDR) ||
if (!(lease->flags & LEASE_HAVE_HWADDR) ||
(lease->flags & (LEASE_TA | LEASE_NA)) ||
lease->last_interface == 0 ||
!lease->hostname)
return ;
old = lease->slaac_address;
lease->slaac_address = NULL;
for (context = daemon->dhcp6; context; context = context->next)
if ((context->flags & CONTEXT_RA_NAME) &&
for (context = daemon->dhcp6; context; context = context->next)
if ((context->flags & CONTEXT_RA_NAME) &&
!(context->flags & CONTEXT_OLD) &&
lease->last_interface == context->if_index)
{
@@ -58,7 +58,7 @@ void slaac_add_addrs(struct dhcp_lease *lease, time_t now, int force)
memcpy(&addr.s6_addr[8], lease->hwaddr, 8);
#endif
#if defined(ARPHRD_IEEE1394) && defined(ARPHRD_EUI64)
else if (lease->clid_len == 9 &&
else if (lease->clid_len == 9 &&
lease->clid[0] == ARPHRD_EUI64 &&
lease->hwaddr_type == ARPHRD_IEEE1394)
/* firewire has EUI-64 identifier as clid */
@@ -66,9 +66,9 @@ void slaac_add_addrs(struct dhcp_lease *lease, time_t now, int force)
#endif
else
continue;
addr.s6_addr[8] ^= 0x02;
/* check if we already have this one */
for (up = &old, slaac = old; slaac; slaac = slaac->next)
{
@@ -86,7 +86,7 @@ void slaac_add_addrs(struct dhcp_lease *lease, time_t now, int force)
}
up = &slaac->next;
}
/* No, make new one */
if (!slaac && (slaac = whine_malloc(sizeof(struct slaac_address))))
{
@@ -96,17 +96,17 @@ void slaac_add_addrs(struct dhcp_lease *lease, time_t now, int force)
/* Do RA's to prod it */
ra_start_unsolicited(now, context);
}
if (slaac)
{
slaac->next = lease->slaac_address;
lease->slaac_address = slaac;
}
}
if (old || dns_dirty)
lease_update_dns(1);
/* Free any no reused */
for (; old; old = slaac)
{
@@ -122,7 +122,7 @@ time_t periodic_slaac(time_t now, struct dhcp_lease *leases)
struct dhcp_lease *lease;
struct slaac_address *slaac;
time_t next_event = 0;
for (context = daemon->dhcp6; context; context = context->next)
if ((context->flags & CONTEXT_RA_NAME) && !(context->flags & CONTEXT_OLD))
break;
@@ -140,12 +140,12 @@ time_t periodic_slaac(time_t now, struct dhcp_lease *leases)
/* confirmed or given up? */
if (slaac->backoff == 0 || slaac->ping_time == 0)
continue;
if (difftime(slaac->ping_time, now) <= 0.0)
{
struct ping_packet *ping;
struct sockaddr_in6 addr;
reset_counter();
if (!(ping = expand(sizeof(struct ping_packet))))
@@ -155,7 +155,7 @@ time_t periodic_slaac(time_t now, struct dhcp_lease *leases)
ping->code = 0;
ping->identifier = ping_id;
ping->sequence_no = slaac->backoff;
memset(&addr, 0, sizeof(addr));
#ifdef HAVE_SOCKADDR_SA_LEN
addr.sin6_len = sizeof(struct sockaddr_in6);
@@ -163,12 +163,12 @@ time_t periodic_slaac(time_t now, struct dhcp_lease *leases)
addr.sin6_family = AF_INET6;
addr.sin6_port = htons(IPPROTO_ICMPV6);
addr.sin6_addr = slaac->addr;
if (sendto(daemon->icmp6fd, daemon->outpacket.iov_base, save_counter(-1), 0,
(struct sockaddr *)&addr, sizeof(addr)) == -1 &&
errno == EHOSTUNREACH &&
slaac->backoff == 12)
slaac->ping_time = 0; /* Give up */
slaac->ping_time = 0; /* Give up */
else
{
slaac->ping_time += (1 << (slaac->backoff - 1)) + (rand16()/21785); /* 0 - 3 */
@@ -178,7 +178,7 @@ time_t periodic_slaac(time_t now, struct dhcp_lease *leases)
slaac->backoff++;
}
}
if (slaac->ping_time != 0 &&
(next_event == 0 || difftime(next_event, slaac->ping_time) >= 0.0))
next_event = slaac->ping_time;
@@ -194,7 +194,7 @@ void slaac_ping_reply(struct in6_addr *sender, unsigned char *packet, char *inte
struct slaac_address *slaac;
struct ping_packet *ping = (struct ping_packet *)packet;
int gotone = 0;
if (ping->identifier == ping_id)
for (lease = leases; lease; lease = lease->next)
for (slaac = lease->slaac_address; slaac; slaac = slaac->next)
@@ -204,10 +204,10 @@ void slaac_ping_reply(struct in6_addr *sender, unsigned char *packet, char *inte
gotone = 1;
inet_ntop(AF_INET6, sender, daemon->addrbuff, ADDRSTRLEN);
if (!option_bool(OPT_QUIET_DHCP6))
my_syslog(MS_DHCP | LOG_INFO, "SLAAC-CONFIRM(%s) %s %s", interface, daemon->addrbuff, lease->hostname);
my_syslog(MS_DHCP | LOG_INFO, "SLAAC-CONFIRM(%s) %s %s", interface, daemon->addrbuff, lease->hostname);
}
lease_update_dns(gotone);
}
#endif
+7 -7
View File
@@ -4,12 +4,12 @@
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991, or
(at your option) version 3 dated 29 June, 2007.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
@@ -58,10 +58,10 @@ void check_ubus_listeners()
return;
ubus_add_object(ubus, &ubus_object);
}
if (poll_check(ubus->sock.fd, POLLIN))
ubus_handle_event(ubus);
if (poll_check(ubus->sock.fd, POLLHUP))
{
ubus_free(ubus);
@@ -79,9 +79,9 @@ static int ubus_handle_metrics(struct ubus_context *ctx, struct ubus_object *obj
for(i=0; i < __METRIC_MAX; i++)
blobmsg_add_u32(&b, get_metric_name(i), daemon->metrics[i]);
ubus_send_reply(ctx, req, b.head);
return 0;
}
@@ -99,7 +99,7 @@ void ubus_event_bcast(const char *type, const char *mac, const char *ip, const c
blobmsg_add_string(&b, "name", name);
if (interface)
blobmsg_add_string(&b, "interface", interface);
ubus_notify(ubus, &ubus_object, type, b.head, -1);
}
+80 -80
View File
@@ -4,17 +4,17 @@
it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991, or
(at your option) version 3 dated 29 June, 2007.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
/* The SURF random number generator was taken from djbdns-1.05, by
/* The SURF random number generator was taken from djbdns-1.05, by
Daniel J Bernstein, which is public domain. */
@@ -40,12 +40,12 @@ static int outleft = 0;
void rand_init()
{
int fd = open(RANDFILE, O_RDONLY);
if (fd == -1 ||
!read_write(fd, (unsigned char *)&seed, sizeof(seed), 1) ||
!read_write(fd, (unsigned char *)&in, sizeof(in), 1))
die(_("failed to seed the random number generator: %s"), NULL, EC_MISC);
close(fd);
}
@@ -73,26 +73,26 @@ static void surf(void)
unsigned short rand16(void)
{
if (!outleft)
if (!outleft)
{
if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3];
surf();
outleft = 8;
}
return (unsigned short) out[--outleft];
}
u32 rand32(void)
{
if (!outleft)
if (!outleft)
{
if (!++in[0]) if (!++in[1]) if (!++in[2]) ++in[3];
surf();
outleft = 8;
}
return out[--outleft];
return out[--outleft];
}
u64 rand64(void)
@@ -105,7 +105,7 @@ u64 rand64(void)
surf();
outleft = 8;
}
outleft -= 2;
return (u64)out[outleft+1] + (((u64)out[outleft]) << 32);
@@ -114,15 +114,15 @@ u64 rand64(void)
/* returns 2 if names is OK but contains one or more underscores */
static int check_name(char *in)
{
/* remove trailing .
/* remove trailing .
also fail empty string and label > 63 chars */
size_t dotgap = 0, l = strlen(in);
char c;
int nowhite = 0;
int hasuscore = 0;
if (l == 0 || l > MAXDNAME) return 0;
if (in[l-1] == '.')
{
in[l-1] = 0;
@@ -135,7 +135,7 @@ static int check_name(char *in)
dotgap = 0;
else if (++dotgap > MAXLABEL)
return 0;
else if (isascii((unsigned char)c) && iscntrl((unsigned char)c))
else if (isascii((unsigned char)c) && iscntrl((unsigned char)c))
/* iscntrl only gives expected results for ascii */
return 0;
#if !defined(HAVE_IDN) && !defined(HAVE_LIBIDN2)
@@ -157,8 +157,8 @@ static int check_name(char *in)
}
/* Hostnames have a more limited valid charset than domain names
so check for legal char a-z A-Z 0-9 - _
Note that this may receive a FQDN, so only check the first label
so check for legal char a-z A-Z 0-9 - _
Note that this may receive a FQDN, so only check the first label
for the tighter criteria. */
int legal_hostname(char *name)
{
@@ -178,28 +178,28 @@ int legal_hostname(char *name)
if (!first && (c == '-' || c == '_'))
continue;
/* end of hostname part */
if (c == '.')
return 1;
return 0;
}
return 1;
}
char *canonicalise(char *in, int *nomem)
{
char *ret = NULL;
int rc;
if (nomem)
*nomem = 0;
if (!(rc = check_name(in)))
return NULL;
#if defined(HAVE_LIBIDN2) && (!defined(IDN2_VERSION_NUMBER) || IDN2_VERSION_NUMBER < 0x02000003)
/* older libidn2 strips underscores, so don't do IDN processing
if the name has an underscore (check_name() returned 2) */
@@ -218,24 +218,24 @@ char *canonicalise(char *in, int *nomem)
{
if (ret)
free(ret);
if (nomem && (rc == IDNA_MALLOC_ERROR || rc == IDNA_DLOPEN_ERROR))
{
my_syslog(LOG_ERR, _("failed to allocate memory"));
*nomem = 1;
}
return NULL;
}
return ret;
}
#endif
if ((ret = whine_malloc(strlen(in)+1)))
strcpy(ret, in);
else if (nomem)
*nomem = 1;
*nomem = 1;
return ret;
}
@@ -243,7 +243,7 @@ char *canonicalise(char *in, int *nomem)
unsigned char *do_rfc1035_name(unsigned char *p, char *sval, char *limit)
{
int j;
while (sval && *sval)
{
unsigned char *cp = p++;
@@ -260,15 +260,15 @@ unsigned char *do_rfc1035_name(unsigned char *p, char *sval, char *limit)
if (option_bool(OPT_DNSSEC_VALID) && *sval == NAME_ESCAPE)
*p++ = (*(++sval))-1;
else
#endif
#endif
*p++ = *sval;
}
*cp = j;
if (*sval)
sval++;
}
return p;
}
@@ -276,10 +276,10 @@ unsigned char *do_rfc1035_name(unsigned char *p, char *sval, char *limit)
void *safe_malloc(size_t size)
{
void *ret = calloc(1, size);
if (!ret)
die(_("could not get memory"), NULL, EC_NOMEM);
return ret;
}
@@ -296,7 +296,7 @@ void safe_strncpy(char *dest, const char *src, size_t size)
void safe_pipe(int *fd, int read_noblock)
{
if (pipe(fd) == -1 ||
if (pipe(fd) == -1 ||
!fix_fd(fd[1]) ||
(read_noblock && !fix_fd(fd[0])))
die(_("cannot create pipe: %s"), NULL, EC_MISC);
@@ -308,19 +308,19 @@ void *whine_malloc(size_t size)
if (!ret)
my_syslog(LOG_ERR, _("failed to allocate %d bytes"), (int) size);
return ret;
}
int sockaddr_isequal(union mysockaddr *s1, union mysockaddr *s2)
{
if (s1->sa.sa_family == s2->sa.sa_family)
{
{
if (s1->sa.sa_family == AF_INET &&
s1->in.sin_port == s2->in.sin_port &&
s1->in.sin_addr.s_addr == s2->in.sin_addr.s_addr)
return 1;
#ifdef HAVE_IPV6
#ifdef HAVE_IPV6
if (s1->sa.sa_family == AF_INET6 &&
s1->in6.sin6_port == s2->in6.sin6_port &&
s1->in6.sin6_scope_id == s2->in6.sin6_scope_id &&
@@ -341,7 +341,7 @@ int sa_len(union mysockaddr *addr)
return sizeof(addr->in6);
else
#endif
return sizeof(addr->in);
return sizeof(addr->in);
#endif
}
@@ -349,20 +349,20 @@ int sa_len(union mysockaddr *addr)
int hostname_isequal(const char *a, const char *b)
{
unsigned int c1, c2;
do {
c1 = (unsigned char) *a++;
c2 = (unsigned char) *b++;
if (c1 >= 'A' && c1 <= 'Z')
c1 += 'a' - 'A';
if (c2 >= 'A' && c2 <= 'Z')
c2 += 'a' - 'A';
if (c1 != c2)
return 0;
} while (c1);
return 1;
}
@@ -371,9 +371,9 @@ int hostname_issubdomain(char *a, char *b)
{
char *ap, *bp;
unsigned int c1, c2;
/* move to the end */
for (ap = a; *ap; ap++);
for (ap = a; *ap; ap++);
for (bp = b; *bp; bp++);
/* a shorter than b or a empty. */
@@ -384,7 +384,7 @@ int hostname_issubdomain(char *a, char *b)
{
c1 = (unsigned char) *(--ap);
c2 = (unsigned char) *(--bp);
if (c1 >= 'A' && c1 <= 'Z')
c1 += 'a' - 'A';
if (c2 >= 'A' && c2 <= 'Z')
@@ -402,8 +402,8 @@ int hostname_issubdomain(char *a, char *b)
return 0;
}
time_t dnsmasq_time(void)
{
#ifdef HAVE_BROKEN_RTC
@@ -423,19 +423,19 @@ int netmask_length(struct in_addr mask)
{
int zero_count = 0;
while (0x0 == (mask.s_addr & 0x1) && zero_count < 32)
while (0x0 == (mask.s_addr & 0x1) && zero_count < 32)
{
mask.s_addr >>= 1;
zero_count++;
}
return 32 - zero_count;
}
int is_same_net(struct in_addr a, struct in_addr b, struct in_addr mask)
{
return (a.s_addr & mask.s_addr) == (b.s_addr & mask.s_addr);
}
}
#ifdef HAVE_IPV6
int is_same_net6(struct in6_addr *a, struct in6_addr *b, int prefixlen)
@@ -477,13 +477,13 @@ void setaddr6part(struct in6_addr *addr, u64 host)
}
#endif
/* returns port number from address */
int prettyprint_addr(union mysockaddr *addr, char *buf)
{
int port = 0;
#ifdef HAVE_IPV6
if (addr->sa.sa_family == AF_INET)
{
@@ -505,9 +505,9 @@ int prettyprint_addr(union mysockaddr *addr, char *buf)
}
#else
strcpy(buf, inet_ntoa(addr->in.sin_addr));
port = ntohs(addr->in.sin_port);
port = ntohs(addr->in.sin_port);
#endif
return port;
}
@@ -530,26 +530,26 @@ void prettyprint_time(char *buf, unsigned int t)
}
/* in may equal out, when maxlen may be -1 (No max len).
/* in may equal out, when maxlen may be -1 (No max len).
Return -1 for extraneous no-hex chars found. */
int parse_hex(char *in, unsigned char *out, int maxlen,
int parse_hex(char *in, unsigned char *out, int maxlen,
unsigned int *wildcard_mask, int *mac_type)
{
int mask = 0, i = 0;
char *r;
if (mac_type)
*mac_type = 0;
while (maxlen == -1 || i < maxlen)
{
for (r = in; *r != 0 && *r != ':' && *r != '-' && *r != ' '; r++)
if (*r != '*' && !isxdigit((unsigned char)*r))
return -1;
if (*r == 0)
maxlen = i;
if (r != in )
{
if (*r == '-' && i == 0 && mac_type)
@@ -570,7 +570,7 @@ int parse_hex(char *in, unsigned char *out, int maxlen,
{
int j, bytes = (1 + (r - in))/2;
for (j = 0; j < bytes; j++)
{
{
char sav = sav;
if (j < bytes - 1)
{
@@ -584,7 +584,7 @@ int parse_hex(char *in, unsigned char *out, int maxlen,
out[i] = strtol(&in[j*2], NULL, 16);
mask = mask << 1;
if (++i == maxlen)
break;
break;
if (j < bytes - 1)
in[(j+1)*2] = sav;
}
@@ -593,7 +593,7 @@ int parse_hex(char *in, unsigned char *out, int maxlen,
}
in = r+1;
}
if (wildcard_mask)
*wildcard_mask = mask;
@@ -645,13 +645,13 @@ char *print_mac(char *buff, unsigned char *mac, int len)
{
char *p = buff;
int i;
if (len == 0)
sprintf(p, "<null>");
else
for (i = 0; i < len; i++)
p += sprintf(p, "%.2x%s", mac[i], (i == len - 1) ? "" : ":");
return buff;
}
@@ -662,17 +662,17 @@ int retry_send(ssize_t rc)
{
static int retries = 0;
struct timespec waiter;
if (rc != -1)
{
retries = 0;
errno = 0;
return 0;
}
/* Linux kernels can return EAGAIN in perpetuity when calling
sendmsg() and the relevant interface has gone. Here we loop
retrying in EAGAIN for 1 second max, to avoid this hanging
retrying in EAGAIN for 1 second max, to avoid this hanging
dnsmasq. */
if (errno == EAGAIN || errno == EWOULDBLOCK)
@@ -683,36 +683,36 @@ int retry_send(ssize_t rc)
if (retries++ < 1000)
return 1;
}
retries = 0;
if (errno == EINTR)
return 1;
return 0;
}
int read_write(int fd, unsigned char *packet, int size, int rw)
{
ssize_t n, done;
for (done = 0; done < size; done += n)
{
do {
do {
if (rw)
n = read(fd, &packet[done], (size_t)(size - done));
else
n = write(fd, &packet[done], (size_t)(size - done));
if (n == 0)
return 0;
} while (retry_send(n) || errno == ENOMEM || errno == ENOBUFS);
if (errno != 0)
return 0;
}
return 1;
}
@@ -725,7 +725,7 @@ int wildcard_match(const char* wildcard, const char* match)
return 1;
if (*wildcard != *match)
return 0;
return 0;
++wildcard;
++match;
@@ -743,7 +743,7 @@ int wildcard_matchn(const char* wildcard, const char* match, int num)
return 1;
if (*wildcard != *match)
return 0;
return 0;
++wildcard;
++match;