fix: Extract network metadata from tcpdump headers to populate SIP packet IPs
This commit is contained in:
BIN
inspector.exe
BIN
inspector.exe
Binary file not shown.
@@ -6,6 +6,7 @@ import (
|
|||||||
"io"
|
"io"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
|
"time"
|
||||||
|
|
||||||
"telephony-inspector/internal/sip"
|
"telephony-inspector/internal/sip"
|
||||||
internalSSH "telephony-inspector/internal/ssh"
|
internalSSH "telephony-inspector/internal/ssh"
|
||||||
@@ -17,6 +18,7 @@ type Capturer struct {
|
|||||||
cleanup func() error
|
cleanup func() error
|
||||||
running bool
|
running bool
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
|
currentNetInfo *NetInfo
|
||||||
|
|
||||||
// Callbacks
|
// Callbacks
|
||||||
OnPacket func(*sip.Packet)
|
OnPacket func(*sip.Packet)
|
||||||
@@ -114,6 +116,15 @@ func (c *Capturer) processStream(r io.Reader) {
|
|||||||
|
|
||||||
line := scanner.Text()
|
line := scanner.Text()
|
||||||
|
|
||||||
|
// Check for tcpdump header
|
||||||
|
if netInfo := parseTcpdumpHeader(line); netInfo != nil {
|
||||||
|
c.currentNetInfo = netInfo
|
||||||
|
// If we were parsing a message, this header likely means the previous message ended (or it's just info)
|
||||||
|
// But tcpdump prints header BEFORE payload.
|
||||||
|
// Proceed to next line
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
// Detect start of SIP message
|
// Detect start of SIP message
|
||||||
if idx := findSIPStart(line); idx != -1 {
|
if idx := findSIPStart(line); idx != -1 {
|
||||||
// Clean the line (remove prefix garbage)
|
// Clean the line (remove prefix garbage)
|
||||||
@@ -159,10 +170,23 @@ func (c *Capturer) parseAndEmit(raw string) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if packet != nil && c.OnPacket != nil {
|
if packet != nil {
|
||||||
|
// Attach network info if available
|
||||||
|
if c.currentNetInfo != nil {
|
||||||
|
// Use timestamp from packet header if possible, or keep what parser found?
|
||||||
|
// Parser doesn't find time.
|
||||||
|
packet.Timestamp = c.currentNetInfo.Timestamp
|
||||||
|
packet.SourceIP = c.currentNetInfo.SourceIP
|
||||||
|
packet.SourcePort = c.currentNetInfo.SourcePort
|
||||||
|
packet.DestIP = c.currentNetInfo.DestIP
|
||||||
|
packet.DestPort = c.currentNetInfo.DestPort
|
||||||
|
}
|
||||||
|
|
||||||
|
if c.OnPacket != nil {
|
||||||
c.OnPacket(packet)
|
c.OnPacket(packet)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// findSIPStart returns the index of the start of a SIP message, or -1 if not found
|
// findSIPStart returns the index of the start of a SIP message, or -1 if not found
|
||||||
func findSIPStart(line string) int {
|
func findSIPStart(line string) int {
|
||||||
@@ -198,3 +222,57 @@ func findSIPStart(line string) int {
|
|||||||
|
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NetInfo stores network layer information from tcpdump headers
|
||||||
|
type NetInfo struct {
|
||||||
|
Timestamp time.Time
|
||||||
|
SourceIP string
|
||||||
|
SourcePort int
|
||||||
|
DestIP string
|
||||||
|
DestPort int
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseTcpdumpHeader(line string) *NetInfo {
|
||||||
|
// Format: 15:35:10.430328 IP 192.168.0.164.51416 > 192.168.0.158.5060: ...
|
||||||
|
parts := strings.Fields(line)
|
||||||
|
if len(parts) < 5 || parts[1] != "IP" {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse Timestamp
|
||||||
|
// Using generic date + log time
|
||||||
|
now := time.Now()
|
||||||
|
t, err := time.Parse("15:04:05.000000", parts[0])
|
||||||
|
if err == nil {
|
||||||
|
t = time.Date(now.Year(), now.Month(), now.Day(), t.Hour(), t.Minute(), t.Second(), t.Nanosecond(), now.Location())
|
||||||
|
} else {
|
||||||
|
t = now
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper to extract IP and Port
|
||||||
|
parseIPPort := func(s string) (string, int) {
|
||||||
|
lastDot := strings.LastIndex(s, ".")
|
||||||
|
if lastDot == -1 {
|
||||||
|
return s, 0
|
||||||
|
}
|
||||||
|
ip := s[:lastDot]
|
||||||
|
portStr := s[lastDot+1:]
|
||||||
|
// Remove trailing colon if present (dest)
|
||||||
|
portStr = strings.TrimSuffix(portStr, ":")
|
||||||
|
|
||||||
|
var port int
|
||||||
|
fmt.Sscanf(portStr, "%d", &port)
|
||||||
|
return ip, port
|
||||||
|
}
|
||||||
|
|
||||||
|
srcIP, srcPort := parseIPPort(parts[2])
|
||||||
|
dstIP, dstPort := parseIPPort(parts[4])
|
||||||
|
|
||||||
|
return &NetInfo{
|
||||||
|
Timestamp: t,
|
||||||
|
SourceIP: srcIP,
|
||||||
|
SourcePort: srcPort,
|
||||||
|
DestIP: dstIP,
|
||||||
|
DestPort: dstPort,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ type LocalCapturer struct {
|
|||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
running bool
|
running bool
|
||||||
mu sync.Mutex
|
mu sync.Mutex
|
||||||
|
currentNetInfo *NetInfo
|
||||||
|
|
||||||
// Callbacks
|
// Callbacks
|
||||||
OnPacket func(*sip.Packet)
|
OnPacket func(*sip.Packet)
|
||||||
@@ -138,6 +139,13 @@ func (c *LocalCapturer) processStream(r io.Reader) {
|
|||||||
line := scanner.Text()
|
line := scanner.Text()
|
||||||
// logger.Debug("Stdout: %s", line) // Commented out to reduce noise, enable if needed
|
// logger.Debug("Stdout: %s", line) // Commented out to reduce noise, enable if needed
|
||||||
|
|
||||||
|
// Check for tcpdump header
|
||||||
|
if netInfo := parseTcpdumpHeader(line); netInfo != nil {
|
||||||
|
c.currentNetInfo = netInfo
|
||||||
|
// Proceed to next line
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
// Detect start of SIP message
|
// Detect start of SIP message
|
||||||
if idx := findSIPStart(line); idx != -1 {
|
if idx := findSIPStart(line); idx != -1 {
|
||||||
logger.Debug("SIP Start detected: %s", line)
|
logger.Debug("SIP Start detected: %s", line)
|
||||||
@@ -190,6 +198,14 @@ func (c *LocalCapturer) parseAndEmit(raw string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
if packet != nil {
|
if packet != nil {
|
||||||
|
// Attach network info if available
|
||||||
|
if c.currentNetInfo != nil {
|
||||||
|
packet.Timestamp = c.currentNetInfo.Timestamp
|
||||||
|
packet.SourceIP = c.currentNetInfo.SourceIP
|
||||||
|
packet.SourcePort = c.currentNetInfo.SourcePort
|
||||||
|
packet.DestIP = c.currentNetInfo.DestIP
|
||||||
|
packet.DestPort = c.currentNetInfo.DestPort
|
||||||
|
}
|
||||||
logger.Debug("Packet parsed: %s %s -> %s", packet.Method, packet.SourceIP, packet.DestIP)
|
logger.Debug("Packet parsed: %s %s -> %s", packet.Method, packet.SourceIP, packet.DestIP)
|
||||||
if c.OnPacket != nil {
|
if c.OnPacket != nil {
|
||||||
c.OnPacket(packet)
|
c.OnPacket(packet)
|
||||||
|
|||||||
Reference in New Issue
Block a user