112
static int dns_name_decode(uint8_t *buf, size_t size, char **rname,
121
bsize = min(size, DNS_NAME_MAX_SIZE);
139
if ((lsize & 0xc0) == 0xc0) {
141
printf("compression not supported!\n");
149
for (i = 0; i < lsize; i++) {
158
*act_size = bp - buf;
162
/** Decode unaligned big-endian 16-bit integer */
163
static uint16_t dns_uint16_t_decode(uint8_t *buf, size_t buf_size)
165
assert(buf_size >= 2);
167
return ((uint16_t)buf[0] << 8) + buf[1];
170
/** Encode unaligned big-endian 16-bit integer */
111
171
static void dns_uint16_t_encode(uint16_t w, uint8_t *buf, size_t buf_size)
113
173
if (buf != NULL && buf_size >= 1)
117
177
buf[1] = w & 0xff;
180
/** Decode unaligned big-endian 32-bit integer */
181
static uint16_t dns_uint32_t_decode(uint8_t *buf, size_t buf_size)
183
assert(buf_size >= 4);
185
return ((uint32_t)buf[0] << 24) +
186
((uint32_t)buf[1] << 16) +
187
((uint32_t)buf[2] << 8) +
120
191
static int dns_question_encode(dns_question_t *question, uint8_t *buf,
121
192
size_t buf_size, size_t *act_size)
220
static int dns_question_decode(uint8_t *buf, size_t buf_size,
221
dns_question_t **rquestion, size_t *act_size)
223
dns_question_t *question;
227
question = calloc(1, sizeof (dns_question_t));
228
if (question == NULL)
231
printf("decode name..\n");
232
rc = dns_name_decode(buf, buf_size, &question->qname, &name_size);
234
printf("error decoding name..\n");
239
printf("ok decoding name..\n");
240
if (name_size + 2 * sizeof(uint16_t) > buf_size) {
241
printf("name_size + 2 * 2 = %d > buf_size = %d\n",
242
name_size + 2 * sizeof(uint16_t), buf_size);
247
question->qtype = dns_uint16_t_decode(buf + name_size, buf_size - name_size);
248
question->qclass = dns_uint16_t_decode(buf + sizeof(uint16_t) + name_size,
249
buf_size - sizeof(uint16_t) - name_size);
250
*act_size = name_size + 2 * sizeof(uint16_t);
252
*rquestion = question;
256
static int dns_rr_decode(uint8_t *buf, size_t buf_size,
257
dns_rr_t **retrr, size_t *act_size)
266
rr = calloc(1, sizeof (dns_rr_t));
270
printf("decode name..\n");
271
rc = dns_name_decode(buf, buf_size, &rr->name, &name_size);
273
printf("error decoding name..\n");
278
printf("ok decoding name..\n");
279
if (name_size + 2 * sizeof(uint16_t) > buf_size) {
280
printf("name_size + 2 * 2 = %d > buf_size = %d\n",
281
name_size + 2 * sizeof(uint16_t), buf_size);
287
bp = buf + name_size;
288
bsz = buf_size - name_size;
290
if (bsz < 3 * sizeof(uint16_t) + sizeof(uint32_t)) {
296
rr->rtype = dns_uint16_t_decode(bp, bsz);
297
bp += sizeof(uint16_t); bsz -= sizeof(uint16_t);
299
rr->rclass = dns_uint16_t_decode(bp, bsz);
300
bp += sizeof(uint16_t); bsz -= sizeof(uint16_t);
302
rr->ttl = dns_uint32_t_decode(bp, bsz);
303
bp += sizeof(uint32_t); bsz -= sizeof(uint32_t);
305
rdlength = dns_uint16_t_decode(bp, bsz);
306
bp += sizeof(uint16_t); bsz -= sizeof(uint16_t);
308
if (rdlength > bsz) {
314
rr->rdata_size = rdlength;
315
rr->rdata = calloc(1, sizeof(rdlength));
316
if (rr->rdata == NULL) {
322
memcpy(rr->rdata, bp, rdlength);
326
*act_size = bp - buf;
149
331
int dns_message_encode(dns_message_t *msg, void **rdata, size_t *rsize)
391
int dns_message_decode(void *data, size_t size, dns_message_t **rmsg)
398
dns_question_t *question;
405
msg = calloc(1, sizeof(dns_message_t));
409
if (size < sizeof(dns_header_t))
414
msg->id = uint16_t_be2host(hdr->id);
415
msg->qr = BIT_RANGE_EXTRACT(uint16_t, OPB_QR, OPB_QR, hdr->opbits);
416
msg->opcode = BIT_RANGE_EXTRACT(uint16_t, OPB_OPCODE_h, OPB_OPCODE_l,
418
msg->aa = BIT_RANGE_EXTRACT(uint16_t, OPB_AA, OPB_AA, hdr->opbits);
419
msg->tc = BIT_RANGE_EXTRACT(uint16_t, OPB_TC, OPB_TC, hdr->opbits);
420
msg->rd = BIT_RANGE_EXTRACT(uint16_t, OPB_RD, OPB_RD, hdr->opbits);
421
msg->ra = BIT_RANGE_EXTRACT(uint16_t, OPB_RA, OPB_RA, hdr->opbits);
422
msg->rcode = BIT_RANGE_EXTRACT(uint16_t, OPB_RCODE_h, OPB_RCODE_l,
425
list_initialize(&msg->question);
426
list_initialize(&msg->answer);
427
list_initialize(&msg->authority);
428
list_initialize(&msg->additional);
430
dp = (uint8_t *)data + sizeof(dns_header_t);
431
dsize = size - sizeof(dns_header_t);
433
qd_count = uint16_t_be2host(hdr->qd_count);
434
printf("qd_count = %d\n", (int)qd_count);
436
for (i = 0; i < qd_count; i++) {
437
printf("decode question..\n");
438
rc = dns_question_decode(dp, dsize, &question, &field_size);
440
printf("error decoding question\n");
443
printf("ok decoding question\n");
449
an_count = uint16_t_be2host(hdr->an_count);
450
printf("an_count = %d\n", an_count);
452
for (i = 0; i < an_count; i++) {
453
printf("decode answer..\n");
454
rc = dns_rr_decode(dp, dsize, &rr, &field_size);
456
printf("error decoding answer\n");
459
printf("ok decoding answer\n");
465
printf("ns_count = %d\n", uint16_t_be2host(hdr->ns_count));
466
printf("ar_count = %d\n", uint16_t_be2host(hdr->ar_count));
471
/* XXX Destroy message */