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