...
1
2
3
4
5
6
7
8
9
10
11
12
13 package net
14
15
16
17
18
19
20
21
22
23 import (
24 stdnet "net"
25 )
26
27
28
29
30
31 type IP = stdnet.IP
32 type IPNet = stdnet.IPNet
33 type ParseError = stdnet.ParseError
34
35 const IPv4len = stdnet.IPv4len
36 const IPv6len = stdnet.IPv6len
37
38 var CIDRMask = stdnet.CIDRMask
39 var IPv4 = stdnet.IPv4
40
41
42 func parseIPv4(s string) IP {
43 var p [IPv4len]byte
44 for i := 0; i < IPv4len; i++ {
45 if len(s) == 0 {
46
47 return nil
48 }
49 if i > 0 {
50 if s[0] != '.' {
51 return nil
52 }
53 s = s[1:]
54 }
55 n, c, ok := dtoi(s)
56 if !ok || n > 0xFF {
57 return nil
58 }
59
60
61
62
63
64
65
66
67
68
69
70 s = s[c:]
71 p[i] = byte(n)
72 }
73 if len(s) != 0 {
74 return nil
75 }
76 return IPv4(p[0], p[1], p[2], p[3])
77 }
78
79
80
81 func parseIPv6(s string) (ip IP) {
82 ip = make(IP, IPv6len)
83 ellipsis := -1
84
85
86 if len(s) >= 2 && s[0] == ':' && s[1] == ':' {
87 ellipsis = 0
88 s = s[2:]
89
90 if len(s) == 0 {
91 return ip
92 }
93 }
94
95
96 i := 0
97 for i < IPv6len {
98
99 n, c, ok := xtoi(s)
100 if !ok || n > 0xFFFF {
101 return nil
102 }
103
104
105 if c < len(s) && s[c] == '.' {
106 if ellipsis < 0 && i != IPv6len-IPv4len {
107
108 return nil
109 }
110 if i+IPv4len > IPv6len {
111
112 return nil
113 }
114 ip4 := parseIPv4(s)
115 if ip4 == nil {
116 return nil
117 }
118 ip[i] = ip4[12]
119 ip[i+1] = ip4[13]
120 ip[i+2] = ip4[14]
121 ip[i+3] = ip4[15]
122 s = ""
123 i += IPv4len
124 break
125 }
126
127
128 ip[i] = byte(n >> 8)
129 ip[i+1] = byte(n)
130 i += 2
131
132
133 s = s[c:]
134 if len(s) == 0 {
135 break
136 }
137
138
139 if s[0] != ':' || len(s) == 1 {
140 return nil
141 }
142 s = s[1:]
143
144
145 if s[0] == ':' {
146 if ellipsis >= 0 {
147 return nil
148 }
149 ellipsis = i
150 s = s[1:]
151 if len(s) == 0 {
152 break
153 }
154 }
155 }
156
157
158 if len(s) != 0 {
159 return nil
160 }
161
162
163 if i < IPv6len {
164 if ellipsis < 0 {
165 return nil
166 }
167 n := IPv6len - i
168 for j := i - 1; j >= ellipsis; j-- {
169 ip[j+n] = ip[j]
170 }
171 for j := ellipsis + n - 1; j >= ellipsis; j-- {
172 ip[j] = 0
173 }
174 } else if ellipsis >= 0 {
175
176 return nil
177 }
178 return ip
179 }
180
181
182
183
184
185
186 func ParseIP(s string) IP {
187 for i := 0; i < len(s); i++ {
188 switch s[i] {
189 case '.':
190 return parseIPv4(s)
191 case ':':
192 return parseIPv6(s)
193 }
194 }
195 return nil
196 }
197
198
199
200
201
202
203
204
205
206 func ParseCIDR(s string) (IP, *IPNet, error) {
207 i := indexByteString(s, '/')
208 if i < 0 {
209 return nil, nil, &ParseError{Type: "CIDR address", Text: s}
210 }
211 addr, mask := s[:i], s[i+1:]
212 iplen := IPv4len
213 ip := parseIPv4(addr)
214 if ip == nil {
215 iplen = IPv6len
216 ip = parseIPv6(addr)
217 }
218 n, i, ok := dtoi(mask)
219 if ip == nil || !ok || i != len(mask) || n < 0 || n > 8*iplen {
220 return nil, nil, &ParseError{Type: "CIDR address", Text: s}
221 }
222 m := CIDRMask(n, 8*iplen)
223 return ip, &IPNet{IP: ip.Mask(m), Mask: m}, nil
224 }
225
226
227
228
229 func indexByteString(s string, c byte) int {
230 for i := 0; i < len(s); i++ {
231 if s[i] == c {
232 return i
233 }
234 }
235 return -1
236 }
237
View as plain text