natlab

package
v0.0.0-...-113f59a Latest Latest
Warning

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

Go to latest
Published: Feb 16, 2024 License: BSD-3-Clause Imports: 16 Imported by: 0

Documentation

Overview

Package natlab lets us simulate different types of networks all in-memory without running VMs or requiring root, etc. Despite the name, it does more than just NATs. But NATs are the most interesting.

Index

Constants

View Source
const DefaultMappingTimeout = 30 * time.Second

DefaultMappingTimeout is the default timeout for a NAT mapping.

View Source
const DefaultSessionTimeout = 30 * time.Second

DefaultSessionTimeout is the default timeout for a firewall session.

Variables

This section is empty.

Functions

This section is empty.

Types

type Firewall

type Firewall struct {
	// SessionTimeout is the lifetime of idle sessions in the firewall
	// state. Packets transiting from the TrustedInterface reset the
	// session lifetime to SessionTimeout. If zero,
	// DefaultSessionTimeout is used.
	SessionTimeout time.Duration
	// Type specifies how precisely return traffic must match
	// previously seen outbound traffic to be allowed. Defaults to
	// AddressAndPortDependentFirewall.
	Type FirewallType
	// TrustedInterface is an optional interface that is considered
	// trusted in addition to PacketConns local to the Machine. All
	// other interfaces can only respond to traffic from
	// TrustedInterface or the local host.
	TrustedInterface *Interface
	// TimeNow is a function returning the current time. If nil,
	// time.Now is used.
	TimeNow func() time.Time
	// contains filtered or unexported fields
}

Firewall is a simple stateful firewall that allows all outbound traffic and filters inbound traffic based on recently seen outbound traffic. Its HandlePacket method should be attached to a Machine to give it a stateful firewall.

func (*Firewall) HandleForward

func (f *Firewall) HandleForward(p *Packet, iif *Interface, oif *Interface) *Packet

func (*Firewall) HandleIn

func (f *Firewall) HandleIn(p *Packet, iif *Interface) *Packet

func (*Firewall) HandleOut

func (f *Firewall) HandleOut(p *Packet, oif *Interface) *Packet

func (*Firewall) Reset

func (f *Firewall) Reset()

Reset drops all firewall state, forgetting all flows.

type FirewallType

type FirewallType int

FirewallType is the type of filtering a stateful firewall does. Values express different modes defined by RFC 4787.

const (
	// AddressAndPortDependentFirewall specifies a destination
	// address-and-port dependent firewall. Outbound traffic to an
	// ip:port authorizes traffic from that ip:port exactly, and
	// nothing else.
	AddressAndPortDependentFirewall FirewallType = iota
	// AddressDependentFirewall specifies a destination address
	// dependent firewall. Once outbound traffic has been seen to an
	// IP address, that IP address can talk back from any port.
	AddressDependentFirewall
	// EndpointIndependentFirewall specifies a destination endpoint
	// independent firewall. Once outbound traffic has been seen from
	// a source, anyone can talk back to that source.
	EndpointIndependentFirewall
)

type Interface

type Interface struct {
	// contains filtered or unexported fields
}

func (*Interface) Contains

func (f *Interface) Contains(ip netip.Addr) bool

Contains reports whether f contains ip as an IP.

func (*Interface) Machine

func (f *Interface) Machine() *Machine

func (*Interface) Network

func (f *Interface) Network() *Network

func (*Interface) String

func (f *Interface) String() string

func (*Interface) V4

func (f *Interface) V4() netip.Addr

V4 returns the machine's first IPv4 address, or the zero value if none.

func (*Interface) V6

func (f *Interface) V6() netip.Addr

V6 returns the machine's first IPv6 address, or the zero value if none.

type Machine

type Machine struct {
	// Name is a pretty name for debugging and packet tracing. It need
	// not be globally unique.
	Name string

	// PacketHandler, if not nil, is a PacketHandler implementation
	// that inspects all packets arriving, departing, or transiting
	// the Machine. See the definition of the PacketHandler interface
	// for semantics.
	//
	// If PacketHandler is nil, the machine allows all inbound
	// traffic, all outbound traffic, and drops forwarded packets.
	PacketHandler PacketHandler
	// contains filtered or unexported fields
}

A Machine is a representation of an operating system's network stack. It has a network routing table and can have multiple attached networks. The zero value is valid, but lacks any networking capability until Attach is called.

func (*Machine) AddNetwork

func (m *Machine) AddNetwork(n *Network)

func (*Machine) Attach

func (m *Machine) Attach(interfaceName string, n *Network) *Interface

Attach adds an interface to a machine.

The first interface added to a Machine becomes that machine's default route.

func (*Machine) ListenPacket

func (m *Machine) ListenPacket(ctx context.Context, network, address string) (net.PacketConn, error)

type NATType

type NATType int

NATType is the mapping behavior of a NAT device. Values express different modes defined by RFC 4787.

