1 | /* |
2 | * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") |
3 | * Copyright (c) 1996,1999 by Internet Software Consortium. |
4 | * |
5 | * Permission to use, copy, modify, and distribute this software for any |
6 | * purpose with or without fee is hereby granted, provided that the above |
7 | * copyright notice and this permission notice appear in all copies. |
8 | * |
9 | * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES |
10 | * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF |
11 | * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR |
12 | * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES |
13 | * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN |
14 | * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT |
15 | * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
16 | */ |
17 | |
18 | #include <sys/types.h> |
19 | |
20 | #include <netinet/in.h> |
21 | #include <arpa/nameser.h> |
22 | |
23 | #include <errno.h> |
24 | #include <resolv.h> |
25 | #include <string.h> |
26 | #include <ctype.h> |
27 | #include <stdlib.h> |
28 | #include <limits.h> |
29 | |
30 | # define SPRINTF(x) ((size_t)sprintf x) |
31 | |
32 | /* Forward. */ |
33 | |
34 | static int labellen(const u_char *); |
35 | |
36 | /* Public. */ |
37 | |
38 | /*% |
39 | * Convert a network strings labels into all lowercase. |
40 | * |
41 | * return: |
42 | *\li Number of bytes written to buffer, or -1 (with errno set) |
43 | * |
44 | * notes: |
45 | *\li Enforces label and domain length limits. |
46 | */ |
47 | |
48 | int |
49 | ns_name_ntol(const u_char *src, u_char *dst, size_t dstsiz) |
50 | { |
51 | const u_char *cp; |
52 | u_char *dn, *eom; |
53 | u_char c; |
54 | u_int n; |
55 | int l; |
56 | |
57 | cp = src; |
58 | dn = dst; |
59 | eom = dst + dstsiz; |
60 | |
61 | if (dn >= eom) { |
62 | __set_errno (EMSGSIZE); |
63 | return (-1); |
64 | } |
65 | while ((n = *cp++) != 0) { |
66 | if ((n & NS_CMPRSFLGS) == NS_CMPRSFLGS) { |
67 | /* Some kind of compression pointer. */ |
68 | __set_errno (EMSGSIZE); |
69 | return (-1); |
70 | } |
71 | *dn++ = n; |
72 | if ((l = labellen(cp - 1)) < 0) { |
73 | __set_errno (EMSGSIZE); |
74 | return (-1); |
75 | } |
76 | if (dn + l >= eom) { |
77 | __set_errno (EMSGSIZE); |
78 | return (-1); |
79 | } |
80 | for ((void)NULL; l > 0; l--) { |
81 | c = *cp++; |
82 | if (isupper(c)) |
83 | *dn++ = tolower(c); |
84 | else |
85 | *dn++ = c; |
86 | } |
87 | } |
88 | *dn++ = '\0'; |
89 | return (dn - dst); |
90 | } |
91 | |
92 | /*% |
93 | * Reset dnptrs so that there are no active references to pointers at or |
94 | * after src. |
95 | */ |
96 | void |
97 | ns_name_rollback(const u_char *src, const u_char **dnptrs, |
98 | const u_char **lastdnptr) |
99 | { |
100 | while (dnptrs < lastdnptr && *dnptrs != NULL) { |
101 | if (*dnptrs >= src) { |
102 | *dnptrs = NULL; |
103 | break; |
104 | } |
105 | dnptrs++; |
106 | } |
107 | } |
108 | |
109 | /* Private. */ |
110 | |
111 | /* Return the length of the encoded label starting at LP, or -1 for |
112 | compression references and extended label types. */ |
113 | static int |
114 | labellen (const unsigned char *lp) |
115 | { |
116 | if (*lp <= 63) |
117 | return *lp; |
118 | return -1; |
119 | } |
120 | |
121 | /*! \file */ |
122 | |