mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 18:28:25 +00:00
First cut at zone transfer.
This commit is contained in:
163
src/auth.c
163
src/auth.c
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
#include "dnsmasq.h"
|
#include "dnsmasq.h"
|
||||||
|
|
||||||
|
|
||||||
static struct subnet *filter_zone(struct auth_zone *zone, int flag, struct all_addr *addr_u)
|
static struct subnet *filter_zone(struct auth_zone *zone, int flag, struct all_addr *addr_u)
|
||||||
{
|
{
|
||||||
struct subnet *subnet;
|
struct subnet *subnet;
|
||||||
@@ -44,6 +45,31 @@ static struct subnet *filter_zone(struct auth_zone *zone, int flag, struct all_a
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int in_zone(struct auth_zone *zone, char *name, char **cut)
|
||||||
|
{
|
||||||
|
size_t namelen = strlen(name);
|
||||||
|
size_t domainlen = strlen(zone->domain);
|
||||||
|
|
||||||
|
if (cut)
|
||||||
|
*cut = NULL;
|
||||||
|
|
||||||
|
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];
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t now)
|
size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t now)
|
||||||
@@ -51,12 +77,13 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
char *name = daemon->namebuff;
|
char *name = daemon->namebuff;
|
||||||
unsigned char *p, *ansp;
|
unsigned char *p, *ansp;
|
||||||
int qtype, qclass;
|
int qtype, qclass;
|
||||||
unsigned int nameoffset;
|
int nameoffset, axfroffset = 0;
|
||||||
int q, anscount = 0, authcount = 0;
|
int q, anscount = 0, authcount = 0;
|
||||||
struct crec *crecp;
|
struct crec *crecp;
|
||||||
int auth = 1, trunc = 0, nxdomain = 1, soa = 0, ns = 0;
|
int auth = 1, trunc = 0, nxdomain = 1, soa = 0, ns = 0, axfr = 0;
|
||||||
struct auth_zone *zone = NULL;
|
struct auth_zone *zone = NULL;
|
||||||
struct subnet *subnet = NULL;
|
struct subnet *subnet = NULL;
|
||||||
|
char *cut;
|
||||||
|
|
||||||
if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY )
|
if (ntohs(header->qdcount) == 0 || OPCODE(header) != QUERY )
|
||||||
return 0;
|
return 0;
|
||||||
@@ -70,7 +97,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
|
|
||||||
for (q = ntohs(header->qdcount); q != 0; q--)
|
for (q = ntohs(header->qdcount); q != 0; q--)
|
||||||
{
|
{
|
||||||
size_t domainlen, namelen;
|
|
||||||
unsigned short flag = 0;
|
unsigned short flag = 0;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
struct mx_srv_record *rec, *move, **up;
|
struct mx_srv_record *rec, *move, **up;
|
||||||
@@ -108,8 +134,6 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
domainlen = strlen(zone->domain);
|
|
||||||
|
|
||||||
if (flag == F_IPV4)
|
if (flag == F_IPV4)
|
||||||
{
|
{
|
||||||
for (intr = daemon->int_names; intr; intr = intr->next)
|
for (intr = daemon->int_names; intr; intr = intr->next)
|
||||||
@@ -123,10 +147,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
|
|
||||||
if (intr)
|
if (intr)
|
||||||
{
|
{
|
||||||
namelen = strlen(intr->name);
|
if (in_zone(zone, intr->name, NULL))
|
||||||
|
|
||||||
if (namelen >= domainlen && hostname_isequal(zone->domain, &intr->name[namelen - domainlen]) &&
|
|
||||||
(namelen == domainlen || intr->name[namelen - domainlen - 1] == '.'))
|
|
||||||
{
|
{
|
||||||
found = 1;
|
found = 1;
|
||||||
log_query(F_IPV4 | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
|
log_query(F_IPV4 | F_REVERSE | F_CONFIG, intr->name, &addr, NULL);
|
||||||
@@ -158,17 +179,8 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
T_PTR, C_IN, "d", name))
|
T_PTR, C_IN, "d", name))
|
||||||
anscount++;
|
anscount++;
|
||||||
}
|
}
|
||||||
else if (crecp->flags & (F_DHCP | F_HOSTS))
|
else if (crecp->flags & (F_DHCP | F_HOSTS) && in_zone(zone, name, NULL))
|
||||||
{
|
{
|
||||||
namelen = strlen(name);
|
|
||||||
|
|
||||||
if (namelen > domainlen + 1 &&
|
|
||||||
name[namelen - domainlen - 1] != '.')
|
|
||||||
continue;
|
|
||||||
if (namelen < domainlen ||
|
|
||||||
!hostname_isequal(zone->domain, &name[namelen - domainlen]))
|
|
||||||
continue; /* wrong domain */
|
|
||||||
|
|
||||||
log_query(crecp->flags & ~F_FORWARD, name, &addr, record_source(crecp->uid));
|
log_query(crecp->flags & ~F_FORWARD, name, &addr, record_source(crecp->uid));
|
||||||
found = 1;
|
found = 1;
|
||||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||||
@@ -188,16 +200,9 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
}
|
}
|
||||||
|
|
||||||
cname_restart:
|
cname_restart:
|
||||||
namelen = strlen(name);
|
|
||||||
|
|
||||||
for (zone = daemon->auth_zones; zone; zone = zone->next)
|
for (zone = daemon->auth_zones; zone; zone = zone->next)
|
||||||
{
|
if (in_zone(zone, name, &cut))
|
||||||
domainlen = strlen(zone->domain);
|
break;
|
||||||
if (namelen >= domainlen &&
|
|
||||||
hostname_isequal(zone->domain, &name[namelen - domainlen]) &&
|
|
||||||
(namelen == domainlen || name[namelen - domainlen - 1] == '.'))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!zone)
|
if (!zone)
|
||||||
{
|
{
|
||||||
@@ -340,14 +345,23 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
flag = F_IPV6;
|
flag = F_IPV6;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (qtype == T_SOA && namelen == domainlen)
|
if (qtype == T_SOA && !cut)
|
||||||
{
|
{
|
||||||
soa = 1; /* inhibits auth section */
|
soa = 1; /* inhibits auth section */
|
||||||
found = 1;
|
found = 1;
|
||||||
log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<SOA>");
|
log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<SOA>");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qtype == T_NS && namelen == domainlen)
|
if (qtype == T_AXFR && !cut)
|
||||||
|
{
|
||||||
|
soa = 1; /* inhibits auth section */
|
||||||
|
axfr = 1;
|
||||||
|
found = 1;
|
||||||
|
axfroffset = nameoffset;
|
||||||
|
log_query(F_RRNAME | F_AUTH, zone->domain, NULL, "<AXFR>");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (qtype == T_NS && !cut)
|
||||||
{
|
{
|
||||||
ns = 1; /* inhibits auth section */
|
ns = 1; /* inhibits auth section */
|
||||||
found = 1;
|
found = 1;
|
||||||
@@ -355,9 +369,9 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!option_bool(OPT_DHCP_FQDN) && namelen > domainlen + 1)
|
if (!option_bool(OPT_DHCP_FQDN) && cut)
|
||||||
{
|
{
|
||||||
name[namelen - domainlen - 1] = 0; /* remove domain part */
|
*cut = 0; /* remove domain part */
|
||||||
|
|
||||||
if (!strchr(name, '.') && (crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6)))
|
if (!strchr(name, '.') && (crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6)))
|
||||||
{
|
{
|
||||||
@@ -367,9 +381,9 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
nxdomain = 0;
|
nxdomain = 0;
|
||||||
if ((crecp->flags & flag) && filter_zone(zone, flag, &(crecp->addr.addr)))
|
if ((crecp->flags & flag) && filter_zone(zone, flag, &(crecp->addr.addr)))
|
||||||
{
|
{
|
||||||
name[namelen - domainlen - 1] = '.'; /* restore domain part */
|
*cut = '.'; /* restore domain part */
|
||||||
log_query(crecp->flags, name, &crecp->addr.addr, record_source(crecp->uid));
|
log_query(crecp->flags, name, &crecp->addr.addr, record_source(crecp->uid));
|
||||||
name[namelen - domainlen - 1] = 0; /* remove domain part */
|
*cut = 0; /* remove domain part */
|
||||||
found = 1;
|
found = 1;
|
||||||
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
if (add_resource_record(header, limit, &trunc, nameoffset, &ansp,
|
||||||
daemon->auth_ttl, NULL, qtype, C_IN,
|
daemon->auth_ttl, NULL, qtype, C_IN,
|
||||||
@@ -379,7 +393,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
} while ((crecp = cache_find_by_name(crecp, name, now, F_IPV4 | F_IPV6)));
|
} while ((crecp = cache_find_by_name(crecp, name, now, F_IPV4 | F_IPV6)));
|
||||||
}
|
}
|
||||||
|
|
||||||
name[namelen - domainlen - 1] = '.'; /* restore domain part */
|
*cut = '.'; /* restore domain part */
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6)))
|
if ((crecp = cache_find_by_name(NULL, name, now, F_IPV4 | F_IPV6)))
|
||||||
@@ -408,11 +422,16 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
/* Add auth section */
|
/* Add auth section */
|
||||||
if (auth)
|
if (auth)
|
||||||
{
|
{
|
||||||
|
char *authname;
|
||||||
|
|
||||||
if (!subnet)
|
if (!subnet)
|
||||||
name = zone->domain;
|
authname = zone->domain;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* handle NS and SOA for PTR records */
|
/* handle NS and SOA for PTR records */
|
||||||
|
|
||||||
|
authname = name;
|
||||||
|
|
||||||
if (!subnet->is6)
|
if (!subnet->is6)
|
||||||
{
|
{
|
||||||
in_addr_t a = ntohl(subnet->addr4.s_addr) >> 8;
|
in_addr_t a = ntohl(subnet->addr4.s_addr) >> 8;
|
||||||
@@ -447,7 +466,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
/* handle NS and SOA in auth section or for explicit queries */
|
/* handle NS and SOA in auth section or for explicit queries */
|
||||||
if ((anscount != 0 || ns) &&
|
if ((anscount != 0 || ns) &&
|
||||||
add_resource_record(header, limit, &trunc, 0, &ansp,
|
add_resource_record(header, limit, &trunc, 0, &ansp,
|
||||||
daemon->auth_ttl, NULL, T_NS, C_IN, "d", name, daemon->authserver))
|
daemon->auth_ttl, NULL, T_NS, C_IN, "d", authname, daemon->authserver))
|
||||||
{
|
{
|
||||||
if (ns)
|
if (ns)
|
||||||
anscount++;
|
anscount++;
|
||||||
@@ -458,7 +477,7 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
if ((anscount == 0 || soa) &&
|
if ((anscount == 0 || 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",
|
daemon->auth_ttl, NULL, T_SOA, C_IN, "ddlllll",
|
||||||
name, daemon->authserver, daemon->hostmaster,
|
authname, daemon->authserver, daemon->hostmaster,
|
||||||
daemon->soa_sn, daemon->soa_refresh,
|
daemon->soa_sn, daemon->soa_refresh,
|
||||||
daemon->soa_retry, daemon->soa_expiry,
|
daemon->soa_retry, daemon->soa_expiry,
|
||||||
daemon->auth_ttl))
|
daemon->auth_ttl))
|
||||||
@@ -468,6 +487,74 @@ size_t answer_auth(struct dns_header *header, char *limit, size_t qlen, time_t n
|
|||||||
else
|
else
|
||||||
authcount++;
|
authcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (axfr)
|
||||||
|
{
|
||||||
|
cache_enumerate(1);
|
||||||
|
while ((crecp = cache_enumerate(0)))
|
||||||
|
{
|
||||||
|
if ((crecp->flags & (F_IPV4 | F_IPV6)) &&
|
||||||
|
!(crecp->flags & (F_NEG | F_NXDOMAIN)) &&
|
||||||
|
(crecp->flags & F_FORWARD))
|
||||||
|
{
|
||||||
|
if ((crecp->flags & F_DHCP) && !option_bool(OPT_DHCP_FQDN))
|
||||||
|
{
|
||||||
|
char *cache_name = cache_get_name(crecp);
|
||||||
|
if (!strchr(cache_name, '.') && filter_zone(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr.addr)))
|
||||||
|
{
|
||||||
|
qtype = T_A;
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
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,
|
||||||
|
(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) && filter_zone(zone, (crecp->flags & (F_IPV6 | F_IPV4)), &(crecp->addr.addr)))
|
||||||
|
{
|
||||||
|
qtype = T_A;
|
||||||
|
#ifdef HAVE_IPV6
|
||||||
|
if (crecp->flags & F_IPV6)
|
||||||
|
qtype = T_AAAA;
|
||||||
|
#endif
|
||||||
|
if (cut)
|
||||||
|
{
|
||||||
|
*cut = 0;
|
||||||
|
if (add_resource_record(header, limit, &trunc, -axfroffset, &ansp,
|
||||||
|
daemon->auth_ttl, NULL, qtype, C_IN,
|
||||||
|
(crecp->flags & F_IPV4) ? "4" : "6", name, &crecp->addr))
|
||||||
|
anscount++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (add_resource_record(header, limit, &trunc, axfroffset, &ansp,
|
||||||
|
daemon->auth_ttl, NULL, qtype, C_IN,
|
||||||
|
(crecp->flags & F_IPV4) ? "4" : "6", &crecp->addr))
|
||||||
|
anscount++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* repeat SOA as last record */
|
||||||
|
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->auth_ttl))
|
||||||
|
anscount++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* done all questions, set up header and return length of result */
|
/* done all questions, set up header and return length of result */
|
||||||
|
|||||||
23
src/cache.c
23
src/cache.c
@@ -235,6 +235,29 @@ char *cache_get_name(struct crec *crecp)
|
|||||||
return crecp->name.sname;
|
return crecp->name.sname;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct crec *cache_enumerate(int init)
|
||||||
|
{
|
||||||
|
static int bucket;
|
||||||
|
static struct crec *cache;
|
||||||
|
|
||||||
|
if (init)
|
||||||
|
{
|
||||||
|
bucket = 0;
|
||||||
|
cache = NULL;
|
||||||
|
}
|
||||||
|
else if (cache && cache->hash_next)
|
||||||
|
cache = cache->hash_next;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cache = NULL;
|
||||||
|
while (bucket < hash_size)
|
||||||
|
if ((cache = hash_table[bucket++]))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return cache;
|
||||||
|
}
|
||||||
|
|
||||||
static int is_outdated_cname_pointer(struct crec *crecp)
|
static int is_outdated_cname_pointer(struct crec *crecp)
|
||||||
{
|
{
|
||||||
if (!(crecp->flags & F_CNAME))
|
if (!(crecp->flags & F_CNAME))
|
||||||
|
|||||||
@@ -52,6 +52,7 @@
|
|||||||
#define T_OPT 41
|
#define T_OPT 41
|
||||||
#define T_TKEY 249
|
#define T_TKEY 249
|
||||||
#define T_TSIG 250
|
#define T_TSIG 250
|
||||||
|
#define T_AXFR 252
|
||||||
#define T_MAILB 253
|
#define T_MAILB 253
|
||||||
#define T_ANY 255
|
#define T_ANY 255
|
||||||
|
|
||||||
|
|||||||
@@ -870,6 +870,7 @@ struct in_addr a_record_from_hosts(char *name, time_t now);
|
|||||||
void cache_unhash_dhcp(void);
|
void cache_unhash_dhcp(void);
|
||||||
void dump_cache(time_t now);
|
void dump_cache(time_t now);
|
||||||
char *cache_get_name(struct crec *crecp);
|
char *cache_get_name(struct crec *crecp);
|
||||||
|
struct crec *cache_enumerate(int init);
|
||||||
char *get_domain(struct in_addr addr);
|
char *get_domain(struct in_addr addr);
|
||||||
#ifdef HAVE_IPV6
|
#ifdef HAVE_IPV6
|
||||||
char *get_domain6(struct in6_addr *addr);
|
char *get_domain6(struct in6_addr *addr);
|
||||||
@@ -899,7 +900,7 @@ size_t resize_packet(struct dns_header *header, size_t plen,
|
|||||||
unsigned char *pheader, size_t hlen);
|
unsigned char *pheader, size_t hlen);
|
||||||
size_t add_mac(struct dns_header *header, size_t plen, char *limit, union mysockaddr *l3);
|
size_t add_mac(struct dns_header *header, size_t plen, char *limit, union mysockaddr *l3);
|
||||||
int add_resource_record(struct dns_header *header, char *limit, int *truncp,
|
int add_resource_record(struct dns_header *header, char *limit, int *truncp,
|
||||||
unsigned int nameoffset, unsigned char **pp, unsigned long ttl,
|
int nameoffset, unsigned char **pp, unsigned long ttl,
|
||||||
unsigned int *offset, unsigned short type, unsigned short class, char *format, ...);
|
unsigned int *offset, unsigned short type, unsigned short class, char *format, ...);
|
||||||
unsigned char *skip_questions(struct dns_header *header, size_t plen);
|
unsigned char *skip_questions(struct dns_header *header, size_t plen);
|
||||||
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,
|
||||||
|
|||||||
@@ -1185,7 +1185,7 @@ int check_for_bogus_wildcard(struct dns_header *header, size_t qlen, char *name,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int add_resource_record(struct dns_header *header, char *limit, int *truncp, unsigned int nameoffset, unsigned char **pp,
|
int add_resource_record(struct dns_header *header, char *limit, int *truncp, int nameoffset, unsigned char **pp,
|
||||||
unsigned long ttl, unsigned int *offset, unsigned short type, unsigned short class, char *format, ...)
|
unsigned long ttl, unsigned int *offset, unsigned short type, unsigned short class, char *format, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
@@ -1200,14 +1200,19 @@ int add_resource_record(struct dns_header *header, char *limit, int *truncp, uns
|
|||||||
|
|
||||||
va_start(ap, format); /* make ap point to 1st unamed argument */
|
va_start(ap, format); /* make ap point to 1st unamed argument */
|
||||||
|
|
||||||
if (nameoffset != 0)
|
if (nameoffset > 0)
|
||||||
{
|
{
|
||||||
PUTSHORT(nameoffset | 0xc000, p);
|
PUTSHORT(nameoffset | 0xc000, p);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
p = do_rfc1035_name(p, va_arg(ap, char *));
|
p = do_rfc1035_name(p, va_arg(ap, char *));
|
||||||
*p++ = 0;
|
if (nameoffset < 0)
|
||||||
|
{
|
||||||
|
PUTSHORT(-nameoffset | 0xc000, p);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
*p++ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
PUTSHORT(type, p);
|
PUTSHORT(type, p);
|
||||||
@@ -1312,7 +1317,7 @@ size_t answer_request(struct dns_header *header, char *limit, size_t qlen,
|
|||||||
unsigned char *p, *ansp, *pheader;
|
unsigned char *p, *ansp, *pheader;
|
||||||
int qtype, qclass;
|
int qtype, qclass;
|
||||||
struct all_addr addr;
|
struct all_addr addr;
|
||||||
unsigned int nameoffset;
|
int nameoffset;
|
||||||
unsigned short flag;
|
unsigned short flag;
|
||||||
int q, ans, anscount = 0, addncount = 0;
|
int q, ans, anscount = 0, addncount = 0;
|
||||||
int dryrun = 0, sec_reqd = 0;
|
int dryrun = 0, sec_reqd = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user