diff options
Diffstat (limited to '')
-rw-r--r-- | win32/inet_pton.c | 95 |
1 files changed, 95 insertions, 0 deletions
diff --git a/win32/inet_pton.c b/win32/inet_pton.c new file mode 100644 index 000000000..f229a9355 --- /dev/null +++ b/win32/inet_pton.c | |||
@@ -0,0 +1,95 @@ | |||
1 | /* | ||
2 | inet_pton from musl (https://www.musl-libc.org/). | ||
3 | |||
4 | MIT licensed: | ||
5 | |||
6 | ---------------------------------------------------------------------- | ||
7 | Copyright © 2005-2020 Rich Felker, et al. | ||
8 | |||
9 | Permission is hereby granted, free of charge, to any person obtaining | ||
10 | a copy of this software and associated documentation files (the | ||
11 | "Software"), to deal in the Software without restriction, including | ||
12 | without limitation the rights to use, copy, modify, merge, publish, | ||
13 | distribute, sublicense, and/or sell copies of the Software, and to | ||
14 | permit persons to whom the Software is furnished to do so, subject to | ||
15 | the following conditions: | ||
16 | |||
17 | The above copyright notice and this permission notice shall be | ||
18 | included in all copies or substantial portions of the Software. | ||
19 | |||
20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | ||
21 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | ||
22 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. | ||
23 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY | ||
24 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, | ||
25 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE | ||
26 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. | ||
27 | ---------------------------------------------------------------------- | ||
28 | */ | ||
29 | #include "libbb.h" | ||
30 | |||
31 | static int hexval(unsigned c) | ||
32 | { | ||
33 | if (c-'0'<10) return c-'0'; | ||
34 | c |= 32; | ||
35 | if (c-'a'<6) return c-'a'+10; | ||
36 | return -1; | ||
37 | } | ||
38 | |||
39 | int inet_pton(int af, const char *restrict s, void *restrict a0) | ||
40 | { | ||
41 | uint16_t ip[8]; | ||
42 | unsigned char *a = a0; | ||
43 | int i, j, v, d, brk=-1, need_v4=0; | ||
44 | |||
45 | if (af==AF_INET) { | ||
46 | for (i=0; i<4; i++) { | ||
47 | for (v=j=0; j<3 && isdigit(s[j]); j++) | ||
48 | v = 10*v + s[j]-'0'; | ||
49 | if (j==0 || (j>1 && s[0]=='0') || v>255) return 0; | ||
50 | a[i] = v; | ||
51 | if (s[j]==0 && i==3) return 1; | ||
52 | if (s[j]!='.') return 0; | ||
53 | s += j+1; | ||
54 | } | ||
55 | return 0; | ||
56 | } else if (af!=AF_INET6) { | ||
57 | errno = EAFNOSUPPORT; | ||
58 | return -1; | ||
59 | } | ||
60 | |||
61 | if (*s==':' && *++s!=':') return 0; | ||
62 | |||
63 | for (i=0; ; i++) { | ||
64 | if (s[0]==':' && brk<0) { | ||
65 | brk=i; | ||
66 | ip[i&7]=0; | ||
67 | if (!*++s) break; | ||
68 | if (i==7) return 0; | ||
69 | continue; | ||
70 | } | ||
71 | for (v=j=0; j<4 && (d=hexval(s[j]))>=0; j++) | ||
72 | v=16*v+d; | ||
73 | if (j==0) return 0; | ||
74 | ip[i&7] = v; | ||
75 | if (!s[j] && (brk>=0 || i==7)) break; | ||
76 | if (i==7) return 0; | ||
77 | if (s[j]!=':') { | ||
78 | if (s[j]!='.' || (i<6 && brk<0)) return 0; | ||
79 | need_v4=1; | ||
80 | i++; | ||
81 | break; | ||
82 | } | ||
83 | s += j+1; | ||
84 | } | ||
85 | if (brk>=0) { | ||
86 | memmove(ip+brk+7-i, ip+brk, 2*(i+1-brk)); | ||
87 | for (j=0; j<7-i; j++) ip[brk+j] = 0; | ||
88 | } | ||
89 | for (j=0; j<8; j++) { | ||
90 | *a++ = ip[j]>>8; | ||
91 | *a++ = ip[j]; | ||
92 | } | ||
93 | if (need_v4 && inet_pton(AF_INET, (void *)s, a-4) <= 0) return 0; | ||
94 | return 1; | ||
95 | } | ||