mirror of
https://github.com/pi-hole/dnsmasq.git
synced 2025-12-19 10:18:25 +00:00
import of dnsmasq-2.40.tar.gz
This commit is contained in:
109
src/rfc1035.c
109
src/rfc1035.c
@@ -304,10 +304,10 @@ static unsigned char *skip_name(unsigned char *ansp, HEADER *header, size_t plen
|
||||
|
||||
static unsigned char *skip_questions(HEADER *header, size_t plen)
|
||||
{
|
||||
int q, qdcount = ntohs(header->qdcount);
|
||||
int q;
|
||||
unsigned char *ansp = (unsigned char *)(header+1);
|
||||
|
||||
for (q = 0; q<qdcount; q++)
|
||||
for (q = ntohs(header->qdcount); q != 0; q--)
|
||||
{
|
||||
if (!(ansp = skip_name(ansp, header, plen)))
|
||||
return NULL;
|
||||
@@ -349,7 +349,7 @@ unsigned int questions_crc(HEADER *header, size_t plen, char *name)
|
||||
unsigned int crc = 0xffffffff;
|
||||
unsigned char *p1, *p = (unsigned char *)(header+1);
|
||||
|
||||
for (q = 0; q < ntohs(header->qdcount); q++)
|
||||
for (q = ntohs(header->qdcount); q != 0; q--)
|
||||
{
|
||||
if (!extract_name(header, plen, &p, name, 1))
|
||||
return crc; /* bad packet */
|
||||
@@ -426,7 +426,7 @@ unsigned char *find_pseudoheader(HEADER *header, size_t plen, size_t *len, unsi
|
||||
|
||||
if (header->opcode == QUERY)
|
||||
{
|
||||
for (i = 0; i < ntohs(header->qdcount); i++)
|
||||
for (i = ntohs(header->qdcount); i != 0; i--)
|
||||
{
|
||||
if (!(ansp = skip_name(ansp, header, plen)))
|
||||
return NULL;
|
||||
@@ -496,21 +496,8 @@ static int private_net(struct in_addr addr)
|
||||
((ip_addr & 0xFFF00000) == 0xAC100000) /* 172.16.0.0/12 (private) */ ||
|
||||
((ip_addr & 0xFFFF0000) == 0xA9FE0000) /* 169.254.0.0/16 (zeroconf) */ ;
|
||||
}
|
||||
|
||||
static void dns_doctor(HEADER *header, struct doctor *doctor, struct in_addr *addr)
|
||||
{
|
||||
for (; doctor; doctor = doctor->next)
|
||||
if (is_same_net(doctor->in, *addr, doctor->mask))
|
||||
{
|
||||
addr->s_addr &= ~doctor->mask.s_addr;
|
||||
addr->s_addr |= (doctor->out.s_addr & doctor->mask.s_addr);
|
||||
/* Since we munged the data, the server it came from is no longer authoritative */
|
||||
header->aa = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static int find_soa(HEADER *header, struct doctor *doctor, size_t qlen)
|
||||
static int find_soa(HEADER *header, size_t qlen)
|
||||
{
|
||||
unsigned char *p;
|
||||
int qtype, qclass, rdlen;
|
||||
@@ -522,7 +509,7 @@ static int find_soa(HEADER *header, struct doctor *doctor, size_t qlen)
|
||||
!(p = skip_section(p, ntohs(header->ancount), header, qlen)))
|
||||
return 0; /* bad packet */
|
||||
|
||||
for (i=0; i<ntohs(header->nscount); i++)
|
||||
for (i = ntohs(header->nscount); i != 0; i--)
|
||||
{
|
||||
if (!(p = skip_name(p, header, qlen)))
|
||||
return 0; /* bad packet */
|
||||
@@ -557,8 +544,8 @@ static int find_soa(HEADER *header, struct doctor *doctor, size_t qlen)
|
||||
return 0; /* bad packet */
|
||||
}
|
||||
|
||||
if (doctor)
|
||||
for (i=0; i<ntohs(header->arcount); i++)
|
||||
if (daemon->doctors)
|
||||
for (i = ntohs(header->arcount); i != 0; i--)
|
||||
{
|
||||
if (!(p = skip_name(p, header, qlen)))
|
||||
return 0; /* bad packet */
|
||||
@@ -569,7 +556,24 @@ static int find_soa(HEADER *header, struct doctor *doctor, size_t qlen)
|
||||
GETSHORT(rdlen, p);
|
||||
|
||||
if ((qclass == C_IN) && (qtype == T_A))
|
||||
dns_doctor(header, doctor, (struct in_addr *)p);
|
||||
{
|
||||
struct doctor *doctor;
|
||||
struct in_addr addr;
|
||||
|
||||
/* alignment */
|
||||
memcpy(&addr, p, INADDRSZ);
|
||||
|
||||
for (doctor = daemon->doctors; doctor; doctor = doctor->next)
|
||||
if (is_same_net(doctor->in, addr, doctor->mask))
|
||||
{
|
||||
addr.s_addr &= ~doctor->mask.s_addr;
|
||||
addr.s_addr |= (doctor->out.s_addr & doctor->mask.s_addr);
|
||||
/* Since we munged the data, the server it came from is no longer authoritative */
|
||||
header->aa = 0;
|
||||
memcpy(p, &addr, INADDRSZ);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
p += rdlen;
|
||||
|
||||
@@ -583,11 +587,12 @@ static int find_soa(HEADER *header, struct doctor *doctor, size_t qlen)
|
||||
/* Note that the following code can create CNAME chains that don't point to a real record,
|
||||
either because of lack of memory, or lack of SOA records. These are treated by the cache code as
|
||||
expired and cleaned out that way. */
|
||||
void extract_addresses(HEADER *header, size_t qlen, char *name, time_t now, struct daemon *daemon)
|
||||
void extract_addresses(HEADER *header, size_t qlen, char *name, time_t now)
|
||||
{
|
||||
unsigned char *p, *p1, *endrr;
|
||||
int i, j, qtype, qclass, aqtype, aqclass, ardlen, res, searched_soa = 0;
|
||||
unsigned long ttl = 0;
|
||||
struct all_addr addr;
|
||||
|
||||
cache_start_insert();
|
||||
|
||||
@@ -595,13 +600,13 @@ void extract_addresses(HEADER *header, size_t qlen, char *name, time_t now, stru
|
||||
if (daemon->doctors)
|
||||
{
|
||||
searched_soa = 1;
|
||||
ttl = find_soa(header, daemon->doctors, qlen);
|
||||
ttl = find_soa(header, qlen);
|
||||
}
|
||||
|
||||
/* go through the questions. */
|
||||
p = (unsigned char *)(header+1);
|
||||
|
||||
for (i = 0; i<ntohs(header->qdcount); i++)
|
||||
for (i = ntohs(header->qdcount); i != 0; i--)
|
||||
{
|
||||
int found = 0, cname_count = 5;
|
||||
struct crec *cpp = NULL;
|
||||
@@ -621,7 +626,6 @@ void extract_addresses(HEADER *header, size_t qlen, char *name, time_t now, stru
|
||||
represent them in the cache. */
|
||||
if (qtype == T_PTR)
|
||||
{
|
||||
struct all_addr addr;
|
||||
int name_encoding = in_arpa_name_2_addr(name, &addr);
|
||||
|
||||
if (!name_encoding)
|
||||
@@ -633,7 +637,7 @@ void extract_addresses(HEADER *header, size_t qlen, char *name, time_t now, stru
|
||||
if (!(p1 = skip_questions(header, qlen)))
|
||||
return;
|
||||
|
||||
for (j = 0; j<ntohs(header->ancount); j++)
|
||||
for (j = ntohs(header->ancount); j != 0; j--)
|
||||
{
|
||||
if (!(res = extract_name(header, qlen, &p1, name, 0)))
|
||||
return; /* bad packet */
|
||||
@@ -675,22 +679,29 @@ void extract_addresses(HEADER *header, size_t qlen, char *name, time_t now, stru
|
||||
if (!searched_soa)
|
||||
{
|
||||
searched_soa = 1;
|
||||
ttl = find_soa(header, NULL, qlen);
|
||||
ttl = find_soa(header, qlen);
|
||||
}
|
||||
if (ttl)
|
||||
cache_insert(name, &addr, now, ttl, name_encoding | F_REVERSE | F_NEG | flags);
|
||||
cache_insert(NULL, &addr, now, ttl, name_encoding | F_REVERSE | F_NEG | flags);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* everything other than PTR */
|
||||
struct crec *newc;
|
||||
|
||||
int addrlen;
|
||||
|
||||
if (qtype == T_A)
|
||||
flags |= F_IPV4;
|
||||
{
|
||||
addrlen = INADDRSZ;
|
||||
flags |= F_IPV4;
|
||||
}
|
||||
#ifdef HAVE_IPV6
|
||||
else if (qtype == T_AAAA)
|
||||
flags |= F_IPV6;
|
||||
{
|
||||
addrlen = IN6ADDRSZ;
|
||||
flags |= F_IPV6;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
continue;
|
||||
@@ -701,7 +712,7 @@ void extract_addresses(HEADER *header, size_t qlen, char *name, time_t now, stru
|
||||
if (!(p1 = skip_questions(header, qlen)))
|
||||
return;
|
||||
|
||||
for (j = 0; j<ntohs(header->ancount); j++)
|
||||
for (j = ntohs(header->ancount); j != 0; j--)
|
||||
{
|
||||
if (!(res = extract_name(header, qlen, &p1, name, 0)))
|
||||
return; /* bad packet */
|
||||
@@ -736,9 +747,9 @@ void extract_addresses(HEADER *header, size_t qlen, char *name, time_t now, stru
|
||||
else
|
||||
{
|
||||
found = 1;
|
||||
if (aqtype == T_A)
|
||||
dns_doctor(header, daemon->doctors, (struct in_addr *)p1);
|
||||
newc = cache_insert(name, (struct all_addr *)p1, now, attl, flags | F_FORWARD);
|
||||
/* copy address into aligned storage */
|
||||
memcpy(&addr, p1, addrlen);
|
||||
newc = cache_insert(name, &addr, now, attl, flags | F_FORWARD);
|
||||
if (newc && cpp)
|
||||
{
|
||||
cpp->addr.cname.cache = newc;
|
||||
@@ -759,13 +770,13 @@ void extract_addresses(HEADER *header, size_t qlen, char *name, time_t now, stru
|
||||
if (!searched_soa)
|
||||
{
|
||||
searched_soa = 1;
|
||||
ttl = find_soa(header, NULL, qlen);
|
||||
ttl = find_soa(header, qlen);
|
||||
}
|
||||
/* If there's no SOA to get the TTL from, but there is a CNAME
|
||||
pointing at this, inherit it's TTL */
|
||||
if (ttl || cpp)
|
||||
{
|
||||
newc = cache_insert(name, (struct all_addr *)p, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags);
|
||||
newc = cache_insert(name, NULL, now, ttl ? ttl : cttl, F_FORWARD | F_NEG | flags);
|
||||
if (newc && cpp)
|
||||
{
|
||||
cpp->addr.cname.cache = newc;
|
||||
@@ -860,7 +871,7 @@ size_t setup_reply(HEADER *header, size_t qlen,
|
||||
}
|
||||
|
||||
/* check if name matches local names ie from /etc/hosts or DHCP or local mx names. */
|
||||
int check_for_local_domain(char *name, time_t now, struct daemon *daemon)
|
||||
int check_for_local_domain(char *name, time_t now)
|
||||
{
|
||||
struct crec *crecp;
|
||||
struct mx_srv_record *mx;
|
||||
@@ -906,7 +917,7 @@ int check_for_bogus_wildcard(HEADER *header, size_t qlen, char *name,
|
||||
if (!(p = skip_questions(header, qlen)))
|
||||
return 0; /* bad packet */
|
||||
|
||||
for (i=0; i<ntohs(header->ancount); i++)
|
||||
for (i = ntohs(header->ancount); i != 0; i--)
|
||||
{
|
||||
if (!extract_name(header, qlen, &p, name, 1))
|
||||
return 0; /* bad packet */
|
||||
@@ -1019,7 +1030,7 @@ static int add_resource_record(HEADER *header, char *limit, int *truncp, unsigne
|
||||
}
|
||||
|
||||
/* return zero if we can't answer from cache, or packet size if we can */
|
||||
size_t answer_request(HEADER *header, char *limit, size_t qlen, struct daemon *daemon,
|
||||
size_t answer_request(HEADER *header, char *limit, size_t qlen,
|
||||
struct in_addr local_addr, struct in_addr local_netmask, time_t now)
|
||||
{
|
||||
char *name = daemon->namebuff;
|
||||
@@ -1028,7 +1039,6 @@ size_t answer_request(HEADER *header, char *limit, size_t qlen, struct daemon *d
|
||||
struct all_addr addr;
|
||||
unsigned int nameoffset;
|
||||
unsigned short flag;
|
||||
int qdcount = ntohs(header->qdcount);
|
||||
int q, ans, anscount = 0, addncount = 0;
|
||||
int dryrun = 0, sec_reqd = 0;
|
||||
int is_sign;
|
||||
@@ -1063,7 +1073,7 @@ size_t answer_request(HEADER *header, char *limit, size_t qlen, struct daemon *d
|
||||
dryrun = 1;
|
||||
}
|
||||
|
||||
if (!qdcount || header->opcode != QUERY )
|
||||
if (ntohs(header->qdcount) == 0 || header->opcode != QUERY )
|
||||
return 0;
|
||||
|
||||
for (rec = daemon->mxnames; rec; rec = rec->next)
|
||||
@@ -1077,7 +1087,7 @@ size_t answer_request(HEADER *header, char *limit, size_t qlen, struct daemon *d
|
||||
/* now process each question, answers go in RRs after the question */
|
||||
p = (unsigned char *)(header+1);
|
||||
|
||||
for (q=0; q<qdcount; q++)
|
||||
for (q = ntohs(header->qdcount); q != 0; q--)
|
||||
{
|
||||
/* save pointer to name for copying into answers */
|
||||
nameoffset = p - (unsigned char *)header;
|
||||
@@ -1127,8 +1137,13 @@ size_t answer_request(HEADER *header, char *limit, size_t qlen, struct daemon *d
|
||||
|
||||
if (is_arpa == F_IPV4)
|
||||
for (intr = daemon->int_names; intr; intr = intr->next)
|
||||
if (addr.addr.addr4.s_addr == get_ifaddr(daemon, intr->intr).s_addr)
|
||||
break;
|
||||
{
|
||||
if (addr.addr.addr4.s_addr == get_ifaddr(intr->intr).s_addr)
|
||||
break;
|
||||
else
|
||||
while (intr->next && strcmp(intr->intr, intr->next->intr) == 0)
|
||||
intr = intr->next;
|
||||
}
|
||||
|
||||
if (intr)
|
||||
{
|
||||
@@ -1252,7 +1267,7 @@ size_t answer_request(HEADER *header, char *limit, size_t qlen, struct daemon *d
|
||||
ans = 1;
|
||||
if (!dryrun)
|
||||
{
|
||||
if ((addr.addr.addr4 = get_ifaddr(daemon, intr->intr)).s_addr == (in_addr_t) -1)
|
||||
if ((addr.addr.addr4 = get_ifaddr(intr->intr)).s_addr == (in_addr_t) -1)
|
||||
log_query(F_FORWARD | F_CONFIG | F_IPV4 | F_NEG, name, NULL, 0, NULL, 0);
|
||||
else
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user