Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions producer/proto/producer_nf.go
Original file line number Diff line number Diff line change
Expand Up @@ -671,18 +671,13 @@ func SearchNetFlowDataSets(version uint16, baseTime uint32, uptime uint32, dataF
func SearchNetFlowOptionDataSets(dataFlowSet []netflow.OptionsDataFlowSet) (samplingRate uint32, found bool, err error) {
for _, dataFlowSetItem := range dataFlowSet {
for _, record := range dataFlowSetItem.Records {
if found, err := NetFlowPopulate(record.OptionsValues, 305, &samplingRate); err != nil || found {
return samplingRate, found, err
}
if found, err := NetFlowPopulate(record.OptionsValues, 50, &samplingRate); err != nil || found {
return samplingRate, found, err
}
if found, err := NetFlowPopulate(record.OptionsValues, 34, &samplingRate); err != nil || found {
return samplingRate, found, err
samplingOptions, err := SamplingFromOptions(record)
if err == nil {
return samplingOptions.SamplingRate(), true, nil
}
}
}
return samplingRate, found, err
return 0, false, nil
}

func SplitNetFlowSets(packetNFv9 netflow.NFv9Packet) ([]netflow.DataFlowSet, []netflow.TemplateFlowSet, []netflow.NFv9OptionsTemplateFlowSet, []netflow.OptionsDataFlowSet) {
Expand Down
82 changes: 82 additions & 0 deletions producer/proto/sampling_rate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package protoproducer

import (
"bytes"
"encoding/binary"
"errors"
"fmt"

"github.com/netsampler/goflow2/v2/decoders/netflow"
"github.com/netsampler/goflow2/v2/decoders/utils"
)

type SamplingRateOptions struct {
PacketSpace uint32
PacketInterval uint32
RandomInterval uint32
SamplingInterval uint32
}

func SamplingFromOptions(records netflow.OptionsDataRecord) (*SamplingRateOptions, error) {
samplingOptions := SamplingRateOptions{}
for _, option := range records.OptionsValues {
switch option.Type {
case netflow.IPFIX_FIELD_samplingPacketSpace:
if err := binDecode(option.Value, &samplingOptions.PacketSpace); err != nil {
return nil, fmt.Errorf("can't make samplingPacketSpace from option value %b", option.Value)
}
case netflow.IPFIX_FIELD_samplingPacketInterval:
if err := binDecode(option.Value, &samplingOptions.PacketInterval); err != nil {
return nil, fmt.Errorf("can't make samplingPacketInterval from option value %b", option.Value)
}
case netflow.IPFIX_FIELD_samplerRandomInterval:
if err := binDecode(option.Value, &samplingOptions.RandomInterval); err != nil {
return nil, fmt.Errorf("can't make samplerRandomInterval from option value %b", option.Value)
}
case netflow.IPFIX_FIELD_samplingInterval:
if err := binDecode(option.Value, &samplingOptions.SamplingInterval); err != nil {
return nil, fmt.Errorf("can't make samplingInterval from option value %b", option.Value)
}
default:
}
}
if samplingOptions.SamplingRate() > 0 {
return &samplingOptions, nil
}
return nil, errors.New("no sampling rate options found")
}

func (s *SamplingRateOptions) SamplingRate() uint32 {
var tmpRate uint32
if s.PacketInterval > 0 {
tmpRate += s.PacketInterval
if s.PacketSpace > 0 {
tmpRate += s.PacketSpace
}
return tmpRate
}
if s.RandomInterval > 0 {
return s.RandomInterval
}
if s.SamplingInterval > 0 {
return s.SamplingInterval
}
return 0
}

func binDecode(source any, destination any) error {
if source == nil {
return errors.New("can't decode nil source")
}
if destination == nil {
return errors.New("can't decode to nil destination")
}
valueBytes, ok := source.([]byte)
if !ok {
return errors.New("source value is not []byte")
}
if err := utils.BinaryRead(bytes.NewBuffer(valueBytes), binary.BigEndian, destination); err != nil {
return err
}
return nil
}