forked from abh/djbdns
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprintpacket.c
90 lines (76 loc) · 2.04 KB
/
printpacket.c
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
#include "uint16.h"
#include "uint32.h"
#include "error.h"
#include "byte.h"
#include "dns.h"
#include "printrecord.h"
#include "printpacket.h"
static char *d;
#define X(s) if (!stralloc_cats(out,s)) return 0;
#define NUM(u) if (!stralloc_catulong0(out,u,0)) return 0;
unsigned int printpacket_cat(stralloc *out,char *buf,unsigned int len)
{
uint16 numqueries;
uint16 numanswers;
uint16 numauthority;
uint16 numglue;
unsigned int pos;
char data[12];
uint16 type;
pos = dns_packet_copy(buf,len,0,data,12); if (!pos) return 0;
uint16_unpack_big(data + 4,&numqueries);
uint16_unpack_big(data + 6,&numanswers);
uint16_unpack_big(data + 8,&numauthority);
uint16_unpack_big(data + 10,&numglue);
NUM(len)
X(" bytes, ")
NUM(numqueries)
X("+")
NUM(numanswers)
X("+")
NUM(numauthority)
X("+")
NUM(numglue)
X(" records")
if (data[2] & 128) X(", response")
if (data[2] & 120) X(", weird op")
if (data[2] & 4) X(", authoritative")
if (data[2] & 2) X(", truncated")
if (data[2] & 1) X(", weird rd")
if (data[3] & 128) X(", weird ra")
switch(data[3] & 15) {
case 0: X(", noerror"); break;
case 3: X(", nxdomain"); break;
case 4: X(", notimp"); break;
case 5: X(", refused"); break;
default: X(", weird rcode");
}
if (data[3] & 112) X(", weird z")
X("\n")
while (numqueries) {
--numqueries;
X("query: ")
pos = dns_packet_getname(buf,len,pos,&d); if (!pos) return 0;
pos = dns_packet_copy(buf,len,pos,data,4); if (!pos) return 0;
if (byte_diff(data + 2,2,DNS_C_IN)) {
X("weird class")
}
else {
uint16_unpack_big(data,&type);
NUM(type)
X(" ")
if (!dns_domain_todot_cat(out,d)) return 0;
}
X("\n")
}
for (;;) {
if (numanswers) { --numanswers; X("answer: ") }
else if (numauthority) { --numauthority; X("authority: ") }
else if (numglue) { --numglue; X("additional: ") }
else break;
pos = printrecord_cat(out,buf,len,pos,0,0);
if (!pos) return 0;
}
if (pos != len) { errno = error_proto; return 0; }
return 1;
}