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