1
2
3
4
5
6
7 package route
8
9 import (
10 "runtime"
11 "syscall"
12 )
13
14 func (m *RouteMessage) marshal() ([]byte, error) {
15 w, ok := wireFormats[m.Type]
16 if !ok {
17 return nil, errUnsupportedMessage
18 }
19 l := w.bodyOff + addrsSpace(m.Addrs)
20 if runtime.GOOS == "darwin" || runtime.GOOS == "ios" {
21
22
23 l += 1024
24 }
25 b := make([]byte, l)
26 nativeEndian.PutUint16(b[:2], uint16(l))
27 if m.Version == 0 {
28 b[2] = rtmVersion
29 } else {
30 b[2] = byte(m.Version)
31 }
32 b[3] = byte(m.Type)
33 nativeEndian.PutUint32(b[8:12], uint32(m.Flags))
34 nativeEndian.PutUint16(b[4:6], uint16(m.Index))
35 nativeEndian.PutUint32(b[16:20], uint32(m.ID))
36 nativeEndian.PutUint32(b[20:24], uint32(m.Seq))
37 attrs, err := marshalAddrs(b[w.bodyOff:], m.Addrs)
38 if err != nil {
39 return nil, err
40 }
41 if attrs > 0 {
42 nativeEndian.PutUint32(b[12:16], uint32(attrs))
43 }
44 return b, nil
45 }
46
47 func (w *wireFormat) parseRouteMessage(typ RIBType, b []byte) (Message, error) {
48 if len(b) < w.bodyOff {
49 return nil, errMessageTooShort
50 }
51 l := int(nativeEndian.Uint16(b[:2]))
52 if len(b) < l {
53 return nil, errInvalidMessage
54 }
55 m := &RouteMessage{
56 Version: int(b[2]),
57 Type: int(b[3]),
58 Flags: int(nativeEndian.Uint32(b[8:12])),
59 Index: int(nativeEndian.Uint16(b[4:6])),
60 ID: uintptr(nativeEndian.Uint32(b[16:20])),
61 Seq: int(nativeEndian.Uint32(b[20:24])),
62 extOff: w.extOff,
63 raw: b[:l],
64 }
65 errno := syscall.Errno(nativeEndian.Uint32(b[28:32]))
66 if errno != 0 {
67 m.Err = errno
68 }
69 var err error
70 m.Addrs, err = parseAddrs(uint(nativeEndian.Uint32(b[12:16])), parseKernelInetAddr, b[w.bodyOff:])
71 if err != nil {
72 return nil, err
73 }
74 return m, nil
75 }
76
View as plain text