/** @file
  Convert a string internet address into an integer (32-bit) address.

  Copyright (c) 2011, Intel Corporation. All rights reserved.<BR>
  This program and the accompanying materials are licensed and made available under
  the terms and conditions of the BSD License that accompanies this distribution.
  The full text of the license may be found at
  http://opensource.org/licenses/bsd-license.

  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

 * Copyright (c) 1983, 1990, 1993
 *    The Regents of the University of California.  All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *  This product includes software developed by the University of
 *  California, Berkeley and its contributors.
 * 4. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.

 * Portions Copyright (c) 1993 by Digital Equipment Corporation.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies, and that
 * the name of Digital Equipment Corporation not be used in advertising or
 * publicity pertaining to distribution of the document or software without
 * specific, written prior permission.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
 * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS.   IN NO EVENT SHALL DIGITAL EQUIPMENT
 * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
 * SOFTWARE.

 * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC")
 * Portions Copyright (c) 1996-1999 by Internet Software Consortium.
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.

  NetBSD: inet_addr.c,v 1.1 2005/12/20 19:28:51 christos Exp
  inet_addr.c 8.1 (Berkeley) 6/17/93
  inet_addr.c,v 1.2.206.2 2004/03/17 00:29:45 marka Exp
**/

#if !defined(_KERNEL) && !defined(_STANDALONE)
#include  <LibConfig.h>

//#include "port_before.h"

#include <namespace.h>
#include <sys/types.h>
#include <sys/param.h>

#include <netinet/in.h>
#include <arpa/inet.h>

#include <ctype.h>

//#include "port_after.h"

#ifdef __weak_alias
  __weak_alias(inet_aton,_inet_aton)
#endif

#else   // NOT (!defined(_KERNEL) && !defined(_STANDALONE))
  #include <lib/libkern/libkern.h>
  #include <netinet/in.h>
#endif

/*
 * Ascii internet address interpretation routine.
 * The value returned is in network order.
 */
u_int32_t
inet_addr(const char *cp) {
  struct in_addr val;

  if (inet_aton(cp, &val))
    return (val.s_addr);
  return (INADDR_NONE);
}

/*
 * 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) {
  u_int32_t val;
  int base, n;
  char c;
  u_int8_t parts[4];
  u_int8_t *pp = parts;
  int digit;

  c = *cp;
  for (;;) {
    /*
     * Collect number up to ``.''.
     * Values are specified as for C:
     * 0x=hex, 0=octal, isdigit=decimal.
     */
    if (!isdigit((unsigned char)c))
      return (0);
    val = 0; base = 10; digit = 0;
    if (c == '0') {
      c = *++cp;
      if (c == 'x' || c == 'X')
        base = 16, c = *++cp;
      else {
        base = 8;
        digit = 1 ;
      }
    }
    for (;;) {
      if (isascii(c) && isdigit((unsigned char)c)) {
        if (base == 8 && (c == '8' || c == '9'))
          return (0);
        val = (val * base) + (c - '0');
        c = *++cp;
        digit = 1;
      } else if (base == 16 && isascii(c) &&
           isxdigit((unsigned char)c)) {
        val = (val << 4) |
          (c + 10 - (islower((unsigned char)c) ? 'a' : 'A'));
        c = *++cp;
        digit = 1;
      } 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 || val > 0xffU)
        return (0);
      *pp++ = (u_int8_t)val;
      c = *++cp;
    } else
      break;
  }
  /*
   * Check for trailing characters.
   */
  if (c != '\0' && (!isascii(c) || !isspace((unsigned char)c)))
    return (0);
  /*
   * Did we get a valid digit?
   */
  if (!digit)
    return (0);
  /*
   * Concoct the address according to
   * the number of parts specified.
   */
  n = (int)(pp - parts + 1);
  switch (n) {
  case 1:       /* a -- 32 bits */
    break;

  case 2:       /* a.b -- 8.24 bits */
    if (val > 0xffffffU)
      return (0);
    val |= parts[0] << 24;
    break;

  case 3:       /* a.b.c -- 8.8.16 bits */
    if (val > 0xffffU)
      return (0);
    val |= (parts[0] << 24) | (parts[1] << 16);
    break;

  case 4:       /* a.b.c.d -- 8.8.8.8 bits */
    if (val > 0xffU)
      return (0);
    val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
    break;
  }
  if (addr != NULL)
    addr->s_addr = htonl(val);
  return (1);
}
