res_comp.c revision 156952
184309Sluigi/* 284309Sluigi * Copyright (c) 1985, 1993 384309Sluigi * The Regents of the University of California. All rights reserved. 484309Sluigi * 584309Sluigi * Redistribution and use in source and binary forms, with or without 684309Sluigi * modification, are permitted provided that the following conditions 784309Sluigi * are met: 884309Sluigi * 1. Redistributions of source code must retain the above copyright 984309Sluigi * notice, this list of conditions and the following disclaimer. 1084309Sluigi * 2. Redistributions in binary form must reproduce the above copyright 1184309Sluigi * notice, this list of conditions and the following disclaimer in the 1284309Sluigi * documentation and/or other materials provided with the distribution. 1384309Sluigi * 3. All advertising materials mentioning features or use of this software 1484309Sluigi * must display the following acknowledgement: 1584309Sluigi * This product includes software developed by the University of 1684309Sluigi * California, Berkeley and its contributors. 1784309Sluigi * 4. Neither the name of the University nor the names of its contributors 1884309Sluigi * may be used to endorse or promote products derived from this software 1984309Sluigi * without specific prior written permission. 2084309Sluigi * 2184309Sluigi * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2284309Sluigi * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2384309Sluigi * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2484309Sluigi * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2584309Sluigi * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2684309Sluigi * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2784309Sluigi * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2884309Sluigi * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2984309Sluigi * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3084309Sluigi * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3184309Sluigi * SUCH DAMAGE. 3284309Sluigi */ 3384309Sluigi 3484309Sluigi/* 3584309Sluigi * Portions Copyright (c) 1993 by Digital Equipment Corporation. 3684309Sluigi * 3784309Sluigi * Permission to use, copy, modify, and distribute this software for any 3884309Sluigi * purpose with or without fee is hereby granted, provided that the above 3984309Sluigi * copyright notice and this permission notice appear in all copies, and that 4084309Sluigi * the name of Digital Equipment Corporation not be used in advertising or 4184309Sluigi * publicity pertaining to distribution of the document or software without 4284309Sluigi * specific, written prior permission. 4384309Sluigi * 4484309Sluigi * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL 4584605Sluigi * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES 4684309Sluigi * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT 4784309Sluigi * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 4884309Sluigi * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 4984309Sluigi * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 5084309Sluigi * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 5184309Sluigi * SOFTWARE. 5284309Sluigi */ 5384309Sluigi 5484309Sluigi/* 5584309Sluigi * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") 5684309Sluigi * Portions Copyright (c) 1996-1999 by Internet Software Consortium. 5784309Sluigi * 5884309Sluigi * Permission to use, copy, modify, and distribute this software for any 5984309Sluigi * purpose with or without fee is hereby granted, provided that the above 6084309Sluigi * copyright notice and this permission notice appear in all copies. 6184309Sluigi * 6284309Sluigi * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES 6384309Sluigi * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 6484309Sluigi * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR 6584309Sluigi * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 6684309Sluigi * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 6784309Sluigi * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT 6884309Sluigi * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 6984309Sluigi */ 7084309Sluigi 7184309Sluigi#if defined(LIBC_SCCS) && !defined(lint) 7284309Sluigistatic const char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93"; 7384309Sluigistatic const char rcsid[] = "$Id: res_comp.c,v 1.1.2.1.4.2 2005/07/28 07:43:22 marka Exp $"; 7484309Sluigi#endif /* LIBC_SCCS and not lint */ 7584309Sluigi 7684309Sluigi#include "port_before.h" 7784309Sluigi#include <sys/types.h> 7884309Sluigi#include <sys/param.h> 79203876Sluigi#include <netinet/in.h> 8084309Sluigi#include <arpa/nameser.h> 8184309Sluigi#include <ctype.h> 8284309Sluigi#include <resolv.h> 8394201Sru#include <stdio.h> 8484309Sluigi#include <string.h> 8584309Sluigi#include <unistd.h> 8684309Sluigi#include "port_after.h" 8784309Sluigi 8884309Sluigi/* 89104744Salfred * Expand compressed domain name 'src' to full domain name. 90104744Salfred * 'msg' is a pointer to the begining of the message, 91104744Salfred * 'eom' points to the first location after the message, 92104744Salfred * 'dst' is a pointer to a buffer of size 'dstsiz' for the result. 93104744Salfred * Return size of compressed name or -1 if there was an error. 94104744Salfred */ 95104744Salfredint 96104744Salfreddn_expand(const u_char *msg, const u_char *eom, const u_char *src, 97104744Salfred char *dst, int dstsiz) 98104744Salfred{ 99104744Salfred int n = ns_name_uncompress(msg, eom, src, dst, (size_t)dstsiz); 100104744Salfred 101104744Salfred if (n > 0 && dst[0] == '.') 10284309Sluigi dst[0] = '\0'; 10384309Sluigi return (n); 104104744Salfred} 105104744Salfred 106104744Salfred/* 10784309Sluigi * Pack domain name 'exp_dn' in presentation form into 'comp_dn'. 10884309Sluigi * Return the size of the compressed name or -1. 10984309Sluigi * 'length' is the size of the array pointed to by 'comp_dn'. 11084309Sluigi */ 11184309Sluigiint 11284309Sluigidn_comp(const char *src, u_char *dst, int dstsiz, 11384309Sluigi u_char **dnptrs, u_char **lastdnptr) 11484309Sluigi{ 11584309Sluigi return (ns_name_compress(src, dst, (size_t)dstsiz, 11684309Sluigi (const u_char **)dnptrs, 11784309Sluigi (const u_char **)lastdnptr)); 11884309Sluigi} 11984309Sluigi 12084309Sluigi/* 121104744Salfred * Skip over a compressed domain name. Return the size or -1. 122104744Salfred */ 12384309Sluigiint 12484309Sluigidn_skipname(const u_char *ptr, const u_char *eom) { 12584309Sluigi const u_char *saveptr = ptr; 12684309Sluigi 12784309Sluigi if (ns_name_skip(&ptr, eom) == -1) 12884309Sluigi return (-1); 12984309Sluigi return (ptr - saveptr); 13084309Sluigi} 13184309Sluigi 13284309Sluigi/* 13384309Sluigi * Verify that a domain name uses an acceptable character set. 13484309Sluigi */ 13584309Sluigi 13684309Sluigi/* 13784309Sluigi * Note the conspicuous absence of ctype macros in these definitions. On 13884309Sluigi * non-ASCII hosts, we can't depend on string literals or ctype macros to 13984309Sluigi * tell us anything about network-format data. The rest of the BIND system 14084309Sluigi * is not careful about this, but for some reason, we're doing it right here. 14194203Sru */ 14294203Sru#define PERIOD 0x2e 14384309Sluigi#define hyphenchar(c) ((c) == 0x2d) 14484309Sluigi#define bslashchar(c) ((c) == 0x5c) 14584309Sluigi#define periodchar(c) ((c) == PERIOD) 14684309Sluigi#define asterchar(c) ((c) == 0x2a) 14784309Sluigi#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \ 14884309Sluigi || ((c) >= 0x61 && (c) <= 0x7a)) 14984309Sluigi#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39) 15084309Sluigi 15184309Sluigi#define borderchar(c) (alphachar(c) || digitchar(c)) 15284309Sluigi#define middlechar(c) (borderchar(c) || hyphenchar(c)) 153203876Sluigi#define domainchar(c) ((c) > 0x20 && (c) < 0x7f) 15484309Sluigi 15584309Sluigiint 15684309Sluigires_hnok(const char *dn) { 157239991Sed int pch = PERIOD, ch = *dn++; 15884309Sluigi 15984309Sluigi while (ch != '\0') { 16084309Sluigi int nch = *dn++; 16184309Sluigi 16284309Sluigi if (periodchar(ch)) { 16394203Sru (void)NULL; 16484309Sluigi } else if (periodchar(pch)) { 165203876Sluigi if (!borderchar(ch)) 166203876Sluigi return (0); 16784309Sluigi } else if (periodchar(nch) || nch == '\0') { 16884309Sluigi if (!borderchar(ch)) 16984309Sluigi return (0); 17084309Sluigi } else { 17184309Sluigi if (!middlechar(ch)) 17284309Sluigi return (0); 17384309Sluigi } 17484309Sluigi pch = ch, ch = nch; 17584309Sluigi } 17684309Sluigi return (1); 17784309Sluigi} 17884309Sluigi 17984309Sluigi/* 18084309Sluigi * hostname-like (A, MX, WKS) owners can have "*" as their first label 18184309Sluigi * but must otherwise be as a host name. 18284309Sluigi */ 18384309Sluigiint 18484309Sluigires_ownok(const char *dn) { 18584309Sluigi if (asterchar(dn[0])) { 18684309Sluigi if (periodchar(dn[1])) 18784309Sluigi return (res_hnok(dn+2)); 18884309Sluigi if (dn[1] == '\0') 18984309Sluigi return (1); 19084309Sluigi } 19184309Sluigi return (res_hnok(dn)); 19284309Sluigi} 19384309Sluigi 19484309Sluigi/* 19584309Sluigi * SOA RNAMEs and RP RNAMEs can have any printable character in their first 19684309Sluigi * label, but the rest of the name has to look like a host name. 19784309Sluigi */ 19884309Sluigiint 19984309Sluigires_mailok(const char *dn) { 20084309Sluigi int ch, escaped = 0; 20184309Sluigi 20284309Sluigi /* "." is a valid missing representation */ 20384309Sluigi if (*dn == '\0') 20484309Sluigi return (1); 20584309Sluigi 20684309Sluigi /* otherwise <label>.<hostname> */ 20784309Sluigi while ((ch = *dn++) != '\0') { 20884309Sluigi if (!domainchar(ch)) 20984309Sluigi return (0); 21084309Sluigi if (!escaped && periodchar(ch)) 21184309Sluigi break; 21284309Sluigi if (escaped) 21384309Sluigi escaped = 0; 21484309Sluigi else if (bslashchar(ch)) 21584309Sluigi escaped = 1; 21684309Sluigi } 21784309Sluigi if (periodchar(ch)) 21884309Sluigi return (res_hnok(dn)); 21984309Sluigi return (0); 22084309Sluigi} 22184309Sluigi 22284309Sluigi/* 22384309Sluigi * This function is quite liberal, since RFC 1034's character sets are only 22484309Sluigi * recommendations. 22584309Sluigi */ 22684309Sluigiint 22784309Sluigires_dnok(const char *dn) { 22884309Sluigi int ch; 22984309Sluigi 23084309Sluigi while ((ch = *dn++) != '\0') 23184309Sluigi if (!domainchar(ch)) 232146187Sume return (0); 23384309Sluigi return (1); 23484309Sluigi} 23584309Sluigi 23684309Sluigi#ifdef BIND_4_COMPAT 23784309Sluigi/* 23884309Sluigi * This module must export the following externally-visible symbols: 23984309Sluigi * ___putlong 24084309Sluigi * ___putshort 24184309Sluigi * __getlong 24284309Sluigi * __getshort 24384309Sluigi * Note that one _ comes from C and the others come from us. 24484309Sluigi */ 24584309Sluigi 24684309Sluigi#ifdef SOLARIS2 24784309Sluigi#ifdef __putlong 24884309Sluigi#undef __putlong 24984309Sluigi#endif 25084309Sluigi#ifdef __putshort 25184309Sluigi#undef __putshort 25284309Sluigi#endif 25384309Sluigi#pragma weak putlong = __putlong 25484309Sluigi#pragma weak putshort = __putshort 25584309Sluigi#endif /* SOLARIS2 */ 25684309Sluigi 25784309Sluigivoid __putlong(u_int32_t src, u_char *dst) { ns_put32(src, dst); } 25884309Sluigivoid __putshort(u_int16_t src, u_char *dst) { ns_put16(src, dst); } 25984309Sluigi#ifndef __ultrix__ 26084309Sluigiu_int32_t _getlong(const u_char *src) { return (ns_get32(src)); } 26184309Sluigiu_int16_t _getshort(const u_char *src) { return (ns_get16(src)); } 26284309Sluigi#endif /*__ultrix__*/ 26384309Sluigi#endif /*BIND_4_COMPAT*/ 26484309Sluigi