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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 23 /* 24 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 25 * Use is subject to license terms. 26 */ 27 28 /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ 29 /* All Rights Reserved */ 30 /* 31 * Portions of this source code were derived from Berkeley 32 * 4.3 BSD under license from the Regents of the University of 33 * California. 34 */ 35 36 #pragma ident "%Z%%M% %I% %E% SMI" 37 38 /* 39 * Convert network-format internet address 40 * to base 256 d.d.d.d representation. 41 * 42 * Reentrant interface 43 */ 44 45 #pragma weak inet_aton = _inet_aton 46 47 #include "mt.h" 48 #include "rpc_mt.h" 49 #include <errno.h> 50 #include <sys/types.h> 51 #include <ctype.h> 52 #include <netinet/in.h> 53 #include <stdio.h> 54 #include <stdlib.h> 55 56 57 char * 58 inet_ntoa_r(in, b) 59 struct in_addr in; 60 char b[]; /* Assumed >= 18 bytes */ 61 { 62 char *p; 63 64 p = (char *)∈ 65 #define UC(b) (((int)b)&0xff) 66 (void) sprintf(b, "%d.%d.%d.%d", 67 UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3])); 68 return (b); 69 } 70 71 char * 72 inet_ntoa(in) 73 struct in_addr in; 74 { 75 char *b; 76 static char b_main[18]; 77 static pthread_key_t ntoa_key; 78 79 if (thr_main()) 80 b = b_main; 81 else if ((b = thr_get_storage(&ntoa_key, 18, free)) == NULL) 82 b = b_main; 83 84 return (inet_ntoa_r(in, b)); 85 } 86 87 /* 88 * Check whether "cp" is a valid ascii representation 89 * of an Internet address and convert to a binary address. 90 * Returns 1 if the address is valid, 0 if not. 91 * This replaces inet_addr, the return value from which 92 * cannot distinguish between failure and a local broadcast address. 93 */ 94 int 95 inet_aton(const char *cp, struct in_addr *addr) 96 { 97 uint32_t val; 98 int base, n; 99 char c; 100 unsigned int parts[4]; 101 unsigned int *pp = parts; 102 103 104 c = *cp; 105 for (;;) { 106 /* 107 * Collect number up to ``.''. 108 * Values are specified as for C: 109 * 0x=hex, 0=octal, isdigit=decimal. 110 */ 111 if (!isdigit(c)) 112 return (0); 113 val = 0; base = 10; 114 if (c == '0') { 115 c = *++cp; 116 if (c == 'x' || c == 'X') 117 base = 16, c = *++cp; 118 else 119 base = 8; 120 } 121 for (;;) { 122 if (isascii(c) && isdigit(c)) { 123 val = (val * base) + (c - '0'); 124 c = *++cp; 125 } else if (base == 16 && isascii(c) && isxdigit(c)) { 126 val = (val << 4) | 127 (c + 10 - (islower(c) ? 'a' : 'A')); 128 c = *++cp; 129 } else 130 break; 131 } 132 if (c == '.') { 133 /* 134 * Internet format: 135 * a.b.c.d 136 * a.b.c (with c treated as 16 bits) 137 * a.b (with b treated as 24 bits) 138 */ 139 if (pp >= parts + 3) 140 return (0); 141 *pp++ = val; 142 c = *++cp; 143 } else 144 break; 145 } 146 /* 147 * Check for trailing characters. 148 */ 149 if (c != '\0' && (!isascii(c) || !isspace(c))) 150 return (0); 151 /* 152 * Concoct the address according to 153 * the number of parts specified. 154 */ 155 n = pp - parts + 1; 156 switch (n) { 157 158 case 0: 159 return (0); /* initial nondigit */ 160 161 case 1: /* a -- 32 bits */ 162 break; 163 164 case 2: /* a.b -- 8.24 bits */ 165 if ((val > 0xffffff) || (parts[0] > 0xff)) 166 return (0); 167 val |= parts[0] << 24; 168 break; 169 170 case 3: /* a.b.c -- 8.8.16 bits */ 171 if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff)) 172 return (0); 173 val |= (parts[0] << 24) | (parts[1] << 16); 174 break; 175 176 case 4: /* a.b.c.d -- 8.8.8.8 bits */ 177 if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || 178 (parts[2] > 0xff)) 179 return (0); 180 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); 181 break; 182 } 183 if (addr) 184 addr->s_addr = htonl(val); 185 return (1); 186 } 187 188 /* 189 * Internet address interpretation routine. 190 * All the network library routines call this 191 * routine to interpret entries in the data bases 192 * which are expected to be an address. 193 * The value returned is in network order. 194 */ 195 in_addr_t 196 inet_addr(const char *cp) 197 { 198 struct in_addr val; 199 200 if (inet_aton(cp, &val)) 201 return (val.s_addr); 202 return (INADDR_NONE); 203 } 204 205 /* 206 * Return the network number from an internet 207 * address; handles class a/b/c network #'s. 208 */ 209 uint_t 210 inet_netof(struct in_addr in) 211 { 212 uint32_t i = ntohl(in.s_addr); 213 214 if (IN_CLASSA(i)) 215 return ((i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT); 216 if (IN_CLASSB(i)) 217 return ((i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT); 218 return ((i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT); 219 } 220