Added support for MMS connection tracking
[openwrt.git] / package / mtr / patches / 501-dns.patch
1 diff -Naur mtr-0.69.old/dns.c mtr-0.69.new/dns.c
2 --- mtr-0.69.old/dns.c 2005-01-11 09:32:42.000000000 +0100
3 +++ mtr-0.69.new/dns.c 2005-10-03 21:31:27.000000000 +0200
4 @@ -853,6 +853,507 @@
5 fputs("\r",stderr);
6 }
7
8 +#ifdef __UCLIBC__
9 +
10 +static const char digits[] = "0123456789";
11 +#define __set_errno(e) (errno = (e))
12 +
13 +#define NS_PUT16(s, cp) do { \
14 + register u_int16_t t_s = (u_int16_t)(s); \
15 + register u_char *t_cp = (u_char *)(cp); \
16 + *t_cp++ = t_s >> 8; \
17 + *t_cp = t_s; \
18 + (cp) += NS_INT16SZ; \
19 +} while (0)
20 +
21 +
22 +
23 +#define NS_PUT32(l, cp) do { \
24 + register u_int32_t t_l = (u_int32_t)(l); \
25 + register u_char *t_cp = (u_char *)(cp); \
26 + *t_cp++ = t_l >> 24; \
27 + *t_cp++ = t_l >> 16; \
28 + *t_cp++ = t_l >> 8; \
29 + *t_cp = t_l; \
30 + (cp) += NS_INT32SZ; \
31 +} while (0)
32 +
33 +
34 +void
35 +ns_put16(u_int src, u_char *dst) {
36 + NS_PUT16(src, dst);
37 +}
38 +
39 +void
40 +ns_put32(u_long src, u_char *dst) {
41 + NS_PUT32(src, dst);
42 +}
43 +
44 +void __putshort(u_int16_t src, u_char *dst) { ns_put16(src, dst); }
45 +void __putlong(u_int32_t src, u_char *dst) { ns_put32(src, dst); }
46 +
47 +int
48 +mklower(int ch) {
49 + if (ch >= 0x41 && ch <= 0x5A)
50 + return (ch + 0x20);
51 + return (ch);
52 +}
53 +
54 +
55 +static int
56 +dn_find(const u_char *domain, const u_char *msg,
57 + const u_char * const *dnptrs,
58 + const u_char * const *lastdnptr)
59 +{
60 + const u_char *dn, *cp, *sp;
61 + const u_char * const *cpp;
62 + u_int n;
63 +
64 + for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
65 + sp = *cpp;
66 + /*
67 + * terminate search on:
68 + * root label
69 + * compression pointer
70 + * unusable offset
71 + */
72 + while (*sp != 0 && (*sp & NS_CMPRSFLGS) == 0 &&
73 + (sp - msg) < 0x4000) {
74 + dn = domain;
75 + cp = sp;
76 + while ((n = *cp++) != 0) {
77 + /*
78 + * check for indirection
79 + */
80 + switch (n & NS_CMPRSFLGS) {
81 + case 0: /* normal case, n == len */
82 + if (n != *dn++)
83 + goto next;
84 + for ((void)NULL; n > 0; n--)
85 + if (mklower(*dn++) !=
86 + mklower(*cp++))
87 + goto next;
88 + /* Is next root for both ? */
89 + if (*dn == '\0' && *cp == '\0')
90 + return (sp - msg);
91 + if (*dn)
92 + continue;
93 + goto next;
94 +
95 + case NS_CMPRSFLGS: /* indirection */
96 + cp = msg + (((n & 0x3f) << 8) | *cp);
97 + break;
98 +
99 + default: /* illegal type */
100 + __set_errno (EMSGSIZE);
101 + return (-1);
102 + }
103 + }
104 + next:
105 + sp += *sp + 1;
106 + }
107 + }
108 + __set_errno (ENOENT);
109 + return (-1);
110 +}
111 +
112 +
113 +int
114 +ns_name_pack(const u_char *src, u_char *dst, int dstsiz,
115 + const u_char **dnptrs, const u_char **lastdnptr)
116 +{
117 + u_char *dstp;
118 + const u_char **cpp, **lpp, *eob, *msg;
119 + const u_char *srcp;
120 + int n, l, first = 1;
121 +
122 + srcp = src;
123 + dstp = dst;
124 + eob = dstp + dstsiz;
125 + lpp = cpp = NULL;
126 + if (dnptrs != NULL) {
127 + if ((msg = *dnptrs++) != NULL) {
128 + for (cpp = dnptrs; *cpp != NULL; cpp++)
129 + (void)NULL;
130 + lpp = cpp; /* end of list to search */
131 + }
132 + } else
133 + msg = NULL;
134 +
135 + /* make sure the domain we are about to add is legal */
136 + l = 0;
137 + do {
138 + n = *srcp;
139 + if ((n & NS_CMPRSFLGS) != 0 && n != 0x41) {
140 + __set_errno (EMSGSIZE);
141 + return (-1);
142 + }
143 + if (n == 0x41)
144 + n = *++srcp / 8;
145 + l += n + 1;
146 + if (l > MAXCDNAME) {
147 + __set_errno (EMSGSIZE);
148 + return (-1);
149 + }
150 + srcp += n + 1;
151 + } while (n != 0);
152 +
153 + /* from here on we need to reset compression pointer array on error */
154 + srcp = src;
155 + do {
156 + /* Look to see if we can use pointers. */
157 + n = *srcp;
158 + if (n != 0 && n != 0x41 && msg != NULL) {
159 + l = dn_find(srcp, msg, (const u_char * const *)dnptrs,
160 + (const u_char * const *)lpp);
161 + if (l >= 0) {
162 + if (dstp + 1 >= eob) {
163 + goto cleanup;
164 + }
165 + *dstp++ = (l >> 8) | NS_CMPRSFLGS;
166 + *dstp++ = l % 256;
167 + return (dstp - dst);
168 + }
169 + /* Not found, save it. */
170 + if (lastdnptr != NULL && cpp < lastdnptr - 1 &&
171 + (dstp - msg) < 0x4000 && first) {
172 + *cpp++ = dstp;
173 + *cpp = NULL;
174 + first = 0;
175 + }
176 + }
177 + /* copy label to buffer */
178 + if ((n & NS_CMPRSFLGS) != 0 && n != 0x41) { /* Should not happen. */
179 + goto cleanup;
180 + }
181 + if (n == 0x41) {
182 + n = *++srcp / 8;
183 + if (dstp + 1 >= eob)
184 + goto cleanup;
185 + *dstp++ = 0x41;
186 + }
187 + if (dstp + 1 + n >= eob) {
188 + goto cleanup;
189 + }
190 + memcpy(dstp, srcp, n + 1);
191 + srcp += n + 1;
192 + dstp += n + 1;
193 + } while (n != 0);
194 +
195 + if (dstp > eob) {
196 +cleanup:
197 + if (msg != NULL)
198 + *lpp = NULL;
199 + __set_errno (EMSGSIZE);
200 + return (-1);
201 + }
202 + return (dstp - dst);
203 +}
204 +
205 +
206 +int
207 +ns_name_pton(const char *src, u_char *dst, size_t dstsiz) {
208 + u_char *label, *bp, *eom;
209 + int c, n, escaped;
210 + char *cp;
211 +
212 + escaped = 0;
213 + bp = dst;
214 + eom = dst + dstsiz;
215 + label = bp++;
216 +
217 + while ((c = *src++) != 0) {
218 + if (escaped) {
219 + if ((cp = strchr(digits, c)) != NULL) {
220 + n = (cp - digits) * 100;
221 + if ((c = *src++) == 0 ||
222 + (cp = strchr(digits, c)) == NULL) {
223 + __set_errno (EMSGSIZE);
224 + return (-1);
225 + }
226 + n += (cp - digits) * 10;
227 + if ((c = *src++) == 0 ||
228 + (cp = strchr(digits, c)) == NULL) {
229 + __set_errno (EMSGSIZE);
230 + return (-1);
231 + }
232 + n += (cp - digits);
233 + if (n > 255) {
234 + __set_errno (EMSGSIZE);
235 + return (-1);
236 + }
237 + c = n;
238 + } else if (c == '[' && label == bp - 1 && *src == 'x') {
239 + /* Theoretically we would have to handle \[o
240 + as well but we do not since we do not need
241 + it internally. */
242 + *label = 0x41;
243 + label = bp++;
244 + ++src;
245 + while (isxdigit (*src)) {
246 + n = *src > '9' ? *src - 'a' + 10 : *src - '0';
247 + ++src;
248 + if (! isxdigit(*src)) {
249 + __set_errno (EMSGSIZE);
250 + return (-1);
251 + }
252 + n <<= 4;
253 + n += *src > '9' ? *src - 'a' + 10 : *src - '0';
254 + if (bp + 1 >= eom) {
255 + __set_errno (EMSGSIZE);
256 + return (-1);
257 + }
258 + *bp++ = n;
259 + ++src;
260 + }
261 + *label = (bp - label - 1) * 8;
262 + if (*src++ != ']' || *src++ != '.') {
263 + __set_errno (EMSGSIZE);
264 + return (-1);
265 + }
266 + escaped = 0;
267 + label = bp++;
268 + if (bp >= eom) {
269 + __set_errno (EMSGSIZE);
270 + return (-1);
271 + }
272 + continue;
273 + }
274 + escaped = 0;
275 + } else if (c == '\\') {
276 + escaped = 1;
277 + continue;
278 + } else if (c == '.') {
279 + c = (bp - label - 1);
280 + if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */
281 + __set_errno (EMSGSIZE);
282 + return (-1);
283 + }
284 + if (label >= eom) {
285 + __set_errno (EMSGSIZE);
286 + return (-1);
287 + }
288 + *label = c;
289 + /* Fully qualified ? */
290 + if (*src == '\0') {
291 + if (c != 0) {
292 + if (bp >= eom) {
293 + __set_errno (EMSGSIZE);
294 + return (-1);
295 + }
296 + *bp++ = '\0';
297 + }
298 + if ((bp - dst) > MAXCDNAME) {
299 + __set_errno (EMSGSIZE);
300 + return (-1);
301 + }
302 + return (1);
303 + }
304 + if (c == 0 || *src == '.') {
305 + __set_errno (EMSGSIZE);
306 + return (-1);
307 + }
308 + label = bp++;
309 + continue;
310 + }
311 + if (bp >= eom) {
312 + __set_errno (EMSGSIZE);
313 + return (-1);
314 + }
315 + *bp++ = (u_char)c;
316 + }
317 + c = (bp - label - 1);
318 + if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */
319 + __set_errno (EMSGSIZE);
320 + return (-1);
321 + }
322 + if (label >= eom) {
323 + __set_errno (EMSGSIZE);
324 + return (-1);
325 + }
326 + *label = c;
327 + if (c != 0) {
328 + if (bp >= eom) {
329 + __set_errno (EMSGSIZE);
330 + return (-1);
331 + }
332 + *bp++ = 0;
333 + }
334 + if ((bp - dst) > MAXCDNAME) { /* src too big */
335 + __set_errno (EMSGSIZE);
336 + return (-1);
337 + }
338 + return (0);
339 +}
340 +
341 +
342 +
343 +int
344 +ns_name_compress(const char *src, u_char *dst, size_t dstsiz,
345 + const u_char **dnptrs, const u_char **lastdnptr)
346 +{
347 + u_char tmp[NS_MAXCDNAME];
348 +
349 + if (ns_name_pton(src, tmp, sizeof tmp) == -1)
350 + return (-1);
351 + return (ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr));
352 +}
353 +
354 +
355 +int
356 +dn_comp(const char *src, u_char *dst, int dstsiz,
357 + u_char **dnptrs, u_char **lastdnptr)
358 +{
359 + return (ns_name_compress(src, dst, (size_t)dstsiz,
360 + (const u_char **)dnptrs,
361 + (const u_char **)lastdnptr));
362 +}
363 +
364 +
365 +
366 +
367 +int
368 +res_nmkquery(res_state statp,
369 + int op, /* opcode of query */
370 + const char *dname, /* domain name */
371 + int class, int type, /* class and type of query */
372 + const u_char *data, /* resource record data */
373 + int datalen, /* length of data */
374 + const u_char *newrr_in, /* new rr for modify or append */
375 + u_char *buf, /* buffer to put query */
376 + int buflen) /* size of buffer */
377 +{
378 + register HEADER *hp;
379 + register u_char *cp;
380 + register int n;
381 + u_char *dnptrs[20], **dpp, **lastdnptr;
382 +
383 +#ifdef DEBUG
384 + if (statp->options & RES_DEBUG)
385 + printf(";; res_nmkquery(%s, %s, %s, %s)\n",
386 + _res_opcodes[op], dname, p_class(class), p_type(type));
387 +#endif
388 + /*
389 + * Initialize header fields.
390 + */
391 + if ((buf == NULL) || (buflen < HFIXEDSZ))
392 + return (-1);
393 + memset(buf, 0, HFIXEDSZ);
394 + hp = (HEADER *) buf;
395 + /* We randomize the IDs every time. The old code just
396 + incremented by one after the initial randomization which
397 + still predictable if the application does multiple
398 + requests. */
399 +#if 0
400 + hp->id = htons(++statp->id);
401 +#else
402 + hp->id = htons(statp->id);
403 + int randombits;
404 + do
405 + {
406 +#ifdef RANDOM_BITS
407 + RANDOM_BITS (randombits);
408 +#else
409 + struct timeval tv;
410 + gettimeofday (&tv, NULL);
411 + randombits = (tv.tv_sec << 8) ^ tv.tv_usec;
412 +#endif
413 + }
414 + while ((randombits & 0xffff) == 0);
415 + statp->id = (statp->id + randombits) & 0xffff;
416 +#endif
417 + hp->opcode = op;
418 + hp->rd = (statp->options & RES_RECURSE) != 0;
419 + hp->rcode = NOERROR;
420 + cp = buf + HFIXEDSZ;
421 + buflen -= HFIXEDSZ;
422 + dpp = dnptrs;
423 + *dpp++ = buf;
424 + *dpp++ = NULL;
425 + lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
426 + /*
427 + * perform opcode specific processing
428 + */
429 + switch (op) {
430 + case QUERY: /*FALLTHROUGH*/
431 + case NS_NOTIFY_OP:
432 + if ((buflen -= QFIXEDSZ) < 0)
433 + return (-1);
434 + if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
435 + return (-1);
436 + cp += n;
437 + buflen -= n;
438 + __putshort(type, cp);
439 + cp += INT16SZ;
440 + __putshort(class, cp);
441 + cp += INT16SZ;
442 + hp->qdcount = htons(1);
443 + if (op == QUERY || data == NULL)
444 + break;
445 + /*
446 + * Make an additional record for completion domain.
447 + */
448 + buflen -= RRFIXEDSZ;
449 + n = dn_comp((char *)data, cp, buflen, dnptrs, lastdnptr);
450 + if (n < 0)
451 + return (-1);
452 + cp += n;
453 + buflen -= n;
454 + __putshort(T_NULL, cp);
455 + cp += INT16SZ;
456 + __putshort(class, cp);
457 + cp += INT16SZ;
458 + __putlong(0, cp);
459 + cp += INT32SZ;
460 + __putshort(0, cp);
461 + cp += INT16SZ;
462 + hp->arcount = htons(1);
463 + break;
464 +
465 + case IQUERY:
466 + /*
467 + * Initialize answer section
468 + */
469 + if (buflen < 1 + RRFIXEDSZ + datalen)
470 + return (-1);
471 + *cp++ = '\0'; /* no domain name */
472 + __putshort(type, cp);
473 + cp += INT16SZ;
474 + __putshort(class, cp);
475 + cp += INT16SZ;
476 + __putlong(0, cp);
477 + cp += INT32SZ;
478 + __putshort(datalen, cp);
479 + cp += INT16SZ;
480 + if (datalen) {
481 + memcpy(cp, data, datalen);
482 + cp += datalen;
483 + }
484 + hp->ancount = htons(1);
485 + break;
486 +
487 + default:
488 + return (-1);
489 + }
490 + return (cp - buf);
491 +}
492 +
493 +int
494 +res_mkquery(int op, /* opcode of query */
495 + const char *dname, /* domain name */
496 + int class, int type, /* class and type of query */
497 + const u_char *data, /* resource record data */
498 + int datalen, /* length of data */
499 + const u_char *newrr_in, /* new rr for modify or append */
500 + u_char *buf, /* buffer to put query */
501 + int buflen) /* size of buffer */
502 +{
503 + return (res_nmkquery(&_res, op, dname, class, type,
504 + data, datalen,
505 + newrr_in, buf, buflen));
506 +}
507 +
508 +#endif
509
510 void dorequest(char *s,int type,word id)
511 {
This page took 0.072404 seconds and 5 git commands to generate.