Commit | Line | Data |
---|---|---|
dc0d77d7 CE |
1 | /* |
2 | DNS should have used LZ77 instead of its own sophomoric compression algorithm. | |
3 | */ | |
4 | ||
5 | #include "error.h" | |
6 | #include "dns.h" | |
7 | ||
8 | unsigned int dns_packet_copy(const char *buf,unsigned int len,unsigned int pos,char *out,unsigned int outlen) | |
9 | { | |
10 | while (outlen) { | |
11 | if (pos >= len) { errno = error_proto; return 0; } | |
12 | *out = buf[pos++]; | |
13 | ++out; --outlen; | |
14 | } | |
15 | return pos; | |
16 | } | |
17 | ||
18 | unsigned int dns_packet_skipname(const char *buf,unsigned int len,unsigned int pos) | |
19 | { | |
20 | unsigned char ch; | |
21 | ||
22 | for (;;) { | |
23 | if (pos >= len) break; | |
24 | ch = buf[pos++]; | |
25 | if (ch >= 192) return pos + 1; | |
26 | if (ch >= 64) break; | |
27 | if (!ch) return pos; | |
28 | pos += ch; | |
29 | } | |
30 | ||
31 | errno = error_proto; | |
32 | return 0; | |
33 | } | |
34 | ||
35 | unsigned int dns_packet_getname(const char *buf,unsigned int len,unsigned int pos,char **d) | |
36 | { | |
37 | unsigned int loop = 0; | |
38 | unsigned int state = 0; | |
39 | unsigned int firstcompress = 0; | |
40 | unsigned int where; | |
41 | unsigned char ch; | |
42 | char name[255]; | |
43 | unsigned int namelen = 0; | |
44 | ||
45 | for (;;) { | |
46 | if (pos >= len) goto PROTO; ch = buf[pos++]; | |
47 | if (++loop >= 1000) goto PROTO; | |
48 | ||
49 | if (state) { | |
50 | if (namelen + 1 > sizeof name) goto PROTO; name[namelen++] = ch; | |
51 | --state; | |
52 | } | |
53 | else { | |
54 | while (ch >= 192) { | |
55 | where = ch; where -= 192; where <<= 8; | |
56 | if (pos >= len) goto PROTO; ch = buf[pos++]; | |
57 | if (!firstcompress) firstcompress = pos; | |
58 | pos = where + ch; | |
59 | if (pos >= len) goto PROTO; ch = buf[pos++]; | |
60 | if (++loop >= 1000) goto PROTO; | |
61 | } | |
62 | if (ch >= 64) goto PROTO; | |
63 | if (namelen + 1 > sizeof name) goto PROTO; name[namelen++] = ch; | |
64 | if (!ch) break; | |
65 | state = ch; | |
66 | } | |
67 | } | |
68 | ||
69 | if (!dns_domain_copy(d,name)) return 0; | |
70 | ||
71 | if (firstcompress) return firstcompress; | |
72 | return pos; | |
73 | ||
74 | PROTO: | |
75 | errno = error_proto; | |
76 | return 0; | |
77 | } |