/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */ /* All Rights Reserved */ /* * Portions of this source code were derived from Berkeley * 4.3 BSD under license from the Regents of the University of * California. */ #pragma ident "%Z%%M% %I% %E% SMI" /* * Convert network-format internet address * to base 256 d.d.d.d representation. * * Reentrant interface */ #pragma weak inet_aton = _inet_aton #include "mt.h" #include "rpc_mt.h" #include #include #include #include #include #include char * inet_ntoa_r(in, b) struct in_addr in; char b[]; /* Assumed >= 18 bytes */ { char *p; p = (char *)∈ #define UC(b) (((int)b)&0xff) (void) sprintf(b, "%d.%d.%d.%d", UC(p[0]), UC(p[1]), UC(p[2]), UC(p[3])); return (b); } char * inet_ntoa(in) struct in_addr in; { char *b; static char b_main[18]; static pthread_key_t ntoa_key = PTHREAD_ONCE_KEY_NP; if (thr_main()) b = b_main; else if ((b = thr_get_storage(&ntoa_key, 18, free)) == NULL) b = b_main; return (inet_ntoa_r(in, b)); } /* * Check whether "cp" is a valid ascii representation * of an Internet address and convert to a binary address. * Returns 1 if the address is valid, 0 if not. * This replaces inet_addr, the return value from which * cannot distinguish between failure and a local broadcast address. */ int inet_aton(const char *cp, struct in_addr *addr) { uint32_t val; int base, n; char c; unsigned int parts[4]; unsigned int *pp = parts; c = *cp; for (;;) { /* * Collect number up to ``.''. * Values are specified as for C: * 0x=hex, 0=octal, isdigit=decimal. */ if (!isdigit(c)) return (0); val = 0; base = 10; if (c == '0') { c = *++cp; if (c == 'x' || c == 'X') base = 16, c = *++cp; else base = 8; } for (;;) { if (isascii(c) && isdigit(c)) { val = (val * base) + (c - '0'); c = *++cp; } else if (base == 16 && isascii(c) && isxdigit(c)) { val = (val << 4) | (c + 10 - (islower(c) ? 'a' : 'A')); c = *++cp; } else break; } if (c == '.') { /* * Internet format: * a.b.c.d * a.b.c (with c treated as 16 bits) * a.b (with b treated as 24 bits) */ if (pp >= parts + 3) return (0); *pp++ = val; c = *++cp; } else break; } /* * Check for trailing characters. */ if (c != '\0' && (!isascii(c) || !isspace(c))) return (0); /* * Concoct the address according to * the number of parts specified. */ n = pp - parts + 1; switch (n) { case 0: return (0); /* initial nondigit */ case 1: /* a -- 32 bits */ break; case 2: /* a.b -- 8.24 bits */ if ((val > 0xffffff) || (parts[0] > 0xff)) return (0); val |= parts[0] << 24; break; case 3: /* a.b.c -- 8.8.16 bits */ if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff)) return (0); val |= (parts[0] << 24) | (parts[1] << 16); break; case 4: /* a.b.c.d -- 8.8.8.8 bits */ if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff)) return (0); val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); break; } if (addr) addr->s_addr = htonl(val); return (1); } /* * Internet address interpretation routine. * All the network library routines call this * routine to interpret entries in the data bases * which are expected to be an address. * The value returned is in network order. */ in_addr_t inet_addr(const char *cp) { struct in_addr val; if (inet_aton(cp, &val)) return (val.s_addr); return (INADDR_NONE); } /* * Return the network number from an internet * address; handles class a/b/c network #'s. */ uint_t inet_netof(struct in_addr in) { uint32_t i = ntohl(in.s_addr); if (IN_CLASSA(i)) return ((i & IN_CLASSA_NET) >> IN_CLASSA_NSHIFT); if (IN_CLASSB(i)) return ((i & IN_CLASSB_NET) >> IN_CLASSB_NSHIFT); return ((i & IN_CLASSC_NET) >> IN_CLASSC_NSHIFT); }