CapturePrinter expose Ethernet and IP printers

This commit is contained in:
Patricio Whittingslow
2026-06-17 16:42:38 -03:00
parent 5a674a4ad1
commit 059f761856
4 changed files with 36 additions and 11 deletions
+2 -2
View File
@@ -148,7 +148,7 @@ func stackLoop(ctx context.Context, stack *xnet.StackAsync) {
fmt.Println("encaps err:", err) fmt.Println("encaps err:", err)
} else if nwrite > 0 { } else if nwrite > 0 {
network.SendEth(buf[:nwrite]) network.SendEth(buf[:nwrite])
cap.PrintPacket("OUT", buf[:nwrite]) cap.PrintEthernet("OUT", buf[:nwrite])
} }
nread, err := network.RecvEth(buf[:]) nread, err := network.RecvEth(buf[:])
if err != nil { if err != nil {
@@ -158,7 +158,7 @@ func stackLoop(ctx context.Context, stack *xnet.StackAsync) {
if err != nil && err != lneto.ErrPacketDrop { if err != nil && err != lneto.ErrPacketDrop {
fmt.Println("demux err:", err) fmt.Println("demux err:", err)
} else { } else {
cap.PrintPacket("IN ", buf[:nread]) cap.PrintEthernet("IN ", buf[:nread])
} }
} }
if nwrite == 0 && nread == 0 { if nwrite == 0 && nread == 0 {
+27 -2
View File
@@ -5,6 +5,7 @@ import (
"strconv" "strconv"
"time" "time"
"github.com/soypat/lneto"
"github.com/soypat/lneto/internet/pcap" "github.com/soypat/lneto/internet/pcap"
) )
@@ -50,7 +51,20 @@ func (stack *CapturePrinter) Formatter() *pcap.Formatter {
return &stack.pfmt return &stack.pfmt
} }
func (stack *CapturePrinter) PrintPacket(prefix string, pkt []byte) { // PrintIP formats and writes a breakdown of the IPv4 or IPv6 packet, prefixed by prefix.
func (stack *CapturePrinter) PrintIP(prefix string, ipPkt []byte) {
stack.printPacket(prefix, true, ipPkt)
}
// PrintEthernet formats and writes a breakdown of the Ethernet frame, prefixed by prefix.
func (stack *CapturePrinter) PrintEthernet(prefix string, ethPkt []byte) {
stack.printPacket(prefix, false, ethPkt)
}
func (stack *CapturePrinter) printPacket(prefix string, ip bool, pkt []byte) {
if len(pkt) == 0 {
return
}
fmtbuf := stack.fmtPcapBuf[:0] fmtbuf := stack.fmtPcapBuf[:0]
useTimestamps := stack.printTimestamps() useTimestamps := stack.printTimestamps()
var captime time.Time var captime time.Time
@@ -58,7 +72,18 @@ func (stack *CapturePrinter) PrintPacket(prefix string, pkt []byte) {
captime = stack.now() captime = stack.now()
} }
var err error var err error
stack.frms, err = stack.cap.CaptureEthernet(stack.frms[:0], pkt, 0) if ip {
switch pkt[0] >> 4 {
case 4:
stack.frms, err = stack.cap.CaptureIPv4(stack.frms[:0], pkt, 0)
case 6:
stack.frms, err = stack.cap.CaptureIPv6(stack.frms[:0], pkt, 0)
default:
err = lneto.ErrUnsupported
}
} else {
stack.frms, err = stack.cap.CaptureEthernet(stack.frms[:0], pkt, 0)
}
if err == nil { if err == nil {
if useTimestamps { if useTimestamps {
diff := captime.Sub(stack.origin) diff := captime.Sub(stack.origin)
+1 -1
View File
@@ -13,5 +13,5 @@ func init() {
} }
func debugPacket(msg string, b []byte) { func debugPacket(msg string, b []byte) {
_pcap.PrintPacket(msg, b) _pcap.PrintEthernet(msg, b)
} }
+6 -6
View File
@@ -503,7 +503,7 @@ func testStackSeeded(t *testing.T, seed1, seed2 int64) {
betsAreOff = true betsAreOff = true
} }
if verbose { if verbose {
fzppr.PrintPacket(first.Hostname(), buf[:n]) fzppr.PrintEthernet(first.Hostname(), buf[:n])
} }
err = second.IngressEthernet(buf[:n]) err = second.IngressEthernet(buf[:n])
if err != nil && !betsAreOff && err != lneto.ErrPacketDrop && err != lneto.ErrExhausted { if err != nil && !betsAreOff && err != lneto.ErrPacketDrop && err != lneto.ErrExhausted {
@@ -524,7 +524,7 @@ func testStackSeeded(t *testing.T, seed1, seed2 int64) {
betsAreOff = true betsAreOff = true
} }
if verbose { if verbose {
fzppr.PrintPacket(second.Hostname(), buf[:n]) fzppr.PrintEthernet(second.Hostname(), buf[:n])
} }
err = first.IngressEthernet(buf[:n]) err = first.IngressEthernet(buf[:n])
if err != nil && !betsAreOff && err != lneto.ErrPacketDrop && err != lneto.ErrExhausted { if err != nil && !betsAreOff && err != lneto.ErrPacketDrop && err != lneto.ErrExhausted {
@@ -542,21 +542,21 @@ func testStackSeeded(t *testing.T, seed1, seed2 int64) {
limit := d == drainLimit-1 limit := d == drainLimit-1
n, err := first.EgressEthernet(buf[:]) n, err := first.EgressEthernet(buf[:])
if (err != nil || n > 0) && limit { if (err != nil || n > 0) && limit {
fzppr.PrintPacket(first.Hostname(), buf[:n]) fzppr.PrintEthernet(first.Hostname(), buf[:n])
t.Fatal(i, "stuck in data/error loop:", err) t.Fatal(i, "stuck in data/error loop:", err)
} else if n > 0 { } else if n > 0 {
if verbose { if verbose {
fzppr.PrintPacket(first.Hostname(), buf[:n]) fzppr.PrintEthernet(first.Hostname(), buf[:n])
} }
second.IngressEthernet(buf[:n]) second.IngressEthernet(buf[:n])
} }
n, err = second.EgressEthernet(buf[:]) n, err = second.EgressEthernet(buf[:])
if (err != nil || n > 0) && limit { if (err != nil || n > 0) && limit {
fzppr.PrintPacket("(2) ", buf[:n]) fzppr.PrintEthernet("(2) ", buf[:n])
t.Fatal(i, "stuck in data/error loop:", err) t.Fatal(i, "stuck in data/error loop:", err)
} else if n > 0 { } else if n > 0 {
if verbose { if verbose {
fzppr.PrintPacket(second.Hostname(), buf[:n]) fzppr.PrintEthernet(second.Hostname(), buf[:n])
} }
first.IngressEthernet(buf[:n]) first.IngressEthernet(buf[:n])
} }