Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libast/string/fmtip6.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1985-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* David Korn <[email protected]> *
19
* Phong Vo <[email protected]> *
20
* *
21
***********************************************************************/
22
#pragma prototyped
23
24
#if _PACKAGE_ast
25
#include <ast.h>
26
#endif
27
28
#include <ip6.h>
29
30
#if !_PACKAGE_ast
31
32
/*
33
* return a pointer to n bytes from a circular re-use buffer
34
*/
35
36
static char*
37
fmtbuf(int n)
38
{
39
char* b;
40
41
static char buf[1024];
42
static char* p = buf;
43
44
if ((&buf[sizeof(buf)] - p) < n)
45
p = buf;
46
b = p;
47
p += n;
48
return b;
49
}
50
51
#endif
52
53
/*
54
* copy p to s, then convert 0<=n<=999 to text
55
* next char in s returned
56
* caller ensures that s can take strlen(p)+3 bytes
57
*/
58
59
static char*
60
dec(char* s, char* p, int n)
61
{
62
while (*s = *p++)
63
s++;
64
if (n >= 100)
65
*s++ = '0' + ((n / 100) % 10);
66
if (n >= 10)
67
*s++ = '0' + ((n / 10) % 10);
68
*s++ = '0' + (n % 10);
69
return s;
70
}
71
72
/*
73
* return pointer to normalized ipv6 address addr
74
* with optional prefix bits if 0 <= bits <= 128
75
* return value in short-term circular buffer
76
*/
77
78
char*
79
fmtip6(const unsigned char* addr, int bits)
80
{
81
register const unsigned char* a = addr;
82
register int n = IP6ADDR;
83
register int i;
84
register int z;
85
register int k;
86
register int m;
87
unsigned char r[IP6ADDR];
88
char* b;
89
char* s;
90
91
static const char dig[] = "0123456789ABCDEF";
92
93
s = b = fmtbuf(44);
94
r[m = z = 0] = 0;
95
if (a[0] == 0x20 && a[1] == 0x02 && (a[2] || a[3] || a[4] || a[5]))
96
{
97
z = 6;
98
s = dec(s, "2002:", a[2]);
99
s = dec(s, ".", a[3]);
100
s = dec(s, ".", a[4]);
101
s = dec(s, ".", a[5]);
102
}
103
for (i = z; i < n; i += 2)
104
{
105
for (k = i; i < n - 1 && !a[i] && !a[i + 1]; i += 2);
106
if ((r[k] = i - k) > r[m] || r[k] == r[m] && i >= (n - 1))
107
m = k;
108
}
109
if (!m)
110
switch (r[m])
111
{
112
case 0:
113
m = -1;
114
break;
115
case 14:
116
if (!a[14] && a[15] <= 15)
117
break;
118
/*FALLTHROUGH*/
119
case 12:
120
s = dec(s, "::", a[12]);
121
s = dec(s, ".", a[13]);
122
s = dec(s, ".", a[14]);
123
s = dec(s, ".", a[15]);
124
n = 0;
125
break;
126
case 10:
127
if (a[10] == 0xFF && a[11] == 0xFF)
128
{
129
s = dec(s, "::FFFF:", a[12]);
130
s = dec(s, ".", a[13]);
131
s = dec(s, ".", a[14]);
132
s = dec(s, ".", a[15]);
133
n = 0;
134
}
135
break;
136
}
137
for (i = z; i < n; i++)
138
{
139
if (i == m)
140
{
141
*s++ = ':';
142
*s++ = ':';
143
if ((i += r[m]) >= n)
144
{
145
z = 1;
146
break;
147
}
148
z = 0;
149
}
150
else if (i && !(i & 1))
151
{
152
if (z)
153
z = 0;
154
else
155
*s++ = '0';
156
*s++ = ':';
157
}
158
if ((k = (a[i] >> 4) & 0xf) || z)
159
{
160
z = 1;
161
*s++ = dig[k];
162
}
163
if ((k = a[i] & 0xf) || z)
164
{
165
z = 1;
166
*s++ = dig[k];
167
}
168
}
169
if (!z && *(s - 1) == ':')
170
*s++ = '0';
171
if (bits >= 0 && bits <= 128)
172
s = dec(s, "/", bits);
173
*s = 0;
174
return b;
175
}
176
177