1 package nl
2
3 import (
4 "bytes"
5 "crypto/rand"
6 "encoding/binary"
7 "reflect"
8 "testing"
9 "time"
10
11 "golang.org/x/sys/unix"
12 )
13
14 type testSerializer interface {
15 serializeSafe() []byte
16 Serialize() []byte
17 }
18
19 func testDeserializeSerialize(t *testing.T, orig []byte, safemsg testSerializer, msg testSerializer) {
20 if !reflect.DeepEqual(safemsg, msg) {
21 t.Fatal("Deserialization failed.\n", safemsg, "\n", msg)
22 }
23 safe := msg.serializeSafe()
24 if !bytes.Equal(safe, orig) {
25 t.Fatal("Safe serialization failed.\n", safe, "\n", orig)
26 }
27 b := msg.Serialize()
28 if !bytes.Equal(b, safe) {
29 t.Fatal("Serialization failed.\n", b, "\n", safe)
30 }
31 }
32
33 func (msg *IfInfomsg) write(b []byte) {
34 native := NativeEndian()
35 b[0] = msg.Family
36
37 native.PutUint16(b[2:4], msg.Type)
38 native.PutUint32(b[4:8], uint32(msg.Index))
39 native.PutUint32(b[8:12], msg.Flags)
40 native.PutUint32(b[12:16], msg.Change)
41 }
42
43 func (msg *IfInfomsg) serializeSafe() []byte {
44 length := unix.SizeofIfInfomsg
45 b := make([]byte, length)
46 msg.write(b)
47 return b
48 }
49
50 func deserializeIfInfomsgSafe(b []byte) *IfInfomsg {
51 var msg = IfInfomsg{}
52 binary.Read(bytes.NewReader(b[0:unix.SizeofIfInfomsg]), NativeEndian(), &msg)
53 return &msg
54 }
55
56 func TestIfInfomsgDeserializeSerialize(t *testing.T) {
57 var orig = make([]byte, unix.SizeofIfInfomsg)
58 rand.Read(orig)
59
60 orig[1] = 0
61 safemsg := deserializeIfInfomsgSafe(orig)
62 msg := DeserializeIfInfomsg(orig)
63 testDeserializeSerialize(t, orig, safemsg, msg)
64 }
65
66 func TestIfSocketCloses(t *testing.T) {
67 nlSock, err := Subscribe(unix.NETLINK_ROUTE, unix.RTNLGRP_NEIGH)
68 if err != nil {
69 t.Fatalf("Error on creating the socket: %v", err)
70 }
71 endCh := make(chan error)
72 go func(sk *NetlinkSocket, endCh chan error) {
73 endCh <- nil
74 for {
75 _, _, err := sk.Receive()
76 if err == unix.EAGAIN {
77 endCh <- err
78 return
79 }
80 }
81 }(nlSock, endCh)
82
83
84 if msg := <-endCh; msg != nil {
85 t.Fatalf("Expected nil instead got: %v", msg)
86 }
87
88 time.Sleep(4 * time.Second)
89
90
91 nlSock.Close()
92
93
94 msg := <-endCh
95 if msg == nil {
96 t.Fatalf("Expected error instead received nil")
97 }
98 }
99
100 func (msg *CnMsgOp) write(b []byte) {
101 native := NativeEndian()
102 native.PutUint32(b[0:4], msg.ID.Idx)
103 native.PutUint32(b[4:8], msg.ID.Val)
104 native.PutUint32(b[8:12], msg.Seq)
105 native.PutUint32(b[12:16], msg.Ack)
106 native.PutUint16(b[16:18], msg.Length)
107 native.PutUint16(b[18:20], msg.Flags)
108 native.PutUint32(b[20:24], msg.Op)
109 }
110
111 func (msg *CnMsgOp) serializeSafe() []byte {
112 length := msg.Len()
113 b := make([]byte, length)
114 msg.write(b)
115 return b
116 }
117
118 func deserializeCnMsgOpSafe(b []byte) *CnMsgOp {
119 var msg = CnMsgOp{}
120 binary.Read(bytes.NewReader(b[0:SizeofCnMsgOp]), NativeEndian(), &msg)
121 return &msg
122 }
123
124 func TestCnMsgOpDeserializeSerialize(t *testing.T) {
125 var orig = make([]byte, SizeofCnMsgOp)
126 rand.Read(orig)
127 safemsg := deserializeCnMsgOpSafe(orig)
128 msg := DeserializeCnMsgOp(orig)
129 testDeserializeSerialize(t, orig, safemsg, msg)
130 }
131
132 func TestParseRouteAttrAsMap(t *testing.T) {
133 attr1 := NewRtAttr(0x1, ZeroTerminated("foo"))
134 attr2 := NewRtAttr(0x2, ZeroTerminated("bar"))
135 raw := make([]byte, 0)
136 raw = append(raw, attr1.Serialize()...)
137 raw = append(raw, attr2.Serialize()...)
138 attrs, err := ParseRouteAttrAsMap(raw)
139 if err != nil {
140 t.Errorf("failed to parse route attributes %s", err)
141 }
142
143 attr, ok := attrs[0x1]
144 if !ok || BytesToString(attr.Value) != "foo" {
145 t.Error("missing/incorrect \"foo\" attribute")
146 }
147
148 attr, ok = attrs[0x2]
149 if !ok || BytesToString(attr.Value) != "bar" {
150 t.Error("missing/incorrect \"bar\" attribute")
151 }
152 }
153
View as plain text