diff --git a/README.md b/README.md index 287353449f5df55332ca2b1b6fc438ded5836bee..46d16ae07f15141170c80b0c010f3ba66b944cfc 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ export FLOWS_TARGET_HOST=... export FLOWS_TARGET_PORT=... sudo -E bin/netobserv-ebpf-agent ``` - +To deploy locally, use instructions from [flowlogs-dump (like tcpdump)](./examples/flowlogs-dump/README.md). To deploy it as a Pod, you can check the [deployment example](./examples/performance/deployment.yml). ## Where is the collector? diff --git a/examples/flowlogs-dump/README.md b/examples/flowlogs-dump/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a5169b78f42539075760f7ea6393baebcb39b894 --- /dev/null +++ b/examples/flowlogs-dump/README.md @@ -0,0 +1,36 @@ +# flowlogs-dump (like tcpdump) + +## How to run + +From the root directory of the project: + +Build the agent (the flowlogs client that uses ebpf) using: +```bash +make build +``` +Build the flowlogs-dump-collector (the server that receives logs from the agent and dumps to screen) using: +```bash +go build -mod vendor -o bin/flowlogs-dump-collector examples/flowlogs-dump/server/flowlogs-dump-collector.go +``` +Start the agent using: +```bash +sudo FLOWS_TARGET_HOST=127.0.0.1 FLOWS_TARGET_PORT=9999 ./bin/netobserv-ebpf-agent +``` + +Start the flowlogs-dump-collector using: (in a secondary shell) +```bash +./bin/flowlogs-dump-collector -listen_port=9999 +``` + +You should see output such as: +```bash +starting flowlogs-dump-collector on port 9999 +13:31:38.857689 eth0 IP 192.168.50.88:5353 > 224.0.0.251:5353: proto:2048 dir:0 bytes:384 packets:2 ends: 13:31:38.859561 +13:31:38.858447 eth0 IP 0.0.0.0:0 > 0.0.0.0:0: proto:34525 dir:0 bytes:424 packets:2 ends: 13:31:38.860284 +13:31:37.409071 eth0 IP 192.168.50.16:2221 > 192.168.50.88:59239: proto:2048 dir:1 bytes:371806 packets:403 ends: 13:31:42.342690 +13:31:37.408148 eth0 IP 192.168.50.88:59239 > 192.168.50.16:2221: proto:2048 dir:0 bytes:16926 packets:277 ends: 13:31:42.390777 +... +``` + + + diff --git a/examples/flowlogs-dump/server/flowlogs-dump-collector.go b/examples/flowlogs-dump/server/flowlogs-dump-collector.go new file mode 100644 index 0000000000000000000000000000000000000000..cfb0bd6854379b6c2db37eefc2596999cde88d3e --- /dev/null +++ b/examples/flowlogs-dump/server/flowlogs-dump-collector.go @@ -0,0 +1,81 @@ +/* + * Copyright (C) 2022 IBM, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package main + +import ( + "flag" + "log" + "net" + + "github.com/netobserv/netobserv-ebpf-agent/pkg/grpc" + "github.com/netobserv/netobserv-ebpf-agent/pkg/pbflow" +) + +var ( + port = flag.Int("listen_port", 9999, "TCP port to listen for flows") +) + +var protocolByNumber = map[uint32]string{ + 1: "icmp", + 2: "igmp", + 6: "tcp", + 17: "udp", + 58: "ipv6-icmp", +} + +func ipIntToNetIP(ipAsInt uint32) net.IP { + var bytes [4]byte + bytes[0] = byte(ipAsInt & 0xFF) + bytes[1] = byte((ipAsInt >> 8) & 0xFF) + bytes[2] = byte((ipAsInt >> 16) & 0xFF) + bytes[3] = byte((ipAsInt >> 24) & 0xFF) + + return net.IPv4(bytes[3], bytes[2], bytes[1], bytes[0]) +} + +// tcpdump flow collector +func main() { + log.SetFlags(0) + flag.Parse() + + receivedRecords := make(chan *pbflow.Records, 100) + log.Println("starting flowlogs-dump-collector on port", *port) + go func() { + _, err := grpc.StartCollector(*port, receivedRecords) + if err != nil { + panic(err) + } + }() + for records := range receivedRecords { + for _, record := range records.Entries { + log.Printf("%v %s IP %s:%d > %s:%d: protocol:%s dir:%d bytes:%d packets:%d ends: %v\n", + record.TimeFlowStart.AsTime().Local().Format("15:04:05.000000"), + record.Interface, + ipIntToNetIP(record.Network.GetSrcAddr().GetIpv4()).String(), + record.Transport.SrcPort, + ipIntToNetIP(record.Network.GetDstAddr().GetIpv4()).String(), + record.Transport.DstPort, + protocolByNumber[record.Transport.Protocol], + record.Direction, + record.Bytes, + record.Packets, + record.TimeFlowEnd.AsTime().Local().Format("15:04:05.000000"), + ) + } + } +}