18462SApril.Chin@Sun.COM /***********************************************************************
28462SApril.Chin@Sun.COM * *
38462SApril.Chin@Sun.COM * This software is part of the ast package *
4*12068SRoger.Faulkner@Oracle.COM * Copyright (c) 1985-2010 AT&T Intellectual Property *
58462SApril.Chin@Sun.COM * and is licensed under the *
68462SApril.Chin@Sun.COM * Common Public License, Version 1.0 *
78462SApril.Chin@Sun.COM * by AT&T Intellectual Property *
88462SApril.Chin@Sun.COM * *
98462SApril.Chin@Sun.COM * A copy of the License is available at *
108462SApril.Chin@Sun.COM * http://www.opensource.org/licenses/cpl1.0.txt *
118462SApril.Chin@Sun.COM * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
128462SApril.Chin@Sun.COM * *
138462SApril.Chin@Sun.COM * Information and Software Systems Research *
148462SApril.Chin@Sun.COM * AT&T Research *
158462SApril.Chin@Sun.COM * Florham Park NJ *
168462SApril.Chin@Sun.COM * *
178462SApril.Chin@Sun.COM * Glenn Fowler <gsf@research.att.com> *
188462SApril.Chin@Sun.COM * David Korn <dgk@research.att.com> *
198462SApril.Chin@Sun.COM * Phong Vo <kpv@research.att.com> *
208462SApril.Chin@Sun.COM * *
218462SApril.Chin@Sun.COM ***********************************************************************/
228462SApril.Chin@Sun.COM #pragma prototyped
238462SApril.Chin@Sun.COM
248462SApril.Chin@Sun.COM #if _PACKAGE_ast
258462SApril.Chin@Sun.COM #include <ast.h>
268462SApril.Chin@Sun.COM #endif
278462SApril.Chin@Sun.COM
288462SApril.Chin@Sun.COM #include <ip6.h>
298462SApril.Chin@Sun.COM
308462SApril.Chin@Sun.COM #if !_PACKAGE_ast
318462SApril.Chin@Sun.COM
328462SApril.Chin@Sun.COM /*
338462SApril.Chin@Sun.COM * return a pointer to n bytes from a circular re-use buffer
348462SApril.Chin@Sun.COM */
358462SApril.Chin@Sun.COM
368462SApril.Chin@Sun.COM static char*
fmtbuf(int n)378462SApril.Chin@Sun.COM fmtbuf(int n)
388462SApril.Chin@Sun.COM {
398462SApril.Chin@Sun.COM char* b;
408462SApril.Chin@Sun.COM
418462SApril.Chin@Sun.COM static char buf[1024];
428462SApril.Chin@Sun.COM static char* p = buf;
438462SApril.Chin@Sun.COM
448462SApril.Chin@Sun.COM if ((&buf[sizeof(buf)] - p) < n)
458462SApril.Chin@Sun.COM p = buf;
468462SApril.Chin@Sun.COM b = p;
478462SApril.Chin@Sun.COM p += n;
488462SApril.Chin@Sun.COM return b;
498462SApril.Chin@Sun.COM }
508462SApril.Chin@Sun.COM
518462SApril.Chin@Sun.COM #endif
528462SApril.Chin@Sun.COM
538462SApril.Chin@Sun.COM /*
548462SApril.Chin@Sun.COM * copy p to s, then convert 0<=n<=999 to text
558462SApril.Chin@Sun.COM * next char in s returned
568462SApril.Chin@Sun.COM * caller ensures that s can take strlen(p)+3 bytes
578462SApril.Chin@Sun.COM */
588462SApril.Chin@Sun.COM
598462SApril.Chin@Sun.COM static char*
dec(char * s,char * p,int n)608462SApril.Chin@Sun.COM dec(char* s, char* p, int n)
618462SApril.Chin@Sun.COM {
628462SApril.Chin@Sun.COM while (*s = *p++)
638462SApril.Chin@Sun.COM s++;
648462SApril.Chin@Sun.COM if (n >= 100)
658462SApril.Chin@Sun.COM *s++ = '0' + ((n / 100) % 10);
668462SApril.Chin@Sun.COM if (n >= 10)
678462SApril.Chin@Sun.COM *s++ = '0' + ((n / 10) % 10);
688462SApril.Chin@Sun.COM *s++ = '0' + (n % 10);
698462SApril.Chin@Sun.COM return s;
708462SApril.Chin@Sun.COM }
718462SApril.Chin@Sun.COM
728462SApril.Chin@Sun.COM /*
738462SApril.Chin@Sun.COM * return pointer to normalized ipv6 address addr
748462SApril.Chin@Sun.COM * with optional prefix bits if 0 < bits <= 128
758462SApril.Chin@Sun.COM * return value in short-term circular buffer
768462SApril.Chin@Sun.COM */
778462SApril.Chin@Sun.COM
788462SApril.Chin@Sun.COM char*
fmtip6(unsigned char * addr,int bits)798462SApril.Chin@Sun.COM fmtip6(unsigned char* addr, int bits)
808462SApril.Chin@Sun.COM {
818462SApril.Chin@Sun.COM register unsigned char* a = addr;
828462SApril.Chin@Sun.COM register int n = IP6ADDR;
838462SApril.Chin@Sun.COM register int i;
848462SApril.Chin@Sun.COM register int z;
858462SApril.Chin@Sun.COM register int k;
868462SApril.Chin@Sun.COM register int m;
878462SApril.Chin@Sun.COM unsigned char r[IP6ADDR];
888462SApril.Chin@Sun.COM char* b;
898462SApril.Chin@Sun.COM char* s;
908462SApril.Chin@Sun.COM
918462SApril.Chin@Sun.COM static const char dig[] = "0123456789ABCDEF";
928462SApril.Chin@Sun.COM
938462SApril.Chin@Sun.COM s = b = fmtbuf(44);
948462SApril.Chin@Sun.COM r[m = z = 0] = 0;
958462SApril.Chin@Sun.COM if (a[0] == 0x20 && a[1] == 0x02 && (a[2] || a[3] || a[4] || a[5]))
968462SApril.Chin@Sun.COM {
978462SApril.Chin@Sun.COM z = 6;
988462SApril.Chin@Sun.COM s = dec(s, "2002:", a[2]);
998462SApril.Chin@Sun.COM s = dec(s, ".", a[3]);
1008462SApril.Chin@Sun.COM s = dec(s, ".", a[4]);
1018462SApril.Chin@Sun.COM s = dec(s, ".", a[5]);
1028462SApril.Chin@Sun.COM }
1038462SApril.Chin@Sun.COM for (i = z; i < n; i += 2)
1048462SApril.Chin@Sun.COM {
1058462SApril.Chin@Sun.COM for (k = i; i < n - 1 && !a[i] && !a[i + 1]; i += 2);
1068462SApril.Chin@Sun.COM if ((r[k] = i - k) > r[m] || r[k] == r[m] && i >= (n - 1))
1078462SApril.Chin@Sun.COM m = k;
1088462SApril.Chin@Sun.COM }
1098462SApril.Chin@Sun.COM if (!m)
1108462SApril.Chin@Sun.COM switch (r[m])
1118462SApril.Chin@Sun.COM {
1128462SApril.Chin@Sun.COM case 0:
1138462SApril.Chin@Sun.COM m = -1;
1148462SApril.Chin@Sun.COM break;
1158462SApril.Chin@Sun.COM case 14:
1168462SApril.Chin@Sun.COM if (!a[14] && a[15] <= 15)
1178462SApril.Chin@Sun.COM break;
1188462SApril.Chin@Sun.COM /*FALLTHROUGH*/
1198462SApril.Chin@Sun.COM case 12:
1208462SApril.Chin@Sun.COM s = dec(s, "::", a[12]);
1218462SApril.Chin@Sun.COM s = dec(s, ".", a[13]);
1228462SApril.Chin@Sun.COM s = dec(s, ".", a[14]);
1238462SApril.Chin@Sun.COM s = dec(s, ".", a[15]);
1248462SApril.Chin@Sun.COM n = 0;
1258462SApril.Chin@Sun.COM break;
1268462SApril.Chin@Sun.COM case 10:
1278462SApril.Chin@Sun.COM if (a[10] == 0xFF && a[11] == 0xFF)
1288462SApril.Chin@Sun.COM {
1298462SApril.Chin@Sun.COM s = dec(s, "::FFFF:", a[12]);
1308462SApril.Chin@Sun.COM s = dec(s, ".", a[13]);
1318462SApril.Chin@Sun.COM s = dec(s, ".", a[14]);
1328462SApril.Chin@Sun.COM s = dec(s, ".", a[15]);
1338462SApril.Chin@Sun.COM n = 0;
1348462SApril.Chin@Sun.COM }
1358462SApril.Chin@Sun.COM break;
1368462SApril.Chin@Sun.COM }
1378462SApril.Chin@Sun.COM for (i = z; i < n; i++)
1388462SApril.Chin@Sun.COM {
1398462SApril.Chin@Sun.COM if (i == m)
1408462SApril.Chin@Sun.COM {
1418462SApril.Chin@Sun.COM *s++ = ':';
1428462SApril.Chin@Sun.COM *s++ = ':';
1438462SApril.Chin@Sun.COM if ((i += r[m]) >= n)
14410898Sroland.mainz@nrubsig.org {
14510898Sroland.mainz@nrubsig.org z = 1;
1468462SApril.Chin@Sun.COM break;
14710898Sroland.mainz@nrubsig.org }
1488462SApril.Chin@Sun.COM z = 0;
1498462SApril.Chin@Sun.COM }
1508462SApril.Chin@Sun.COM else if (i && !(i & 1))
1518462SApril.Chin@Sun.COM {
1528462SApril.Chin@Sun.COM if (z)
1538462SApril.Chin@Sun.COM z = 0;
1548462SApril.Chin@Sun.COM else
1558462SApril.Chin@Sun.COM *s++ = '0';
1568462SApril.Chin@Sun.COM *s++ = ':';
1578462SApril.Chin@Sun.COM }
1588462SApril.Chin@Sun.COM if ((k = (a[i] >> 4) & 0xf) || z)
1598462SApril.Chin@Sun.COM {
1608462SApril.Chin@Sun.COM z = 1;
1618462SApril.Chin@Sun.COM *s++ = dig[k];
1628462SApril.Chin@Sun.COM }
1638462SApril.Chin@Sun.COM if ((k = a[i] & 0xf) || z)
1648462SApril.Chin@Sun.COM {
1658462SApril.Chin@Sun.COM z = 1;
1668462SApril.Chin@Sun.COM *s++ = dig[k];
1678462SApril.Chin@Sun.COM }
1688462SApril.Chin@Sun.COM }
16910898Sroland.mainz@nrubsig.org if (!z && *(s - 1) == ':')
17010898Sroland.mainz@nrubsig.org *s++ = '0';
1718462SApril.Chin@Sun.COM if (bits > 0 && bits <= 128)
1728462SApril.Chin@Sun.COM s = dec(s, "/", bits);
1738462SApril.Chin@Sun.COM *s = 0;
1748462SApril.Chin@Sun.COM return b;
1758462SApril.Chin@Sun.COM }
176