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
ns_name_ntol(const u_char * src,u_char * dst,size_t dstsiz)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
ns_name_rollback(const u_char * src,const u_char ** dnptrs,const u_char ** lastdnptr)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
labellen(const unsigned char * lp)114 labellen (const unsigned char *lp)
115 {
116   if (*lp <= 63)
117     return *lp;
118   return -1;
119 }
120 
121 /*! \file */
122