Beyond gopacket: Introducing goscapy, the Powerful Go Network Library

The article examines goscapy, a pure‑Go network library that brings Scapy‑style stream‑builder APIs, automatic checksum calculation, protocol inference and zero‑copy serialization to Go, and compares it in depth with gopacket, showing code examples, performance tricks, and practical use‑cases such as ARP and TCP SYN scanning.

BirdNest Tech Talk
BirdNest Tech Talk
BirdNest Tech Talk
Beyond gopacket: Introducing goscapy, the Powerful Go Network Library

Core Design: Builder API and Shortcut Functions

goscapy provides two ways to construct packets:

Builder API – chainable methods that add protocol layers. Example:

pkt, err := goscapy.NewEthernet().
    SrcMAC("aa:bb:cc:dd:ee:ff").
    DstMAC("ff:ff:ff:ff:ff:ff").
    Over(goscapy.NewIP().SrcIP("192.168.1.1").DstIP("8.8.8.8")).
    Over(goscapy.NewICMP().Type(8).Code(0)).
    Build()

Shortcut functions – common layer combinations in a single call. Example:

pkt, _ := goscapy.EtherIPTCP("aa:bb:cc:dd:ee:ff", "ff:ff:ff:ff:ff:ff", "192.168.1.1", "10.0.0.1", 12345, 80, layers.TCPSyn)

pkt, _ := goscapy.EtherARP("aa:bb:cc:dd:ee:ff", "ff:ff:ff:ff:ff:ff", "192.168.1.1", "192.168.1.2", layers.ARPWhoHas)

Both approaches are type‑safe and validated at compile time.

Automatic Checksums and Layer Binding

When Build() is invoked, each layer registers a BuildHook that automatically computes total lengths, IP header checksums, TCP/UDP pseudo‑header checksums, and other derived fields. No manual SerializeOptions{ComputeChecksums:true} is required.

Layer‑to‑layer binding rules (e.g., Ethernet type 0x0800 → IP, IP proto 6 → TCP) are stored in a registration table. Calling Over() automatically sets the correct magic numbers, eliminating the need to remember protocol constants.

Packet Dissection: Automatic Protocol Inference

Dissect()

walks the registration‑driven table to infer the full protocol stack from raw bytes. Heuristic rules map well‑known ports to applications (e.g., UDP 53 → DNS, TCP 80 → HTTP). Nested tunnels such as VXLAN are supported up to eight layers.

Send/Receive and Sniffing

Sending mirrors Scapy’s sr() / sr1() model:

pkt := goscapy.NewEthernet().
    DstMAC("ff:ff:ff:ff:ff:ff").
    Over(goscapy.NewIP().SrcIP("192.168.1.1").DstIP("8.8.8.8")).
    Over(goscapy.NewICMP().Type(8).Code(0)).
    Packet()

sendrecv.Send(pkt, "eth0")   // L3 send (OS adds Ethernet)
sendrecv.Sendp(pkt, "eth0")  // L2 send (full Ethernet frame)

Response matching is handled by DefaultMatch, which automatically pairs ICMP Echo‑Request/Reply, TCP SYN/SYN‑ACK, UDP port pairs, DNS transaction IDs, ARP requests/replies, etc., without user‑written matching logic.

Sniffing offers two APIs:

Callback‑style for streaming processing.

Channel‑style for batch collection.

Both use BPF filters that run in the kernel for high performance.

Protocol Coverage

goscapy ships with built‑in support for more than 30 protocols across multiple layers:

Link: Ethernet, ARP, 802.1Q (VLAN), 802.11 (WiFi), RadioTap, Bluetooth HCI/L2CAP/ATT

Network: IPv4, IPv6, IPv6 extension headers, ICMPv6, NDP

Transport: TCP (with options), UDP, ICMP, GRE, VXLAN

Routing: OSPF, BGP, LLDP

Application: DNS, DHCP, HTTP, NTP, TLS, QUIC, SNMP, RADIUS, LDAP, Kerberos

