ui

package
v0.2.23 Latest Latest
Warning

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

Go to latest
Published: Aug 12, 2026 License: MIT Imports: 15 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var Interactive = isTTY(os.Stderr)

Interactive is true when stderr is attached to a terminal; spinners and the banner are suppressed otherwise (e.g. when output is piped or redirected).

Functions

func ApplyHostnames added in v0.2.1

func ApplyHostnames(rows []Row, names map[string]string)

ApplyHostnames fills in hostnames the scan itself didn't learn.

The native fast path reports no hostnames at all — it never asks a resolver — which is the main reason users reach for the far slower nmap presets. A reverse lookup closes most of that gap for a few milliseconds. Names already present are never overwritten: nmap's own PTR result came from the scan and outranks a later best-effort lookup.

func ApplySelfReportedNames added in v0.2.18

func ApplySelfReportedNames(rows []Row, names map[string]string)

ApplySelfReportedNames fills in names a device announced about itself, replacing a weaker one where it finds it.

Multicast used to run before the reverse lookup, so "first writer wins" was enough to keep the better name. Deferring it — so a scan can show results without waiting on a multi-second listen — inverts that order, and under the old rule the deferred pass could never improve anything: PTR would already have filled every field it was going to fill.

So this one may overwrite, but only a name that came from a resolver, and only when the device's own answer is genuinely different. A device calling itself "Sarpers-MacBook-Pro" outranks a reverse zone that spells the address back as "mac"; it does not outrank a name the user set, which is applied elsewhere and never reaches this function.

func Banner(version string)

Banner prints the app header to stderr so stdout stays clean for results.

func IPLess

func IPLess(a, b string) bool

IPLess orders IPv4/IPv6 addresses numerically, falling back to a string compare for values that don't parse. Every view sorts through this so the CLI and the TUI agree on ordering (a lexical sort would put .10 before .9).

func Infof

func Infof(format string, a ...any)

Infof prints a dim info line to stderr.

func PortNumber

func PortNumber(label string) string

PortNumber exposes the "22/tcp ssh" -> "22" reduction for table-style views.

func PrintNextSteps added in v0.2.15

func PrintNextSteps(recorded bool, targets []string)

PrintNextSteps names what the scan just made possible.

Every scan records a baseline, a device inventory and a timeline, and none of that was ever mentioned at the one moment the user is certain to be paying attention. The result was a product whose entire change-detection half went unnoticed unless someone read `--help` for fun.

recorded means this run was trustworthy enough to be written as a baseline — the outcome's own judgement, not the diff's. A cancelled or partial scan records nothing, and pointing that user at `ndscan diff` would be advice they cannot act on.

Deliberately not gated on a diff existing: the first scan of a network has nothing to compare against and so produces no diff, and that is precisely the run whose user has never heard of `ndscan diff`. Gating on the diff would hide the hint from everyone except people who had already discovered the feature.

stderr, like the summary above it, so redirected stdout stays clean. One line each, printed once: a scanner that lectures after every run is worse than one that says nothing.

func PrintSummary

func PrintSummary(hostsUp, openPorts int, elapsed time.Duration)

PrintSummary prints the closing stats line to stderr.

func PrintTableRows added in v0.2.6

func PrintTableRows(rows []Row, showMac bool)

PrintTableRows renders rows that have already been built.

The scan pipeline hands its callers []Row rather than raw nmap results, so the renderers have to start from the same place. Keeping one implementation here — rather than a second copy in whichever front end needed rows — is what stops the table drifting between the CLI and everything else.

func PrintTableWithMACMap

func PrintTableWithMACMap(res []scan.HostResult, db vendor.DB, showMac, showVendors bool, macMap map[string]string)

func PrintTreeRows added in v0.2.6

func PrintTreeRows(rows []Row, showMac, showVendors bool)

PrintTreeRows renders the tree view from rows that have already been built.

func PrintTreeWithMACMap

