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