scan

package
v0.1.1 Latest Latest
Warning

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

Go to latest
Published: Jul 20, 2026 License: GPL-3.0 Imports: 15 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var DisplayFields = map[string]func(r *scan.Run) string{
	"ID": func(r *scan.Run) string {
		id := display.FormatSmallID(r.GetId())
		switch stateOf(r) {
		case stateDone:
			return color.HiGreenString(id)
		case stateFailed:
			return color.HiRedString(id)
		case stateRunning:
			return color.HiYellowString(id)
		default:
			return id
		}
	},
	"Scanner": func(r *scan.Run) string { return r.GetScanner() },
	"Name":    func(r *scan.Run) string { return r.GetProfileName() },
	"Status":  func(r *scan.Run) string { return stateToken(r) },
	"Info": func(r *scan.Run) string {
		info := r.GetInfo()
		if info == nil {
			return ""
		}
		var parts []string
		if info.Protocol != "" {
			parts = append(parts, info.Protocol)
		}
		if info.Type != "" {
			parts = append(parts, info.Type)
		}
		return strings.Join(parts, "/")
	},
	"Args":    func(r *scan.Run) string { return r.GetArgs() },
	"When":    func(r *scan.Run) string { return whenLabel(r) },
	"Hosts":   func(r *scan.Run) string { return hostsUpDown(r) },
	"Targets": func(r *scan.Run) string { return targetsSummary(r) },
	"Tasks":   func(r *scan.Run) string { return tasksSummary(r) },
}

DisplayFields maps column names to per-run value generators — the single source of truth feeding the table and completions. Every accessor is nil-safe (a partially observed run must never panic the table), and state-dependent fields route through stateOf so the whole view agrees.

Functions

func AreScansIdentical

func AreScansIdentical(a, b *scan.RunORM) bool

AreScansIdentical reports whether two runs are the same scan re-imported.

RawXML is the scanner's verbatim output and thus a definitive fingerprint: when both runs carry it, equality alone decides identity and inequality alone rules it out. Only when a run lacks raw output does it fall back to a field-weighted comparison over the runs' identity fields.

The fallback counts *evidence*, not absence: a field contributes only when both runs actually populated it — agreement is positive evidence, a disagreement on a populated field is disqualifying, and a field left empty on either side is neutral. Two dataless runs therefore score no evidence and are not "identical" (the earlier scoring treated two empty task-lists as a match, which made every empty run collide with every other). Runs match when they agree on every populated identity field, disagree on none, and carry at least one field of real evidence.

func Completions

func Completions() []display.Options

Completions returns the columns combined into completion candidates and their descriptions.

func Detail

func Detail(r *scan.Run, all []*scan.Run, opt DetailOpts) display.Detail

Detail assembles the full `show` view for a single run: the state banner, the side-by-side info panes, derived insights (including the cross-run host-sharing count, which needs the whole set `all` to compute), and any flag-selected trailing sections. It hands these to the shared display.Detail renderer, so a run's detail view is laid out identically to every other domain's.

func DisplayDetails

func DisplayDetails() []display.Options

DisplayDetails is retained only for the c2 agent/channel `show` placeholders, which reuse this weighted header set against their own DisplayFields map. Scan's own `show` uses the richer Detail renderer (banner + panes + insights + sections); prefer that. Deprecated: do not build on this for the scan domain.

func DisplayHeaders

func DisplayHeaders() []display.Options

DisplayHeaders returns all weighted table headers for a table of scans. Weight-1 columns are the always-on signal (identity, scanner, live status, host outcome, recency); heavier columns shed first on narrow terminals.

func IsRunning

func IsRunning(r *scan.Run) bool

IsRunning reports whether the run appears to be mid-flight — task activity (Begin/Progress) with no terminal Finished stats. Today no running run is ever persisted (`scan run` blocks to completion before storing), so this is always false for stored runs; it exists so destructive operations can refuse an in-flight run once live/streaming scans land (SCAN.md Part C), rather than silently dropping a partial record while the scanner keeps going.

func SortRuns

func SortRuns(runs []*scan.Run)

SortRuns orders runs for listing: running scans first (most actionable), then queued, then the rest — each group by most-recent activity. Stable, so equal keys keep their read order.

func TargetSpecs

func TargetSpecs(targets []*scan.Target) []string

TargetSpecs renders targets as the address/host tokens a scanner takes on its command line — Address preferred, else Domain — preserving order and dropping blanks, so the result can be appended straight onto a scanner's arguments.

func TargetsFromHosts

func TargetsFromHosts(hosts ...*host.Host) []*scan.Target

TargetsFromHosts derives scan Targets from stored hosts. Each host contributes one Target per address (its identity anchor); a host with no address falls back to its hostnames as Domain targets. Duplicate endpoints (same address, or same domain) are collapsed so overlapping hosts never re-target the same thing. The result is deterministic in host/address order.

Types

type DetailOpts

