Documentation
¶
Index ¶
- func IsLocalMAC(mac net.HardwareAddr, localMACs []net.HardwareAddr) bool
- func Mbps(bytes int64, d time.Duration) float64
- type AccessPoint
- type Alias
- type AliasLookup
- type BandwidthResult
- type CounterReader
- type Device
- type DeviceClass
- type Discovery
- type Event
- type EventKind
- type HostResolver
- type InterfaceConfigurator
- type InterfaceInfo
- type InterfaceInspector
- type NetCounters
- type Network
- type Pinger
- type Prober
- type Rate
- type RateMeter
- type Scanner
- type SpeedTester
- type Speedtest
- type StaticConfig
- type TrackedDevice
- type Tracker
- type VendorLookup
- type WiFiInfo
- type WiFiInspector
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func IsLocalMAC ¶ added in v0.2.0
func IsLocalMAC(mac net.HardwareAddr, localMACs []net.HardwareAddr) bool
classFromVendor maps distinctive OUI vendors to a likely class. Ambiguous vendors (e.g. Apple, Samsung — could be phone, PC or TV) stay Unknown so a port fingerprint or nothing decides instead of a coin flip. IsLocalMAC reports whether mac belongs to one of this machine's own interfaces (e.g. Ethernet and Wi-Fi both connected at once show up as two separate devices in a scan; this recognizes the second one as "us" too, since its IP won't match Network.Self).
Types ¶
type AccessPoint ¶
AccessPoint is a single visible wireless network.
type Alias ¶
type Alias struct {
MAC net.HardwareAddr
Name string
}
Alias is a user-defined nickname bound to a device's MAC address. Keying on the MAC (not the IP) keeps the label stable across DHCP lease changes.
type AliasLookup ¶
type AliasLookup interface {
Alias(mac net.HardwareAddr) string
}
AliasLookup returns a user-defined nickname for a MAC, or "" if none is set.
type BandwidthResult ¶
BandwidthResult holds a speed-test outcome in megabits per second.
type CounterReader ¶
type CounterReader interface {
Counters() (NetCounters, error)
}
CounterReader reads the active interface's cumulative byte counters.
type Device ¶
type Device struct {
IP net.IP // IPv4 address on the local subnet
MAC net.HardwareAddr // Layer-2 address (from ARP)
Alias string // User-defined nickname, keyed by MAC; empty if unset
Hostname string // Reverse-DNS name, empty if unresolved
Vendor string // Manufacturer, resolved from the MAC's OUI prefix
Class DeviceClass // Best-effort guess at what kind of device this is
RTT time.Duration // ICMP round-trip time; 0 with Reachable false if no reply
Reachable bool // Answered an ICMP echo during enrichment
Online bool // Answered the active probe during this scan
Ports []int // Open TCP ports found by the classification probe; nil if not probed
}
Device is a host discovered on the local network.
It is a pure domain type: no I/O, no OS calls. Adapters produce it, the TUI consumes it.
type DeviceClass ¶
type DeviceClass int
DeviceClass is a coarse, best-effort guess at what a host is.
const ( ClassUnknown DeviceClass = iota ClassThisDevice // the machine running netwp ClassRouter // the default gateway ClassComputer // PC / server / SBC ClassMobile // phone / tablet ClassMedia // TV / streaming stick / speaker ClassPrinter ClassIoT // smart home / embedded )
func Classify ¶
func Classify(d Device, gateway, self net.IP, openPorts []int, localMACs []net.HardwareAddr) DeviceClass
Classify guesses a device's class from the signals a scan can gather: whether it is us, whether it is the gateway, which TCP ports answered, and its vendor.
ponytail: pure heuristic, deliberately conservative — identity signals (self, gateway) win, then port fingerprints, then a vendor-keyword fallback. Wrong guesses fall back to Unknown rather than asserting nonsense.
func (DeviceClass) String ¶
func (c DeviceClass) String() string
type Discovery ¶
type Discovery struct {
// contains filtered or unexported fields
}
Discovery is the device-discovery use case. It orchestrates a scan and then enriches each result with hostname, vendor, class and round-trip time. It depends only on ports, so it is fully testable with fakes.
func NewDiscovery ¶
func NewDiscovery(scanner Scanner, names HostResolver, vendors VendorLookup, prober Prober, aliases AliasLookup, pinger Pinger) *Discovery
type HostResolver ¶
HostResolver turns an IP into a hostname (reverse DNS). Cross-platform.
type InterfaceConfigurator ¶
type InterfaceConfigurator interface {
SetStatic(cfg StaticConfig) error
SetDHCP() error
}
InterfaceConfigurator applies an IPv4 configuration change to the active interface. Implementations require elevated/admin privileges.
type InterfaceInfo ¶
type InterfaceInfo struct {
Name string
MAC net.HardwareAddr
IP net.IP
CIDR *net.IPNet
Gateway net.IP
DNSServers []net.IP
DHCP bool // true if the address was assigned by DHCP, false if static
}
InterfaceInfo describes the active network interface's IP configuration.
type InterfaceInspector ¶
type InterfaceInspector interface {
Inspect() (InterfaceInfo, error)
}
InterfaceInspector reads the active network interface's IP configuration.
type NetCounters ¶
NetCounters is a point-in-time reading of an interface's byte totals.
type Network ¶
type Network struct {
Self net.IP // Our address on this network
CIDR *net.IPNet // The subnet (address + mask)
Gateway net.IP // Default gateway (the router), nil if undetermined
LocalMACs []net.HardwareAddr // MACs of all of this machine's own interfaces, not just Self
}
Network is the target subnet of a scan: our own address plus its CIDR.
Value object — no behaviour beyond deriving the set of scannable hosts.
type Pinger ¶
Pinger measures ICMP round-trip time to a host. ok is false on timeout or error (host unreachable), in which case the duration is meaningless.
type Prober ¶
Prober reports which of a small set of well-known TCP ports a host accepts connections on — the "detailed scan" used to refine device classification.
type Rate ¶
type Rate struct {
DownBps float64 // bytes per second, download
UpBps float64 // bytes per second, upload
TotalRx uint64 // bytes received since the meter started
TotalTx uint64 // bytes sent since the meter started
}
Rate is a throughput reading derived from two counter samples.
type RateMeter ¶
type RateMeter struct {
// contains filtered or unexported fields
}
RateMeter turns successive NetCounters samples into throughput. Not safe for concurrent use; drive it from one goroutine (the dashboard's update loop).
type Scanner ¶
Scanner performs active discovery of hosts on a target network.
This is the central port. Implementations are platform-specific and selected at build time (Windows: SendARP; Linux: raw ARP over AF_PACKET). The core never knows which one it talks to.
type SpeedTester ¶
type SpeedTester interface {
Download(ctx context.Context, size int64) (time.Duration, error)
Upload(ctx context.Context, size int64) (time.Duration, error)
}
SpeedTester transfers a fixed number of bytes and reports how long it took. Implemented by an adapter talking to a public speed-test endpoint.
type Speedtest ¶
type Speedtest struct {
// contains filtered or unexported fields
}
Speedtest is the bandwidth-measurement use case.
func NewSpeedtest ¶
func NewSpeedtest(tester SpeedTester) *Speedtest
NewSpeedtest builds the use case with transfer sizes tuned for a typical home link.
ponytail: fixed sizes. Adaptive ramping (grow until the link saturates) can come later if the numbers read low on very fast or very slow connections.
type StaticConfig ¶
type StaticConfig struct {
IP net.IP
Mask net.IP // dotted-decimal, e.g. 255.255.255.0
Gateway net.IP
DNS []net.IP
}
StaticConfig is a static IPv4 configuration to apply to an interface.
type TrackedDevice ¶
TrackedDevice is a device plus its presence history across scans.
type Tracker ¶
type Tracker struct {
// contains filtered or unexported fields
}
Tracker folds successive scans into a stable device set and reports join/leave events. Pure logic: the caller supplies the clock, so it is fully testable. Not safe for concurrent use — drive it from a single goroutine.
func NewTracker ¶
NewTracker returns a Tracker that marks a device offline only once it has been missing for at least offlineAfter — a grace window so a single missed scan (common on Wi-Fi) does not flap a device in and out.
func (*Tracker) Devices ¶
func (t *Tracker) Devices() []TrackedDevice
Devices returns the tracked devices sorted by IP address.
type VendorLookup ¶
type VendorLookup interface {
Vendor(mac net.HardwareAddr) string
}
VendorLookup resolves a MAC address to a manufacturer via its OUI prefix.
type WiFiInfo ¶
type WiFiInfo struct {
Connected bool
SSID string
BSSID string
Band string // e.g. "5 GHz"
RadioType string // e.g. "802.11ax"
Channel int
SignalPercent int // 0..100 as reported by the OS
RxRateMbps int
TxRateMbps int
Nearby []AccessPoint // other visible APs, for interference context
}
WiFiInfo describes the active wireless connection and its radio environment. Fields are best-effort: anything the platform does not report stays zero/empty.
func (WiFiInfo) RecommendChannel ¶
RecommendChannel suggests the least-congested channel for the current band.
ponytail: a count-based heuristic, not an RF planner. On 2.4 GHz it scores the non-overlapping channels 1/6/11 (each overlaps its neighbours by ~4). On 5 GHz it only considers channels already in use plus the current one, so it never suggests a possibly-illegal channel for the region. Returns the current channel when it is already the clearest.
func (WiFiInfo) SameChannelCount ¶
SameChannelCount returns how many nearby APs share this connection's channel, a rough interference indicator.
type WiFiInspector ¶
WiFiInspector reports the current wireless state, or an error if there is no wireless interface.