/*
 * Copyright (c) 1986, 1993
 *  The Regents of the University of California.  All rights reserved.
 *
 * This code is derived from software contributed to Berkeley by
 * J.Q. Johnson.
 *
 * Portions copyright (c) 1999, 2000
 * Intel Corporation.
 * 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, Intel Corporation, and its contributors.
 *
 * 4. Neither the name of University, Intel Corporation, or their respective
 *    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, INTEL CORPORATION 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,
 * INTEL CORPORATION 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.
 *
 */

#if defined(LIBC_SCCS) && !defined(lint)
static char sccsid[] = "@(#)ns_addr.c 8.1 (Berkeley) 6/7/93";
#endif /* LIBC_SCCS and not lint */

#include <sys/param.h>
#include <netns/ns.h>
#include <stdio.h>
#include <string.h>

static struct ns_addr addr, zero_addr;

static void Field   (char *buf, u_char *out, int len);
static void cvtbase (long oldbase, int newbase, int input[], int inlen, unsigned char result[], int reslen);

struct ns_addr
ns_addr(
  const char *name
  )
{
  char separator;
  char *hostname, *socketname, *cp;
  char buf[50];

  (void)strncpy(buf, name, sizeof(buf) - 1);
  buf[sizeof(buf) - 1] = '\0';

  /*
   * First, figure out what he intends as a field separtor.
   * Despite the way this routine is written, the prefered
   * form  2-272.AA001234H.01777, i.e. XDE standard.
   * Great efforts are made to insure backward compatability.
   */
  if ((hostname = strchr(buf, '#')) != NULL)
    separator = '#';
  else {
    hostname = strchr(buf, '.');
    if ((cp = strchr(buf, ':')) &&
        ((hostname && cp < hostname) || (hostname == 0))) {
      hostname = cp;
      separator = ':';
    } else
      separator = '.';
  }
  if (hostname)
    *hostname++ = 0;

  addr = zero_addr;
  Field(buf, addr.x_net.c_net, 4);
  if (hostname == 0)
    return (addr);  /* No separator means net only */

  socketname = strchr(hostname, separator);
  if (socketname) {
    *socketname++ = 0;
    Field(socketname, (u_char *)&addr.x_port, 2);
  }

  Field(hostname, addr.x_host.c_host, 6);

  return (addr);
}

static void
Field(
  char *buf,
  u_char *out,
  int len
  )
{
  register char *bp = buf;
  int i, ibase, base16 = 0, base10 = 0, clen = 0;
  int hb[6], *hp;
  char *fmt;

  /*
   * first try 2-273#2-852-151-014#socket
   */
  if ((*buf != '-') &&
      (1 < (i = sscanf(buf, "%d-%d-%d-%d-%d",
      &hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) {
    cvtbase(1000L, 256, hb, i, out, len);
    return;
  }
  /*
   * try form 8E1#0.0.AA.0.5E.E6#socket
   */
  if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x",
      &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
    cvtbase(256L, 256, hb, i, out, len);
    return;
  }
  /*
   * try form 8E1#0:0:AA:0:5E:E6#socket
   */
  if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x",
      &hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
    cvtbase(256L, 256, hb, i, out, len);
    return;
  }
  /*
   * This is REALLY stretching it but there was a
   * comma notation separting shorts -- definitely non standard
   */
  if (1 < (i = sscanf(buf,"%x,%x,%x",
      &hb[0], &hb[1], &hb[2]))) {
    hb[0] = htons(hb[0]); hb[1] = htons(hb[1]);
    hb[2] = htons(hb[2]);
    cvtbase(65536L, 256, hb, i, out, len);
    return;
  }

  /* Need to decide if base 10, 16 or 8 */
  while (*bp) switch (*bp++) {

  case '0': case '1': case '2': case '3': case '4': case '5':
  case '6': case '7': case '-':
    break;

  case '8': case '9':
    base10 = 1;
    break;

  case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
  case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
    base16 = 1;
    break;

  case 'x': case 'X':
    *--bp = '0';
    base16 = 1;
    break;

  case 'h': case 'H':
    base16 = 1;
    /* fall into */

  default:
    *--bp = 0; /* Ends Loop */
  }
  if (base16) {
    fmt = "%3x";
    ibase = 4096;
  } else if (base10 == 0 && *buf == '0') {
    fmt = "%3o";
    ibase = 512;
  } else {
    fmt = "%3d";
    ibase = 1000;
  }

  for (bp = buf; *bp++; ) clen++;
  if (clen == 0) clen++;
  if (clen > 18) clen = 18;
  i = ((clen - 1) / 3) + 1;
  bp = clen + buf - 3;
  hp = hb + i - 1;

  while (hp > hb) {
    (void)sscanf(bp, fmt, hp);
    bp[0] = 0;
    hp--;
    bp -= 3;
  }
  (void)sscanf(buf, fmt, hp);
  cvtbase((long)ibase, 256, hb, i, out, len);
}

static void
cvtbase(
  long oldbase,
  int newbase,
  int input[],
  int inlen,
  unsigned char result[],
  int reslen
  )
{
  int d, e;
  long sum;

  e = 1;
  while (e > 0 && reslen > 0) {
    d = 0; e = 0; sum = 0;
    /* long division: input=input/newbase */
    while (d < inlen) {
      sum = sum*oldbase + (long) input[d];
      e += (sum > 0);
      input[d++] = sum / newbase;
      sum %= newbase;
    }
    result[--reslen] = (u_char)sum; /* accumulate remainder */
  }
  for (d=0; d < reslen; d++)
    result[d] = 0;
}