type DetailOpts struct {
	Tasks   bool // the running/done task tables (the live view)
	Targets bool // the full target list with per-target status/reason
	Hosts   bool // the scanned hosts rendered as a compact table
}

DetailOpts selects which trailing sections a detail view includes. They are flag-gated at the CLI because each is verbose (task streams, full target lists, the shared-host table) and off by default keeps `scan show` scannable.

type HostDelta

type HostDelta struct {
	Before    *host.Host
	After     *host.Host
	NewPorts  []*host.Port // in b, not in a
	GonePorts []*host.Port // in a, not in b
	Changed   []PortDelta  // same (proto, number), but service or state differs
}

HostDelta captures how one host's surface changed between the two runs.

type PortDelta

type PortDelta struct {
	Before *host.Port
	After  *host.Port
}

PortDelta is a port whose service identity or state changed between runs.

type Result

type Result scan.Result

Result - A type containing various objects that are outputs of a scan. It has only one .Target, which theoretically means that we must have n Results for n Results. This type is to be created from and used by a scan.Run type, which has various methods to set up, populate, curate and save the data from a complete Scan, sometimes concurrently. A Result is not meant to be saved in a database: it is only used as a feeder type for the scan.Run.

func (*Result) ToPB

func (r *Result) ToPB() *scan.Result

ToPB - Get the Protobuf object for the Result.

type Run

type Run scan.Run

Run - Represents a scan before, after or while being run. This run can be the one of any scanner: fields are not mandatorily used by all scanners for all scans, but this type gives a common tree in which to store hosts, ports, services, statistics and various other information.

The type provides many convenience methods to process all the output of the scan, either at once or continuously, or even to refine the objects based on/ with those already in a database. Therefore, all the methods of this type are meant to be used server-side, and not in an implant.

For having similar functionality from within an implant, use the Protobuf scan.Run type, which itself has some convenience methods that do NOT need any database or its related libraries.

func NewRun

func NewRun(scanner string, args ...string) *Run

NewRun - Create a new scan.Run based on a tool (scanner) name, and with an optional Options type holding various settings to be customized for your use.

func (*Run) AddHosts

func (r *Run) AddHosts(hosts ...*host.Host)

AddHosts folds one or more hosts into this Run, deduplicating and merging by natural key. It is the bulk entry point behind the import path: the Hosts of a freshly parsed scan.Run (e.g. from nmap.FromXML) are folded in one by one, so an import that overlaps hosts already in the Run enriches them instead of duplicating.

func (*Run) AddResult

func (r *Run) AddResult(res *Result) (err error)

AddResult folds one feeder Result into the Run's host tree. The Result is the universal adapter output (one {Host, Address, Port, Service, Data} tuple emitted by any scanner); AddResult assembles it into a single-host subtree and merges that in via the non-destructive fold (see fold.go / DEDUP.md). Calling it twice with the same observation is idempotent — the second call merges into the row the first created and changes nothing.

If the Result carries Data (a custom scanner's opaque payload), it is preserved as a script observation on the port (or host) so nothing is lost; mapping structured payloads into the recursive NSE Script/Table/Element tree (jsonToScript, SCAN.md §D) is the richer, philosophy-true follow-on.

func (*Run) AddTarget

func (r *Run) AddTarget(t *Target)

when they are needed by the service probing stack used by the scan.

func (*Run) InitResult

func (r *Run) InitResult() *Result

InitResult - Instantiate a new result that has the Run UUID in ref. The rest of the object can be populated by the user as he wishes.

func (*Run) ToPB

func (r *Run) ToPB() *scan.Run

ToPB - Get the Protobuf object for the Result.

type RunDiff

type RunDiff struct {
	NewHosts  []*host.Host // present in b, absent in a
	GoneHosts []*host.Host // present in a, absent in b
	Changed   []HostDelta  // present in both, but ports/services differ
}

RunDiff is the delta from Run a (earlier) to Run b (later).

func DiffRuns

func DiffRuns(a, b *scan.Run) *RunDiff

DiffRuns computes the drift from a (earlier) to b (later). Either may be nil (treated as an empty host set). The result is deterministic in b's then a's host order.

func (*RunDiff) Empty

func (d *RunDiff) Empty() bool

Empty reports whether the two runs are identical at the host/port/service level.

type Target

type Target scan.Target

Target - This type can be used as an Input object to a scan, in which case only the Input fields matter to you

Represents how the target was specified when passed to nmap, its status and the reason of its status. Example: <target specification="domain.does.not.exist" status="skipped" reason="invalid"/>.

func (*Target) ToORM

func (t *Target) ToORM(ctx context.Context) (scan.TargetORM, error)

ToORM - Get the SQL object for the Target.

func (*Target) ToPB

func (t *Target) ToPB() *scan.Target

ToPB - Get the Protobuf object for the Target.

Directories

Path Synopsis
pb
rpc

Jump to

Keyboard shortcuts

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