Skip to content

Commit

Permalink
Merge pull request #35 from twsnmp/twsnmp
Browse files Browse the repository at this point in the history
Added function to decode EventDiscardedPacket and fix warning
  • Loading branch information
Preetam authored Jun 22, 2024
2 parents 912a0ce + 21cda3c commit ed105e3
Show file tree
Hide file tree
Showing 8 changed files with 230 additions and 9 deletions.
Binary file added _test/event_discarded_packet.dump
Binary file not shown.
4 changes: 2 additions & 2 deletions counter_sample.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ func decodeCounterSample(r io.ReadSeeker) (Sample, error) {
}

s.SourceIdIndexVal = uint32(srcIdIndexVal[2]) |
uint32(srcIdIndexVal[1]<<8) |
uint32(srcIdIndexVal[0]<<16)
uint32(srcIdIndexVal[1])<<8 |
uint32(srcIdIndexVal[0])<<16

err = binary.Read(r, binary.BigEndian, &s.numRecords)
if err != nil {
Expand Down
32 changes: 32 additions & 0 deletions decode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -173,3 +173,35 @@ func TestDecodeFlow1(t *testing.T) {
t.Errorf("expected FrameLength to be 128, got %d", rec.HeaderSize)
}
}

func TestDecodeEventDiscardedPacket(t *testing.T) {
f, err := os.Open("_test/event_discarded_packet.dump")
if err != nil {
t.Fatal(err)
}

d := NewDecoder(f)

dgram, err := d.Decode()
if err != nil {
t.Fatal(err)
}

if dgram.Version != 5 {
t.Errorf("Expected datagram version %v, got %v", 5, dgram.Version)
}

if int(dgram.NumSamples) != len(dgram.Samples) {
t.Fatalf("expected NumSamples to be %d, but len(Samples) is %d", dgram.NumSamples, len(dgram.Samples))
}

if len(dgram.Samples) != 1 {
t.Fatalf("expected 1 sample, got %d", len(dgram.Samples))
}

_, ok := dgram.Samples[0].(*EventDiscardedPacket)
if !ok {
t.Fatalf("expected a EventDiscardedPacket, got %T", dgram.Samples[0])
}

}
2 changes: 1 addition & 1 deletion encoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func NewEncoder(source net.IP, subAgentId uint32, initialSequenceNumber uint32)
// Encode encodes an sFlow v5 datagram with the given samples and
// writes the packet to w.
func (e *Encoder) Encode(w io.Writer, samples []Sample) error {
if samples == nil || len(samples) == 0 {
if len(samples) == 0 {
return ErrNoSamplesProvided
}

Expand Down
185 changes: 185 additions & 0 deletions event_discarded_packet.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
package sflow

import (
"bytes"
"encoding/binary"
"fmt"
"io"
)

type EventDiscardedPacket struct {
SequenceNum uint32
DsClass uint32
DsIndex uint32
Drops uint32
Input uint32
Output uint32
Reason uint32
numRecords uint32
Records []Record
}

func (s EventDiscardedPacket) String() string {
type X EventDiscardedPacket
x := X(s)
return fmt.Sprintf("EventDiscardedPacket: %+v", x)
}

// SampleType returns the type of sFlow sample.
func (s *EventDiscardedPacket) SampleType() int {
return TypeEventDiscardedPacket
}

func (s *EventDiscardedPacket) GetRecords() []Record {
return s.Records
}

func decodEventDiscardedPacket(r io.ReadSeeker) (Sample, error) {
s := &EventDiscardedPacket{}

var err error

err = binary.Read(r, binary.BigEndian, &s.SequenceNum)
if err != nil {
return nil, err
}

err = binary.Read(r, binary.BigEndian, &s.DsClass)
if err != nil {
return nil, err
}

err = binary.Read(r, binary.BigEndian, &s.DsIndex)
if err != nil {
return nil, err
}

err = binary.Read(r, binary.BigEndian, &s.Drops)
if err != nil {
return nil, err
}

err = binary.Read(r, binary.BigEndian, &s.Input)
if err != nil {
return nil, err
}

err = binary.Read(r, binary.BigEndian, &s.Output)
if err != nil {
return nil, err
}

err = binary.Read(r, binary.BigEndian, &s.Reason)
if err != nil {
return nil, fmt.Errorf("read reson %v", err)
}

err = binary.Read(r, binary.BigEndian, &s.numRecords)
if err != nil {
return nil, fmt.Errorf("read numRecords %v", err)
}

for i := uint32(0); i < s.numRecords; i++ {
format, length := uint32(0), uint32(0)

err = binary.Read(r, binary.BigEndian, &format)
if err != nil {
return nil, fmt.Errorf("read record format %d %v", i, err)
}

err = binary.Read(r, binary.BigEndian, &length)
if err != nil {
return nil, fmt.Errorf("read record length %d %v", i, err)
}

var rec Record

switch format {
case TypeRawPacketFlowRecord:
rec, err = decodeRawPacketFlow(r)
if err != nil {
return nil, fmt.Errorf("read record flow %d %v", i, err)
}
case TypeExtendedSwitchFlowRecord:
rec, err = decodedExtendedSwitchFlow(r)
if err != nil {
return nil, fmt.Errorf("read record switch flow %d %v", i, err)
}

default:
_, err := r.Seek(int64(length), 1)
if err != nil {
return nil, fmt.Errorf("read record seek %d %v", i, err)
}

continue
}

s.Records = append(s.Records, rec)
}

return s, nil
}

func (s *EventDiscardedPacket) encode(w io.Writer) error {
var err error

// We first need to encode the records.
buf := &bytes.Buffer{}

for _, rec := range s.Records {
err = rec.encode(buf)
if err != nil {
return ErrEncodingRecord
}
}

// Fields
encodedSampleSize := uint32(4 * 8)

// Encoded records
encodedSampleSize += uint32(buf.Len())

err = binary.Write(w, binary.BigEndian, uint32(s.SampleType()))
if err != nil {
return err
}
err = binary.Write(w, binary.BigEndian, encodedSampleSize)
if err != nil {
return err
}
err = binary.Write(w, binary.BigEndian, s.SequenceNum)
if err != nil {
return err
}
err = binary.Write(w, binary.BigEndian, s.DsClass)
if err != nil {
return err
}
err = binary.Write(w, binary.BigEndian, s.DsIndex)
if err != nil {
return err
}
err = binary.Write(w, binary.BigEndian, s.Drops)
if err != nil {
return err
}
err = binary.Write(w, binary.BigEndian, s.Input)
if err != nil {
return err
}
err = binary.Write(w, binary.BigEndian, s.Output)
if err != nil {
return err
}
err = binary.Write(w, binary.BigEndian, s.Reason)
if err != nil {
return err
}
err = binary.Write(w, binary.BigEndian, uint32(len(s.Records)))
if err != nil {
return err
}
_, err = io.Copy(w, buf)
return err
}
8 changes: 4 additions & 4 deletions flow_record.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,12 +69,12 @@ func decodeRawPacketFlow(r io.Reader) (RawPacketFlow, error) {
MaximumHeaderLength, f.HeaderSize)
}

padding := (4 - f.HeaderSize) % 4
padding := (4 - int(f.HeaderSize)) % 4
if padding < 0 {
padding += 4
}

f.Header = make([]byte, f.HeaderSize+padding)
f.Header = make([]byte, f.HeaderSize+uint32(padding))

_, err = r.Read(f.Header)
if err != nil {
Expand All @@ -100,12 +100,12 @@ func (f RawPacketFlow) encode(w io.Writer) error {
encodedRecordLength := uint32(4 * 4) // 4 32-bit records

// Add the length of the header padded to a multiple of 4 bytes.
padding := (4 - f.HeaderSize) % 4
padding := (4 - int(f.HeaderSize)) % 4
if padding < 0 {
padding += 4
}

encodedRecordLength += f.HeaderSize + padding
encodedRecordLength += f.HeaderSize + uint32(padding)

err = binary.Write(w, binary.BigEndian, encodedRecordLength)
if err != nil {
Expand Down
4 changes: 2 additions & 2 deletions flow_sample.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,8 +82,8 @@ func decodeFlowSample(r io.ReadSeeker) (Sample, error) {
}

s.SourceIdIndexVal = uint32(srcIdIndexVal[2]) |
uint32(srcIdIndexVal[1]<<8) |
uint32(srcIdIndexVal[0]<<16)
uint32(srcIdIndexVal[1])<<8 |
uint32(srcIdIndexVal[0])<<16

err = binary.Read(r, binary.BigEndian, &s.SamplingRate)
if err != nil {
Expand Down
4 changes: 4 additions & 0 deletions sample.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const (
TypeCounterSample = 2
TypeExpandedFlowSample = 3
TypeExpandedCounterSample = 4
TypeEventDiscardedPacket = 5
)

var (
Expand Down Expand Up @@ -43,6 +44,9 @@ func decodeSample(r io.ReadSeeker) (Sample, error) {
case TypeFlowSample:
return decodeFlowSample(r)

case TypeEventDiscardedPacket:
return decodEventDiscardedPacket(r)

default:
_, err = r.Seek(int64(length), 1)
if err != nil {
Expand Down

0 comments on commit ed105e3

Please sign in to comment.