2 * Copyright (c) 1996,1999 by Internet Software Consortium.
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
9 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
10 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
11 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
12 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
13 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
14 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
19 * Modified by Hotbird64 for use with vlmcs.
23 #define CONFIG "config.h"
27 #ifdef DNS_PARSER_INTERNAL
30 #include <sys/types.h>
42 # define SPRINTF(x) strlen(sprintf/**/x)
44 # define SPRINTF(x) ((size_t)sprintf x)
47 #define NS_TYPE_ELT 0x40 /* EDNS0 extended label type */
48 #define DNS_LABELTYPE_BITSTRING 0x41
50 #define NS_MAXCDNAME 255
51 #define NS_CMPRSFLGS 0xc0
55 static char digits
[] = "0123456789";
60 static int special_vlmcsd(int);
61 static int printable_vlmcsd(int);
62 static int labellen_vlmcsd(const uint8_t *);
63 static int decode_bitstring_vlmcsd(const char **, char *, const char *);
66 * ns_name_ntop(src, dst, dstsiz)
67 * Convert an encoded domain name to printable ascii as per RFC1035.
69 * Number of bytes written to buffer, or -1 (with errno set)
71 * The root is returned as "."
72 * All other domains are returned in non absolute form
75 ns_name_ntop_vlmcsd(const uint8_t *src
, char *dst
, size_t dstsiz
)
87 while ((n
= *cp
++) != 0) {
88 if ((n
& NS_CMPRSFLGS
) == NS_CMPRSFLGS
) {
89 /* Some kind of compression pointer. */
100 if ((l
= labellen_vlmcsd(cp
- 1)) < 0) {
101 errno
= EMSGSIZE
; /* XXX */
108 if ((n
& NS_CMPRSFLGS
) == NS_TYPE_ELT
) {
111 if (n
!= DNS_LABELTYPE_BITSTRING
) {
112 /* XXX: labellen should reject this case */
116 if ((m
= decode_bitstring_vlmcsd((const char **)&cp
, dn
, eom
)) < 0)
124 for ((void)NULL
; l
> 0; l
--) {
126 if (special_vlmcsd(c
)) {
133 } else if (!printable_vlmcsd(c
)) {
139 *dn
++ = digits
[c
/ 100];
140 *dn
++ = digits
[(c
% 100) / 10];
141 *dn
++ = digits
[c
% 10];
167 ns_name_unpack_vlmcsd(const uint8_t *msg
, const uint8_t *eom
, const uint8_t *src
,
168 uint8_t *dst
, size_t dstsiz
)
170 const uint8_t *srcp
, *dstlim
;
172 int n
, len
, checked
, l
;
178 dstlim
= dst
+ dstsiz
;
179 if (srcp
< msg
|| srcp
>= eom
) {
183 /* Fetch next label in domain name. */
184 while ((n
= *srcp
++) != 0) {
185 /* Check for indirection. */
186 switch (n
& NS_CMPRSFLGS
) {
190 if ((l
= labellen_vlmcsd(srcp
- 1)) < 0) {
194 if (dstp
+ l
+ 1 >= dstlim
|| srcp
+ l
>= eom
) {
200 memcpy(dstp
, srcp
, l
);
211 len
= srcp
- src
+ 1;
212 srcp
= msg
+ (((n
& 0x3f) << 8) | (*srcp
& 0xff));
213 if (srcp
< msg
|| srcp
>= eom
) { /* Out of range. */
219 * Check for loops in the compressed name;
220 * if we've looked at the whole message,
221 * there must be a loop.
223 if (checked
>= eom
- msg
) {
231 return (-1); /* flag error */
242 * ns_name_uncompress_vlmcsd(msg, eom, src, dst, dstsiz)
243 * Expand compressed domain name to presentation format.
245 * Number of bytes read out of `src', or -1 (with errno set).
247 * Root domain returns as "." not "".
250 ns_name_uncompress_vlmcsd(const uint8_t *msg
, const uint8_t *eom
, const uint8_t *src
,
251 char *dst
, size_t dstsiz
)
253 uint8_t tmp
[NS_MAXCDNAME
];
256 if ((n
= ns_name_unpack_vlmcsd(msg
, eom
, src
, tmp
, sizeof tmp
)) == -1)
258 if (ns_name_ntop_vlmcsd(tmp
, dst
, dstsiz
) == -1)
265 * Thinking in noninternationalized USASCII (per the DNS spec),
266 * is this characted special ("in need of quoting") ?
271 special_vlmcsd(int ch
) {
276 case 0x5C: /* '\\' */
279 /* Special modifiers in zone files. */
290 * Thinking in noninternationalized USASCII (per the DNS spec),
291 * is this character visible and not a space when printed ?
296 printable_vlmcsd(int ch
) {
297 return (ch
> 0x20 && ch
< 0x7f);
301 decode_bitstring_vlmcsd(const char **cpp
, char *dn
, const char *eom
)
303 const char *cp
= *cpp
;
307 if ((blen
= (*cp
& 0xff)) == 0)
309 plen
= (blen
+ 3) / 4;
310 plen
+= sizeof("\\[x/]") + (blen
> 99 ? 3 : (blen
> 9) ? 2 : 1);
311 if (dn
+ plen
>= eom
)
315 dn
+= SPRINTF((dn
, "\\[x"));
316 for (b
= blen
; b
> 7; b
-= 8, cp
++)
317 dn
+= SPRINTF((dn
, "%02x", *cp
& 0xff));
320 dn
+= SPRINTF((dn
, "%02x", tc
& (0xff << (8 - b
))));
323 dn
+= SPRINTF((dn
, "%1x",
324 ((tc
>> 4) & 0x0f) & (0x0f << (4 - b
))));
326 dn
+= SPRINTF((dn
, "/%d]", blen
));
333 labellen_vlmcsd(const uint8_t *lp
)
338 if ((l
& NS_CMPRSFLGS
) == NS_CMPRSFLGS
) {
339 /* should be avoided by the caller */
343 if ((l
& NS_CMPRSFLGS
) == NS_TYPE_ELT
) {
344 if (l
== DNS_LABELTYPE_BITSTRING
) {
345 if ((bitlen
= *(lp
+ 1)) == 0)
347 return((bitlen
+ 7 ) / 8 + 1);
349 return(-1); /* unknwon ELT */
355 #endif // DNS_PARSER_INTERNAL