1157016Sdes/* $OpenBSD: inet_addr.c,v 1.9 2005/08/06 20:30:03 espie Exp $ */ 2126274Sdes 398937Sdes/* 498937Sdes * Copyright (c) 1983, 1990, 1993 598937Sdes * The Regents of the University of California. All rights reserved. 6323124Sdes * 798937Sdes * Redistribution and use in source and binary forms, with or without 898937Sdes * modification, are permitted provided that the following conditions 998937Sdes * are met: 1098937Sdes * 1. Redistributions of source code must retain the above copyright 1198937Sdes * notice, this list of conditions and the following disclaimer. 1298937Sdes * 2. Redistributions in binary form must reproduce the above copyright 1398937Sdes * notice, this list of conditions and the following disclaimer in the 1498937Sdes * documentation and/or other materials provided with the distribution. 15124208Sdes * 3. Neither the name of the University nor the names of its contributors 1698937Sdes * may be used to endorse or promote products derived from this software 1798937Sdes * without specific prior written permission. 18323124Sdes * 1998937Sdes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 2098937Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2198937Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2298937Sdes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 2398937Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2498937Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2598937Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2698937Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2798937Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2898937Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2998937Sdes * SUCH DAMAGE. 3098937Sdes * - 3198937Sdes * Portions Copyright (c) 1993 by Digital Equipment Corporation. 32323124Sdes * 3398937Sdes * Permission to use, copy, modify, and distribute this software for any 3498937Sdes * purpose with or without fee is hereby granted, provided that the above 3598937Sdes * copyright notice and this permission notice appear in all copies, and that 3698937Sdes * the name of Digital Equipment Corporation not be used in advertising or 3798937Sdes * publicity pertaining to distribution of the document or software without 3898937Sdes * specific, written prior permission. 39323124Sdes * 4098937Sdes * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL 4198937Sdes * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES 4298937Sdes * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT 4398937Sdes * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL 4498937Sdes * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR 4598937Sdes * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS 4698937Sdes * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 4798937Sdes * SOFTWARE. 4898937Sdes * - 4998937Sdes * --Copyright-- 5098937Sdes */ 5198937Sdes 52157016Sdes/* OPENBSD ORIGINAL: lib/libc/net/inet_addr.c */ 53157016Sdes 5498937Sdes#include "includes.h" 5598937Sdes 5698937Sdes#if !defined(HAVE_INET_ATON) 5798937Sdes 5898937Sdes#include <sys/types.h> 5998937Sdes#include <sys/param.h> 6098937Sdes#include <netinet/in.h> 6198937Sdes#include <arpa/inet.h> 6298937Sdes#include <ctype.h> 6398937Sdes 6498937Sdes#if 0 6598937Sdes/* 6698937Sdes * Ascii internet address interpretation routine. 6798937Sdes * The value returned is in network order. 6898937Sdes */ 6998937Sdesin_addr_t 70157016Sdesinet_addr(const char *cp) 7198937Sdes{ 7298937Sdes struct in_addr val; 7398937Sdes 7498937Sdes if (inet_aton(cp, &val)) 7598937Sdes return (val.s_addr); 7698937Sdes return (INADDR_NONE); 7798937Sdes} 7898937Sdes#endif 7998937Sdes 80323124Sdes/* 8198937Sdes * Check whether "cp" is a valid ascii representation 8298937Sdes * of an Internet address and convert to a binary address. 8398937Sdes * Returns 1 if the address is valid, 0 if not. 8498937Sdes * This replaces inet_addr, the return value from which 8598937Sdes * cannot distinguish between failure and a local broadcast address. 8698937Sdes */ 8798937Sdesint 8898937Sdesinet_aton(const char *cp, struct in_addr *addr) 8998937Sdes{ 90157016Sdes u_int32_t val; 91157016Sdes int base, n; 92157016Sdes char c; 93157016Sdes u_int parts[4]; 94157016Sdes u_int *pp = parts; 9598937Sdes 9698937Sdes c = *cp; 9798937Sdes for (;;) { 9898937Sdes /* 9998937Sdes * Collect number up to ``.''. 10098937Sdes * Values are specified as for C: 10198937Sdes * 0x=hex, 0=octal, isdigit=decimal. 10298937Sdes */ 10398937Sdes if (!isdigit(c)) 10498937Sdes return (0); 10598937Sdes val = 0; base = 10; 10698937Sdes if (c == '0') { 10798937Sdes c = *++cp; 10898937Sdes if (c == 'x' || c == 'X') 10998937Sdes base = 16, c = *++cp; 11098937Sdes else 11198937Sdes base = 8; 11298937Sdes } 11398937Sdes for (;;) { 11498937Sdes if (isascii(c) && isdigit(c)) { 11598937Sdes val = (val * base) + (c - '0'); 11698937Sdes c = *++cp; 11798937Sdes } else if (base == 16 && isascii(c) && isxdigit(c)) { 11898937Sdes val = (val << 4) | 11998937Sdes (c + 10 - (islower(c) ? 'a' : 'A')); 12098937Sdes c = *++cp; 12198937Sdes } else 12298937Sdes break; 12398937Sdes } 12498937Sdes if (c == '.') { 12598937Sdes /* 12698937Sdes * Internet format: 12798937Sdes * a.b.c.d 12898937Sdes * a.b.c (with c treated as 16 bits) 12998937Sdes * a.b (with b treated as 24 bits) 13098937Sdes */ 13198937Sdes if (pp >= parts + 3) 13298937Sdes return (0); 13398937Sdes *pp++ = val; 13498937Sdes c = *++cp; 13598937Sdes } else 13698937Sdes break; 13798937Sdes } 13898937Sdes /* 13998937Sdes * Check for trailing characters. 14098937Sdes */ 14198937Sdes if (c != '\0' && (!isascii(c) || !isspace(c))) 14298937Sdes return (0); 14398937Sdes /* 14498937Sdes * Concoct the address according to 14598937Sdes * the number of parts specified. 14698937Sdes */ 14798937Sdes n = pp - parts + 1; 14898937Sdes switch (n) { 14998937Sdes 15098937Sdes case 0: 15198937Sdes return (0); /* initial nondigit */ 15298937Sdes 15398937Sdes case 1: /* a -- 32 bits */ 15498937Sdes break; 15598937Sdes 15698937Sdes case 2: /* a.b -- 8.24 bits */ 15798937Sdes if ((val > 0xffffff) || (parts[0] > 0xff)) 15898937Sdes return (0); 15998937Sdes val |= parts[0] << 24; 16098937Sdes break; 16198937Sdes 16298937Sdes case 3: /* a.b.c -- 8.8.16 bits */ 16398937Sdes if ((val > 0xffff) || (parts[0] > 0xff) || (parts[1] > 0xff)) 16498937Sdes return (0); 16598937Sdes val |= (parts[0] << 24) | (parts[1] << 16); 16698937Sdes break; 16798937Sdes 16898937Sdes case 4: /* a.b.c.d -- 8.8.8.8 bits */ 16998937Sdes if ((val > 0xff) || (parts[0] > 0xff) || (parts[1] > 0xff) || (parts[2] > 0xff)) 17098937Sdes return (0); 17198937Sdes val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8); 17298937Sdes break; 17398937Sdes } 17498937Sdes if (addr) 17598937Sdes addr->s_addr = htonl(val); 17698937Sdes return (1); 17798937Sdes} 17898937Sdes 17998937Sdes#endif /* !defined(HAVE_INET_ATON) */ 180