1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
#include "header.h"
#include "buffer.h"
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <arpa/inet.h>
uint8_t rescode_to_id(ResultCode code) {
switch(code) {
case NOERROR:
return 0;
case FORMERR:
return 1;
case SERVFAIL:
return 2;
case NXDOMAIN:
return 3;
case NOTIMP:
return 4;
case REFUSED:
return 5;
default:
return 2;
}
}
ResultCode rescode_from_id(uint8_t id) {
switch(id) {
case 0:
return NOERROR;
case 1:
return FORMERR;
case 2:
return SERVFAIL;
case 3:
return NXDOMAIN;
case 4:
return NOTIMP;
case 5:
return REFUSED;
default:
return FORMERR;
}
}
const char* str_from_code(ResultCode code) {
switch(code) {
case NOERROR: return "NOERROR";
case FORMERR: return "FORMERR";
case SERVFAIL: return "SERVFAIL";
case NXDOMAIN: return "NXDOMAIN";
case NOTIMP: return "NOTIMP";
case REFUSED: return "REFUSED";
default: return "????";
}
}
#define MAX(var, max) var = var > max ? max : var;
void read_header(PacketBuffer* buffer, Header* header) {
// memset(header, 0, sizeof(Header));
header->id = buffer_read_short(buffer);
uint8_t a = buffer_read(buffer);
header->recursion_desired = (a & (1 << 0)) > 0;
header->truncated_message = (a & (1 << 1)) > 0;
header->authorative_answer = (a & (1 << 2)) > 0;
header->opcode = (a >> 3) & 0x0F;
header->response = (a & (1 << 7)) > 0;
uint8_t b = buffer_read(buffer);
header->rescode = rescode_from_id(b & 0x0F);
header->checking_disabled = (b & (1 << 4)) > 0;
header->authed_data = (b& (1 << 4)) > 0;
header->z = (b & (1 << 6)) > 0;
header->recursion_available = (b & (1 << 7)) > 0;
header->questions = buffer_read_short(buffer);
header->answers = buffer_read_short(buffer);
header->authoritative_entries = buffer_read_short(buffer);
header->resource_entries = buffer_read_short(buffer);
}
void write_header(PacketBuffer* buffer, Header* header) {
buffer_write_short(buffer, header->id);
buffer_write(buffer,
((uint8_t) header->recursion_desired) |
((uint8_t) header->truncated_message << 1) |
((uint8_t) header->authorative_answer << 2) |
(header->opcode << 3) |
((uint8_t) header->response << 7)
);
buffer_write(buffer,
(rescode_to_id(header->rescode)) |
((uint8_t) header->checking_disabled << 4) |
((uint8_t) header->authed_data << 5) |
((uint8_t) header->z << 6) |
((uint8_t) header->recursion_available << 7)
);
buffer_write_short(buffer, header->questions);
buffer_write_short(buffer, header->answers);
buffer_write_short(buffer, header->authoritative_entries);
buffer_write_short(buffer, header->resource_entries);
}
|