| 1 | $FreeWRT$
|
|---|
| 2 | --- trafshow-5.2.3.orig/domain_resolver.c 2006-01-08 06:59:23.000000000 +0100
|
|---|
| 3 | +++ trafshow-5.2.3/domain_resolver.c 2007-02-04 19:40:27.000000000 +0100
|
|---|
| 4 | @@ -28,6 +28,676 @@
|
|---|
| 5 | #include <resolv.h>
|
|---|
| 6 | #endif
|
|---|
| 7 |
|
|---|
| 8 | +/*
|
|---|
| 9 | + * Copyright (c) 1985, 1993
|
|---|
| 10 | + * The Regents of the University of California. All rights reserved.
|
|---|
| 11 | + *
|
|---|
| 12 | + * Redistribution and use in source and binary forms, with or without
|
|---|
| 13 | + * modification, are permitted provided that the following conditions
|
|---|
| 14 | + * are met:
|
|---|
| 15 | + * 1. Redistributions of source code must retain the above copyright
|
|---|
| 16 | + * notice, this list of conditions and the following disclaimer.
|
|---|
| 17 | + * 2. Redistributions in binary form must reproduce the above copyright
|
|---|
| 18 | + * notice, this list of conditions and the following disclaimer in the
|
|---|
| 19 | + * documentation and/or other materials provided with the distribution.
|
|---|
| 20 | + * 4. Neither the name of the University nor the names of its contributors
|
|---|
| 21 | + * may be used to endorse or promote products derived from this software
|
|---|
| 22 | + * without specific prior written permission.
|
|---|
| 23 | + *
|
|---|
| 24 | + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
|---|
| 25 | + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|---|
| 26 | + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|---|
| 27 | + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
|---|
| 28 | + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|---|
| 29 | + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
|---|
| 30 | + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
|---|
| 31 | + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|---|
| 32 | + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
|---|
| 33 | + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
|---|
| 34 | + * SUCH DAMAGE.
|
|---|
| 35 | + */
|
|---|
| 36 | +
|
|---|
| 37 | +/*
|
|---|
| 38 | + * Portions Copyright (c) 1993 by Digital Equipment Corporation.
|
|---|
| 39 | + *
|
|---|
| 40 | + * Permission to use, copy, modify, and distribute this software for any
|
|---|
| 41 | + * purpose with or without fee is hereby granted, provided that the above
|
|---|
| 42 | + * copyright notice and this permission notice appear in all copies, and that
|
|---|
| 43 | + * the name of Digital Equipment Corporation not be used in advertising or
|
|---|
| 44 | + * publicity pertaining to distribution of the document or software without
|
|---|
| 45 | + * specific, written prior permission.
|
|---|
| 46 | + *
|
|---|
| 47 | + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
|
|---|
| 48 | + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
|
|---|
| 49 | + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
|
|---|
| 50 | + * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
|---|
| 51 | + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
|---|
| 52 | + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
|---|
| 53 | + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|---|
| 54 | + * SOFTWARE.
|
|---|
| 55 | + */
|
|---|
| 56 | +
|
|---|
| 57 | +/*
|
|---|
| 58 | + * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
|
|---|
| 59 | + *
|
|---|
| 60 | + * Permission to use, copy, modify, and distribute this software for any
|
|---|
| 61 | + * purpose with or without fee is hereby granted, provided that the above
|
|---|
| 62 | + * copyright notice and this permission notice appear in all copies.
|
|---|
| 63 | + *
|
|---|
| 64 | + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
|---|
| 65 | + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
|---|
| 66 | + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
|---|
| 67 | + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
|---|
| 68 | + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
|---|
| 69 | + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
|---|
| 70 | + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|---|
| 71 | + * SOFTWARE.
|
|---|
| 72 | + */
|
|---|
| 73 | +
|
|---|
| 74 | +/*
|
|---|
| 75 | + * Copyright (c) 1996,1999 by Internet Software Consortium.
|
|---|
| 76 | + *
|
|---|
| 77 | + * Permission to use, copy, modify, and distribute this software for any
|
|---|
| 78 | + * purpose with or without fee is hereby granted, provided that the above
|
|---|
| 79 | + * copyright notice and this permission notice appear in all copies.
|
|---|
| 80 | + *
|
|---|
| 81 | + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
|---|
| 82 | + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
|---|
| 83 | + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
|---|
| 84 | + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
|---|
| 85 | + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
|---|
| 86 | + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
|---|
| 87 | + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
|---|
| 88 | + * SOFTWARE.
|
|---|
| 89 | + */
|
|---|
| 90 | +
|
|---|
| 91 | +/*
|
|---|
| 92 | + *
|
|---|
| 93 | + * DNS helper functions not implemented in uclibc
|
|---|
| 94 | + *
|
|---|
| 95 | + */
|
|---|
| 96 | +
|
|---|
| 97 | +#include <ctype.h>
|
|---|
| 98 | +#include <unistd.h>
|
|---|
| 99 | +
|
|---|
| 100 | +static const char digits[] = "0123456789";
|
|---|
| 101 | +
|
|---|
| 102 | +/* Forward. */
|
|---|
| 103 | +
|
|---|
| 104 | +static int special(int);
|
|---|
| 105 | +static int printable(int);
|
|---|
| 106 | +static int dn_find(const u_char *, const u_char *,
|
|---|
| 107 | + const u_char * const *,
|
|---|
| 108 | + const u_char * const *);
|
|---|
| 109 | +
|
|---|
| 110 | +
|
|---|
| 111 | +/*
|
|---|
| 112 | + * ns_name_ntop(src, dst, dstsiz)
|
|---|
| 113 | + * Convert an encoded domain name to printable ascii as per RFC1035.
|
|---|
| 114 | + * return:
|
|---|
| 115 | + * Number of bytes written to buffer, or -1 (with errno set)
|
|---|
| 116 | + * notes:
|
|---|
| 117 | + * The root is returned as "."
|
|---|
| 118 | + * All other domains are returned in non absolute form
|
|---|
| 119 | + */
|
|---|
| 120 | +int
|
|---|
| 121 | +ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) {
|
|---|
| 122 | + const u_char *cp;
|
|---|
| 123 | + char *dn, *eom;
|
|---|
| 124 | + u_char c;
|
|---|
| 125 | + u_int n;
|
|---|
| 126 | +
|
|---|
| 127 | + cp = src;
|
|---|
| 128 | + dn = dst;
|
|---|
| 129 | + eom = dst + dstsiz;
|
|---|
| 130 | +
|
|---|
| 131 | + while ((n = *cp++) != 0) {
|
|---|
| 132 | + if ((n & NS_CMPRSFLGS) != 0) {
|
|---|
| 133 | + /* Some kind of compression pointer. */
|
|---|
| 134 | + return (-1);
|
|---|
| 135 | + }
|
|---|
| 136 | + if (dn != dst) {
|
|---|
| 137 | + if (dn >= eom) {
|
|---|
| 138 | + return (-1);
|
|---|
| 139 | + }
|
|---|
| 140 | + *dn++ = '.';
|
|---|
| 141 | + }
|
|---|
| 142 | + if (dn + n >= eom) {
|
|---|
| 143 | + return (-1);
|
|---|
| 144 | + }
|
|---|
| 145 | + for ((void)NULL; n > 0; n--) {
|
|---|
| 146 | + c = *cp++;
|
|---|
| 147 | + if (special(c)) {
|
|---|
| 148 | + if (dn + 1 >= eom) {
|
|---|
| 149 | + return (-1);
|
|---|
| 150 | + }
|
|---|
| 151 | + *dn++ = '\\';
|
|---|
| 152 | + *dn++ = (char)c;
|
|---|
| 153 | + } else if (!printable(c)) {
|
|---|
| 154 | + if (dn + 3 >= eom) {
|
|---|
| 155 | + return (-1);
|
|---|
| 156 | + }
|
|---|
| 157 | + *dn++ = '\\';
|
|---|
| 158 | + *dn++ = digits[c / 100];
|
|---|
| 159 | + *dn++ = digits[(c % 100) / 10];
|
|---|
| 160 | + *dn++ = digits[c % 10];
|
|---|
| 161 | + } else {
|
|---|
| 162 | + if (dn >= eom) {
|
|---|
| 163 | + return (-1);
|
|---|
| 164 | + }
|
|---|
| 165 | + *dn++ = (char)c;
|
|---|
| 166 | + }
|
|---|
| 167 | + }
|
|---|
| 168 | + }
|
|---|
| 169 | + if (dn == dst) {
|
|---|
| 170 | + if (dn >= eom) {
|
|---|
| 171 | + return (-1);
|
|---|
| 172 | + }
|
|---|
| 173 | + *dn++ = '.';
|
|---|
| 174 | + }
|
|---|
| 175 | + if (dn >= eom) {
|
|---|
| 176 | + return (-1);
|
|---|
| 177 | + }
|
|---|
| 178 | + *dn++ = '\0';
|
|---|
| 179 | + return (dn - dst);
|
|---|
| 180 | +}
|
|---|
| 181 | +
|
|---|
| 182 | +/*
|
|---|
| 183 | + * ns_name_pton(src, dst, dstsiz)
|
|---|
| 184 | + * Convert a ascii string into an encoded domain name as per RFC1035.
|
|---|
| 185 | + * return:
|
|---|
| 186 | + * -1 if it fails
|
|---|
| 187 | + * 1 if string was fully qualified
|
|---|
| 188 | + * 0 is string was not fully qualified
|
|---|
| 189 | + * notes:
|
|---|
| 190 | + * Enforces label and domain length limits.
|
|---|
| 191 | + */
|
|---|
| 192 | +
|
|---|
| 193 | +int
|
|---|
| 194 | +ns_name_pton(const char *src, u_char *dst, size_t dstsiz) {
|
|---|
| 195 | + u_char *label, *bp, *eom;
|
|---|
| 196 | + int c, n, escaped;
|
|---|
| 197 | + char *cp;
|
|---|
| 198 | +
|
|---|
| 199 | + escaped = 0;
|
|---|
| 200 | + bp = dst;
|
|---|
| 201 | + eom = dst + dstsiz;
|
|---|
| 202 | + label = bp++;
|
|---|
| 203 | +
|
|---|
| 204 | + while ((c = *src++) != 0) {
|
|---|
| 205 | + if (escaped) {
|
|---|
| 206 | + if ((cp = strchr(digits, c)) != NULL) {
|
|---|
| 207 | + n = (cp - digits) * 100;
|
|---|
| 208 | + if ((c = *src++) == 0 ||
|
|---|
| 209 | + (cp = strchr(digits, c)) == NULL) {
|
|---|
| 210 | + return (-1);
|
|---|
| 211 | + }
|
|---|
| 212 | + n += (cp - digits) * 10;
|
|---|
| 213 | + if ((c = *src++) == 0 ||
|
|---|
| 214 | + (cp = strchr(digits, c)) == NULL) {
|
|---|
| 215 | + return (-1);
|
|---|
| 216 | + }
|
|---|
| 217 | + n += (cp - digits);
|
|---|
| 218 | + if (n > 255) {
|
|---|
| 219 | + return (-1);
|
|---|
| 220 | + }
|
|---|
| 221 | + c = n;
|
|---|
| 222 | + }
|
|---|
| 223 | + escaped = 0;
|
|---|
| 224 | + } else if (c == '\\') {
|
|---|
| 225 | + escaped = 1;
|
|---|
| 226 | + continue;
|
|---|
| 227 | + } else if (c == '.') {
|
|---|
| 228 | + c = (bp - label - 1);
|
|---|
| 229 | + if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */
|
|---|
| 230 | + return (-1);
|
|---|
| 231 | + }
|
|---|
| 232 | + if (label >= eom) {
|
|---|
| 233 | + return (-1);
|
|---|
| 234 | + }
|
|---|
| 235 | + *label = c;
|
|---|
| 236 | + /* Fully qualified ? */
|
|---|
| 237 | + if (*src == '\0') {
|
|---|
| 238 | + if (c != 0) {
|
|---|
| 239 | + if (bp >= eom) {
|
|---|
| 240 | + return (-1);
|
|---|
| 241 | + }
|
|---|
| 242 | + *bp++ = '\0';
|
|---|
| 243 | + }
|
|---|
| 244 | + if ((bp - dst) > MAXCDNAME) {
|
|---|
| 245 | + return (-1);
|
|---|
| 246 | + }
|
|---|
| 247 | + return (1);
|
|---|
| 248 | + }
|
|---|
| 249 | + if (c == 0 || *src == '.') {
|
|---|
| 250 | + return (-1);
|
|---|
| 251 | + }
|
|---|
| 252 | + label = bp++;
|
|---|
| 253 | + continue;
|
|---|
| 254 | + }
|
|---|
| 255 | + if (bp >= eom) {
|
|---|
| 256 | + return (-1);
|
|---|
| 257 | + }
|
|---|
| 258 | + *bp++ = (u_char)c;
|
|---|
| 259 | + }
|
|---|
| 260 | + c = (bp - label - 1);
|
|---|
| 261 | + if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */
|
|---|
| 262 | + return (-1);
|
|---|
| 263 | + }
|
|---|
| 264 | + if (label >= eom) {
|
|---|
| 265 | + return (-1);
|
|---|
| 266 | + }
|
|---|
| 267 | + *label = c;
|
|---|
| 268 | + if (c != 0) {
|
|---|
| 269 | + if (bp >= eom) {
|
|---|
| 270 | + return (-1);
|
|---|
| 271 | + }
|
|---|
| 272 | + *bp++ = 0;
|
|---|
| 273 | + }
|
|---|
| 274 | + if ((bp - dst) > MAXCDNAME) { /* src too big */
|
|---|
| 275 | + return (-1);
|
|---|
| 276 | + }
|
|---|
| 277 | + return (0);
|
|---|
| 278 | +}
|
|---|
| 279 | +
|
|---|
| 280 | +/*
|
|---|
| 281 | + * ns_name_ntol(src, dst, dstsiz)
|
|---|
| 282 | + * Convert a network strings labels into all lowercase.
|
|---|
| 283 | + * return:
|
|---|
| 284 | + * Number of bytes written to buffer, or -1 (with errno set)
|
|---|
| 285 | + * notes:
|
|---|
| 286 | + * Enforces label and domain length limits.
|
|---|
| 287 | + */
|
|---|
| 288 | +
|
|---|
| 289 | +int
|
|---|
| 290 | +ns_name_ntol(const u_char *src, u_char *dst, size_t dstsiz) {
|
|---|
| 291 | + const u_char *cp;
|
|---|
| 292 | + u_char *dn, *eom;
|
|---|
| 293 | + u_char c;
|
|---|
| 294 | + u_int n;
|
|---|
| 295 | +
|
|---|
| 296 | + cp = src;
|
|---|
| 297 | + dn = dst;
|
|---|
| 298 | + eom = dst + dstsiz;
|
|---|
| 299 | +
|
|---|
| 300 | + while ((n = *cp++) != 0) {
|
|---|
| 301 | + if ((n & NS_CMPRSFLGS) != 0) {
|
|---|
| 302 | + /* Some kind of compression pointer. */
|
|---|
| 303 | + return (-1);
|
|---|
| 304 | + }
|
|---|
| 305 | + *dn++ = n;
|
|---|
| 306 | + if (dn + n >= eom) {
|
|---|
| 307 | + return (-1);
|
|---|
| 308 | + }
|
|---|
| 309 | + for ((void)NULL; n > 0; n--) {
|
|---|
| 310 | + c = *cp++;
|
|---|
| 311 | + if (isupper(c))
|
|---|
| 312 | + *dn++ = tolower(c);
|
|---|
| 313 | + else
|
|---|
| 314 | + *dn++ = c;
|
|---|
| 315 | + }
|
|---|
| 316 | + }
|
|---|
| 317 | + *dn++ = '\0';
|
|---|
| 318 | + return (dn - dst);
|
|---|
| 319 | +}
|
|---|
| 320 | +
|
|---|
| 321 | +/*
|
|---|
| 322 | + * ns_name_unpack(msg, eom, src, dst, dstsiz)
|
|---|
| 323 | + * Unpack a domain name from a message, source may be compressed.
|
|---|
| 324 | + * return:
|
|---|
| 325 | + * -1 if it fails, or consumed octets if it succeeds.
|
|---|
| 326 | + */
|
|---|
| 327 | +int
|
|---|
| 328 | +ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
|
|---|
| 329 | + u_char *dst, size_t dstsiz)
|
|---|
| 330 | +{
|
|---|
| 331 | + const u_char *srcp, *dstlim;
|
|---|
| 332 | + u_char *dstp;
|
|---|
| 333 | + int n, len, checked;
|
|---|
| 334 | +
|
|---|
| 335 | + len = -1;
|
|---|
| 336 | + checked = 0;
|
|---|
| 337 | + dstp = dst;
|
|---|
| 338 | + srcp = src;
|
|---|
| 339 | + dstlim = dst + dstsiz;
|
|---|
| 340 | + if (srcp < msg || srcp >= eom) {
|
|---|
| 341 | + return (-1);
|
|---|
| 342 | + }
|
|---|
| 343 | + /* Fetch next label in domain name. */
|
|---|
| 344 | + while ((n = *srcp++) != 0) {
|
|---|
| 345 | + /* Check for indirection. */
|
|---|
| 346 | + switch (n & NS_CMPRSFLGS) {
|
|---|
| 347 | + case 0:
|
|---|
| 348 | + /* Limit checks. */
|
|---|
| 349 | + if (dstp + n + 1 >= dstlim || srcp + n >= eom) {
|
|---|
| 350 | + return (-1);
|
|---|
| 351 | + }
|
|---|
| 352 | + checked += n + 1;
|
|---|
| 353 | + *dstp++ = n;
|
|---|
| 354 | + memcpy(dstp, srcp, n);
|
|---|
| 355 | + dstp += n;
|
|---|
| 356 | + srcp += n;
|
|---|
| 357 | + break;
|
|---|
| 358 | +
|
|---|
| 359 | + case NS_CMPRSFLGS:
|
|---|
| 360 | + if (srcp >= eom) {
|
|---|
| 361 | + return (-1);
|
|---|
| 362 | + }
|
|---|
| 363 | + if (len < 0)
|
|---|
| 364 | + len = srcp - src + 1;
|
|---|
| 365 | + srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
|
|---|
| 366 | + if (srcp < msg || srcp >= eom) { /* Out of range. */
|
|---|
| 367 | + return (-1);
|
|---|
| 368 | + }
|
|---|
| 369 | + checked += 2;
|
|---|
| 370 | + /*
|
|---|
| 371 | + * Check for loops in the compressed name;
|
|---|
| 372 | + * if we've looked at the whole message,
|
|---|
| 373 | + * there must be a loop.
|
|---|
| 374 | + */
|
|---|
| 375 | + if (checked >= eom - msg) {
|
|---|
| 376 | + return (-1);
|
|---|
| 377 | + }
|
|---|
| 378 | + break;
|
|---|
| 379 | +
|
|---|
| 380 | + default:
|
|---|
| 381 | + return (-1); /* flag error */
|
|---|
| 382 | + }
|
|---|
| 383 | + }
|
|---|
| 384 | + *dstp = '\0';
|
|---|
| 385 | + if (len < 0)
|
|---|
| 386 | + len = srcp - src;
|
|---|
| 387 | + return (len);
|
|---|
| 388 | +}
|
|---|
| 389 | +
|
|---|
| 390 | +/*
|
|---|
| 391 | + * ns_name_pack(src, dst, dstsiz, dnptrs, lastdnptr)
|
|---|
| 392 | + * Pack domain name 'domain' into 'comp_dn'.
|
|---|
| 393 | + * return:
|
|---|
| 394 | + * Size of the compressed name, or -1.
|
|---|
| 395 | + * notes:
|
|---|
| 396 | + * 'dnptrs' is an array of pointers to previous compressed names.
|
|---|
| 397 | + * dnptrs[0] is a pointer to the beginning of the message. The array
|
|---|
| 398 | + * ends with NULL.
|
|---|
| 399 | + * 'lastdnptr' is a pointer to the end of the array pointed to
|
|---|
| 400 | + * by 'dnptrs'.
|
|---|
| 401 | + * Side effects:
|
|---|
| 402 | + * The list of pointers in dnptrs is updated for labels inserted into
|
|---|
| 403 | + * the message as we compress the name. If 'dnptr' is NULL, we don't
|
|---|
| 404 | + * try to compress names. If 'lastdnptr' is NULL, we don't update the
|
|---|
| 405 | + * list.
|
|---|
| 406 | + */
|
|---|
| 407 | +int
|
|---|
| 408 | +ns_name_pack(const u_char *src, u_char *dst, int dstsiz,
|
|---|
| 409 | + const u_char **dnptrs, const u_char **lastdnptr)
|
|---|
| 410 | +{
|
|---|
| 411 | + u_char *dstp;
|
|---|
| 412 | + const u_char **cpp, **lpp, *eob, *msg;
|
|---|
| 413 | + const u_char *srcp;
|
|---|
| 414 | + int n, l, first = 1;
|
|---|
| 415 | +
|
|---|
| 416 | + srcp = src;
|
|---|
| 417 | + dstp = dst;
|
|---|
| 418 | + eob = dstp + dstsiz;
|
|---|
| 419 | + lpp = cpp = NULL;
|
|---|
| 420 | + if (dnptrs != NULL) {
|
|---|
| 421 | + if ((msg = *dnptrs++) != NULL) {
|
|---|
| 422 | + for (cpp = dnptrs; *cpp != NULL; cpp++)
|
|---|
| 423 | + (void)NULL;
|
|---|
| 424 | + lpp = cpp; /* end of list to search */
|
|---|
| 425 | + }
|
|---|
| 426 | + } else
|
|---|
| 427 | + msg = NULL;
|
|---|
| 428 | +
|
|---|
| 429 | + /* make sure the domain we are about to add is legal */
|
|---|
| 430 | + l = 0;
|
|---|
| 431 | + do {
|
|---|
| 432 | + n = *srcp;
|
|---|
| 433 | + if ((n & NS_CMPRSFLGS) != 0) {
|
|---|
| 434 | + return (-1);
|
|---|
| 435 | + }
|
|---|
| 436 | + l += n + 1;
|
|---|
| 437 | + if (l > MAXCDNAME) {
|
|---|
| 438 | + return (-1);
|
|---|
| 439 | + }
|
|---|
| 440 | + srcp += n + 1;
|
|---|
| 441 | + } while (n != 0);
|
|---|
| 442 | +
|
|---|
| 443 | + /* from here on we need to reset compression pointer array on error */
|
|---|
| 444 | + srcp = src;
|
|---|
| 445 | + do {
|
|---|
| 446 | + /* Look to see if we can use pointers. */
|
|---|
| 447 | + n = *srcp;
|
|---|
| 448 | + if (n != 0 && msg != NULL) {
|
|---|
| 449 | + l = dn_find(srcp, msg, (const u_char * const *)dnptrs,
|
|---|
| 450 | + (const u_char * const *)lpp);
|
|---|
| 451 | + if (l >= 0) {
|
|---|
| 452 | + if (dstp + 1 >= eob) {
|
|---|
| 453 | + goto cleanup;
|
|---|
| 454 | + }
|
|---|
| 455 | + *dstp++ = (l >> 8) | NS_CMPRSFLGS;
|
|---|
| 456 | + *dstp++ = l % 256;
|
|---|
| 457 | + return (dstp - dst);
|
|---|
| 458 | + }
|
|---|
| 459 | + /* Not found, save it. */
|
|---|
| 460 | + if (lastdnptr != NULL && cpp < lastdnptr - 1 &&
|
|---|
| 461 | + (dstp - msg) < 0x4000 && first) {
|
|---|
| 462 | + *cpp++ = dstp;
|
|---|
| 463 | + *cpp = NULL;
|
|---|
| 464 | + first = 0;
|
|---|
| 465 | + }
|
|---|
| 466 | + }
|
|---|
| 467 | + /* copy label to buffer */
|
|---|
| 468 | + if (n & NS_CMPRSFLGS) { /* Should not happen. */
|
|---|
| 469 | + goto cleanup;
|
|---|
| 470 | + }
|
|---|
| 471 | + if (dstp + 1 + n >= eob) {
|
|---|
| 472 | + goto cleanup;
|
|---|
| 473 | + }
|
|---|
| 474 | + memcpy(dstp, srcp, n + 1);
|
|---|
| 475 | + srcp += n + 1;
|
|---|
| 476 | + dstp += n + 1;
|
|---|
| 477 | + } while (n != 0);
|
|---|
| 478 | +
|
|---|
| 479 | + if (dstp > eob) {
|
|---|
| 480 | +cleanup:
|
|---|
| 481 | + if (msg != NULL)
|
|---|
| 482 | + *lpp = NULL;
|
|---|
| 483 | + return (-1);
|
|---|
| 484 | + }
|
|---|
| 485 | + return (dstp - dst);
|
|---|
| 486 | +}
|
|---|
| 487 | +
|
|---|
| 488 | +/*
|
|---|
| 489 | + * ns_name_uncompress(msg, eom, src, dst, dstsiz)
|
|---|
| 490 | + * Expand compressed domain name to presentation format.
|
|---|
| 491 | + * return:
|
|---|
| 492 | + * Number of bytes read out of `src', or -1 (with errno set).
|
|---|
| 493 | + * note:
|
|---|
| 494 | + * Root domain returns as "." not "".
|
|---|
| 495 | + */
|
|---|
| 496 | +int
|
|---|
| 497 | +ns_name_uncompress(const u_char *msg, const u_char *eom, const u_char *src,
|
|---|
| 498 | + char *dst, size_t dstsiz)
|
|---|
| 499 | +{
|
|---|
| 500 | + u_char tmp[NS_MAXCDNAME];
|
|---|
| 501 | + int n;
|
|---|
| 502 | +
|
|---|
| 503 | + if ((n = ns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1)
|
|---|
| 504 | + return (-1);
|
|---|
| 505 | + if (ns_name_ntop(tmp, dst, dstsiz) == -1)
|
|---|
| 506 | + return (-1);
|
|---|
| 507 | + return (n);
|
|---|
| 508 | +}
|
|---|
| 509 | +
|
|---|
| 510 | +/*
|
|---|
| 511 | + * ns_name_compress(src, dst, dstsiz, dnptrs, lastdnptr)
|
|---|
| 512 | + * Compress a domain name into wire format, using compression pointers.
|
|---|
| 513 | + * return:
|
|---|
| 514 | + * Number of bytes consumed in `dst' or -1 (with errno set).
|
|---|
| 515 | + * notes:
|
|---|
| 516 | + * 'dnptrs' is an array of pointers to previous compressed names.
|
|---|
| 517 | + * dnptrs[0] is a pointer to the beginning of the message.
|
|---|
| 518 | + * The list ends with NULL. 'lastdnptr' is a pointer to the end of the
|
|---|
| 519 | + * array pointed to by 'dnptrs'. Side effect is to update the list of
|
|---|
| 520 | + * pointers for labels inserted into the message as we compress the name.
|
|---|
| 521 | + * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
|
|---|
| 522 | + * is NULL, we don't update the list.
|
|---|
| 523 | + */
|
|---|
| 524 | +int
|
|---|
| 525 | +ns_name_compress(const char *src, u_char *dst, size_t dstsiz,
|
|---|
| 526 | + const u_char **dnptrs, const u_char **lastdnptr)
|
|---|
| 527 | +{
|
|---|
| 528 | + u_char tmp[NS_MAXCDNAME];
|
|---|
| 529 | +
|
|---|
| 530 | + if (ns_name_pton(src, tmp, sizeof tmp) == -1)
|
|---|
| 531 | + return (-1);
|
|---|
| 532 | + return (ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr));
|
|---|
| 533 | +}
|
|---|
| 534 | +
|
|---|
| 535 | +/*
|
|---|
| 536 | + * special(ch)
|
|---|
| 537 | + * Thinking in noninternationalized USASCII (per the DNS spec),
|
|---|
| 538 | + * is this characted special ("in need of quoting") ?
|
|---|
| 539 | + * return:
|
|---|
| 540 | + * boolean.
|
|---|
| 541 | + */
|
|---|
| 542 | +static int
|
|---|
| 543 | +special(int ch) {
|
|---|
| 544 | + switch (ch) {
|
|---|
| 545 | + case 0x22: /* '"' */
|
|---|
| 546 | + case 0x2E: /* '.' */
|
|---|
| 547 | + case 0x3B: /* ';' */
|
|---|
| 548 | + case 0x5C: /* '\\' */
|
|---|
| 549 | + /* Special modifiers in zone files. */
|
|---|
| 550 | + case 0x40: /* '@' */
|
|---|
| 551 | + case 0x24: /* '$' */
|
|---|
| 552 | + return (1);
|
|---|
| 553 | + default:
|
|---|
| 554 | + return (0);
|
|---|
| 555 | + }
|
|---|
| 556 | +}
|
|---|
| 557 | +
|
|---|
| 558 | +/*
|
|---|
| 559 | + * printable(ch)
|
|---|
| 560 | + * Thinking in noninternationalized USASCII (per the DNS spec),
|
|---|
| 561 | + * is this character visible and not a space when printed ?
|
|---|
| 562 | + * return:
|
|---|
| 563 | + * boolean.
|
|---|
| 564 | + */
|
|---|
| 565 | +static int
|
|---|
| 566 | +printable(int ch) {
|
|---|
| 567 | + return (ch > 0x20 && ch < 0x7f);
|
|---|
| 568 | +}
|
|---|
| 569 | +
|
|---|
| 570 | +/*
|
|---|
| 571 | + * Thinking in noninternationalized USASCII (per the DNS spec),
|
|---|
| 572 | + * convert this character to lower case if it's upper case.
|
|---|
| 573 | + */
|
|---|
| 574 | +static int
|
|---|
| 575 | +mklower(int ch) {
|
|---|
| 576 | + if (ch >= 0x41 && ch <= 0x5A)
|
|---|
| 577 | + return (ch + 0x20);
|
|---|
| 578 | + return (ch);
|
|---|
| 579 | +}
|
|---|
| 580 | +
|
|---|
| 581 | +/*
|
|---|
| 582 | + * dn_find(domain, msg, dnptrs, lastdnptr)
|
|---|
| 583 | + * Search for the counted-label name in an array of compressed names.
|
|---|
| 584 | + * return:
|
|---|
| 585 | + * offset from msg if found, or -1.
|
|---|
| 586 | + * notes:
|
|---|
| 587 | + * dnptrs is the pointer to the first name on the list,
|
|---|
| 588 | + * not the pointer to the start of the message.
|
|---|
| 589 | + */
|
|---|
| 590 | +static int
|
|---|
| 591 | +dn_find(const u_char *domain, const u_char *msg,
|
|---|
| 592 | + const u_char * const *dnptrs,
|
|---|
| 593 | + const u_char * const *lastdnptr)
|
|---|
| 594 | +{
|
|---|
| 595 | + const u_char *dn, *cp, *sp;
|
|---|
| 596 | + const u_char * const *cpp;
|
|---|
| 597 | + u_int n;
|
|---|
| 598 | +
|
|---|
| 599 | + for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
|
|---|
| 600 | + sp = *cpp;
|
|---|
| 601 | + /*
|
|---|
| 602 | + * terminate search on:
|
|---|
| 603 | + * root label
|
|---|
| 604 | + * compression pointer
|
|---|
| 605 | + * unusable offset
|
|---|
| 606 | + */
|
|---|
| 607 | + while (*sp != 0 && (*sp & NS_CMPRSFLGS) == 0 &&
|
|---|
| 608 | + (sp - msg) < 0x4000) {
|
|---|
| 609 | + dn = domain;
|
|---|
| 610 | + cp = sp;
|
|---|
| 611 | + while ((n = *cp++) != 0) {
|
|---|
| 612 | + /*
|
|---|
| 613 | + * check for indirection
|
|---|
| 614 | + */
|
|---|
| 615 | + switch (n & NS_CMPRSFLGS) {
|
|---|
| 616 | + case 0: /* normal case, n == len */
|
|---|
| 617 | + if (n != *dn++)
|
|---|
| 618 | + goto next;
|
|---|
| 619 | + for ((void)NULL; n > 0; n--)
|
|---|
| 620 | + if (mklower(*dn++) !=
|
|---|
| 621 | + mklower(*cp++))
|
|---|
| 622 | + goto next;
|
|---|
| 623 | + /* Is next root for both ? */
|
|---|
| 624 | + if (*dn == '\0' && *cp == '\0')
|
|---|
| 625 | + return (sp - msg);
|
|---|
| 626 | + if (*dn)
|
|---|
| 627 | + continue;
|
|---|
| 628 | + goto next;
|
|---|
| 629 | +
|
|---|
| 630 | + case NS_CMPRSFLGS: /* indirection */
|
|---|
| 631 | + cp = msg + (((n & 0x3f) << 8) | *cp);
|
|---|
| 632 | + break;
|
|---|
| 633 | +
|
|---|
| 634 | + default: /* illegal type */
|
|---|
| 635 | + return (-1);
|
|---|
| 636 | + }
|
|---|
| 637 | + }
|
|---|
| 638 | + next:
|
|---|
| 639 | + sp += *sp + 1;
|
|---|
| 640 | + }
|
|---|
| 641 | + }
|
|---|
| 642 | + return (-1);
|
|---|
| 643 | +}
|
|---|
| 644 | +
|
|---|
| 645 | +/*
|
|---|
| 646 | + * Expand compressed domain name 'comp_dn' to full domain name.
|
|---|
| 647 | + * 'msg' is a pointer to the begining of the message,
|
|---|
| 648 | + * 'eomorig' points to the first location after the message,
|
|---|
| 649 | + * 'exp_dn' is a pointer to a buffer of size 'length' for the result.
|
|---|
| 650 | + * Return size of compressed name or -1 if there was an error.
|
|---|
| 651 | + */
|
|---|
| 652 | +int
|
|---|
| 653 | +dn_expand(const u_char *msg, const u_char *eom, const u_char *src,
|
|---|
| 654 | + char *dst, int dstsiz)
|
|---|
| 655 | +{
|
|---|
| 656 | + int n = ns_name_uncompress(msg, eom, src, dst, (size_t)dstsiz);
|
|---|
| 657 | +
|
|---|
| 658 | + if (n > 0 && dst[0] == '.')
|
|---|
| 659 | + dst[0] = '\0';
|
|---|
| 660 | + return (n);
|
|---|
| 661 | +}
|
|---|
| 662 | +
|
|---|
| 663 | +/*
|
|---|
| 664 | + * Pack domain name 'exp_dn' in presentation form into 'comp_dn'.
|
|---|
| 665 | + * Return the size of the compressed name or -1.
|
|---|
| 666 | + * 'length' is the size of the array pointed to by 'comp_dn'.
|
|---|
| 667 | + */
|
|---|
| 668 | +int
|
|---|
| 669 | +dn_comp(const char *src, u_char *dst, int dstsiz,
|
|---|
| 670 | + u_char **dnptrs, u_char **lastdnptr)
|
|---|
| 671 | +{
|
|---|
| 672 | + return (ns_name_compress(src, dst, (size_t)dstsiz,
|
|---|
| 673 | + (const u_char **)dnptrs,
|
|---|
| 674 | + (const u_char **)lastdnptr));
|
|---|
| 675 | +}
|
|---|
| 676 | +
|
|---|
| 677 | +
|
|---|
| 678 | #include "domain_resolver.h"
|
|---|
| 679 | #include "session.h"
|
|---|
| 680 | #include "util.h"
|
|---|