Skip to content

Commit

Permalink
decoders: fix sflow parsing of IP and MAC addresses (#261)
Browse files Browse the repository at this point in the history
Due to IP and MAC addresses being a non-standard type, utils.BinaryRead
was not able to decode them. Move these two types inside utils.go and
teach BinaryRead to use them.

Co-authored-by: lspgn <lspgn@users.noreply.github.com>
  • Loading branch information
vincentbernat and lspgn authored Jan 6, 2024
1 parent ff4ddca commit a61288e
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 56 deletions.
65 changes: 28 additions & 37 deletions decoders/sflow/datastructure.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package sflow

import (
"fmt"
"net"
)
import "github.com/netsampler/goflow2/v2/decoders/utils"

type SampledHeader struct {
Protocol uint32 `json:"protocol"`
Expand All @@ -14,26 +11,20 @@ type SampledHeader struct {
}

type SampledEthernet struct {
Length uint32 `json:"length"`
SrcMac MacAddress `json:"src-mac"`
DstMac MacAddress `json:"dst-mac"`
EthType uint32 `json:"eth-type"`
Length uint32 `json:"length"`
SrcMac utils.MacAddress `json:"src-mac"`
DstMac utils.MacAddress `json:"dst-mac"`
EthType uint32 `json:"eth-type"`
}

type SampledIPBase struct {
Length uint32 `json:"length"`
Protocol uint32 `json:"protocol"`
SrcIP IPAddress `json:"src-ip"`
DstIP IPAddress `json:"dst-ip"`
SrcPort uint32 `json:"src-port"`
DstPort uint32 `json:"dst-port"`
TcpFlags uint32 `json:"tcp-flags"`
}

type MacAddress []byte // purely for the formatting purpose

func (s *MacAddress) MarshalJSON() ([]byte, error) {
return []byte(fmt.Sprintf("\"%s\"", net.HardwareAddr([]byte(*s)).String())), nil
Length uint32 `json:"length"`
Protocol uint32 `json:"protocol"`
SrcIP utils.IPAddress `json:"src-ip"`
DstIP utils.IPAddress `json:"dst-ip"`
SrcPort uint32 `json:"src-port"`
DstPort uint32 `json:"dst-port"`
TcpFlags uint32 `json:"tcp-flags"`
}

type SampledIPv4 struct {
Expand All @@ -54,25 +45,25 @@ type ExtendedSwitch struct {
}

type ExtendedRouter struct {
NextHopIPVersion uint32 `json:"next-hop-ip-version"`
NextHop IPAddress `json:"next-hop"`
SrcMaskLen uint32 `json:"src-mask-len"`
DstMaskLen uint32 `json:"dst-mask-len"`
NextHopIPVersion uint32 `json:"next-hop-ip-version"`
NextHop utils.IPAddress `json:"next-hop"`
SrcMaskLen uint32 `json:"src-mask-len"`
DstMaskLen uint32 `json:"dst-mask-len"`
}

type ExtendedGateway struct {
NextHopIPVersion uint32 `json:"next-hop-ip-version"`
NextHop IPAddress `json:"next-hop"`
AS uint32 `json:"as"`
SrcAS uint32 `json:"src-as"`
SrcPeerAS uint32 `json:"src-peer-as"`
ASDestinations uint32 `json:"as-destinations"`
ASPathType uint32 `json:"as-path-type"`
ASPathLength uint32 `json:"as-path-length"`
ASPath []uint32 `json:"as-path"`
CommunitiesLength uint32 `json:"communities-length"`
Communities []uint32 `json:"communities"`
LocalPref uint32 `json:"local-pref"`
NextHopIPVersion uint32 `json:"next-hop-ip-version"`
NextHop utils.IPAddress `json:"next-hop"`
AS uint32 `json:"as"`
SrcAS uint32 `json:"src-as"`
SrcPeerAS uint32 `json:"src-peer-as"`
ASDestinations uint32 `json:"as-destinations"`
ASPathType uint32 `json:"as-path-type"`
ASPathLength uint32 `json:"as-path-length"`
ASPath []uint32 `json:"as-path"`
CommunitiesLength uint32 `json:"communities-length"`
Communities []uint32 `json:"communities"`
LocalPref uint32 `json:"local-pref"`
}

type IfCounters struct {
Expand Down
28 changes: 9 additions & 19 deletions decoders/sflow/packet.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,16 @@
package sflow

import (
"fmt"
"net/netip"
)
import "github.com/netsampler/goflow2/v2/decoders/utils"

type Packet struct {
Version uint32 `json:"version"`
IPVersion uint32 `json:"ip-version"`
AgentIP IPAddress `json:"agent-ip"`
SubAgentId uint32 `json:"sub-agent-id"`
SequenceNumber uint32 `json:"sequence-number"`
Uptime uint32 `json:"uptime"`
SamplesCount uint32 `json:"samples-count"`
Samples []interface{} `json:"samples"`
}

type IPAddress []byte // purely for the formatting purpose

func (s IPAddress) MarshalJSON() ([]byte, error) {
ip, _ := netip.AddrFromSlice([]byte(s))
return []byte(fmt.Sprintf("\"%s\"", ip.String())), nil
Version uint32 `json:"version"`
IPVersion uint32 `json:"ip-version"`
AgentIP utils.IPAddress `json:"agent-ip"`
SubAgentId uint32 `json:"sub-agent-id"`
SequenceNumber uint32 `json:"sequence-number"`
Uptime uint32 `json:"uptime"`
SamplesCount uint32 `json:"samples-count"`
Samples []interface{} `json:"samples"`
}

type SampleHeader struct {
Expand Down
20 changes: 20 additions & 0 deletions decoders/utils/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package utils

import (
"fmt"
"net"
"net/netip"
)

type MacAddress []byte // purely for the formatting purpose

func (s *MacAddress) MarshalJSON() ([]byte, error) {
return []byte(fmt.Sprintf("\"%s\"", net.HardwareAddr([]byte(*s)).String())), nil
}

type IPAddress []byte // purely for the formatting purpose

func (s IPAddress) MarshalJSON() ([]byte, error) {
ip, _ := netip.AddrFromSlice([]byte(s))
return []byte(fmt.Sprintf("\"%s\"", ip.String())), nil
}
8 changes: 8 additions & 0 deletions decoders/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,10 @@ func BinaryRead(payload BytesBuffer, order binary.ByteOrder, data any) error {
}
case []uint8:
copy(data, bs)
case IPAddress:
copy(data, bs)
case MacAddress:
copy(data, bs)
case []int16:
for i := range data {
data[i] = int16(order.Uint16(bs[2*i:]))
Expand Down Expand Up @@ -105,6 +109,10 @@ func intDataSize(data any) int {
return len(data)
case []uint8:
return len(data)
case IPAddress:
return len(data)
case MacAddress:
return len(data)
case int16, uint16, *int16, *uint16:
return 2
case []int16:
Expand Down

0 comments on commit a61288e

Please sign in to comment.