IoT/Wireless: Zigbee (NWK/APS/Cluster), LoRaWAN, Bluetooth

Monitoring/Stream: Netflow V5/V9, IPFIX, RTP, RTCP, SIP, ERSPAN

Tunnel: VXLAN, GRE, ERSPAN v3, QinQ

Practical Examples

ARP Scanner (≈200 LOC)

Build an ARP request, send it with Srp1(), extract the MAC address, and limit concurrency with a semaphore. A /24 subnet scan completes in a few seconds.

pkt := goscapy.NewEthernet().
    DstMAC("ff:ff:ff:ff:ff:ff").
    SrcMAC(srcMAC).
    Type(layers.EtherTypeARP).
    Over(goscapy.NewARP().
        Op(layers.ARPWhoHas).
        SrcMAC(srcMAC).
        SrcIP(srcIP).
        DstIP(targetIP)).
    Packet()

_, reply, err := sendrecv.Srp1(pkt, iface, timeout, nil)
arpLayer := reply.GetLayer("ARP")
hwSrc, _ := arpLayer.Get("hwsrc")

TCP SYN Scan

Construct a SYN packet, send it, and verify the reply flags for SYN‑ACK using DefaultMatch:

pkt := goscapy.NewIP().SrcIP(srcIP).DstIP(targetIP).
    Over(goscapy.NewTCP().SrcPort(12345).DstPort(port).Flags(layers.TCPSyn)).
    Packet()

_, reply, err := sendrecv.Sr1(pkt, iface, 2*time.Second, nil)
if err == nil && reply != nil {
    tcpLayer := reply.GetLayer("TCP")
    flags, _ := tcpLayer.Get("flags")
    if flags.(uint8)&layers.TCPSyn != 0 && flags.(uint8)&layers.TCPAck != 0 {
        fmt.Printf("Port %d: OPEN
", port)
    }
}

Internal Architecture: Three‑Layer Abstraction

goscapy layer – user‑facing Builder API and shortcut functions.

packet layer – core abstractions Packet, Layer, Dissect, BindingRule, and BuildHook.

fields layer – type‑safe field implementations ( ByteField, ShortField, MACField, etc.) that support zero‑copy PackInto and SerializeInto.

This separation makes adding a new protocol straightforward: define the field list, register binding rules, and provide a BuildHook.

Performance: Zero‑Copy Serialization

SerializeInto

– writes directly into a user‑provided buffer. BuildInto – builds the whole packet in‑place into a caller‑supplied slice. RecvInto – reads packets directly into a buffer.

Checksum calculation folds multiple memory regions without extra copies.

Linux‑specific high‑throughput paths such as AF_PACKET mmap, PACKET_QDISC_BYPASS, and io_uring are demonstrated in the examples directory.

buf := make([]byte, 1500) // MTU‑size buffer
result, err := pkt.BuildInto(buf) // zero‑copy write

Rich Example Suite

More than 50 examples cover basic tasks (ping, traceroute, ARP/TCP scans), protocol clients (DNS, DHCP, NTP), tunneling (VXLAN, GRE, ERSPAN), advanced features (pcap I/O, TCP stream reassembly, BPF filtering), wireless frames, and security use‑cases. Each can be run with go run.

When to Use Which Library

gopacket – excels when deep libpcap integration, obscure protocol support, or heavy pcap file processing is required.

goscapy – better suited for security tools, fast packet generation, and network monitoring where a pure‑Go, easy‑to‑use API and zero‑dependency deployment are valuable.

Conclusion

goscapy brings Scapy‑style ergonomics to Go, offering stream‑builder APIs, automatic checksum and binding, protocol inference, zero‑copy performance, and a large example collection, making Go network programming more concise and productive.

Project URL: https://github.com/smallnest/goscapy

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

GoZero-copyNetwork SecurityNetwork ProgramminggopacketScapyPacket craftinggoscapy
BirdNest Tech Talk
Written by

BirdNest Tech Talk

Author of the rpcx microservice framework, original book author, and chair of Baidu's Go CMC committee.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.