Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
package packetv3
import (
"bytes"
"fmt"
"github.com/bio-routing/bio-rd/net"
"github.com/bio-routing/bio-rd/util/decode"
"github.com/bio-routing/tflow2/convert"
"github.com/pkg/errors"
)
// Prefix Option Bits
const (
NUBIT = 1
LABIT = 2
PBIT = 8
DNBIT = 16
)
type PrefixOptions struct {
NoUnicast bool // NU-bit
LocalAddress bool // LA-bit
Propagate bool // P-bit
DN bool // DN-bit
}
func (o PrefixOptions) Serialize(buf *bytes.Buffer) {
var rawOptions uint8
if o.NoUnicast {
rawOptions = rawOptions | NUBIT
}
if o.LocalAddress {
rawOptions = rawOptions | LABIT
}
if o.Propagate {
rawOptions = rawOptions | PBIT
}
if o.DN {
rawOptions = rawOptions | DNBIT
}
buf.WriteByte(rawOptions)
}
type LSAPrefix struct {
PrefixLength uint8
Options PrefixOptions
// this may represent different things
// used for metric or referenced LSType
Special uint16
Address net.IP
}
func DeserializeLSAPrefix(buf *bytes.Buffer) (LSAPrefix, int, error) {
pdu := LSAPrefix{}
var readBytes int
var err error
var rawOptions uint8
fields := []interface{}{
&pdu.PrefixLength,
&rawOptions,
&pdu.Special,
}
err = decode.Decode(buf, fields)
if err != nil {
return pdu, readBytes, fmt.Errorf("Unable to decode fields: %v", err)
}
readBytes += 4
// read Options
pdu.Options.NoUnicast = (rawOptions & NUBIT) != 0
pdu.Options.LocalAddress = (rawOptions & LABIT) != 0
pdu.Options.Propagate = (rawOptions & PBIT) != 0
pdu.Options.DN = (rawOptions & DNBIT) != 0
// read AddressPrefix
numBytes := int((pdu.PrefixLength+31)/32) * 4
pfxBytes := buf.Next(numBytes)
ipBytes := make([]byte, 16)
copy(ipBytes[:len(pfxBytes)], pfxBytes)
addr, err := net.IPFromBytes(ipBytes)
if err != nil {
return pdu, readBytes, errors.Wrap(err, "unable to decode AddressPrefix")
}
pdu.Address = *addr
readBytes += len(pfxBytes)
return pdu, readBytes, nil
}
func (x *LSAPrefix) Serialize(buf *bytes.Buffer) {
buf.WriteByte(x.PrefixLength)
x.Options.Serialize(buf)
buf.Write(convert.Uint16Byte(x.Special))
// serialize AddressPrefix
numBytes := int((x.PrefixLength+31)/32) * 4
buf.Write(x.Address.Bytes()[:numBytes])
}