- Rewrite README.md with overview, features, installation (go install +
build from source), quick start, full CLI flag reference table,
output section descriptions, project structure, and development guide
- Add package-level doc comments to all five internal packages:
config, dns, fingerprint, output, traverse (via doc.go or existing
package-declaration files)
- Add GoDoc comments on every exported type, constant, function, and
method across all packages:
- internal/config: Config struct fields, all Parse*/Default/Validate
- internal/dns: QueryConfig, Resolver, BasicResolver, CachingResolver,
ExchangeFunc, RootServer, RootDiscoveryConfig, DecodedResponse,
ResponseClassification, all exported helpers
- internal/fingerprint: Fingerprinter, New, NewWithTimeout, Query,
FingerprintAll
- internal/traverse: Traverser, TraverserConfig, TraversalResult,
Referral, ResolutionState, Response, ResponseType, InfoCache,
Stack, TraverserHooks, EventStage, TraversalEvent, EventHandler,
CircularReferralError, UnresolvableNameserverError
- internal/output: Format, Config, Formatter, SummaryStats,
NewFormatter, AttachHooks, RunTraversal, DefaultConfig,
ComputeSummary
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: multica-agent <github@multica.ai>
This commit is contained in:
co-authored by
Copilot
multica-agent
parent
fe1afe2a97
commit
9aa85d8e5d
+54
-13
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/miekg/dns"
|
||||
)
|
||||
|
||||
// Sentinel errors returned by validation and parsing functions.
|
||||
var (
|
||||
ErrInvalidQueryType = errors.New("invalid query type")
|
||||
ErrInvalidUDPSize = errors.New("UDP size must be between 512 and 4096")
|
||||
@@ -20,22 +21,41 @@ var (
|
||||
ErrInvalidRootServer = errors.New("invalid root server IP address")
|
||||
)
|
||||
|
||||
// Config holds all runtime settings for ExploreDNS.
|
||||
// Populate it from CLI flags, then call Validate before use.
|
||||
type Config struct {
|
||||
QueryType string
|
||||
RootServer string
|
||||
// QueryType is the DNS record type to query (e.g. "A", "MX", "TXT").
|
||||
QueryType string
|
||||
// RootServer overrides the root server IP used to begin traversal.
|
||||
// Empty string means auto-discover via the system resolver.
|
||||
RootServer string
|
||||
// AllRootServers queries all 13 DNS root servers instead of one.
|
||||
AllRootServers bool
|
||||
RootAAAA bool
|
||||
FollowAAAA bool
|
||||
UDPSize int
|
||||
AllowTCP bool
|
||||
AlwaysTCP bool
|
||||
MaxDepth int
|
||||
Retries int
|
||||
Fast bool
|
||||
Verbose bool
|
||||
Debug int
|
||||
Quiet bool
|
||||
// RootAAAA includes IPv6 addresses of root servers when true.
|
||||
RootAAAA bool
|
||||
// FollowAAAA restricts referral following to AAAA glue records only.
|
||||
FollowAAAA bool
|
||||
// UDPSize is the EDNS0 advertised UDP payload size (512–4096 bytes).
|
||||
UDPSize int
|
||||
// AllowTCP enables TCP fallback when a UDP response is truncated.
|
||||
AllowTCP bool
|
||||
// AlwaysTCP forces all queries over TCP (requires AllowTCP = true).
|
||||
AlwaysTCP bool
|
||||
// MaxDepth limits the traversal depth (1–100).
|
||||
MaxDepth int
|
||||
// Retries is the number of times a failed query is retried (0–10).
|
||||
Retries int
|
||||
// Fast enables the shared-cache fast mode. When true, sibling branches
|
||||
// inherit glue discovered by earlier branches, trading accuracy for speed.
|
||||
Fast bool
|
||||
// Verbose enables verbose output lines.
|
||||
Verbose bool
|
||||
// Debug controls debug verbosity: 0 = off, 1 = app debug, 2 = library debug.
|
||||
Debug int
|
||||
// Quiet suppresses supplementary informational output.
|
||||
Quiet bool
|
||||
|
||||
// Output visibility flags — each controls a section of the output.
|
||||
ShowProgress bool
|
||||
ShowResolves bool
|
||||
ShowServers bool
|
||||
@@ -45,6 +65,8 @@ type Config struct {
|
||||
ShowSummaryResults bool
|
||||
}
|
||||
|
||||
// ParseQueryType converts a case-insensitive query type string (e.g. "A", "MX")
|
||||
// to its numeric DNS type constant. Returns ErrInvalidQueryType for unknown types.
|
||||
func ParseQueryType(s string) (uint16, error) {
|
||||
s = strings.ToUpper(s)
|
||||
switch s {
|
||||
@@ -71,6 +93,8 @@ func ParseQueryType(s string) (uint16, error) {
|
||||
}
|
||||
}
|
||||
|
||||
// ParseUDPSize parses a string as a UDP buffer size.
|
||||
// Returns ErrInvalidUDPSize if the string is not an integer or is outside 512–4096.
|
||||
func ParseUDPSize(s string) (int, error) {
|
||||
var size int
|
||||
if _, err := fmt.Sscanf(s, "%d", &size); err != nil {
|
||||
@@ -82,6 +106,8 @@ func ParseUDPSize(s string) (int, error) {
|
||||
return size, nil
|
||||
}
|
||||
|
||||
// ParseMaxDepth parses a string as a traversal depth.
|
||||
// Returns ErrInvalidMaxDepth if the string is not an integer or is outside 1–100.
|
||||
func ParseMaxDepth(s string) (int, error) {
|
||||
var depth int
|
||||
if _, err := fmt.Sscanf(s, "%d", &depth); err != nil {
|
||||
@@ -93,6 +119,8 @@ func ParseMaxDepth(s string) (int, error) {
|
||||
return depth, nil
|
||||
}
|
||||
|
||||
// ParseRetries parses a string as a retry count.
|
||||
// Returns ErrInvalidRetries if the string is not an integer or is outside 0–10.
|
||||
func ParseRetries(s string) (int, error) {
|
||||
var retries int
|
||||
if _, err := fmt.Sscanf(s, "%d", &retries); err != nil {
|
||||
@@ -104,6 +132,9 @@ func ParseRetries(s string) (int, error) {
|
||||
return retries, nil
|
||||
}
|
||||
|
||||
// Validate checks that all Config fields are within their accepted ranges and
|
||||
// that flag combinations are valid (e.g. AlwaysTCP requires AllowTCP).
|
||||
// Returns the first validation error encountered, or nil.
|
||||
func (c *Config) Validate() error {
|
||||
if _, err := ParseQueryType(c.QueryType); err != nil {
|
||||
return err
|
||||
@@ -128,6 +159,8 @@ func (c *Config) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetDomain returns the domain name from the positional CLI arguments.
|
||||
// Returns ErrMissingDomain when args is empty.
|
||||
func (c *Config) GetDomain(args []string) (string, error) {
|
||||
if len(args) == 0 {
|
||||
return "", ErrMissingDomain
|
||||
@@ -135,6 +168,9 @@ func (c *Config) GetDomain(args []string) (string, error) {
|
||||
return args[0], nil
|
||||
}
|
||||
|
||||
// ParseRootServer parses the RootServer field as an IP address.
|
||||
// Returns nil, nil when RootServer is empty (auto-discover mode).
|
||||
// Returns ErrInvalidRootServer when the string is non-empty but not a valid IP.
|
||||
func (c *Config) ParseRootServer() (net.IP, error) {
|
||||
if c.RootServer == "" {
|
||||
return nil, nil
|
||||
@@ -158,6 +194,8 @@ func ParseDebugLevel(d, dd bool) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
// PrintUsage writes a grouped help message to stderr, listing every flag with
|
||||
// its description. It is registered as flag.Usage by main.
|
||||
func PrintUsage() {
|
||||
fmt.Fprintf(os.Stderr, "ExploreDNS - DNS reconnaissance and exploration tool\n\n")
|
||||
fmt.Fprintf(os.Stderr, "Usage:\n")
|
||||
@@ -211,6 +249,9 @@ func PrintUsage() {
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultConfig returns a Config populated with sensible defaults:
|
||||
// query type A, UDP size 2048, max depth 20, 2 retries, fast mode on,
|
||||
// TCP fallback allowed, and all output sections visible.
|
||||
func DefaultConfig() *Config {
|
||||
return &Config{
|
||||
QueryType: "A",
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
// Package config defines the ExploreDNS runtime configuration, flag parsing
|
||||
// helpers, input validation, and usage text.
|
||||
//
|
||||
// Config holds all settings that control traversal behaviour and output.
|
||||
// DefaultConfig returns a ready-to-use Config with sensible defaults.
|
||||
// After populating Config from CLI flags, call Validate to ensure
|
||||
// all field values are within their accepted ranges.
|
||||
//
|
||||
// Helper functions such as ParseQueryType, ParseDebugLevel, and
|
||||
// ParseRootServer are pure converters; they never read flag state.
|
||||
package config
|
||||
Reference in New Issue
Block a user