Documentation
¶
Overview ¶
Package discovery reads the system's network configuration — interfaces, addresses, routes and neighbours — and works out the things a user should not have to type: which interface to use, what source address to send from, and which MAC address the next hop has.
Everything it needs from the kernel goes through the Source interface, so the decision logic is ordinary testable code with no root, no netlink and no hardware. NewSource returns the real netlink-backed implementation.
Index ¶
- Constants
- func DefaultRouteLink(s Source) (int, bool)
- func ExplainVLANInterface(s Source, l Link) string
- func SourceCandidates(l Link, dst netip.Prefix) []netip.Addr
- func Usable(l Link) bool
- type Link
- type MACSource
- type NeedsDstMACError
- type Neighbor
- type Options
- type Resolved
- type Route
- type Source
Constants ¶
const DefaultProbeTimeout = 1500 * time.Millisecond
DefaultProbeTimeout is how long an active ARP probe waits for an answer before giving up. Long enough for a switched LAN, short enough that a mistyped address does not feel like a hang.
Variables ¶
This section is empty.
Functions ¶
func DefaultRouteLink ¶
DefaultRouteLink returns the index of the interface that owns the default route, and whether there is one. Used to warn before blasting traffic out of the interface the machine reaches the world through.
func ExplainVLANInterface ¶
ExplainVLANInterface builds the message shown when a user selects an 802.1Q sub-interface. Rather than a bare rejection it names the interface and flag combination that does what they meant.
func SourceCandidates ¶
SourceCandidates lists the addresses a user may pick as the source for a run, in the order the wizard should offer them: matching the destination's family and scope, and on the same subnet, first.
func Usable ¶
Usable reports whether an interface can carry an AF_XDP run: administratively up, not loopback, with a real 6-byte hardware address and at least one receive queue.
VLAN sub-interfaces are excluded on purpose. Binding AF_XDP to one only ever gets the slow generic path, and the right answer is always to bind the parent NIC and set --vlan, which Wireblast says explicitly when a user picks one. See ExplainVLANInterface.
Types ¶
type Link ¶
type Link struct {
Name string
Index int
MAC net.HardwareAddr
MTU int
// Up is the administrative state; Carrier is whether the link is
// operationally up (a cable is plugged in and negotiated).
Up bool
Carrier bool
Loopback bool
Driver string
// Addrs holds the interface's addresses, IPv4 and IPv6 alike, so the
// wizard can show what the user expects to see.
Addrs []netip.Prefix
// VLANID and ParentIndex are set for an 802.1Q sub-interface; VLANID is 0
// on any other kind of device.
VLANID int
ParentIndex int
// RxQueues is how many receive queues the device exposes. AF_XDP binds one
// socket per queue, so a device with none cannot be used.
RxQueues int
// SpeedMbps is the negotiated link speed, or 0 when the device does not
// report one (a veth, or a physical port with no carrier). Backends that
// size themselves against line rate need it; nothing else does.
SpeedMbps int
}
Link is one network interface.
func Interfaces ¶
Interfaces returns the interfaces a user may choose from, best candidate first.
The ordering matters more than it sounds: a busy host can have twenty veth, dummy and bridge devices that are technically usable but never what someone running a traffic generator wants. Physical NICs — the ones with a real kernel driver — come first, then those with a carrier, then those with an IPv4 address, then by name.
func VLANLink ¶
VLANLink finds the 802.1Q sub-interface carrying vlanID on top of parent, if one exists. Wireblast uses it for routing, neighbour lookups and ARP probes, because that is where the kernel keeps the addressing for that VLAN.
func (Link) IsPhysical ¶
IsPhysical reports whether the interface is backed by a real kernel driver rather than being a virtual device. Used to sort and label the wizard's interface list.
type MACSource ¶
type MACSource string
MACSource records how the destination MAC was arrived at, so the review screen can say where the number came from rather than presenting it as magic.
const ( MACFromFlag MACSource = "given with --dst-mac" MACFromNeighbor MACSource = "from the neighbour table" MACFromARP MACSource = "resolved by ARP" MACFromND MACSource = "resolved by neighbour discovery" MACFromGateway MACSource = "gateway's MAC" MACPreserved MACSource = "not needed (the capture's own MACs are preserved)" MACNotNeeded MACSource = "not needed" )
type NeedsDstMACError ¶
type NeedsDstMACError struct {
Reason string
// Suggestion, when set, is a command the user could run to fix things.
Suggestion string
}
NeedsDstMACError is returned when the destination cannot be resolved automatically but a user-supplied --dst-mac would work. It carries an explanation of why, so the TUI can show the reason instead of a generic validation failure.
func (*NeedsDstMACError) Error ¶
func (e *NeedsDstMACError) Error() string
type Neighbor ¶
type Neighbor struct {
IP netip.Addr
MAC net.HardwareAddr
LinkIndex int
// Reachable is true for entries the kernel considers usable (REACHABLE,
// STALE, PERMANENT and friends) rather than incomplete or failed.
Reachable bool
}
Neighbor is one entry from the IPv4 neighbour (ARP) table.
type Options ¶
type Options struct {
// ProbeTimeout bounds the active ARP probe. Zero uses DefaultProbeTimeout;
// negative disables probing so only the existing neighbour table is used.
ProbeTimeout time.Duration
}
Options tunes resolution, mostly for tests.
type Resolved ¶
type Resolved struct {
// Link is the interface AF_XDP binds to — always a physical NIC.
Link Link
// L3Link is where addressing lives. It is the VLAN sub-interface when
// --vlan names one, and Link otherwise.
L3Link Link
SrcMAC net.HardwareAddr
SrcIP netip.Addr
Dst netip.Prefix
DstMAC net.HardwareAddr
MACSource MACSource
// NextHop is the address the MAC belongs to: the destination itself when
// it is on-link, or the gateway when it is not.
NextHop netip.Addr
OnLink bool
// Notes are informational lines for the review screen.
Notes []string
}
Resolved is everything discovery worked out for a run: which interface to transmit from, which addresses to put in the packets, and the next-hop MAC.
func Resolve ¶
Resolve works out the addressing for a run.
The order of preference is deliberate and never guesses: an explicit --dst-mac always wins; otherwise an on-link destination is resolved through the neighbour table and then an active ARP probe; an off-link destination is resolved through the route the user's own interface would use. If the routing table disagrees with the chosen interface, or a destination CIDR spans more than one next hop, Resolve stops and explains rather than picking something plausible. It never falls back to the broadcast address.
type Route ¶
type Route struct {
// Dst is the destination prefix. The zero Prefix means the default route.
Dst netip.Prefix
// Gateway is the next hop, or the zero Addr for a directly connected
// ("on-link") route.
Gateway netip.Addr
LinkIndex int
Priority int
Src netip.Addr
}
Route is one routing-table entry.
type Source ¶
type Source interface {
Links() ([]Link, error)
Routes() ([]Route, error)
Neighbors(linkIndex int) ([]Neighbor, error)
// Probe provokes IPv4 neighbour resolution for dst out of the given link
// and waits up to timeout for the kernel to answer. Returning an error is
// not fatal — the caller checks the neighbour table afterwards either way.
Probe(link Link, dst netip.Addr, timeout time.Duration) error
}
Source supplies the system state discovery reasons about. It exists so the interface-selection and next-hop logic can be unit-tested against fixtures instead of whatever machine the tests happen to run on.