feat(tui): refine transaction flow with source/dest IPs and improved styling

This commit is contained in:
Jose Luis Montañes Ojados
2026-01-20 22:28:20 +01:00
parent c052cc72fb
commit 713903c463
2 changed files with 243 additions and 8 deletions

View File

@@ -0,0 +1,223 @@
Call Detail Export
==================
Date: Tue, 20 Jan 2026 22:27:28 CET
Call-ID: e06cb346194a4f9295d3a325b185912f
From: <sip:1001@192.168.0.162>;tag=d715109fcadd492b8fa1ce009ae2c095
To: <sip:123456@192.168.0.162>
State: Connected
Duration: 2.81879s
Packets: 8
Network Layer:
Source: Windows (Carrier) (192.168.0.164:51416)
Destination: Asterisk (PBX) (192.168.0.162:5060)
Network Context:
- Windows (Carrier): 192.168.0.164
- Asterisk (PBX): 192.168.0.162
Transaction Flow:
-----------------
01. [14:24:30.477] Windows (Carrier) (192.168.0.164) -> Asterisk (PBX) (192.168.0.162) (INVITE line 1153)
02. [14:24:30.478] Asterisk (PBX) (192.168.0.162) <- Windows (Carrier) (192.168.0.164) (Trying line 382)
03. [14:24:30.479] Asterisk (PBX) (192.168.0.162) <- Windows (Carrier) (192.168.0.164) (OK line 1075)
04. [14:24:30.479] Windows (Carrier) (192.168.0.164) -> Asterisk (PBX) (192.168.0.162) (ACK line 371)
05. [14:24:30.479] Windows (Carrier) (192.168.0.164) -> Asterisk (PBX) (192.168.0.162) (UPDATE line 870)
06. [14:24:30.480] Asterisk (PBX) (192.168.0.162) <- Windows (Carrier) (192.168.0.164) (OK line 939)
07. [14:24:33.296] Windows (Carrier) (192.168.0.164) -> Asterisk (PBX) (192.168.0.162) (BYE line 400)
08. [14:24:33.296] Asterisk (PBX) (192.168.0.162) <- Windows (Carrier) (192.168.0.164) (OK line 416)
Packet Details:
---------------
--- Packet 1 [14:24:30.477] ---
Windows (Carrier) (192.168.0.164) -> Asterisk (PBX) (192.168.0.162)
INVITE sip:123456@192.168.0.162 SIP/2.0
Via: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPjc988f0aca12d47aa900f472ea93fc0d6
Max-Forwards: 70
From: <sip:1001@192.168.0.162>;tag=d715109fcadd492b8fa1ce009ae2c095
To: <sip:123456@192.168.0.162>
Contact: <sip:1001@192.168.0.164:51416;ob>
Call-ID: e06cb346194a4f9295d3a325b185912f
CSeq: 12831 INVITE
Allow: PRACK, INVITE, ACK, BYE, CANCEL, UPDATE, INFO, SUBSCRIBE, NOTIFY, REFER, MESSAGE, OPTIONS
Supported: replaces, 100rel, timer, norefersub
Session-Expires: 1800
Min-SE: 90
User-Agent: MicroSIP/3.21.6
Content-Type: application/sdp
Content-Length: 527
v=0
o=- 3977821470 3977821470 IN IP4 192.168.0.164
s=pjmedia
b=AS:84
t=0 0
a=X-nat:0
m=audio 4040 RTP/AVP 0 8 96 101 102
c=IN IP4 192.168.0.164
b=TIAS:64000
a=rtcp:4041 IN IP4 192.168.0.164
a=sendrecv
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:96 opus/48000/2
a=fmtp:96 maxplaybackrate=24000;sprop-maxcapturerate=24000;maxaveragebitrate=64000;useinbandfec=1
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=rtpmap:102 telephone-event/48000
a=fmtp:102 0-16
a=ssrc:825569477 cname:1f442b6f1a4c18c5
--- Packet 2 [14:24:30.478] ---
Asterisk (PBX) (192.168.0.162) -> Windows (Carrier) (192.168.0.164)
SIP/2.0 100 Trying
Via: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPjc988f0aca12d47aa900f472ea93fc0d6
Call-ID: e06cb346194a4f9295d3a325b185912f
From: <sip:1001@192.168.0.162>;tag=d715109fcadd492b8fa1ce009ae2c095
To: <sip:123456@192.168.0.162>
CSeq: 12831 INVITE
Server: Asterisk PBX 18.10.0~dfsg+~cs6.10.40431411-2
Content-Length: 0
--- Packet 3 [14:24:30.479] ---
Asterisk (PBX) (192.168.0.162) -> Windows (Carrier) (192.168.0.164)
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPjc988f0aca12d47aa900f472ea93fc0d6
Call-ID: e06cb346194a4f9295d3a325b185912f
From: <sip:1001@192.168.0.162>;tag=d715109fcadd492b8fa1ce009ae2c095
To: <sip:123456@192.168.0.162>;tag=643ebe4c-3476-4110-98e6-1b14f62996e1
CSeq: 12831 INVITE
Server: Asterisk PBX 18.10.0~dfsg+~cs6.10.40431411-2
Contact: <sip:192.168.0.162:5060>
Allow: OPTIONS, REGISTER, SUBSCRIBE, NOTIFY, PUBLISH, INVITE, ACK, BYE, CANCEL, UPDATE, PRACK, MESSAGE, REFER
Supported: 100rel, timer, replaces, norefersub
Session-Expires: 1800;refresher=uac
Require: timer
Content-Type: application/sdp
Content-Length: 375
v=0
o=- 3977821470 3977821472 IN IP4 192.168.0.162
s=Asterisk
c=IN IP4 192.168.0.162
t=0 0
m=audio 12862 RTP/AVP 0 8 96 101
a=rtpmap:0 PCMU/8000
a=rtpmap:8 PCMA/8000
a=rtpmap:96 opus/48000/2
a=fmtp:96 maxplaybackrate=24000;sprop-maxcapturerate=24000;maxaveragebitrate=64000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20
a=maxptime:60
a=sendrecv
--- Packet 4 [14:24:30.479] ---
Windows (Carrier) (192.168.0.164) -> Asterisk (PBX) (192.168.0.162)
ACK sip:192.168.0.162:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPjf0cf112e8b5d4759a3417bc63cd5481e
Max-Forwards: 70
From: <sip:1001@192.168.0.162>;tag=d715109fcadd492b8fa1ce009ae2c095
To: <sip:123456@192.168.0.162>;tag=643ebe4c-3476-4110-98e6-1b14f62996e1
Call-ID: e06cb346194a4f9295d3a325b185912f
CSeq: 12831 ACK
Content-Length: 0
--- Packet 5 [14:24:30.479] ---
Windows (Carrier) (192.168.0.164) -> Asterisk (PBX) (192.168.0.162)
UPDATE sip:192.168.0.162:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPj1453a8f281f04023b1a9d246fb587ca3
Max-Forwards: 70
From: <sip:1001@192.168.0.162>;tag=d715109fcadd492b8fa1ce009ae2c095
To: <sip:123456@192.168.0.162>;tag=643ebe4c-3476-4110-98e6-1b14f62996e1
Contact: <sip:1001@192.168.0.164:51416;ob>
Call-ID: e06cb346194a4f9295d3a325b185912f
CSeq: 12832 UPDATE
Supported: replaces, 100rel, timer, norefersub
Session-Expires: 1800;refresher=uac
Min-SE: 90
Content-Type: application/sdp
Content-Length: 318
v=0
o=- 3977821470 3977821471 IN IP4 192.168.0.164
s=pjmedia
b=AS:84
t=0 0
a=X-nat:0
m=audio 4040 RTP/AVP 0 101
c=IN IP4 192.168.0.164
b=TIAS:64000
a=rtcp:4041 IN IP4 192.168.0.164
a=ssrc:825569477 cname:1f442b6f1a4c18c5
a=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=sendrecv
--- Packet 6 [14:24:30.480] ---
Asterisk (PBX) (192.168.0.162) -> Windows (Carrier) (192.168.0.164)
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPj1453a8f281f04023b1a9d246fb587ca3
Call-ID: e06cb346194a4f9295d3a325b185912f
From: <sip:1001@192.168.0.162>;tag=d715109fcadd492b8fa1ce009ae2c095
To: <sip:123456@192.168.0.162>;tag=643ebe4c-3476-4110-98e6-1b14f62996e1
CSeq: 12832 UPDATE
Session-Expires: 1800;refresher=uac
Require: timer
Contact: <sip:192.168.0.162:5060>
Allow: OPTIONS, REGISTER, SUBSCRIBE, NOTIFY, PUBLISH, INVITE, ACK, BYE, CANCEL, UPDATE, PRACK, MESSAGE, REFER
Supported: 100rel, timer, replaces, norefersub
Server: Asterisk PBX 18.10.0~dfsg+~cs6.10.40431411-2
Content-Type: application/sdp
Content-Length: 239
v=0
o=- 3977821470 3977821473 IN IP4 192.168.0.162
s=Asterisk
c=IN IP4 192.168.0.162
t=0 0
m=audio 12862 RTP/AVP 0 101
a=rtpmap:0 PCMU/8000
a=rtpmap:101 telephone-event/8000
a=fmtp:101 0-16
a=ptime:20
a=maxptime:150
a=sendrecv
--- Packet 7 [14:24:33.296] ---
Windows (Carrier) (192.168.0.164) -> Asterisk (PBX) (192.168.0.162)
BYE sip:192.168.0.162:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.0.164:51416;rport;branch=z9hG4bKPj15f5d8bca6884d6794f27c43437f1201
Max-Forwards: 70
From: <sip:1001@192.168.0.162>;tag=d715109fcadd492b8fa1ce009ae2c095
To: <sip:123456@192.168.0.162>;tag=643ebe4c-3476-4110-98e6-1b14f62996e1
Call-ID: e06cb346194a4f9295d3a325b185912f
CSeq: 12833 BYE
User-Agent: MicroSIP/3.21.6
Content-Length: 0
--- Packet 8 [14:24:33.296] ---
Asterisk (PBX) (192.168.0.162) -> Windows (Carrier) (192.168.0.164)
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.0.164:51416;rport=51416;received=192.168.0.164;branch=z9hG4bKPj15f5d8bca6884d6794f27c43437f1201
Call-ID: e06cb346194a4f9295d3a325b185912f
From: <sip:1001@192.168.0.162>;tag=d715109fcadd492b8fa1ce009ae2c095
To: <sip:123456@192.168.0.162>;tag=643ebe4c-3476-4110-98e6-1b14f62996e1
CSeq: 12833 BYE
Server: Asterisk PBX 18.10.0~dfsg+~cs6.10.40431411-2
Content-Length: 0