const (
	// EndpointIndependentNAT specifies a destination endpoint
	// independent NAT. All traffic from a source ip:port gets mapped
	// to a single WAN ip:port.
	EndpointIndependentNAT NATType = iota
	// AddressDependentNAT specifies a destination address dependent
	// NAT. Every distinct destination IP gets its own WAN ip:port
	// allocation.
	AddressDependentNAT
	// AddressAndPortDependentNAT specifies a destination
	// address-and-port dependent NAT. Every distinct destination
	// ip:port gets its own WAN ip:port allocation.
	AddressAndPortDependentNAT
)

type Network

type Network struct {
	Name    string
	Prefix4 netip.Prefix
	Prefix6 netip.Prefix
	// contains filtered or unexported fields
}

func NewInternet

func NewInternet() *Network

NewInternet returns a network that simulates the internet.

func (*Network) SetDefaultGateway

func (n *Network) SetDefaultGateway(gwIf *Interface)

type Packet

type Packet struct {
	Src, Dst netip.AddrPort
	Payload  []byte
	// contains filtered or unexported fields
}

Packet represents a UDP packet flowing through the virtual network.

func (*Packet) Clone

func (p *Packet) Clone() *Packet

Clone returns a copy of p that shares nothing with p.

func (*Packet) Equivalent

func (p *Packet) Equivalent(p2 *Packet) bool

Equivalent returns true if Src, Dst and Payload are the same in p and p2.

func (*Packet) Trace

func (p *Packet) Trace(msg string, args ...any)

type PacketHandler

type PacketHandler interface {
	// HandleIn processes a packet arriving on iif, whose destination
	// is an IP address owned by the attached Machine. If p is
	// returned unmodified, the Machine will go on to deliver the
	// Packet to the appropriate listening PacketConn, if one exists.
	HandleIn(p *Packet, iif *Interface) *Packet
	// HandleOut processes a packet about to depart on oif from a
	// local PacketConn. If p is returned unmodified, the Machine will
	// transmit the Packet on oif.
	HandleOut(p *Packet, oif *Interface) *Packet
	// HandleForward is called when the Machine wants to forward a
	// packet from iif to oif. If p is returned unmodified, the
	// Machine will transmit the packet on oif.
	HandleForward(p *Packet, iif, oif *Interface) *Packet
}

A PacketHandler can look at packets arriving at, departing, and transiting a Machine, and filter or mutate them.

Each method is invoked with a Packet that natlab would like to keep processing. Handlers can return that same Packet to allow processing to continue; nil to drop the Packet; or a different Packet that should be processed instead of the original.

Packets passed to handlers share no state with anything else, and are therefore safe to mutate. It's safe to return the original packet mutated in-place, or a brand new packet initialized from scratch.

Packets mutated by a PacketHandler are processed anew by the associated Machine, as if the packet had always been the mutated one. For example, if HandleForward is invoked with a Packet, and the handler changes the destination IP address to one of the Machine's own IPs, the Machine restarts delivery, but this time going to a local PacketConn (which in turn will invoke HandleIn, since the packet is now destined for local delivery).

type PacketVerdict

type PacketVerdict int

A PacketVerdict is a decision of what to do with a packet.

const (
	// Continue means the packet should be processed by the "local
	// sockets" logic of the Machine.
	Continue PacketVerdict = iota
	// Drop means the packet should not be handled further.
	Drop
)

func (PacketVerdict) String

func (v PacketVerdict) String() string

type SNAT44

type SNAT44 struct {
	// Machine is the machine to which this NAT is attached. Altered
	// packets are injected back into this Machine for processing.
	Machine *Machine
	// ExternalInterface is the "WAN" interface of Machine. Packets
	// from other sources get NATed onto this interface.
	ExternalInterface *Interface
	// Type specifies the mapping allocation behavior for this NAT.
	Type NATType
	// MappingTimeout is the lifetime of individual NAT sessions. Once
	// a session expires, the mapped port effectively "closes" to new
	// traffic. If MappingTimeout is 0, DefaultMappingTimeout is used.
	MappingTimeout time.Duration
	// Firewall is an optional packet handler that will be invoked as
	// a firewall during NAT translation. The firewall always sees
	// packets in their "LAN form", i.e. before translation in the
	// outbound direction and after translation in the inbound
	// direction.
	Firewall PacketHandler
	// TimeNow is a function that returns the current time. If
	// nil, time.Now is used.
	TimeNow func() time.Time
	// contains filtered or unexported fields
}

SNAT44 implements an IPv4-to-IPv4 source NAT (SNAT) translator, with optional builtin firewall.

func (*SNAT44) HandleForward

func (n *SNAT44) HandleForward(p *Packet, iif, oif *Interface) *Packet

func (*SNAT44) HandleIn

func (n *SNAT44) HandleIn(p *Packet, iif *Interface) *Packet

func (*SNAT44) HandleOut

func (n *SNAT44) HandleOut(p *Packet, oif *Interface) *Packet

Jump to

Keyboard shortcuts

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