Logo Search packages:      
Sourcecode: ksh version File versions  Download package

fmtip6.c

/***********************************************************************
*                                                                      *
*               This software is part of the ast package               *
*          Copyright (c) 1985-2010 AT&T Intellectual Property          *
*                      and is licensed under the                       *
*                  Common Public License, Version 1.0                  *
*                    by AT&T Intellectual Property                     *
*                                                                      *
*                A copy of the License is available at                 *
*            http://www.opensource.org/licenses/cpl1.0.txt             *
*         (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9)         *
*                                                                      *
*              Information and Software Systems Research               *
*                            AT&T Research                             *
*                           Florham Park NJ                            *
*                                                                      *
*                 Glenn Fowler <gsf@research.att.com>                  *
*                  David Korn <dgk@research.att.com>                   *
*                   Phong Vo <kpv@research.att.com>                    *
*                                                                      *
***********************************************************************/
#pragma prototyped

#if _PACKAGE_ast
#include <ast.h>
#endif

#include <ip6.h>

#if !_PACKAGE_ast

/*
 * return a pointer to n bytes from a circular re-use buffer
 */

static char*
fmtbuf(int n)
{
      char*       b;

      static char buf[1024];
      static char*      p = buf;

      if ((&buf[sizeof(buf)] - p) < n)
            p = buf;
      b = p;
      p += n;
      return b;
}

#endif

/* 
 * copy p to s, then convert 0<=n<=999 to text
 * next char in s returned
 * caller ensures that s can take strlen(p)+3 bytes
 */

static char*
dec(char* s, char* p, int n)
{
      while (*s = *p++)
            s++;
      if (n >= 100)
            *s++ = '0' + ((n / 100) % 10);
      if (n >= 10)
            *s++ = '0' + ((n / 10) % 10);
      *s++ = '0' + (n % 10);
      return s;
}

/*
 * return pointer to normalized ipv6 address addr
 * with optional prefix bits if 0 < bits <= 128
 * return value in short-term circular buffer
 */

char*
fmtip6(unsigned char* addr, int bits)
{
      register unsigned char* a = addr;
      register int            n = IP6ADDR;
      register int            i;
      register int            z;
      register int            k;
      register int            m;
      unsigned char           r[IP6ADDR];
      char*             b;
      char*             s;

      static const char dig[] = "0123456789ABCDEF";

      s = b = fmtbuf(44);
      r[m = z = 0] = 0;
      if (a[0] == 0x20 && a[1] == 0x02 && (a[2] || a[3] || a[4] || a[5]))
      {
            z = 6;
            s = dec(s, "2002:", a[2]);
            s = dec(s, ".", a[3]);
            s = dec(s, ".", a[4]);
            s = dec(s, ".", a[5]);
      }
      for (i = z; i < n; i += 2)
      {
            for (k = i; i < n - 1 && !a[i] && !a[i + 1]; i += 2);
            if ((r[k] = i - k) > r[m] || r[k] == r[m] && i >= (n - 1))
                  m = k;
      }
      if (!m)
            switch (r[m])
            {
            case 0:
                  m = -1;
                  break;
            case 14:
                  if (!a[14] && a[15] <= 15)
                        break;
                  /*FALLTHROUGH*/
            case 12:
                  s = dec(s, "::", a[12]);
                  s = dec(s, ".", a[13]);
                  s = dec(s, ".", a[14]);
                  s = dec(s, ".", a[15]);
                  n = 0;
                  break;
            case 10:
                  if (a[10] == 0xFF && a[11] == 0xFF)
                  {
                        s = dec(s, "::FFFF:", a[12]);
                        s = dec(s, ".", a[13]);
                        s = dec(s, ".", a[14]);
                        s = dec(s, ".", a[15]);
                        n = 0;
                  }
                  break;
            }
      for (i = z; i < n; i++)
      {
            if (i == m)
            {
                  *s++ = ':';
                  *s++ = ':';
                  if ((i += r[m]) >= n)
                  {
                        z = 1;
                        break;
                  }
                  z = 0;
            }
            else if (i && !(i & 1))
            {
                  if (z)
                        z = 0;
                  else
                        *s++ = '0';
                  *s++ = ':';
            }
            if ((k = (a[i] >> 4) & 0xf) || z)
            {
                  z = 1;
                  *s++ = dig[k];
            }
            if ((k = a[i] & 0xf) || z)
            {
                  z = 1;
                  *s++ = dig[k];
            }
      }
      if (!z && *(s - 1) == ':')
            *s++ = '0';
      if (bits > 0 && bits <= 128)
            s = dec(s, "/", bits);
      *s = 0;
      return b;
}

Generated by  Doxygen 1.6.0   Back to index