@@ -5,14 +5,29 @@ import (
55 "encoding/binary"
66 "fmt"
77
8+ "github.com/bio-routing/bio-rd/util/checksum"
89 "github.com/bio-routing/bio-rd/util/decode"
910 "github.com/bio-routing/tflow2/convert"
1011 "github.com/pkg/errors"
1112)
1213
14+ const expectedVersion = 3
15+
16+ type OSPFMessageType uint8
17+
18+ // OSPF message types
19+ const (
20+ MsgTypeUnknown OSPFMessageType = iota
21+ MsgTypeHello
22+ MsgTypeDatabaseDescription
23+ MsgTypeLinkStateRequest
24+ MsgTypeLinkStateUpdate
25+ MsgTypeLinkStateAcknowledgment
26+ )
27+
1328type OSPFv3Message struct {
1429 Version uint8
15- Type uint8
30+ Type OSPFMessageType
1631 PacketLength uint16
1732 RouterID ID
1833 AreaID ID
@@ -22,21 +37,40 @@ type OSPFv3Message struct {
2237}
2338
2439const OSPFv3MessageHeaderLength = 16
40+ const OSPFv3MessagePacketLengthAtByte = 2
41+ const OSPFv3MessageChecksumAtByte = 12
42+
43+ func (x * OSPFv3Message ) Serialize (out * bytes.Buffer ) {
44+ buf := bytes .NewBuffer (nil )
2545
26- func (x * OSPFv3Message ) Serialize (buf * bytes.Buffer ) {
2746 buf .WriteByte (x .Version )
28- buf .WriteByte (x .Type )
47+ buf .WriteByte (uint8 ( x .Type ) )
2948 buf .Write (convert .Uint16Byte (x .PacketLength ))
3049 x .RouterID .Serialize (buf )
3150 x .AreaID .Serialize (buf )
3251 buf .Write (convert .Uint16Byte (x .Checksum ))
3352 buf .WriteByte (x .InstanceID )
3453 buf .WriteByte (0 ) // 1 byte reserved
3554 x .Body .Serialize (buf )
55+
56+ data := buf .Bytes ()
57+
58+ length := uint16 (len (data ))
59+ putUint16 (data , OSPFv3MessagePacketLengthAtByte , length )
60+
61+ checksum := checksum .IPChecksum (data , OSPFv3MessageChecksumAtByte )
62+ putUint16 (data , OSPFv3MessageChecksumAtByte , checksum )
63+
64+ out .Write (data )
65+ }
66+
67+ func putUint16 (b []byte , p int , v uint16 ) {
68+ binary .BigEndian .PutUint16 (b [p :p + 2 ], v )
3669}
3770
3871func DeserializeOSPFv3Message (buf * bytes.Buffer ) (* OSPFv3Message , int , error ) {
3972 pdu := & OSPFv3Message {}
73+ data := buf .Bytes ()
4074
4175 var readBytes int
4276 var err error
@@ -59,6 +93,15 @@ func DeserializeOSPFv3Message(buf *bytes.Buffer) (*OSPFv3Message, int, error) {
5993 }
6094 readBytes += 16
6195
96+ if pdu .Version != expectedVersion {
97+ return nil , readBytes , fmt .Errorf ("Invalid OSPF version: %d" , pdu .Version )
98+ }
99+
100+ expectedChecksum := checksum .IPChecksum (data , OSPFv3MessageChecksumAtByte )
101+ if pdu .Checksum != expectedChecksum {
102+ return nil , readBytes , fmt .Errorf ("Checksum mismatch. Expected %#04x, got %#04x" , expectedChecksum , pdu .Checksum )
103+ }
104+
62105 n , err := pdu .ReadBody (buf )
63106 if err != nil {
64107 return nil , readBytes , errors .Wrap (err , "unable to decode message body" )
@@ -75,15 +118,15 @@ func (m *OSPFv3Message) ReadBody(buf *bytes.Buffer) (int, error) {
75118 var err error
76119
77120 switch m .Type {
78- case 1 :
121+ case MsgTypeHello :
79122 body , readBytes , err = DeserializeHello (buf , bodyLength )
80- case 2 :
123+ case MsgTypeDatabaseDescription :
81124 body , readBytes , err = DeserializeDatabaseDescription (buf , bodyLength )
82- case 3 :
125+ case MsgTypeLinkStateRequest :
83126 body , readBytes , err = DeserializeLinkStateRequestMsg (buf , bodyLength )
84- case 4 :
127+ case MsgTypeLinkStateUpdate :
85128 body , readBytes , err = DeserializeLinkStateUpdate (buf )
86- case 5 :
129+ case MsgTypeLinkStateAcknowledgment :
87130 body , readBytes , err = DeserializeLinkStateAcknowledgement (buf , bodyLength )
88131 default :
89132 return 0 , fmt .Errorf ("unknown message type: %d" , m .Type )
@@ -157,10 +200,19 @@ func DeserializeHello(buf *bytes.Buffer, bodyLength uint16) (*Hello, int, error)
157200 return pdu , readBytes , nil
158201}
159202
203+ type DBFlags uint8
204+
205+ // database description flags
206+ const (
207+ DBFlagInit DBFlags = 1 << iota
208+ DBFlagMore
209+ DBFlagMS
210+ )
211+
160212type DatabaseDescription struct {
161213 Options RouterOptions
162214 InterfaceMTU uint16
163- DBFlags uint8
215+ DBFlags DBFlags
164216 DDSequenceNumber uint32
165217 LSAHeaders []* LSA
166218}
@@ -170,7 +222,7 @@ func (x *DatabaseDescription) Serialize(buf *bytes.Buffer) {
170222 x .Options .Serialize (buf )
171223 buf .Write (convert .Uint16Byte (x .InterfaceMTU ))
172224 buf .WriteByte (0 ) // 1 byte reserved
173- buf .WriteByte (x .DBFlags )
225+ buf .WriteByte (uint8 ( x .DBFlags ) )
174226 buf .Write (convert .Uint32Byte (x .DDSequenceNumber ))
175227 for i := range x .LSAHeaders {
176228 x .LSAHeaders [i ].Serialize (buf , true )
0 commit comments