flags: add -proxy flag and RegisterProxyFlag helper

Introduces three exports in pkg/flags:
- ProxyFlagUsage: the shared -proxy usage string, so tools that hand-roll
  their flag setup render identical help text to Parse().
- ConfigureProxy(url): calls transport.Configure and exits on error.
  Centralizes the "fail loud on bad -proxy" behavior.
- RegisterProxyFlag(): registers -proxy on the default flag.CommandLine
  and returns a finalizer to call after flag.Parse(). Two-line
  integration for tools that don't use flags.Parse().

Parse() now uses these internally. It also calls ConfigureProxy and
applies Debug/Timestamp unconditionally rather than returning early when
NArg == 0; tools that take all their config via flags (listeners, etc.)
were previously losing -proxy because the early return skipped Configure.
This commit is contained in:
psycep
2026-04-22 09:54:09 -05:00
parent 90038dcfc2
commit 7a1914a077
+38 -9
View File
@@ -23,6 +23,7 @@ import (
"gopacket/internal/build"
"gopacket/pkg/session"
"gopacket/pkg/transport"
)
// ExtraUsageLine is appended to the "Usage: tool [options] target" line (e.g. "[maxRid]")
@@ -46,6 +47,7 @@ type Options struct {
TargetIP string
Port int
IPv6 bool
Proxy string
// Utility
InputFile string
@@ -62,6 +64,29 @@ type Options struct {
Arguments []string
}
// ProxyFlagUsage is the shared usage string for -proxy. Keep tools consistent
// so the flag behaves identically whether registered via Parse() or
// RegisterProxyFlag().
const ProxyFlagUsage = "SOCKS5 proxy URL (e.g. socks5h://127.0.0.1:1080). Routes TCP through the proxy. UDP features are disabled. If unset, ALL_PROXY env is consulted."
// ConfigureProxy wires the transport layer with the given proxy URL. Exits on
// error so a misconfigured -proxy fails the tool instead of silently bypassing
// the proxy. Call after flag.Parse().
func ConfigureProxy(proxyURL string) {
if err := transport.Configure(transport.Options{Proxy: proxyURL}); err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(2)
}
}
// RegisterProxyFlag registers -proxy on the default flag.CommandLine and
// returns a finalizer to call after flag.Parse(). Intended for tools that
// hand-roll their flag setup instead of using Parse().
func RegisterProxyFlag() func() {
proxyURL := flag.String("proxy", "", ProxyFlagUsage)
return func() { ConfigureProxy(*proxyURL) }
}
// CheckHelp scans os.Args for -h/--help anywhere and shows usage if found.
// Call this after setting flag.Usage but before flag.Parse().
// This handles the case where -h appears after positional arguments,
@@ -90,6 +115,7 @@ func Parse() *Options {
flag.StringVar(&opts.TargetIP, "target-ip", "", "IP Address of the target machine")
flag.IntVar(&opts.Port, "port", 445, "Destination port to connect to SMB Server")
flag.BoolVar(&opts.IPv6, "6", false, "Connect via IPv6")
flag.StringVar(&opts.Proxy, "proxy", "", ProxyFlagUsage)
flag.StringVar(&opts.InputFile, "inputfile", "", "input file with list of entries")
flag.StringVar(&opts.OutputFile, "outputfile", "", "base output filename")
@@ -120,6 +146,17 @@ func Parse() *Options {
flag.Parse()
// Set global settings and configure transport unconditionally, even when
// no positional args were given. Tools that take config entirely via
// flags (e.g. listeners) still need Debug/Timestamp/-proxy to take effect.
if opts.Debug {
build.Debug = true
}
if opts.Timestamp {
build.Timestamp = true
}
ConfigureProxy(opts.Proxy)
// Handle Positional Arguments (target + optional command/args)
if flag.NArg() == 0 {
return opts
@@ -129,14 +166,6 @@ func Parse() *Options {
opts.Arguments = flag.Args()[1:]
}
// Set Global Settings
if opts.Debug {
build.Debug = true
}
if opts.Timestamp {
build.Timestamp = true
}
return opts
}
@@ -154,7 +183,7 @@ func printBanner() {
func printGroupedHelp() {
authFlags := []string{"hashes", "no-pass", "k", "aesKey", "keytab"}
connFlags := []string{"6", "dc-host", "dc-ip", "target-ip", "port"}
connFlags := []string{"6", "dc-host", "dc-ip", "target-ip", "port", "proxy"}
miscFlags := []string{"inputfile", "outputfile", "ts", "debug"}
// Maps to store flags