1package nl
2
3import (
4	"unsafe"
5
6	"golang.org/x/sys/unix"
7)
8
9type RtMsg struct {
10	unix.RtMsg
11}
12
13func NewRtMsg() *RtMsg {
14	return &RtMsg{
15		RtMsg: unix.RtMsg{
16			Table:    unix.RT_TABLE_MAIN,
17			Scope:    unix.RT_SCOPE_UNIVERSE,
18			Protocol: unix.RTPROT_BOOT,
19			Type:     unix.RTN_UNICAST,
20		},
21	}
22}
23
24func NewRtDelMsg() *RtMsg {
25	return &RtMsg{
26		RtMsg: unix.RtMsg{
27			Table: unix.RT_TABLE_MAIN,
28			Scope: unix.RT_SCOPE_NOWHERE,
29		},
30	}
31}
32
33func (msg *RtMsg) Len() int {
34	return unix.SizeofRtMsg
35}
36
37func DeserializeRtMsg(b []byte) *RtMsg {
38	return (*RtMsg)(unsafe.Pointer(&b[0:unix.SizeofRtMsg][0]))
39}
40
41func (msg *RtMsg) Serialize() []byte {
42	return (*(*[unix.SizeofRtMsg]byte)(unsafe.Pointer(msg)))[:]
43}
44
45type RtNexthop struct {
46	unix.RtNexthop
47	Children []NetlinkRequestData
48}
49
50func DeserializeRtNexthop(b []byte) *RtNexthop {
51	return (*RtNexthop)(unsafe.Pointer(&b[0:unix.SizeofRtNexthop][0]))
52}
53
54func (msg *RtNexthop) Len() int {
55	if len(msg.Children) == 0 {
56		return unix.SizeofRtNexthop
57	}
58
59	l := 0
60	for _, child := range msg.Children {
61		l += rtaAlignOf(child.Len())
62	}
63	l += unix.SizeofRtNexthop
64	return rtaAlignOf(l)
65}
66
67func (msg *RtNexthop) Serialize() []byte {
68	length := msg.Len()
69	msg.RtNexthop.Len = uint16(length)
70	buf := make([]byte, length)
71	copy(buf, (*(*[unix.SizeofRtNexthop]byte)(unsafe.Pointer(msg)))[:])
72	next := rtaAlignOf(unix.SizeofRtNexthop)
73	if len(msg.Children) > 0 {
74		for _, child := range msg.Children {
75			childBuf := child.Serialize()
76			copy(buf[next:], childBuf)
77			next += rtaAlignOf(len(childBuf))
78		}
79	}
80	return buf
81}
82