Skip to content

Commit

Permalink
Merge branch 'master' into chore/update_deps
Browse files Browse the repository at this point in the history
  • Loading branch information
pouriyajamshidi authored Dec 31, 2024
2 parents 2e024db + 9a6ca8f commit de3f4a3
Show file tree
Hide file tree
Showing 9 changed files with 109 additions and 10 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/codeql-analysis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ jobs:
uses: actions/checkout@v4

- name: Setting Go version
uses: actions/setup-go@v5.0.2
uses: actions/setup-go@v5.2.0
with:
go-version-file: "go.mod"
check-latest: true
Expand Down
38 changes: 37 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,22 @@ This repo is the companion to my blog posts about eBPF at <https://thegraynode.i

## Running The Program

Clone the repository.
You can install **flat** in two ways.

1. Download the [pre-compiled binary](#download-the-pre-compiled-binary)
2. Compile from [source](#compile-from-source)

### Download The Pre-compiled Binary

```bash
wget https://github.com/pouriyajamshidi/flat/releases/latest/download/flat
```

Then check out the [examples](#examples).

### Compile From Source

Clone the repository:

```bash
git clone https://github.com/pouriyajamshidi/flat .
Expand All @@ -32,13 +47,34 @@ Compile the **Go** program:
go build -ldflags "-s -w" -o flat cmd/flat.go
```

### Examples

Run it with elevated privileges:

```bash
# Replace eth0 with your desired interface name
sudo ./flat -i eth0
# Or
sudo ./flat -i eth0 -ip 1.1.1.1
# Or
sudo ./flat -i eth0 -port 53
# Or
sudo ./flat -i eth0 -ip 1.1.1.1 -port 53
```

## Flags

**flat** supports four flags at the moment:

| flag | Description |
| ----- | ----------------------------------- |
| -i | interface to attach the probe to |
| -ip | IP address to filter on (optional) |
| -port | Port number to filter on (optional) |
| -h | Show help message |

---

## Acknolegments

Heavily inspired by [flowlat](https://github.com/markpash/flowlat).
41 changes: 39 additions & 2 deletions cmd/flat.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,13 @@ import (
"fmt"
"log"
"net"
"net/netip"
"os"
"os/signal"
"syscall"

"github.com/pouriyajamshidi/flat/internal/probe"
"github.com/pouriyajamshidi/flat/internal/types"
"github.com/vishvananda/netlink"
)

Expand Down Expand Up @@ -41,23 +43,58 @@ func displayInterfaces() {
os.Exit(1)
}

func main() {
// getUserInput gets and validates user input
func getUserInput() types.UserInput {
ifaceFlag := flag.String("i", "eth0", "interface to attach the probe to")
ipFlag := flag.String("ip", "", "IP address to track (optional)")
portFlag := flag.Uint("port", 0, "Port number to track (optional)")
flag.Parse()

var userInput types.UserInput

iface, err := netlink.LinkByName(*ifaceFlag)

if err != nil {
log.Printf("Could not find interface %v: %v", *ifaceFlag, err)
displayInterfaces()
}

userInput.Interface = iface

if *ipFlag != "" {
userInput.IP, err = netip.ParseAddr(*ipFlag)

if err != nil {
log.Printf("Could not parse IP address %v: %v", *ipFlag, err)
os.Exit(1)
}

log.Printf("Filtering results on IP %v", userInput.IP)
}

if *portFlag != 0 {
if *portFlag < 1 || *portFlag > 65535 {
log.Printf("Could not parse port %v: %v", *portFlag, err)
os.Exit(1)
}

userInput.Port = uint16(*portFlag)

log.Printf("Filtering results on port %d", userInput.Port)
}

return userInput
}

func main() {
userInput := getUserInput()

ctx := context.Background()
ctx, cancel := context.WithCancel(ctx)

signalHandler(cancel)

if err := probe.Run(ctx, iface); err != nil {
if err := probe.Run(ctx, userInput); err != nil {
log.Fatalf("Failed running the probe: %v", err)
}
}
4 changes: 3 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
module github.com/pouriyajamshidi/flat


go 1.23.4


require (
github.com/cilium/ebpf v0.17.1
github.com/google/gopacket v1.1.19
github.com/gookit/color v1.5.4
github.com/stretchr/testify v1.9.0
github.com/stretchr/testify v1.10.0
github.com/vishvananda/netlink v1.3.0
golang.org/x/sys v0.28.0
)
Expand Down
4 changes: 2 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M=
github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/vishvananda/netlink v1.3.0 h1:X7l42GfcV4S6E4vHTsw48qbrV+9PVojNfIhZcwQdrZk=
github.com/vishvananda/netlink v1.3.0/go.mod h1:i6NetklAujEcC6fK0JPjT8qSwWyO0HLn4UKG+hGqeJs=
github.com/vishvananda/netns v0.0.4/go.mod h1:SpkAiCQRtJ6TvvxPnOSyH3BMl6unz3xZlaprSwhNNJM=
Expand Down
16 changes: 13 additions & 3 deletions internal/probe/probe.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"github.com/pouriyajamshidi/flat/clsact"
"github.com/pouriyajamshidi/flat/internal/flowtable"
"github.com/pouriyajamshidi/flat/internal/packet"
"github.com/pouriyajamshidi/flat/internal/types"
"github.com/vishvananda/netlink"
"golang.org/x/sys/unix"
)
Expand Down Expand Up @@ -180,7 +181,7 @@ func (p *probe) Close() error {

// Run attaches the probe, reads from the eBPF map
// as well as calculating and displaying the flow latencies
func Run(ctx context.Context, iface netlink.Link) error {
func Run(ctx context.Context, userInput types.UserInput) error {
log.Println("Starting up the probe")

if err := setRlimit(); err != nil {
Expand All @@ -196,7 +197,7 @@ func Run(ctx context.Context, iface netlink.Link) error {
}
}()

probe, err := newProbe(iface)
probe, err := newProbe(userInput.Interface)

if err != nil {
return err
Expand Down Expand Up @@ -235,7 +236,16 @@ func Run(ctx context.Context, iface netlink.Link) error {
log.Printf("Could not unmarshall packet: %+v", pkt)
continue
}
packet.CalcLatency(packetAttrs, flowtable)
if !userInput.IP.IsValid() && userInput.Port == 0 {
packet.CalcLatency(packetAttrs, flowtable)
// FIXME:
// } else if (userInput.Port == packetAttrs.DstPort || userInput.Port == packetAttrs.SrcPort) && (userInput.IP == packetAttrs.DstIP.Unmap() || userInput.IP == packetAttrs.SrcIP.Unmap()) {
// packet.CalcLatency(packetAttrs, flowtable)
} else if userInput.IP == packetAttrs.DstIP.Unmap() || userInput.IP == packetAttrs.SrcIP.Unmap() {
packet.CalcLatency(packetAttrs, flowtable)
} else if userInput.Port == packetAttrs.DstPort || userInput.Port == packetAttrs.SrcPort {
packet.CalcLatency(packetAttrs, flowtable)
}
}
}
}
Binary file modified internal/probe/probe_bpfeb.o
Binary file not shown.
Binary file modified internal/probe/probe_bpfel.o
Binary file not shown.
14 changes: 14 additions & 0 deletions internal/types/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package types

import (
"net/netip"

"github.com/vishvananda/netlink"
)

// UserInput holds the information provided through flags
type UserInput struct {
Interface netlink.Link
IP netip.Addr
Port uint16
}

0 comments on commit de3f4a3

Please sign in to comment.