... | ... |
@@ -36,14 +36,12 @@ |
36 | 36 |
char* eat_line(char* buffer, unsigned int len) |
37 | 37 |
{ |
38 | 38 |
char* nl; |
39 |
- char c; |
|
40 | 39 |
|
41 | 40 |
/* jku .. replace for search with a library function; not conformant |
42 | 41 |
as I do not care about CR |
43 | 42 |
*/ |
44 | 43 |
nl=(char *)q_memchr( buffer, '\n', len ); |
45 | 44 |
if ( nl ) { |
46 |
- c=* nl; |
|
47 | 45 |
if ( nl + 1 < buffer+len) nl++; |
48 | 46 |
if (( nl+1<buffer+len) && * nl=='\r') nl++; |
49 | 47 |
} else nl=buffer+len; |
... | ... |
@@ -66,7 +66,7 @@ unsigned char* dns_skipname(unsigned char* p, unsigned char* end) |
66 | 66 |
/* normal label */ |
67 | 67 |
p+=*p+1; |
68 | 68 |
} |
69 |
- return (p>end)?0:p; |
|
69 |
+ return (p>=end)?0:p; |
|
70 | 70 |
} |
71 | 71 |
|
72 | 72 |
|
... | ... |
@@ -98,7 +98,7 @@ struct srv_rdata* dns_srv_parser( unsigned char* msg, unsigned char* end, |
98 | 98 |
int len; |
99 | 99 |
|
100 | 100 |
srv=0; |
101 |
- if ((rdata+6)>end) goto error; |
|
101 |
+ if ((rdata+6)>=end) goto error; |
|
102 | 102 |
srv=(struct srv_rdata*)local_malloc(sizeof(struct srv_rdata)); |
103 | 103 |
if (srv==0){ |
104 | 104 |
LOG(L_ERR, "ERROR: dns_srv_parser: out of memory\n"); |
... | ... |
@@ -122,6 +122,73 @@ error: |
122 | 122 |
} |
123 | 123 |
|
124 | 124 |
|
125 |
+/* parses the naptr record into a naptr_rdata structure |
|
126 |
+ * msg - pointer to the dns message |
|
127 |
+ * end - pointer to the end of the message |
|
128 |
+ * rdata - pointer to the rdata part of the naptr answer |
|
129 |
+ * returns 0 on error, or a dyn. alloc'ed naptr_rdata structure */ |
|
130 |
+/* NAPTR rdata format: |
|
131 |
+ * 111111 |
|
132 |
+ * 0123456789012345 |
|
133 |
+ * +----------------+ |
|
134 |
+ * | order | |
|
135 |
+ * |----------------| |
|
136 |
+ * | preference | |
|
137 |
+ * |----------------| |
|
138 |
+ * ~ flags ~ |
|
139 |
+ * | (string) | |
|
140 |
+ * |----------------| |
|
141 |
+ * ~ services ~ |
|
142 |
+ * | (string) | |
|
143 |
+ * |----------------| |
|
144 |
+ * ~ regexp ~ |
|
145 |
+ * | (string) | |
|
146 |
+ * |----------------| |
|
147 |
+ * ~ replacement ~ |
|
148 |
+ | (name) | |
|
149 |
+ * +----------------+ |
|
150 |
+ */ |
|
151 |
+struct naptr_rdata* dns_naptr_parser( unsigned char* msg, unsigned char* end, |
|
152 |
+ unsigned char* rdata) |
|
153 |
+{ |
|
154 |
+ struct naptr_rdata* naptr; |
|
155 |
+ int len; |
|
156 |
+ |
|
157 |
+ naptr = 0; |
|
158 |
+ if ((rdata + 7) >= end) goto error; |
|
159 |
+ naptr=(struct naptr_rdata*)local_malloc(sizeof(struct naptr_rdata)); |
|
160 |
+ if (naptr == 0){ |
|
161 |
+ LOG(L_ERR, "ERROR: dns_naptr_parser: out of memory\n"); |
|
162 |
+ goto error; |
|
163 |
+ } |
|
164 |
+ |
|
165 |
+ memcpy((void*)&naptr->order, rdata, 2); |
|
166 |
+ naptr->order=ntohs(naptr->order); |
|
167 |
+ memcpy((void*)&naptr->pref, rdata + 2, 2); |
|
168 |
+ naptr->pref=ntohs(naptr->pref); |
|
169 |
+ naptr->flags_len = (int)rdata[4]; |
|
170 |
+ if ((rdata + 7 + naptr->flags_len) >= end) goto error; |
|
171 |
+ memcpy((void*)&naptr->flags, rdata + 5, naptr->flags_len); |
|
172 |
+ naptr->services_len = (int)rdata[5 + naptr->flags_len]; |
|
173 |
+ if ((rdata + 7 + naptr->flags_len + naptr->services_len) >= end) goto error; |
|
174 |
+ memcpy((void*)&naptr->services, rdata + 6 + naptr->flags_len, naptr->services_len); |
|
175 |
+ naptr->regexp_len = (int)rdata[6 + naptr->flags_len + naptr->services_len]; |
|
176 |
+ if ((rdata + 7 + naptr->flags_len + naptr->services_len + |
|
177 |
+ naptr->regexp_len) >= end) goto error; |
|
178 |
+ memcpy((void*)&naptr->regexp, rdata + 7 + naptr->flags_len + |
|
179 |
+ naptr->services_len, naptr->regexp_len); |
|
180 |
+ rdata = rdata + 7 + naptr->flags_len + naptr->services_len + |
|
181 |
+ naptr->regexp_len; |
|
182 |
+ if ((len=dn_expand(msg, end, rdata, naptr->repl, MAX_DNS_NAME-1)) == -1) |
|
183 |
+ goto error; |
|
184 |
+ /* add terminating 0 ? (warning: len=compressed name len) */ |
|
185 |
+ return naptr; |
|
186 |
+error: |
|
187 |
+ if (naptr) local_free(naptr); |
|
188 |
+ return 0; |
|
189 |
+} |
|
190 |
+ |
|
191 |
+ |
|
125 | 192 |
|
126 | 193 |
/* parses a CNAME record into a cname_rdata structure */ |
127 | 194 |
struct cname_rdata* dns_cname_parser( unsigned char* msg, unsigned char* end, |
... | ... |
@@ -153,7 +220,7 @@ struct a_rdata* dns_a_parser(unsigned char* rdata, unsigned char* end) |
153 | 220 |
{ |
154 | 221 |
struct a_rdata* a; |
155 | 222 |
|
156 |
- if (rdata+4>end) goto error; |
|
223 |
+ if (rdata+4>=end) goto error; |
|
157 | 224 |
a=(struct a_rdata*)local_malloc(sizeof(struct a_rdata)); |
158 | 225 |
if (a==0){ |
159 | 226 |
LOG(L_ERR, "ERROR: dns_a_parser: out of memory\n"); |
... | ... |
@@ -173,7 +240,7 @@ struct aaaa_rdata* dns_aaaa_parser(unsigned char* rdata, unsigned char* end) |
173 | 240 |
{ |
174 | 241 |
struct aaaa_rdata* aaaa; |
175 | 242 |
|
176 |
- if (rdata+16>end) goto error; |
|
243 |
+ if (rdata+16>=end) goto error; |
|
177 | 244 |
aaaa=(struct aaaa_rdata*)local_malloc(sizeof(struct aaaa_rdata)); |
178 | 245 |
if (aaaa==0){ |
179 | 246 |
LOG(L_ERR, "ERROR: dns_aaaa_parser: out of memory\n"); |
... | ... |
@@ -224,8 +291,6 @@ struct rdata* get_record(char* name, int type) |
224 | 291 |
struct srv_rdata* srv_rd; |
225 | 292 |
struct srv_rdata* crt_srv; |
226 | 293 |
|
227 |
- |
|
228 |
- |
|
229 | 294 |
size=res_search(name, C_IN, type, buff.buff, sizeof(buff)); |
230 | 295 |
if (size<0) { |
231 | 296 |
DBG("get_record: lookup(%s, %d) failed\n", name, type); |
... | ... |
@@ -237,7 +302,7 @@ struct rdata* get_record(char* name, int type) |
237 | 302 |
|
238 | 303 |
p=buff.buff+DNS_HDR_SIZE; |
239 | 304 |
end=buff.buff+size; |
240 |
- if (p>end) goto error_boundary; |
|
305 |
+ if (p>=end) goto error_boundary; |
|
241 | 306 |
qno=ntohs((unsigned short)buff.hdr.qdcount); |
242 | 307 |
|
243 | 308 |
for (r=0; r<qno; r++){ |
... | ... |
@@ -251,8 +316,8 @@ struct rdata* get_record(char* name, int type) |
251 | 316 |
for (;(p<end && (*p)); p++); |
252 | 317 |
p+=1+2+2; /* skip the ending '\0, QCODE and QCLASS */ |
253 | 318 |
#endif |
254 |
- if (p>end) { |
|
255 |
- LOG(L_ERR, "ERROR: get_record: p>end\n"); |
|
319 |
+ if (p>=end) { |
|
320 |
+ LOG(L_ERR, "ERROR: get_record: p>=end\n"); |
|
256 | 321 |
goto error; |
257 | 322 |
} |
258 | 323 |
}; |
... | ... |
@@ -269,8 +334,8 @@ struct rdata* get_record(char* name, int type) |
269 | 334 |
skip=dn_expand(buff.buff, end, p, t, ans_len); |
270 | 335 |
p+=skip; |
271 | 336 |
*/ |
272 |
- /* check if enough space is left fot type, class, ttl & size */ |
|
273 |
- if ((p+2+2+4+2)>end) goto error_boundary; |
|
337 |
+ /* check if enough space is left for type, class, ttl & size */ |
|
338 |
+ if ((p+2+2+4+2)>=end) goto error_boundary; |
|
274 | 339 |
/* get type */ |
275 | 340 |
memcpy((void*) &rtype, (void*)p, 2); |
276 | 341 |
rtype=ntohs(rtype); |
... | ... |
@@ -348,6 +413,12 @@ struct rdata* get_record(char* name, int type) |
348 | 413 |
*last=rd; |
349 | 414 |
last=&(rd->next); |
350 | 415 |
break; |
416 |
+ case T_NAPTR: |
|
417 |
+ rd->rdata=(void*) dns_naptr_parser(buff.buff, end, p); |
|
418 |
+ if(rd->rdata==0) goto error_parse; |
|
419 |
+ *last=rd; |
|
420 |
+ last=&(rd->next); |
|
421 |
+ break; |
|
351 | 422 |
default: |
352 | 423 |
LOG(L_ERR, "WARNING: get_record: unknown type %d\n", rtype); |
353 | 424 |
rd->rdata=0; |
... | ... |
@@ -44,6 +44,7 @@ |
44 | 44 |
#define ANS_SIZE 8192 |
45 | 45 |
#define DNS_HDR_SIZE 12 |
46 | 46 |
#define MAX_DNS_NAME 256 |
47 |
+#define MAX_DNS_STRING 255 |
|
47 | 48 |
|
48 | 49 |
|
49 | 50 |
|
... | ... |
@@ -73,6 +74,20 @@ struct srv_rdata { |
73 | 74 |
char name[MAX_DNS_NAME]; |
74 | 75 |
}; |
75 | 76 |
|
77 |
+/* naptr rec. struct*/ |
|
78 |
+struct naptr_rdata { |
|
79 |
+ unsigned short order; |
|
80 |
+ unsigned short pref; |
|
81 |
+ unsigned int flags_len; |
|
82 |
+ char flags[MAX_DNS_STRING]; |
|
83 |
+ unsigned int services_len; |
|
84 |
+ char services[MAX_DNS_STRING]; |
|
85 |
+ unsigned int regexp_len; |
|
86 |
+ char regexp[MAX_DNS_STRING]; |
|
87 |
+ unsigned int repl_len; /* not currently used */ |
|
88 |
+ char repl[MAX_DNS_NAME]; |
|
89 |
+}; |
|
90 |
+ |
|
76 | 91 |
|
77 | 92 |
/* A rec. struct */ |
78 | 93 |
struct a_rdata { |