1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
  28 /* All Rights Reserved */
  29 /*
  30  * Portions of this source code were derived from Berkeley
  31  * 4.3 BSD under license from the Regents of the University of
  32  * California.
  33  */
  34 
  35 /*
  36  * Copyright (c) 1983, 1990, 1993
  37  *    The Regents of the University of California.  All rights reserved.
  38  *
  39  * Redistribution and use in source and binary forms, with or without
  40  * modification, are permitted provided that the following conditions
  41  * are met:
  42  * 1. Redistributions of source code must retain the above copyright
  43  *    notice, this list of conditions and the following disclaimer.
  44  * 2. Redistributions in binary form must reproduce the above copyright
  45  *    notice, this list of conditions and the following disclaimer in the
  46  *    documentation and/or other materials provided with the distribution.
  47  * 3. All advertising materials mentioning features or use of this software
  48  *    must display the following acknowledgement:
  49  *      This product includes software developed by the University of
  50  *      California, Berkeley and its contributors.
  51  * 4. Neither the name of the University nor the names of its contributors
  52  *    may be used to endorse or promote products derived from this software
  53  *    without specific prior written permission.
  54  *
  55  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  56  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  57  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  58  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  59  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  60  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  61  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  62  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  63  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  64  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  65  * SUCH DAMAGE.
  66  */
  67 
  68 /*
  69  * Portions Copyright (c) 1993 by Digital Equipment Corporation.
  70  *
  71  * Permission to use, copy, modify, and distribute this software for any
  72  * purpose with or without fee is hereby granted, provided that the above
  73  * copyright notice and this permission notice appear in all copies, and that
  74  * the name of Digital Equipment Corporation not be used in advertising or
  75  * publicity pertaining to distribution of the document or software without
  76  * specific, written prior permission.
  77  *
  78  * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
  79  * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
  80  * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
  81  * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  82  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
  83  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
  84  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  85  * SOFTWARE.
  86  */
  87 
  88 /*
  89  * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
  90  *
  91  * Permission to use, copy, modify, and distribute this software for any
  92  * purpose with or without fee is hereby granted, provided that the above
  93  * copyright notice and this permission notice appear in all copies.
  94  *
  95  * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
  96  * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
  97  * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
  98  * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
  99  * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 100  * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 101  * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 102  * SOFTWARE.
 103  */
 104 
 105 /*
 106  * Convert network-format internet address
 107  * to base 256 d.d.d.d representation.
 108  *
 109  * Reentrant interface
 110  */
 111 
 112 #include "lint.h"
 113 
 114 #include <sys/types.h>
 115 
 116 #include <netinet/in.h>
 117 
 118 #include <ctype.h>
 119 #include <errno.h>
 120 #include <stdio.h>
 121 #include <stdlib.h>
 122 #include <threads.h>
 123 
 124 static thread_local char ntoa_buf[18];
 125 
 126 char *
 127 inet_ntoa_r(struct in_addr in, char b[])
 128 {
 129         char    *p;
 130 
 131         p = (char *)&in;
 132 #define UC(b)   (((int)b)&0xff)
 133         (void) sprintf(b, "%d.%d.%d.%d",
 134             UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
 135         return (b);
 136 }
 137 
 138 char *
 139 inet_ntoa(struct in_addr in)
 140 {
 141         return (inet_ntoa_r(in, ntoa_buf));
 142 }
 143 
 144 /*
 145  * Check whether "cp" is a valid ascii representation
 146  * of an Internet address and convert to a binary address.
 147  * Returns 1 if the address is valid, 0 if not.
 148  * This replaces inet_addr, the return value from which
 149  * cannot distinguish between failure and a local broadcast address.
 150  */
 151 int
 152 inet_aton(const char *cp, struct in_addr *addr)
 153 {
 154         uint32_t val;
 155         int base, n;
 156         char c;
 157         unsigned int parts[4];
 158         unsigned int *pp = parts;
 159 
 160         c = *cp;
 161         for (;;) {
 162                 /*
 163                  * Collect number up to ``.''.
 164                  * Values are specified as for C:
 165                  * 0x=hex, 0=octal, isdigit=decimal.
 166                  */
 167                 if (!isdigit(c))
 168                         return (0);
 169                 val = 0; base = 10;
 170                 if (c == '0') {
 171                         c = *++cp;
 172                         if (c == 'x' || c == 'X')
 173                                 base = 16, c = *++cp;
 174                         else
 175                                 base = 8;
 176                 }
 177                 for (;;) {
 178                         if (isascii(c) && isdigit(c)) {
 179                                 val = (val * base) + (c - '0');
 180                                 c = *++cp;
 181                         } else if (base == 16 && isascii(c) && isxdigit(c)) {
 182                                 val = (val << 4) |
 183                                     (c + 10 - (islower(c) ? 'a' : 'A'));
 184                                 c = *++cp;
 185                         } else
 186                                 break;
 187                 }
 188                 if (c == '.') {
 189                         /*
 190                          * Internet format:
 191                          *      a.b.c.d
 192                          *      a.b.c   (with c treated as 16 bits)
 193                          *      a.b     (with b treated as 24 bits)
 194                          */
 195                         if (pp >= parts + 3)
 196                                 return (0);
 197                         *pp++ = val;
 198                         c = *++cp;
 199                 } else
 200                         break;
 201         }
 202         /*
 203          * Check for trailing characters.
 204          */
 205         if (c != '\0' && (!isascii(c) || !isspace(c)))
 206                 return (0);
 207         /*
 208          * Concoct the address according to
 209          * the number of parts specified.
 210          */
 211         n = pp - parts + 1;
 212         switch (n) {
 213 
 214         case 0:
 215                 return (0);             /* initial nondigit */
 216 
 217         case 1:                         /* a -- 32 bits */
 218                 break;
 219 
 220         case 2:                         /* a.b -- 8.24 bits */
 221                 if ((val > 0xffffff) || (parts[0] > 0xff))
 222                         return (0);
 223                 val |= parts[0] << 24;
 224                 break;
 225 
 226         case 3:                         /* a.b.c -- 8.8.16 bits */
 227                 if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff))
 228                         return (0);
 229                 val |= (parts[0] << 24) | (parts[1] << 16);
 230                 break;
 231 
 232         case 4:                         /* a.b.c.d -- 8.8.8.8 bits */
 233                 if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) ||
 234                     (parts[2] > 0xff))
 235                         return (0);
 236                 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
 237                 break;
 238         }
 239         if (addr)
 240                 addr->s_addr = htonl(val);
 241         return (1);
 242 }
 243 
 244 /*
 245  * Internet address interpretation routine.
 246  * All the network library routines call this
 247  * routine to interpret entries in the data bases
 248  * which are expected to be an address.
 249  * The value returned is in network order.
 250  */
 251 in_addr_t
 252 inet_addr(const char *cp)
 253 {
 254         struct in_addr val;
 255 
 256         if (inet_aton(cp, &val))
 257                 return (val.s_addr);
 258         return (INADDR_NONE);
 259 }
 260 
 261 /*
 262  * Return the network number from an internet
 263  * address; handles class a/b/c network #'s.
 264  */
 265 in_addr_t
 266 inet_netof(struct in_addr in)
 267 {
 268         uint32_t i = ntohl(in.s_addr);
 269 
 270         if (IN_CLASSA(i))
 271                 return ((i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
 272         if (IN_CLASSB(i))
 273                 return ((i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
 274         return ((i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
 275 }