1#include <string.h>
2
3int __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