fehQlibs 26
Qlibs
Loading...
Searching...
No Matches
ip6.c
Go to the documentation of this file.
1#include "fmt.h"
2#include "byte.h"
3#include "scan.h"
4#include "ip.h"
5#include "str.h"
6
21unsigned int ip6_fmt(char *s,char ip[16])
22{
23 unsigned int len;
24 unsigned int i;
25 unsigned int temp, temp0;
26 unsigned int compressing;
27 unsigned int compressed;
28 int j;
29
30 len = 0;
31 compressing = 0;
32 compressed = 0;
33
34 for (j = 0; j < 16; j += 2) {
35 if (j == 12 && ip6_isv4mapped(ip)) {
36 len += ip4_fmt(s,ip+12);
37 break;
38 }
39
40 temp = ((unsigned long) (unsigned char) ip[j] << 8) +
41 (unsigned long) (unsigned char) ip[j+1];
42
43 temp0 = 0;
44 if (!compressing && j < 16)
45 temp0 = ((unsigned long) (unsigned char) ip[j+2] << 8) +
46 (unsigned long) (unsigned char) ip[j+3];
47
48 if (temp == 0 && temp0 == 0 && !compressed) {
49 if (!compressing) {
50 compressing = 1;
51 if (j == 0) {
52 if (s) *s++ = ':';
53 ++len;
54 }
55 }
56 } else {
57 if (compressing) {
58 compressing = 0;
59 ++compressed;
60 if (s) *s++ = ':';
61 ++len;
62 }
63 i = fmt_xlong(s,temp);
64 len += i;
65 if (s) s += i;
66 if (j < 14) {
67 if (s) *s++ = ':';
68 ++len;
69 }
70 }
71 }
72 if (compressing) { *s++ = ':'; ++len; }
73
74 return len;
75}
76
84unsigned int ip6_fmt_flat(char *s,char ip[16])
85{
86 int i;
87 for (i = 0; i < 16; i++) {
88 *s++ = tohex((unsigned char)ip[i] >> 4);
89 *s++ = tohex((unsigned char)ip[i] & 15);
90 }
91 return 32;
92}
93
102unsigned int ia6_fmt(char *s,char ip[16])
103{
104 unsigned int i;
105 unsigned int len;
106 int j;
107
108 static char data[] = "0123456789abcdef";
109 len = 0;
110
111 for (j = 15; j >= 0; j--) {
112 i = fmt_str(s,&data[ip[j] & 0x0f]); len += i; if (s) s += i;
113 i = fmt_str(s,"."); len += i; if (s) s += i;
114 i = fmt_str(s,&data[ip[j] >> 4 & 0x0f]); len += i; if (s) s += i;
115 i = fmt_str(s,"."); len += i; if (s) s += i;
116 }
117 i = fmt_str(s,"ip6.arpa."); len += i; if (s) s += i;
118
119 return len;
120}
121
129unsigned int ip6_scan_flat(const char *s,char ip[16])
130{
131 int i, tmp;
132
133 for (i = 0; i < 16; i++) {
134 tmp = fromhex(*s++);
135 if (tmp < 0) return 0;
136 ip[i] = tmp << 4;
137 tmp = fromhex(*s++);
138 if (tmp < 0) return 0;
139 ip[i] += tmp;
140 }
141 return 32;
142}
143
151unsigned int ip6_scan(const char *s,char ip[16])
152{
153 unsigned int i, j;
154 unsigned int len = 0;
155 unsigned long u;
156
157 char suffix[16];
158 int prefixlen = 0;
159 int suffixlen = 0;
160
161 /* Always return IPv4 as IPv4-mapped IPv6 address */
162 if ((i = ip4_scan(s,ip+12))) {
163 for (len = 0; len < 12; ++len)
164 ip[len] = V4mappedprefix[len];
165 return i;
166 if (byte_equal(ip+12,4,V4localnet)) {
167 byte_copy(ip,16,V6localnet);
168 return 16;
169 }
170 }
171 byte_zero(ip,16);
172
173 for (;;) {
174 if (*s == ':') {
175 len++;
176 if (s[1] == ':') { /* Found "::", skip to part 2 */
177 s += 2; len++;
178 break;
179 }
180 s++;
181 }
182 i = scan_xlong((char *)s,&u);
183 if (!i) return 0;
184
185 if (prefixlen == 12 && s[i] == '.') {
186 /* the last 4 bytes may be written as IPv4 address */
187 i = ip4_scan(s,ip+12);
188 if (i)
189 return i+len;
190 else
191 return 0;
192 }
193
194 ip[prefixlen++] = (u >> 8);
195 ip[prefixlen++] = (u & 255);
196 s += i; len += i;
197 if (prefixlen == 16) return len;
198 }
199
200/* part 2, after "::" */
201 for (;;) {
202 if (*s == ':') {
203 if (suffixlen == 0) break;
204 s++;
205 len++;
206 } else if (suffixlen != 0) break;
207
208 i = scan_xlong((char *)s,&u);
209 if (!i) {
210 len--;
211 break;
212 }
213
214 if (suffixlen + prefixlen <= 12 && s[i] == '.') {
215 j = ip4_scan(s,suffix+suffixlen);
216 if (j) {
217 suffixlen += 4;
218 len += j;
219 break;
220 } else
221 prefixlen = 12 - suffixlen; /* make end-of-loop test true */
222 }
223
224 suffix[suffixlen++] = (u >> 8);
225 suffix[suffixlen++] = (u & 255);
226 s += i; len += i;
227 if (prefixlen + suffixlen == 16) break;
228 }
229
230 for (i = 0; i < suffixlen; i++)
231 ip[16 - suffixlen + i] = suffix[i];
232
233 return len;
234}
235
243unsigned int ip6_scanbracket(const char *s,char ip[16])
244{
245 unsigned int len;
246
247 if (*s != '[') return 0;
248 len = ip6_scan(s + 1,ip);
249 if (!len) return 0;
250 if (s[len + 1] != ']') return 0;
251 return len + 2;
252}
253
262unsigned int ip6_ifscan(char *s,char ip[16],stralloc *ifname)
263{
264 int i;
265 int j = 0;
266 int k = 0;
267 if (!stralloc_copys(ifname,"0")) return 0;
268
269 if ((j = str_chr(s,'%'))) {
270 if ((i = str_chr(s+j+1,' '))) k = i;
271 else if ((i = str_chr(s+j+1,'\n'))) k = i;
272 else if ((i = str_chr(s+j+1,'\t'))) k = i;
273 if (k) s[j+k+1] = '\0'; /* input might contain trailing chars */
274 if (!stralloc_copys(ifname,s+j+1)) return 0;
275 s[j] = 0;
276 }
277 if (!stralloc_0(ifname)) return 0;
278
279 return ip6_scan(s,ip);
280}
281
290unsigned int ip6_cidr(char *s,char ip[16],unsigned long *plen)
291{
292 unsigned int j = 0;
293 *plen = 128UL;
294
295 j = str_chr(s,'/');
296 if (s[j] == '/') {
297 s[j] = 0;
298 j = scan_ulong(s+j+1,plen);
299 }
300 return ip6_scan((const char *)s,ip);
301}
302
310unsigned int ip6_bytestring(stralloc *ipstring,char ip[16],int prefix)
311{
312 int i, j, n = 0;
313 unsigned char lowbyte, highbyte;
314
315 if (!stralloc_readyplus(ipstring,128)) return -1;
316 if (!stralloc_copys(ipstring,"")) return -1;
317
318 for (i = 0; i < 16; i++) {
319 lowbyte = (unsigned char) (ip[i]) & 0x0f;
320 highbyte = (unsigned char) (ip[i] >> 4) & 0x0f;
321
322 for (j = 3; j >= 0; j--) {
323 if (highbyte & (1 << j)) {
324 n++;
325 if (!stralloc_cats(ipstring,"1")) return -1;
326 } else {
327 n++;
328 if (!stralloc_cats(ipstring,"0")) return -1;
329 }
330 prefix--;
331 if (!prefix) goto DONE;
332 }
333 for (j = 3; j >= 0; j--) {
334 if (lowbyte & (1 << j)) {
335 n++;
336 if (!stralloc_cats(ipstring,"1")) return -1;
337 } else {
338 n++;
339 if (!stralloc_cats(ipstring,"0")) return -1;
340 }
341 prefix--;
342 if (!prefix) goto DONE;
343 }
344 }
345
346DONE:
347 if (!stralloc_0(ipstring)) return -1;
348
349 return n;
350}
const unsigned char V4localnet[4]
Definition: socket_if.c:16
const unsigned char V4mappedprefix[12]
Definition: socket_if.c:18
const unsigned char V6localnet[16]
Definition: socket_if.c:19
unsigned int ip6_fmt_flat(char *s, char ip[16])
ip6_fmt_flat convert IPv6 address to IPv6 address string
Definition: ip6.c:84
unsigned int ia6_fmt(char *s, char ip[16])
ia6_fmt convert IPv6 address to inverse DNS nibble format 1.2.3.4.5.6.7.8.9.a.b.c....
Definition: ip6.c:102
unsigned int ip6_cidr(char *s, char ip[16], unsigned long *plen)
ip6_cidr parse compactified IPv6 address string concatinated with the prefix length: fe80::1/64
Definition: ip6.c:290
unsigned int ip6_scan_flat(const char *s, char ip[16])
ip6_scan_flat convert IPv6 address string to IPv6 address array
Definition: ip6.c:129
unsigned int ip6_fmt(char *s, char ip[16])
ip6_fmt convert IPv6 address to compactified IPv6 address string
Definition: ip6.c:21
unsigned int ip6_ifscan(char *s, char ip[16], stralloc *ifname)
ip6_ifscan parse compactified IPv6 address string concatinated with the interface name: fe80::1eth0
Definition: ip6.c:262
unsigned int ip6_scanbracket(const char *s, char ip[16])
ip6_scanbracket parse IPv6 string address enclosed in brackets
Definition: ip6.c:243
unsigned int ip6_bytestring(stralloc *ipstring, char ip[16], int prefix)
ip6_bytestring parse IPv6 address and represent as char string with length prefix
Definition: ip6.c:310
unsigned int ip6_scan(const char *s, char ip[16])
ip6_scan parse compactified IPv6 address string and convert to IPv6 address array
Definition: ip6.c:151
unsigned int ip4_fmt(char *, char[4])
ip4_fmt converts IPv4 address to dotted decimal string format
Definition: ip4.c:20
#define ip6_isv4mapped(ip)
Definition: ip.h:105
unsigned int ip4_scan(const char *, char[4])
ip4_scan parse IPv4 address string and convert to IP address array
Definition: ip4.c:67
unsigned int scan_xlong(const char *, unsigned long *)
Definition: scan.c:93
unsigned int scan_ulong(const char *, unsigned long *)
Definition: scan.c:79
conversion function declarations
unsigned int fmt_xlong(char *, unsigned long)
Definition: fmt.c:57
unsigned int fmt_str(char *, const char *)
Definition: fmt.c:10
int fromhex(unsigned char)
Definition: fmt.c:79
char tohex(char)
Definition: fmt.c:70
void byte_copy(void *, unsigned int, const void *)
Definition: byte.c:20
#define byte_equal(s, n, t)
Definition: byte.h:18
void byte_zero(void *, unsigned int)
Definition: byte.c:65
unsigned int str_chr(const char *, int)
Definition: str.c:81
#define stralloc_0(sa)
Definition: stralloc.h:37
int stralloc_cats(stralloc *, const char *)
Definition: stralloc.c:36
int stralloc_readyplus(stralloc *sa, size_t len)
Definition: stralloc.c:61
int stralloc_copys(stralloc *, const char *)
Definition: stralloc.c:79