1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18: #if !defined(_LIBC) && !defined(lint)
19: static const char rcsid[] = "$BINDId: ns_name.c,v 8.15 2000/03/30 22:53:46 vixie Exp $";
20: #endif
21:
22: #include <sys/types.h>
23:
24: #include <netinet/in.h>
25: #include <arpa/nameser.h>
26:
27: #include <ctype.h>
28: #include <errno.h>
29: #include <resolv.h>
30: #include <string.h>
31: #include <ctype.h>
32:
33:
34:
35: static const char digits[] = "0123456789";
36:
37:
38:
39: static int special(int);
40: static int printable(int);
41: static int dn_find(const u_char *, const u_char *,
42: const u_char * const *,
43: const u_char * const *);
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56: int
57: ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) {
58: const u_char *cp;
59: char *dn, *eom;
60: u_char c;
61: u_int n;
62:
63: cp = src;
64: dn = dst;
65: eom = dst + dstsiz;
66:
67: while ((n = *cp++) != 0) {
68: if ((n & NS_CMPRSFLGS) != 0 && n != 0x41) {
69:
70: __set_errno (EMSGSIZE);
71: return (-1);
72: }
73: if (dn != dst) {
74: if (dn >= eom) {
75: __set_errno (EMSGSIZE);
76: return (-1);
77: }
78: *dn++ = '.';
79: }
80:
81: if (n == 0x41) {
82: n = *cp++ / 8;
83: if (dn + n * 2 + 4 >= eom) {
84: __set_errno (EMSGSIZE);
85: return (-1);
86: }
87: *dn++ = '\\';
88: *dn++ = '[';
89: *dn++ = 'x';
90:
91: while (n-- > 0) {
92: c = *cp++;
93: unsigned u = c >> 4;
94: *dn++ = u > 9 ? 'a' + u - 10 : '0' + u;
95: u = c & 0xf;
96: *dn++ = u > 9 ? 'a' + u - 10 : '0' + u;
97: }
98:
99: *dn++ = ']';
100: continue;
101: }
102:
103: if (dn + n >= eom) {
104: __set_errno (EMSGSIZE);
105: return (-1);
106: }
107: for ((void)NULL; n > 0; n--) {
108: c = *cp++;
109: if (special(c)) {
110: if (dn + 1 >= eom) {
111: __set_errno (EMSGSIZE);
112: return (-1);
113: }
114: *dn++ = '\\';
115: *dn++ = (char)c;
116: } else if (!printable(c)) {
117: if (dn + 3 >= eom) {
118: __set_errno (EMSGSIZE);
119: return (-1);
120: }
121: *dn++ = '\\';
122: *dn++ = digits[c / 100];
123: *dn++ = digits[(c % 100) / 10];
124: *dn++ = digits[c % 10];
125: } else {
126: if (dn >= eom) {
127: __set_errno (EMSGSIZE);
128: return (-1);
129: }
130: *dn++ = (char)c;
131: }
132: }
133: }
134: if (dn == dst) {
135: if (dn >= eom) {
136: __set_errno (EMSGSIZE);
137: return (-1);
138: }
139: *dn++ = '.';
140: }
141: if (dn >= eom) {
142: __set_errno (EMSGSIZE);
143: return (-1);
144: }
145: *dn++ = '\0';
146: return (dn - dst);
147: }
148: libresolv_hidden_def (ns_name_ntop)
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161: int
162: ns_name_pton(const char *src, u_char *dst, size_t dstsiz) {
163: u_char *label, *bp, *eom;
164: int c, n, escaped;
165: char *cp;
166:
167: escaped = 0;
168: bp = dst;
169: eom = dst + dstsiz;
170: label = bp++;
171:
172: while ((c = *src++) != 0) {
173: if (escaped) {
174: if ((cp = strchr(digits, c)) != NULL) {
175: n = (cp - digits) * 100;
176: if ((c = *src++) == 0 ||
177: (cp = strchr(digits, c)) == NULL) {
178: __set_errno (EMSGSIZE);
179: return (-1);
180: }
181: n += (cp - digits) * 10;
182: if ((c = *src++) == 0 ||
183: (cp = strchr(digits, c)) == NULL) {
184: __set_errno (EMSGSIZE);
185: return (-1);
186: }
187: n += (cp - digits);
188: if (n > 255) {
189: __set_errno (EMSGSIZE);
190: return (-1);
191: }
192: c = n;
193: } else if (c == '[' && label == bp - 1 && *src == 'x') {
194:
195:
196:
197: *label = 0x41;
198: label = bp++;
199: ++src;
200: while (isxdigit (*src)) {
201: n = *src > '9' ? *src - 'a' + 10 : *src - '0';
202: ++src;
203: if (! isxdigit(*src)) {
204: __set_errno (EMSGSIZE);
205: return (-1);
206: }
207: n <<= 4;
208: n += *src > '9' ? *src - 'a' + 10 : *src - '0';
209: if (bp + 1 >= eom) {
210: __set_errno (EMSGSIZE);
211: return (-1);
212: }
213: *bp++ = n;
214: ++src;
215: }
216: *label = (bp - label - 1) * 8;
217: if (*src++ != ']' || *src++ != '.') {
218: __set_errno (EMSGSIZE);
219: return (-1);
220: }
221: escaped = 0;
222: label = bp++;
223: if (bp >= eom) {
224: __set_errno (EMSGSIZE);
225: return (-1);
226: }
227: continue;
228: }
229: escaped = 0;
230: } else if (c == '\\') {
231: escaped = 1;
232: continue;
233: } else if (c == '.') {
234: c = (bp - label - 1);
235: if ((c & NS_CMPRSFLGS) != 0) {
236: __set_errno (EMSGSIZE);
237: return (-1);
238: }
239: if (label >= eom) {
240: __set_errno (EMSGSIZE);
241: return (-1);
242: }
243: *label = c;
244:
245: if (*src == '\0') {
246: if (c != 0) {
247: if (bp >= eom) {
248: __set_errno (EMSGSIZE);
249: return (-1);
250: }
251: *bp++ = '\0';
252: }
253: if ((bp - dst) > MAXCDNAME) {
254: __set_errno (EMSGSIZE);
255: return (-1);
256: }
257: return (1);
258: }
259: if (c == 0 || *src == '.') {
260: __set_errno (EMSGSIZE);
261: return (-1);
262: }
263: label = bp++;
264: continue;
265: }
266: if (bp >= eom) {
267: __set_errno (EMSGSIZE);
268: return (-1);
269: }
270: *bp++ = (u_char)c;
271: }
272: c = (bp - label - 1);
273: if ((c & NS_CMPRSFLGS) != 0) {
274: __set_errno (EMSGSIZE);
275: return (-1);
276: }
277: if (label >= eom) {
278: __set_errno (EMSGSIZE);
279: return (-1);
280: }
281: *label = c;
282: if (c != 0) {
283: if (bp >= eom) {
284: __set_errno (EMSGSIZE);
285: return (-1);
286: }
287: *bp++ = 0;
288: }
289: if ((bp - dst) > MAXCDNAME) {
290: __set_errno (EMSGSIZE);
291: return (-1);
292: }
293: return (0);
294: }
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305: int
306: ns_name_ntol(const u_char *src, u_char *dst, size_t dstsiz) {
307: const u_char *cp;
308: u_char *dn, *eom;
309: u_char c;
310: u_int n;
311:
312: cp = src;
313: dn = dst;
314: eom = dst + dstsiz;
315:
316: while ((n = *cp++) != 0) {
317: if ((n & NS_CMPRSFLGS) != 0) {
318:
319: __set_errno (EMSGSIZE);
320: return (-1);
321: }
322: *dn++ = n;
323: if (dn + n >= eom) {
324: __set_errno (EMSGSIZE);
325: return (-1);
326: }
327: for ((void)NULL; n > 0; n--) {
328: c = *cp++;
329: if (isupper(c))
330: *dn++ = tolower(c);
331: else
332: *dn++ = c;
333: }
334: }
335: *dn++ = '\0';
336: return (dn - dst);
337: }
338:
339:
340:
341:
342:
343:
344:
345: int
346: ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
347: u_char *dst, size_t dstsiz)
348: {
349: const u_char *srcp, *dstlim;
350: u_char *dstp;
351: int n, len, checked;
352:
353: len = -1;
354: checked = 0;
355: dstp = dst;
356: srcp = src;
357: dstlim = dst + dstsiz;
358: if (srcp < msg || srcp >= eom) {
359: __set_errno (EMSGSIZE);
360: return (-1);
361: }
362:
363: while ((n = *srcp++) != 0) {
364:
365: switch (n & NS_CMPRSFLGS) {
366: case 0x40:
367: if (n == 0x41) {
368: if (dstp + 1 >= dstlim) {
369: __set_errno (EMSGSIZE);
370: return (-1);
371: }
372: *dstp++ = 0x41;
373: n = *srcp++ / 8;
374: ++checked;
375: } else {
376: __set_errno (EMSGSIZE);
377: return (-1);
378: }
379:
380: case 0:
381:
382: if (dstp + n + 1 >= dstlim || srcp + n >= eom) {
383: __set_errno (EMSGSIZE);
384: return (-1);
385: }
386: checked += n + 1;
387: dstp = mempcpy(dstp, srcp - 1, n + 1);
388: srcp += n;
389: break;
390:
391: case NS_CMPRSFLGS:
392: if (srcp >= eom) {
393: __set_errno (EMSGSIZE);
394: return (-1);
395: }
396: if (len < 0)
397: len = srcp - src + 1;
398: srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
399: if (srcp < msg || srcp >= eom) {
400: __set_errno (EMSGSIZE);
401: return (-1);
402: }
403: checked += 2;
404:
405:
406:
407:
408:
409: if (checked >= eom - msg) {
410: __set_errno (EMSGSIZE);
411: return (-1);
412: }
413: break;
414:
415: default:
416: __set_errno (EMSGSIZE);
417: return (-1);
418: }
419: }
420: *dstp = '\0';
421: if (len < 0)
422: len = srcp - src;
423: return (len);
424: }
425: libresolv_hidden_def (ns_name_unpack)
426:
427:
428:
429:
430:
431:
432:
433:
434:
435:
436:
437:
438:
439:
440:
441:
442:
443:
444: int
445: ns_name_pack(const u_char *src, u_char *dst, int dstsiz,
446: const u_char **dnptrs, const u_char **lastdnptr)
447: {
448: u_char *dstp;
449: const u_char **cpp, **lpp, *eob, *msg;
450: const u_char *srcp;
451: int n, l, first = 1;
452:
453: srcp = src;
454: dstp = dst;
455: eob = dstp + dstsiz;
456: lpp = cpp = NULL;
457: if (dnptrs != NULL) {
458: if ((msg = *dnptrs++) != NULL) {
459: for (cpp = dnptrs; *cpp != NULL; cpp++)
460: (void)NULL;
461: lpp = cpp;
462: }
463: } else
464: msg = NULL;
465:
466:
467: l = 0;
468: do {
469: n = *srcp;
470: if ((n & NS_CMPRSFLGS) != 0 && n != 0x41) {
471: __set_errno (EMSGSIZE);
472: return (-1);
473: }
474: if (n == 0x41)
475: n = *++srcp / 8;
476: l += n + 1;
477: if (l > MAXCDNAME) {
478: __set_errno (EMSGSIZE);
479: return (-1);
480: }
481: srcp += n + 1;
482: } while (n != 0);
483:
484:
485: srcp = src;
486: do {
487:
488: n = *srcp;
489: if (n != 0 && n != 0x41 && msg != NULL) {
490: l = dn_find(srcp, msg, (const u_char * const *)dnptrs,
491: (const u_char * const *)lpp);
492: if (l >= 0) {
493: if (dstp + 1 >= eob) {
494: goto cleanup;
495: }
496: *dstp++ = (l >> 8) | NS_CMPRSFLGS;
497: *dstp++ = l % 256;
498: return (dstp - dst);
499: }
500:
501: if (lastdnptr != NULL && cpp < lastdnptr - 1 &&
502: (dstp - msg) < 0x4000 && first) {
503: *cpp++ = dstp;
504: *cpp = NULL;
505: first = 0;
506: }
507: }
508:
509: if ((n & NS_CMPRSFLGS) != 0 && n != 0x41) {
510: goto cleanup;
511: }
512: if (n == 0x41) {
513: n = *++srcp / 8;
514: if (dstp + 1 >= eob)
515: goto cleanup;
516: *dstp++ = 0x41;
517: }
518: if (dstp + 1 + n >= eob) {
519: goto cleanup;
520: }
521: memcpy(dstp, srcp, n + 1);
522: srcp += n + 1;
523: dstp += n + 1;
524: } while (n != 0);
525:
526: if (dstp > eob) {
527: cleanup:
528: if (msg != NULL)
529: *lpp = NULL;
530: __set_errno (EMSGSIZE);
531: return (-1);
532: }
533: return (dstp - dst);
534: }
535:
536:
537:
538:
539:
540:
541:
542:
543:
544: int
545: ns_name_uncompress(const u_char *msg, const u_char *eom, const u_char *src,
546: char *dst, size_t dstsiz)
547: {
548: u_char tmp[NS_MAXCDNAME];
549: int n;
550:
551: if ((n = ns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1)
552: return (-1);
553: if (ns_name_ntop(tmp, dst, dstsiz) == -1)
554: return (-1);
555: return (n);
556: }
557:
558:
559:
560:
561:
562:
563:
564:
565:
566:
567:
568:
569:
570:
571: