Commit | Line | Data |
---|---|---|
dc0d77d7 CE |
1 | #include "error.h" |
2 | #include "alloc.h" | |
3 | #include "byte.h" | |
4 | #include "dns.h" | |
5 | ||
6 | int dns_domain_fromdot(char **out,const char *buf,unsigned int n) | |
7 | { | |
8 | char label[63]; | |
9 | unsigned int labellen = 0; /* <= sizeof label */ | |
10 | char name[255]; | |
11 | unsigned int namelen = 0; /* <= sizeof name */ | |
12 | char ch; | |
13 | char *x; | |
14 | ||
15 | errno = error_proto; | |
16 | ||
17 | for (;;) { | |
18 | if (!n) break; | |
19 | ch = *buf++; --n; | |
20 | if (ch == '.') { | |
21 | if (labellen) { | |
22 | if (namelen + labellen + 1 > sizeof name) return 0; | |
23 | name[namelen++] = labellen; | |
24 | byte_copy(name + namelen,labellen,label); | |
25 | namelen += labellen; | |
26 | labellen = 0; | |
27 | } | |
28 | continue; | |
29 | } | |
30 | if (ch == '\\') { | |
31 | if (!n) break; | |
32 | ch = *buf++; --n; | |
33 | if ((ch >= '0') && (ch <= '7')) { | |
34 | ch -= '0'; | |
35 | if (n && (*buf >= '0') && (*buf <= '7')) { | |
36 | ch <<= 3; | |
37 | ch += *buf - '0'; | |
38 | ++buf; --n; | |
39 | if (n && (*buf >= '0') && (*buf <= '7')) { | |
40 | ch <<= 3; | |
41 | ch += *buf - '0'; | |
42 | ++buf; --n; | |
43 | } | |
44 | } | |
45 | } | |
46 | } | |
47 | if (labellen >= sizeof label) return 0; | |
48 | label[labellen++] = ch; | |
49 | } | |
50 | ||
51 | if (labellen) { | |
52 | if (namelen + labellen + 1 > sizeof name) return 0; | |
53 | name[namelen++] = labellen; | |
54 | byte_copy(name + namelen,labellen,label); | |
55 | namelen += labellen; | |
56 | labellen = 0; | |
57 | } | |
58 | ||
59 | if (namelen + 1 > sizeof name) return 0; | |
60 | name[namelen++] = 0; | |
61 | ||
62 | x = alloc(namelen); | |
63 | if (!x) return 0; | |
64 | byte_copy(x,namelen,name); | |
65 | ||
66 | if (*out) alloc_free(*out); | |
67 | *out = x; | |
68 | return 1; | |
69 | } |