packet interceptor

This commit is contained in:
Sudo-Ivan
2025-01-04 18:37:53 -06:00
parent 79e1caa815
commit 77729e07e1
2 changed files with 196 additions and 20 deletions

View File

@@ -0,0 +1,104 @@
package testutils
import (
"encoding/hex"
"fmt"
"os"
"sync"
"time"
"github.com/Sudo-Ivan/reticulum-go/pkg/common"
)
type PacketInterceptor struct {
mutex sync.Mutex
outputFile *os.File
isEnabled bool
packetCount uint64
}
func NewPacketInterceptor(outputPath string) (*PacketInterceptor, error) {
file, err := os.OpenFile(outputPath, os.O_CREATE|os.O_APPEND|os.O_WRONLY, 0644)
if err != nil {
return nil, fmt.Errorf("failed to open output file: %v", err)
}
pi := &PacketInterceptor{
outputFile: file,
isEnabled: true,
}
// Write header
header := fmt.Sprintf("=== Packet Capture Started at %s ===\n\n",
time.Now().UTC().Format("2006-01-02 15:04:05"))
if _, err := file.WriteString(header); err != nil {
file.Close()
return nil, fmt.Errorf("failed to write header: %v", err)
}
return pi, nil
}
func (pi *PacketInterceptor) Close() error {
pi.mutex.Lock()
defer pi.mutex.Unlock()
if pi.outputFile != nil {
return pi.outputFile.Close()
}
return nil
}
func (pi *PacketInterceptor) InterceptPacket(data []byte, iface common.NetworkInterface, direction string) error {
pi.mutex.Lock()
defer pi.mutex.Unlock()
if !pi.isEnabled || pi.outputFile == nil {
return nil
}
timestamp := time.Now().UTC().Format("2006-01-02 15:04:05.000")
pi.packetCount++
// Format packet info
logEntry := fmt.Sprintf("[%s] %s packet #%d on interface %s\n",
timestamp,
direction,
pi.packetCount,
iface.GetName(),
)
// Add hex dump of packet data
logEntry += fmt.Sprintf("Data (%d bytes):\n%s\n\n",
len(data),
hex.Dump(data),
)
// Write to file
if _, err := pi.outputFile.WriteString(logEntry); err != nil {
return fmt.Errorf("failed to write to log file: %v", err)
}
// Ensure data is written to disk
return pi.outputFile.Sync()
}
func (pi *PacketInterceptor) InterceptOutgoing(data []byte, iface common.NetworkInterface) error {
return pi.InterceptPacket(data, iface, "OUTGOING")
}
func (pi *PacketInterceptor) InterceptIncoming(data []byte, iface common.NetworkInterface) error {
return pi.InterceptPacket(data, iface, "INCOMING")
}
func (pi *PacketInterceptor) Enable() {
pi.mutex.Lock()
defer pi.mutex.Unlock()
pi.isEnabled = true
}
func (pi *PacketInterceptor) Disable() {
pi.mutex.Lock()
defer pi.mutex.Unlock()
pi.isEnabled = false
}