Skip to content

Commit

Permalink
windows dropreasons
Browse files Browse the repository at this point in the history
  • Loading branch information
matmerr committed May 16, 2024
1 parent 32197cf commit 40185dc
Show file tree
Hide file tree
Showing 10 changed files with 3,685 additions and 787 deletions.
1,200 changes: 618 additions & 582 deletions pkg/metrics/types_windows.go

Large diffs are not rendered by default.

116 changes: 116 additions & 0 deletions pkg/plugin/windows/pktmon/pktmon_parsing_windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package pktmon

import (
"fmt"

"github.com/cilium/cilium/api/v1/flow"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/microsoft/retina/pkg/utils"

Check failure on line 9 in pkg/plugin/windows/pktmon/pktmon_parsing_windows.go

View workflow job for this annotation

GitHub Actions / Lint (windows, arm64)

could not import github.com/microsoft/retina/pkg/utils (-: # github.com/microsoft/retina/pkg/utils

Check failure on line 9 in pkg/plugin/windows/pktmon/pktmon_parsing_windows.go

View workflow job for this annotation

GitHub Actions / Lint (windows, amd64)

could not import github.com/microsoft/retina/pkg/utils (-: # github.com/microsoft/retina/pkg/utils
"go.uber.org/zap"
)

func (w *WinPktMon) getUnixTimestamp(StreamMetaData C.PACKETMONITOR_STREAM_METADATA_RETINA) int64 {

Check failure on line 13 in pkg/plugin/windows/pktmon/pktmon_parsing_windows.go

View workflow job for this annotation

GitHub Actions / Lint (windows, arm64)

undefined: WinPktMon (typecheck)

Check failure on line 13 in pkg/plugin/windows/pktmon/pktmon_parsing_windows.go

View workflow job for this annotation

GitHub Actions / Lint (windows, amd64)

undefined: WinPktMon (typecheck)
// use C conversion to pull Windows timestamp
var timestampint C.longlong
C.LargeIntegerToInt(StreamMetaData.TimeStamp, &timestampint)
timestamp := int64(timestampint)

// convert from windows to unix time
var epochDifference int64 = 116444736000000000
return (timestamp - epochDifference) / 10000000
}

func (w *WinPktMon) getVerdict(StreamMetaData C.PACKETMONITOR_STREAM_METADATA_RETINA) flow.Verdict {

Check failure on line 24 in pkg/plugin/windows/pktmon/pktmon_parsing_windows.go

View workflow job for this annotation

GitHub Actions / Lint (windows, arm64)

undefined: WinPktMon (typecheck)

Check failure on line 24 in pkg/plugin/windows/pktmon/pktmon_parsing_windows.go

View workflow job for this annotation

GitHub Actions / Lint (windows, amd64)

undefined: WinPktMon (typecheck)
if StreamMetaData.DropReason != 0 {
return flow.Verdict_DROPPED
}
return flow.Verdict_FORWARDED
}

func (w *WinPktMon) parseL4(packet gopacket.Packet) (*layers.IPv4, error) {

Check failure on line 31 in pkg/plugin/windows/pktmon/pktmon_parsing_windows.go

View workflow job for this annotation

GitHub Actions / Lint (windows, arm64)

undefined: WinPktMon (typecheck)

Check failure on line 31 in pkg/plugin/windows/pktmon/pktmon_parsing_windows.go

View workflow job for this annotation

GitHub Actions / Lint (windows, amd64)

undefined: WinPktMon (typecheck)
ip := &layers.IPv4{}
if ipLayer := packet.Layer(layers.LayerTypeIPv4); ipLayer != nil {
ip, _ = ipLayer.(*layers.IPv4)
} else {
return nil, fmt.Errorf("Failed to parse IP layer %w", ErrFailedToParseWithGoPacket)
}
return ip, nil
}

func (w *WinPktMon) parseTCP(packet gopacket.Packet) (*layers.TCP, error) {

Check failure on line 41 in pkg/plugin/windows/pktmon/pktmon_parsing_windows.go

View workflow job for this annotation

GitHub Actions / Lint (windows, arm64)

undefined: WinPktMon (typecheck)

Check failure on line 41 in pkg/plugin/windows/pktmon/pktmon_parsing_windows.go

View workflow job for this annotation

GitHub Actions / Lint (windows, amd64)

undefined: WinPktMon (typecheck)
tcp := &layers.TCP{}
if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {
tcp, _ = tcpLayer.(*layers.TCP)
} else {
return nil, fmt.Errorf("Failed to parse TCP layer %w", ErrFailedToParseWithGoPacket)
}
return tcp, nil
}

func (w *WinPktMon) parseUDP(packet gopacket.Packet) (*layers.UDP, error) {

Check failure on line 51 in pkg/plugin/windows/pktmon/pktmon_parsing_windows.go

View workflow job for this annotation

GitHub Actions / Lint (windows, arm64)

undefined: WinPktMon (typecheck)

Check failure on line 51 in pkg/plugin/windows/pktmon/pktmon_parsing_windows.go

View workflow job for this annotation

GitHub Actions / Lint (windows, amd64)

undefined: WinPktMon (typecheck)
udp := &layers.UDP{}
if udpLayer := packet.Layer(layers.LayerTypeUDP); udpLayer != nil {
udp, _ = udpLayer.(*layers.UDP)
} else {
return nil, fmt.Errorf("Failed to parse UDP layer %w", ErrFailedToParseWithGoPacket)
}
return udp, nil
}

func (w *WinPktMon) parsePacket(buffer []byte, StreamMetaData C.PACKETMONITOR_STREAM_METADATA_RETINA) (gopacket.Packet, error) {

Check failure on line 61 in pkg/plugin/windows/pktmon/pktmon_parsing_windows.go

View workflow job for this annotation

GitHub Actions / Lint (windows, arm64)

undefined: WinPktMon (typecheck)

Check failure on line 61 in pkg/plugin/windows/pktmon/pktmon_parsing_windows.go

View workflow job for this annotation

GitHub Actions / Lint (windows, amd64)

undefined: WinPktMon (typecheck)
var packet gopacket.Packet
// Ethernet
if StreamMetaData.PacketType == 1 {
packet = gopacket.NewPacket(buffer, layers.LayerTypeEthernet, gopacket.NoCopy)

// IPv4
} else if StreamMetaData.PacketType == 3 {
packet = gopacket.NewPacket(buffer, layers.LayerTypeIPv4, gopacket.NoCopy)
} else {
return nil, ErrUnknownPacketType
}
return packet, nil
}

func (w *WinPktMon) ParseDNS(fl *flow.Flow, metadata *utils.RetinaMetadata, packet gopacket.Packet) error {
dns := &layers.DNS{}
if dnsLayer := packet.Layer(layers.LayerTypeDNS); dnsLayer != nil {
dns, _ = dnsLayer.(*layers.DNS)
} else {
return nil
}

if dns != nil {
//fmt.Printf("qType %d\n", packet.dns.OpCode)
var qtype string
switch dns.OpCode {
case layers.DNSOpCodeQuery:
qtype = "Q"
case layers.DNSOpCodeStatus:
qtype = "R"
default:
qtype = "U"
}

var as, qs []string
for _, a := range dns.Answers {
if a.IP != nil {
as = append(as, a.IP.String())
}
}
for _, q := range dns.Questions {
qs = append(qs, string(q.Name))
}

var query string
if len(dns.Questions) > 0 {
query = string(dns.Questions[0].Name[:])
}
w.l.Debug("DNS packet", zap.String("query", query), zap.String("qtype", qtype), zap.String("answers", fmt.Sprintf("%v", as)))
fl.Verdict = utils.Verdict_DNS
utils.AddDNSInfo(fl, metadata, qtype, uint32(dns.ResponseCode), query, []string{qtype}, len(as), as)
}

return nil
}
50 changes: 23 additions & 27 deletions pkg/plugin/windows/pktmon/pktmon_plugin_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,12 @@ type PktMonPlugin struct {
l *log.ZapLogger
}

func (p *PktMonPlugin) Compile(ctx context.Context) error {
return nil
}

func (p *PktMonPlugin) Generate(ctx context.Context) error {
return nil
}

func (p *PktMonPlugin) Init() error {
pktmonlogger := log.Logger().Named(Name)
p.pkt = &WinPktMon{
l: log.Logger().Named(Name),
l: pktmonlogger,
}
p.l = log.Logger().Named(Name)
p.l = pktmonlogger

return nil
}
Expand All @@ -51,20 +44,6 @@ func (p *PktMonPlugin) Name() string {
return "pktmon"
}

func (p *PktMonPlugin) SetupChannel(ch chan *v1.Event) error {
p.externalChannel = ch
return nil
}

func New(cfg *kcfg.Config) api.Plugin {
return &PktMonPlugin{}
}

type DNSRequest struct {
SourceIP byte
DestinationIP byte
}

func (p *PktMonPlugin) Start(ctx context.Context) error {
fmt.Printf("setting up enricher since pod level is enabled \n")
p.enricher = enricher.Instance()
Expand Down Expand Up @@ -96,9 +75,9 @@ func (p *PktMonPlugin) Start(ctx context.Context) error {

// do this here instead of GetNextPacket to keep higher level
// packet parsing out of L4 parsing
err = parseDNS(fl, meta, packet)
err = p.pkt.ParseDNS(fl, meta, packet)
if err != nil {
golog.Printf("Error parsing DNS: %v\n", err)
golog.Printf("Error parsing DNS: %v\n ", err)
continue
}

Expand All @@ -110,7 +89,7 @@ func (p *PktMonPlugin) Start(ctx context.Context) error {
if p.enricher != nil {
p.enricher.Write(ev)
} else {
fmt.Printf("enricher is nil when writing\n")
fmt.Printf("enricher is nil when writing\n ")
}

// Write the event to the external channel.
Expand All @@ -127,6 +106,23 @@ func (p *PktMonPlugin) Start(ctx context.Context) error {
}
}

func (p *PktMonPlugin) SetupChannel(ch chan *v1.Event) error {
p.externalChannel = ch
return nil
}

func New(cfg *kcfg.Config) api.Plugin {
return &PktMonPlugin{}
}

func (p *PktMonPlugin) Stop() error {
return nil
}

func (p *PktMonPlugin) Compile(ctx context.Context) error {
return nil
}

func (p *PktMonPlugin) Generate(ctx context.Context) error {
return nil
}
109 changes: 2 additions & 107 deletions pkg/plugin/windows/pktmon/pktmon_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,114 +152,9 @@ func (w *WinPktMon) GetNextPacket() (*flow.Flow, *utils.RetinaMetadata, gopacket

// add metadata
meta := &utils.RetinaMetadata{
Bytes: uint64(payloadLength),
Bytes: uint64(payloadLength),
DropReason: metrics.GetDropReason(),
}

return fl, meta, packet, nil
}

func (w *WinPktMon) getUnixTimestamp(StreamMetaData C.PACKETMONITOR_STREAM_METADATA_RETINA) int64 {
// use C conversion to pull Windows timestamp
var timestampint C.longlong
C.LargeIntegerToInt(StreamMetaData.TimeStamp, &timestampint)
timestamp := int64(timestampint)

// convert from windows to unix time
var epochDifference int64 = 116444736000000000
return (timestamp - epochDifference) / 10000000
}

func (w *WinPktMon) getVerdict(StreamMetaData C.PACKETMONITOR_STREAM_METADATA_RETINA) flow.Verdict {
if StreamMetaData.DropReason != 0 {
return flow.Verdict_DROPPED
}
return flow.Verdict_FORWARDED
}

func (w *WinPktMon) parseL4(packet gopacket.Packet) (*layers.IPv4, error) {
ip := &layers.IPv4{}
if ipLayer := packet.Layer(layers.LayerTypeIPv4); ipLayer != nil {
ip, _ = ipLayer.(*layers.IPv4)
} else {
return nil, fmt.Errorf("Failed to parse IP layer %w", ErrFailedToParseWithGoPacket)
}
return ip, nil
}

func (w *WinPktMon) parseTCP(packet gopacket.Packet) (*layers.TCP, error) {
tcp := &layers.TCP{}
if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {
tcp, _ = tcpLayer.(*layers.TCP)
} else {
return nil, fmt.Errorf("Failed to parse TCP layer %w", ErrFailedToParseWithGoPacket)
}
return tcp, nil
}

func (w *WinPktMon) parseUDP(packet gopacket.Packet) (*layers.UDP, error) {
udp := &layers.UDP{}
if udpLayer := packet.Layer(layers.LayerTypeUDP); udpLayer != nil {
udp, _ = udpLayer.(*layers.UDP)
} else {
return nil, fmt.Errorf("Failed to parse UDP layer %w", ErrFailedToParseWithGoPacket)
}
return udp, nil
}

func (w *WinPktMon) parsePacket(buffer []byte, StreamMetaData C.PACKETMONITOR_STREAM_METADATA_RETINA) (gopacket.Packet, error) {
var packet gopacket.Packet
// Ethernet
if StreamMetaData.PacketType == 1 {
packet = gopacket.NewPacket(buffer, layers.LayerTypeEthernet, gopacket.NoCopy)

// IPv4
} else if StreamMetaData.PacketType == 3 {
packet = gopacket.NewPacket(buffer, layers.LayerTypeIPv4, gopacket.NoCopy)
} else {
return nil, ErrUnknownPacketType
}
return packet, nil
}

func parseDNS(fl *flow.Flow, metadata *utils.RetinaMetadata, packet gopacket.Packet) error {
dns := &layers.DNS{}
if dnsLayer := packet.Layer(layers.LayerTypeDNS); dnsLayer != nil {
dns, _ = dnsLayer.(*layers.DNS)
} else {
return nil
}

if dns != nil {
//fmt.Printf("qType %d\n", packet.dns.OpCode)
var qtype string
switch dns.OpCode {
case layers.DNSOpCodeQuery:
qtype = "Q"
case layers.DNSOpCodeStatus:
qtype = "R"
default:
qtype = "U"
}

var as, qs []string
for _, a := range dns.Answers {
if a.IP != nil {
as = append(as, a.IP.String())
}
}
for _, q := range dns.Questions {
qs = append(qs, string(q.Name))
}

var query string
if len(dns.Questions) > 0 {
query = string(dns.Questions[0].Name[:])
}

fl.Verdict = utils.Verdict_DNS

utils.AddDNSInfo(fl, metadata, qtype, uint32(dns.ResponseCode), query, []string{qtype}, len(as), as)
}

return nil
}
1 change: 1 addition & 0 deletions pkg/plugin/windows/pktmon/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
type PktMon interface {
Initialize() error
GetNextPacket() (*flow.Flow, *utils.RetinaMetadata, gopacket.Packet, error)
ParseDNS(*flow.Flow, *utils.RetinaMetadata, gopacket.Packet) error
}

type MockPktMon struct{}
Expand Down
2 changes: 1 addition & 1 deletion pkg/utils/flow_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ func AddTCPFlags(f *flow.Flow, syn, ack, fin, rst, psh, urg uint16) {
}

func AddTcpFlagsBool(f *flow.Flow, syn, ack, fin, rst, psh, urg bool) {

Check failure on line 150 in pkg/utils/flow_utils.go

View workflow job for this annotation

GitHub Actions / Lint (linux, amd64)

var-naming: func AddTcpFlagsBool should be AddTCPFlagsBool (revive)

Check failure on line 150 in pkg/utils/flow_utils.go

View workflow job for this annotation

GitHub Actions / Lint (linux, arm64)

var-naming: func AddTcpFlagsBool should be AddTCPFlagsBool (revive)
if f.L4.GetTCP() == nil {
if f.GetL4().GetTCP() == nil {
return
}

Expand Down
Loading

0 comments on commit 40185dc

Please sign in to comment.