packet

package
v1.6.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 16, 2021 License: BSD-3-Clause Imports: 9 Imported by: 25

Documentation

Overview

Package packet contains packet parsing and marshaling utilities.

Parsed provides allocation-free minimal packet header decoding, for use in packet filtering. The other types in the package are for constructing and marshaling packets into []bytes.

To support allocation-free parsing, this package defines IPv4 and IPv6 address types. You should prefer to use netaddr's types, except where you absolutely need allocation-free IP handling (i.e. in the tunnel datapath) and are willing to implement all codepaths and data structures twice, once per IP family.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func Generate

func Generate(h Header, payload []byte) []byte

Generate generates a new packet with the given Header and payload. This function allocates memory, see Header.Marshal for an allocation-free option.

func Hexdump

func Hexdump(b []byte) string

Types

type Header interface {
	// Len returns the length of the marshaled packet.
	Len() int
	// Marshal serializes the header into buf, which must be at
	// least Len() bytes long. Implementations of Marshal assume
	// that bytes after the first Len() are payload bytes for the
	// purpose of computing length and checksum fields. Marshal
	// implementations must not allocate memory.
	Marshal(buf []byte) error
}

Header is a packet header capable of marshaling itself into a byte buffer.

type ICMP4Code

type ICMP4Code uint8

ICMP4Code is an ICMPv4 code, as specified in https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml

const (
	ICMP4NoCode ICMP4Code = 0
)

type ICMP4Header

type ICMP4Header struct {
	IP4Header
	Type ICMP4Type
	Code ICMP4Code
}

ICMP4Header is an IPv4+ICMPv4 header.

func (ICMP4Header) Len

func (h ICMP4Header) Len() int

Len implements Header.

func (ICMP4Header) Marshal

func (h ICMP4Header) Marshal(buf []byte) error

Marshal implements Header.

func (*ICMP4Header) ToResponse

func (h *ICMP4Header) ToResponse()

ToResponse implements Header. TODO: it doesn't implement it correctly, instead it statically generates an ICMP Echo Reply packet.

type ICMP4Type

type ICMP4Type uint8

ICMP4Type is an ICMPv4 type, as specified in https://www.iana.org/assignments/icmp-parameters/icmp-parameters.xhtml

const (
	ICMP4EchoReply    ICMP4Type = 0x00
	ICMP4EchoRequest  ICMP4Type = 0x08
	ICMP4Unreachable  ICMP4Type = 0x03
	ICMP4TimeExceeded ICMP4Type = 0x0b
)

func (ICMP4Type) String

func (t ICMP4Type) String() string

type ICMP6Code

type ICMP6Code uint8

ICMP6Code is an ICMPv6 code, as specified in https://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xhtml

const (
	ICMP6NoCode ICMP6Code = 0
)

type ICMP6Type

type ICMP6Type uint8

ICMP6Type is an ICMPv6 type, as specified in https://www.iana.org/assignments/icmpv6-parameters/icmpv6-parameters.xhtml

const (
	ICMP6Unreachable  ICMP6Type = 1
	ICMP6TimeExceeded ICMP6Type = 3
	ICMP6EchoRequest  ICMP6Type = 128
	ICMP6EchoReply    ICMP6Type = 129
)

func (ICMP6Type) String

func (t ICMP6Type) String() string

type IP4Header

type IP4Header struct {
	IPProto IPProto
	IPID    uint16
	Src     netaddr.IP
	Dst     netaddr.IP
}

IP4Header represents an IPv4 packet header.

func (IP4Header) Len

func (h IP4Header) Len() int

Len implements Header.

func (IP4Header) Marshal

func (h IP4Header) Marshal(buf []byte) error

Marshal implements Header.

func (*IP4Header) ToResponse

func (h *IP4Header) ToResponse()

ToResponse implements Header.

type IP6Header

type IP6Header struct {
	IPProto IPProto
	IPID    uint32 // only lower 20 bits used
	Src     netaddr.IP
	Dst     netaddr.IP
}

IP6Header represents an IPv6 packet header.

func (IP6Header) Len

func (h IP6Header) Len() int

Len implements Header.

func (IP6Header) Marshal

func (h IP6Header) Marshal(buf []byte) error

Marshal implements Header.

func (*IP6Header) ToResponse

func (h *IP6Header) ToResponse()

ToResponse implements Header.

type IPProto

type IPProto uint8

