4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
40 #pragma ident "%Z%%M% %I% %E% SMI"
42 #include <sys/types.h>
44 #include <arpa/nameser.h>
46 static int dn_find(u_char
*exp_dn
, u_char
*msg
, u_char
**dnptrs
,
51 * Expand compressed domain name 'comp_dn' to full domain name.
52 * 'msg' is a pointer to the begining of the message,
53 * 'eomorig' points to the first location after the message,
54 * 'exp_dn' is a pointer to a buffer of size 'length' for the result.
55 * Return size of compressed name or -1 if there was an error.
58 dn_expand(msg
, eomorig
, comp_dn
, exp_dn
, length
)
59 u_char
*msg
, *eomorig
, *comp_dn
, *exp_dn
;
62 register u_char
*cp
, *dn
;
65 int len
= -1, checked
= 0;
69 eom
= exp_dn
+ length
;
71 * fetch next label in domain name
75 * Check for indirection
77 switch (n
& INDIR_MASK
) {
88 if ((c
= *cp
++) == '.') {
89 if (dn
+ n
+ 2 >= eom
)
94 if (cp
>= eomorig
) /* out of range */
101 len
= cp
- comp_dn
+ 1;
102 cp
= msg
+ (((n
& 0x3f) << 8) | (*cp
& 0xff));
103 if (cp
< msg
|| cp
>= eomorig
) /* out of range */
107 * Check for loops in the compressed name;
108 * if we've looked at the whole message,
109 * there must be a loop.
111 if (checked
>= eomorig
- msg
)
116 return (-1); /* flag error */
126 * Compress domain name 'exp_dn' into 'comp_dn'.
127 * Return the size of the compressed name or -1.
128 * 'length' is the size of the array pointed to by 'comp_dn'.
129 * 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0]
130 * is a pointer to the beginning of the message. The list ends with NULL.
131 * 'lastdnptr' is a pointer to the end of the arrary pointed to
132 * by 'dnptrs'. Side effect is to update the list of pointers for
133 * labels inserted into the message as we compress the name.
134 * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
135 * is NULL, we don't update the list.
138 dn_comp(exp_dn
, comp_dn
, length
, dnptrs
, lastdnptr
)
139 u_char
*exp_dn
, *comp_dn
;
141 u_char
**dnptrs
, **lastdnptr
;
143 register u_char
*cp
, *dn
;
145 u_char
**cpp
, **lpp
, *sp
, *eob
;
151 if (dnptrs
!= NULL
) {
152 if ((msg
= *dnptrs
++) != NULL
) {
153 for (cpp
= dnptrs
; *cpp
!= NULL
; cpp
++)
155 lpp
= cpp
; /* end of list to search */
159 for (c
= *dn
++; c
!= '\0'; /*EMPTY*/) {
160 /* look to see if we can use pointers */
162 if ((l
= dn_find(dn
-1, msg
, dnptrs
, lpp
)) >= 0) {
165 *cp
++ = (l
>> 8) | INDIR_MASK
;
167 return (cp
- comp_dn
);
169 /* not found, save it */
170 if (lastdnptr
!= NULL
&& cpp
< lastdnptr
-1) {
175 sp
= cp
++; /* save ptr to length byte */
182 if ((c
= *dn
++) == '\0')
191 } while ((c
= *dn
++) != '\0');
192 /* catch trailing '.'s but not '..' */
193 if ((l
= cp
- sp
- 1) == 0 && c
== '\0') {
197 if (l
<= 0 || l
> MAXLABEL
) {
210 return (cp
- comp_dn
);
214 * Skip over a compressed domain name. Return the size or -1.
217 dn_skipname(comp_dn
, eom
)
218 u_char
*comp_dn
, *eom
;
224 while (cp
< eom
&& (n
= *cp
++)) {
226 * check for indirection
228 switch (n
& INDIR_MASK
) {
229 case 0: /* normal case, n == len */
232 default: /* illegal type */
234 case INDIR_MASK
: /* indirection */
239 return (cp
- comp_dn
);
243 * Search for expanded name from a list of previously compressed names.
244 * Return the offset from msg if found or -1.
245 * dnptrs is the pointer to the first name on the list,
246 * not the pointer to the start of the message.
249 dn_find(u_char
*exp_dn
, u_char
*msg
, u_char
**dnptrs
, u_char
**lastdnptr
)
251 register u_char
*dn
, *cp
, **cpp
;
255 for (cpp
= dnptrs
; cpp
< lastdnptr
; cpp
++) {
260 * check for indirection
262 switch (n
& INDIR_MASK
) {
263 case 0: /* normal case, n == len */
272 if ((n
= *dn
++) == '\0' && *cp
== '\0')
278 default: /* illegal type */
281 case INDIR_MASK
: /* indirection */
282 cp
= msg
+ (((n
& 0x3f) << 8) | *cp
);
293 * Routines to insert/extract short/long's. Must account for byte
294 * order and non-alignment problems. This code at least has the
295 * advantage of being portable.
304 register u_char
*p
= (u_char
*) msgp
;
307 * vax compiler doesn't put shorts in registers
315 return ((u_short
)(u
| *p
));
322 register u_char
*p
= (u_char
*) msgp
;
334 register u_char
*msgp
;
344 register u_char
*msgp
;