Documentation
¶
Overview ¶
Package wireguard decodes WireGuard UDP packets per the official protocol specification at https://www.wireguard.com/protocol/.
Wrap-vs-native judgement
Native. The WireGuard wire format is a tight fixed- layout binary header with a documented set of four message types. There are no variable-length integers, no version negotiation, no extensions, and no compression at this layer. Operators paste UDP payload bytes from a Wireshark wg dissector, an `iptables -j LOG` capture, or any `tcpdump -X udp port 51820` line and inspect every documented field. Pure offline parser. The cryptographic primitives (Curve25519, Blake2s, ChaCha20Poly1305, XChaCha20Poly1305) are NOT decoded — encrypted material is surfaced as hex for traceability, and decryption belongs in a separate Spec.
What this package covers
Auto-detect by leading message-type byte: 0x01 Handshake Initiation, 0x02 Handshake Response, 0x03 Cookie Reply, 0x04 Transport Data. The 3 reserved bytes after the type are required to be zero per spec — non-zero values are surfaced as a note (some middleboxes / forks abuse them).
**Handshake Initiation** (148 bytes fixed): sender index (u32 LE) + unencrypted ephemeral Curve25519 public key (32 bytes) + encrypted static key (32+16 AEAD) + encrypted timestamp (12+16 AEAD) + MAC1 (16 bytes Blake2s(MAC1_key || msg)) + MAC2 (16 bytes, zero when no cookie).
**Handshake Response** (92 bytes fixed): sender index
receiver index + unencrypted ephemeral key (32 bytes)
encrypted nothing (0+16 AEAD — proves the static keypair was used) + MAC1 + MAC2.
**Cookie Reply** (64 bytes fixed): receiver index + nonce (24 bytes XChaCha20Poly1305) + encrypted cookie (16+16 AEAD).
**Transport Data** (variable, ≥ 32 bytes): receiver index + counter (u64 LE — increments per direction; replay-protection nonce) + encrypted encapsulated packet (≥0 bytes plaintext IP packet + 16-byte Poly1305 tag). Surfaces the payload length as the inner-IP-packet length minus the 16-byte tag.
MAC2 detection: the all-zero pattern is recognised and flagged as "no cookie applied" — clients only populate MAC2 after they receive a Cookie Reply.
What this package does NOT cover (deliberately out of scope)
Decryption — operators need the static + ephemeral key material plus the noise-IK handshake state. A separate Spec would handle the symmetric layer.
Noise IK handshake state machine — we surface what's on the wire; reconstructing the chain of derived keys is a session-tracker's job.
UDP / IP framing — feed the UDP payload bytes after the IP+UDP headers (or after a Wireshark Follow UDP Stream extraction).
MAC1 / MAC2 verification — would require the responder's static public key. The values are surfaced so an operator with the key can re-derive and verify.
Cookie reply re-derivation (Blake2s of source IP + port + responder mac1_key) — same reason.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Cookie ¶
type Cookie struct {
ReceiverIndex uint32 `json:"receiver_index"`
ReceiverIndexHex string `json:"receiver_index_hex"`
NonceHex string `json:"nonce_hex"`
EncryptedCookie string `json:"encrypted_cookie_hex"`
}
Cookie is the body of message type 3.
type Initiation ¶
type Initiation struct {
SenderIndex uint32 `json:"sender_index"`
SenderIndexHex string `json:"sender_index_hex"`
EphemeralPubKeyHex string `json:"unencrypted_ephemeral_pubkey_hex"`
EncryptedStaticHex string `json:"encrypted_static_hex"`
EncryptedTimestampHex string `json:"encrypted_timestamp_hex"`
MAC1Hex string `json:"mac1_hex"`
MAC2Hex string `json:"mac2_hex"`
MAC2Zero bool `json:"mac2_zero"`
}
Initiation is the body of message type 1.
type Response ¶
type Response struct {
SenderIndex uint32 `json:"sender_index"`
SenderIndexHex string `json:"sender_index_hex"`
ReceiverIndex uint32 `json:"receiver_index"`
ReceiverIndexHex string `json:"receiver_index_hex"`
EphemeralPubKeyHex string `json:"unencrypted_ephemeral_pubkey_hex"`
EncryptedNothingHex string `json:"encrypted_nothing_hex"`
MAC1Hex string `json:"mac1_hex"`
MAC2Hex string `json:"mac2_hex"`
MAC2Zero bool `json:"mac2_zero"`
}
Response is the body of message type 2.
type Result ¶
type Result struct {
MessageType int `json:"message_type"`
MessageTypeName string `json:"message_type_name"`
TotalBytes int `json:"total_bytes"`
ReservedZero bool `json:"reserved_zero"`
ReservedHex string `json:"reserved_hex,omitempty"`
Initiation *Initiation `json:"initiation,omitempty"`
Response *Response `json:"response,omitempty"`
Cookie *Cookie `json:"cookie_reply,omitempty"`
Transport *Transport `json:"transport,omitempty"`
Notes []string `json:"notes,omitempty"`
}
Result is the top-level decoded view.
type Transport ¶
type Transport struct {
ReceiverIndex uint32 `json:"receiver_index"`
ReceiverIndexHex string `json:"receiver_index_hex"`
Counter uint64 `json:"counter"`
EncryptedPayloadHex string `json:"encrypted_payload_hex,omitempty"`
EncryptedPayloadLen int `json:"encrypted_payload_length"`
InnerPlaintextLen int `json:"inner_plaintext_length_inferred"`
KeepAlive bool `json:"keep_alive,omitempty"`
}
Transport is the body of message type 4.