From aba91a412323133ecfbbe569a438d27a7d41f2da Mon Sep 17 00:00:00 2001 From: Marc Guasch Date: Thu, 15 Feb 2024 14:43:31 +0100 Subject: [PATCH] [packetbeat] Fix interface device parsing for packetbeat protocols (#37946) * Fix interface device parsing for packetbeat protocols * Add unit test * Move device check out of validation function * Add err check on condition for clarity --- CHANGELOG.next.asciidoc | 1 + packetbeat/protos/protos.go | 27 ++++++++++----- packetbeat/protos/protos_test.go | 57 ++++++++++++++++++++++++++++++++ 3 files changed, 77 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.next.asciidoc b/CHANGELOG.next.asciidoc index 322348c98bd..5f64d98eb96 100644 --- a/CHANGELOG.next.asciidoc +++ b/CHANGELOG.next.asciidoc @@ -107,6 +107,7 @@ fields added to events containing the Beats version. {pull}37553[37553] *Packetbeat* +- Fix interface device parsing for packetbeat protocols. {pull}37946[37946] *Winlogbeat* diff --git a/packetbeat/protos/protos.go b/packetbeat/protos/protos.go index 26e2783d216..887c349e5b7 100644 --- a/packetbeat/protos/protos.go +++ b/packetbeat/protos/protos.go @@ -173,16 +173,9 @@ func (s ProtocolsStruct) configureProtocol(test bool, device string, pub reporte if device != "" { // This could happen earlier, but let any errors be found first. - var protocol struct { - Device string `config:"interface"` - } - err := config.Unpack(&protocol) - if err != nil { + if isValid, err := validateProtocolDevice(device, config); !isValid || err != nil { return err } - if protocol.Device != "" && protocol.Device != device { - return nil - } } var client beat.Client @@ -205,6 +198,24 @@ func (s ProtocolsStruct) configureProtocol(test bool, device string, pub reporte return nil } +func validateProtocolDevice(device string, config *conf.C) (bool, error) { + var protocol struct { + Interface struct { + Device string `config:"device"` + } `config:"interface"` + } + + if err := config.Unpack(&protocol); err != nil { + return false, err + } + + if protocol.Interface.Device != "" && protocol.Interface.Device != device { + return false, nil + } + + return true, nil +} + func (s ProtocolsStruct) register(proto Protocol, client beat.Client, plugin Plugin) { if _, exists := s.all[proto]; exists { logp.Warn("Protocol (%s) plugin will overwritten by another plugin", proto.String()) diff --git a/packetbeat/protos/protos_test.go b/packetbeat/protos/protos_test.go index 3637d139407..39c11c7847c 100644 --- a/packetbeat/protos/protos_test.go +++ b/packetbeat/protos/protos_test.go @@ -24,6 +24,8 @@ import ( "time" "github.com/elastic/beats/v7/libbeat/common" + conf "github.com/elastic/elastic-agent-libs/config" + "github.com/elastic/go-ucfg" "github.com/stretchr/testify/assert" ) @@ -200,3 +202,58 @@ func TestGetUDP(t *testing.T) { assert.NotNil(t, udp) assert.Contains(t, udp.GetPorts(), 53) } + +func TestValidateProtocolDevice(t *testing.T) { + tcs := []struct { + testCase, device string + config map[string]interface{} + expectedValid bool + expectedErr string + }{ + { + "DeviceIsIncorrect", + "eth0", + map[string]interface{}{ + "interface": map[string]interface{}{ + "device": "eth1", + }, + }, + false, + "", + }, + { + "DeviceIsCorrect", + "eth1", + map[string]interface{}{ + "interface": map[string]interface{}{ + "device": "eth1", + }, + }, + true, + "", + }, + { + "ConfigIsInvalid", + "eth0", + map[string]interface{}{ + "interface": "eth1", + }, + false, + "required 'object', but found 'string' in field 'interface'", + }, + } + + for _, tc := range tcs { + tc := tc + t.Run(tc.testCase, func(t *testing.T) { + cfg := (*conf.C)(ucfg.MustNewFrom(tc.config)) + isValid, err := validateProtocolDevice(tc.device, cfg) + assert.Equal(t, tc.expectedValid, isValid) + if tc.expectedErr == "" { + assert.Nil(t, err) + } else { + assert.EqualError(t, err, tc.expectedErr) + } + }) + } +}