1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
#include <stdlib.h>
#include <arpa/inet.h>
#include <errno.h>
static unsigned int scan_ip6(const char *s,char ip[16])
{
unsigned int i;
unsigned int len=0;
unsigned long u;
char suffix[16];
int prefixlen=0;
int suffixlen=0;
for (i=0; i<16; i++) ip[i]=0;
for (;;) {
if (*s == ':') {
len++;
if (s[1] == ':') { /* Found "::", skip to part 2 */
s+=2;
len++;
break;
}
s++;
}
{
char *tmp;
u=strtol(s,&tmp,16);
i=tmp-s;
}
if (!i) return 0;
if (prefixlen==12 && s[i]=='.') {
/* the last 4 bytes may be written as IPv4 address */
if (inet_aton(s,(struct in_addr*)(ip+12)))
return i+len;
else
return 0;
}
ip[prefixlen++] = (u >> 8);
ip[prefixlen++] = (u & 255);
s += i; len += i;
if (prefixlen==16)
return len;
}
/* part 2, after "::" */
for (;;) {
if (*s == ':') {
if (suffixlen==0)
break;
s++;
len++;
} else if (suffixlen!=0)
break;
{
char *tmp;
u=strtol(s,&tmp,16);
i=tmp-s;
}
if (!i) {
len--;
break;
}
if (suffixlen+prefixlen<=12 && s[i]=='.') {
if (inet_aton(s,(struct in_addr*)(suffix+suffixlen))) {
suffixlen+=4;
len+=strlen(s);
break;
} else
prefixlen=12-suffixlen; /* make end-of-loop test true */
}
suffix[suffixlen++] = (u >> 8);
suffix[suffixlen++] = (u & 255);
s += i; len += i;
if (prefixlen+suffixlen==16)
break;
}
for (i=0; i<suffixlen; i++)
ip[16-suffixlen+i] = suffix[i];
return len;
}
int inet_pton(int AF, const char *CP, void *BUF) {
if (AF==AF_INET) {
if (!inet_aton(CP,(struct in_addr*)BUF))
return 0;
} else if (AF==AF_INET6) {
if (CP[scan_ip6(CP,BUF)])
return 0;
} else {
errno=EAFNOSUPPORT;
return -1;
}
return 1;
}
|