View File

@@ -1407,7 +1407,7 @@ func (m *Model) updateCallDetailView() {
arrow := "→"
arrowStyle := m.styles.ArrowOut
if len(flow.Packets) > 0 && pkt.SourceIP != flow.Packets[0].SourceIP {
arrow = "←"
// Keep arrow pointing right as we are showing Src -> Dst
arrowStyle = m.styles.ArrowIn
}
@@ -1440,10 +1440,27 @@ func (m *Model) updateCallDetailView() {
}
}
ts := pkt.Timestamp.Format("15:04:05.000")
// Resolve IPs and apply styles
srcLabel := m.networkMap.LabelForIP(pkt.SourceIP)
if srcNode := m.networkMap.FindByIP(pkt.SourceIP); srcNode != nil {
srcLabel = m.styleForNode(srcNode).Render(srcLabel)
}
dstLabel := m.networkMap.LabelForIP(pkt.DestIP)
if dstNode := m.networkMap.FindByIP(pkt.DestIP); dstNode != nil {
dstLabel = m.styleForNode(dstNode).Render(dstLabel)
}
// Use pre-calculated format
numStr := fmt.Sprintf(numFmt, i+1)
lineStr := fmt.Sprintf("%s [%s] %s %s", numStr, ts, arrowStyle.Render(arrow), summaryStyle.Render(pkt.Summary()))
if i == m.selectedPacketIndex {
numStr = m.styles.Active.Render("> " + numStr)
} else {
numStr = " " + numStr
}
lineStr := fmt.Sprintf("%s %s %s %s %s", numStr, srcLabel, arrowStyle.Render(arrow), dstLabel, summaryStyle.Render(pkt.Summary()))
if pkt.SDP != nil {
mediaIP := pkt.SDP.GetSDPMediaIP()
@@ -1457,11 +1474,6 @@ func (m *Model) updateCallDetailView() {
}
}
if i == m.selectedPacketIndex {
lineStr = m.styles.Active.Render("> " + lineStr)
} else {
lineStr = " " + lineStr
}
right.WriteString(lineStr + "\n")
}