-
Notifications
You must be signed in to change notification settings - Fork 33
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
NETOBSERV-1703 Add enrichment in packet capture #364
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,7 @@ | ||
package decode | ||
|
||
import ( | ||
"encoding/base64" | ||
"fmt" | ||
"syscall" | ||
"time" | ||
|
@@ -9,6 +10,8 @@ import ( | |
"github.com/netobserv/netobserv-ebpf-agent/pkg/flow" | ||
"github.com/netobserv/netobserv-ebpf-agent/pkg/pbflow" | ||
|
||
"github.com/google/gopacket" | ||
"github.com/google/gopacket/layers" | ||
"github.com/mdlayher/ethernet" | ||
log "github.com/sirupsen/logrus" | ||
"google.golang.org/protobuf/proto" | ||
|
@@ -139,6 +142,71 @@ func RecordToMap(fr *flow.Record) config.GenericMap { | |
return out | ||
} | ||
|
||
func PacketToMap(pr *flow.PacketRecord) config.GenericMap { | ||
out := config.GenericMap{} | ||
|
||
if pr == nil { | ||
return out | ||
} | ||
|
||
packet := gopacket.NewPacket(pr.Stream, layers.LayerTypeEthernet, gopacket.Lazy) | ||
if ethLayer := packet.Layer(layers.LayerTypeEthernet); ethLayer != nil { | ||
eth, _ := ethLayer.(*layers.Ethernet) | ||
out["SrcMac"] = eth.SrcMAC.String() | ||
out["DstMac"] = eth.DstMAC.String() | ||
} | ||
|
||
if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil { | ||
tcp, _ := tcpLayer.(*layers.TCP) | ||
out["SrcPort"] = tcp.SrcPort.String() | ||
out["DstPort"] = tcp.DstPort.String() | ||
} else if udpLayer := packet.Layer(layers.LayerTypeUDP); udpLayer != nil { | ||
udp, _ := udpLayer.(*layers.UDP) | ||
out["SrcPort"] = udp.SrcPort.String() | ||
out["DstPort"] = udp.DstPort.String() | ||
} else if sctpLayer := packet.Layer(layers.LayerTypeSCTP); sctpLayer != nil { | ||
sctp, _ := sctpLayer.(*layers.SCTP) | ||
out["SrcPort"] = sctp.SrcPort.String() | ||
out["DstPort"] = sctp.DstPort.String() | ||
} | ||
|
||
if ipv4Layer := packet.Layer(layers.LayerTypeIPv4); ipv4Layer != nil { | ||
ipv4, _ := ipv4Layer.(*layers.IPv4) | ||
out["SrcAddr"] = ipv4.SrcIP.String() | ||
out["DstAddr"] = ipv4.DstIP.String() | ||
out["Proto"] = ipv4.Protocol | ||
} else if ipv6Layer := packet.Layer(layers.LayerTypeIPv6); ipv6Layer != nil { | ||
ipv6, _ := ipv6Layer.(*layers.IPv6) | ||
out["SrcAddr"] = ipv6.SrcIP.String() | ||
out["DstAddr"] = ipv6.DstIP.String() | ||
out["Proto"] = ipv6.NextHeader | ||
} | ||
|
||
if icmpv4Layer := packet.Layer(layers.LayerTypeICMPv4); icmpv4Layer != nil { | ||
icmpv4, _ := icmpv4Layer.(*layers.ICMPv4) | ||
out["IcmpType"] = icmpv4.TypeCode.Type() | ||
out["IcmpCode"] = icmpv4.TypeCode.Code() | ||
} else if icmpv6Layer := packet.Layer(layers.LayerTypeICMPv6); icmpv6Layer != nil { | ||
icmpv6, _ := icmpv6Layer.(*layers.ICMPv6) | ||
out["IcmpType"] = icmpv6.TypeCode.Type() | ||
out["IcmpCode"] = icmpv6.TypeCode.Code() | ||
} | ||
|
||
if dnsLayer := packet.Layer(layers.LayerTypeDNS); dnsLayer != nil { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we allow DNS in packet capture mode ? pca code doesn't enable any feature including DNS There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
dns, _ := dnsLayer.(*layers.DNS) | ||
out["DnsId"] = dns.ID | ||
out["DnsFlagsResponseCode"] = dns.ResponseCode.String() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. DNS enrichement not enabled with pca There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. see #364 (comment) |
||
//TODO: add DNS questions / answers / authorities | ||
} | ||
|
||
out["Bytes"] = len(pr.Stream) | ||
// Data is base64 encoded to avoid marshal / unmarshal issues | ||
out["Data"] = base64.StdEncoding.EncodeToString(packet.Data()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is this efficient I didn't look for any better alternative did u get a chance to explore other options ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm considering to update the gRPC message to send flows and packets as two separate byte array but during the pipeline lifetime I feel that's the easiest solution. On my local kind cluster it's super fast so for now I'm not looking deeper in this. |
||
out["Time"] = pr.Time.Unix() | ||
|
||
return out | ||
} | ||
|
||
// TCPStateToStr is based on kernel TCP state definition | ||
// https://elixir.bootlin.com/linux/v6.3/source/include/net/tcp_states.h#L12 | ||
func TCPStateToStr(state uint32) string { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you are missing
SCTP
protocol supportThere was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure I can add it !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
b39afec