diff --git a/lib/libc/net/Makefile.inc b/lib/libc/net/Makefile.inc index 112e7a4ec144..43de58fc69b4 100644 --- a/lib/libc/net/Makefile.inc +++ b/lib/libc/net/Makefile.inc @@ -1,51 +1,53 @@ # @(#)Makefile.inc 8.2 (Berkeley) 9/5/93 # machine-independent net sources .PATH: ${.CURDIR}/${MACHINE}/net ${.CURDIR}/net -SRCS+= addr2ascii.c ascii2addr.c \ +SRCS+= addr2ascii.c ascii2addr.c base64.c \ gethostbydns.c gethostbyht.c gethostbynis.c gethostnamadr.c \ getnetbydns.c getnetbyht.c getnetbynis.c getnetnamadr.c \ getproto.c getprotoent.c getprotoname.c getservbyname.c \ getservbyport.c getservent.c herror.c inet_addr.c inet_lnaof.c \ inet_makeaddr.c inet_netof.c inet_network.c inet_ntoa.c inet_ntop.c \ + inet_net_ntop.c inet_net_pton.c inet_neta.c \ inet_pton.c linkaddr.c map_v4v6.c nsap_addr.c \ rcmd.c recv.c res_comp.c res_data.c res_debug.c \ - res_init.c res_mkquery.c res_query.c res_send.c send.c ether_addr.c \ - ns_addr.c ns_ntoa.c + res_init.c res_mkquery.c res_query.c res_send.c res_stubs.c \ + send.c ether_addr.c \ + ns_addr.c ns_ntoa.c # iso_addr.c # machine-dependent net sources .include "${.CURDIR}/${MACHINE}/net/Makefile.inc" MAN3+= net/addr2ascii.3 \ net/byteorder.3 net/ethers.3 net/gethostbyname.3 net/getnetent.3 \ net/getprotoent.3 net/getservent.3 net/inet.3 net/linkaddr.3 \ net/rcmd.3 resolver.3 # not installed: net/ns.3 net/iso_addr.3 MLINKS+=addr2ascii.3 ascii2addr.3 MLINKS+=byteorder.3 htonl.3 byteorder.3 htons.3 byteorder.3 ntohl.3 \ byteorder.3 ntohs.3 MLINKS+=ethers.3 ether_line.3 ethers.3 ether_aton.3 ethers.3 ether_ntoa.3 \ ethers.3 ether_ntohost.3 ethers.3 ether_hostton.3 MLINKS+=gethostbyname.3 endhostent.3 gethostbyname.3 gethostbyaddr.3 \ gethostbyname.3 sethostent.3 gethostbyname.3 gethostent.3 \ gethostbyname.3 herror.3 gethostbyname.3 hstrerror.3 \ gethostbyname.3 gethostbyname2.3 MLINKS+=getnetent.3 endnetent.3 getnetent.3 getnetbyaddr.3 \ getnetent.3 getnetbyname.3 getnetent.3 setnetent.3 MLINKS+=getprotoent.3 endprotoent.3 getprotoent.3 getprotobyname.3 \ getprotoent.3 getprotobynumber.3 getprotoent.3 setprotoent.3 MLINKS+=getservent.3 endservent.3 getservent.3 getservbyname.3 \ getservent.3 getservbyport.3 getservent.3 setservent.3 MLINKS+=inet.3 addr.3 inet.3 inet_addr.3 inet.3 inet_lnaof.3 \ inet.3 inet_makeaddr.3 inet.3 inet_netof.3 inet.3 inet_network.3 \ inet.3 inet_ntoa.3 inet.3 network.3 inet.3 ntoa.3 inet.3 inet_aton.3 MLINKS+=linkaddr.3 link_addr.3 linkaddr.3 link_ntoa.3 #MLINKS+=ns.3 ns_addr.3 ns.3 ns_ntoa.3 MLINKS+=rcmd.3 rresvport.3 rcmd.3 iruserok.3 rcmd.3 ruserok.3 MLINKS+=resolver.3 dn_comp.3 resolver.3 dn_expand.3 resolver.3 res_init.3 \ resolver.3 res_mkquery.3 resolver.3 res_send.3 resolver.3 res_query.3 \ resolver.3 res_search.3 diff --git a/lib/libc/net/base64.c b/lib/libc/net/base64.c new file mode 100644 index 000000000000..868826a777dc --- /dev/null +++ b/lib/libc/net/base64.c @@ -0,0 +1,321 @@ +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +/* + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software. No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#if defined(BSD) && (BSD >= 199103) && defined(AF_INET6) +# include +# include +#else +# include "../conf/portability.h" +#endif + +#define Assert(Cond) if (!(Cond)) abort() + +static const char Base64[] = + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; +static const char Pad64 = '='; + +/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt) + The following encoding technique is taken from RFC 1521 by Borenstein + and Freed. It is reproduced here in a slightly edited form for + convenience. + + A 65-character subset of US-ASCII is used, enabling 6 bits to be + represented per printable character. (The extra 65th character, "=", + is used to signify a special processing function.) + + The encoding process represents 24-bit groups of input bits as output + strings of 4 encoded characters. Proceeding from left to right, a + 24-bit input group is formed by concatenating 3 8-bit input groups. + These 24 bits are then treated as 4 concatenated 6-bit groups, each + of which is translated into a single digit in the base64 alphabet. + + Each 6-bit group is used as an index into an array of 64 printable + characters. The character referenced by the index is placed in the + output string. + + Table 1: The Base64 Alphabet + + Value Encoding Value Encoding Value Encoding Value Encoding + 0 A 17 R 34 i 51 z + 1 B 18 S 35 j 52 0 + 2 C 19 T 36 k 53 1 + 3 D 20 U 37 l 54 2 + 4 E 21 V 38 m 55 3 + 5 F 22 W 39 n 56 4 + 6 G 23 X 40 o 57 5 + 7 H 24 Y 41 p 58 6 + 8 I 25 Z 42 q 59 7 + 9 J 26 a 43 r 60 8 + 10 K 27 b 44 s 61 9 + 11 L 28 c 45 t 62 + + 12 M 29 d 46 u 63 / + 13 N 30 e 47 v + 14 O 31 f 48 w (pad) = + 15 P 32 g 49 x + 16 Q 33 h 50 y + + Special processing is performed if fewer than 24 bits are available + at the end of the data being encoded. A full encoding quantum is + always completed at the end of a quantity. When fewer than 24 input + bits are available in an input group, zero bits are added (on the + right) to form an integral number of 6-bit groups. Padding at the + end of the data is performed using the '=' character. + + Since all base64 input is an integral number of octets, only the + ------------------------------------------------- + following cases can arise: + + (1) the final quantum of encoding input is an integral + multiple of 24 bits; here, the final unit of encoded + output will be an integral multiple of 4 characters + with no "=" padding, + (2) the final quantum of encoding input is exactly 8 bits; + here, the final unit of encoded output will be two + characters followed by two "=" padding characters, or + (3) the final quantum of encoding input is exactly 16 bits; + here, the final unit of encoded output will be three + characters followed by one "=" padding character. + */ + +int +b64_ntop(src, srclength, target, targsize) + u_char const *src; + size_t srclength; + char *target; + size_t targsize; +{ + size_t datalength = 0; + u_char input[3]; + u_char output[4]; + int i; + + while (2 < srclength) { + input[0] = *src++; + input[1] = *src++; + input[2] = *src++; + srclength -= 3; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + output[3] = input[2] & 0x3f; + Assert(output[0] < 64); + Assert(output[1] < 64); + Assert(output[2] < 64); + Assert(output[3] < 64); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + target[datalength++] = Base64[output[2]]; + target[datalength++] = Base64[output[3]]; + } + + /* Now we worry about padding. */ + if (0 != srclength) { + /* Get what's left. */ + input[0] = input[1] = input[2] = '\0'; + for (i = 0; i < srclength; i++) + input[i] = *src++; + + output[0] = input[0] >> 2; + output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4); + output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6); + Assert(output[0] < 64); + Assert(output[1] < 64); + Assert(output[2] < 64); + + if (datalength + 4 > targsize) + return (-1); + target[datalength++] = Base64[output[0]]; + target[datalength++] = Base64[output[1]]; + if (srclength == 1) + target[datalength++] = Pad64; + else + target[datalength++] = Base64[output[2]]; + target[datalength++] = Pad64; + } + if (datalength >= targsize) + return (-1); + target[datalength] = '\0'; /* Returned value doesn't count \0. */ + return (datalength); +} + +/* skips all whitespace anywhere. + converts characters, four at a time, starting at (or after) + src from base - 64 numbers into three 8 bit bytes in the target area. + it returns the number of data bytes stored at the target, or -1 on error. + */ + +int +b64_pton(src, target, targsize) + char const *src; + u_char *target; + size_t targsize; +{ + int tarindex, state, ch; + char *pos; + + state = 0; + tarindex = 0; + + while ((ch = *src++) != '\0') { + if (isspace(ch)) /* Skip whitespace anywhere. */ + continue; + + if (ch == Pad64) + break; + + pos = strchr(Base64, ch); + if (pos == 0) /* A non-base64 character. */ + return (-1); + + switch (state) { + case 0: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] = (pos - Base64) << 2; + } + state = 1; + break; + case 1: + if (target) { + if (tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 4; + target[tarindex+1] = ((pos - Base64) & 0x0f) + << 4 ; + } + tarindex++; + state = 2; + break; + case 2: + if (target) { + if (tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (pos - Base64) >> 2; + target[tarindex+1] = ((pos - Base64) & 0x03) + << 6; + } + tarindex++; + state = 3; + break; + case 3: + if (target) { + if (tarindex >= targsize) + return (-1); + target[tarindex] |= (pos - Base64); + } + tarindex++; + state = 0; + break; + default: + abort(); + } + } + + /* + * We are done decoding Base-64 chars. Let's see if we ended + * on a byte boundary, and/or with erroneous trailing characters. + */ + + if (ch == Pad64) { /* We got a pad char. */ + ch = *src++; /* Skip it, get next. */ + switch (state) { + case 0: /* Invalid = in first position */ + case 1: /* Invalid = in second position */ + return (-1); + + case 2: /* Valid, means one byte of info */ + /* Skip any number of spaces. */ + for (NULL; ch != '\0'; ch = *src++) + if (!isspace(ch)) + break; + /* Make sure there is another trailing = sign. */ + if (ch != Pad64) + return (-1); + ch = *src++; /* Skip the = */ + /* Fall through to "single trailing =" case. */ + /* FALLTHROUGH */ + + case 3: /* Valid, means two bytes of info */ + /* + * We know this char is an =. Is there anything but + * whitespace after it? + */ + for (NULL; ch != '\0'; ch = *src++) + if (!isspace(ch)) + return (-1); + + /* + * Now make sure for cases 2 and 3 that the "extra" + * bits that slopped past the last full byte were + * zeros. If we don't check them, they become a + * subliminal channel. + */ + if (target && target[tarindex] != 0) + return (-1); + } + } else { + /* + * We ended by seeing the end of the string. Make sure we + * have no partial bytes lying around. + */ + if (state != 0) + return (-1); + } + + return (tarindex); +} diff --git a/lib/libc/net/gethostbydns.c b/lib/libc/net/gethostbydns.c index 2808c9518eed..f25abfc29ff1 100644 --- a/lib/libc/net/gethostbydns.c +++ b/lib/libc/net/gethostbydns.c @@ -1,688 +1,719 @@ -/*- +/* + * ++Copyright++ 1985, 1988, 1993 + * - * Copyright (c) 1985, 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Portions Copyright (c) 1993 by Digital Equipment Corporation. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. * - * --Copyright-- */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id: gethostbydns.c,v 1.14 1996/12/24 02:10:24 wpaul Exp $"; +static char fromrcsid[] = "From: Id: gethnamaddr.c,v 8.20 1996/09/28 06:51:07 vixie Exp"; +static char rcsid[] = "$Id: gethostbydns.c,v 1.15 1996/12/27 18:21:05 wpaul Exp $"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "res_config.h" -extern void _res_close __P((void)); - #define SPRINTF(x) ((size_t)sprintf x) #define MAXALIASES 35 #define MAXADDRS 35 static const char AskedForGot[] = "gethostby*.gethostanswer: asked for \"%s\", got \"%s\""; static char *h_addr_ptrs[MAXADDRS + 1]; -static struct hostent *gethostbyname_ipv4 __P((const char *)); static struct hostent host; static char *host_aliases[MAXALIASES]; static char hostbuf[8*1024]; static u_char host_addr[16]; /* IPv4 or IPv6 */ #ifdef RESOLVSORT static void addrsort __P((char **, int)); #endif #if PACKETSZ > 1024 #define MAXPACKET PACKETSZ #else #define MAXPACKET 1024 #endif typedef union { HEADER hdr; u_char buf[MAXPACKET]; } querybuf; typedef union { int32_t al; char ac; } align; extern int h_errno; int _dns_ttl_; #ifdef DEBUG static void dprintf(msg, num) char *msg; int num; { if (_res.options & RES_DEBUG) { int save = errno; printf(msg, num); errno = save; } } #else # define dprintf(msg, num) /*nada*/ #endif static struct hostent * gethostanswer(answer, anslen, qname, qtype) const querybuf *answer; int anslen; const char *qname; int qtype; { register const HEADER *hp; register const u_char *cp; register int n; const u_char *eom; char *bp, **ap, **hap; int type, class, buflen, ancount, qdcount; int haveanswer, had_error; int toobig = 0; - char tbuf[MAXDNAME+1]; + char tbuf[MAXDNAME]; const char *tname; int (*name_ok) __P((const char *)); tname = qname; host.h_name = NULL; eom = answer->buf + anslen; switch (qtype) { case T_A: case T_AAAA: name_ok = res_hnok; break; case T_PTR: name_ok = res_dnok; break; default: h_errno = NO_RECOVERY; return (NULL); /* XXX should be abort(); */ } /* * find first satisfactory answer */ hp = &answer->hdr; ancount = ntohs(hp->ancount); qdcount = ntohs(hp->qdcount); bp = hostbuf; buflen = sizeof hostbuf; cp = answer->buf + HFIXEDSZ; if (qdcount != 1) { h_errno = NO_RECOVERY; return (NULL); } n = dn_expand(answer->buf, eom, cp, bp, buflen); if ((n < 0) || !(*name_ok)(bp)) { h_errno = NO_RECOVERY; return (NULL); } cp += n + QFIXEDSZ; if (qtype == T_A || qtype == T_AAAA) { /* res_send() has already verified that the query name is the * same as the one we sent; this just gets the expanded name * (i.e., with the succeeding search-domain tacked on). */ n = strlen(bp) + 1; /* for the \0 */ host.h_name = bp; bp += n; buflen -= n; /* The qname can be abbreviated, but h_name is now absolute. */ qname = host.h_name; } ap = host_aliases; *ap = NULL; host.h_aliases = host_aliases; hap = h_addr_ptrs; *hap = NULL; host.h_addr_list = h_addr_ptrs; haveanswer = 0; had_error = 0; _dns_ttl_ = -1; while (ancount-- > 0 && cp < eom && !had_error) { n = dn_expand(answer->buf, eom, cp, bp, buflen); if ((n < 0) || !(*name_ok)(bp)) { had_error++; continue; } cp += n; /* name */ type = _getshort(cp); cp += INT16SZ; /* type */ class = _getshort(cp); cp += INT16SZ; /* class */ if (qtype == T_A && type == T_A) _dns_ttl_ = _getlong(cp); cp += INT32SZ; /* TTL */ n = _getshort(cp); cp += INT16SZ; /* len */ if (class != C_IN) { /* XXX - debug? syslog? */ cp += n; continue; /* XXX - had_error++ ? */ } if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) { if (ap >= &host_aliases[MAXALIASES-1]) continue; n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); if ((n < 0) || !(*name_ok)(tbuf)) { had_error++; continue; } cp += n; /* Store alias. */ *ap++ = bp; n = strlen(bp) + 1; /* for the \0 */ bp += n; buflen -= n; /* Get canonical name. */ n = strlen(tbuf) + 1; /* for the \0 */ if (n > buflen) { had_error++; continue; } strcpy(bp, tbuf); host.h_name = bp; bp += n; buflen -= n; continue; } if (qtype == T_PTR && type == T_CNAME) { n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf); if ((n < 0) || !res_hnok(tbuf)) { had_error++; continue; } cp += n; /* Get canonical name. */ n = strlen(tbuf) + 1; /* for the \0 */ if (n > buflen) { had_error++; continue; } strcpy(bp, tbuf); tname = bp; bp += n; buflen -= n; continue; } if (type != qtype) { syslog(LOG_NOTICE|LOG_AUTH, - "gethostby*.gethostanswer: asked for \"%s %s %s\", got type \"%s\"", + "gethostby*.gethostanswer: asked for \"%s %s %s\", got type \"%s\"", qname, p_class(C_IN), p_type(qtype), p_type(type)); cp += n; continue; /* XXX - had_error++ ? */ } switch (type) { case T_PTR: if (strcasecmp(tname, bp) != 0) { syslog(LOG_NOTICE|LOG_AUTH, AskedForGot, qname, bp); cp += n; continue; /* XXX - had_error++ ? */ } n = dn_expand(answer->buf, eom, cp, bp, buflen); if ((n < 0) || !res_hnok(bp)) { had_error++; break; } #if MULTI_PTRS_ARE_ALIASES cp += n; if (!haveanswer) host.h_name = bp; else if (ap < &host_aliases[MAXALIASES-1]) *ap++ = bp; else n = -1; if (n != -1) { n = strlen(bp) + 1; /* for the \0 */ bp += n; buflen -= n; } break; #else host.h_name = bp; if (_res.options & RES_USE_INET6) { n = strlen(bp) + 1; /* for the \0 */ bp += n; buflen -= n; _map_v4v6_hostent(&host, &bp, &buflen); } h_errno = NETDB_SUCCESS; return (&host); #endif case T_A: case T_AAAA: if (strcasecmp(host.h_name, bp) != 0) { syslog(LOG_NOTICE|LOG_AUTH, AskedForGot, host.h_name, bp); cp += n; continue; /* XXX - had_error++ ? */ } if (n != host.h_length) { cp += n; continue; } if (!haveanswer) { register int nn; host.h_name = bp; nn = strlen(bp) + 1; /* for the \0 */ bp += nn; buflen -= nn; } bp += sizeof(align) - ((u_long)bp % sizeof(align)); if (bp + n >= &hostbuf[sizeof hostbuf]) { dprintf("size (%d) too big\n", n); had_error++; continue; } if (hap >= &h_addr_ptrs[MAXADDRS-1]) { if (!toobig++) dprintf("Too many addresses (%d)\n", MAXADDRS); cp += n; continue; } bcopy(cp, *hap++ = bp, n); bp += n; buflen -= n; cp += n; break; default: dprintf("Impossible condition (type=%d)\n", type); h_errno = NO_RECOVERY; return (NULL); - } /*switch*/ + /* BIND has abort() here, too risky on bad data */ + } if (!had_error) haveanswer++; - } /*while*/ + } if (haveanswer) { *ap = NULL; *hap = NULL; # if defined(RESOLVSORT) /* * Note: we sort even if host can take only one address * in its return structures - should give it the "best" * address in that case, not some random one */ if (_res.nsort && haveanswer > 1 && qtype == T_A) addrsort(h_addr_ptrs, haveanswer); # endif /*RESOLVSORT*/ if (!host.h_name) { n = strlen(qname) + 1; /* for the \0 */ if (n > buflen) goto try_again; strcpy(bp, qname); host.h_name = bp; bp += n; buflen -= n; } if (_res.options & RES_USE_INET6) _map_v4v6_hostent(&host, &bp, &buflen); h_errno = NETDB_SUCCESS; return (&host); } try_again: h_errno = TRY_AGAIN; return (NULL); } struct hostent * __dns_getanswer(answer, anslen, qname, qtype) const char *answer; int anslen; const char *qname; int qtype; { switch(qtype) { case T_AAAA: host.h_addrtype = AF_INET6; host.h_length = IN6ADDRSZ; break; case T_A: default: host.h_addrtype = AF_INET; host.h_length = INADDRSZ; break; } return(gethostanswer((const querybuf *)answer, anslen, qname, qtype)); } struct hostent * _gethostbydnsname(name, af) const char *name; int af; { querybuf buf; register const char *cp; char *bp; int n, size, type, len; if ((_res.options & RES_INIT) == 0 && res_init() == -1) { h_errno = NETDB_INTERNAL; return (NULL); } switch (af) { case AF_INET: size = INADDRSZ; type = T_A; break; case AF_INET6: size = IN6ADDRSZ; type = T_AAAA; break; default: h_errno = NETDB_INTERNAL; errno = EAFNOSUPPORT; return (NULL); } host.h_addrtype = af; host.h_length = size; /* * if there aren't any dots, it could be a user-level alias. * this is also done in res_query() since we are not the only * function that looks up host names. */ if (!strchr(name, '.') && (cp = __hostalias(name))) name = cp; /* * disallow names consisting only of digits/dots, unless * they end in a dot. */ if (isdigit(name[0])) for (cp = name;; ++cp) { if (!*cp) { if (*--cp == '.') break; /* * All-numeric, no dot at the end. * Fake up a hostent as if we'd actually * done a lookup. */ if (inet_pton(af, name, host_addr) <= 0) { h_errno = HOST_NOT_FOUND; return (NULL); } strncpy(hostbuf, name, MAXDNAME); hostbuf[MAXDNAME] = '\0'; bp = hostbuf + MAXDNAME; len = sizeof hostbuf - MAXDNAME; host.h_name = hostbuf; host.h_aliases = host_aliases; host_aliases[0] = NULL; h_addr_ptrs[0] = (char *)host_addr; h_addr_ptrs[1] = NULL; host.h_addr_list = h_addr_ptrs; if (_res.options & RES_USE_INET6) _map_v4v6_hostent(&host, &bp, &len); h_errno = NETDB_SUCCESS; return (&host); } if (!isdigit(*cp) && *cp != '.') break; } + if (isxdigit(name[0]) || name[0] == ':') + for (cp = name;; ++cp) { + if (!*cp) { + if (*--cp == '.') + break; + /* + * All-IPv6-legal, no dot at the end. + * Fake up a hostent as if we'd actually + * done a lookup. + */ + if (inet_pton(af, name, host_addr) <= 0) { + h_errno = HOST_NOT_FOUND; + return (NULL); + } + strncpy(hostbuf, name, MAXDNAME); + hostbuf[MAXDNAME] = '\0'; + bp = hostbuf + MAXDNAME; + len = sizeof hostbuf - MAXDNAME; + host.h_name = hostbuf; + host.h_aliases = host_aliases; + host_aliases[0] = NULL; + h_addr_ptrs[0] = (char *)host_addr; + h_addr_ptrs[1] = NULL; + host.h_addr_list = h_addr_ptrs; + h_errno = NETDB_SUCCESS; + return (&host); + } + if (!isxdigit(*cp) && *cp != ':' && *cp != '.') + break; + } if ((n = res_search(name, C_IN, type, buf.buf, sizeof(buf))) < 0) { dprintf("res_search failed (%d)\n", n); return (NULL); } return (gethostanswer(&buf, n, name, type)); } struct hostent * _gethostbydnsaddr(addr, len, af) const char *addr; /* XXX should have been def'd as u_char! */ int len, af; { const u_char *uaddr = (const u_char *)addr; static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff }; static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 }; int n, size; querybuf buf; register struct hostent *hp; char qbuf[MAXDNAME+1], *qp; #ifdef SUNSECURITY register struct hostent *rhp; char **haddr; u_long old_options; char hname2[MAXDNAME+1]; #endif /*SUNSECURITY*/ if ((_res.options & RES_INIT) == 0 && res_init() == -1) { h_errno = NETDB_INTERNAL; return (NULL); } if (af == AF_INET6 && len == IN6ADDRSZ && (!bcmp(uaddr, mapped, sizeof mapped) || !bcmp(uaddr, tunnelled, sizeof tunnelled))) { /* Unmap. */ addr += sizeof mapped; uaddr += sizeof mapped; af = AF_INET; len = INADDRSZ; } switch (af) { case AF_INET: size = INADDRSZ; break; case AF_INET6: size = IN6ADDRSZ; break; default: errno = EAFNOSUPPORT; h_errno = NETDB_INTERNAL; return (NULL); } if (size != len) { errno = EINVAL; h_errno = NETDB_INTERNAL; return (NULL); } switch (af) { case AF_INET: (void) sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", (uaddr[3] & 0xff), (uaddr[2] & 0xff), (uaddr[1] & 0xff), (uaddr[0] & 0xff)); break; case AF_INET6: qp = qbuf; for (n = IN6ADDRSZ - 1; n >= 0; n--) { qp += SPRINTF((qp, "%x.%x.", uaddr[n] & 0xf, (uaddr[n] >> 4) & 0xf)); } strcpy(qp, "ip6.int"); break; default: abort(); } n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf); if (n < 0) { dprintf("res_query failed (%d)\n", n); return (NULL); } if (!(hp = gethostanswer(&buf, n, qbuf, T_PTR))) return (NULL); /* h_errno was set by gethostanswer() */ #ifdef SUNSECURITY if (af == AF_INET) { /* * turn off search as the name should be absolute, * 'localhost' should be matched by defnames */ strncpy(hname2, hp->h_name, MAXDNAME); hname2[MAXDNAME] = '\0'; old_options = _res.options; _res.options &= ~RES_DNSRCH; _res.options |= RES_DEFNAMES; if (!(rhp = gethostbyname(hname2))) { syslog(LOG_NOTICE|LOG_AUTH, "gethostbyaddr: No A record for %s (verifying [%s])", hname2, inet_ntoa(*((struct in_addr *)addr))); _res.options = old_options; h_errno = HOST_NOT_FOUND; return (NULL); } _res.options = old_options; for (haddr = rhp->h_addr_list; *haddr; haddr++) if (!memcmp(*haddr, addr, INADDRSZ)) break; if (!*haddr) { syslog(LOG_NOTICE|LOG_AUTH, "gethostbyaddr: A record of %s != PTR record [%s]", hname2, inet_ntoa(*((struct in_addr *)addr))); h_errno = HOST_NOT_FOUND; return (NULL); } } #endif /*SUNSECURITY*/ hp->h_addrtype = af; hp->h_length = len; bcopy(addr, host_addr, len); h_addr_ptrs[0] = (char *)host_addr; h_addr_ptrs[1] = NULL; if (af == AF_INET && (_res.options & RES_USE_INET6)) { _map_v4v6_address((char*)host_addr, (char*)host_addr); hp->h_addrtype = AF_INET6; hp->h_length = IN6ADDRSZ; } h_errno = NETDB_SUCCESS; return (hp); } #ifdef RESOLVSORT static void addrsort(ap, num) char **ap; int num; { int i, j; char **p; short aval[MAXADDRS]; int needsort = 0; p = ap; for (i = 0; i < num; i++, p++) { for (j = 0 ; (unsigned)j < _res.nsort; j++) if (_res.sort_list[j].addr.s_addr == (((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask)) break; aval[i] = j; if (needsort == 0 && i > 0 && j < aval[i-1]) needsort = i; } if (!needsort) return; while (needsort < num) { for (j = needsort - 1; j >= 0; j--) { if (aval[j] > aval[j+1]) { char *hp; i = aval[j]; aval[j] = aval[j+1]; aval[j+1] = i; hp = ap[j]; ap[j] = ap[j+1]; ap[j+1] = hp; } else break; } needsort++; } } #endif void _sethostdnsent(stayopen) int stayopen; { if ((_res.options & RES_INIT) == 0 && res_init() == -1) return; if (stayopen) _res.options |= RES_STAYOPEN | RES_USEVC; } void _endhostdnsent() { _res.options &= ~(RES_STAYOPEN | RES_USEVC); _res_close(); } diff --git a/lib/libc/net/gethostbyht.c b/lib/libc/net/gethostbyht.c index 3623ced42d76..77d0b3c41bc4 100644 --- a/lib/libc/net/gethostbyht.c +++ b/lib/libc/net/gethostbyht.c @@ -1,210 +1,209 @@ /*- * Copyright (c) 1985, 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Portions Copyright (c) 1993 by Digital Equipment Corporation. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. * - * --Copyright-- */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id: gethostbyht.c,v 1.5 1996/08/29 20:07:51 peter Exp $"; +static char rcsid[] = "$Id: gethostbyht.c,v 1.6 1996/08/30 00:26:49 peter Exp $"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include #include #include #include #include /* XXX */ #include /* XXX */ #define MAXALIASES 35 static struct hostent host; static char *host_aliases[MAXALIASES]; static char hostbuf[BUFSIZ+1]; static FILE *hostf = NULL; static u_char host_addr[16]; /* IPv4 or IPv6 */ static char *h_addr_ptrs[2]; static int stayopen = 0; void _sethosthtent(f) int f; { if (!hostf) hostf = fopen(_PATH_HOSTS, "r" ); else rewind(hostf); - stayopen |= f; + stayopen = f; } void _endhosthtent() { if (hostf && !stayopen) { (void) fclose(hostf); hostf = NULL; } } struct hostent * gethostent() { char *p; register char *cp, **q; int af, len; if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) { h_errno = NETDB_INTERNAL; return (NULL); } again: if (!(p = fgets(hostbuf, sizeof hostbuf, hostf))) { h_errno = HOST_NOT_FOUND; return (NULL); } if (*p == '#') goto again; if (!(cp = strpbrk(p, "#\n"))) goto again; *cp = '\0'; if (!(cp = strpbrk(p, " \t"))) goto again; *cp++ = '\0'; if ((_res.options & RES_USE_INET6) && inet_pton(AF_INET6, p, host_addr) > 0) { af = AF_INET6; len = IN6ADDRSZ; } else if (inet_pton(AF_INET, p, host_addr) > 0) { if (_res.options & RES_USE_INET6) { _map_v4v6_address((char*)host_addr, (char*)host_addr); af = AF_INET6; len = IN6ADDRSZ; } else { af = AF_INET; len = INADDRSZ; } } else { goto again; } h_addr_ptrs[0] = (char *)host_addr; h_addr_ptrs[1] = NULL; host.h_addr_list = h_addr_ptrs; host.h_length = len; host.h_addrtype = af; while (*cp == ' ' || *cp == '\t') cp++; host.h_name = cp; q = host.h_aliases = host_aliases; - if (cp = strpbrk(cp, " \t")) + if ((cp = strpbrk(cp, " \t")) != NULL) *cp++ = '\0'; while (cp && *cp) { if (*cp == ' ' || *cp == '\t') { cp++; continue; } if (q < &host_aliases[MAXALIASES - 1]) *q++ = cp; - if (cp = strpbrk(cp, " \t")) + if ((cp = strpbrk(cp, " \t")) != NULL) *cp++ = '\0'; } *q = NULL; if (_res.options & RES_USE_INET6) { char *bp = hostbuf; int buflen = sizeof hostbuf; _map_v4v6_hostent(&host, &bp, &buflen); } h_errno = NETDB_SUCCESS; return (&host); } struct hostent * _gethostbyhtname(name, af) const char *name; int af; { register struct hostent *p; register char **cp; sethostent(0); - while ( (p = gethostent()) ) { + while ((p = gethostent()) != NULL) { if (p->h_addrtype != af) continue; if (strcasecmp(p->h_name, name) == 0) break; for (cp = p->h_aliases; *cp != 0; cp++) if (strcasecmp(*cp, name) == 0) goto found; } found: endhostent(); return (p); } struct hostent * _gethostbyhtaddr(addr, len, af) const char *addr; int len, af; { register struct hostent *p; sethostent(0); - while ( (p = gethostent()) ) + while ((p = gethostent()) != NULL) if (p->h_addrtype == af && !bcmp(p->h_addr, addr, len)) break; endhostent(); return (p); } - diff --git a/lib/libc/net/getnetbydns.c b/lib/libc/net/getnetbydns.c index 1f7607b2012a..d3f031c39e5f 100644 --- a/lib/libc/net/getnetbydns.c +++ b/lib/libc/net/getnetbydns.c @@ -1,311 +1,310 @@ /*- * Copyright (c) 1985, 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Portions Copyright (c) 1993 by Digital Equipment Corporation. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. * - * --Copyright-- */ /* Portions Copyright (c) 1993 Carlos Leandro and Rui Salgueiro * Dep. Matematica Universidade de Coimbra, Portugal, Europe * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id: getnetbydns.c,v 1.6 1996/07/12 18:54:37 jkh Exp $"; +static char rcsid[] = "$Id: getnetbydns.c,v 1.7 1996/08/29 20:07:58 peter Exp $"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include "res_config.h" -extern void _res_close __P((void)); extern int h_errno; #define BYADDR 0 #define BYNAME 1 #define MAXALIASES 35 #if PACKETSZ > 1024 #define MAXPACKET PACKETSZ #else #define MAXPACKET 1024 #endif typedef union { HEADER hdr; u_char buf[MAXPACKET]; } querybuf; typedef union { long al; char ac; } align; static struct netent * getnetanswer(answer, anslen, net_i) querybuf *answer; int anslen; int net_i; { register HEADER *hp; register u_char *cp; register int n; u_char *eom; int type, class, buflen, ancount, qdcount, haveanswer, i, nchar; char aux1[30], aux2[30], ans[30], *in, *st, *pauxt, *bp, **ap, *paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0; static struct netent net_entry; static char *net_aliases[MAXALIASES], netbuf[BUFSIZ+1]; /* * find first satisfactory answer * * answer --> +------------+ ( MESSAGE ) * | Header | * +------------+ * | Question | the question for the name server * +------------+ * | Answer | RRs answering the question * +------------+ * | Authority | RRs pointing toward an authority * | Additional | RRs holding additional information * +------------+ */ eom = answer->buf + anslen; hp = &answer->hdr; ancount = ntohs(hp->ancount); /* #/records in the answer section */ qdcount = ntohs(hp->qdcount); /* #/entries in the question section */ bp = netbuf; buflen = sizeof(netbuf); cp = answer->buf + HFIXEDSZ; if (!qdcount) { if (hp->aa) h_errno = HOST_NOT_FOUND; else h_errno = TRY_AGAIN; return (NULL); } while (qdcount-- > 0) cp += __dn_skipname(cp, eom) + QFIXEDSZ; ap = net_aliases; *ap = NULL; net_entry.n_aliases = net_aliases; haveanswer = 0; while (--ancount >= 0 && cp < eom) { n = dn_expand(answer->buf, eom, cp, bp, buflen); if ((n < 0) || !res_dnok(bp)) break; cp += n; ans[0] = '\0'; (void)strcpy(&ans[0], bp); GETSHORT(type, cp); GETSHORT(class, cp); cp += INT32SZ; /* TTL */ GETSHORT(n, cp); if (class == C_IN && type == T_PTR) { n = dn_expand(answer->buf, eom, cp, bp, buflen); if ((n < 0) || !res_hnok(bp)) { cp += n; return (NULL); } cp += n; *ap++ = bp; bp += strlen(bp) + 1; net_entry.n_addrtype = (class == C_IN) ? AF_INET : AF_UNSPEC; haveanswer++; } } if (haveanswer) { *ap = NULL; switch (net_i) { case BYADDR: net_entry.n_name = *net_entry.n_aliases; net_entry.n_net = 0L; break; case BYNAME: in = *net_entry.n_aliases; net_entry.n_name = &ans[0]; aux2[0] = '\0'; for (i = 0; i < 4; i++) { for (st = in, nchar = 0; *st != '.'; st++, nchar++) ; if (nchar != 1 || *in != '0' || flag) { flag = 1; (void)strncpy(paux1, (i==0) ? in : in-1, (i==0) ?nchar : nchar+1); paux1[(i==0) ? nchar : nchar+1] = '\0'; pauxt = paux2; paux2 = strcat(paux1, paux2); paux1 = pauxt; } in = ++st; } net_entry.n_net = inet_network(paux2); break; } net_entry.n_aliases++; return (&net_entry); } h_errno = TRY_AGAIN; return (NULL); } struct netent * _getnetbydnsaddr(net, net_type) register unsigned long net; register int net_type; { unsigned int netbr[4]; int nn, anslen; querybuf buf; char qbuf[MAXDNAME]; unsigned long net2; struct netent *net_entry; if (net_type != AF_INET) return (NULL); for (nn = 4, net2 = net; net2; net2 >>= 8) netbr[--nn] = net2 & 0xff; switch (nn) { case 3: /* Class A */ sprintf(qbuf, "0.0.0.%u.in-addr.arpa", netbr[3]); break; case 2: /* Class B */ sprintf(qbuf, "0.0.%u.%u.in-addr.arpa", netbr[3], netbr[2]); break; case 1: /* Class C */ sprintf(qbuf, "0.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2], netbr[1]); break; case 0: /* Class D - E */ sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2], netbr[1], netbr[0]); break; } anslen = res_query(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf)); if (anslen < 0) { #ifdef DEBUG if (_res.options & RES_DEBUG) printf("res_query failed\n"); #endif return (NULL); } net_entry = getnetanswer(&buf, anslen, BYADDR); if (net_entry) { unsigned u_net = net; /* maybe net should be unsigned ? */ /* Strip trailing zeros */ while ((u_net & 0xff) == 0 && u_net != 0) u_net >>= 8; net_entry->n_net = u_net; return (net_entry); } return (NULL); } struct netent * _getnetbydnsname(net) register const char *net; { int anslen; querybuf buf; char qbuf[MAXDNAME]; if ((_res.options & RES_INIT) == 0 && res_init() == -1) { h_errno = NETDB_INTERNAL; return (NULL); } strcpy(&qbuf[0], net); anslen = res_search(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf)); if (anslen < 0) { #ifdef DEBUG if (_res.options & RES_DEBUG) printf("res_query failed\n"); #endif return (NULL); } return getnetanswer(&buf, anslen, BYNAME); } void _setnetdnsent(stayopen) int stayopen; { if (stayopen) _res.options |= RES_STAYOPEN | RES_USEVC; } void _endnetdnsent() { _res.options &= ~(RES_STAYOPEN | RES_USEVC); - _res_close(); + res_close(); } diff --git a/lib/libc/net/getnetnamadr.c b/lib/libc/net/getnetnamadr.c index b0e7468babed..9e5fce14d8b7 100644 --- a/lib/libc/net/getnetnamadr.c +++ b/lib/libc/net/getnetnamadr.c @@ -1,191 +1,191 @@ /*- * Copyright (c) 1994, Garrett Wollman * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)$Id: getnetnamadr.c,v 1.5 1996/07/12 18:54:40 jkh Exp $"; -static char rcsid[] = "$Id: getnetnamadr.c,v 1.5 1996/07/12 18:54:40 jkh Exp $"; +static char sccsid[] = "@(#)$Id: getnetnamadr.c,v 1.6 1996/08/29 20:08:04 peter Exp $"; +static char rcsid[] = "$Id: getnetnamadr.c,v 1.6 1996/08/29 20:08:04 peter Exp $"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include #include #include #include #ifndef _PATH_NETCONF #define _PATH_NETCONF "/etc/host.conf" #endif enum service_type { SERVICE_NONE = 0, SERVICE_BIND, SERVICE_TABLE, SERVICE_NIS }; #define SERVICE_MAX SERVICE_NIS static struct { const char *name; enum service_type type; } service_names[] = { { "hosts", SERVICE_TABLE }, { "/etc/hosts", SERVICE_TABLE }, { "hosttable", SERVICE_TABLE }, { "htable", SERVICE_TABLE }, { "bind", SERVICE_BIND }, { "dns", SERVICE_BIND }, { "domain", SERVICE_BIND }, { "yp", SERVICE_NIS }, { "yellowpages", SERVICE_NIS }, { "nis", SERVICE_NIS }, { 0, SERVICE_NONE } }; static enum service_type service_order[SERVICE_MAX + 1]; static int service_done = 0; static enum service_type get_service_name(const char *name) { int i; for(i = 0; service_names[i].type != SERVICE_NONE; i++) { if(!strcasecmp(name, service_names[i].name)) { return service_names[i].type; } } return SERVICE_NONE; } static void init_services() { char *cp, *p, buf[BUFSIZ]; register int cc = 0; FILE *fd; if ((fd = (FILE *)fopen(_PATH_NETCONF, "r")) == NULL) { /* make some assumptions */ service_order[0] = SERVICE_TABLE; service_order[1] = SERVICE_NONE; } else { while (fgets(buf, BUFSIZ, fd) != NULL && cc < SERVICE_MAX) { if(buf[0] == '#') continue; p = buf; while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0') ; if (cp == NULL) continue; do { if (isalpha(cp[0])) { service_order[cc] = get_service_name(cp); if(service_order[cc] != SERVICE_NONE) cc++; } while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0') ; } while(cp != NULL && cc < SERVICE_MAX); } service_order[cc] = SERVICE_NONE; fclose(fd); } service_done = 1; } struct netent * getnetbyname(const char *name) { struct netent *hp = 0; int nserv = 0; if (!service_done) init_services(); while (!hp) { switch (service_order[nserv]) { case SERVICE_NONE: return NULL; case SERVICE_TABLE: hp = _getnetbyhtname(name); break; case SERVICE_BIND: hp = _getnetbydnsname(name); break; case SERVICE_NIS: hp = _getnetbynisname(name); break; } nserv++; } return hp; } struct netent * getnetbyaddr(addr, af) - long addr; + u_long addr; int af; { struct netent *hp = 0; int nserv = 0; if (!service_done) init_services(); while (!hp) { switch (service_order[nserv]) { case SERVICE_NONE: return 0; case SERVICE_TABLE: hp = _getnetbyhtaddr(addr, af); break; case SERVICE_BIND: hp = _getnetbydnsaddr(addr, af); break; case SERVICE_NIS: hp = _getnetbynisaddr(addr, af); break; } nserv++; } return hp; } void setnetent(stayopen) int stayopen; { _setnethtent(stayopen); _setnetdnsent(stayopen); } void endnetent() { _endnethtent(); _endnetdnsent(); } diff --git a/lib/libc/net/inet_net_ntop.c b/lib/libc/net/inet_net_ntop.c new file mode 100644 index 000000000000..4c7893d417ff --- /dev/null +++ b/lib/libc/net/inet_net_ntop.c @@ -0,0 +1,140 @@ +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static const char orig_rcsid[] = "From Id: inet_net_ntop.c,v 8.2 1996/08/08 06:54:44 vixie Exp"; +static const char rcsid[] = "$Id$"; +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef SPRINTF_CHAR +# define SPRINTF(x) strlen(sprintf/**/x) +#else +# define SPRINTF(x) ((size_t)sprintf x) +#endif + +static char * inet_net_ntop_ipv4 __P((const u_char *src, int bits, + char *dst, size_t size)); + +/* + * char * + * inet_net_ntop(af, src, bits, dst, size) + * convert network number from network to presentation format. + * generates CIDR style result always. + * return: + * pointer to dst, or NULL if an error occurred (check errno). + * author: + * Paul Vixie (ISC), July 1996 + */ +char * +inet_net_ntop(af, src, bits, dst, size) + int af; + const void *src; + int bits; + char *dst; + size_t size; +{ + switch (af) { + case AF_INET: + return (inet_net_ntop_ipv4(src, bits, dst, size)); + default: + errno = EAFNOSUPPORT; + return (NULL); + } +} + +/* + * static char * + * inet_net_ntop_ipv4(src, bits, dst, size) + * convert IPv4 network number from network to presentation format. + * generates CIDR style result always. + * return: + * pointer to dst, or NULL if an error occurred (check errno). + * note: + * network byte order assumed. this means 192.5.5.240/28 has + * 0x11110000 in its fourth octet. + * author: + * Paul Vixie (ISC), July 1996 + */ +static char * +inet_net_ntop_ipv4(src, bits, dst, size) + const u_char *src; + int bits; + char *dst; + size_t size; +{ + char *odst = dst; + char *t; + u_int m; + int b; + + if (bits < 0 || bits > 32) { + errno = EINVAL; + return (NULL); + } + if (bits == 0) { + if (size < sizeof "0") + goto emsgsize; + *dst++ = '0'; + *dst = '\0'; + } + + /* Format whole octets. */ + for (b = bits / 8; b > 0; b--) { + if (size < sizeof "255.") + goto emsgsize; + t = dst; + dst += SPRINTF((dst, "%u", *src++)); + if (b > 1) { + *dst++ = '.'; + *dst = '\0'; + } + size -= (size_t)(dst - t); + } + + /* Format partial octet. */ + b = bits % 8; + if (b > 0) { + if (size < sizeof ".255") + goto emsgsize; + t = dst; + if (dst != odst) + *dst++ = '.'; + m = ((1 << b) - 1) << (8 - b); + dst += SPRINTF((dst, "%u", *src & m)); + size -= (size_t)(dst - t); + } + + /* Format CIDR /width. */ + if (size < sizeof "/32") + goto emsgsize; + dst += SPRINTF((dst, "/%u", bits)); + return (odst); + + emsgsize: + errno = EMSGSIZE; + return (NULL); +} diff --git a/lib/libc/net/inet_net_pton.c b/lib/libc/net/inet_net_pton.c new file mode 100644 index 000000000000..6fd6a06c6da9 --- /dev/null +++ b/lib/libc/net/inet_net_pton.c @@ -0,0 +1,208 @@ +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static const char orig_rcsid[] = "From Id: inet_net_pton.c,v 8.3 1996/11/11 06:36:52 vixie Exp"; +static const char rcsid[] = "$Id$"; +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifdef SPRINTF_CHAR +# define SPRINTF(x) strlen(sprintf/**/x) +#else +# define SPRINTF(x) ((size_t)sprintf x) +#endif + +static int inet_net_pton_ipv4 __P((const char *src, u_char *dst, + size_t size)); + +/* + * static int + * inet_net_pton(af, src, dst, size) + * convert network number from presentation to network format. + * accepts hex octets, hex strings, decimal octets, and /CIDR. + * "size" is in bytes and describes "dst". + * return: + * number of bits, either imputed classfully or specified with /CIDR, + * or -1 if some failure occurred (check errno). ENOENT means it was + * not a valid network specification. + * author: + * Paul Vixie (ISC), June 1996 + */ +int +inet_net_pton(af, src, dst, size) + int af; + const char *src; + void *dst; + size_t size; +{ + switch (af) { + case AF_INET: + return (inet_net_pton_ipv4(src, dst, size)); + default: + errno = EAFNOSUPPORT; + return (-1); + } +} + +/* + * static int + * inet_net_pton_ipv4(src, dst, size) + * convert IPv4 network number from presentation to network format. + * accepts hex octets, hex strings, decimal octets, and /CIDR. + * "size" is in bytes and describes "dst". + * return: + * number of bits, either imputed classfully or specified with /CIDR, + * or -1 if some failure occurred (check errno). ENOENT means it was + * not an IPv4 network specification. + * note: + * network byte order assumed. this means 192.5.5.240/28 has + * 0x11110000 in its fourth octet. + * author: + * Paul Vixie (ISC), June 1996 + */ +static int +inet_net_pton_ipv4(src, dst, size) + const char *src; + u_char *dst; + size_t size; +{ + static const char + xdigits[] = "0123456789abcdef", + digits[] = "0123456789"; + int n, ch, tmp, dirty, bits; + const u_char *odst = dst; + + ch = *src++; + if (ch == '0' && (src[0] == 'x' || src[0] == 'X') + && isascii(src[1]) && isxdigit(src[1])) { + /* Hexadecimal: Eat nybble string. */ + if (size <= 0) + goto emsgsize; + *dst = 0, dirty = 0; + src++; /* skip x or X. */ + while ((ch = *src++) != '\0' && + isascii(ch) && isxdigit(ch)) { + if (isupper(ch)) + ch = tolower(ch); + n = strchr(xdigits, ch) - xdigits; + assert(n >= 0 && n <= 15); + *dst |= n; + if (!dirty++) + *dst <<= 4; + else if (size-- > 0) + *++dst = 0, dirty = 0; + else + goto emsgsize; + } + if (dirty) + size--; + } else if (isascii(ch) && isdigit(ch)) { + /* Decimal: eat dotted digit string. */ + for (;;) { + tmp = 0; + do { + n = strchr(digits, ch) - digits; + assert(n >= 0 && n <= 9); + tmp *= 10; + tmp += n; + if (tmp > 255) + goto enoent; + } while ((ch = *src++) != '\0' && + isascii(ch) && isdigit(ch)); + if (size-- <= 0) + goto emsgsize; + *dst++ = (u_char) tmp; + if (ch == '\0' || ch == '/') + break; + if (ch != '.') + goto enoent; + ch = *src++; + if (!isascii(ch) || !isdigit(ch)) + goto enoent; + } + } else + goto enoent; + + bits = -1; + if (ch == '/' && isascii(src[0]) && isdigit(src[0]) && dst > odst) { + /* CIDR width specifier. Nothing can follow it. */ + ch = *src++; /* Skip over the /. */ + bits = 0; + do { + n = strchr(digits, ch) - digits; + assert(n >= 0 && n <= 9); + bits *= 10; + bits += n; + } while ((ch = *src++) != '\0' && + isascii(ch) && isdigit(ch)); + if (ch != '\0') + goto enoent; + if (bits > 32) + goto emsgsize; + } + + /* Firey death and destruction unless we prefetched EOS. */ + if (ch != '\0') + goto enoent; + + /* If nothing was written to the destination, we found no address. */ + if (dst == odst) + goto enoent; + /* If no CIDR spec was given, infer width from net class. */ + if (bits == -1) { + if (*odst >= 240) /* Class E */ + bits = 32; + else if (*odst >= 224) /* Class D */ + bits = 4; + else if (*odst >= 192) /* Class C */ + bits = 24; + else if (*odst >= 128) /* Class B */ + bits = 16; + else /* Class A */ + bits = 8; + /* If imputed mask is narrower than specified octets, widen. */ + if (bits >= 8 && bits < ((dst - odst) * 8)) + bits = (dst - odst) * 8; + } + /* Extend network to cover the actual mask. */ + while (bits > ((dst - odst) * 8)) { + if (size-- <= 0) + goto emsgsize; + *dst++ = '\0'; + } + return (bits); + + enoent: + errno = ENOENT; + return (-1); + + emsgsize: + errno = EMSGSIZE; + return (-1); +} diff --git a/lib/libc/net/inet_neta.c b/lib/libc/net/inet_neta.c new file mode 100644 index 000000000000..15a1c70529ac --- /dev/null +++ b/lib/libc/net/inet_neta.c @@ -0,0 +1,83 @@ +/* + * Copyright (c) 1996 by Internet Software Consortium. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static const char orig_rcsid[] = "From Id: inet_neta.c,v 8.2 1996/08/08 06:54:44 vixie Exp"; +static const char rcsid[] = "$Id$"; +#endif + +#include +#include +#include +#include + +#include +#include + +#ifdef SPRINTF_CHAR +# define SPRINTF(x) strlen(sprintf/**/x) +#else +# define SPRINTF(x) ((size_t)sprintf x) +#endif + +/* + * char * + * inet_neta(src, dst, size) + * format a u_long network number into presentation format. + * return: + * pointer to dst, or NULL if an error occurred (check errno). + * note: + * format of ``src'' is as for inet_network(). + * author: + * Paul Vixie (ISC), July 1996 + */ +char * +inet_neta(src, dst, size) + u_long src; + char *dst; + size_t size; +{ + char *odst = dst; + char *tp; + + while (src & 0xffffffff) { + u_char b = (src & 0xff000000) >> 24; + + src <<= 8; + if (b) { + if (size < sizeof "255.") + goto emsgsize; + tp = dst; + dst += SPRINTF((dst, "%u", b)); + if (src != 0L) { + *dst++ = '.'; + *dst = '\0'; + } + size -= (size_t)(dst - tp); + } + } + if (dst == odst) { + if (size < sizeof "0.0.0.0") + goto emsgsize; + strcpy(dst, "0.0.0.0"); + } + return (odst); + + emsgsize: + errno = EMSGSIZE; + return (NULL); +} diff --git a/lib/libc/net/map_v4v6.c b/lib/libc/net/map_v4v6.c index f4fdc2329d8d..01c0103ac937 100644 --- a/lib/libc/net/map_v4v6.c +++ b/lib/libc/net/map_v4v6.c @@ -1,127 +1,128 @@ /* * ++Copyright++ 1985, 1988, 1993 * - * Copyright (c) 1985, 1988, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Portions Copyright (c) 1993 by Digital Equipment Corporation. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. * - * --Copyright-- */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id: gethnamaddr.c,v 8.17 1996/08/05 08:31:35 vixie Exp $"; +static char rcsid[] = "$Id: map_v4v6.c,v 1.1 1996/08/29 20:08:07 peter Exp $"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include #include +#include #include #include #include #include #include typedef union { int32_t al; char ac; } align; void _map_v4v6_address(src, dst) const char *src; char *dst; { u_char *p = (u_char *)dst; char tmp[INADDRSZ]; int i; /* Stash a temporary copy so our caller can update in place. */ bcopy(src, tmp, INADDRSZ); /* Mark this ipv6 addr as a mapped ipv4. */ for (i = 0; i < 10; i++) *p++ = 0x00; *p++ = 0xff; *p++ = 0xff; /* Retrieve the saved copy and we're done. */ bcopy(tmp, (void*)p, INADDRSZ); } void _map_v4v6_hostent(hp, bpp, lenp) struct hostent *hp; char **bpp; int *lenp; { char **ap; if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ) return; hp->h_addrtype = AF_INET6; hp->h_length = IN6ADDRSZ; for (ap = hp->h_addr_list; *ap; ap++) { int i = sizeof(align) - ((u_long)*bpp % sizeof(align)); if (*lenp < (i + IN6ADDRSZ)) { /* Out of memory. Truncate address list here. XXX */ *ap = NULL; return; } *bpp += i; *lenp -= i; _map_v4v6_address(*ap, *bpp); *ap = *bpp; *bpp += IN6ADDRSZ; *lenp -= IN6ADDRSZ; } } diff --git a/lib/libc/net/ns_addr.c b/lib/libc/net/ns_addr.c index da8f8b4d72ca..3446e08c19a6 100644 --- a/lib/libc/net/ns_addr.c +++ b/lib/libc/net/ns_addr.c @@ -1,227 +1,227 @@ /* * Copyright (c) 1986, 1993 * The Regents of the University of California. All rights reserved. * * This code is derived from software contributed to Berkeley by * J.Q. Johnson. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)ns_addr.c 8.1 (Berkeley) 6/7/93"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include static struct ns_addr addr, zero_addr; static void Field(), cvtbase(); struct ns_addr ns_addr(name) const char *name; { char separator; char *hostname, *socketname, *cp; char buf[50]; (void)strncpy(buf, name, sizeof(buf) - 1); buf[sizeof(buf) - 1] = '\0'; /* * First, figure out what he intends as a field separtor. * Despite the way this routine is written, the prefered * form 2-272.AA001234H.01777, i.e. XDE standard. * Great efforts are made to insure backward compatability. */ - if (hostname = strchr(buf, '#')) + if ((hostname = strchr(buf, '#')) != NULL) separator = '#'; else { hostname = strchr(buf, '.'); if ((cp = strchr(buf, ':')) && ((hostname && cp < hostname) || (hostname == 0))) { hostname = cp; separator = ':'; } else separator = '.'; } if (hostname) *hostname++ = 0; addr = zero_addr; Field(buf, addr.x_net.c_net, 4); if (hostname == 0) return (addr); /* No separator means net only */ socketname = strchr(hostname, separator); if (socketname) { *socketname++ = 0; Field(socketname, (u_char *)&addr.x_port, 2); } Field(hostname, addr.x_host.c_host, 6); return (addr); } static void Field(buf, out, len) char *buf; u_char *out; int len; { register char *bp = buf; int i, ibase, base16 = 0, base10 = 0, clen = 0; int hb[6], *hp; char *fmt; /* * first try 2-273#2-852-151-014#socket */ if ((*buf != '-') && (1 < (i = sscanf(buf, "%d-%d-%d-%d-%d", &hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) { cvtbase(1000L, 256, hb, i, out, len); return; } /* * try form 8E1#0.0.AA.0.5E.E6#socket */ if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x", &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) { cvtbase(256L, 256, hb, i, out, len); return; } /* * try form 8E1#0:0:AA:0:5E:E6#socket */ if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x", &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) { cvtbase(256L, 256, hb, i, out, len); return; } /* * This is REALLY stretching it but there was a * comma notation separting shorts -- definitely non standard */ if (1 < (i = sscanf(buf,"%x,%x,%x", &hb[0], &hb[1], &hb[2]))) { hb[0] = htons(hb[0]); hb[1] = htons(hb[1]); hb[2] = htons(hb[2]); cvtbase(65536L, 256, hb, i, out, len); return; } /* Need to decide if base 10, 16 or 8 */ while (*bp) switch (*bp++) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '-': break; case '8': case '9': base10 = 1; break; case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': base16 = 1; break; case 'x': case 'X': *--bp = '0'; base16 = 1; break; case 'h': case 'H': base16 = 1; /* fall into */ default: *--bp = 0; /* Ends Loop */ } if (base16) { fmt = "%3x"; ibase = 4096; } else if (base10 == 0 && *buf == '0') { fmt = "%3o"; ibase = 512; } else { fmt = "%3d"; ibase = 1000; } for (bp = buf; *bp++; ) clen++; if (clen == 0) clen++; if (clen > 18) clen = 18; i = ((clen - 1) / 3) + 1; bp = clen + buf - 3; hp = hb + i - 1; while (hp > hb) { (void)sscanf(bp, fmt, hp); bp[0] = 0; hp--; bp -= 3; } (void)sscanf(buf, fmt, hp); cvtbase((long)ibase, 256, hb, i, out, len); } static void cvtbase(oldbase,newbase,input,inlen,result,reslen) long oldbase; int newbase; int input[]; int inlen; unsigned char result[]; int reslen; { int d, e; long sum; e = 1; while (e > 0 && reslen > 0) { d = 0; e = 0; sum = 0; /* long division: input=input/newbase */ while (d < inlen) { sum = sum*oldbase + (long) input[d]; e += (sum > 0); input[d++] = sum / newbase; sum %= newbase; } result[--reslen] = sum; /* accumulate remainder */ } for (d=0; d < reslen; d++) result[d] = 0; } diff --git a/lib/libc/net/nsap_addr.c b/lib/libc/net/nsap_addr.c index fcbbf1ebc2d7..0c295825eb96 100644 --- a/lib/libc/net/nsap_addr.c +++ b/lib/libc/net/nsap_addr.c @@ -1,103 +1,103 @@ /* * Copyright (c) 1996 by Internet Software Consortium. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. */ #if defined(LIBC_SCCS) && !defined(lint) -static char rcsid[] = "$Id: nsap_addr.c,v 8.3 1996/08/05 08:31:35 vixie Exp $"; +static char rcsid[] = "$Id: nsap_addr.c,v 1.1 1996/08/29 20:08:08 peter Exp $"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include #include static char xtob(c) register int c; { return (c - (((c >= '0') && (c <= '9')) ? '0' : '7')); } u_int inet_nsap_addr(ascii, binary, maxlen) const char *ascii; u_char *binary; int maxlen; { register u_char c, nib; u_int len = 0; while ((c = *ascii++) != '\0' && len < maxlen) { if (c == '.' || c == '+' || c == '/') continue; if (!isascii(c)) return (0); if (islower(c)) c = toupper(c); if (isxdigit(c)) { nib = xtob(c); - if (c = *ascii++) { + if ((c = *ascii++) != '\0') { c = toupper(c); if (isxdigit(c)) { *binary++ = (nib << 4) | xtob(c); len++; } else return (0); } else return (0); } else return (0); } return (len); } char * inet_nsap_ntoa(binlen, binary, ascii) int binlen; register const u_char *binary; register char *ascii; { register int nib; int i; static char tmpbuf[255*3]; char *start; if (ascii) start = ascii; else { ascii = tmpbuf; start = tmpbuf; } if (binlen > 255) binlen = 255; for (i = 0; i < binlen; i++) { nib = *binary >> 4; *ascii++ = nib + (nib < 10 ? '0' : '7'); nib = *binary++ & 0x0f; *ascii++ = nib + (nib < 10 ? '0' : '7'); if (((i % 2) == 0 && (i + 1) < binlen)) *ascii++ = '.'; } *ascii = '\0'; return (start); } diff --git a/lib/libc/net/res_comp.c b/lib/libc/net/res_comp.c index 6f4d31f74266..20b0e3a66f4d 100644 --- a/lib/libc/net/res_comp.c +++ b/lib/libc/net/res_comp.c @@ -1,486 +1,491 @@ /* * ++Copyright++ 1985, 1993 * - * Copyright (c) 1985, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * Portions Copyright (c) 1993 by Digital Equipment Corporation. * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies, and that * the name of Digital Equipment Corporation not be used in advertising or * publicity pertaining to distribution of the document or software without * specific, written prior permission. * * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS * SOFTWARE. * - * --Copyright-- */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93"; -static char rcsid[] = "$Id: res_comp.c,v 8.8 1996/08/05 08:31:35 vixie Exp $"; +static char orig_rcsid[] = "From: Id: res_comp.c,v 8.11 1996/12/02 09:17:22 vixie Exp"; +static char rcsid[] = "$Id: res_comp.c,v 1.7 1996/08/30 21:13:27 peter Exp $"; #endif /* LIBC_SCCS and not lint */ #include #include #include #include #include #include #include #include #include static int dn_find __P((u_char *exp_dn, u_char *msg, u_char **dnptrs, u_char **lastdnptr)); /* * Expand compressed domain name 'comp_dn' to full domain name. * 'msg' is a pointer to the begining of the message, * 'eomorig' points to the first location after the message, * 'exp_dn' is a pointer to a buffer of size 'length' for the result. * Return size of compressed name or -1 if there was an error. */ int dn_expand(msg, eomorig, comp_dn, exp_dn, length) const u_char *msg, *eomorig, *comp_dn; char *exp_dn; int length; { register const u_char *cp; register char *dn; register int n, c; char *eom; int len = -1, checked = 0; dn = exp_dn; cp = comp_dn; eom = exp_dn + length; /* * fetch next label in domain name */ while ( (n = *cp++) ) { /* * Check for indirection */ switch (n & INDIR_MASK) { case 0: if (dn != exp_dn) { if (dn >= eom) return (-1); *dn++ = '.'; } if (dn+n >= eom) return (-1); checked += n + 1; while (--n >= 0) { if (((c = *cp++) == '.') || (c == '\\')) { if (dn + n + 2 >= eom) return (-1); *dn++ = '\\'; } *dn++ = c; if (cp >= eomorig) /* out of range */ return (-1); } break; case INDIR_MASK: if (len < 0) len = cp - comp_dn + 1; cp = msg + (((n & 0x3f) << 8) | (*cp & 0xff)); if (cp < msg || cp >= eomorig) /* out of range */ return (-1); checked += 2; /* * Check for loops in the compressed name; * if we've looked at the whole message, * there must be a loop. */ if (checked >= eomorig - msg) return (-1); break; default: return (-1); /* flag error */ } } *dn = '\0'; if (len < 0) len = cp - comp_dn; return (len); } /* * Compress domain name 'exp_dn' into 'comp_dn'. * Return the size of the compressed name or -1. * 'length' is the size of the array pointed to by 'comp_dn'. * 'dnptrs' is a list of pointers to previous compressed names. dnptrs[0] * is a pointer to the beginning of the message. The list ends with NULL. * 'lastdnptr' is a pointer to the end of the arrary pointed to * by 'dnptrs'. Side effect is to update the list of pointers for * labels inserted into the message as we compress the name. * If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr' * is NULL, we don't update the list. */ int dn_comp(exp_dn, comp_dn, length, dnptrs, lastdnptr) const char *exp_dn; u_char *comp_dn, **dnptrs, **lastdnptr; int length; { register u_char *cp, *dn; register int c, l; u_char **cpp, **lpp, *sp, *eob; u_char *msg; dn = (u_char *)exp_dn; cp = comp_dn; eob = cp + length; lpp = cpp = NULL; if (dnptrs != NULL) { if ((msg = *dnptrs++) != NULL) { for (cpp = dnptrs; *cpp != NULL; cpp++) ; lpp = cpp; /* end of list to search */ } } else msg = NULL; for (c = *dn++; c != '\0'; ) { /* look to see if we can use pointers */ if (msg != NULL) { if ((l = dn_find(dn-1, msg, dnptrs, lpp)) >= 0) { if (cp+1 >= eob) return (-1); *cp++ = (l >> 8) | INDIR_MASK; *cp++ = l % 256; return (cp - comp_dn); } /* not found, save it */ if (lastdnptr != NULL && cpp < lastdnptr-1) { *cpp++ = cp; *cpp = NULL; } } sp = cp++; /* save ptr to length byte */ do { if (c == '.') { c = *dn++; break; } if (c == '\\') { if ((c = *dn++) == '\0') break; } if (cp >= eob) { if (msg != NULL) *lpp = NULL; return (-1); } *cp++ = c; } while ((c = *dn++) != '\0'); /* catch trailing '.'s but not '..' */ if ((l = cp - sp - 1) == 0 && c == '\0') { cp--; break; } if (l <= 0 || l > MAXLABEL) { if (msg != NULL) *lpp = NULL; return (-1); } *sp = l; } if (cp >= eob) { if (msg != NULL) *lpp = NULL; return (-1); } *cp++ = '\0'; return (cp - comp_dn); } /* * Skip over a compressed domain name. Return the size or -1. */ int __dn_skipname(comp_dn, eom) const u_char *comp_dn, *eom; { register const u_char *cp; register int n; cp = comp_dn; while (cp < eom && (n = *cp++)) { /* * check for indirection */ switch (n & INDIR_MASK) { case 0: /* normal case, n == len */ cp += n; continue; case INDIR_MASK: /* indirection */ cp++; break; default: /* illegal type */ return (-1); } break; } if (cp > eom) return (-1); return (cp - comp_dn); } static int mklower(ch) register int ch; { if (isascii(ch) && isupper(ch)) return (tolower(ch)); return (ch); } /* * Search for expanded name from a list of previously compressed names. * Return the offset from msg if found or -1. * dnptrs is the pointer to the first name on the list, * not the pointer to the start of the message. */ static int dn_find(exp_dn, msg, dnptrs, lastdnptr) u_char *exp_dn, *msg; u_char **dnptrs, **lastdnptr; { register u_char *dn, *cp, **cpp; register int n; u_char *sp; for (cpp = dnptrs; cpp < lastdnptr; cpp++) { dn = exp_dn; sp = cp = *cpp; while ( (n = *cp++) ) { /* * check for indirection */ switch (n & INDIR_MASK) { case 0: /* normal case, n == len */ while (--n >= 0) { if (*dn == '.') goto next; if (*dn == '\\') dn++; if (mklower(*dn++) != mklower(*cp++)) goto next; } if ((n = *dn++) == '\0' && *cp == '\0') return (sp - msg); if (n == '.') continue; goto next; case INDIR_MASK: /* indirection */ cp = msg + (((n & 0x3f) << 8) | *cp); break; default: /* illegal type */ return (-1); } } if (*dn == '\0') return (sp - msg); next: ; } return (-1); } /* * Verify that a domain name uses an acceptable character set. */ /* * Note the conspicuous absence of ctype macros in these definitions. On * non-ASCII hosts, we can't depend on string literals or ctype macros to * tell us anything about network-format data. The rest of the BIND system * is not careful about this, but for some reason, we're doing it right here. */ #define PERIOD 0x2e #define hyphenchar(c) ((c) == 0x2d) #define bslashchar(c) ((c) == 0x5c) #define periodchar(c) ((c) == PERIOD) #define asterchar(c) ((c) == 0x2a) #define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \ || ((c) >= 0x61 && (c) <= 0x7a)) #define digitchar(c) ((c) >= 0x30 && (c) <= 0x39) #define borderchar(c) (alphachar(c) || digitchar(c)) #define middlechar(c) (borderchar(c) || hyphenchar(c)) #define domainchar(c) ((c) > 0x20 && (c) < 0x7f) int res_hnok(dn) const char *dn; { int ppch = '\0', pch = PERIOD, ch = *dn++; while (ch != '\0') { int nch = *dn++; if (periodchar(ch)) { NULL; } else if (periodchar(pch)) { if (!borderchar(ch)) return (0); } else if (periodchar(nch) || nch == '\0') { if (!borderchar(ch)) return (0); } else { if (!middlechar(ch)) return (0); } ppch = pch, pch = ch, ch = nch; } return (1); } /* * hostname-like (A, MX, WKS) owners can have "*" as their first label * but must otherwise be as a host name. */ int res_ownok(dn) const char *dn; { - if (asterchar(dn[0]) && periodchar(dn[1])) - dn += 2; + if (asterchar(dn[0])) { + if (periodchar(dn[1])) + return (res_hnok(dn+2)); + if (dn[1] == '\0') + return (1); + } return (res_hnok(dn)); } /* * SOA RNAMEs and RP RNAMEs can have any printable character in their first * label, but the rest of the name has to look like a host name. */ int res_mailok(dn) const char *dn; { int ch, escaped = 0; /* "." is a valid missing representation */ if (*dn == '\0') return(1); /* otherwise