1 #include "e.h"
2 #include "byte.h"
3 #include "dns.h"
4
dns_packet_copy(const unsigned char * buf,long long len,long long pos,unsigned char * out,long long outlen)5 long long dns_packet_copy(const unsigned char *buf, long long len, long long pos, unsigned char *out, long long outlen) {
6
7 while (outlen > 0) {
8 if (pos >= len) { errno = EPROTO; return 0; }
9 *out = buf[pos++];
10 ++out; --outlen;
11 }
12 return pos;
13 }
14
dns_packet_skipname(const unsigned char * buf,long long len,long long pos)15 long long dns_packet_skipname(const unsigned char *buf, long long len, long long pos) {
16
17 unsigned char ch;
18
19 for (;;) {
20 if (pos >= len) break;
21 ch = buf[pos++];
22 if (ch >= 192) return pos + 1;
23 if (ch >= 64) break;
24 if (!ch) return pos;
25 pos += ch;
26 }
27
28 errno = EPROTO;
29 return 0;
30 }
31
dns_packet_getname(const unsigned char * buf,long long len,long long pos,unsigned char ** d)32 long long dns_packet_getname(const unsigned char *buf, long long len, long long pos, unsigned char **d) {
33
34 long long loop = 0;
35 long long state = 0;
36 long long firstcompress = 0;
37 long long where;
38 unsigned char ch;
39 unsigned char name[255];
40 long long namelen = 0;
41
42 for (;;) {
43 if (pos >= len) goto PROTO; ch = buf[pos++];
44 if (++loop >= 1000) goto PROTO;
45
46 if (state > 0) {
47 if (namelen + 1 > sizeof name) goto PROTO; name[namelen++] = ch;
48 --state;
49 }
50 else {
51 while (ch >= 192) {
52 where = ch; where -= 192; where <<= 8;
53 if (pos >= len) goto PROTO; ch = buf[pos++];
54 if (!firstcompress) firstcompress = pos;
55 pos = where + ch;
56 if (pos >= len) goto PROTO; ch = buf[pos++];
57 if (++loop >= 1000) goto PROTO;
58 }
59 if (ch >= 64) goto PROTO;
60 if (namelen + 1 > sizeof name) goto PROTO; name[namelen++] = ch;
61 if (!ch) break;
62 state = ch;
63 }
64 }
65
66 if (!dns_domain_copy(d, name)) return 0;
67
68 if (firstcompress) return firstcompress;
69 return pos;
70
71 PROTO:
72 errno = EPROTO;
73 return 0;
74 }
75
dns_packet_getname_static(const unsigned char * buf,long long len,long long pos,unsigned char * name)76 long long dns_packet_getname_static(const unsigned char *buf, long long len, long long pos, unsigned char *name) {
77
78 long long loop = 0;
79 long long state = 0;
80 long long firstcompress = 0;
81 long long where;
82 unsigned char ch;
83 long long namelen = 0;
84
85 byte_zero(name, 256);
86
87 for (;;) {
88 if (pos >= len) goto PROTO; ch = buf[pos++];
89 if (++loop >= 1000) goto PROTO;
90
91 if (state > 0) {
92 if (namelen + 1 > 255) goto PROTO; name[namelen++] = ch;
93 --state;
94 }
95 else {
96 while (ch >= 192) {
97 where = ch; where -= 192; where <<= 8;
98 if (pos >= len) goto PROTO; ch = buf[pos++];
99 if (!firstcompress) firstcompress = pos;
100 pos = where + ch;
101 if (pos >= len) goto PROTO; ch = buf[pos++];
102 if (++loop >= 1000) goto PROTO;
103 }
104 if (ch >= 64) goto PROTO;
105 if (namelen + 1 > 255) goto PROTO; name[namelen++] = ch;
106 if (!ch) break;
107 state = ch;
108 }
109 }
110
111 if (firstcompress) return firstcompress;
112 return pos;
113
114 PROTO:
115 errno = EPROTO;
116 return 0;
117 }
118