From 996ba03612cffaa3368fb27a330db44af5ef3300 Mon Sep 17 00:00:00 2001 From: Patricio Whittingslow Date: Sun, 22 Feb 2026 10:47:58 -0300 Subject: [PATCH] add xnet.CapturePrinter type --- x/xnet/pcap-printer.go | 62 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 x/xnet/pcap-printer.go diff --git a/x/xnet/pcap-printer.go b/x/xnet/pcap-printer.go new file mode 100644 index 0000000..b0fbb90 --- /dev/null +++ b/x/xnet/pcap-printer.go @@ -0,0 +1,62 @@ +package xnet + +import ( + "io" + "strconv" + + "github.com/soypat/lneto/internet/pcap" +) + +type CapturePrinterConfig struct { + NamespaceWidth int +} + +// CapturePrinter prints internet packets using the [pcap.PacketBreakdown] and [pcap.Formatter] types. +type CapturePrinter struct { + write func(b []byte) (int, error) + frms []pcap.Frame + cap pcap.PacketBreakdown + pfmt pcap.Formatter + fmtPcapBuf []byte + // minimum length of namespace on print. + namespaceminwidth int +} + +func (stack *CapturePrinter) Configure(writer io.Writer, cfg CapturePrinterConfig) error { + stack.namespaceminwidth = cfg.NamespaceWidth + stack.write = writer.Write + return nil +} + +// Formatter returns a pointer to the underlying pcap.Formatter type. +// One can then configure the formatter's fields to affect printing. +func (stack *CapturePrinter) Formatter() *pcap.Formatter { + return &stack.pfmt +} + +func (stack *CapturePrinter) PrintPacket(prefix string, pkt []byte) { + fmtbuf := stack.fmtPcapBuf[:0] + var err error + stack.frms, err = stack.cap.CaptureEthernet(stack.frms[:0], pkt, 0) + if err == nil { + fmtbuf = append(fmtbuf, prefix...) + // Ensure minimum width of packet length display for less jitter in log viewline. + prevlen := len(prefix) + fmtbuf = strconv.AppendInt(fmtbuf, int64(len(pkt)), 10) + numLength := len(fmtbuf) - prevlen + appendSpaces := max(0, stack.namespaceminwidth-numLength) + 1 // add single space to separate actual format from packet length. + for range appendSpaces { + fmtbuf = append(fmtbuf, ' ') + } + fmtbuf, err = stack.pfmt.FormatFrames(fmtbuf, stack.frms, pkt) + } + fmtbuf = append(fmtbuf, '\n') + if err != nil { + fmtbuf = append(fmtbuf, "ERROR "...) + fmtbuf = append(fmtbuf, prefix...) + fmtbuf = append(fmtbuf, ": "...) + fmtbuf = append(fmtbuf, err.Error()...) + } + stack.write(fmtbuf) + stack.fmtPcapBuf = fmtbuf[:0] // Reuse buffer if allocated at larger size. +}