1 #include <string.h>
2 
__dns_parse(const unsigned char * r,int rlen,int (* callback)(void *,int,const void *,int,const void *),void * ctx)3 int __dns_parse(const unsigned char* r, int rlen,
4                 int (*callback)(void*, int, const void*, int, const void*), void* ctx) {
5     int qdcount, ancount;
6     const unsigned char* p;
7     int len;
8 
9     if (rlen < 12)
10         return -1;
11     if ((r[3] & 15))
12         return 0;
13     p = r + 12;
14     qdcount = r[4] * 256 + r[5];
15     ancount = r[6] * 256 + r[7];
16     if (qdcount + ancount > 64)
17         return -1;
18     while (qdcount--) {
19         while (p - r < rlen && *p - 1U < 127)
20             p++;
21         if (*p > 193 || (*p == 193 && p[1] > 254) || p > r + rlen - 6)
22             return -1;
23         p += 5 + !!*p;
24     }
25     while (ancount--) {
26         while (p - r < rlen && *p - 1U < 127)
27             p++;
28         if (*p > 193 || (*p == 193 && p[1] > 254) || p > r + rlen - 6)
29             return -1;
30         p += 1 + !!*p;
31         len = p[8] * 256 + p[9];
32         if (p + len > r + rlen)
33             return -1;
34         if (callback(ctx, p[1], p + 10, len, r) < 0)
35             return -1;
36         p += 10 + len;
37     }
38     return 0;
39 }
40