17c2fbfb3SApril Chin /***********************************************************************
27c2fbfb3SApril Chin * *
37c2fbfb3SApril Chin * This software is part of the ast package *
4*b30d1939SAndy Fiddaman * Copyright (c) 1985-2011 AT&T Intellectual Property *
57c2fbfb3SApril Chin * and is licensed under the *
6*b30d1939SAndy Fiddaman * Eclipse Public License, Version 1.0 *
77c2fbfb3SApril Chin * by AT&T Intellectual Property *
87c2fbfb3SApril Chin * *
97c2fbfb3SApril Chin * A copy of the License is available at *
10*b30d1939SAndy Fiddaman * http://www.eclipse.org/org/documents/epl-v10.html *
11*b30d1939SAndy Fiddaman * (with md5 checksum b35adb5213ca9657e911e9befb180842) *
127c2fbfb3SApril Chin * *
137c2fbfb3SApril Chin * Information and Software Systems Research *
147c2fbfb3SApril Chin * AT&T Research *
157c2fbfb3SApril Chin * Florham Park NJ *
167c2fbfb3SApril Chin * *
177c2fbfb3SApril Chin * Glenn Fowler <gsf@research.att.com> *
187c2fbfb3SApril Chin * David Korn <dgk@research.att.com> *
197c2fbfb3SApril Chin * Phong Vo <kpv@research.att.com> *
207c2fbfb3SApril Chin * *
217c2fbfb3SApril Chin ***********************************************************************/
227c2fbfb3SApril Chin #pragma prototyped
237c2fbfb3SApril Chin
247c2fbfb3SApril Chin #if _PACKAGE_ast
257c2fbfb3SApril Chin #include <ast.h>
267c2fbfb3SApril Chin #endif
277c2fbfb3SApril Chin
287c2fbfb3SApril Chin #include <ip6.h>
297c2fbfb3SApril Chin
307c2fbfb3SApril Chin #if !_PACKAGE_ast
317c2fbfb3SApril Chin
327c2fbfb3SApril Chin /*
337c2fbfb3SApril Chin * return a pointer to n bytes from a circular re-use buffer
347c2fbfb3SApril Chin */
357c2fbfb3SApril Chin
367c2fbfb3SApril Chin static char*
fmtbuf(int n)377c2fbfb3SApril Chin fmtbuf(int n)
387c2fbfb3SApril Chin {
397c2fbfb3SApril Chin char* b;
407c2fbfb3SApril Chin
417c2fbfb3SApril Chin static char buf[1024];
427c2fbfb3SApril Chin static char* p = buf;
437c2fbfb3SApril Chin
447c2fbfb3SApril Chin if ((&buf[sizeof(buf)] - p) < n)
457c2fbfb3SApril Chin p = buf;
467c2fbfb3SApril Chin b = p;
477c2fbfb3SApril Chin p += n;
487c2fbfb3SApril Chin return b;
497c2fbfb3SApril Chin }
507c2fbfb3SApril Chin
517c2fbfb3SApril Chin #endif
527c2fbfb3SApril Chin
537c2fbfb3SApril Chin /*
547c2fbfb3SApril Chin * copy p to s, then convert 0<=n<=999 to text
557c2fbfb3SApril Chin * next char in s returned
567c2fbfb3SApril Chin * caller ensures that s can take strlen(p)+3 bytes
577c2fbfb3SApril Chin */
587c2fbfb3SApril Chin
597c2fbfb3SApril Chin static char*
dec(char * s,char * p,int n)607c2fbfb3SApril Chin dec(char* s, char* p, int n)
617c2fbfb3SApril Chin {
627c2fbfb3SApril Chin while (*s = *p++)
637c2fbfb3SApril Chin s++;
647c2fbfb3SApril Chin if (n >= 100)
657c2fbfb3SApril Chin *s++ = '0' + ((n / 100) % 10);
667c2fbfb3SApril Chin if (n >= 10)
677c2fbfb3SApril Chin *s++ = '0' + ((n / 10) % 10);
687c2fbfb3SApril Chin *s++ = '0' + (n % 10);
697c2fbfb3SApril Chin return s;
707c2fbfb3SApril Chin }
717c2fbfb3SApril Chin
727c2fbfb3SApril Chin /*
737c2fbfb3SApril Chin * return pointer to normalized ipv6 address addr
74*b30d1939SAndy Fiddaman * with optional prefix bits if 0 <= bits <= 128
757c2fbfb3SApril Chin * return value in short-term circular buffer
767c2fbfb3SApril Chin */
777c2fbfb3SApril Chin
787c2fbfb3SApril Chin char*
fmtip6(const unsigned char * addr,int bits)79*b30d1939SAndy Fiddaman fmtip6(const unsigned char* addr, int bits)
807c2fbfb3SApril Chin {
81*b30d1939SAndy Fiddaman register const unsigned char* a = addr;
82*b30d1939SAndy Fiddaman register int n = IP6ADDR;
83*b30d1939SAndy Fiddaman register int i;
84*b30d1939SAndy Fiddaman register int z;
85*b30d1939SAndy Fiddaman register int k;
86*b30d1939SAndy Fiddaman register int m;
87*b30d1939SAndy Fiddaman unsigned char r[IP6ADDR];
88*b30d1939SAndy Fiddaman char* b;
89*b30d1939SAndy Fiddaman char* s;
907c2fbfb3SApril Chin
917c2fbfb3SApril Chin static const char dig[] = "0123456789ABCDEF";
927c2fbfb3SApril Chin
937c2fbfb3SApril Chin s = b = fmtbuf(44);
947c2fbfb3SApril Chin r[m = z = 0] = 0;
957c2fbfb3SApril Chin if (a[0] == 0x20 && a[1] == 0x02 && (a[2] || a[3] || a[4] || a[5]))
967c2fbfb3SApril Chin {
977c2fbfb3SApril Chin z = 6;
987c2fbfb3SApril Chin s = dec(s, "2002:", a[2]);
997c2fbfb3SApril Chin s = dec(s, ".", a[3]);
1007c2fbfb3SApril Chin s = dec(s, ".", a[4]);
1017c2fbfb3SApril Chin s = dec(s, ".", a[5]);
1027c2fbfb3SApril Chin }
1037c2fbfb3SApril Chin for (i = z; i < n; i += 2)
1047c2fbfb3SApril Chin {
1057c2fbfb3SApril Chin for (k = i; i < n - 1 && !a[i] && !a[i + 1]; i += 2);
1067c2fbfb3SApril Chin if ((r[k] = i - k) > r[m] || r[k] == r[m] && i >= (n - 1))
1077c2fbfb3SApril Chin m = k;
1087c2fbfb3SApril Chin }
1097c2fbfb3SApril Chin if (!m)
1107c2fbfb3SApril Chin switch (r[m])
1117c2fbfb3SApril Chin {
1127c2fbfb3SApril Chin case 0:
1137c2fbfb3SApril Chin m = -1;
1147c2fbfb3SApril Chin break;
1157c2fbfb3SApril Chin case 14:
1167c2fbfb3SApril Chin if (!a[14] && a[15] <= 15)
1177c2fbfb3SApril Chin break;
1187c2fbfb3SApril Chin /*FALLTHROUGH*/
1197c2fbfb3SApril Chin case 12:
1207c2fbfb3SApril Chin s = dec(s, "::", a[12]);
1217c2fbfb3SApril Chin s = dec(s, ".", a[13]);
1227c2fbfb3SApril Chin s = dec(s, ".", a[14]);
1237c2fbfb3SApril Chin s = dec(s, ".", a[15]);
1247c2fbfb3SApril Chin n = 0;
1257c2fbfb3SApril Chin break;
1267c2fbfb3SApril Chin case 10:
1277c2fbfb3SApril Chin if (a[10] == 0xFF && a[11] == 0xFF)
1287c2fbfb3SApril Chin {
1297c2fbfb3SApril Chin s = dec(s, "::FFFF:", a[12]);
1307c2fbfb3SApril Chin s = dec(s, ".", a[13]);
1317c2fbfb3SApril Chin s = dec(s, ".", a[14]);
1327c2fbfb3SApril Chin s = dec(s, ".", a[15]);
1337c2fbfb3SApril Chin n = 0;
1347c2fbfb3SApril Chin }
1357c2fbfb3SApril Chin break;
1367c2fbfb3SApril Chin }
1377c2fbfb3SApril Chin for (i = z; i < n; i++)
1387c2fbfb3SApril Chin {
1397c2fbfb3SApril Chin if (i == m)
1407c2fbfb3SApril Chin {
1417c2fbfb3SApril Chin *s++ = ':';
1427c2fbfb3SApril Chin *s++ = ':';
1437c2fbfb3SApril Chin if ((i += r[m]) >= n)
14434f9b3eeSRoland Mainz {
14534f9b3eeSRoland Mainz z = 1;
1467c2fbfb3SApril Chin break;
14734f9b3eeSRoland Mainz }
1487c2fbfb3SApril Chin z = 0;
1497c2fbfb3SApril Chin }
1507c2fbfb3SApril Chin else if (i && !(i & 1))
1517c2fbfb3SApril Chin {
1527c2fbfb3SApril Chin if (z)
1537c2fbfb3SApril Chin z = 0;
1547c2fbfb3SApril Chin else
1557c2fbfb3SApril Chin *s++ = '0';
1567c2fbfb3SApril Chin *s++ = ':';
1577c2fbfb3SApril Chin }
1587c2fbfb3SApril Chin if ((k = (a[i] >> 4) & 0xf) || z)
1597c2fbfb3SApril Chin {
1607c2fbfb3SApril Chin z = 1;
1617c2fbfb3SApril Chin *s++ = dig[k];
1627c2fbfb3SApril Chin }
1637c2fbfb3SApril Chin if ((k = a[i] & 0xf) || z)
1647c2fbfb3SApril Chin {
1657c2fbfb3SApril Chin z = 1;
1667c2fbfb3SApril Chin *s++ = dig[k];
1677c2fbfb3SApril Chin }
1687c2fbfb3SApril Chin }
16934f9b3eeSRoland Mainz if (!z && *(s - 1) == ':')
17034f9b3eeSRoland Mainz *s++ = '0';
171*b30d1939SAndy Fiddaman if (bits >= 0 && bits <= 128)
1727c2fbfb3SApril Chin s = dec(s, "/", bits);
1737c2fbfb3SApril Chin *s = 0;
1747c2fbfb3SApril Chin return b;
1757c2fbfb3SApril Chin }
176