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 #include "thr_uberdata.h"
 114 
 115 #include <sys/types.h>
 116 
 117 #include <netinet/in.h>
 118 
 119 #include <ctype.h>
 120 #include <errno.h>
 121 #include <stdio.h>
 122 #include <stdlib.h>
 123 
 124 char *
 125 inet_ntoa_r(struct in_addr in, char b[])
 126 {
 127         char    *p;
 128 
 129         p = (char *)&in;
 130 #define UC(b)   (((int)b)&0xff)
 131         (void) sprintf(b, "%d.%d.%d.%d",
 132             UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3]));
 133         return (b);
 134 }
 135 
 136 char *
 137 inet_ntoa(struct in_addr in)
 138 {
 139         return (inet_ntoa_r(in, curthread->ul_ntoabuf));
 140 }
 141 
 142 /*
 143  * Check whether "cp" is a valid ascii representation
 144  * of an Internet address and convert to a binary address.
 145  * Returns 1 if the address is valid, 0 if not.
 146  * This replaces inet_addr, the return value from which
 147  * cannot distinguish between failure and a local broadcast address.
 148  */
 149 int
 150 inet_aton(const char *cp, struct in_addr *addr)
 151 {
 152         uint32_t val;
 153         int base, n;
 154         char c;
 155         unsigned int parts[4];
 156         unsigned int *pp = parts;
 157 
 158         c = *cp;
 159         for (;;) {
 160                 /*
 161                  * Collect number up to ``.''.
 162                  * Values are specified as for C:
 163                  * 0x=hex, 0=octal, isdigit=decimal.
 164                  */
 165                 if (!isdigit(c))
 166                         return (0);
 167                 val = 0; base = 10;
 168                 if (c == '0') {
 169                         c = *++cp;
 170                         if (c == 'x' || c == 'X')
 171                                 base = 16, c = *++cp;
 172                         else
 173                                 base = 8;
 174                 }
 175                 for (;;) {
 176                         if (isascii(c) && isdigit(c)) {
 177                                 val = (val * base) + (c - '0');
 178                                 c = *++cp;
 179                         } else if (base == 16 && isascii(c) && isxdigit(c)) {
 180                                 val = (val << 4) |
 181                                     (c + 10 - (islower(c) ? 'a' : 'A'));
 182                                 c = *++cp;
 183                         } else
 184                                 break;
 185                 }
 186                 if (c == '.') {
 187                         /*
 188                          * Internet format:
 189                          *      a.b.c.d
 190                          *      a.b.c   (with c treated as 16 bits)
 191                          *      a.b     (with b treated as 24 bits)
 192                          */
 193                         if (pp >= parts + 3)
 194                                 return (0);
 195                         *pp++ = val;
 196                         c = *++cp;
 197                 } else
 198                         break;
 199         }
 200         /*
 201          * Check for trailing characters.
 202          */
 203         if (c != '\0' && (!isascii(c) || !isspace(c)))
 204                 return (0);
 205         /*
 206          * Concoct the address according to
 207          * the number of parts specified.
 208          */
 209         n = pp - parts + 1;
 210         switch (n) {
 211 
 212         case 0:
 213                 return (0);             /* initial nondigit */
 214 
 215         case 1:                         /* a -- 32 bits */
 216                 break;
 217 
 218         case 2:                         /* a.b -- 8.24 bits */
 219                 if ((val > 0xffffff) || (parts[0] > 0xff))
 220                         return (0);
 221                 val |= parts[0] << 24;
 222                 break;
 223 
 224         case 3:                         /* a.b.c -- 8.8.16 bits */
 225                 if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff))
 226                         return (0);
 227                 val |= (parts[0] << 24) | (parts[1] << 16);
 228                 break;
 229 
 230         case 4:                         /* a.b.c.d -- 8.8.8.8 bits */
 231                 if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) ||
 232                     (parts[2] > 0xff))
 233                         return (0);
 234                 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
 235                 break;
 236         }
 237         if (addr)
 238                 addr->s_addr = htonl(val);
 239         return (1);
 240 }
 241 
 242 /*
 243  * Internet address interpretation routine.
 244  * All the network library routines call this
 245  * routine to interpret entries in the data bases
 246  * which are expected to be an address.
 247  * The value returned is in network order.
 248  */
 249 in_addr_t
 250 inet_addr(const char *cp)
 251 {
 252         struct in_addr val;
 253 
 254         if (inet_aton(cp, &val))
 255                 return (val.s_addr);
 256         return (INADDR_NONE);
 257 }
 258 
 259 /*
 260  * Return the network number from an internet
 261  * address; handles class a/b/c network #'s.
 262  */
 263 in_addr_t
 264 inet_netof(struct in_addr in)
 265 {
 266         uint32_t i = ntohl(in.s_addr);
 267 
 268         if (IN_CLASSA(i))
 269                 return ((i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
 270         if (IN_CLASSB(i))
 271                 return ((i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
 272         return ((i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
 273 }