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