Skip to content

Commit 18e017f

Browse files
authored
NETOBSERV-1890: decode TCP flags (new stage/rule) (#747)
* NETOBSERV-1890: decode TCP flags (new stage/rule) * Use flags list
1 parent 0fa789c commit 18e017f

File tree

5 files changed

+63
-1
lines changed

5 files changed

+63
-1
lines changed

docs/api.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ Following is the supported API format for network transformations:
255255
add_kubernetes_infra: add output kubernetes isInfra field from input
256256
reinterpret_direction: reinterpret flow direction at the node level (instead of net interface), to ease the deduplication process
257257
add_subnet_label: categorize IPs based on known subnets configuration
258+
decode_tcp_flags: decode bitwise TCP flags into a string
258259
kubernetes_infra: Kubernetes infra rule configuration
259260
namespaceNameFields: entries for namespace and name input fields
260261
name: name of the object
@@ -286,6 +287,9 @@ Following is the supported API format for network transformations:
286287
input: entry input field
287288
output: entry output field
288289
protocol: entry protocol field
290+
decode_tcp_flags: Decode bitwise TCP flags into a string
291+
input: entry input field
292+
output: entry output field
289293
kubeConfig: global configuration related to Kubernetes (optional)
290294
configPath: path to kubeconfig file (optional)
291295
secondaryNetworks: configuration for secondary networks

pkg/api/transform_network.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ const (
5959
NetworkAddKubernetesInfra TransformNetworkOperationEnum = "add_kubernetes_infra" // add output kubernetes isInfra field from input
6060
NetworkReinterpretDirection TransformNetworkOperationEnum = "reinterpret_direction" // reinterpret flow direction at the node level (instead of net interface), to ease the deduplication process
6161
NetworkAddSubnetLabel TransformNetworkOperationEnum = "add_subnet_label" // categorize IPs based on known subnets configuration
62+
NetworkDecodeTCPFlags TransformNetworkOperationEnum = "decode_tcp_flags" // decode bitwise TCP flags into a string
6263
)
6364

6465
type NetworkTransformRule struct {
@@ -69,6 +70,7 @@ type NetworkTransformRule struct {
6970
AddLocation *NetworkGenericRule `yaml:"add_location,omitempty" json:"add_location,omitempty" doc:"Add location rule configuration"`
7071
AddSubnetLabel *NetworkAddSubnetLabelRule `yaml:"add_subnet_label,omitempty" json:"add_subnet_label,omitempty" doc:"Add subnet label rule configuration"`
7172
AddService *NetworkAddServiceRule `yaml:"add_service,omitempty" json:"add_service,omitempty" doc:"Add service rule configuration"`
73+
DecodeTCPFlags *NetworkGenericRule `yaml:"decode_tcp_flags,omitempty" json:"decode_tcp_flags,omitempty" doc:"Decode bitwise TCP flags into a string"`
7274
}
7375

7476
type K8sInfraRule struct {

pkg/pipeline/transform/transform_network.go

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,13 @@ func (n *Network) Transform(inputEntry config.GenericMap) (config.GenericMap, bo
141141
}
142142
}
143143
}
144+
case api.NetworkDecodeTCPFlags:
145+
if anyFlags, ok := outputEntry[rule.DecodeTCPFlags.Input]; ok && anyFlags != nil {
146+
if flags, ok := anyFlags.(uint16); ok {
147+
flags := util.DecodeTCPFlags(flags)
148+
outputEntry[rule.DecodeTCPFlags.Output] = flags
149+
}
150+
}
144151

145152
default:
146153
log.Panicf("unknown type %s for transform.Network rule: %v", rule.Type, rule)
@@ -194,7 +201,8 @@ func NewTransformNetwork(params config.StageParam, opMetrics *operational.Metric
194201
if len(jsonNetworkTransform.SubnetLabels) == 0 {
195202
return nil, fmt.Errorf("a rule '%s' was found, but there are no subnet labels configured", api.NetworkAddSubnetLabel)
196203
}
197-
case api.NetworkAddSubnet:
204+
case api.NetworkAddSubnet, api.NetworkDecodeTCPFlags:
205+
// nothing
198206
}
199207
}
200208

pkg/utils/tcp_flags.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package utils
2+
3+
type tcpFlag struct {
4+
value uint16
5+
name string
6+
}
7+
8+
var tcpFlags = []tcpFlag{
9+
{value: 1, name: "FIN"},
10+
{value: 2, name: "SYN"},
11+
{value: 4, name: "RST"},
12+
{value: 8, name: "PSH"},
13+
{value: 16, name: "ACK"},
14+
{value: 32, name: "URG"},
15+
{value: 64, name: "ECE"},
16+
{value: 128, name: "CWR"},
17+
{value: 256, name: "SYN_ACK"},
18+
{value: 512, name: "FIN_ACK"},
19+
{value: 1024, name: "RST_ACK"},
20+
}
21+
22+
func DecodeTCPFlags(bitfield uint16) []string {
23+
var values []string
24+
for _, flag := range tcpFlags {
25+
if bitfield&flag.value != 0 {
26+
values = append(values, flag.name)
27+
}
28+
}
29+
return values
30+
}

pkg/utils/tcp_flags_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package utils
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
)
8+
9+
func TestDecodeFlags(t *testing.T) {
10+
flags528 := DecodeTCPFlags(528)
11+
assert.Equal(t, []string{"ACK", "FIN_ACK"}, flags528)
12+
13+
flags256 := DecodeTCPFlags(256)
14+
assert.Equal(t, []string{"SYN_ACK"}, flags256)
15+
16+
flags666 := DecodeTCPFlags(666)
17+
assert.Equal(t, []string{"SYN", "PSH", "ACK", "CWR", "FIN_ACK"}, flags666)
18+
}

0 commit comments

Comments
 (0)