7 * Contains the implementations for dn_comp and rdn_expand as well as
8 * some other functions used internally by these two functions.
10 * WSHelper DNS/Hesiod Library for WINSOCK
15 * Copyright (c) 1985 Regents of the University of California.
16 * All rights reserved.
18 * Redistribution and use in source and binary forms, with or without
19 * modification, are permitted provided that the following conditions
21 * 1. Redistributions of source code must retain the above copyright
22 * notice, this list of conditions and the following disclaimer.
23 * 2. Redistributions in binary form must reproduce the above copyright
24 * notice, this list of conditions and the following disclaimer in the
25 * documentation and/or other materials provided with the distribution.
26 * 3. All advertising materials mentioning features or use of this software
27 * must display the following acknowledgement:
28 * This product includes software developed by the University of
29 * California, Berkeley and its contributors.
30 * 4. Neither the name of the University nor the names of its contributors
31 * may be used to endorse or promote products derived from this software
32 * without specific prior written permission.
34 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
35 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
36 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
37 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
38 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
39 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
40 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
41 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
42 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
43 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47 #if defined(LIBC_SCCS) && !defined(lint)
48 static char sccsid[] = "@(#)res_comp.c 6.22 (Berkeley) 3/19/91";
49 #endif /* LIBC_SCCS and not lint */
60 replacement for dn_expand called rdn_expand. Older versions of
61 the DLL used to this as dn_expand but this has caused some
62 conflict with more recent versions of the MSDEV
63 libraries. rdn_expand() expands the compressed domain name comp_dn to
64 a full domain name. Expanded names are converted to upper case.
66 \param[in] msg msg is a pointer to the beginning of the message
68 \param[in] comp_dn the compressed domain name.
69 \param[in, out] expn_dn a pointer to the result buffer
70 \param[in] length size of the result in expn_dn
72 \retval the size of compressed name is returned or -1 if there was an error.
78 rdn_expand(const u_char *msg, const u_char *eomorig,
79 const u_char *comp_dn, u_char *exp_dn, int length)
81 register u_char *cp, *dn;
88 cp = (u_char *)comp_dn;
89 eom = exp_dn + length;
91 * fetch next label in domain name
95 * Check for indirection
97 switch (n & INDIR_MASK) {
108 if ((c = *cp++) == '.') {
109 if (dn + n + 2 >= eom)
114 if (cp >= eomorig) /* out of range */
121 len = cp - comp_dn + 1;
122 cp = (u_char *)msg + (((n & 0x3f) << 8) | (*cp & 0xff));
123 if (cp < msg || cp >= eomorig) /* out of range */
127 * Check for loops in the compressed name;
128 * if we've looked at the whole message,
129 * there must be a loop.
131 if (checked >= eomorig - msg)
136 return (-1); /* flag error */
147 Compress domain name 'exp_dn' into 'comp_dn'
148 \param[in] exp_dn name to compress
149 \param[in, out] comp_dn result of the compression
150 \paramp[in] length the size of the array pointed to by 'comp_dn'.
151 \param[in, out] dnptrs a list of pointers to previous compressed names. dnptrs[0]
152 is a pointer to the beginning of the message. The list ends with NULL.
153 \param[in] lastdnptr a pointer to the end of the arrary pointed to by 'dnptrs'. Side effect
154 is to update the list of pointers for labels inserted into the
155 message as we compress the name. If 'dnptr' is NULL, we don't try to
156 compress names. If 'lastdnptr' is NULL, we don't update the list.
157 \retval Return the size of the compressed name or -1
160 dn_comp(const u_char *exp_dn, u_char *comp_dn, int length,
161 u_char **dnptrs, u_char **lastdnptr)
163 register u_char *cp, *dn;
165 u_char **cpp, **lpp, *sp, *eob;
168 dn = (u_char *)exp_dn;
171 if (dnptrs != NULL) {
172 if ((msg = *dnptrs++) != NULL) {
173 for (cpp = dnptrs; *cpp != NULL; cpp++)
175 lpp = cpp; /* end of list to search */
179 for (c = *dn++; c != '\0'; ) {
180 /* look to see if we can use pointers */
182 if ((l = dn_find(dn-1, msg, dnptrs, lpp)) >= 0) {
185 *cp++ = (l >> 8) | INDIR_MASK;
187 return (int)(cp - comp_dn);
189 /* not found, save it */
190 if (lastdnptr != NULL && cpp < lastdnptr-1) {
195 sp = cp++; /* save ptr to length byte */
202 if ((c = *dn++) == '\0')
211 } while ((c = *dn++) != '\0');
212 /* catch trailing '.'s but not '..' */
213 if ((l =(int)( cp - sp - 1)) == 0 && c == '\0') {
217 if (l <= 0 || l > MAXLABEL) {
230 return (int)(cp - comp_dn);
234 * Skip over a compressed domain name. Return the size or -1.
236 __dn_skipname(const u_char *comp_dn, const u_char *eom)
241 cp = (u_char *)comp_dn;
242 while (cp < eom && (n = *cp++)) {
244 * check for indirection
246 switch (n & INDIR_MASK) {
247 case 0: /* normal case, n == len */
250 default: /* illegal type */
252 case INDIR_MASK: /* indirection */
257 return (int)(cp - comp_dn);
261 * Search for expanded name from a list of previously compressed names.
262 * Return the offset from msg if found or -1.
263 * dnptrs is the pointer to the first name on the list,
264 * not the pointer to the start of the message.
267 dn_find(u_char *exp_dn, u_char *msg, u_char **dnptrs, u_char **lastdnptr)
269 register u_char *dn, *cp, **cpp;
273 for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
278 * check for indirection
280 switch (n & INDIR_MASK) {
281 case 0: /* normal case, n == len */
290 if ((n = *dn++) == '\0' && *cp == '\0')
291 return (int)(sp - msg);
296 default: /* illegal type */
299 case INDIR_MASK: /* indirection */
300 cp = msg + (((n & 0x3f) << 8) | *cp);
304 return (int)(sp - msg);
311 * Routines to insert/extract short/long's. Must account for byte
312 * order and non-alignment problems. This code at least has the
313 * advantage of being portable.
319 _getshort(u_char *msgp)
321 register u_char *p = (u_char *) msgp;
324 * vax compiler doesn't put shorts in registers
332 return ((u_short)(u | *p));
336 _getlong(u_char *msgp)
338 register u_char *p = (u_char *) msgp;
349 __putshort(register u_short s, register u_char *msgp)
353 register u_char *msgp;
363 register u_char *msgp;
365 msgp[3] = LOBYTE(LOWORD(l));
366 msgp[2] = HIBYTE(LOWORD(l));
367 msgp[1] = LOBYTE(HIWORD(l));
368 msgp[0] = HIBYTE(HIWORD(l));