501-dns.patch 18 KB

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