Skip to content

Commit

Permalink
Add packet collector implementation with an error
Browse files Browse the repository at this point in the history
  • Loading branch information
thegodenage committed Apr 10, 2024
1 parent 260f844 commit 3451015
Show file tree
Hide file tree
Showing 4 changed files with 127 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ we are missing a real modular and open source **Web Application Firewall** that
### Prerequisites
+ Go 1.22+
+ golangci-lint
+ [Npcap](https://npcap.com/) (windows)
+ make (if windows, try using chocolatey)
+ openssl (if windows, try using git bash)
+ [mockery](https://vektra.github.io/mockery/latest/installation/)
Expand Down
26 changes: 26 additions & 0 deletions cmd/collector/main.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,31 @@
package main

import (
"context"
"golang.org/x/sys/windows"
"log"

"waffle/internal/worker"
"waffle/pkg/permission"
)

func main() {
if !windows.GetCurrentProcessToken().IsElevated() {
if err := permission.RunMeElevated(); err != nil {
panic(err.Error())
}
}

ctx := context.Background()

log.Println("starting collector")

collector := worker.NewCollector(worker.CollectorConfig{
Protocol: "tcp",
Port: "8080",
})

if err := collector.Run(ctx); err != nil {
panic(err.Error())
}
}
70 changes: 70 additions & 0 deletions internal/worker/collector.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package worker

import (
"context"
"fmt"
"log"

"github.com/google/gopacket"
"github.com/google/gopacket/pcap"
)

type PacketSerializer interface {
SerializePackets(ctx context.Context, packetsChan chan<- gopacket.Packet) error
}

type CollectorConfig struct {
Protocol string
Port string
}

type Collector struct {
cfg *CollectorConfig
serializer PacketSerializer
}

func NewCollector(cfg CollectorConfig) *Collector {
return &Collector{
cfg: &cfg,
}
}

func (c *Collector) Run(ctx context.Context) error {
handle, err := pcap.OpenLive("eth0", 1600, true, pcap.BlockForever)
if err != nil {
return fmt.Errorf("pcap open live: %w", err)
}

if err := handle.SetBPFFilter(fmt.Sprintf("%s port %s", c.cfg.Protocol, c.cfg.Port)); err != nil {
return fmt.Errorf("set BPFF filter: %w", err)
}

packetSource := gopacket.NewPacketSource(handle, handle.LinkType())

packetsChan := make(chan gopacket.Packet)
defer func() {
close(packetsChan)

log.Println("collector closed")
}()

go func() {
if err := c.serializer.SerializePackets(ctx, packetsChan); err != nil {
log.Println("error in serialize packets")
}
}()

for {
select {
case packet, ok := <-packetSource.Packets():
if !ok {
log.Println("error reading packet")
}

packetsChan <- packet

case <-ctx.Done():
return nil
}
}
}
30 changes: 30 additions & 0 deletions pkg/permission/windows.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package permission

import (
"fmt"
"golang.org/x/sys/windows"
"os"
"strings"
"syscall"
)

func RunMeElevated() error {
verb := "runas"
exe, _ := os.Executable()
cwd, _ := os.Getwd()
args := strings.Join(os.Args[1:], " ")

verbPtr, _ := syscall.UTF16PtrFromString(verb)
exePtr, _ := syscall.UTF16PtrFromString(exe)
cwdPtr, _ := syscall.UTF16PtrFromString(cwd)
argPtr, _ := syscall.UTF16PtrFromString(args)

var showCmd int32 = 1 //SW_NORMAL

err := windows.ShellExecute(0, verbPtr, exePtr, argPtr, cwdPtr, showCmd)
if err != nil {
return fmt.Errorf("windows shell execute: %w", err)
}

return nil
}

0 comments on commit 3451015

Please sign in to comment.