1#include "libc.h"
2#include <resolv.h>
3#include <string.h>
4#include <time.h>
5
6int __res_mkquery(int op, const char* dname, int class, int type, const unsigned char* data,
7                  int datalen, const unsigned char* newrr, unsigned char* buf, int buflen) {
8    int id, i, j;
9    unsigned char q[280];
10    struct timespec ts;
11    size_t l = strnlen(dname, 255);
12    int n;
13
14    if (l && dname[l - 1] == '.')
15        l--;
16    n = 17 + l + !!l;
17    if (l > 253 || buflen < n || op > 15u || class > 255u || type > 255u)
18        return -1;
19
20    /* Construct query template - ID will be filled later */
21    memset(q, 0, n);
22    q[2] = op * 8 + 1;
23    q[5] = 1;
24    memcpy((char*)q + 13, dname, l);
25    for (i = 13; q[i]; i = j + 1) {
26        for (j = i; q[j] && q[j] != '.'; j++)
27            ;
28        if (j - i - 1u > 62u)
29            return -1;
30        q[i - 1] = j - i;
31    }
32    q[i + 1] = type;
33    q[i + 3] = class;
34
35    /* Make a reasonably unpredictable id */
36    clock_gettime(CLOCK_REALTIME, &ts);
37    id = (ts.tv_nsec + ts.tv_nsec / 65536UL) & 0xffff;
38    q[0] = id / 256;
39    q[1] = id;
40
41    memcpy(buf, q, n);
42    return n;
43}
44
45weak_alias(__res_mkquery, res_mkquery);
46