feat: Add pcap import, file browser, logging, local capture, and stable call ordering

This commit is contained in:
Jose Luis Montañes Ojados
2026-01-19 14:28:56 +01:00
parent 3e5742d353
commit efb50ffc8e
19 changed files with 2660 additions and 45 deletions

View File

@@ -4,15 +4,27 @@ import (
"fmt" "fmt"
"os" "os"
"telephony-inspector/internal/logger"
"telephony-inspector/internal/tui" "telephony-inspector/internal/tui"
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
) )
func main() { func main() {
// Initialize logger
if err := logger.Init(); err != nil {
fmt.Fprintf(os.Stderr, "Warning: Could not initialize logger: %v\n", err)
}
defer logger.Close()
logger.Info("Starting Telephony Inspector")
p := tea.NewProgram(tui.NewModel(), tea.WithAltScreen()) p := tea.NewProgram(tui.NewModel(), tea.WithAltScreen())
if _, err := p.Run(); err != nil { if _, err := p.Run(); err != nil {
logger.Error("Program error: %v", err)
fmt.Fprintf(os.Stderr, "Error: %v\n", err) fmt.Fprintf(os.Stderr, "Error: %v\n", err)
os.Exit(1) os.Exit(1)
} }
logger.Info("Telephony Inspector exited normally")
} }

BIN
data/calls.pcap Normal file

Binary file not shown.

BIN
data/test.pcapng Normal file

Binary file not shown.

BIN
data/test2.pcap Normal file

Binary file not shown.

4
go.mod
View File

