OLD | NEW |
1 #include <string.h> | 1 #include <string.h> |
2 #include <resolv.h> | 2 #include <resolv.h> |
3 #include "libc.h" | 3 #include "libc.h" |
4 | 4 |
5 /* RFC 1035 message compression */ | 5 /* RFC 1035 message compression */ |
6 | 6 |
7 /* label start offsets of a compressed domain name s */ | 7 /* label start offsets of a compressed domain name s */ |
8 static int getoffs(short *offs, const unsigned char *base, const unsigned char *
s) | 8 static int getoffs(short* offs, |
9 { | 9 const unsigned char* base, |
10 » int i=0; | 10 const unsigned char* s) { |
11 » for (;;) { | 11 int i = 0; |
12 » » while (*s & 0xc0) { | 12 for (;;) { |
13 » » » if ((*s & 0xc0) != 0xc0) return 0; | 13 while (*s & 0xc0) { |
14 » » » s = base + ((s[0]&0x3f)<<8 | s[1]); | 14 if ((*s & 0xc0) != 0xc0) |
15 » » } | 15 return 0; |
16 » » if (!*s) return i; | 16 s = base + ((s[0] & 0x3f) << 8 | s[1]); |
17 » » if (s-base >= 0x4000) return 0; | 17 } |
18 » » offs[i++] = s-base; | 18 if (!*s) |
19 » » s += *s + 1; | 19 return i; |
20 » } | 20 if (s - base >= 0x4000) |
| 21 return 0; |
| 22 offs[i++] = s - base; |
| 23 s += *s + 1; |
| 24 } |
21 } | 25 } |
22 | 26 |
23 /* label lengths of an ascii domain name s */ | 27 /* label lengths of an ascii domain name s */ |
24 static int getlens(unsigned char *lens, const char *s, int l) | 28 static int getlens(unsigned char* lens, const char* s, int l) { |
25 { | 29 int i = 0, j = 0, k = 0; |
26 » int i=0,j=0,k=0; | 30 for (;;) { |
27 » for (;;) { | 31 for (; j < l && s[j] != '.'; j++) |
28 » » for (; j<l && s[j]!='.'; j++); | 32 ; |
29 » » if (j-k-1u > 62) return 0; | 33 if (j - k - 1u > 62) |
30 » » lens[i++] = j-k; | 34 return 0; |
31 » » if (j==l) return i; | 35 lens[i++] = j - k; |
32 » » k = ++j; | 36 if (j == l) |
33 » } | 37 return i; |
| 38 k = ++j; |
| 39 } |
34 } | 40 } |
35 | 41 |
36 /* longest suffix match of an ascii domain with a compressed domain name dn */ | 42 /* longest suffix match of an ascii domain with a compressed domain name dn */ |
37 static int match(int *offset, const unsigned char *base, const unsigned char *dn
, | 43 static int match(int* offset, |
38 » const char *end, const unsigned char *lens, int nlen) | 44 const unsigned char* base, |
39 { | 45 const unsigned char* dn, |
40 » int l, o, m=0; | 46 const char* end, |
41 » short offs[128]; | 47 const unsigned char* lens, |
42 » int noff = getoffs(offs, base, dn); | 48 int nlen) { |
43 » if (!noff) return 0; | 49 int l, o, m = 0; |
44 » for (;;) { | 50 short offs[128]; |
45 » » l = lens[--nlen]; | 51 int noff = getoffs(offs, base, dn); |
46 » » o = offs[--noff]; | 52 if (!noff) |
47 » » end -= l; | 53 return 0; |
48 » » if (l != base[o] || memcmp(base+o+1, end, l)) | 54 for (;;) { |
49 » » » return m; | 55 l = lens[--nlen]; |
50 » » *offset = o; | 56 o = offs[--noff]; |
51 » » m += l; | 57 end -= l; |
52 » » if (nlen) m++; | 58 if (l != base[o] || memcmp(base + o + 1, end, l)) |
53 » » if (!nlen || !noff) return m; | 59 return m; |
54 » » end--; | 60 *offset = o; |
55 » } | 61 m += l; |
| 62 if (nlen) |
| 63 m++; |
| 64 if (!nlen || !noff) |
| 65 return m; |
| 66 end--; |
| 67 } |
56 } | 68 } |
57 | 69 |
58 int __dn_comp(const char *src, unsigned char *dst, int space, unsigned char **dn
ptrs, unsigned char **lastdnptr) | 70 int __dn_comp(const char* src, |
59 { | 71 unsigned char* dst, |
60 » int i, j, n, m=0, offset, bestlen=0, bestoff; | 72 int space, |
61 » unsigned char lens[127]; | 73 unsigned char** dnptrs, |
62 » unsigned char **p; | 74 unsigned char** lastdnptr) { |
63 » const char *end; | 75 int i, j, n, m = 0, offset, bestlen = 0, bestoff; |
64 » size_t l = strnlen(src, 255); | 76 unsigned char lens[127]; |
65 » if (l && src[l-1] == '.') l--; | 77 unsigned char** p; |
66 » if (l>253 || space<=0) return -1; | 78 const char* end; |
67 » if (!l) { | 79 size_t l = strnlen(src, 255); |
68 » » *dst = 0; | 80 if (l && src[l - 1] == '.') |
69 » » return 1; | 81 l--; |
70 » } | 82 if (l > 253 || space <= 0) |
71 » end = src+l; | 83 return -1; |
72 » n = getlens(lens, src, l); | 84 if (!l) { |
73 » if (!n) return -1; | 85 *dst = 0; |
| 86 return 1; |
| 87 } |
| 88 end = src + l; |
| 89 n = getlens(lens, src, l); |
| 90 if (!n) |
| 91 return -1; |
74 | 92 |
75 » p = dnptrs; | 93 p = dnptrs; |
76 » if (p && *p) for (p++; *p; p++) { | 94 if (p && *p) |
77 » » m = match(&offset, *dnptrs, *p, end, lens, n); | 95 for (p++; *p; p++) { |
78 » » if (m > bestlen) { | 96 m = match(&offset, *dnptrs, *p, end, lens, n); |
79 » » » bestlen = m; | 97 if (m > bestlen) { |
80 » » » bestoff = offset; | 98 bestlen = m; |
81 » » » if (m == l) | 99 bestoff = offset; |
82 » » » » break; | 100 if (m == l) |
83 » » } | 101 break; |
84 » } | 102 } |
| 103 } |
85 | 104 |
86 » /* encode unmatched part */ | 105 /* encode unmatched part */ |
87 » if (space < l-bestlen+2+(bestlen-1 < l-1)) return -1; | 106 if (space < l - bestlen + 2 + (bestlen - 1 < l - 1)) |
88 » memcpy(dst+1, src, l-bestlen); | 107 return -1; |
89 » for (i=j=0; i<l-bestlen; i+=lens[j++]+1) | 108 memcpy(dst + 1, src, l - bestlen); |
90 » » dst[i] = lens[j]; | 109 for (i = j = 0; i < l - bestlen; i += lens[j++] + 1) |
| 110 dst[i] = lens[j]; |
91 | 111 |
92 » /* add tail */ | 112 /* add tail */ |
93 » if (bestlen) { | 113 if (bestlen) { |
94 » » dst[i++] = 0xc0 | bestoff>>8; | 114 dst[i++] = 0xc0 | bestoff >> 8; |
95 » » dst[i++] = bestoff; | 115 dst[i++] = bestoff; |
96 » } else | 116 } else |
97 » » dst[i++] = 0; | 117 dst[i++] = 0; |
98 | 118 |
99 » /* save dst pointer */ | 119 /* save dst pointer */ |
100 » if (i>2 && lastdnptr && dnptrs && *dnptrs) { | 120 if (i > 2 && lastdnptr && dnptrs && *dnptrs) { |
101 » » while (*p) p++; | 121 while (*p) |
102 » » if (p+1 < lastdnptr) { | 122 p++; |
103 » » » *p++ = dst; | 123 if (p + 1 < lastdnptr) { |
104 » » » *p=0; | 124 *p++ = dst; |
105 » » } | 125 *p = 0; |
106 » } | 126 } |
107 » return i; | 127 } |
| 128 return i; |
108 } | 129 } |
109 | 130 |
110 weak_alias(__dn_comp, dn_comp); | 131 weak_alias(__dn_comp, dn_comp); |
OLD | NEW |