func PrintTreeWithMACMap(res []scan.HostResult, db vendor.DB, showMac, showVendors bool, macMap map[string]string)

func SetHostnames added in v0.2.1

func SetHostnames(names map[string]string)

SetHostnames registers reverse-DNS results for the current scan. Call it after the scan and before rendering. Not safe for concurrent use with rendering, which is fine for its one caller: the CLI resolves once, then prints. Long-running callers should use ApplyHostnames instead.

func Summarize

func Summarize(res []scan.HostResult) (hostsUp, openPorts int)

func SummarizeRows added in v0.2.6

func SummarizeRows(rows []Row) (hostsUp, openPorts int)

Summarize returns the number of hosts that are up and the total count of open ports across all results, for the post-scan summary line.

func Warnf

func Warnf(format string, a ...any)

Warnf prints a yellow warning line to stderr.

func WriteJSONWithMACMap

func WriteJSONWithMACMap(res []scan.HostResult, db vendor.DB, path string, showMac, showVendors bool, macMap map[string]string) error

Types

type PortInfo

type PortInfo struct {
	Port      int    `json:"port"`
	Proto     string `json:"proto"`
	Service   string `json:"service,omitempty"`
	Product   string `json:"product,omitempty"`
	Version   string `json:"version,omitempty"`
	ExtraInfo string `json:"extra_info,omitempty"` // e.g. "Python 3.14.3"
	CPE       string `json:"cpe,omitempty"`        // e.g. "cpe:/a:python:python:3.14"
	TLS       bool   `json:"tls,omitempty"`        // service runs over an SSL/TLS tunnel
	HTTPTitle string `json:"http_title,omitempty"` // page title (http-title script)
	Cert      string `json:"cert,omitempty"`       // TLS cert summary (ssl-cert script)
	Severity  string `json:"severity,omitempty"`   // "", "info", "warn", "high"
	Risk      string `json:"risk,omitempty"`       // human-readable reason
}

PortInfo is the structured form of one open port.

func (PortInfo) VersionLabel

func (p PortInfo) VersionLabel() string

VersionLabel renders product + version, e.g. "OpenSSH 9.6", or "".

type Row

type Row struct {
	IP         string   `json:"ip"`
	MAC        string   `json:"mac,omitempty"`
	Vendor     string   `json:"vendor,omitempty"`
	Host       string   `json:"hostname,omitempty"`
	OS         string   `json:"os,omitempty"`          // best OS-detection guess (needs -A presets)
	OSAccuracy int      `json:"os_accuracy,omitempty"` // confidence 0-100
	OSCPE      string   `json:"os_cpe,omitempty"`      // first OS CPE
	RTT        string   `json:"rtt,omitempty"`         // smoothed round-trip time, e.g. "2.1ms"
	Up         bool     `json:"up"`
	Ports      []string `json:"ports,omitempty"` // labels like "22/tcp ssh"
	// PortDetails carries the structured per-port view (number, service,
	// version, risk) for detail panes and reports. It mirrors Ports.
	PortDetails []PortInfo `json:"port_details,omitempty"`
}

func BuildRows

func BuildRows(res []scan.HostResult, db vendor.DB, showMac, showVendors bool, macMap map[string]string) []Row

BuildRows flattens raw scan results into display rows, fills any missing MACs from macMap, and resolves vendor names when requested. The TUI and the non-interactive printers share this so the data is identical across views.

type Spinner

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

Spinner renders an animated status line on stderr. On non-interactive terminals it degrades to plain log lines.

func StartSpinner

func StartSpinner(msg string) *Spinner

func (*Spinner) Fail

func (s *Spinner) Fail(msg string)

Fail stops the spinner and prints a red cross line.

func (*Spinner) Success

func (s *Spinner) Success(msg string)

Success stops the spinner and prints a green check line.

func (*Spinner) Update

func (s *Spinner) Update(msg string)

Update swaps the message while the spinner keeps animating.

Jump to

Keyboard shortcuts

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