@@ -5,12 +5,15 @@ go 1.24.0
toolchain go1.24.12 toolchain go1.24.12
require ( require (
github.com/charmbracelet/bubbles v0.21.0
github.com/charmbracelet/bubbletea v1.3.10 github.com/charmbracelet/bubbletea v1.3.10
github.com/charmbracelet/lipgloss v1.1.0 github.com/charmbracelet/lipgloss v1.1.0
github.com/google/gopacket v1.1.19
golang.org/x/crypto v0.47.0 golang.org/x/crypto v0.47.0
) )
require ( require (
github.com/atotto/clipboard v0.1.4 // indirect
github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect
github.com/charmbracelet/x/ansi v0.10.1 // indirect github.com/charmbracelet/x/ansi v0.10.1 // indirect
@@ -25,6 +28,7 @@ require (
github.com/muesli/cancelreader v0.2.2 // indirect github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/termenv v0.16.0 // indirect github.com/muesli/termenv v0.16.0 // indirect
github.com/rivo/uniseg v0.4.7 // indirect github.com/rivo/uniseg v0.4.7 // indirect
github.com/sahilm/fuzzy v0.1.1 // indirect
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect
golang.org/x/sys v0.40.0 // indirect golang.org/x/sys v0.40.0 // indirect
golang.org/x/text v0.33.0 // indirect golang.org/x/text v0.33.0 // indirect

28
go.sum
View File

@@ -1,5 +1,11 @@
github.com/atotto/clipboard v0.1.4 h1:EH0zSVneZPSuFR11BlR9YppQTVDbh5+16AmcJi4g1z4=
github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/aymanbagabas/go-udiff v0.2.0 h1:TK0fH4MteXUDspT88n8CKzvK0X9O2xu9yQjWpi6yML8=
github.com/aymanbagabas/go-udiff v0.2.0/go.mod h1:RE4Ex0qsGkTAJoQdQQCA0uG+nAzJO/pI/QwceO5fgrA=
github.com/charmbracelet/bubbles v0.21.0 h1:9TdC97SdRVg/1aaXNVWfFH3nnLAwOXr8Fn6u6mfQdFs=
github.com/charmbracelet/bubbles v0.21.0/go.mod h1:HF+v6QUR4HkEpz62dx7ym2xc71/KBHg+zKwJtMw+qtg=
github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw= github.com/charmbracelet/bubbletea v1.3.10 h1:otUDHWMMzQSB0Pkc87rm691KZ3SWa4KUlvF9nRvCICw=
github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4= github.com/charmbracelet/bubbletea v1.3.10/go.mod h1:ORQfo0fk8U+po9VaNvnV95UPWA1BitP1E0N6xJPlHr4=
github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs= github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs=
@@ -10,10 +16,16 @@ github.com/charmbracelet/x/ansi v0.10.1 h1:rL3Koar5XvX0pHGfovN03f5cxLbCF2YvLeyz7
github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE= github.com/charmbracelet/x/ansi v0.10.1/go.mod h1:3RQDQ6lDnROptfpWuUVIUG64bD2g2BgntdxH0Ya5TeE=
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8= github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8=
github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs= github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs=
github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91 h1:payRxjMjKgx2PaCWLZ4p3ro9y97+TVLZNaRZgJwSVDQ=
github.com/charmbracelet/x/exp/golden v0.0.0-20241011142426-46044092ad91/go.mod h1:wDlXFlCrmJ8J+swcL/MnGUuYnqgQdW9rhSD61oNMb6U=
github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ=
github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4=
github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f/go.mod h1:vw97MGsxSvLiUE2X8qFplwetxpGLQrlU1Q9AUEIzCaM=
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY=
github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
@@ -31,17 +43,33 @@ github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ=
github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88=
github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA=
github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no=
github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8= golang.org/x/crypto v0.47.0 h1:V6e3FRj+n4dbpw86FJ8Fv7XVOql7TEwpHapKoMJ/GO8=
golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A= golang.org/x/crypto v0.47.0/go.mod h1:ff3Y9VzzKbwSSEzWqJsJVBnWmRwRSHt/6Op5n9bQc4A=
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E= golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561 h1:MDc5xs78ZrZr3HMQugiXOAkSZtfTpbJLDr/lwfgO53E=
golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE= golang.org/x/exp v0.0.0-20220909182711-5c715a9e8561/go.mod h1:cyybsKvd6eL0RnXn6p/Grxp8F5bW7iYuBgsNCOHpMYE=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.48.0 h1:zyQRTTrjc33Lhh0fBgT/H3oZq9WuvRR5gPC70xpDiQU=
golang.org/x/net v0.48.0/go.mod h1:+ndRgGjkh8FGtu1w1FGbEC31if4VrNVMuKTgcAAnQRY=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ= golang.org/x/sys v0.40.0 h1:DBZZqJ2Rkml6QMQsZywtnjnnGvHza6BTfYFWY9kjEWQ=
golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks= golang.org/x/sys v0.40.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY= golang.org/x/term v0.39.0 h1:RclSuaJf32jOqZz74CkPA9qFuVTX7vhLlpfj/IGWlqY=
golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww= golang.org/x/term v0.39.0/go.mod h1:yxzUCTP/U+FzoxfdKmLaA0RV1WgE0VY7hXBwKtY/4ww=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE= golang.org/x/text v0.33.0 h1:B3njUFyqtHDUI5jMn1YIr5B0IE2U0qck04r6d4KPAxE=
golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8= golang.org/x/text v0.33.0/go.mod h1:LuMebE6+rBincTi9+xWTY8TztLzKHc/9C1uBCG27+q8=
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

Binary file not shown.

180
internal/capture/local.go Normal file
View File

@@ -0,0 +1,180 @@
package capture
import (
"bufio"
"context"
"fmt"
"io"
"os/exec"
"strings"
"sync"
"telephony-inspector/internal/sip"
)
// LocalCapturer handles SIP packet capture locally via tcpdump
type LocalCapturer struct {
cmd *exec.Cmd
cancel context.CancelFunc
running bool
mu sync.Mutex
// Callbacks
OnPacket func(*sip.Packet)
OnError func(error)
}
// NewLocalCapturer creates a new local capturer
func NewLocalCapturer() *LocalCapturer {
return &LocalCapturer{}
}
// Start begins capturing SIP traffic locally
func (c *LocalCapturer) Start(iface string, port int) error {
c.mu.Lock()
if c.running {
c.mu.Unlock()
return fmt.Errorf("capture already running")
}
c.running = true
c.mu.Unlock()
ctx, cancel := context.WithCancel(context.Background())
c.cancel = cancel
// Build tcpdump command
// -l: line buffered
// -A: print packet payload in ASCII
// -s 0: capture full packets
args := []string{"-l", "-A", "-s", "0", "-i", iface, "port", fmt.Sprintf("%d", port)}
c.cmd = exec.CommandContext(ctx, "tcpdump", args...)
stdout, err := c.cmd.StdoutPipe()
if err != nil {
c.mu.Lock()
c.running = false
c.mu.Unlock()
return fmt.Errorf("failed to get stdout: %w", err)
}
stderr, err := c.cmd.StderrPipe()
if err != nil {
c.mu.Lock()
c.running = false
c.mu.Unlock()
return fmt.Errorf("failed to get stderr: %w", err)
}
if err := c.cmd.Start(); err != nil {
c.mu.Lock()
c.running = false
c.mu.Unlock()
return fmt.Errorf("failed to start tcpdump: %w", err)
}
// Process stdout in goroutine
go c.processStream(stdout)
// Log stderr
go c.processErrors(stderr)
return nil
}
// Stop stops the capture
func (c *LocalCapturer) Stop() {
c.mu.Lock()
defer c.mu.Unlock()
if !c.running {
return
}
c.running = false
if c.cancel != nil {
c.cancel()
c.cancel = nil
}
if c.cmd != nil && c.cmd.Process != nil {
c.cmd.Process.Kill()
c.cmd.Wait()
}
}
// IsRunning returns whether capture is active
func (c *LocalCapturer) IsRunning() bool {
c.mu.Lock()
defer c.mu.Unlock()
return c.running
}
// Close cleans up resources
func (c *LocalCapturer) Close() error {
c.Stop()
return nil
}
func (c *LocalCapturer) processStream(r io.Reader) {
scanner := bufio.NewScanner(r)
var buffer strings.Builder
inSIPMessage := false
for scanner.Scan() {
c.mu.Lock()
running := c.running
c.mu.Unlock()
if !running {
break
}
line := scanner.Text()
// Detect start of SIP message
if isSIPStart(line) {
// If we were building a message, parse it
if buffer.Len() > 0 {
c.parseAndEmit(buffer.String())
buffer.Reset()
}
inSIPMessage = true
}
if inSIPMessage {
buffer.WriteString(line)
buffer.WriteString("\r\n")
}
}
// Parse remaining buffer
if buffer.Len() > 0 {
c.parseAndEmit(buffer.String())
}
}
func (c *LocalCapturer) processErrors(r io.Reader) {
scanner := bufio.NewScanner(r)
for scanner.Scan() {
text := scanner.Text()
// tcpdump prints "listening on..." to stderr, ignore it
if strings.Contains(text, "listening on") {
continue
}
if c.OnError != nil {
c.OnError(fmt.Errorf("tcpdump: %s", text))
}
}
}
func (c *LocalCapturer) parseAndEmit(raw string) {
packet, err := sip.Parse(raw)
if err != nil {
if c.OnError != nil {
c.OnError(err)
}
return
}
if packet != nil && c.OnPacket != nil {
c.OnPacket(packet)
}
}

View File

@@ -0,0 +1,243 @@
package capture
import (
"fmt"
"os"
"telephony-inspector/internal/logger"
"telephony-inspector/internal/sip"
"github.com/google/gopacket"
"github.com/google/gopacket/layers"
"github.com/google/gopacket/pcap"
)
// PcapReader reads and parses pcap files
type PcapReader struct {
path string
handle *pcap.Handle
packets []*sip.Packet
}
// NewPcapReader creates a new pcap reader
func NewPcapReader(path string) *PcapReader {
logger.Info("PcapReader: Creating reader for %s", path)
return &PcapReader{
path: path,
packets: make([]*sip.Packet, 0),
}
}
// ReadAll reads all SIP packets from the pcap file
func (r *PcapReader) ReadAll() ([]*sip.Packet, error) {
logger.Info("PcapReader: Opening file %s", r.path)
// Check if file exists
if _, err := os.Stat(r.path); os.IsNotExist(err) {
logger.Error("PcapReader: File does not exist: %s", r.path)
return nil, fmt.Errorf("file does not exist: %s", r.path)
}
handle, err := pcap.OpenOffline(r.path)
if err != nil {
logger.Error("PcapReader: Failed to open pcap: %v", err)
return nil, fmt.Errorf("failed to open pcap: %w", err)
}
defer handle.Close()
logger.Info("PcapReader: File opened successfully, link type: %v", handle.LinkType())
// Try setting BPF filter (optional)
if err := handle.SetBPFFilter("port 5060 or port 5061"); err != nil {
logger.Warn("PcapReader: Could not set BPF filter: %v (continuing without filter)", err)
} else {
logger.Debug("PcapReader: BPF filter set for SIP ports")
}
packetSource := gopacket.NewPacketSource(handle, handle.LinkType())
totalPackets := 0
sipPackets := 0
for packet := range packetSource.Packets() {
totalPackets++
logger.Debug("PcapReader: Processing packet %d, layers: %v", totalPackets, packet.Layers())
sipPacket := r.extractSIPPacket(packet, totalPackets)
if sipPacket != nil {
sipPackets++
r.packets = append(r.packets, sipPacket)
logger.Info("PcapReader: Found SIP packet %d: %s %s", sipPackets,
func() string {
if sipPacket.IsRequest {
return string(sipPacket.Method)
} else {
return fmt.Sprintf("%d", sipPacket.StatusCode)
}
}(),
sipPacket.CallID)
}
}
logger.Info("PcapReader: Finished reading. Total packets: %d, SIP packets: %d", totalPackets, sipPackets)
return r.packets, nil
}
// extractSIPPacket extracts SIP data from a gopacket
func (r *PcapReader) extractSIPPacket(packet gopacket.Packet, packetNum int) *sip.Packet {
// Get network layer for IPs
var srcIP, dstIP string
var srcPort, dstPort int
var payload []byte
if ipLayer := packet.Layer(layers.LayerTypeIPv4); ipLayer != nil {
ip := ipLayer.(*layers.IPv4)
srcIP = ip.SrcIP.String()
dstIP = ip.DstIP.String()
logger.Debug("PcapReader: Packet %d IPv4 %s -> %s", packetNum, srcIP, dstIP)
} else if ipLayer := packet.Layer(layers.LayerTypeIPv6); ipLayer != nil {
ip := ipLayer.(*layers.IPv6)
srcIP = ip.SrcIP.String()
dstIP = ip.DstIP.String()
logger.Debug("PcapReader: Packet %d IPv6 %s -> %s", packetNum, srcIP, dstIP)
} else {
logger.Debug("PcapReader: Packet %d has no IP layer", packetNum)
}
// Get transport layer for ports AND payload
if udpLayer := packet.Layer(layers.LayerTypeUDP); udpLayer != nil {
udp := udpLayer.(*layers.UDP)
srcPort = int(udp.SrcPort)
dstPort = int(udp.DstPort)
payload = udp.Payload
logger.Debug("PcapReader: Packet %d UDP %d -> %d, payload len: %d", packetNum, srcPort, dstPort, len(payload))
} else if tcpLayer := packet.Layer(layers.LayerTypeTCP); tcpLayer != nil {
tcp := tcpLayer.(*layers.TCP)
srcPort = int(tcp.SrcPort)
dstPort = int(tcp.DstPort)
payload = tcp.Payload
logger.Debug("PcapReader: Packet %d TCP %d -> %d, payload len: %d", packetNum, srcPort, dstPort, len(payload))
} else {
logger.Debug("PcapReader: Packet %d has no TCP/UDP layer", packetNum)
return nil
}
if len(payload) == 0 {
logger.Debug("PcapReader: Packet %d has empty payload", packetNum)
return nil
}
payloadStr := string(payload)
// Log first 200 chars to see full SIP headers
preview := payloadStr
if len(preview) > 200 {
preview = preview[:200]
}
logger.Debug("PcapReader: Packet %d full payload preview: %q", packetNum, preview)
// Check if it looks like SIP
if !isSIPPayload(payloadStr) {
logger.Debug("PcapReader: Packet %d is not SIP", packetNum)
return nil
}
logger.Debug("PcapReader: Packet %d detected as SIP, parsing...", packetNum)
// Parse the SIP message
sipPacket, err := sip.Parse(payloadStr)
if err != nil {
logger.Warn("PcapReader: Packet %d SIP parse error: %v", packetNum, err)
return nil
}
if sipPacket == nil {
logger.Warn("PcapReader: Packet %d SIP parse returned nil", packetNum)
return nil
}
// Set network info
sipPacket.SourceIP = srcIP
sipPacket.SourcePort = srcPort
sipPacket.DestIP = dstIP
sipPacket.DestPort = dstPort
return sipPacket
}
// isSIPPayload checks if payload looks like a SIP message
func isSIPPayload(payload string) bool {
if len(payload) < 4 {
return false
}
// Check for SIP request methods
methods := []string{"INVITE ", "ACK ", "BYE ", "CANCEL ", "REGISTER ", "OPTIONS ",
"PRACK ", "SUBSCRIBE ", "NOTIFY ", "PUBLISH ", "INFO ", "REFER ", "MESSAGE ", "UPDATE "}
for _, m := range methods {
if len(payload) >= len(m) && payload[:len(m)] == m {
logger.Debug("isSIPPayload: Detected SIP method: %s", m[:len(m)-1])
return true
}
}
// Check for SIP response
if len(payload) >= 7 && payload[:7] == "SIP/2.0" {
logger.Debug("isSIPPayload: Detected SIP response")
return true
}
// Check if this looks like an SDP body (might be reassembled SIP)
if len(payload) >= 4 && payload[:4] == "v=0\r" {
logger.Debug("isSIPPayload: Detected SDP-only payload (no SIP headers)")
// This is SDP without SIP headers - likely a reassembly issue
// Log first 50 chars for debugging
preview := payload
if len(preview) > 50 {
preview = preview[:50]
}
logger.Debug("isSIPPayload: SDP payload: %q", preview)
return false
}
// Log what the payload starts with for debugging
preview := payload
if len(preview) > 20 {
preview = preview[:20]
}
logger.Debug("isSIPPayload: Unrecognized payload start: %q", preview)
return false
}
// GetPacketCount returns number of packets read
func (r *PcapReader) GetPacketCount() int {
return len(r.packets)
}
// Close closes the reader
func (r *PcapReader) Close() error {
if r.handle != nil {
r.handle.Close()
}
return nil
}
// ListPcapFiles lists .pcap files in a directory
func ListPcapFiles(dir string) ([]string, error) {
entries, err := os.ReadDir(dir)
if err != nil {
return nil, err
}
var files []string
for _, e := range entries {
if e.IsDir() {
continue
}
name := e.Name()
if len(name) > 5 && (name[len(name)-5:] == ".pcap" || name[len(name)-7:] == ".pcapng") {
files = append(files, name)
}
}
return files, nil
}

72
internal/config/loader.go Normal file
View File

@@ -0,0 +1,72 @@
package config
import (
"encoding/json"
"os"
)
// LoadNetworkMap loads a network map from a JSON file
func LoadNetworkMap(path string) (*NetworkMap, error) {
data, err := os.ReadFile(path)
if err != nil {
return nil, err
}
var nm NetworkMap
if err := json.Unmarshal(data, &nm); err != nil {
return nil, err
}
return &nm, nil
}
// SaveNetworkMap saves a network map to a JSON file
func SaveNetworkMap(nm *NetworkMap, path string) error {
data, err := json.MarshalIndent(nm, "", " ")
if err != nil {
return err
}
return os.WriteFile(path, data, 0644)
}
// DefaultNetworkMapPath returns a default path for the network map file
func DefaultNetworkMapPath() string {
return "network_map.json"
}
// CreateSampleNetworkMap creates a sample network map for testing
func CreateSampleNetworkMap() *NetworkMap {
nm := NewNetworkMap()
nm.AddNode(NetworkNode{
Name: "Asterisk PBX",
IP: "192.168.1.10",
Type: NodeTypePBX,
Description: "Main PBX server",
})
nm.AddNode(NetworkNode{
Name: "Kamailio Proxy",
IP: "192.168.1.20",
Type: NodeTypeProxy,
Aliases: []string{"10.0.0.20"},
Description: "SIP proxy/load balancer",
})
nm.AddNode(NetworkNode{
Name: "RTPEngine",
IP: "192.168.1.30",
Type: NodeTypeMediaServer,
Description: "Media relay server",
})
nm.AddNode(NetworkNode{
Name: "PSTN Gateway",
IP: "192.168.1.40",
Type: NodeTypeGateway,
Description: "Gateway to PSTN",
})
return nm
}

113
internal/logger/logger.go Normal file
View File

@@ -0,0 +1,113 @@
package logger
import (
"fmt"
"io"
"os"
"path/filepath"
"sync"
"time"
)
var (
instance *Logger
once sync.Once
)
// Logger handles application logging
type Logger struct {
file *os.File
mu sync.Mutex
path string
}
// Init initializes the logger with timestamp-based filename
func Init() error {
var err error
once.Do(func() {
// Create logs directory
logsDir := "logs"
if mkErr := os.MkdirAll(logsDir, 0755); mkErr != nil {
err = mkErr
return
}
// Create log file with timestamp
timestamp := time.Now().Format("2006-01-02_15-04-05")
filename := filepath.Join(logsDir, fmt.Sprintf("%s.log", timestamp))
f, openErr := os.Create(filename)
if openErr != nil {
err = openErr
return
}
instance = &Logger{
file: f,
path: filename,
}
Info("Logger initialized: %s", filename)
})
return err
}
// Close closes the logger
func Close() {
if instance != nil && instance.file != nil {
instance.file.Close()
}
}
// GetPath returns the log file path
func GetPath() string {
if instance != nil {
return instance.path
}
return ""
}
// log writes a log entry
func log(level, format string, args ...interface{}) {
if instance == nil {
return
}
instance.mu.Lock()
defer instance.mu.Unlock()
timestamp := time.Now().Format("15:04:05.000")
msg := fmt.Sprintf(format, args...)
line := fmt.Sprintf("[%s] [%s] %s\n", timestamp, level, msg)
instance.file.WriteString(line)
instance.file.Sync()
}
// Debug logs a debug message
func Debug(format string, args ...interface{}) {
log("DEBUG", format, args...)
}
// Info logs an info message
func Info(format string, args ...interface{}) {
log("INFO", format, args...)
}
// Warn logs a warning message
func Warn(format string, args ...interface{}) {
log("WARN", format, args...)
}
// Error logs an error message
func Error(format string, args ...interface{}) {
log("ERROR", format, args...)
}
// Writer returns an io.Writer that logs to the file
func Writer() io.Writer {
if instance != nil {
return instance.file
}
return os.Stdout
}

199
internal/sip/callflow.go Normal file
View File

@@ -0,0 +1,199 @@
package sip
import (
"sync"
"time"
)
// CallFlow represents a SIP call with all its packets
type CallFlow struct {
CallID string
Packets []*Packet
StartTime time.Time
EndTime time.Time
// Summary info
From string
To string
State CallState
}
// CallState represents the current state of a call
type CallState string
const (
CallStateInitial CallState = "Initial"
CallStateRinging CallState = "Ringing"
CallStateConnected CallState = "Connected"
CallStateTerminated CallState = "Terminated"
CallStateFailed CallState = "Failed"
)
// CallFlowStore stores and manages call flows
type CallFlowStore struct {
mu sync.RWMutex
flows map[string]*CallFlow
}
// NewCallFlowStore creates a new call flow store
func NewCallFlowStore() *CallFlowStore {
return &CallFlowStore{
flows: make(map[string]*CallFlow),
}
}
// AddPacket adds a packet to the appropriate call flow
func (s *CallFlowStore) AddPacket(p *Packet) *CallFlow {
s.mu.Lock()
defer s.mu.Unlock()
if p.CallID == "" {
return nil
}
flow, exists := s.flows[p.CallID]
if !exists {
flow = &CallFlow{
CallID: p.CallID,
Packets: make([]*Packet, 0),
StartTime: time.Now(),
From: p.From,
To: p.To,
State: CallStateInitial,
}
s.flows[p.CallID] = flow
}
flow.Packets = append(flow.Packets, p)
flow.EndTime = time.Now()
// Update call state based on packet
s.updateState(flow, p)
return flow
}
// updateState updates the call state based on the packet
func (s *CallFlowStore) updateState(flow *CallFlow, p *Packet) {
if p.IsRequest {
switch p.Method {
case MethodINVITE:
if flow.State == CallStateInitial {
flow.State = CallStateInitial
}
case MethodBYE, MethodCANCEL:
flow.State = CallStateTerminated
}
} else {
// Response
switch {
case p.StatusCode >= 100 && p.StatusCode < 200:
if p.StatusCode == 180 || p.StatusCode == 183 {
flow.State = CallStateRinging
}
case p.StatusCode >= 200 && p.StatusCode < 300:
flow.State = CallStateConnected
case p.StatusCode >= 400:
flow.State = CallStateFailed
}
}
}
// GetFlow returns a call flow by Call-ID
func (s *CallFlowStore) GetFlow(callID string) *CallFlow {
s.mu.RLock()
defer s.mu.RUnlock()
return s.flows[callID]
}
// GetAllFlows returns all call flows
func (s *CallFlowStore) GetAllFlows() []*CallFlow {
s.mu.RLock()
defer s.mu.RUnlock()
flows := make([]*CallFlow, 0, len(s.flows))
for _, f := range s.flows {
flows = append(flows, f)
}
return flows
}
// GetRecentFlows returns the N most recent call flows sorted by StartTime (oldest first)
func (s *CallFlowStore) GetRecentFlows(n int) []*CallFlow {
flows := s.GetAllFlows()
// Sort by start time ascending (oldest first), then by CallID for stable order
for i := 0; i < len(flows)-1; i++ {
for j := i + 1; j < len(flows); j++ {
// Compare by StartTime first
if flows[i].StartTime.After(flows[j].StartTime) {
flows[i], flows[j] = flows[j], flows[i]
} else if flows[i].StartTime.Equal(flows[j].StartTime) {
// If same time, sort by CallID for stable order
if flows[i].CallID > flows[j].CallID {
flows[i], flows[j] = flows[j], flows[i]
}
}
}
}
if len(flows) > n {
flows = flows[:n]
}
return flows
}
// Count returns the number of call flows
func (s *CallFlowStore) Count() int {
s.mu.RLock()
defer s.mu.RUnlock()
return len(s.flows)
}
// Summary returns a string summary of a packet for display
func (p *Packet) Summary() string {
if p.IsRequest {
return string(p.Method)
}
return formatStatusCode(p.StatusCode, p.StatusText)
}
func formatStatusCode(code int, text string) string {
if text != "" {
return text
}
switch code {
case 100:
return "100 Trying"
case 180:
return "180 Ringing"
case 183:
return "183 Session Progress"
case 200:
return "200 OK"
case 400:
return "400 Bad Request"
case 401:
return "401 Unauthorized"
case 403:
return "403 Forbidden"
case 404:
return "404 Not Found"
case 408:
return "408 Request Timeout"
case 480:
return "480 Temporarily Unavailable"
case 486:
return "486 Busy Here"
case 487:
return "487 Request Terminated"
case 488:
return "488 Not Acceptable Here"
case 500:
return "500 Server Internal Error"
case 503:
return "503 Service Unavailable"
default:
return string(rune('0'+code/100)) + "xx"
}
}

View File

@@ -0,0 +1,256 @@
package tui
import (
"os"
"path/filepath"
"sort"
"strings"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)
// FileBrowserModel handles file selection
type FileBrowserModel struct {
currentDir string
entries []os.DirEntry
selected int
filter string // file extension filter (e.g., ".pcap")
height int
offset int
// Results
selectedFile string
cancelled bool
err error
}
// NewFileBrowser creates a new file browser starting at dir
func NewFileBrowser(startDir string, filter string) FileBrowserModel {
if startDir == "" {
startDir, _ = os.Getwd()
}
fb := FileBrowserModel{
currentDir: startDir,
filter: filter,
height: 15,
}
fb.loadDir()
return fb
}
func (m *FileBrowserModel) loadDir() {
entries, err := os.ReadDir(m.currentDir)
if err != nil {
m.err = err
return
}
// Filter and sort entries
var filtered []os.DirEntry
for _, e := range entries {
if e.IsDir() {
filtered = append(filtered, e)
} else if m.filter == "" {
filtered = append(filtered, e)
} else {
name := strings.ToLower(e.Name())
if strings.HasSuffix(name, m.filter) || strings.HasSuffix(name, ".pcapng") {
filtered = append(filtered, e)
}
}
}
// Sort: directories first, then alphabetically
sort.Slice(filtered, func(i, j int) bool {
iDir := filtered[i].IsDir()
jDir := filtered[j].IsDir()
if iDir != jDir {
return iDir
}
return strings.ToLower(filtered[i].Name()) < strings.ToLower(filtered[j].Name())
})
m.entries = filtered
m.selected = 0
m.offset = 0
}
// Init initializes the model
func (m FileBrowserModel) Init() tea.Cmd {
return nil
}
// Update handles messages
func (m FileBrowserModel) Update(msg tea.Msg) (FileBrowserModel, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
case "esc", "q":
m.cancelled = true
return m, nil
case "up", "k":
if m.selected > 0 {
m.selected--
if m.selected < m.offset {
m.offset = m.selected
}
}
case "down", "j":
if m.selected < len(m.entries)-1 {
m.selected++
if m.selected >= m.offset+m.height {
m.offset = m.selected - m.height + 1
}
}
case "enter":
if len(m.entries) == 0 {
return m, nil
}
entry := m.entries[m.selected]
fullPath := filepath.Join(m.currentDir, entry.Name())
if entry.IsDir() {
m.currentDir = fullPath
m.loadDir()
} else {
m.selectedFile = fullPath
}
case "backspace", "h":
// Go to parent directory
parent := filepath.Dir(m.currentDir)
if parent != m.currentDir {
m.currentDir = parent
m.loadDir()
}
case "home":
home, err := os.UserHomeDir()
if err == nil {
m.currentDir = home
m.loadDir()
}
}
case tea.WindowSizeMsg:
m.height = msg.Height - 10
if m.height < 5 {
m.height = 5
}
}
return m, nil
}
// View renders the file browser
func (m FileBrowserModel) View() string {
titleStyle := lipgloss.NewStyle().
Bold(true).
Foreground(lipgloss.Color("#7D56F4")).
MarginBottom(1)
pathStyle := lipgloss.NewStyle().
Foreground(lipgloss.Color("#AFAFAF")).
MarginBottom(1)
dirStyle := lipgloss.NewStyle().
Foreground(lipgloss.Color("#8BE9FD"))
fileStyle := lipgloss.NewStyle().
Foreground(lipgloss.Color("#F8F8F2"))
selectedStyle := lipgloss.NewStyle().
Bold(true).
Background(lipgloss.Color("#44475A")).
Foreground(lipgloss.Color("#50FA7B"))
helpStyle := lipgloss.NewStyle().
Foreground(lipgloss.Color("#626262")).
MarginTop(1)
var b strings.Builder
b.WriteString(titleStyle.Render("📁 Select PCAP File"))
b.WriteString("\n")
b.WriteString(pathStyle.Render(m.currentDir))
b.WriteString("\n\n")
if m.err != nil {
b.WriteString(lipgloss.NewStyle().Foreground(lipgloss.Color("#FF5555")).Render("Error: " + m.err.Error()))
b.WriteString("\n")
}
if len(m.entries) == 0 {
b.WriteString("(empty directory)\n")
} else {
// Show entries with scrolling
end := m.offset + m.height
if end > len(m.entries) {
end = len(m.entries)
}
for i := m.offset; i < end; i++ {
entry := m.entries[i]
name := entry.Name()
var style lipgloss.Style
prefix := " "
if entry.IsDir() {
name = "📂 " + name + "/"
style = dirStyle
} else {
name = "📄 " + name
style = fileStyle
}
if i == m.selected {
prefix = "▶ "
style = selectedStyle
}
b.WriteString(prefix + style.Render(name) + "\n")
}
// Show scroll indicator
if len(m.entries) > m.height {
b.WriteString(pathStyle.Render(
strings.Repeat("─", 20) +
" " + string(rune('0'+m.offset/10)) + string(rune('0'+m.offset%10)) +
"/" + string(rune('0'+len(m.entries)/10)) + string(rune('0'+len(m.entries)%10)) + " " +
strings.Repeat("─", 20)))
b.WriteString("\n")
}
}
b.WriteString("\n")
b.WriteString(helpStyle.Render("↑/↓ navigate • Enter select/open • Backspace parent • Esc cancel"))
return b.String()
}
// IsSelected returns true if a file was selected
func (m FileBrowserModel) IsSelected() bool {
return m.selectedFile != ""
}
// IsCancelled returns true if cancelled
func (m FileBrowserModel) IsCancelled() bool {
return m.cancelled
}
// GetSelectedFile returns the selected file path
func (m FileBrowserModel) GetSelectedFile() string {
return m.selectedFile
}
// GetCurrentDir returns current directory
func (m FileBrowserModel) GetCurrentDir() string {
return m.currentDir
}

View File

@@ -2,8 +2,16 @@ package tui
import ( import (
"fmt" "fmt"
"telephony-inspector/internal/config" "strconv"
"strings"
"telephony-inspector/internal/capture"
"telephony-inspector/internal/config"
"telephony-inspector/internal/sip"
internalSSH "telephony-inspector/internal/ssh"
"github.com/charmbracelet/bubbles/list"
"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea" tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss" "github.com/charmbracelet/lipgloss"
) )
@@ -18,9 +26,31 @@ const (
ViewNetworkMap ViewNetworkMap
) )
// SubView for modal states
type SubView int
const (
SubViewNone SubView = iota
SubViewSSHConfig
SubViewAddNode
SubViewCallDetail
SubViewCaptureMenu
SubViewFileBrowser
)
// CaptureMode defines local vs SSH capture
type CaptureMode int
const (
CaptureModeNone CaptureMode = iota
CaptureModeLocal
CaptureModeSSH
)
// Model holds the application state // Model holds the application state
type Model struct { type Model struct {
currentView View currentView View
subView SubView
width int width int
height int height int
@@ -28,9 +58,29 @@ type Model struct {
networkMap *config.NetworkMap networkMap *config.NetworkMap
// Capture state // Capture state
capturing bool captureMode CaptureMode
packetCount int sshConfig SSHConfigModel
lastPackets []string // Last N packet summaries capturer *capture.Capturer
localCapturer *capture.LocalCapturer
connected bool
capturing bool
packetCount int
lastPackets []string
captureError string
captureIface string
// Call flow analysis
callFlowStore *sip.CallFlowStore
selectedFlow int
flowList list.Model
// File browser for pcap import
fileBrowser FileBrowserModel
loadedPcapPath string
// Network node input
nodeInput []textinput.Model
nodeInputFocus int
// Style definitions // Style definitions
styles Styles styles Styles
@@ -44,6 +94,11 @@ type Styles struct {
Inactive lipgloss.Style Inactive lipgloss.Style
Help lipgloss.Style Help lipgloss.Style
StatusBar lipgloss.Style StatusBar lipgloss.Style
Error lipgloss.Style
Success lipgloss.Style
Box lipgloss.Style
PacketRow lipgloss.Style
CallFlow lipgloss.Style
} }
func defaultStyles() Styles { func defaultStyles() Styles {
@@ -66,17 +121,67 @@ func defaultStyles() Styles {
Background(lipgloss.Color("#7D56F4")). Background(lipgloss.Color("#7D56F4")).
Foreground(lipgloss.Color("#FFFFFF")). Foreground(lipgloss.Color("#FFFFFF")).
Padding(0, 1), Padding(0, 1),
Error: lipgloss.NewStyle().
Foreground(lipgloss.Color("#FF5555")),
Success: lipgloss.NewStyle().
Foreground(lipgloss.Color("#50FA7B")),
Box: lipgloss.NewStyle().
Border(lipgloss.RoundedBorder()).
BorderForeground(lipgloss.Color("#7D56F4")).
Padding(1, 2),
PacketRow: lipgloss.NewStyle().
Foreground(lipgloss.Color("#F8F8F2")),
CallFlow: lipgloss.NewStyle().
Border(lipgloss.NormalBorder()).
BorderForeground(lipgloss.Color("#44475A")).
Padding(0, 1),
} }
} }
// NewModel creates a new TUI model with default values // NewModel creates a new TUI model with default values
func NewModel() Model { func NewModel() Model {
return Model{ // Try to load existing network map
currentView: ViewDashboard, nm, err := config.LoadNetworkMap(config.DefaultNetworkMapPath())
networkMap: config.NewNetworkMap(), if err != nil {
lastPackets: make([]string, 0, 20), nm = config.NewNetworkMap()
styles: defaultStyles(),
} }
return Model{
currentView: ViewDashboard,
subView: SubViewNone,
networkMap: nm,
callFlowStore: sip.NewCallFlowStore(),
lastPackets: make([]string, 0, 50),
sshConfig: NewSSHConfigModel(),
nodeInput: createNodeInputs(),
styles: defaultStyles(),
}
}
func createNodeInputs() []textinput.Model {
inputs := make([]textinput.Model, 4)
inputs[0] = textinput.New()
inputs[0].Placeholder = "Node Name"
inputs[0].Prompt = "Name: "
inputs[0].CharLimit = 64
inputs[1] = textinput.New()
inputs[1].Placeholder = "192.168.1.x"
inputs[1].Prompt = "IP: "
inputs[1].CharLimit = 45
inputs[2] = textinput.New()
inputs[2].Placeholder = "PBX/Proxy/MediaServer/Gateway"
inputs[2].Prompt = "Type: "
inputs[2].CharLimit = 20
inputs[3] = textinput.New()
inputs[3].Placeholder = "Optional description"
inputs[3].Prompt = "Desc: "
inputs[3].CharLimit = 256
return inputs
} }
// Init initializes the model // Init initializes the model
@@ -84,12 +189,30 @@ func (m Model) Init() tea.Cmd {
return nil return nil
} }
// PacketMsg is sent when a new packet is received
type PacketMsg struct {
Packet *sip.Packet
}
// ErrorMsg is sent when an error occurs
type ErrorMsg struct {
Error error
}
// Update handles messages and updates the model // Update handles messages and updates the model
func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) { func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
var cmd tea.Cmd
// Handle subview updates first
if m.subView != SubViewNone {
return m.updateSubView(msg)
}
switch msg := msg.(type) { switch msg := msg.(type) {
case tea.KeyMsg: case tea.KeyMsg:
switch msg.String() { switch msg.String() {
case "q", "ctrl+c": case "q", "ctrl+c":
m.cleanup()
return m, tea.Quit return m, tea.Quit
case "1": case "1":
m.currentView = ViewDashboard m.currentView = ViewDashboard
@@ -99,18 +222,336 @@ func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
m.currentView = ViewAnalysis m.currentView = ViewAnalysis
case "4": case "4":
m.currentView = ViewNetworkMap m.currentView = ViewNetworkMap
default:
cmd = m.handleViewKeys(msg)
} }
case tea.WindowSizeMsg: case tea.WindowSizeMsg:
m.width = msg.Width m.width = msg.Width
m.height = msg.Height m.height = msg.Height
case PacketMsg:
m.packetCount++
summary := formatPacketSummary(msg.Packet, m.networkMap)
m.lastPackets = append(m.lastPackets, summary)
if len(m.lastPackets) > 50 {
m.lastPackets = m.lastPackets[1:]
}
m.callFlowStore.AddPacket(msg.Packet)
case ErrorMsg:
m.captureError = msg.Error.Error()
}
return m, cmd
}
func (m *Model) handleViewKeys(msg tea.KeyMsg) tea.Cmd {
switch m.currentView {
case ViewCapture:
switch msg.String() {
case "c":
// Show capture mode menu if not capturing
if !m.capturing && m.captureMode == CaptureModeNone {
m.subView = SubViewCaptureMenu
}
case "l":
// Start local capture directly
if !m.capturing {
m.captureMode = CaptureModeLocal
m.captureIface = "any"
return m.startLocalCapture()
}
case "r":
// SSH remote capture
if !m.capturing {
m.subView = SubViewSSHConfig
m.sshConfig = NewSSHConfigModel()
return m.sshConfig.Init()
}
case "s":
if m.capturing {
m.stopCapture()
} else if m.captureMode != CaptureModeNone {
if m.captureMode == CaptureModeLocal {
return m.startLocalCapture()
} else if m.connected {
return m.startSSHCapture()
}
}
case "d":
m.disconnect()
}
case ViewAnalysis:
switch msg.String() {
case "up", "k":
if m.selectedFlow > 0 {
m.selectedFlow--
}
case "down", "j":
flows := m.callFlowStore.GetRecentFlows(20)
if m.selectedFlow < len(flows)-1 {
m.selectedFlow++
}
case "enter":
m.subView = SubViewCallDetail
}
case ViewNetworkMap:
switch msg.String() {
case "a":
m.subView = SubViewAddNode
m.nodeInput = createNodeInputs()
m.nodeInput[0].Focus()
m.nodeInputFocus = 0
case "l":
if nm, err := config.LoadNetworkMap(config.DefaultNetworkMapPath()); err == nil {
m.networkMap = nm
}
case "s":
config.SaveNetworkMap(m.networkMap, config.DefaultNetworkMapPath())
case "g":
m.networkMap = config.CreateSampleNetworkMap()
}
}
return nil
}
func (m *Model) updateSubView(msg tea.Msg) (tea.Model, tea.Cmd) {
switch m.subView {
case SubViewCaptureMenu:
if keyMsg, ok := msg.(tea.KeyMsg); ok {
switch keyMsg.String() {
case "l", "1":
m.captureMode = CaptureModeLocal
m.captureIface = "any"
m.subView = SubViewNone
return m, m.startLocalCapture()
case "r", "2":
m.subView = SubViewSSHConfig
m.sshConfig = NewSSHConfigModel()
return m, m.sshConfig.Init()
case "p", "3":
// Open file browser for pcap
m.fileBrowser = NewFileBrowser("", ".pcap")
m.subView = SubViewFileBrowser
return m, nil
case "esc", "q":
m.subView = SubViewNone
}
}
return m, nil
case SubViewFileBrowser:
var cmd tea.Cmd
m.fileBrowser, cmd = m.fileBrowser.Update(msg)
if m.fileBrowser.IsSelected() {
// Load the pcap file
pcapPath := m.fileBrowser.GetSelectedFile()
m.loadedPcapPath = pcapPath
m.subView = SubViewNone
// Load packets from pcap
reader := capture.NewPcapReader(pcapPath)
packets, err := reader.ReadAll()
if err != nil {
m.captureError = err.Error()
} else {
m.captureError = ""
m.packetCount = len(packets)
for _, pkt := range packets {
m.callFlowStore.AddPacket(pkt)
summary := formatPacketSummary(pkt, m.networkMap)
m.lastPackets = append(m.lastPackets, summary)
}
}
return m, nil
} else if m.fileBrowser.IsCancelled() {
m.subView = SubViewNone
}
return m, cmd
case SubViewSSHConfig:
var cmd tea.Cmd
m.sshConfig, cmd = m.sshConfig.Update(msg)
if m.sshConfig.IsSubmitted() {
host, port, user, password := m.sshConfig.GetConfig()
portInt, _ := strconv.Atoi(port)
if portInt == 0 {
portInt = 22
}
cfg := internalSSH.Config{
Host: host,
Port: portInt,
User: user,
Password: password,
}
m.capturer = capture.NewCapturer(cfg)
if err := m.capturer.Connect(); err != nil {
m.captureError = err.Error()
} else {
m.connected = true
m.captureMode = CaptureModeSSH
m.captureError = ""
}
m.subView = SubViewNone
} else if m.sshConfig.IsCancelled() {
m.subView = SubViewNone
}
return m, cmd
case SubViewAddNode:
return m.updateNodeInput(msg)
case SubViewCallDetail:
if keyMsg, ok := msg.(tea.KeyMsg); ok {
if keyMsg.String() == "esc" || keyMsg.String() == "q" {
m.subView = SubViewNone
}
}
return m, nil
} }
return m, nil return m, nil
} }
func (m *Model) updateNodeInput(msg tea.Msg) (tea.Model, tea.Cmd) {
if keyMsg, ok := msg.(tea.KeyMsg); ok {
switch keyMsg.String() {
case "esc":
m.subView = SubViewNone
return m, nil
case "tab", "down":
m.nodeInput[m.nodeInputFocus].Blur()
m.nodeInputFocus = (m.nodeInputFocus + 1) % len(m.nodeInput)
return m, m.nodeInput[m.nodeInputFocus].Focus()
case "shift+tab", "up":
m.nodeInput[m.nodeInputFocus].Blur()
m.nodeInputFocus--
if m.nodeInputFocus < 0 {
m.nodeInputFocus = len(m.nodeInput) - 1
}
return m, m.nodeInput[m.nodeInputFocus].Focus()
case "enter":
if m.nodeInputFocus == len(m.nodeInput)-1 {
// Submit
name := m.nodeInput[0].Value()
ip := m.nodeInput[1].Value()
nodeType := m.nodeInput[2].Value()
desc := m.nodeInput[3].Value()
if name != "" && ip != "" {
m.networkMap.AddNode(config.NetworkNode{
Name: name,
IP: ip,
Type: config.NodeType(nodeType),
Description: desc,
})
}
m.subView = SubViewNone
return m, nil
}
m.nodeInput[m.nodeInputFocus].Blur()
m.nodeInputFocus++
return m, m.nodeInput[m.nodeInputFocus].Focus()
}
}
var cmd tea.Cmd
m.nodeInput[m.nodeInputFocus], cmd = m.nodeInput[m.nodeInputFocus].Update(msg)
return m, cmd
}
func (m *Model) startLocalCapture() tea.Cmd {
m.capturing = true
m.captureError = ""
m.packetCount = 0
m.lastPackets = m.lastPackets[:0]
m.captureMode = CaptureModeLocal
m.localCapturer = capture.NewLocalCapturer()
m.localCapturer.OnPacket = func(p *sip.Packet) {
// Note: In real implementation, use channel + tea.Cmd
}
m.localCapturer.OnError = func(err error) {
m.captureError = err.Error()
}
iface := m.captureIface
if iface == "" {
iface = "any"
}
if err := m.localCapturer.Start(iface, 5060); err != nil {
m.captureError = err.Error()
m.capturing = false
}
return nil
}
func (m *Model) startSSHCapture() tea.Cmd {
m.capturing = true
m.captureError = ""
m.packetCount = 0
m.lastPackets = m.lastPackets[:0]
m.capturer.OnPacket = func(p *sip.Packet) {
// Note: In real implementation, use channel + tea.Cmd
}
m.capturer.OnError = func(err error) {
m.captureError = err.Error()
}
if err := m.capturer.Start("any", 5060); err != nil {
m.captureError = err.Error()
m.capturing = false
}
return nil
}
func (m *Model) stopCapture() {
if m.localCapturer != nil {
m.localCapturer.Stop()
}
if m.capturer != nil {
m.capturer.Stop()
}
m.capturing = false
}
func (m *Model) disconnect() {
m.stopCapture()
if m.localCapturer != nil {
m.localCapturer.Close()
m.localCapturer = nil
}
if m.capturer != nil {
m.capturer.Close()
m.capturer = nil
}
m.connected = false
m.captureMode = CaptureModeNone
}
func (m *Model) cleanup() {
m.disconnect()
}
// View renders the TUI // View renders the TUI
func (m Model) View() string { func (m Model) View() string {
// Handle subview modals
if m.subView != SubViewNone {
return m.renderSubView()
}
var content string var content string
switch m.currentView { switch m.currentView {
@@ -124,15 +565,94 @@ func (m Model) View() string {
content = m.viewNetworkMap() content = m.viewNetworkMap()
} }
// Navigation bar
nav := m.renderNav() nav := m.renderNav()
status := m.renderStatusBar()
// Status bar
status := m.styles.StatusBar.Render(" Telephony Inspector v0.1.0 ")
return lipgloss.JoinVertical(lipgloss.Left, nav, content, status) return lipgloss.JoinVertical(lipgloss.Left, nav, content, status)
} }
func (m Model) renderSubView() string {
switch m.subView {
case SubViewCaptureMenu:
return m.styles.Box.Render(m.renderCaptureMenu())
case SubViewFileBrowser:
return m.styles.Box.Render(m.fileBrowser.View())
case SubViewSSHConfig:
return m.styles.Box.Render(m.sshConfig.View())
case SubViewAddNode:
return m.styles.Box.Render(m.renderAddNodeForm())
case SubViewCallDetail:
return m.renderCallDetail()
}
return ""
}
func (m Model) renderCaptureMenu() string {
var b strings.Builder
b.WriteString(m.styles.Title.Render("📡 Select Capture Mode"))
b.WriteString("\n\n")
b.WriteString(" [1] [L]ocal - Capture on this machine (requires tcpdump)\n")
b.WriteString(" [2] [R]emote - Capture via SSH on remote server\n")
b.WriteString(" [3] [P]cap - Import pcap file from disk\n")
b.WriteString("\n")
b.WriteString(m.styles.Help.Render("Press 1/L, 2/R, or 3/P to select • Esc to cancel"))
return b.String()
}
func (m Model) renderAddNodeForm() string {
var b strings.Builder
b.WriteString(m.styles.Title.Render(" Add Network Node"))
b.WriteString("\n\n")
for _, input := range m.nodeInput {
b.WriteString(input.View())
b.WriteString("\n")
}
b.WriteString("\n")
b.WriteString(m.styles.Help.Render("Tab navigate • Enter submit • Esc cancel"))
return b.String()
}
func (m Model) renderCallDetail() string {
flows := m.callFlowStore.GetRecentFlows(20)
if m.selectedFlow >= len(flows) || len(flows) == 0 {
return m.styles.Box.Render("No call selected\n\nPress Esc to go back")
}
flow := flows[m.selectedFlow]
var b strings.Builder
b.WriteString(m.styles.Title.Render("📞 Call Detail"))
b.WriteString("\n\n")
b.WriteString(fmt.Sprintf("Call-ID: %s\n", flow.CallID))
b.WriteString(fmt.Sprintf("From: %s\n", flow.From))
b.WriteString(fmt.Sprintf("To: %s\n", flow.To))
b.WriteString(fmt.Sprintf("State: %s\n", flow.State))
b.WriteString(fmt.Sprintf("Packets: %d\n\n", len(flow.Packets)))
b.WriteString("Transaction Flow:\n")
for i, pkt := range flow.Packets {
arrow := "→"
if !pkt.IsRequest {
arrow = "←"
}
b.WriteString(fmt.Sprintf(" %d. %s %s\n", i+1, arrow, pkt.Summary()))
// Show SDP info if present
if pkt.SDP != nil {
mediaIP := pkt.SDP.GetSDPMediaIP()
if mediaIP != "" {
label := m.networkMap.LabelForIP(mediaIP)
b.WriteString(fmt.Sprintf(" SDP Media: %s\n", label))
}
}
}
b.WriteString("\n")
b.WriteString(m.styles.Help.Render("Press Esc to go back"))
return m.styles.Box.Render(b.String())
}
func (m Model) renderNav() string { func (m Model) renderNav() string {
tabs := []string{"[1] Dashboard", "[2] Capture", "[3] Analysis", "[4] Network Map"} tabs := []string{"[1] Dashboard", "[2] Capture", "[3] Analysis", "[4] Network Map"}
var rendered []string var rendered []string
@@ -148,52 +668,163 @@ func (m Model) renderNav() string {
return lipgloss.JoinHorizontal(lipgloss.Top, rendered...) + "\n" return lipgloss.JoinHorizontal(lipgloss.Top, rendered...) + "\n"
} }
func (m Model) renderStatusBar() string {
var parts []string
parts = append(parts, " Telephony Inspector v0.1.0 ")
if m.connected {
parts = append(parts, m.styles.Success.Render(" SSH: Connected "))
}
if m.capturing {
parts = append(parts, m.styles.Active.Render(fmt.Sprintf(" Capturing: %d pkts ", m.packetCount)))
}
if m.captureError != "" {
parts = append(parts, m.styles.Error.Render(" Error: "+m.captureError+" "))
}
return m.styles.StatusBar.Render(strings.Join(parts, "|"))
}
func (m Model) viewDashboard() string { func (m Model) viewDashboard() string {
title := m.styles.Title.Render("📞 Dashboard") title := m.styles.Title.Render("📞 Dashboard")
info := lipgloss.JoinVertical(lipgloss.Left, var stats []string
m.styles.Subtitle.Render("SIP Telephony Inspector"), stats = append(stats, m.styles.Subtitle.Render("SIP Telephony Inspector"))
"", stats = append(stats, "")
"• Capture SIP traffic via SSH + tcpdump",
"• Analyze SIP/SDP packets in real-time",
"• Map network topology for better debugging",
"",
m.styles.Help.Render("Press 1-4 to navigate, q to quit"),
)
return lipgloss.JoinVertical(lipgloss.Left, title, info) if m.connected {
stats = append(stats, m.styles.Success.Render("✓ SSH Connected"))
} else {
stats = append(stats, m.styles.Inactive.Render("○ SSH Disconnected"))
}
stats = append(stats, fmt.Sprintf("Network Nodes: %d", len(m.networkMap.Nodes)))
stats = append(stats, fmt.Sprintf("Active Calls: %d", m.callFlowStore.Count()))
stats = append(stats, fmt.Sprintf("Packets Captured: %d", m.packetCount))
stats = append(stats, "")
stats = append(stats, "Quick Start:")
stats = append(stats, " 1. Go to [2] Capture → Press 'c' to connect SSH")
stats = append(stats, " 2. Press 's' to start capturing SIP traffic")
stats = append(stats, " 3. Go to [3] Analysis to view call flows")
stats = append(stats, " 4. Go to [4] Network Map to label IPs")
stats = append(stats, "")
stats = append(stats, m.styles.Help.Render("Press 1-4 to navigate, q to quit"))
return lipgloss.JoinVertical(lipgloss.Left, title, lipgloss.JoinVertical(lipgloss.Left, stats...))
} }
func (m Model) viewCapture() string { func (m Model) viewCapture() string {
title := m.styles.Title.Render("🔍 Capture") title := m.styles.Title.Render("🔍 Capture")
status := "Status: " var lines []string
if m.capturing {
status += m.styles.Active.Render("● Capturing") // Mode indicator
} else { switch m.captureMode {
status += m.styles.Inactive.Render("○ Stopped") case CaptureModeLocal:
lines = append(lines, m.styles.Success.Render("● Mode: Local capture"))
case CaptureModeSSH:
if m.connected {
lines = append(lines, m.styles.Success.Render("● Mode: SSH (connected)"))
} else {
lines = append(lines, m.styles.Inactive.Render("○ Mode: SSH (disconnected)"))
}
default:
lines = append(lines, m.styles.Inactive.Render("○ No capture mode selected"))
} }
packetInfo := fmt.Sprintf("Packets captured: %d", m.packetCount) // Capture status
if m.capturing {
mode := "local"
if m.captureMode == CaptureModeSSH {
mode = "SSH"
}
lines = append(lines, m.styles.Active.Render(fmt.Sprintf("● Capturing on port 5060 (%s)", mode)))
} else if m.captureMode != CaptureModeNone {
lines = append(lines, m.styles.Inactive.Render("○ Capture stopped"))
}
help := m.styles.Help.Render("[c] Connect SSH [s] Start/Stop Capture [q] Quit") lines = append(lines, fmt.Sprintf("Packets: %d", m.packetCount))
lines = append(lines, "")
return lipgloss.JoinVertical(lipgloss.Left, title, status, packetInfo, "", help) // Last packets
if len(m.lastPackets) > 0 {
lines = append(lines, "Recent Packets:")
start := 0
if len(m.lastPackets) > 15 {
start = len(m.lastPackets) - 15
}
for _, pkt := range m.lastPackets[start:] {
lines = append(lines, " "+pkt)
}
}
lines = append(lines, "")
// Help
var help string
if m.captureMode == CaptureModeNone {
help = "[c] Choose mode [l] Local [r] Remote SSH [q] Quit"
} else if !m.capturing {
help = "[s] Start [c] Change mode [d] Disconnect [q] Quit"
} else {
help = "[s] Stop [d] Disconnect [q] Quit"
}
lines = append(lines, m.styles.Help.Render(help))
return lipgloss.JoinVertical(lipgloss.Left, title, lipgloss.JoinVertical(lipgloss.Left, lines...))
} }
func (m Model) viewAnalysis() string { func (m Model) viewAnalysis() string {
title := m.styles.Title.Render("📊 Analysis") title := m.styles.Title.Render("📊 Analysis")
content := lipgloss.JoinVertical(lipgloss.Left, flows := m.callFlowStore.GetRecentFlows(20)
"Call flows will appear here once packets are captured.",
"",
"Features:",
"• Group packets by Call-ID",
"• Visualize SIP transaction flow",
"• Decode SDP offers/answers",
)
return lipgloss.JoinVertical(lipgloss.Left, title, content) if len(flows) == 0 {
return lipgloss.JoinVertical(lipgloss.Left, title,
"No calls captured yet.",
"",
"Start capturing on the Capture tab to see call flows here.",
"",
m.styles.Help.Render("Press 2 to go to Capture"))
}
var lines []string
lines = append(lines, fmt.Sprintf("Calls: %d", len(flows)))
lines = append(lines, "")
for i, flow := range flows {
prefix := " "
style := m.styles.Inactive
if i == m.selectedFlow {
prefix = "▶ "
style = m.styles.Active
}
stateIcon := "○"
switch flow.State {
case sip.CallStateRinging:
stateIcon = "◐"
case sip.CallStateConnected:
stateIcon = "●"
case sip.CallStateTerminated:
stateIcon = "◯"
case sip.CallStateFailed:
stateIcon = "✕"
}
summary := fmt.Sprintf("%s%s %s → %s [%d pkts]",
prefix, stateIcon,
truncate(extractUser(flow.From), 15),
truncate(extractUser(flow.To), 15),
len(flow.Packets))
lines = append(lines, style.Render(summary))
}
lines = append(lines, "")
lines = append(lines, m.styles.Help.Render("↑/↓ select • Enter details • q quit"))
return lipgloss.JoinVertical(lipgloss.Left, title, lipgloss.JoinVertical(lipgloss.Left, lines...))
} }
func (m Model) viewNetworkMap() string { func (m Model) viewNetworkMap() string {
@@ -203,14 +834,71 @@ func (m Model) viewNetworkMap() string {
return lipgloss.JoinVertical(lipgloss.Left, title, return lipgloss.JoinVertical(lipgloss.Left, title,
"No network nodes configured.", "No network nodes configured.",
"", "",
m.styles.Help.Render("[a] Add node [l] Load from file"), "Add nodes to label IPs in your SIP infrastructure.",
) "",
m.styles.Help.Render("[a] Add node [l] Load file [g] Generate sample"))
} }
var nodes []string var lines []string
for _, node := range m.networkMap.Nodes { for _, node := range m.networkMap.Nodes {
nodes = append(nodes, fmt.Sprintf("• %s (%s): %s", node.Name, node.Type, node.IP)) icon := "○"
switch node.Type {
case config.NodeTypePBX:
icon = "☎"
case config.NodeTypeProxy:
icon = "⇄"
case config.NodeTypeMediaServer:
icon = "♪"
case config.NodeTypeGateway:
icon = "⬚"
}
line := fmt.Sprintf(" %s %s (%s): %s", icon, node.Name, node.Type, node.IP)
if node.Description != "" {
line += " - " + node.Description
}
lines = append(lines, line)
} }
return lipgloss.JoinVertical(lipgloss.Left, title, lipgloss.JoinVertical(lipgloss.Left, nodes...)) lines = append(lines, "")
lines = append(lines, m.styles.Help.Render("[a] Add [s] Save [l] Load [g] Sample [q] Quit"))
return lipgloss.JoinVertical(lipgloss.Left, title, lipgloss.JoinVertical(lipgloss.Left, lines...))
}
// Helper functions
func formatPacketSummary(p *sip.Packet, nm *config.NetworkMap) string {
src := nm.LabelForIP(p.SourceIP)
dst := nm.LabelForIP(p.DestIP)
if p.IsRequest {
return fmt.Sprintf("%s → %s: %s", src, dst, p.Method)
}
return fmt.Sprintf("%s → %s: %d %s", src, dst, p.StatusCode, p.StatusText)
}
func truncate(s string, max int) string {
if len(s) <= max {
return s
}
return s[:max-1] + "…"
}
func extractUser(sipAddr string) string {
// Extract user from "Display Name" <sip:user@host>
if idx := strings.Index(sipAddr, "<sip:"); idx >= 0 {
start := idx + 5
end := strings.Index(sipAddr[start:], "@")
if end > 0 {
return sipAddr[start : start+end]
}
}
if idx := strings.Index(sipAddr, "sip:"); idx >= 0 {
start := idx + 4
end := strings.Index(sipAddr[start:], "@")
if end > 0 {
return sipAddr[start : start+end]
}
}
return sipAddr
} }

180
internal/tui/ssh_config.go Normal file
View File

@@ -0,0 +1,180 @@
package tui
import (
"strings"
"github.com/charmbracelet/bubbles/textinput"
tea "github.com/charmbracelet/bubbletea"
"github.com/charmbracelet/lipgloss"
)
// SSHConfigModel handles SSH connection input
type SSHConfigModel struct {
inputs []textinput.Model
focusIndex int
submitted bool
cancelled bool
// Parsed values
Host string
Port string
User string
Password string
}
const (
inputHost = iota
inputPort
inputUser
inputPassword
)
// NewSSHConfigModel creates a new SSH config input model
func NewSSHConfigModel() SSHConfigModel {
inputs := make([]textinput.Model, 4)
// Host input
inputs[inputHost] = textinput.New()
inputs[inputHost].Placeholder = "192.168.1.100"
inputs[inputHost].Focus()
inputs[inputHost].CharLimit = 256
inputs[inputHost].Width = 30
inputs[inputHost].Prompt = "Host: "
// Port input
inputs[inputPort] = textinput.New()
inputs[inputPort].Placeholder = "22"
inputs[inputPort].CharLimit = 5
inputs[inputPort].Width = 10
inputs[inputPort].Prompt = "Port: "
inputs[inputPort].SetValue("22")
// User input
inputs[inputUser] = textinput.New()
inputs[inputUser].Placeholder = "root"
inputs[inputUser].CharLimit = 64
inputs[inputUser].Width = 20
inputs[inputUser].Prompt = "User: "
// Password input
inputs[inputPassword] = textinput.New()
inputs[inputPassword].Placeholder = "password"
inputs[inputPassword].CharLimit = 128
inputs[inputPassword].Width = 30
inputs[inputPassword].Prompt = "Password: "
inputs[inputPassword].EchoMode = textinput.EchoPassword
inputs[inputPassword].EchoCharacter = '•'
return SSHConfigModel{
inputs: inputs,
focusIndex: 0,
}
}
// Init initializes the model
func (m SSHConfigModel) Init() tea.Cmd {
return textinput.Blink
}
// Update handles messages
func (m SSHConfigModel) Update(msg tea.Msg) (SSHConfigModel, tea.Cmd) {
switch msg := msg.(type) {
case tea.KeyMsg:
switch msg.String() {
case "ctrl+c", "esc":
m.cancelled = true
return m, nil
case "tab", "down":
m.focusIndex++
if m.focusIndex >= len(m.inputs) {
m.focusIndex = 0
}
return m, m.updateFocus()
case "shift+tab", "up":
m.focusIndex--
if m.focusIndex < 0 {
m.focusIndex = len(m.inputs) - 1
}
return m, m.updateFocus()
case "enter":
if m.focusIndex == len(m.inputs)-1 {
// Submit on last field
m.submitted = true
m.Host = m.inputs[inputHost].Value()
m.Port = m.inputs[inputPort].Value()
m.User = m.inputs[inputUser].Value()
m.Password = m.inputs[inputPassword].Value()
return m, nil
}
// Move to next field
m.focusIndex++
return m, m.updateFocus()
}
}
// Update focused input
cmd := m.updateInputs(msg)
return m, cmd
}
func (m *SSHConfigModel) updateFocus() tea.Cmd {
cmds := make([]tea.Cmd, len(m.inputs))
for i := range m.inputs {
if i == m.focusIndex {
cmds[i] = m.inputs[i].Focus()
} else {
m.inputs[i].Blur()
}
}
return tea.Batch(cmds...)
}
func (m *SSHConfigModel) updateInputs(msg tea.Msg) tea.Cmd {
cmds := make([]tea.Cmd, len(m.inputs))
for i := range m.inputs {
m.inputs[i], cmds[i] = m.inputs[i].Update(msg)
}
return tea.Batch(cmds...)
}
// View renders the SSH config form
func (m SSHConfigModel) View() string {
var b strings.Builder
titleStyle := lipgloss.NewStyle().
Bold(true).
Foreground(lipgloss.Color("#7D56F4")).
MarginBottom(1)
b.WriteString(titleStyle.Render("🔌 SSH Connection"))
b.WriteString("\n\n")
for i := range m.inputs {
b.WriteString(m.inputs[i].View())
b.WriteString("\n")
}
helpStyle := lipgloss.NewStyle().Foreground(lipgloss.Color("#626262"))
b.WriteString("\n")
b.WriteString(helpStyle.Render("Tab/↑↓ navigate • Enter submit • Esc cancel"))
return b.String()
}
// IsSubmitted returns true if the form was submitted
func (m SSHConfigModel) IsSubmitted() bool {
return m.submitted
}
// IsCancelled returns true if the form was cancelled
func (m SSHConfigModel) IsCancelled() bool {
return m.cancelled
}
// GetConfig returns the SSH config values
func (m SSHConfigModel) GetConfig() (host, port, user, password string) {
return m.Host, m.Port, m.User, m.Password
}

View File

@@ -0,0 +1,52 @@
[14:18:33.982] [INFO] Logger initialized: logs\2026-01-19_14-18-33.log
[14:18:33.986] [INFO] Starting Telephony Inspector
[14:18:40.383] [INFO] PcapReader: Creating reader for D:\Proyectos\telephony-inspector\data\test2.pcap
[14:18:40.387] [INFO] PcapReader: Opening file D:\Proyectos\telephony-inspector\data\test2.pcap
[14:18:40.391] [INFO] PcapReader: File opened successfully, link type: Ethernet
[14:18:40.395] [DEBUG] PcapReader: BPF filter set for SIP ports
[14:18:40.399] [DEBUG] PcapReader: Processing packet 1, layers: [0xc00022a150 0xc00034a000 0xc000234100 0xc000232090]
[14:18:40.402] [DEBUG] PcapReader: Packet 1 IPv4 192.168.0.164 -> 192.168.0.162
[14:18:40.407] [DEBUG] PcapReader: Packet 1 UDP 51416 -> 5060
[14:18:40.409] [DEBUG] PcapReader: Packet 1 application layer, payload length: 528
[14:18:40.411] [DEBUG] PcapReader: Packet 1 payload preview: "v=0\r\no=- 3977820639 3977820639 IN IP4 192.168.0.164\r\ns=pjmedia\r\nb=AS:84\r\nt=0 0\r\na=X-nat:0\r\nm=audio 4"
[14:18:40.413] [DEBUG] PcapReader: Packet 1 is not SIP
[14:18:40.415] [DEBUG] PcapReader: Processing packet 2, layers: [0xc00022a1c0 0xc00034a0a0 0xc000234180 0xc000232120]
[14:18:40.417] [DEBUG] PcapReader: Packet 2 IPv4 192.168.0.162 -> 192.168.0.164
[14:18:40.419] [DEBUG] PcapReader: Packet 2 UDP 5060 -> 51416
[14:18:40.421] [DEBUG] PcapReader: Packet 2 application layer, payload length: 0
[14:18:40.423] [DEBUG] PcapReader: Packet 2 is not SIP
[14:18:40.425] [DEBUG] PcapReader: Processing packet 3, layers: [0xc00022a230 0xc00034a140 0xc000234200 0xc0002321b0]
[14:18:40.426] [DEBUG] PcapReader: Packet 3 IPv4 192.168.0.162 -> 192.168.0.164
[14:18:40.428] [DEBUG] PcapReader: Packet 3 UDP 5060 -> 51416
[14:18:40.431] [DEBUG] PcapReader: Packet 3 application layer, payload length: 375
[14:18:40.433] [DEBUG] PcapReader: Packet 3 payload preview: "v=0\r\no=- 3977820639 3977820641 IN IP4 192.168.0.162\r\ns=Asterisk\r\nc=IN IP4 192.168.0.162\r\nt=0 0\r\nm=au"
[14:18:40.434] [DEBUG] PcapReader: Packet 3 is not SIP
[14:18:40.436] [DEBUG] PcapReader: Processing packet 4, layers: [0xc00022a2a0 0xc00034a1e0 0xc000234280 0xc000232240]
[14:18:40.439] [DEBUG] PcapReader: Packet 4 IPv4 192.168.0.164 -> 192.168.0.162
[14:18:40.441] [DEBUG] PcapReader: Packet 4 UDP 51416 -> 5060
[14:18:40.443] [DEBUG] PcapReader: Packet 4 application layer, payload length: 0
[14:18:40.444] [DEBUG] PcapReader: Packet 4 is not SIP
[14:18:40.446] [DEBUG] PcapReader: Processing packet 5, layers: [0xc00022a310 0xc00034a280 0xc000234300 0xc0002322d0]
[14:18:40.448] [DEBUG] PcapReader: Packet 5 IPv4 192.168.0.164 -> 192.168.0.162
[14:18:40.450] [DEBUG] PcapReader: Packet 5 UDP 51416 -> 5060
[14:18:40.451] [DEBUG] PcapReader: Packet 5 application layer, payload length: 319
[14:18:40.454] [DEBUG] PcapReader: Packet 5 payload preview: "v=0\r\no=- 3977820639 3977820640 IN IP4 192.168.0.164\r\ns=pjmedia\r\nb=AS:84\r\nt=0 0\r\na=X-nat:0\r\nm=audio 4"
[14:18:40.456] [DEBUG] PcapReader: Packet 5 is not SIP
[14:18:40.457] [DEBUG] PcapReader: Processing packet 6, layers: [0xc00022a380 0xc00034a320 0xc000234380 0xc000232360]
[14:18:40.459] [DEBUG] PcapReader: Packet 6 IPv4 192.168.0.162 -> 192.168.0.164
[14:18:40.461] [DEBUG] PcapReader: Packet 6 UDP 5060 -> 51416
[14:18:40.462] [DEBUG] PcapReader: Packet 6 application layer, payload length: 239
[14:18:40.465] [DEBUG] PcapReader: Packet 6 payload preview: "v=0\r\no=- 3977820639 3977820642 IN IP4 192.168.0.162\r\ns=Asterisk\r\nc=IN IP4 192.168.0.162\r\nt=0 0\r\nm=au"
[14:18:40.467] [DEBUG] PcapReader: Packet 6 is not SIP
[14:18:40.468] [DEBUG] PcapReader: Processing packet 7, layers: [0xc00022a3f0 0xc00034a3c0 0xc000234400 0xc0002323f0]
[14:18:40.470] [DEBUG] PcapReader: Packet 7 IPv4 192.168.0.164 -> 192.168.0.162
[14:18:40.472] [DEBUG] PcapReader: Packet 7 UDP 51416 -> 5060
[14:18:40.474] [DEBUG] PcapReader: Packet 7 application layer, payload length: 0
[14:18:40.476] [DEBUG] PcapReader: Packet 7 is not SIP
[14:18:40.478] [DEBUG] PcapReader: Processing packet 8, layers: [0xc00022a460 0xc00034a460 0xc000234480 0xc000232480]
[14:18:40.480] [DEBUG] PcapReader: Packet 8 IPv4 192.168.0.162 -> 192.168.0.164
[14:18:40.481] [DEBUG] PcapReader: Packet 8 UDP 5060 -> 51416
[14:18:40.483] [DEBUG] PcapReader: Packet 8 application layer, payload length: 0
[14:18:40.485] [DEBUG] PcapReader: Packet 8 is not SIP
[14:18:40.487] [INFO] PcapReader: Finished reading. Total packets: 8, SIP packets: 0
[14:23:18.995] [INFO] Telephony Inspector exited normally

View File

@@ -0,0 +1,237 @@
[14:23:22.124] [INFO] Logger initialized: logs\2026-01-19_14-23-22.log
[14:23:22.128] [INFO] Starting Telephony Inspector
[14:23:26.188] [INFO] PcapReader: Creating reader for D:\Proyectos\telephony-inspector\data\test.pcapng
[14:23:26.193] [INFO] PcapReader: Opening file D:\Proyectos\telephony-inspector\data\test.pcapng
[14:23:26.197] [INFO] PcapReader: File opened successfully, link type: Ethernet
[14:23:26.200] [DEBUG] PcapReader: BPF filter set for SIP ports
[14:23:26.204] [DEBUG] PcapReader: Processing packet 1, layers: [0xc00048c0e0 0xc00049c000 0xc000332100 0xc00049e000]
[14:23:26.208] [DEBUG] PcapReader: Packet 1 IPv4 192.168.0.164 -> 192.168.0.162
[14:23:26.212] [DEBUG] PcapReader: Packet 1 UDP 51416 -> 5060, payload len: 1154
[14:23:26.214] [DEBUG] PcapReader: Packet 1 full payload preview: "INVITE sip:145632@192.168.0.162 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPj2b9d528911164b1795466ba22bc7e1e0\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=d158c77860094"
[14:23:26.215] [DEBUG] isSIPPayload: Detected SIP method: INVITE
[14:23:26.218] [DEBUG] PcapReader: Packet 1 detected as SIP, parsing...
[14:23:26.220] [INFO] PcapReader: Found SIP packet 1: INVITE b8060bf9ee0d43cbb60d714e22046659
[14:23:26.221] [DEBUG] PcapReader: Processing packet 2, layers: [0xc00048c150 0xc00049c0a0 0xc000332180 0xc00049e090]
[14:23:26.223] [DEBUG] PcapReader: Packet 2 IPv4 192.168.0.162 -> 192.168.0.164
[14:23:26.225] [DEBUG] PcapReader: Packet 2 UDP 5060 -> 51416, payload len: 382
[14:23:26.227] [DEBUG] PcapReader: Packet 2 full payload preview: "SIP/2.0 100 Trying\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPj2b9d528911164b1795466ba22bc7e1e0\r\nCall-ID: b8060bf9ee0d43cbb60d714e22046659\r\nFrom: <sip:1001"
[14:23:26.229] [DEBUG] isSIPPayload: Detected SIP response
[14:23:26.231] [DEBUG] PcapReader: Packet 2 detected as SIP, parsing...
[14:23:26.233] [INFO] PcapReader: Found SIP packet 2: 100 b8060bf9ee0d43cbb60d714e22046659
[14:23:26.234] [DEBUG] PcapReader: Processing packet 3, layers: [0xc00048c1c0 0xc00049c140 0xc000332200 0xc00049e120]
[14:23:26.236] [DEBUG] PcapReader: Packet 3 IPv4 192.168.0.162 -> 192.168.0.164
[14:23:26.238] [DEBUG] PcapReader: Packet 3 UDP 5060 -> 51416, payload len: 1075
[14:23:26.240] [DEBUG] PcapReader: Packet 3 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPj2b9d528911164b1795466ba22bc7e1e0\r\nCall-ID: b8060bf9ee0d43cbb60d714e22046659\r\nFrom: <sip:1001@192"
[14:23:26.242] [DEBUG] isSIPPayload: Detected SIP response
[14:23:26.244] [DEBUG] PcapReader: Packet 3 detected as SIP, parsing...
[14:23:26.246] [INFO] PcapReader: Found SIP packet 3: 200 b8060bf9ee0d43cbb60d714e22046659
[14:23:26.248] [DEBUG] PcapReader: Processing packet 4, layers: [0xc00048c230 0xc00049c1e0 0xc000332280 0xc00049e1b0]
[14:23:26.249] [DEBUG] PcapReader: Packet 4 IPv4 192.168.0.164 -> 192.168.0.162
[14:23:26.251] [DEBUG] PcapReader: Packet 4 UDP 51416 -> 5060, payload len: 371
[14:23:26.253] [DEBUG] PcapReader: Packet 4 full payload preview: "ACK sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPj5a53b67ee71748bf944b029063d2d8b4\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=d158c77860094c3dbd"
[14:23:26.255] [DEBUG] isSIPPayload: Detected SIP method: ACK
[14:23:26.257] [DEBUG] PcapReader: Packet 4 detected as SIP, parsing...
[14:23:26.259] [INFO] PcapReader: Found SIP packet 4: ACK b8060bf9ee0d43cbb60d714e22046659
[14:23:26.261] [DEBUG] PcapReader: Processing packet 5, layers: [0xc00048c2a0 0xc00049c280 0xc000332300 0xc00049e240]
[14:23:26.263] [DEBUG] PcapReader: Packet 5 IPv4 192.168.0.164 -> 192.168.0.162
[14:23:26.264] [DEBUG] PcapReader: Packet 5 UDP 51416 -> 5060, payload len: 871
[14:23:26.267] [DEBUG] PcapReader: Packet 5 full payload preview: "UPDATE sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPje6cb582aed174802a817688d4d8b7f0d\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=d158c77860094c3"
[14:23:26.269] [DEBUG] isSIPPayload: Detected SIP method: UPDATE
[14:23:26.271] [DEBUG] PcapReader: Packet 5 detected as SIP, parsing...
[14:23:26.273] [INFO] PcapReader: Found SIP packet 5: UPDATE b8060bf9ee0d43cbb60d714e22046659
[14:23:26.275] [DEBUG] PcapReader: Processing packet 6, layers: [0xc00048c310 0xc00049c320 0xc000332380 0xc00049e2d0]
[14:23:26.276] [DEBUG] PcapReader: Packet 6 IPv4 192.168.0.162 -> 192.168.0.164
[14:23:26.278] [DEBUG] PcapReader: Packet 6 UDP 5060 -> 51416, payload len: 939
[14:23:26.280] [DEBUG] PcapReader: Packet 6 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPje6cb582aed174802a817688d4d8b7f0d\r\nCall-ID: b8060bf9ee0d43cbb60d714e22046659\r\nFrom: <sip:1001@192"
[14:23:26.282] [DEBUG] isSIPPayload: Detected SIP response
[14:23:26.284] [DEBUG] PcapReader: Packet 6 detected as SIP, parsing...
[14:23:26.286] [INFO] PcapReader: Found SIP packet 6: 200 b8060bf9ee0d43cbb60d714e22046659
[14:23:26.288] [DEBUG] PcapReader: Processing packet 7, layers: [0xc00048c380 0xc00049c3c0 0xc000332400 0xc00049e360]
[14:23:26.289] [DEBUG] PcapReader: Packet 7 IPv4 192.168.0.164 -> 192.168.0.162
[14:23:26.291] [DEBUG] PcapReader: Packet 7 UDP 51416 -> 5060, payload len: 400
[14:23:26.293] [DEBUG] PcapReader: Packet 7 full payload preview: "BYE sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPj8e548a072435464c8b97c3930df0cbca\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=d158c77860094c3dbd"
[14:23:26.295] [DEBUG] isSIPPayload: Detected SIP method: BYE
[14:23:26.297] [DEBUG] PcapReader: Packet 7 detected as SIP, parsing...
[14:23:26.299] [INFO] PcapReader: Found SIP packet 7: BYE b8060bf9ee0d43cbb60d714e22046659
[14:23:26.301] [DEBUG] PcapReader: Processing packet 8, layers: [0xc00048c3f0 0xc00049c460 0xc000332480 0xc00049e3f0]
[14:23:26.303] [DEBUG] PcapReader: Packet 8 IPv4 192.168.0.162 -> 192.168.0.164
[14:23:26.305] [DEBUG] PcapReader: Packet 8 UDP 5060 -> 51416, payload len: 416
[14:23:26.306] [DEBUG] PcapReader: Packet 8 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPj8e548a072435464c8b97c3930df0cbca\r\nCall-ID: b8060bf9ee0d43cbb60d714e22046659\r\nFrom: <sip:1001@192"
[14:23:26.308] [DEBUG] isSIPPayload: Detected SIP response
[14:23:26.310] [DEBUG] PcapReader: Packet 8 detected as SIP, parsing...
[14:23:26.311] [INFO] PcapReader: Found SIP packet 8: 200 b8060bf9ee0d43cbb60d714e22046659
[14:23:26.314] [INFO] PcapReader: Finished reading. Total packets: 8, SIP packets: 8
[14:25:08.950] [INFO] PcapReader: Creating reader for D:\Proyectos\telephony-inspector\data\calls.pcap
[14:25:08.953] [INFO] PcapReader: Opening file D:\Proyectos\telephony-inspector\data\calls.pcap
[14:25:08.955] [INFO] PcapReader: File opened successfully, link type: Ethernet
[14:25:08.957] [DEBUG] PcapReader: BPF filter set for SIP ports
[14:25:08.959] [DEBUG] PcapReader: Processing packet 1, layers: [0xc0005320e0 0xc0001121e0 0xc000154080 0xc000232090]
[14:25:08.961] [DEBUG] PcapReader: Packet 1 IPv4 192.168.0.164 -> 192.168.0.162
[14:25:08.963] [DEBUG] PcapReader: Packet 1 UDP 51416 -> 5060, payload len: 1153
[14:25:08.965] [DEBUG] PcapReader: Packet 1 full payload preview: "INVITE sip:123456@192.168.0.162 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPjc988f0aca12d47aa900f472ea93fc0d6\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=d715109fcadd4"
[14:25:08.967] [DEBUG] isSIPPayload: Detected SIP method: INVITE
[14:25:08.969] [DEBUG] PcapReader: Packet 1 detected as SIP, parsing...
[14:25:08.971] [INFO] PcapReader: Found SIP packet 1: INVITE e06cb346194a4f9295d3a325b185912f
[14:25:08.973] [DEBUG] PcapReader: Processing packet 2, layers: [0xc000532150 0xc000112460 0xc000154100 0xc000232120]
[14:25:08.975] [DEBUG] PcapReader: Packet 2 IPv4 192.168.0.162 -> 192.168.0.164
[14:25:08.976] [DEBUG] PcapReader: Packet 2 UDP 5060 -> 51416, payload len: 382
[14:25:08.978] [DEBUG] PcapReader: Packet 2 full payload preview: "SIP/2.0 100 Trying\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPjc988f0aca12d47aa900f472ea93fc0d6\r\nCall-ID: e06cb346194a4f9295d3a325b185912f\r\nFrom: <sip:1001"
[14:25:08.980] [DEBUG] isSIPPayload: Detected SIP response
[14:25:08.981] [DEBUG] PcapReader: Packet 2 detected as SIP, parsing...
[14:25:08.984] [INFO] PcapReader: Found SIP packet 2: 100 e06cb346194a4f9295d3a325b185912f
[14:25:08.986] [DEBUG] PcapReader: Processing packet 3, layers: [0xc0005321c0 0xc0001125a0 0xc000154180 0xc0002321b0]
[14:25:08.988] [DEBUG] PcapReader: Packet 3 IPv4 192.168.0.162 -> 192.168.0.164
[14:25:08.990] [DEBUG] PcapReader: Packet 3 UDP 5060 -> 51416, payload len: 1075
[14:25:08.991] [DEBUG] PcapReader: Packet 3 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPjc988f0aca12d47aa900f472ea93fc0d6\r\nCall-ID: e06cb346194a4f9295d3a325b185912f\r\nFrom: <sip:1001@192"
[14:25:08.993] [DEBUG] isSIPPayload: Detected SIP response
[14:25:08.995] [DEBUG] PcapReader: Packet 3 detected as SIP, parsing...
[14:25:08.997] [INFO] PcapReader: Found SIP packet 3: 200 e06cb346194a4f9295d3a325b185912f
[14:25:08.998] [DEBUG] PcapReader: Processing packet 4, layers: [0xc000532230 0xc0001126e0 0xc000154200 0xc000232240]
[14:25:09.001] [DEBUG] PcapReader: Packet 4 IPv4 192.168.0.164 -> 192.168.0.162
[14:25:09.006] [DEBUG] PcapReader: Packet 4 UDP 51416 -> 5060, payload len: 371
[14:25:09.008] [DEBUG] PcapReader: Packet 4 full payload preview: "ACK sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPjf0cf112e8b5d4759a3417bc63cd5481e\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=d715109fcadd492b8f"
[14:25:09.010] [DEBUG] isSIPPayload: Detected SIP method: ACK
[14:25:09.012] [DEBUG] PcapReader: Packet 4 detected as SIP, parsing...
[14:25:09.014] [INFO] PcapReader: Found SIP packet 4: ACK e06cb346194a4f9295d3a325b185912f
[14:25:09.016] [DEBUG] PcapReader: Processing packet 5, layers: [0xc0005322a0 0xc000112780 0xc000154280 0xc0002322d0]
[14:25:09.018] [DEBUG] PcapReader: Packet 5 IPv4 192.168.0.164 -> 192.168.0.162
[14:25:09.019] [DEBUG] PcapReader: Packet 5 UDP 51416 -> 5060, payload len: 870
[14:25:09.021] [DEBUG] PcapReader: Packet 5 full payload preview: "UPDATE sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPj1453a8f281f04023b1a9d246fb587ca3\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=d715109fcadd492"
[14:25:09.023] [DEBUG] isSIPPayload: Detected SIP method: UPDATE
[14:25:09.025] [DEBUG] PcapReader: Packet 5 detected as SIP, parsing...
[14:25:09.027] [INFO] PcapReader: Found SIP packet 5: UPDATE e06cb346194a4f9295d3a325b185912f
[14:25:09.029] [DEBUG] PcapReader: Processing packet 6, layers: [0xc000532310 0xc000112820 0xc000154300 0xc000232360]
[14:25:09.031] [DEBUG] PcapReader: Packet 6 IPv4 192.168.0.162 -> 192.168.0.164
[14:25:09.032] [DEBUG] PcapReader: Packet 6 UDP 5060 -> 51416, payload len: 939
[14:25:09.034] [DEBUG] PcapReader: Packet 6 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPj1453a8f281f04023b1a9d246fb587ca3\r\nCall-ID: e06cb346194a4f9295d3a325b185912f\r\nFrom: <sip:1001@192"
[14:25:09.035] [DEBUG] isSIPPayload: Detected SIP response
[14:25:09.038] [DEBUG] PcapReader: Packet 6 detected as SIP, parsing...
[14:25:09.040] [INFO] PcapReader: Found SIP packet 6: 200 e06cb346194a4f9295d3a325b185912f
[14:25:09.041] [DEBUG] PcapReader: Processing packet 7, layers: [0xc000532380 0xc0001128c0 0xc000154380 0xc0002323f0]
[14:25:09.043] [DEBUG] PcapReader: Packet 7 IPv4 192.168.0.164 -> 192.168.0.162
[14:25:09.045] [DEBUG] PcapReader: Packet 7 UDP 51416 -> 5060, payload len: 400
[14:25:09.047] [DEBUG] PcapReader: Packet 7 full payload preview: "BYE sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPj15f5d8bca6884d6794f27c43437f1201\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=d715109fcadd492b8f"
[14:25:09.048] [DEBUG] isSIPPayload: Detected SIP method: BYE
[14:25:09.051] [DEBUG] PcapReader: Packet 7 detected as SIP, parsing...
[14:25:09.052] [INFO] PcapReader: Found SIP packet 7: BYE e06cb346194a4f9295d3a325b185912f
[14:25:09.054] [DEBUG] PcapReader: Processing packet 8, layers: [0xc0005323f0 0xc000112960 0xc000154400 0xc000232480]
[14:25:09.056] [DEBUG] PcapReader: Packet 8 IPv4 192.168.0.162 -> 192.168.0.164
[14:25:09.058] [DEBUG] PcapReader: Packet 8 UDP 5060 -> 51416, payload len: 416
[14:25:09.059] [DEBUG] PcapReader: Packet 8 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPj15f5d8bca6884d6794f27c43437f1201\r\nCall-ID: e06cb346194a4f9295d3a325b185912f\r\nFrom: <sip:1001@192"
[14:25:09.061] [DEBUG] isSIPPayload: Detected SIP response
[14:25:09.064] [DEBUG] PcapReader: Packet 8 detected as SIP, parsing...
[14:25:09.065] [INFO] PcapReader: Found SIP packet 8: 200 e06cb346194a4f9295d3a325b185912f
[14:25:09.067] [DEBUG] PcapReader: Processing packet 9, layers: [0xc000532460 0xc000112a00 0xc000154480 0xc000232510]
[14:25:09.069] [DEBUG] PcapReader: Packet 9 IPv4 192.168.0.164 -> 192.168.0.162
[14:25:09.071] [DEBUG] PcapReader: Packet 9 UDP 51416 -> 5060, payload len: 1160
[14:25:09.073] [DEBUG] PcapReader: Packet 9 full payload preview: "INVITE sip:962791077@192.168.0.162 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPj25f0f67dd6cb411ab3b6d48b1c0f9ca9\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=820adc6fe0"
[14:25:09.074] [DEBUG] isSIPPayload: Detected SIP method: INVITE
[14:25:09.076] [DEBUG] PcapReader: Packet 9 detected as SIP, parsing...
[14:25:09.078] [INFO] PcapReader: Found SIP packet 9: INVITE a15e53524b304ebf9dd16209f9c95d18
[14:25:09.080] [DEBUG] PcapReader: Processing packet 10, layers: [0xc0005324d0 0xc000112aa0 0xc000154580 0xc0002325a0]
[14:25:09.081] [DEBUG] PcapReader: Packet 10 IPv4 192.168.0.162 -> 192.168.0.164
[14:25:09.083] [DEBUG] PcapReader: Packet 10 UDP 5060 -> 51416, payload len: 385
[14:25:09.085] [DEBUG] PcapReader: Packet 10 full payload preview: "SIP/2.0 100 Trying\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPj25f0f67dd6cb411ab3b6d48b1c0f9ca9\r\nCall-ID: a15e53524b304ebf9dd16209f9c95d18\r\nFrom: <sip:1001"
[14:25:09.087] [DEBUG] isSIPPayload: Detected SIP response
[14:25:09.089] [DEBUG] PcapReader: Packet 10 detected as SIP, parsing...
[14:25:09.090] [INFO] PcapReader: Found SIP packet 10: 100 a15e53524b304ebf9dd16209f9c95d18
[14:25:09.092] [DEBUG] PcapReader: Processing packet 11, layers: [0xc000532540 0xc000112b40 0xc000154600 0xc000232630]
[14:25:09.094] [DEBUG] PcapReader: Packet 11 IPv4 192.168.0.162 -> 192.168.0.164
[14:25:09.096] [DEBUG] PcapReader: Packet 11 UDP 5060 -> 51416, payload len: 1078
[14:25:09.098] [DEBUG] PcapReader: Packet 11 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPj25f0f67dd6cb411ab3b6d48b1c0f9ca9\r\nCall-ID: a15e53524b304ebf9dd16209f9c95d18\r\nFrom: <sip:1001@192"
[14:25:09.100] [DEBUG] isSIPPayload: Detected SIP response
[14:25:09.101] [DEBUG] PcapReader: Packet 11 detected as SIP, parsing...
[14:25:09.103] [INFO] PcapReader: Found SIP packet 11: 200 a15e53524b304ebf9dd16209f9c95d18
[14:25:09.105] [DEBUG] PcapReader: Processing packet 12, layers: [0xc0005325b0 0xc000112be0 0xc000154680 0xc0002326c0]
[14:25:09.107] [DEBUG] PcapReader: Packet 12 IPv4 192.168.0.164 -> 192.168.0.162
[14:25:09.108] [DEBUG] PcapReader: Packet 12 UDP 51416 -> 5060, payload len: 374
[14:25:09.110] [DEBUG] PcapReader: Packet 12 full payload preview: "ACK sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPj70a4a90d59254a4885b807deca2166fc\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=820adc6fe0694f93bc"
[14:25:09.112] [DEBUG] isSIPPayload: Detected SIP method: ACK
[14:25:09.114] [DEBUG] PcapReader: Packet 12 detected as SIP, parsing...
[14:25:09.116] [INFO] PcapReader: Found SIP packet 12: ACK a15e53524b304ebf9dd16209f9c95d18
[14:25:09.118] [DEBUG] PcapReader: Processing packet 13, layers: [0xc000532620 0xc000112c80 0xc000154700 0xc000232750]
[14:25:09.120] [DEBUG] PcapReader: Packet 13 IPv4 192.168.0.164 -> 192.168.0.162
[14:25:09.121] [DEBUG] PcapReader: Packet 13 UDP 51416 -> 5060, payload len: 874
[14:25:09.123] [DEBUG] PcapReader: Packet 13 full payload preview: "UPDATE sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPjda3c200bd4664b39b5d59177c5f53017\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=820adc6fe0694f9"
[14:25:09.125] [DEBUG] isSIPPayload: Detected SIP method: UPDATE
[14:25:09.127] [DEBUG] PcapReader: Packet 13 detected as SIP, parsing...
[14:25:09.129] [INFO] PcapReader: Found SIP packet 13: UPDATE a15e53524b304ebf9dd16209f9c95d18
[14:25:09.131] [DEBUG] PcapReader: Processing packet 14, layers: [0xc000532690 0xc000112d20 0xc000154780 0xc0002327e0]
[14:25:09.132] [DEBUG] PcapReader: Packet 14 IPv4 192.168.0.162 -> 192.168.0.164
[14:25:09.134] [DEBUG] PcapReader: Packet 14 UDP 5060 -> 51416, payload len: 942
[14:25:09.136] [DEBUG] PcapReader: Packet 14 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPjda3c200bd4664b39b5d59177c5f53017\r\nCall-ID: a15e53524b304ebf9dd16209f9c95d18\r\nFrom: <sip:1001@192"
[14:25:09.138] [DEBUG] isSIPPayload: Detected SIP response
[14:25:09.139] [DEBUG] PcapReader: Packet 14 detected as SIP, parsing...
[14:25:09.141] [INFO] PcapReader: Found SIP packet 14: 200 a15e53524b304ebf9dd16209f9c95d18
[14:25:09.143] [DEBUG] PcapReader: Processing packet 15, layers: [0xc000532700 0xc000112dc0 0xc000154800 0xc000232870]
[14:25:09.145] [DEBUG] PcapReader: Packet 15 IPv4 192.168.0.164 -> 192.168.0.162
[14:25:09.147] [DEBUG] PcapReader: Packet 15 UDP 51416 -> 5060, payload len: 403
[14:25:09.148] [DEBUG] PcapReader: Packet 15 full payload preview: "BYE sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPjcca874595f7840409818bf98eb6f7629\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=820adc6fe0694f93bc"
[14:25:09.150] [DEBUG] isSIPPayload: Detected SIP method: BYE
[14:25:09.152] [DEBUG] PcapReader: Packet 15 detected as SIP, parsing...
[14:25:09.154] [INFO] PcapReader: Found SIP packet 15: BYE a15e53524b304ebf9dd16209f9c95d18
[14:25:09.156] [DEBUG] PcapReader: Processing packet 16, layers: [0xc000532770 0xc000112e60 0xc000154880 0xc000232900]
[14:25:09.157] [DEBUG] PcapReader: Packet 16 IPv4 192.168.0.162 -> 192.168.0.164
[14:25:09.159] [DEBUG] PcapReader: Packet 16 UDP 5060 -> 51416, payload len: 419
[14:25:09.162] [DEBUG] PcapReader: Packet 16 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPjcca874595f7840409818bf98eb6f7629\r\nCall-ID: a15e53524b304ebf9dd16209f9c95d18\r\nFrom: <sip:1001@192"
[14:25:09.163] [DEBUG] isSIPPayload: Detected SIP response
[14:25:09.165] [DEBUG] PcapReader: Packet 16 detected as SIP, parsing...
[14:25:09.167] [INFO] PcapReader: Found SIP packet 16: 200 a15e53524b304ebf9dd16209f9c95d18
[14:25:09.169] [DEBUG] PcapReader: Processing packet 17, layers: [0xc0005327e0 0xc000112f00 0xc000154900 0xc000232990]
[14:25:09.171] [DEBUG] PcapReader: Packet 17 IPv4 192.168.0.164 -> 192.168.0.162
[14:25:09.173] [DEBUG] PcapReader: Packet 17 UDP 51416 -> 5060, payload len: 1150
[14:25:09.175] [DEBUG] PcapReader: Packet 17 full payload preview: "INVITE sip:3333@192.168.0.162 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPjb6b83a62e76f41c58fe9b71e82af61a5\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=c2ffb0450ac24fb"
[14:25:09.176] [DEBUG] isSIPPayload: Detected SIP method: INVITE
[14:25:09.178] [DEBUG] PcapReader: Packet 17 detected as SIP, parsing...
[14:25:09.180] [INFO] PcapReader: Found SIP packet 17: INVITE e9270b7c047542ef9af488d27b82162e
[14:25:09.181] [DEBUG] PcapReader: Processing packet 18, layers: [0xc000532850 0xc000112fa0 0xc000154980 0xc000232a20]
[14:25:09.184] [DEBUG] PcapReader: Packet 18 IPv4 192.168.0.162 -> 192.168.0.164
[14:25:09.186] [DEBUG] PcapReader: Packet 18 UDP 5060 -> 51416, payload len: 380
[14:25:09.187] [DEBUG] PcapReader: Packet 18 full payload preview: "SIP/2.0 100 Trying\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPjb6b83a62e76f41c58fe9b71e82af61a5\r\nCall-ID: e9270b7c047542ef9af488d27b82162e\r\nFrom: <sip:1001"
[14:25:09.189] [DEBUG] isSIPPayload: Detected SIP response
[14:25:09.191] [DEBUG] PcapReader: Packet 18 detected as SIP, parsing...
[14:25:09.193] [INFO] PcapReader: Found SIP packet 18: 100 e9270b7c047542ef9af488d27b82162e
[14:25:09.195] [DEBUG] PcapReader: Processing packet 19, layers: [0xc0005328c0 0xc000113040 0xc000154a00 0xc000232ab0]
[14:25:09.197] [DEBUG] PcapReader: Packet 19 IPv4 192.168.0.162 -> 192.168.0.164
[14:25:09.198] [DEBUG] PcapReader: Packet 19 UDP 5060 -> 51416, payload len: 1073
[14:25:09.201] [DEBUG] PcapReader: Packet 19 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPjb6b83a62e76f41c58fe9b71e82af61a5\r\nCall-ID: e9270b7c047542ef9af488d27b82162e\r\nFrom: <sip:1001@192"
[14:25:09.202] [DEBUG] isSIPPayload: Detected SIP response
[14:25:09.204] [DEBUG] PcapReader: Packet 19 detected as SIP, parsing...
[14:25:09.206] [INFO] PcapReader: Found SIP packet 19: 200 e9270b7c047542ef9af488d27b82162e
[14:25:09.208] [DEBUG] PcapReader: Processing packet 20, layers: [0xc000532930 0xc0001130e0 0xc000154a80 0xc000232b40]
[14:25:09.209] [DEBUG] PcapReader: Packet 20 IPv4 192.168.0.164 -> 192.168.0.162
[14:25:09.212] [DEBUG] PcapReader: Packet 20 UDP 51416 -> 5060, payload len: 369
[14:25:09.213] [DEBUG] PcapReader: Packet 20 full payload preview: "ACK sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPj1ec8fc81ae324187a6feecaf02f04ff1\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=c2ffb0450ac24fb098"
[14:25:09.215] [DEBUG] isSIPPayload: Detected SIP method: ACK
[14:25:09.217] [DEBUG] PcapReader: Packet 20 detected as SIP, parsing...
[14:25:09.219] [INFO] PcapReader: Found SIP packet 20: ACK e9270b7c047542ef9af488d27b82162e
[14:25:09.221] [DEBUG] PcapReader: Processing packet 21, layers: [0xc0005329a0 0xc000113180 0xc000154b00 0xc000232bd0]
[14:25:09.223] [DEBUG] PcapReader: Packet 21 IPv4 192.168.0.164 -> 192.168.0.162
[14:25:09.224] [DEBUG] PcapReader: Packet 21 UDP 51416 -> 5060, payload len: 869
[14:25:09.226] [DEBUG] PcapReader: Packet 21 full payload preview: "UPDATE sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPja17c7b2ea9da425d85da051e336794c9\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=c2ffb0450ac24fb"
[14:25:09.228] [DEBUG] isSIPPayload: Detected SIP method: UPDATE
[14:25:09.230] [DEBUG] PcapReader: Packet 21 detected as SIP, parsing...
[14:25:09.231] [INFO] PcapReader: Found SIP packet 21: UPDATE e9270b7c047542ef9af488d27b82162e
[14:25:09.233] [DEBUG] PcapReader: Processing packet 22, layers: [0xc000532a10 0xc000113220 0xc000154b80 0xc000232c60]
[14:25:09.235] [DEBUG] PcapReader: Packet 22 IPv4 192.168.0.162 -> 192.168.0.164
[14:25:09.237] [DEBUG] PcapReader: Packet 22 UDP 5060 -> 51416, payload len: 937
[14:25:09.239] [DEBUG] PcapReader: Packet 22 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPja17c7b2ea9da425d85da051e336794c9\r\nCall-ID: e9270b7c047542ef9af488d27b82162e\r\nFrom: <sip:1001@192"
[14:25:09.241] [DEBUG] isSIPPayload: Detected SIP response
[14:25:09.242] [DEBUG] PcapReader: Packet 22 detected as SIP, parsing...
[14:25:09.245] [INFO] PcapReader: Found SIP packet 22: 200 e9270b7c047542ef9af488d27b82162e
[14:25:09.246] [DEBUG] PcapReader: Processing packet 23, layers: [0xc000532a80 0xc0001132c0 0xc000154c00 0xc000232cf0]
[14:25:09.248] [DEBUG] PcapReader: Packet 23 IPv4 192.168.0.164 -> 192.168.0.162
[14:25:09.250] [DEBUG] PcapReader: Packet 23 UDP 51416 -> 5060, payload len: 398
[14:25:09.252] [DEBUG] PcapReader: Packet 23 full payload preview: "BYE sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPjc372eee10c754ece9a873f8e36a6a0e2\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=c2ffb0450ac24fb098"
[14:25:09.253] [DEBUG] isSIPPayload: Detected SIP method: BYE
[14:25:09.255] [DEBUG] PcapReader: Packet 23 detected as SIP, parsing...
[14:25:09.257] [INFO] PcapReader: Found SIP packet 23: BYE e9270b7c047542ef9af488d27b82162e
[14:25:09.259] [DEBUG] PcapReader: Processing packet 24, layers: [0xc000532af0 0xc000113360 0xc000154c80 0xc000232d80]
[14:25:09.261] [DEBUG] PcapReader: Packet 24 IPv4 192.168.0.162 -> 192.168.0.164
[14:25:09.263] [DEBUG] PcapReader: Packet 24 UDP 5060 -> 51416, payload len: 414
[14:25:09.264] [DEBUG] PcapReader: Packet 24 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPjc372eee10c754ece9a873f8e36a6a0e2\r\nCall-ID: e9270b7c047542ef9af488d27b82162e\r\nFrom: <sip:1001@192"
[14:25:09.266] [DEBUG] isSIPPayload: Detected SIP response
[14:25:09.268] [DEBUG] PcapReader: Packet 24 detected as SIP, parsing...
[14:25:09.270] [INFO] PcapReader: Found SIP packet 24: 200 e9270b7c047542ef9af488d27b82162e
[14:25:09.271] [INFO] PcapReader: Finished reading. Total packets: 24, SIP packets: 24
[14:25:29.806] [INFO] Telephony Inspector exited normally

View File

@@ -0,0 +1,176 @@
[14:25:30.903] [INFO] Logger initialized: logs\2026-01-19_14-25-30.log
[14:25:30.906] [INFO] Starting Telephony Inspector
[14:25:35.313] [INFO] PcapReader: Creating reader for D:\Proyectos\telephony-inspector\data\calls.pcap
[14:25:35.317] [INFO] PcapReader: Opening file D:\Proyectos\telephony-inspector\data\calls.pcap
[14:25:35.320] [INFO] PcapReader: File opened successfully, link type: Ethernet
[14:25:35.324] [DEBUG] PcapReader: BPF filter set for SIP ports
[14:25:35.327] [DEBUG] PcapReader: Processing packet 1, layers: [0xc00043a230 0xc00044e000 0xc00031a280 0xc000450000]
[14:25:35.331] [DEBUG] PcapReader: Packet 1 IPv4 192.168.0.164 -> 192.168.0.162
[14:25:35.335] [DEBUG] PcapReader: Packet 1 UDP 51416 -> 5060, payload len: 1153
[14:25:35.337] [DEBUG] PcapReader: Packet 1 full payload preview: "INVITE sip:123456@192.168.0.162 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPjc988f0aca12d47aa900f472ea93fc0d6\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=d715109fcadd4"
[14:25:35.338] [DEBUG] isSIPPayload: Detected SIP method: INVITE
[14:25:35.340] [DEBUG] PcapReader: Packet 1 detected as SIP, parsing...
[14:25:35.342] [INFO] PcapReader: Found SIP packet 1: INVITE e06cb346194a4f9295d3a325b185912f
[14:25:35.344] [DEBUG] PcapReader: Processing packet 2, layers: [0xc00043a2a0 0xc00044e0a0 0xc00031a300 0xc000450090]
[14:25:35.346] [DEBUG] PcapReader: Packet 2 IPv4 192.168.0.162 -> 192.168.0.164
[14:25:35.348] [DEBUG] PcapReader: Packet 2 UDP 5060 -> 51416, payload len: 382
[14:25:35.350] [DEBUG] PcapReader: Packet 2 full payload preview: "SIP/2.0 100 Trying\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPjc988f0aca12d47aa900f472ea93fc0d6\r\nCall-ID: e06cb346194a4f9295d3a325b185912f\r\nFrom: <sip:1001"
[14:25:35.351] [DEBUG] isSIPPayload: Detected SIP response
[14:25:35.353] [DEBUG] PcapReader: Packet 2 detected as SIP, parsing...
[14:25:35.355] [INFO] PcapReader: Found SIP packet 2: 100 e06cb346194a4f9295d3a325b185912f
[14:25:35.357] [DEBUG] PcapReader: Processing packet 3, layers: [0xc00043a310 0xc00044e140 0xc00031a380 0xc000450120]
[14:25:35.359] [DEBUG] PcapReader: Packet 3 IPv4 192.168.0.162 -> 192.168.0.164
[14:25:35.361] [DEBUG] PcapReader: Packet 3 UDP 5060 -> 51416, payload len: 1075
[14:25:35.363] [DEBUG] PcapReader: Packet 3 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPjc988f0aca12d47aa900f472ea93fc0d6\r\nCall-ID: e06cb346194a4f9295d3a325b185912f\r\nFrom: <sip:1001@192"
[14:25:35.365] [DEBUG] isSIPPayload: Detected SIP response
[14:25:35.366] [DEBUG] PcapReader: Packet 3 detected as SIP, parsing...
[14:25:35.368] [INFO] PcapReader: Found SIP packet 3: 200 e06cb346194a4f9295d3a325b185912f
[14:25:35.370] [DEBUG] PcapReader: Processing packet 4, layers: [0xc00043a380 0xc00044e1e0 0xc00031a400 0xc0004501b0]
[14:25:35.372] [DEBUG] PcapReader: Packet 4 IPv4 192.168.0.164 -> 192.168.0.162
[14:25:35.374] [DEBUG] PcapReader: Packet 4 UDP 51416 -> 5060, payload len: 371
[14:25:35.376] [DEBUG] PcapReader: Packet 4 full payload preview: "ACK sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPjf0cf112e8b5d4759a3417bc63cd5481e\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=d715109fcadd492b8f"
[14:25:35.378] [DEBUG] isSIPPayload: Detected SIP method: ACK
[14:25:35.379] [DEBUG] PcapReader: Packet 4 detected as SIP, parsing...
[14:25:35.381] [INFO] PcapReader: Found SIP packet 4: ACK e06cb346194a4f9295d3a325b185912f
[14:25:35.383] [DEBUG] PcapReader: Processing packet 5, layers: [0xc00043a3f0 0xc00044e280 0xc00031a480 0xc000450240]
[14:25:35.385] [DEBUG] PcapReader: Packet 5 IPv4 192.168.0.164 -> 192.168.0.162
[14:25:35.387] [DEBUG] PcapReader: Packet 5 UDP 51416 -> 5060, payload len: 870
[14:25:35.389] [DEBUG] PcapReader: Packet 5 full payload preview: "UPDATE sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPj1453a8f281f04023b1a9d246fb587ca3\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=d715109fcadd492"
[14:25:35.390] [DEBUG] isSIPPayload: Detected SIP method: UPDATE
[14:25:35.392] [DEBUG] PcapReader: Packet 5 detected as SIP, parsing...
[14:25:35.394] [INFO] PcapReader: Found SIP packet 5: UPDATE e06cb346194a4f9295d3a325b185912f
[14:25:35.396] [DEBUG] PcapReader: Processing packet 6, layers: [0xc00043a460 0xc00044e320 0xc00031a500 0xc0004502d0]
[14:25:35.398] [DEBUG] PcapReader: Packet 6 IPv4 192.168.0.162 -> 192.168.0.164
[14:25:35.399] [DEBUG] PcapReader: Packet 6 UDP 5060 -> 51416, payload len: 939
[14:25:35.401] [DEBUG] PcapReader: Packet 6 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPj1453a8f281f04023b1a9d246fb587ca3\r\nCall-ID: e06cb346194a4f9295d3a325b185912f\r\nFrom: <sip:1001@192"
[14:25:35.403] [DEBUG] isSIPPayload: Detected SIP response
[14:25:35.405] [DEBUG] PcapReader: Packet 6 detected as SIP, parsing...
[14:25:35.406] [INFO] PcapReader: Found SIP packet 6: 200 e06cb346194a4f9295d3a325b185912f
[14:25:35.408] [DEBUG] PcapReader: Processing packet 7, layers: [0xc00043a4d0 0xc00044e3c0 0xc00031a580 0xc000450360]
[14:25:35.410] [DEBUG] PcapReader: Packet 7 IPv4 192.168.0.164 -> 192.168.0.162
[14:25:35.412] [DEBUG] PcapReader: Packet 7 UDP 51416 -> 5060, payload len: 400
[14:25:35.414] [DEBUG] PcapReader: Packet 7 full payload preview: "BYE sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPj15f5d8bca6884d6794f27c43437f1201\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=d715109fcadd492b8f"
[14:25:35.415] [DEBUG] isSIPPayload: Detected SIP method: BYE
[14:25:35.417] [DEBUG] PcapReader: Packet 7 detected as SIP, parsing...
[14:25:35.419] [INFO] PcapReader: Found SIP packet 7: BYE e06cb346194a4f9295d3a325b185912f
[14:25:35.421] [DEBUG] PcapReader: Processing packet 8, layers: [0xc00043a540 0xc00044e460 0xc00031a600 0xc0004503f0]
[14:25:35.439] [DEBUG] PcapReader: Packet 8 IPv4 192.168.0.162 -> 192.168.0.164
[14:25:35.440] [DEBUG] PcapReader: Packet 8 UDP 5060 -> 51416, payload len: 416
[14:25:35.442] [DEBUG] PcapReader: Packet 8 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPj15f5d8bca6884d6794f27c43437f1201\r\nCall-ID: e06cb346194a4f9295d3a325b185912f\r\nFrom: <sip:1001@192"
[14:25:35.444] [DEBUG] isSIPPayload: Detected SIP response
[14:25:35.446] [DEBUG] PcapReader: Packet 8 detected as SIP, parsing...
[14:25:35.448] [INFO] PcapReader: Found SIP packet 8: 200 e06cb346194a4f9295d3a325b185912f
[14:25:35.450] [DEBUG] PcapReader: Processing packet 9, layers: [0xc00043a5b0 0xc00044e500 0xc00031a680 0xc000450480]
[14:25:35.451] [DEBUG] PcapReader: Packet 9 IPv4 192.168.0.164 -> 192.168.0.162
[14:25:35.453] [DEBUG] PcapReader: Packet 9 UDP 51416 -> 5060, payload len: 1160
[14:25:35.454] [DEBUG] PcapReader: Packet 9 full payload preview: "INVITE sip:962791077@192.168.0.162 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPj25f0f67dd6cb411ab3b6d48b1c0f9ca9\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=820adc6fe0"
[14:25:35.457] [DEBUG] isSIPPayload: Detected SIP method: INVITE
[14:25:35.459] [DEBUG] PcapReader: Packet 9 detected as SIP, parsing...
[14:25:35.461] [INFO] PcapReader: Found SIP packet 9: INVITE a15e53524b304ebf9dd16209f9c95d18
[14:25:35.462] [DEBUG] PcapReader: Processing packet 10, layers: [0xc00043a620 0xc00044e5a0 0xc00031a700 0xc000450510]
[14:25:35.465] [DEBUG] PcapReader: Packet 10 IPv4 192.168.0.162 -> 192.168.0.164
[14:25:35.467] [DEBUG] PcapReader: Packet 10 UDP 5060 -> 51416, payload len: 385
[14:25:35.468] [DEBUG] PcapReader: Packet 10 full payload preview: "SIP/2.0 100 Trying\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPj25f0f67dd6cb411ab3b6d48b1c0f9ca9\r\nCall-ID: a15e53524b304ebf9dd16209f9c95d18\r\nFrom: <sip:1001"
[14:25:35.470] [DEBUG] isSIPPayload: Detected SIP response
[14:25:35.472] [DEBUG] PcapReader: Packet 10 detected as SIP, parsing...
[14:25:35.474] [INFO] PcapReader: Found SIP packet 10: 100 a15e53524b304ebf9dd16209f9c95d18
[14:25:35.476] [DEBUG] PcapReader: Processing packet 11, layers: [0xc00043a690 0xc00044e640 0xc00031a780 0xc0004505a0]
[14:25:35.478] [DEBUG] PcapReader: Packet 11 IPv4 192.168.0.162 -> 192.168.0.164
[14:25:35.480] [DEBUG] PcapReader: Packet 11 UDP 5060 -> 51416, payload len: 1078
[14:25:35.481] [DEBUG] PcapReader: Packet 11 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPj25f0f67dd6cb411ab3b6d48b1c0f9ca9\r\nCall-ID: a15e53524b304ebf9dd16209f9c95d18\r\nFrom: <sip:1001@192"
[14:25:35.483] [DEBUG] isSIPPayload: Detected SIP response
[14:25:35.485] [DEBUG] PcapReader: Packet 11 detected as SIP, parsing...
[14:25:35.487] [INFO] PcapReader: Found SIP packet 11: 200 a15e53524b304ebf9dd16209f9c95d18
[14:25:35.489] [DEBUG] PcapReader: Processing packet 12, layers: [0xc00043a700 0xc00044e6e0 0xc00031a800 0xc000450630]
[14:25:35.491] [DEBUG] PcapReader: Packet 12 IPv4 192.168.0.164 -> 192.168.0.162
[14:25:35.492] [DEBUG] PcapReader: Packet 12 UDP 51416 -> 5060, payload len: 374
[14:25:35.494] [DEBUG] PcapReader: Packet 12 full payload preview: "ACK sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPj70a4a90d59254a4885b807deca2166fc\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=820adc6fe0694f93bc"
[14:25:35.496] [DEBUG] isSIPPayload: Detected SIP method: ACK
[14:25:35.498] [DEBUG] PcapReader: Packet 12 detected as SIP, parsing...
[14:25:35.500] [INFO] PcapReader: Found SIP packet 12: ACK a15e53524b304ebf9dd16209f9c95d18
[14:25:35.502] [DEBUG] PcapReader: Processing packet 13, layers: [0xc00043a770 0xc00044e780 0xc00031a880 0xc0004506c0]
[14:25:35.504] [DEBUG] PcapReader: Packet 13 IPv4 192.168.0.164 -> 192.168.0.162
[14:25:35.505] [DEBUG] PcapReader: Packet 13 UDP 51416 -> 5060, payload len: 874
[14:25:35.507] [DEBUG] PcapReader: Packet 13 full payload preview: "UPDATE sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPjda3c200bd4664b39b5d59177c5f53017\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=820adc6fe0694f9"
[14:25:35.509] [DEBUG] isSIPPayload: Detected SIP method: UPDATE
[14:25:35.511] [DEBUG] PcapReader: Packet 13 detected as SIP, parsing...
[14:25:35.513] [INFO] PcapReader: Found SIP packet 13: UPDATE a15e53524b304ebf9dd16209f9c95d18
[14:25:35.515] [DEBUG] PcapReader: Processing packet 14, layers: [0xc00043a7e0 0xc00044e820 0xc00031a900 0xc000450750]
[14:25:35.517] [DEBUG] PcapReader: Packet 14 IPv4 192.168.0.162 -> 192.168.0.164
[14:25:35.519] [DEBUG] PcapReader: Packet 14 UDP 5060 -> 51416, payload len: 942
[14:25:35.521] [DEBUG] PcapReader: Packet 14 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPjda3c200bd4664b39b5d59177c5f53017\r\nCall-ID: a15e53524b304ebf9dd16209f9c95d18\r\nFrom: <sip:1001@192"
[14:25:35.522] [DEBUG] isSIPPayload: Detected SIP response
[14:25:35.524] [DEBUG] PcapReader: Packet 14 detected as SIP, parsing...
[14:25:35.526] [INFO] PcapReader: Found SIP packet 14: 200 a15e53524b304ebf9dd16209f9c95d18
[14:25:35.528] [DEBUG] PcapReader: Processing packet 15, layers: [0xc00043a850 0xc00044e8c0 0xc00031a980 0xc0004507e0]
[14:25:35.530] [DEBUG] PcapReader: Packet 15 IPv4 192.168.0.164 -> 192.168.0.162
[14:25:35.532] [DEBUG] PcapReader: Packet 15 UDP 51416 -> 5060, payload len: 403
[14:25:35.534] [DEBUG] PcapReader: Packet 15 full payload preview: "BYE sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPjcca874595f7840409818bf98eb6f7629\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=820adc6fe0694f93bc"
[14:25:35.535] [DEBUG] isSIPPayload: Detected SIP method: BYE
[14:25:35.537] [DEBUG] PcapReader: Packet 15 detected as SIP, parsing...
[14:25:35.539] [INFO] PcapReader: Found SIP packet 15: BYE a15e53524b304ebf9dd16209f9c95d18
[14:25:35.541] [DEBUG] PcapReader: Processing packet 16, layers: [0xc00043a8c0 0xc00044e960 0xc00031aa00 0xc000450870]
[14:25:35.543] [DEBUG] PcapReader: Packet 16 IPv4 192.168.0.162 -> 192.168.0.164
[14:25:35.545] [DEBUG] PcapReader: Packet 16 UDP 5060 -> 51416, payload len: 419
[14:25:35.546] [DEBUG] PcapReader: Packet 16 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPjcca874595f7840409818bf98eb6f7629\r\nCall-ID: a15e53524b304ebf9dd16209f9c95d18\r\nFrom: <sip:1001@192"
[14:25:35.548] [DEBUG] isSIPPayload: Detected SIP response
[14:25:35.550] [DEBUG] PcapReader: Packet 16 detected as SIP, parsing...
[14:25:35.552] [INFO] PcapReader: Found SIP packet 16: 200 a15e53524b304ebf9dd16209f9c95d18
[14:25:35.554] [DEBUG] PcapReader: Processing packet 17, layers: [0xc00043a930 0xc00044ea00 0xc00031aa80 0xc000450900]
[14:25:35.555] [DEBUG] PcapReader: Packet 17 IPv4 192.168.0.164 -> 192.168.0.162
[14:25:35.557] [DEBUG] PcapReader: Packet 17 UDP 51416 -> 5060, payload len: 1150
[14:25:35.559] [DEBUG] PcapReader: Packet 17 full payload preview: "INVITE sip:3333@192.168.0.162 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPjb6b83a62e76f41c58fe9b71e82af61a5\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=c2ffb0450ac24fb"
[14:25:35.561] [DEBUG] isSIPPayload: Detected SIP method: INVITE
[14:25:35.563] [DEBUG] PcapReader: Packet 17 detected as SIP, parsing...
[14:25:35.565] [INFO] PcapReader: Found SIP packet 17: INVITE e9270b7c047542ef9af488d27b82162e
[14:25:35.567] [DEBUG] PcapReader: Processing packet 18, layers: [0xc00043a9a0 0xc00044eaa0 0xc00031ab00 0xc000450990]
[14:25:35.568] [DEBUG] PcapReader: Packet 18 IPv4 192.168.0.162 -> 192.168.0.164
[14:25:35.570] [DEBUG] PcapReader: Packet 18 UDP 5060 -> 51416, payload len: 380
[14:25:35.572] [DEBUG] PcapReader: Packet 18 full payload preview: "SIP/2.0 100 Trying\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPjb6b83a62e76f41c58fe9b71e82af61a5\r\nCall-ID: e9270b7c047542ef9af488d27b82162e\r\nFrom: <sip:1001"
[14:25:35.574] [DEBUG] isSIPPayload: Detected SIP response
[14:25:35.576] [DEBUG] PcapReader: Packet 18 detected as SIP, parsing...
[14:25:35.578] [INFO] PcapReader: Found SIP packet 18: 100 e9270b7c047542ef9af488d27b82162e
[14:25:35.579] [DEBUG] PcapReader: Processing packet 19, layers: [0xc00043aa10 0xc00044eb40 0xc00031ab80 0xc000450a20]
[14:25:35.581] [DEBUG] PcapReader: Packet 19 IPv4 192.168.0.162 -> 192.168.0.164
[14:25:35.583] [DEBUG] PcapReader: Packet 19 UDP 5060 -> 51416, payload len: 1073
[14:25:35.585] [DEBUG] PcapReader: Packet 19 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPjb6b83a62e76f41c58fe9b71e82af61a5\r\nCall-ID: e9270b7c047542ef9af488d27b82162e\r\nFrom: <sip:1001@192"
[14:25:35.587] [DEBUG] isSIPPayload: Detected SIP response
[14:25:35.589] [DEBUG] PcapReader: Packet 19 detected as SIP, parsing...
[14:25:35.591] [INFO] PcapReader: Found SIP packet 19: 200 e9270b7c047542ef9af488d27b82162e
[14:25:35.592] [DEBUG] PcapReader: Processing packet 20, layers: [0xc00043aa80 0xc00044ebe0 0xc00031ac00 0xc000450ab0]
[14:25:35.594] [DEBUG] PcapReader: Packet 20 IPv4 192.168.0.164 -> 192.168.0.162
[14:25:35.596] [DEBUG] PcapReader: Packet 20 UDP 51416 -> 5060, payload len: 369
[14:25:35.598] [DEBUG] PcapReader: Packet 20 full payload preview: "ACK sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPj1ec8fc81ae324187a6feecaf02f04ff1\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=c2ffb0450ac24fb098"
[14:25:35.600] [DEBUG] isSIPPayload: Detected SIP method: ACK
[14:25:35.602] [DEBUG] PcapReader: Packet 20 detected as SIP, parsing...
[14:25:35.604] [INFO] PcapReader: Found SIP packet 20: ACK e9270b7c047542ef9af488d27b82162e
[14:25:35.605] [DEBUG] PcapReader: Processing packet 21, layers: [0xc00043aaf0 0xc00044ec80 0xc00031ac80 0xc000450b40]
[14:25:35.607] [DEBUG] PcapReader: Packet 21 IPv4 192.168.0.164 -> 192.168.0.162
[14:25:35.609] [DEBUG] PcapReader: Packet 21 UDP 51416 -> 5060, payload len: 869
[14:25:35.611] [DEBUG] PcapReader: Packet 21 full payload preview: "UPDATE sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPja17c7b2ea9da425d85da051e336794c9\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=c2ffb0450ac24fb"
[14:25:35.613] [DEBUG] isSIPPayload: Detected SIP method: UPDATE
[14:25:35.615] [DEBUG] PcapReader: Packet 21 detected as SIP, parsing...
[14:25:35.617] [INFO] PcapReader: Found SIP packet 21: UPDATE e9270b7c047542ef9af488d27b82162e
[14:25:35.618] [DEBUG] PcapReader: Processing packet 22, layers: [0xc00043ab60 0xc00044ed20 0xc00031ad00 0xc000450bd0]
[14:25:35.620] [DEBUG] PcapReader: Packet 22 IPv4 192.168.0.162 -> 192.168.0.164
[14:25:35.622] [DEBUG] PcapReader: Packet 22 UDP 5060 -> 51416, payload len: 937
[14:25:35.625] [DEBUG] PcapReader: Packet 22 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPja17c7b2ea9da425d85da051e336794c9\r\nCall-ID: e9270b7c047542ef9af488d27b82162e\r\nFrom: <sip:1001@192"
[14:25:35.627] [DEBUG] isSIPPayload: Detected SIP response
[14:25:35.629] [DEBUG] PcapReader: Packet 22 detected as SIP, parsing...
[14:25:35.630] [INFO] PcapReader: Found SIP packet 22: 200 e9270b7c047542ef9af488d27b82162e
[14:25:35.632] [DEBUG] PcapReader: Processing packet 23, layers: [0xc00043abd0 0xc00044edc0 0xc00031ad80 0xc000450c60]
[14:25:35.634] [DEBUG] PcapReader: Packet 23 IPv4 192.168.0.164 -> 192.168.0.162
[14:25:35.636] [DEBUG] PcapReader: Packet 23 UDP 51416 -> 5060, payload len: 398
[14:25:35.638] [DEBUG] PcapReader: Packet 23 full payload preview: "BYE sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPjc372eee10c754ece9a873f8e36a6a0e2\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=c2ffb0450ac24fb098"
[14:25:35.640] [DEBUG] isSIPPayload: Detected SIP method: BYE
[14:25:35.642] [DEBUG] PcapReader: Packet 23 detected as SIP, parsing...
[14:25:35.644] [INFO] PcapReader: Found SIP packet 23: BYE e9270b7c047542ef9af488d27b82162e
[14:25:35.645] [DEBUG] PcapReader: Processing packet 24, layers: [0xc00043ac40 0xc00044ee60 0xc00031ae00 0xc000450cf0]
[14:25:35.647] [DEBUG] PcapReader: Packet 24 IPv4 192.168.0.162 -> 192.168.0.164
[14:25:35.649] [DEBUG] PcapReader: Packet 24 UDP 5060 -> 51416, payload len: 414
[14:25:35.651] [DEBUG] PcapReader: Packet 24 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPjc372eee10c754ece9a873f8e36a6a0e2\r\nCall-ID: e9270b7c047542ef9af488d27b82162e\r\nFrom: <sip:1001@192"
[14:25:35.652] [DEBUG] isSIPPayload: Detected SIP response
[14:25:35.654] [DEBUG] PcapReader: Packet 24 detected as SIP, parsing...
[14:25:35.656] [INFO] PcapReader: Found SIP packet 24: 200 e9270b7c047542ef9af488d27b82162e
[14:25:35.658] [INFO] PcapReader: Finished reading. Total packets: 24, SIP packets: 24
[14:28:06.938] [INFO] Telephony Inspector exited normally

View File

@@ -0,0 +1,175 @@
[14:28:08.952] [INFO] Logger initialized: logs\2026-01-19_14-28-08.log
[14:28:08.956] [INFO] Starting Telephony Inspector
[14:28:12.252] [INFO] PcapReader: Creating reader for D:\Proyectos\telephony-inspector\data\calls.pcap
[14:28:12.256] [INFO] PcapReader: Opening file D:\Proyectos\telephony-inspector\data\calls.pcap
[14:28:12.260] [INFO] PcapReader: File opened successfully, link type: Ethernet
[14:28:12.264] [DEBUG] PcapReader: BPF filter set for SIP ports
[14:28:12.267] [DEBUG] PcapReader: Processing packet 1, layers: [0xc0000e3b20 0xc0000b8640 0xc0000e0280 0xc00037e000]
[14:28:12.272] [DEBUG] PcapReader: Packet 1 IPv4 192.168.0.164 -> 192.168.0.162
[14:28:12.275] [DEBUG] PcapReader: Packet 1 UDP 51416 -> 5060, payload len: 1153
[14:28:12.277] [DEBUG] PcapReader: Packet 1 full payload preview: "INVITE sip:123456@192.168.0.162 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPjc988f0aca12d47aa900f472ea93fc0d6\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=d715109fcadd4"
[14:28:12.280] [DEBUG] isSIPPayload: Detected SIP method: INVITE
[14:28:12.281] [DEBUG] PcapReader: Packet 1 detected as SIP, parsing...
[14:28:12.283] [INFO] PcapReader: Found SIP packet 1: INVITE e06cb346194a4f9295d3a325b185912f
[14:28:12.285] [DEBUG] PcapReader: Processing packet 2, layers: [0xc0000e3b90 0xc0000b86e0 0xc0000e0300 0xc00037e090]
[14:28:12.286] [DEBUG] PcapReader: Packet 2 IPv4 192.168.0.162 -> 192.168.0.164
[14:28:12.289] [DEBUG] PcapReader: Packet 2 UDP 5060 -> 51416, payload len: 382
[14:28:12.290] [DEBUG] PcapReader: Packet 2 full payload preview: "SIP/2.0 100 Trying\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPjc988f0aca12d47aa900f472ea93fc0d6\r\nCall-ID: e06cb346194a4f9295d3a325b185912f\r\nFrom: <sip:1001"
[14:28:12.292] [DEBUG] isSIPPayload: Detected SIP response
[14:28:12.294] [DEBUG] PcapReader: Packet 2 detected as SIP, parsing...
[14:28:12.296] [INFO] PcapReader: Found SIP packet 2: 100 e06cb346194a4f9295d3a325b185912f
[14:28:12.298] [DEBUG] PcapReader: Processing packet 3, layers: [0xc0000e3c00 0xc0000b8780 0xc0000e0380 0xc00037e120]
[14:28:12.300] [DEBUG] PcapReader: Packet 3 IPv4 192.168.0.162 -> 192.168.0.164
[14:28:12.302] [DEBUG] PcapReader: Packet 3 UDP 5060 -> 51416, payload len: 1075
[14:28:12.304] [DEBUG] PcapReader: Packet 3 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPjc988f0aca12d47aa900f472ea93fc0d6\r\nCall-ID: e06cb346194a4f9295d3a325b185912f\r\nFrom: <sip:1001@192"
[14:28:12.306] [DEBUG] isSIPPayload: Detected SIP response
[14:28:12.307] [DEBUG] PcapReader: Packet 3 detected as SIP, parsing...
[14:28:12.309] [INFO] PcapReader: Found SIP packet 3: 200 e06cb346194a4f9295d3a325b185912f
[14:28:12.311] [DEBUG] PcapReader: Processing packet 4, layers: [0xc0000e3c70 0xc0000b8820 0xc0000e0400 0xc00037e1b0]
[14:28:12.313] [DEBUG] PcapReader: Packet 4 IPv4 192.168.0.164 -> 192.168.0.162
[14:28:12.315] [DEBUG] PcapReader: Packet 4 UDP 51416 -> 5060, payload len: 371
[14:28:12.317] [DEBUG] PcapReader: Packet 4 full payload preview: "ACK sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPjf0cf112e8b5d4759a3417bc63cd5481e\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=d715109fcadd492b8f"
[14:28:12.319] [DEBUG] isSIPPayload: Detected SIP method: ACK
[14:28:12.320] [DEBUG] PcapReader: Packet 4 detected as SIP, parsing...
[14:28:12.322] [INFO] PcapReader: Found SIP packet 4: ACK e06cb346194a4f9295d3a325b185912f
[14:28:12.324] [DEBUG] PcapReader: Processing packet 5, layers: [0xc0000e3ce0 0xc0000b88c0 0xc0000e0480 0xc00037e240]
[14:28:12.326] [DEBUG] PcapReader: Packet 5 IPv4 192.168.0.164 -> 192.168.0.162
[14:28:12.328] [DEBUG] PcapReader: Packet 5 UDP 51416 -> 5060, payload len: 870
[14:28:12.330] [DEBUG] PcapReader: Packet 5 full payload preview: "UPDATE sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPj1453a8f281f04023b1a9d246fb587ca3\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=d715109fcadd492"
[14:28:12.332] [DEBUG] isSIPPayload: Detected SIP method: UPDATE
[14:28:12.334] [DEBUG] PcapReader: Packet 5 detected as SIP, parsing...
[14:28:12.335] [INFO] PcapReader: Found SIP packet 5: UPDATE e06cb346194a4f9295d3a325b185912f
[14:28:12.337] [DEBUG] PcapReader: Processing packet 6, layers: [0xc0000e3d50 0xc0000b8960 0xc0000e0500 0xc00037e2d0]
[14:28:12.339] [DEBUG] PcapReader: Packet 6 IPv4 192.168.0.162 -> 192.168.0.164
[14:28:12.341] [DEBUG] PcapReader: Packet 6 UDP 5060 -> 51416, payload len: 939
[14:28:12.342] [DEBUG] PcapReader: Packet 6 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPj1453a8f281f04023b1a9d246fb587ca3\r\nCall-ID: e06cb346194a4f9295d3a325b185912f\r\nFrom: <sip:1001@192"
[14:28:12.345] [DEBUG] isSIPPayload: Detected SIP response
[14:28:12.346] [DEBUG] PcapReader: Packet 6 detected as SIP, parsing...
[14:28:12.348] [INFO] PcapReader: Found SIP packet 6: 200 e06cb346194a4f9295d3a325b185912f
[14:28:12.350] [DEBUG] PcapReader: Processing packet 7, layers: [0xc0000e3dc0 0xc0000b8a00 0xc0000e0580 0xc00037e360]
[14:28:12.352] [DEBUG] PcapReader: Packet 7 IPv4 192.168.0.164 -> 192.168.0.162
[14:28:12.354] [DEBUG] PcapReader: Packet 7 UDP 51416 -> 5060, payload len: 400
[14:28:12.356] [DEBUG] PcapReader: Packet 7 full payload preview: "BYE sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPj15f5d8bca6884d6794f27c43437f1201\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=d715109fcadd492b8f"
[14:28:12.358] [DEBUG] isSIPPayload: Detected SIP method: BYE
[14:28:12.360] [DEBUG] PcapReader: Packet 7 detected as SIP, parsing...
[14:28:12.361] [INFO] PcapReader: Found SIP packet 7: BYE e06cb346194a4f9295d3a325b185912f
[14:28:12.363] [DEBUG] PcapReader: Processing packet 8, layers: [0xc0000e3e30 0xc0000b8aa0 0xc0000e0600 0xc00037e3f0]
[14:28:12.365] [DEBUG] PcapReader: Packet 8 IPv4 192.168.0.162 -> 192.168.0.164
[14:28:12.367] [DEBUG] PcapReader: Packet 8 UDP 5060 -> 51416, payload len: 416
[14:28:12.369] [DEBUG] PcapReader: Packet 8 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPj15f5d8bca6884d6794f27c43437f1201\r\nCall-ID: e06cb346194a4f9295d3a325b185912f\r\nFrom: <sip:1001@192"
[14:28:12.371] [DEBUG] isSIPPayload: Detected SIP response
[14:28:12.373] [DEBUG] PcapReader: Packet 8 detected as SIP, parsing...
[14:28:12.374] [INFO] PcapReader: Found SIP packet 8: 200 e06cb346194a4f9295d3a325b185912f
[14:28:12.376] [DEBUG] PcapReader: Processing packet 9, layers: [0xc0000e3ea0 0xc0000b8b40 0xc0000e0680 0xc00037e480]
[14:28:12.378] [DEBUG] PcapReader: Packet 9 IPv4 192.168.0.164 -> 192.168.0.162
[14:28:12.380] [DEBUG] PcapReader: Packet 9 UDP 51416 -> 5060, payload len: 1160
[14:28:12.382] [DEBUG] PcapReader: Packet 9 full payload preview: "INVITE sip:962791077@192.168.0.162 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPj25f0f67dd6cb411ab3b6d48b1c0f9ca9\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=820adc6fe0"
[14:28:12.384] [DEBUG] isSIPPayload: Detected SIP method: INVITE
[14:28:12.386] [DEBUG] PcapReader: Packet 9 detected as SIP, parsing...
[14:28:12.388] [INFO] PcapReader: Found SIP packet 9: INVITE a15e53524b304ebf9dd16209f9c95d18
[14:28:12.390] [DEBUG] PcapReader: Processing packet 10, layers: [0xc0000e3f10 0xc0000b8be0 0xc0000e0700 0xc00037e510]
[14:28:12.391] [DEBUG] PcapReader: Packet 10 IPv4 192.168.0.162 -> 192.168.0.164
[14:28:12.394] [DEBUG] PcapReader: Packet 10 UDP 5060 -> 51416, payload len: 385
[14:28:12.395] [DEBUG] PcapReader: Packet 10 full payload preview: "SIP/2.0 100 Trying\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPj25f0f67dd6cb411ab3b6d48b1c0f9ca9\r\nCall-ID: a15e53524b304ebf9dd16209f9c95d18\r\nFrom: <sip:1001"
[14:28:12.397] [DEBUG] isSIPPayload: Detected SIP response
[14:28:12.399] [DEBUG] PcapReader: Packet 10 detected as SIP, parsing...
[14:28:12.401] [INFO] PcapReader: Found SIP packet 10: 100 a15e53524b304ebf9dd16209f9c95d18
[14:28:12.403] [DEBUG] PcapReader: Processing packet 11, layers: [0xc000498000 0xc0000b8c80 0xc0000e0780 0xc00037e5a0]
[14:28:12.405] [DEBUG] PcapReader: Packet 11 IPv4 192.168.0.162 -> 192.168.0.164
[14:28:12.407] [DEBUG] PcapReader: Packet 11 UDP 5060 -> 51416, payload len: 1078
[14:28:12.408] [DEBUG] PcapReader: Packet 11 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPj25f0f67dd6cb411ab3b6d48b1c0f9ca9\r\nCall-ID: a15e53524b304ebf9dd16209f9c95d18\r\nFrom: <sip:1001@192"
[14:28:12.410] [DEBUG] isSIPPayload: Detected SIP response
[14:28:12.413] [DEBUG] PcapReader: Packet 11 detected as SIP, parsing...
[14:28:12.414] [INFO] PcapReader: Found SIP packet 11: 200 a15e53524b304ebf9dd16209f9c95d18
[14:28:12.416] [DEBUG] PcapReader: Processing packet 12, layers: [0xc000498070 0xc0000b8d20 0xc0000e0800 0xc00037e630]
[14:28:12.418] [DEBUG] PcapReader: Packet 12 IPv4 192.168.0.164 -> 192.168.0.162
[14:28:12.419] [DEBUG] PcapReader: Packet 12 UDP 51416 -> 5060, payload len: 374
[14:28:12.421] [DEBUG] PcapReader: Packet 12 full payload preview: "ACK sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPj70a4a90d59254a4885b807deca2166fc\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=820adc6fe0694f93bc"
[14:28:12.423] [DEBUG] isSIPPayload: Detected SIP method: ACK
[14:28:12.425] [DEBUG] PcapReader: Packet 12 detected as SIP, parsing...
[14:28:12.427] [INFO] PcapReader: Found SIP packet 12: ACK a15e53524b304ebf9dd16209f9c95d18
[14:28:12.429] [DEBUG] PcapReader: Processing packet 13, layers: [0xc0004980e0 0xc0000b8dc0 0xc0000e0880 0xc00037e6c0]
[14:28:12.431] [DEBUG] PcapReader: Packet 13 IPv4 192.168.0.164 -> 192.168.0.162
[14:28:12.433] [DEBUG] PcapReader: Packet 13 UDP 51416 -> 5060, payload len: 874
[14:28:12.434] [DEBUG] PcapReader: Packet 13 full payload preview: "UPDATE sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPjda3c200bd4664b39b5d59177c5f53017\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=820adc6fe0694f9"
[14:28:12.436] [DEBUG] isSIPPayload: Detected SIP method: UPDATE
[14:28:12.438] [DEBUG] PcapReader: Packet 13 detected as SIP, parsing...
[14:28:12.440] [INFO] PcapReader: Found SIP packet 13: UPDATE a15e53524b304ebf9dd16209f9c95d18
[14:28:12.442] [DEBUG] PcapReader: Processing packet 14, layers: [0xc000498150 0xc0000b8e60 0xc0000e0900 0xc00037e750]
[14:28:12.444] [DEBUG] PcapReader: Packet 14 IPv4 192.168.0.162 -> 192.168.0.164
[14:28:12.446] [DEBUG] PcapReader: Packet 14 UDP 5060 -> 51416, payload len: 942
[14:28:12.448] [DEBUG] PcapReader: Packet 14 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPjda3c200bd4664b39b5d59177c5f53017\r\nCall-ID: a15e53524b304ebf9dd16209f9c95d18\r\nFrom: <sip:1001@192"
[14:28:12.449] [DEBUG] isSIPPayload: Detected SIP response
[14:28:12.451] [DEBUG] PcapReader: Packet 14 detected as SIP, parsing...
[14:28:12.453] [INFO] PcapReader: Found SIP packet 14: 200 a15e53524b304ebf9dd16209f9c95d18
[14:28:12.455] [DEBUG] PcapReader: Processing packet 15, layers: [0xc0004981c0 0xc0000b8f00 0xc0000e0980 0xc00037e7e0]
[14:28:12.457] [DEBUG] PcapReader: Packet 15 IPv4 192.168.0.164 -> 192.168.0.162
[14:28:12.459] [DEBUG] PcapReader: Packet 15 UDP 51416 -> 5060, payload len: 403
[14:28:12.461] [DEBUG] PcapReader: Packet 15 full payload preview: "BYE sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPjcca874595f7840409818bf98eb6f7629\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=820adc6fe0694f93bc"
[14:28:12.462] [DEBUG] isSIPPayload: Detected SIP method: BYE
[14:28:12.464] [DEBUG] PcapReader: Packet 15 detected as SIP, parsing...
[14:28:12.466] [INFO] PcapReader: Found SIP packet 15: BYE a15e53524b304ebf9dd16209f9c95d18
[14:28:12.468] [DEBUG] PcapReader: Processing packet 16, layers: [0xc000498230 0xc0000b8fa0 0xc0000e0a00 0xc00037e870]
[14:28:12.470] [DEBUG] PcapReader: Packet 16 IPv4 192.168.0.162 -> 192.168.0.164
[14:28:12.472] [DEBUG] PcapReader: Packet 16 UDP 5060 -> 51416, payload len: 419
[14:28:12.474] [DEBUG] PcapReader: Packet 16 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPjcca874595f7840409818bf98eb6f7629\r\nCall-ID: a15e53524b304ebf9dd16209f9c95d18\r\nFrom: <sip:1001@192"
[14:28:12.476] [DEBUG] isSIPPayload: Detected SIP response
[14:28:12.482] [DEBUG] PcapReader: Packet 16 detected as SIP, parsing...
[14:28:12.484] [INFO] PcapReader: Found SIP packet 16: 200 a15e53524b304ebf9dd16209f9c95d18
[14:28:12.485] [DEBUG] PcapReader: Processing packet 17, layers: [0xc0004982a0 0xc0000b9040 0xc0000e0a80 0xc00037e900]
[14:28:12.487] [DEBUG] PcapReader: Packet 17 IPv4 192.168.0.164 -> 192.168.0.162
[14:28:12.489] [DEBUG] PcapReader: Packet 17 UDP 51416 -> 5060, payload len: 1150
[14:28:12.492] [DEBUG] PcapReader: Packet 17 full payload preview: "INVITE sip:3333@192.168.0.162 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPjb6b83a62e76f41c58fe9b71e82af61a5\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=c2ffb0450ac24fb"
[14:28:12.493] [DEBUG] isSIPPayload: Detected SIP method: INVITE
[14:28:12.495] [DEBUG] PcapReader: Packet 17 detected as SIP, parsing...
[14:28:12.497] [INFO] PcapReader: Found SIP packet 17: INVITE e9270b7c047542ef9af488d27b82162e
[14:28:12.499] [DEBUG] PcapReader: Processing packet 18, layers: [0xc000498310 0xc0000b90e0 0xc0000e0b00 0xc00037e990]
[14:28:12.501] [DEBUG] PcapReader: Packet 18 IPv4 192.168.0.162 -> 192.168.0.164
[14:28:12.504] [DEBUG] PcapReader: Packet 18 UDP 5060 -> 51416, payload len: 380
[14:28:12.505] [DEBUG] PcapReader: Packet 18 full payload preview: "SIP/2.0 100 Trying\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPjb6b83a62e76f41c58fe9b71e82af61a5\r\nCall-ID: e9270b7c047542ef9af488d27b82162e\r\nFrom: <sip:1001"
[14:28:12.507] [DEBUG] isSIPPayload: Detected SIP response
[14:28:12.509] [DEBUG] PcapReader: Packet 18 detected as SIP, parsing...
[14:28:12.511] [INFO] PcapReader: Found SIP packet 18: 100 e9270b7c047542ef9af488d27b82162e
[14:28:12.513] [DEBUG] PcapReader: Processing packet 19, layers: [0xc000498380 0xc0000b9180 0xc0000e0b80 0xc00037ea20]
[14:28:12.515] [DEBUG] PcapReader: Packet 19 IPv4 192.168.0.162 -> 192.168.0.164
[14:28:12.517] [DEBUG] PcapReader: Packet 19 UDP 5060 -> 51416, payload len: 1073
[14:28:12.518] [DEBUG] PcapReader: Packet 19 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPjb6b83a62e76f41c58fe9b71e82af61a5\r\nCall-ID: e9270b7c047542ef9af488d27b82162e\r\nFrom: <sip:1001@192"
[14:28:12.521] [DEBUG] isSIPPayload: Detected SIP response
[14:28:12.523] [DEBUG] PcapReader: Packet 19 detected as SIP, parsing...
[14:28:12.524] [INFO] PcapReader: Found SIP packet 19: 200 e9270b7c047542ef9af488d27b82162e
[14:28:12.526] [DEBUG] PcapReader: Processing packet 20, layers: [0xc0004983f0 0xc0000b9220 0xc0000e0c00 0xc00037eab0]
[14:28:12.528] [DEBUG] PcapReader: Packet 20 IPv4 192.168.0.164 -> 192.168.0.162
[14:28:12.530] [DEBUG] PcapReader: Packet 20 UDP 51416 -> 5060, payload len: 369
[14:28:12.532] [DEBUG] PcapReader: Packet 20 full payload preview: "ACK sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPj1ec8fc81ae324187a6feecaf02f04ff1\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=c2ffb0450ac24fb098"
[14:28:12.534] [DEBUG] isSIPPayload: Detected SIP method: ACK
[14:28:12.535] [DEBUG] PcapReader: Packet 20 detected as SIP, parsing...
[14:28:12.537] [INFO] PcapReader: Found SIP packet 20: ACK e9270b7c047542ef9af488d27b82162e
[14:28:12.539] [DEBUG] PcapReader: Processing packet 21, layers: [0xc000498460 0xc0000b92c0 0xc0000e0c80 0xc00037eb40]
[14:28:12.541] [DEBUG] PcapReader: Packet 21 IPv4 192.168.0.164 -> 192.168.0.162
[14:28:12.543] [DEBUG] PcapReader: Packet 21 UDP 51416 -> 5060, payload len: 869
[14:28:12.545] [DEBUG] PcapReader: Packet 21 full payload preview: "UPDATE sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPja17c7b2ea9da425d85da051e336794c9\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=c2ffb0450ac24fb"
[14:28:12.547] [DEBUG] isSIPPayload: Detected SIP method: UPDATE
[14:28:12.548] [DEBUG] PcapReader: Packet 21 detected as SIP, parsing...
[14:28:12.550] [INFO] PcapReader: Found SIP packet 21: UPDATE e9270b7c047542ef9af488d27b82162e
[14:28:12.552] [DEBUG] PcapReader: Processing packet 22, layers: [0xc0004984d0 0xc0000b9360 0xc0000e0d00 0xc00037ebd0]
[14:28:12.554] [DEBUG] PcapReader: Packet 22 IPv4 192.168.0.162 -> 192.168.0.164
[14:28:12.555] [DEBUG] PcapReader: Packet 22 UDP 5060 -> 51416, payload len: 937
[14:28:12.558] [DEBUG] PcapReader: Packet 22 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPja17c7b2ea9da425d85da051e336794c9\r\nCall-ID: e9270b7c047542ef9af488d27b82162e\r\nFrom: <sip:1001@192"
[14:28:12.559] [DEBUG] isSIPPayload: Detected SIP response
[14:28:12.561] [DEBUG] PcapReader: Packet 22 detected as SIP, parsing...
[14:28:12.563] [INFO] PcapReader: Found SIP packet 22: 200 e9270b7c047542ef9af488d27b82162e
[14:28:12.565] [DEBUG] PcapReader: Processing packet 23, layers: [0xc000498540 0xc0000b9400 0xc0000e0d80 0xc00037ec60]
[14:28:12.566] [DEBUG] PcapReader: Packet 23 IPv4 192.168.0.164 -> 192.168.0.162
[14:28:12.568] [DEBUG] PcapReader: Packet 23 UDP 51416 -> 5060, payload len: 398
[14:28:12.570] [DEBUG] PcapReader: Packet 23 full payload preview: "BYE sip:192.168.0.162:5060 SIP/2.0\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPjc372eee10c754ece9a873f8e36a6a0e2\r\nMax-Forwards: 70\r\nFrom: <sip:1001@192.168.0.162>;tag=c2ffb0450ac24fb098"
[14:28:12.572] [DEBUG] isSIPPayload: Detected SIP method: BYE
[14:28:12.574] [DEBUG] PcapReader: Packet 23 detected as SIP, parsing...
[14:28:12.576] [INFO] PcapReader: Found SIP packet 23: BYE e9270b7c047542ef9af488d27b82162e
[14:28:12.578] [DEBUG] PcapReader: Processing packet 24, layers: [0xc0004985b0 0xc0000b94a0 0xc0000e0e00 0xc00037ecf0]
[14:28:12.579] [DEBUG] PcapReader: Packet 24 IPv4 192.168.0.162 -> 192.168.0.164
[14:28:12.581] [DEBUG] PcapReader: Packet 24 UDP 5060 -> 51416, payload len: 414
[14:28:12.583] [DEBUG] PcapReader: Packet 24 full payload preview: "SIP/2.0 200 OK\r\nVia: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPjc372eee10c754ece9a873f8e36a6a0e2\r\nCall-ID: e9270b7c047542ef9af488d27b82162e\r\nFrom: <sip:1001@192"
[14:28:12.585] [DEBUG] isSIPPayload: Detected SIP response
[14:28:12.587] [DEBUG] PcapReader: Packet 24 detected as SIP, parsing...
[14:28:12.588] [INFO] PcapReader: Found SIP packet 24: 200 e9270b7c047542ef9af488d27b82162e
[14:28:12.591] [INFO] PcapReader: Finished reading. Total packets: 24, SIP packets: 24