IPProto is an IP subprotocol as defined by the IANA protocol numbers list (https://www.iana.org/assignments/protocol-numbers/protocol-numbers.xhtml), or the special values Unknown or Fragment.

const (
	// Unknown represents an unknown or unsupported protocol; it's
	// deliberately the zero value. Strictly speaking the zero
	// value is IPv6 hop-by-hop extensions, but we don't support
	// those, so this is still technically correct.
	Unknown IPProto = 0x00

	// Values from the IANA registry.
	ICMPv4 IPProto = 0x01
	IGMP   IPProto = 0x02
	ICMPv6 IPProto = 0x3a
	TCP    IPProto = 0x06
	UDP    IPProto = 0x11

	// TSMP is the Tailscale Message Protocol (our ICMP-ish
	// thing), an IP protocol used only between Tailscale nodes
	// (still encrypted by WireGuard) that communicates why things
	// failed, etc.
	//
	// Proto number 99 is reserved for "any private encryption
	// scheme". We never accept these from the host OS stack nor
	// send them to the host network stack. It's only used between
	// nodes.
	TSMP IPProto = 99

	// Fragment represents any non-first IP fragment, for which we
	// don't have the sub-protocol header (and therefore can't
	// figure out what the sub-protocol is).
	//
	// 0xFF is reserved in the IANA registry, so we steal it for
	// internal use.
	Fragment IPProto = 0xFF
)

func (IPProto) String

func (p IPProto) String() string

type Parsed

type Parsed struct {

	// IPVersion is the IP protocol version of the packet (4 or
	// 6), or 0 if the packet doesn't look like IPv4 or IPv6.
	IPVersion uint8
	// IPProto is the IP subprotocol (UDP, TCP, etc.). Valid iff IPVersion != 0.
	IPProto IPProto
	// SrcIP4 is the source address. Family matches IPVersion. Port is
	// valid iff IPProto == TCP || IPProto == UDP.
	Src netaddr.IPPort
	// DstIP4 is the destination address. Family matches IPVersion.
	Dst netaddr.IPPort
	// TCPFlags is the packet's TCP flag bigs. Valid iff IPProto == TCP.
	TCPFlags TCPFlag
	// contains filtered or unexported fields
}

Parsed is a minimal decoding of a packet suitable for use in filters.

func (*Parsed) AsTailscaleRejectedHeader

func (pp *Parsed) AsTailscaleRejectedHeader() (h TailscaleRejectedHeader, ok bool)

AsTailscaleRejectedHeader parses pp as an incoming rejection connection TSMP message.

ok reports whether pp was a valid TSMP rejection packet.

func (*Parsed) Buffer

func (q *Parsed) Buffer() []byte

Buffer returns the entire packet buffer. This is a read-only view; that is, q retains the ownership of the buffer.

func (*Parsed) Decode

func (q *Parsed) Decode(b []byte)

Decode extracts data from the packet in b into q. It performs extremely simple packet decoding for basic IPv4 packet types. It extracts only the subprotocol id, IP addresses, and (if any) ports, and shouldn't need any memory allocation.

func (*Parsed) ICMP4Header

func (q *Parsed) ICMP4Header() ICMP4Header

func (*Parsed) IP4Header

func (q *Parsed) IP4Header() IP4Header

func (*Parsed) IsEchoRequest

func (q *Parsed) IsEchoRequest() bool

IsEchoRequest reports whether q is an ICMP Echo Request.

func (*Parsed) IsEchoResponse

func (q *Parsed) IsEchoResponse() bool

IsEchoRequest reports whether q is an IPv4 ICMP Echo Response.

func (*Parsed) IsError

func (q *Parsed) IsError() bool

IsError reports whether q is an ICMP "Error" packet.

func (*Parsed) IsTCPSyn

func (q *Parsed) IsTCPSyn() bool

IsTCPSyn reports whether q is a TCP SYN packet (i.e. the first packet in a new connection).

func (*Parsed) Payload

func (q *Parsed) Payload() []byte

Payload returns the payload of the IP subprotocol section. This is a read-only view; that is, q retains the ownership of the buffer.

func (*Parsed) String

func (p *Parsed) String() string

func (*Parsed) StuffForTesting added in v1.6.0

func (q *Parsed) StuffForTesting(len int)

StuffForTesting makes Parsed contain a len-bytes buffer. Used in tests to build up a synthetic parse result with a non-zero buffer.

func (*Parsed) UDP4Header

func (q *Parsed) UDP4Header() UDP4Header

type TCPFlag

type TCPFlag uint8
const (
	TCPFin    TCPFlag = 0x01
	TCPSyn    TCPFlag = 0x02
	TCPRst    TCPFlag = 0x04
	TCPPsh    TCPFlag = 0x08
	TCPAck    TCPFlag = 0x10
	TCPSynAck TCPFlag = TCPSyn | TCPAck
)

type TSMPType

type TSMPType uint8
const (
	// TSMPTypeRejectedConn is the type byte for a TailscaleRejectedHeader.
	TSMPTypeRejectedConn TSMPType = '!'
)

type TailscaleRejectReason

type TailscaleRejectReason byte
const (
	// TailscaleRejectReasonNone is the TailscaleRejectReason zero value.
	TailscaleRejectReasonNone TailscaleRejectReason = 0

	// RejectedDueToACLs means that the host rejected the connection due to ACLs.
	RejectedDueToACLs TailscaleRejectReason = 'A'

	// RejectedDueToShieldsUp means that the host rejected the connection due to shields being up.
	RejectedDueToShieldsUp TailscaleRejectReason = 'S'

	// RejectedDueToIPForwarding means that the relay node's IP
	// forwarding is disabled.
	RejectedDueToIPForwarding TailscaleRejectReason = 'F'

	// RejectedDueToHostFirewall means that the target host's
	// firewall is blocking the traffic.
	RejectedDueToHostFirewall TailscaleRejectReason = 'W'
)

func (TailscaleRejectReason) IsZero added in v1.4.3

func (r TailscaleRejectReason) IsZero() bool

IsZero reports whether r is the zero value, representing no rejection.

func (TailscaleRejectReason) String

func (r TailscaleRejectReason) String() string

type TailscaleRejectedHeader

type TailscaleRejectedHeader struct {
	IPSrc  netaddr.IP            // IPv4 or IPv6 header's src IP
	IPDst  netaddr.IP            // IPv4 or IPv6 header's dst IP
	Src    netaddr.IPPort        // rejected flow's src
	Dst    netaddr.IPPort        // rejected flow's dst
	Proto  IPProto               // proto that was rejected (TCP or UDP)
	Reason TailscaleRejectReason // why the connection was rejected

	// MaybeBroken is whether the rejection is non-terminal (the
	// client should not fail immediately). This is sent by a
	// target when it's not sure whether it's totally broken, but
	// it might be. For example, the target tailscaled might think
	// its host firewall or IP forwarding aren't configured
	// properly, but tailscaled might be wrong (not having enough
	// visibility into what the OS is doing). When true, the
	// message is simply an FYI as a potential reason to use for
	// later when the pendopen connection tracking timer expires.
	MaybeBroken bool
}

TailscaleRejectedHeader is a TSMP message that says that one Tailscale node has rejected the connection from another. Unlike a TCP RST, this includes a reason.

On the wire, after the IP header, it's currently 7 or 8 bytes:

  • '!'
  • IPProto byte (IANA protocol number: TCP or UDP)
  • 'A' or 'S' (RejectedDueToACLs, RejectedDueToShieldsUp)
  • srcPort big endian uint16
  • dstPort big endian uint16
  • [optional] byte of flag bits: lowest bit (0x1): MaybeBroken

In the future it might also accept 16 byte IP flow src/dst IPs after the header, if they're different than the IP-level ones.

func (TailscaleRejectedHeader) Flow

func (TailscaleRejectedHeader) Len

func (h TailscaleRejectedHeader) Len() int

func (TailscaleRejectedHeader) Marshal

func (h TailscaleRejectedHeader) Marshal(buf []byte) error

func (TailscaleRejectedHeader) String

func (rh TailscaleRejectedHeader) String() string

type UDP4Header

type UDP4Header struct {
	IP4Header
	SrcPort uint16
	DstPort uint16
}

UDP4Header is an IPv4+UDP header.

func (UDP4Header) Len

func (h UDP4Header) Len() int

Len implements Header.

func (UDP4Header) Marshal

func (h UDP4Header) Marshal(buf []byte) error

Marshal implements Header.

func (*UDP4Header) ToResponse

func (h *UDP4Header) ToResponse()

ToResponse implements Header.

type UDP6Header

type UDP6Header struct {
	IP6Header
	SrcPort uint16
	DstPort uint16
}

UDP6Header is an IPv6+UDP header.

func (UDP6Header) Len

func (h UDP6Header) Len() int

Len implements Header.

func (UDP6Header) Marshal

func (h UDP6Header) Marshal(buf []byte) error

Marshal implements Header.

func (*UDP6Header) ToResponse

func (h *UDP6Header) ToResponse()

ToResponse implements Header.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL