From 6d35406579627de234d7fd228c89df746d11dfa7 Mon Sep 17 00:00:00 2001 From: Oliver Herms <oliver.herms@exaring.de> Date: Sat, 6 Oct 2018 21:51:21 +0200 Subject: [PATCH] More tests --- protocols/isis/packet/header_test.go | 46 +++++++ protocols/isis/packet/hello.go | 5 +- protocols/isis/packet/isis_test.go | 156 +++++++++++++++++++--- protocols/isis/packet/tlv.go | 10 +- protocols/isis/packet/tlv_unknown.go | 54 ++++++++ protocols/isis/packet/tlv_unknown_test.go | 85 ++++++++++++ 6 files changed, 326 insertions(+), 30 deletions(-) create mode 100644 protocols/isis/packet/header_test.go create mode 100644 protocols/isis/packet/tlv_unknown.go create mode 100644 protocols/isis/packet/tlv_unknown_test.go diff --git a/protocols/isis/packet/header_test.go b/protocols/isis/packet/header_test.go new file mode 100644 index 00000000..2d39eb68 --- /dev/null +++ b/protocols/isis/packet/header_test.go @@ -0,0 +1,46 @@ +package packet + +import ( + "bytes" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestHeaderEncode(t *testing.T) { + tests := []struct { + name string + input *ISISHeader + expected []byte + }{ + { + name: "Test #1", + input: &ISISHeader{ + ProtoDiscriminator: 0x83, + LengthIndicator: 27, + ProtocolIDExtension: 0, + IDLength: 0, + PDUType: 16, + Version: 1, + MaxAreaAddresses: 0, + }, + expected: []byte{ + 0x83, + 27, + 0, + 0, + 16, + 1, + 0, + 0, + }, + }, + } + + for _, test := range tests { + buf := bytes.NewBuffer(nil) + test.input.Serialize(buf) + res := buf.Bytes() + assert.Equalf(t, test.expected, res, "%s failed", test.name) + } +} diff --git a/protocols/isis/packet/hello.go b/protocols/isis/packet/hello.go index 5d3494a9..d40d4383 100644 --- a/protocols/isis/packet/hello.go +++ b/protocols/isis/packet/hello.go @@ -4,6 +4,7 @@ import ( "bytes" "fmt" + "github.com/bio-routing/bio-rd/protocols/isis/types" "github.com/taktv6/tflow2/convert" ) @@ -19,7 +20,7 @@ type L2Hello struct { type P2PHello struct { CircuitType uint8 - SystemID [6]byte + SystemID types.SystemID HoldingTimer uint16 PDULength uint16 LocalCircuitID uint8 @@ -28,7 +29,7 @@ type P2PHello struct { const ( P2PHelloMinSize = 20 - ISISHeaderSize = 8 + ISISHeaderSize = 8 L2CircuitType = 2 ) diff --git a/protocols/isis/packet/isis_test.go b/protocols/isis/packet/isis_test.go index 2d39eb68..21a9495c 100644 --- a/protocols/isis/packet/isis_test.go +++ b/protocols/isis/packet/isis_test.go @@ -4,43 +4,161 @@ import ( "bytes" "testing" + "github.com/bio-routing/bio-rd/protocols/isis/types" "github.com/stretchr/testify/assert" ) -func TestHeaderEncode(t *testing.T) { +func TestDecode(t *testing.T) { tests := []struct { name string - input *ISISHeader - expected []byte + input []byte + wantFail bool + expected *ISISPacket }{ { - name: "Test #1", - input: &ISISHeader{ - ProtoDiscriminator: 0x83, - LengthIndicator: 27, - ProtocolIDExtension: 0, - IDLength: 0, - PDUType: 16, - Version: 1, - MaxAreaAddresses: 0, + name: "P2P Hello", + input: []byte{ + // LLC + 0xfe, // DSAP + 0xfe, // SSAP + 0x03, // Control Fields + + // Header + 0x83, + 20, + 1, + 0, + 17, // PDU Type P2P Hello + 1, + 0, + 0, + + // P2P Hello + 02, + 0, 0, 0, 0, 0, 2, + 0, 27, + 0, 50, + 1, + + //TLVs + 240, 5, 0x02, 0x00, 0x00, 0x01, 0x4b, + 129, 2, 0xcc, 0x8e, + 132, 4, 192, 168, 1, 0, + 1, 6, 0x05, 0x49, 0x00, 0x01, 0x00, 0x10, + 211, 3, 0, 0, 0, }, - expected: []byte{ + wantFail: false, + expected: &ISISPacket{ + Header: &ISISHeader{ + ProtoDiscriminator: 0x83, + LengthIndicator: 20, + ProtocolIDExtension: 1, + IDLength: 0, + PDUType: 17, + Version: 1, + MaxAreaAddresses: 0, + }, + Body: &P2PHello{ + CircuitType: 2, + SystemID: types.SystemID{0, 0, 0, 0, 0, 2}, + HoldingTimer: 27, + PDULength: 50, + LocalCircuitID: 1, + TLVs: []TLV{ + &P2PAdjacencyStateTLV{ + TLVType: 240, + TLVLength: 5, + AdjacencyState: 2, + ExtendedLocalCircuitID: 0x0000014b, + }, + &ProtocolsSupportedTLV{ + TLVType: 129, + TLVLength: 2, + NerworkLayerProtocolIDs: []uint8{0xcc, 0x8e}, + }, + &IPInterfaceAddressTLV{ + TLVType: 132, + TLVLength: 4, + IPv4Address: 3232235776, + }, + &AreaAddressesTLV{ + TLVType: 1, + TLVLength: 6, + AreaIDs: []types.AreaID{ + { + 0x49, 0x00, 0x01, 0x00, 0x10, + }, + }, + }, + &UnknownTLV{ + TLVType: 211, + TLVLength: 3, + TLVValue: []byte{0, 0, 0}, + }, + }, + }, + }, + }, + { + name: "Incomplete header", + input: []byte{ + // LLC + 0xfe, // DSAP + 0xfe, // SSAP + 0x03, // Control Fields + + // Header 0x83, - 27, + 20, + 1, 0, + }, + wantFail: true, + }, + { + name: "Incomplete P2P Hello", + input: []byte{ + // LLC + 0xfe, // DSAP + 0xfe, // SSAP + 0x03, // Control Fields + + // Header + 0x83, + 20, + 1, 0, - 16, + 17, // PDU Type P2P Hello 1, 0, 0, + + // P2P Hello + 02, + 0, 0, 0, 0, 0, 2, + 0, 27, }, + wantFail: true, }, } for _, test := range tests { - buf := bytes.NewBuffer(nil) - test.input.Serialize(buf) - res := buf.Bytes() - assert.Equalf(t, test.expected, res, "%s failed", test.name) + buf := bytes.NewBuffer(test.input) + pkt, err := Decode(buf) + + if err != nil { + if test.wantFail { + continue + } + t.Errorf("Unexpected failure for test %q: %v", test.name, err) + continue + } + + if test.wantFail { + t.Errorf("Unexpected success for test %q", test.name) + continue + } + + assert.Equalf(t, test.expected, pkt, "Test %q", test.name) } } diff --git a/protocols/isis/packet/tlv.go b/protocols/isis/packet/tlv.go index 4499391d..6a545c48 100644 --- a/protocols/isis/packet/tlv.go +++ b/protocols/isis/packet/tlv.go @@ -3,8 +3,6 @@ package packet import ( "bytes" "fmt" - - log "github.com/sirupsen/logrus" ) // TLV is an interface that all TLVs must fulfill @@ -67,13 +65,7 @@ func readTLVs(buf *bytes.Buffer) ([]TLV, error) { case P2PAdjacencyStateTLVType: tlv, _, err = readP2PAdjacencyStateTLV(buf, tlvType, tlvLength) default: - log.Warningf("Unknown type: %d", tlvType) - nirvana := make([]byte, tlvLength) - _, err = buf.Read(nirvana) - if err != nil { - return nil, fmt.Errorf("Unable to read: %v", err) - } - continue + tlv, err = readUnknownTLV(buf, tlvType, tlvLength) } if err != nil { diff --git a/protocols/isis/packet/tlv_unknown.go b/protocols/isis/packet/tlv_unknown.go new file mode 100644 index 00000000..b89b7f3b --- /dev/null +++ b/protocols/isis/packet/tlv_unknown.go @@ -0,0 +1,54 @@ +package packet + +import ( + "bytes" + "fmt" +) + +// UnknownTLV represents an unknown TLV +type UnknownTLV struct { + TLVType uint8 + TLVLength uint8 + TLVValue []byte +} + +func readUnknownTLV(buf *bytes.Buffer, tlvType uint8, tlvLength uint8) (*UnknownTLV, error) { + pdu := &UnknownTLV{ + TLVType: tlvType, + TLVLength: tlvLength, + TLVValue: make([]byte, tlvLength), + } + + n, err := buf.Read(pdu.TLVValue) + if err != nil { + return nil, fmt.Errorf("Unable to read: %v", err) + } + + if n != int(tlvLength) { + return nil, fmt.Errorf("Read incomplete") + } + + return pdu, nil +} + +// Type gets the type of the TLV +func (u UnknownTLV) Type() uint8 { + return u.TLVType +} + +// Length gets the length of the TLV +func (u UnknownTLV) Length() uint8 { + return u.TLVLength +} + +// Value gets the TLV itself +func (u *UnknownTLV) Value() interface{} { + return u +} + +// Serialize serializes a protocols supported TLV +func (u UnknownTLV) Serialize(buf *bytes.Buffer) { + buf.WriteByte(u.TLVType) + buf.WriteByte(u.TLVLength) + buf.Write(u.TLVValue) +} diff --git a/protocols/isis/packet/tlv_unknown_test.go b/protocols/isis/packet/tlv_unknown_test.go new file mode 100644 index 00000000..5b0f76dc --- /dev/null +++ b/protocols/isis/packet/tlv_unknown_test.go @@ -0,0 +1,85 @@ +package packet + +import ( + "bytes" + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestReadUnknownTLV(t *testing.T) { + tests := []struct { + name string + input []byte + tlvType uint8 + tlvLength uint8 + wantFail bool + expected *UnknownTLV + }{ + { + name: "Full", + input: []byte{1, 1, 1}, + tlvType: 100, + tlvLength: 3, + wantFail: false, + expected: &UnknownTLV{ + TLVType: 100, + TLVLength: 3, + TLVValue: []byte{1, 1, 1}, + }, + }, + { + name: "Incomplete", + input: []byte{1, 1}, + tlvType: 100, + tlvLength: 3, + wantFail: true, + }, + } + + for _, test := range tests { + buf := bytes.NewBuffer(test.input) + tlv, err := readUnknownTLV(buf, test.tlvType, test.tlvLength) + + if err != nil { + if test.wantFail { + continue + } + t.Errorf("Unexpected failure for test %q: %v", test.name, err) + continue + } + + if test.wantFail { + t.Errorf("Unexpected success for test %q", test.name) + continue + } + + assert.Equalf(t, test.expected, tlv, "Test %q", test.name) + } +} + +func TestUnknownTLVSerialize(t *testing.T) { + tests := []struct { + name string + input *UnknownTLV + expected []byte + }{ + { + name: "Full", + input: &UnknownTLV{ + TLVType: 100, + TLVLength: 3, + TLVValue: []byte{1, 2, 3}, + }, + expected: []byte{ + 100, 3, 1, 2, 3, + }, + }, + } + + for _, test := range tests { + buf := bytes.NewBuffer(nil) + test.input.Serialize(buf) + assert.Equalf(t, test.expected, buf.Bytes(), "Test %q", test.name) + } +} -- GitLab