Source file src/vendor/golang.org/x/net/route/address.go
1
2
3
4
5
6
7 package route
8
9 import "runtime"
10
11
12 type Addr interface {
13
14 Family() int
15 }
16
17
18 type LinkAddr struct {
19 Index int
20 Name string
21 Addr []byte
22 }
23
24
25 func (a *LinkAddr) Family() int { return sysAF_LINK }
26
27 func (a *LinkAddr) lenAndSpace() (int, int) {
28 l := 8 + len(a.Name) + len(a.Addr)
29 return l, roundup(l)
30 }
31
32 func (a *LinkAddr) marshal(b []byte) (int, error) {
33 l, ll := a.lenAndSpace()
34 if len(b) < ll {
35 return 0, errShortBuffer
36 }
37 nlen, alen := len(a.Name), len(a.Addr)
38 if nlen > 255 || alen > 255 {
39 return 0, errInvalidAddr
40 }
41 b[0] = byte(l)
42 b[1] = sysAF_LINK
43 if a.Index > 0 {
44 nativeEndian.PutUint16(b[2:4], uint16(a.Index))
45 }
46 data := b[8:]
47 if nlen > 0 {
48 b[5] = byte(nlen)
49 copy(data[:nlen], a.Addr)
50 data = data[nlen:]
51 }
52 if alen > 0 {
53 b[6] = byte(alen)
54 copy(data[:alen], a.Name)
55 data = data[alen:]
56 }
57 return ll, nil
58 }
59
60 func parseLinkAddr(b []byte) (Addr, error) {
61 if len(b) < 8 {
62 return nil, errInvalidAddr
63 }
64 _, a, err := parseKernelLinkAddr(sysAF_LINK, b[4:])
65 if err != nil {
66 return nil, err
67 }
68 a.(*LinkAddr).Index = int(nativeEndian.Uint16(b[2:4]))
69 return a, nil
70 }
71
72
73
74 func parseKernelLinkAddr(_ int, b []byte) (int, Addr, error) {
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90 nlen, alen, slen := int(b[1]), int(b[2]), int(b[3])
91 if nlen == 0xff {
92 nlen = 0
93 }
94 if alen == 0xff {
95 alen = 0
96 }
97 if slen == 0xff {
98 slen = 0
99 }
100 l := 4 + nlen + alen + slen
101 if len(b) < l {
102 return 0, nil, errInvalidAddr
103 }
104 data := b[4:]
105 var name string
106 var addr []byte
107 if nlen > 0 {
108 name = string(data[:nlen])
109 data = data[nlen:]
110 }
111 if alen > 0 {
112 addr = data[:alen]
113 data = data[alen:]
114 }
115 return l, &LinkAddr{Name: name, Addr: addr}, nil
116 }
117
118
119 type Inet4Addr struct {
120 IP [4]byte
121 }
122
123
124 func (a *Inet4Addr) Family() int { return sysAF_INET }
125
126 func (a *Inet4Addr) lenAndSpace() (int, int) {
127 return sizeofSockaddrInet, roundup(sizeofSockaddrInet)
128 }
129
130 func (a *Inet4Addr) marshal(b []byte) (int, error) {
131 l, ll := a.lenAndSpace()
132 if len(b) < ll {
133 return 0, errShortBuffer
134 }
135 b[0] = byte(l)
136 b[1] = sysAF_INET
137 copy(b[4:8], a.IP[:])
138 return ll, nil
139 }
140
141
142 type Inet6Addr struct {
143 IP [16]byte
144 ZoneID int
145 }
146
147
148 func (a *Inet6Addr) Family() int { return sysAF_INET6 }
149
150 func (a *Inet6Addr) lenAndSpace() (int, int) {
151 return sizeofSockaddrInet6, roundup(sizeofSockaddrInet6)
152 }
153
154 func (a *Inet6Addr) marshal(b []byte) (int, error) {
155 l, ll := a.lenAndSpace()
156 if len(b) < ll {
157 return 0, errShortBuffer
158 }
159 b[0] = byte(l)
160 b[1] = sysAF_INET6
161 copy(b[8:24], a.IP[:])
162 if a.ZoneID > 0 {
163 nativeEndian.PutUint32(b[24:28], uint32(a.ZoneID))
164 }
165 return ll, nil
166 }
167
168
169 func parseInetAddr(af int, b []byte) (Addr, error) {
170 switch af {
171 case sysAF_INET:
172 if len(b) < sizeofSockaddrInet {
173 return nil, errInvalidAddr
174 }
175 a := &Inet4Addr{}
176 copy(a.IP[:], b[4:8])
177 return a, nil
178 case sysAF_INET6:
179 if len(b) < sizeofSockaddrInet6 {
180 return nil, errInvalidAddr
181 }
182 a := &Inet6Addr{ZoneID: int(nativeEndian.Uint32(b[24:28]))}
183 copy(a.IP[:], b[8:24])
184 if a.IP[0] == 0xfe && a.IP[1]&0xc0 == 0x80 || a.IP[0] == 0xff && (a.IP[1]&0x0f == 0x01 || a.IP[1]&0x0f == 0x02) {
185
186
187
188
189 id := int(bigEndian.Uint16(a.IP[2:4]))
190 if id != 0 {
191 a.ZoneID = id
192 a.IP[2], a.IP[3] = 0, 0
193 }
194 }
195 return a, nil
196 default:
197 return nil, errInvalidAddr
198 }
199 }
200
201
202
203 func parseKernelInetAddr(af int, b []byte) (int, Addr, error) {
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223 l := int(b[0])
224 if runtime.GOOS == "darwin" {
225
226
227 if l == 0 || len(b) > roundup(l) {
228 l = roundup(l)
229 }
230 } else {
231 l = roundup(l)
232 }
233 if len(b) < l {
234 return 0, nil, errInvalidAddr
235 }
236
237
238 const (
239 off4 = 4
240 off6 = 8
241 )
242 switch {
243 case b[0] == sizeofSockaddrInet6:
244 a := &Inet6Addr{}
245 copy(a.IP[:], b[off6:off6+16])
246 return int(b[0]), a, nil
247 case af == sysAF_INET6:
248 a := &Inet6Addr{}
249 if l-1 < off6 {
250 copy(a.IP[:], b[1:l])
251 } else {
252 copy(a.IP[:], b[l-off6:l])
253 }
254 return int(b[0]), a, nil
255 case b[0] == sizeofSockaddrInet:
256 a := &Inet4Addr{}
257 copy(a.IP[:], b[off4:off4+4])
258 return int(b[0]), a, nil
259 default:
260 a := &Inet4Addr{}
261 if l-1 < off4 {
262 copy(a.IP[:], b[1:l])
263 } else {
264 copy(a.IP[:], b[l-off4:l])
265 }
266 return int(b[0]), a, nil
267 }
268 }
269
270
271
272 type DefaultAddr struct {
273 af int
274 Raw []byte
275 }
276
277
278 func (a *DefaultAddr) Family() int { return a.af }
279
280 func (a *DefaultAddr) lenAndSpace() (int, int) {
281 l := len(a.Raw)
282 return l, roundup(l)
283 }
284
285 func (a *DefaultAddr) marshal(b []byte) (int, error) {
286 l, ll := a.lenAndSpace()
287 if len(b) < ll {
288 return 0, errShortBuffer
289 }
290 if l > 255 {
291 return 0, errInvalidAddr
292 }
293 b[1] = byte(l)
294 copy(b[:l], a.Raw)
295 return ll, nil
296 }
297
298 func parseDefaultAddr(b []byte) (Addr, error) {
299 if len(b) < 2 || len(b) < int(b[0]) {
300 return nil, errInvalidAddr
301 }
302 a := &DefaultAddr{af: int(b[1]), Raw: b[:b[0]]}
303 return a, nil
304 }
305
306 func addrsSpace(as []Addr) int {
307 var l int
308 for _, a := range as {
309 switch a := a.(type) {
310 case *LinkAddr:
311 _, ll := a.lenAndSpace()
312 l += ll
313 case *Inet4Addr:
314 _, ll := a.lenAndSpace()
315 l += ll
316 case *Inet6Addr:
317 _, ll := a.lenAndSpace()
318 l += ll
319 case *DefaultAddr:
320 _, ll := a.lenAndSpace()
321 l += ll
322 }
323 }
324 return l
325 }
326
327
328
329 func marshalAddrs(b []byte, as []Addr) (uint, error) {
330 var attrs uint
331 for i, a := range as {
332 switch a := a.(type) {
333 case *LinkAddr:
334 l, err := a.marshal(b)
335 if err != nil {
336 return 0, err
337 }
338 b = b[l:]
339 attrs |= 1 << uint(i)
340 case *Inet4Addr:
341 l, err := a.marshal(b)
342 if err != nil {
343 return 0, err
344 }
345 b = b[l:]
346 attrs |= 1 << uint(i)
347 case *Inet6Addr:
348 l, err := a.marshal(b)
349 if err != nil {
350 return 0, err
351 }
352 b = b[l:]
353 attrs |= 1 << uint(i)
354 case *DefaultAddr:
355 l, err := a.marshal(b)
356 if err != nil {
357 return 0, err
358 }
359 b = b[l:]
360 attrs |= 1 << uint(i)
361 }
362 }
363 return attrs, nil
364 }
365
366 func parseAddrs(attrs uint, fn func(int, []byte) (int, Addr, error), b []byte) ([]Addr, error) {
367 var as [sysRTAX_MAX]Addr
368 af := int(sysAF_UNSPEC)
369 for i := uint(0); i < sysRTAX_MAX && len(b) >= roundup(0); i++ {
370 if attrs&(1<<i) == 0 {
371 continue
372 }
373 if i <= sysRTAX_BRD {
374 switch b[1] {
375 case sysAF_LINK:
376 a, err := parseLinkAddr(b)
377 if err != nil {
378 return nil, err
379 }
380 as[i] = a
381 l := roundup(int(b[0]))
382 if len(b) < l {
383 return nil, errMessageTooShort
384 }
385 b = b[l:]
386 case sysAF_INET, sysAF_INET6:
387 af = int(b[1])
388 a, err := parseInetAddr(af, b)
389 if err != nil {
390 return nil, err
391 }
392 as[i] = a
393 l := roundup(int(b[0]))
394 if len(b) < l {
395 return nil, errMessageTooShort
396 }
397 b = b[l:]
398 default:
399 l, a, err := fn(af, b)
400 if err != nil {
401 return nil, err
402 }
403 as[i] = a
404 ll := roundup(l)
405 if len(b) < ll {
406 b = b[l:]
407 } else {
408 b = b[ll:]
409 }
410 }
411 } else {
412 a, err := parseDefaultAddr(b)
413 if err != nil {
414 return nil, err
415 }
416 as[i] = a
417 l := roundup(int(b[0]))
418 if len(b) < l {
419 return nil, errMessageTooShort
420 }
421 b = b[l:]
422 }
423 }
424 return as[:], nil
425 }
426
View as plain text