### Execute Nmap Scripts (NSE) with Go Source: https://context7.com/ullaakut/nmap/llms.txt Demonstrates how to execute Nmap Scripting Engine (NSE) scripts for vulnerability detection. It covers running default scripts and specifying custom scripts with arguments and timeouts. This requires the nmap binary to be installed. ```go package main import ( "context" "fmt" "log" "time" "github.com/Ullaakut/nmap/v3" ) func main() { ctx := context.Background() // Run default scripts defaultScriptScanner, err := nmap.NewScanner( ctx, nmap.WithTargets("scanme.nmap.org"), nmap.WithDefaultScript(), nmap.WithServiceInfo(), ) if err != nil { log.Fatalf("error: %v", err) } // Run specific scripts with arguments specificScriptScanner, err := nmap.NewScanner( ctx, nmap.WithTargets("192.168.1.1"), nmap.WithScripts("http-title", "http-headers", "ssl-cert"), nmap.WithScriptArguments(map[string]string{ "http.useragent": "Mozilla/5.0", "vulns.showall": "", }), nmap.WithScriptTimeout(5*time.Minute), ) if err != nil { log.Fatalf("error: %v", err) } result, warnings, err := defaultScriptScanner.Run() if err != nil { log.Fatalf("scan failed: %v", err) } if len(*warnings) > 0 { log.Printf("warnings: %s\n", *warnings) } for _, host := range result.Hosts { fmt.Printf("Host: %s\n", host.Addresses[0]) for _, script := range host.HostScripts { fmt.Printf(" Script: %s\n", script.ID) fmt.Printf(" Output: %s\n", script.Output) } for _, port := range host.Ports { for _, script := range port.Scripts { fmt.Printf(" Port %d Script: %s\n", port.ID, script.ID) fmt.Printf(" Output: %s\n", script.Output) } } } } ``` -------------------------------- ### Run Basic Nmap Scan with Go Bindings Source: https://github.com/ullaakut/nmap/blob/master/README.md This example demonstrates how to initialize and run a basic nmap scan using the Ullaakut/nmap Go library. It targets specific hosts and ports, handles potential errors and warnings, and iterates through the results to display host and port information. Dependencies include the `context`, `fmt`, `log`, `time`, and `github.com/Ullaakut/nmap/v3` packages. ```go package main import ( "context" "fmt" "log" "time" "github.com/Ullaakut/nmap/v3" ) func main() { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() // Equivalent to `/usr/local/bin/nmap -p 80,443,843 google.com facebook.com youtube.com`, // with a 5-minute timeout. scanner, err := nmap.NewScanner( ctx, nmap.WithTargets("google.com", "facebook.com", "youtube.com"), nmap.WithPorts("80,443,843"), ) if err != nil { log.Fatalf("unable to create nmap scanner: %v", err) } result, warnings, err := scanner.Run() if len(*warnings) > 0 { log.Printf("run finished with warnings: %s\n", *warnings) // Warnings are non-critical errors from nmap. } if err != nil { log.Fatalf("unable to run nmap scan: %v", err) } // Use the results to print an example output for _, host := range result.Hosts { if len(host.Ports) == 0 || len(host.Addresses) == 0 { continue } fmt.Printf("Host %q:\n", host.Addresses[0]) for _, port := range host.Ports { fmt.Printf("\tPort %d/%s %s %s\n", port.ID, port.Protocol, port.State, port.Service.Name) } } fmt.Printf("Nmap done: %d hosts up scanned in %.2f seconds\n", len(result.Hosts), result.Stats.Finished.Elapsed) } ``` -------------------------------- ### Go Nmap Timing and Performance Optimization Source: https://context7.com/ullaakut/nmap/llms.txt Illustrates how to configure scan timing and performance parameters for different scenarios using the nmap library in Go. Examples include fast aggressive scans, slow stealthy scans, and custom timing configurations. Ensure the nmap library is installed. ```go package main import ( "context" "log" "time" "github.com/Ullaakut/nmap/v3" ) func main() { ctx := context.Background() // Fast aggressive scan fastScanner, err := nmap.NewScanner( ctx, nmap.WithTargets("192.168.1.0/24"), nmap.WithPorts("1-1000"), nmap.WithTimingTemplate(nmap.TimingAggressive), nmap.WithMaxParallelism(100), nmap.WithMaxRetries(1), ) if err != nil { log.Fatalf("error creating fast scanner: %v", err) } // Slow stealthy scan stealthyScanner, err := nmap.NewScanner( ctx, nmap.WithTargets("192.168.1.1"), nmap.WithPorts("1-1000"), nmap.WithTimingTemplate(nmap.TimingSneaky), nmap.WithScanDelay(500*time.Millisecond), nmap.WithMaxRetries(3), ) if err != nil { log.Fatalf("error creating stealthy scanner: %v", err) } // Custom timing parameters customScanner, err := nmap.NewScanner( ctx, nmap.WithTargets("192.168.1.0/24"), nmap.WithPorts("80,443,8080"), nmap.WithMinRTTTimeout(100*time.Millisecond), nmap.WithMaxRTTTimeout(1*time.Second), nmap.WithHostTimeout(30*time.Second), nmap.WithMinRate(100), nmap.WithMaxRate(1000), ) if err != nil { log.Fatalf("error creating custom scanner: %v", err) } result, warnings, err := fastScanner.Run() if err != nil { log.Fatalf("scan failed: %v", err) } if len(*warnings) > 0 { log.Printf("warnings: %s\n", *warnings) } log.Printf("Scan completed in %.2f seconds\n", result.Stats.Finished.Elapsed) } ``` -------------------------------- ### Configure Custom Nmap Binary Path and Arguments (Go) Source: https://context7.com/ullaakut/nmap/llms.txt This Go example shows how to customize the Nmap execution by specifying a custom binary path and passing raw arguments to Nmap. It also demonstrates dynamically adding options after the scanner has been created and how to view the generated command-line arguments. ```Go package main import ( "context" "log" "github.com/Ullaakut/nmap/v3" ) func main() { ctx := context.Background() // Use custom nmap binary path scanner, err := nmap.NewScanner( ctx, nmap.WithBinaryPath("/usr/local/bin/nmap"), nmap.WithTargets("192.168.1.1"), nmap.WithPorts("80,443"), ) if err != nil { log.Fatalf("error: %v", err) } // Add custom arguments (use with caution) customScanner, err := nmap.NewScanner( ctx, nmap.WithTargets("192.168.1.1"), nmap.WithCustomArguments("-p", "80,443", "--reason", "-v"), ) if err != nil { log.Fatalf("error: %v", err) } // Dynamically add options after creation scanner.AddOptions( nmap.WithServiceInfo(), nmap.WithTimingTemplate(nmap.TimingAggressive), ) // View the generated command-line arguments args := scanner.Args() log.Printf("Nmap will be executed with args: %v\n", args) result, warnings, err := scanner.Run() if err != nil { log.Fatalf("scan failed: %v", err) } if len(*warnings) > 0 { log.Printf("warnings: %s\n", *warnings) } log.Printf("Scan completed: %d hosts\n", len(result.Hosts)) } ``` -------------------------------- ### Go Nmap Host Discovery Methods Source: https://context7.com/ullaakut/nmap/llms.txt Demonstrates various host discovery techniques using the nmap library in Go. It covers basic ping scans, SYN discovery on specific ports, and skipping host discovery entirely. Ensure the nmap library is installed and accessible. ```go package main import ( "context" "fmt" "log" "github.com/Ullaakut/nmap/v3" ) func main() { ctx := context.Background() // Ping scan to discover hosts without port scanning scanner, err := nmap.NewScanner( ctx, nmap.WithTargets("192.168.1.0/24"), nmap.WithPingScan(), ) if err != nil { log.Fatalf("unable to create scanner: %v", err) } // SYN discovery on specific ports synDiscoveryScanner, err := nmap.NewScanner( ctx, nmap.WithTargets("192.168.1.0/24"), nmap.WithSYNDiscovery("80", "443", "22"), nmap.WithPingScan(), ) if err != nil { log.Fatalf("unable to create scanner: %v", err) } // Skip host discovery and treat all hosts as online noDiscoveryScanner, err := nmap.NewScanner( ctx, nmap.WithTargets("192.168.1.1-50"), nmap.WithSkipHostDiscovery(), nmap.WithPorts("80,443"), ) if err != nil { log.Fatalf("unable to create scanner: %v", err) } result, warnings, err := scanner.Run() if err != nil { log.Fatalf("scan failed: %v", err) } if len(*warnings) > 0 { log.Printf("warnings: %s\n", *warnings) } fmt.Printf("Discovered %d hosts:\n", len(result.Hosts)) for _, host := range result.Hosts { if len(host.Addresses) > 0 { fmt.Printf(" %s (%s)\n", host.Addresses[0].Addr, host.Status.State) } } } ``` -------------------------------- ### Handle Nmap Scan Errors Gracefully (Go) Source: https://context7.com/ullaakut/nmap/llms.txt This Go code illustrates comprehensive error handling for Nmap scans using the nmap Go library. It checks for common issues like nmap not being installed, scan timeouts, interruptions, parsing errors, memory allocation failures, and permission requirements. ```Go package main import ( "context" "errors" "log" "time" "github.com/Ullaakut/nmap/v3" ) func main() { ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() scanner, err := nmap.NewScanner( ctx, nmap.WithTargets("192.168.1.1"), nmap.WithPorts("1-65535"), nmap.WithServiceInfo(), ) // Check scanner creation errors if err != nil { if errors.Is(err, nmap.ErrNmapNotInstalled) { log.Fatalf("nmap is not installed on this system") } log.Fatalf("scanner creation failed: %v", err) } result, warnings, err := scanner.Run() // Handle warnings (non-critical errors) if len(*warnings) > 0 { for _, warning := range *warnings { log.Printf("Warning: %s\n", warning) } } // Handle scan errors if err != nil { switch { case errors.Is(err, nmap.ErrScanTimeout): log.Fatalf("scan timed out after context deadline") case errors.Is(err, nmap.ErrScanInterrupt): log.Fatalf("scan was interrupted (SIGINT)") case errors.Is(err, nmap.ErrParseOutput): log.Fatalf("failed to parse nmap output: %v", err) case errors.Is(err, nmap.ErrMallocFailed): log.Fatalf("nmap ran out of memory") case errors.Is(err, nmap.ErrRequiresRoot): log.Fatalf("this scan technique requires root privileges") case errors.Is(err, nmap.ErrResolveName): log.Fatalf("could not resolve target hostname") default: log.Fatalf("scan failed: %v", err) } } log.Printf("Scan completed successfully: %d hosts found\n", len(result.Hosts)) } ``` -------------------------------- ### Configure TCP/UDP Scan Techniques in Go with Nmap Source: https://context7.com/ullaakut/nmap/llms.txt This Go code demonstrates how to configure various Nmap scan techniques, including SYN scan (requires root), Connect scan (no root required), and a combination of UDP and TCP SYN scans. Each configuration uses `nmap.NewScanner` with specific options like `WithSYNScan()`, `WithConnectScan()`, and `WithUDPScan()` to tailor the scanning behavior for different scenarios. Error handling and warnings are included for each scan setup. ```go package main import ( "context" "log" "github.com/Ullaakut/nmap/v3" ) func main() { ctx := context.Background() // SYN scan (stealth scan, requires root) synScanner, err := nmap.NewScanner( ctx, nmap.WithTargets("192.168.1.1"), nmap.WithPorts("1-1000"), nmap.WithSYNScan(), ) if err != nil { log.Fatalf("SYN scan error: %v", err) } // Connect scan (no root required) connectScanner, err := nmap.NewScanner( ctx, nmap.WithTargets("192.168.1.1"), nmap.WithPorts("1-1000"), nmap.WithConnectScan(), ) if err != nil { log.Fatalf("Connect scan error: %v", err) } // UDP scan combined with TCP SYN scan combinedScanner, err := nmap.NewScanner( ctx, nmap.WithTargets("192.168.1.1"), nmap.WithPorts("53,161,162"), nmap.WithUDPScan(), nmap.WithSYNScan(), ) if err != nil { log.Fatalf("Combined scan error: %v", err) } result, warnings, err := synScanner.Run() if err != nil { log.Fatalf("scan failed: %v", err) } if len(*warnings) > 0 { log.Printf("warnings: %s\n", *warnings) } log.Printf("Found %d hosts\n", len(result.Hosts)) } ``` -------------------------------- ### Create Basic Nmap Scanner and Run Scan in Go Source: https://context7.com/ullaakut/nmap/llms.txt This Go code demonstrates how to create a basic Nmap scanner instance, specify target hosts and ports, execute a scan, and process the results. It handles scanner creation, scan execution, and basic result iteration, including error and warning management. Dependencies include the 'context' and 'log' packages from Go's standard library, and the 'nmap' library itself. ```go package main import ( "context" "fmt" "log" "time" "github.com/Ullaakut/nmap/v3" ) func main() { ctx, cancel := context.WithTimeout(context.Background(), 5*time.Minute) defer cancel() scanner, err := nmap.NewScanner( ctx, nmap.WithTargets("google.com", "facebook.com", "youtube.com"), nmap.WithPorts("80,443,843"), ) if err != nil { log.Fatalf("unable to create nmap scanner: %v", err) } result, warnings, err := scanner.Run() if len(*warnings) > 0 { log.Printf("run finished with warnings: %s\n", *warnings) } if err != nil { log.Fatalf("unable to run nmap scan: %v", err) } for _, host := range result.Hosts { if len(host.Ports) == 0 || len(host.Addresses) == 0 { continue } fmt.Printf("Host %q:\n", host.Addresses[0]) for _, port := range host.Ports { fmt.Printf("\tPort %d/%s %s %s\n", port.ID, port.Protocol, port.State, port.Service.Name) } } fmt.Printf("Nmap done: %d hosts up scanned in %.2f seconds\n", len(result.Hosts), result.Stats.Finished.Elapsed) } ``` -------------------------------- ### Specify Nmap Scan Targets with Go Source: https://context7.com/ullaakut/nmap/llms.txt Illustrates various methods for specifying scan targets in Nmap using the Go library. This includes providing single IPs, hostnames, IP ranges, CIDR notation, excluding specific targets, and reading targets from a file. Requires the nmap binary. ```go package main import ( "context" "log" "os" "github.com/Ullaakut/nmap/v3" ) func main() { ctx := context.Background() // Multiple target formats scanner, err := nmap.NewScanner( ctx, nmap.WithTargets( "192.168.1.1", "192.168.1.10-20", "scanme.nmap.org", "192.168.2.0/24", ), nmap.WithPorts("80,443"), ) if err != nil { log.Fatalf("error: %v", err) } // Target exclusions excludeScanner, err := nmap.NewScanner( ctx, nmap.WithTargets("192.168.1.0/24"), nmap.WithTargetExclusions("192.168.1.1", "192.168.1.254"), nmap.WithPorts("22,80,443"), ) if err != nil { log.Fatalf("error: %v", err) } // Read targets from file targetFile := "/tmp/targets.txt" os.WriteFile(targetFile, []byte("192.168.1.1\n192.168.1.2\nscanme.nmap.org\n"), 0644) fileScanner, err := nmap.NewScanner( ctx, nmap.WithTargetInput(targetFile), nmap.WithPorts("80,443"), ) if err != nil { log.Fatalf("error: %v", err) } result, warnings, err := scanner.Run() if err != nil { log.Fatalf("scan failed: %v", err) } if len(*warnings) > 0 { log.Printf("warnings: %s\n", *warnings) } log.Printf("Scanned %d hosts\n", result.Stats.Hosts.Total) } ``` -------------------------------- ### Discover Network Interfaces and Routes with Go Nmap Source: https://context7.com/ullaakut/nmap/llms.txt This Go code snippet utilizes the nmap library to retrieve and display information about local network interfaces and the system's routing table. It lists details such as device name, IP address, MAC address, MTU, and interface status. Route information includes destination, device, metric, and gateway. ```go package main import ( "context" "fmt" "log" "github.com/Ullaakut/nmap/v3" ) func main() { scanner, err := nmap.NewScanner(context.Background()) if err != nil { log.Fatalf("unable to create nmap scanner: %v", err) } interfaces, err := scanner.GetInterfaceList() if err != nil { log.Fatalf("unable to get interface list: %v", err) } fmt.Println("Network Interfaces:") for _, iface := range interfaces.Interfaces { fmt.Printf(" Device: %s (%s)\n", iface.Device, iface.Short) fmt.Printf(" IP: %s\n", iface.IP) fmt.Printf(" Mask: %s\n", iface.IPMask) fmt.Printf(" Type: %s\n", iface.Type) fmt.Printf(" Status: Up=%v\n", iface.Up) fmt.Printf(" MTU: %d\n", iface.MTU) if len(iface.Mac) > 0 { fmt.Printf(" MAC: %s\n", iface.Mac) } fmt.Println() } fmt.Println("Routes:") for _, route := range interfaces.Routes { fmt.Printf(" Destination: %s/%s\n", route.DestinationIP, route.DestinationIPMask) fmt.Printf(" Device: %s\n", route.Device) fmt.Printf(" Metric: %d\n", route.Metric) if route.Gateway != nil { fmt.Printf(" Gateway: %s\n", route.Gateway) } fmt.Println() } } ``` -------------------------------- ### Parse Nmap Scan Results with Go Source: https://context7.com/ullaakut/nmap/llms.txt This Go snippet demonstrates how to use the nmap library to perform a network scan and parse the detailed results. It covers accessing scan metadata, host information (IP addresses, status, hostnames), port details (service, product, version), OS detection, and traceroute information. The output includes scan duration and a summary of up hosts. ```go package main import ( "context" "fmt" "log" "github.com/Ullaakut/nmap/v3" ) func main() { ctx := context.Background() scanner, err := nmap.NewScanner( ctx, nmap.WithTargets("scanme.nmap.org"), nmap.WithPorts("22,80,443"), nmap.WithServiceInfo(), nmap.WithOSDetection(), ) if err != nil { log.Fatalf("error: %v", err) } result, warnings, err := scanner.Run() if err != nil { log.Fatalf("scan failed: %v", err) } if len(*warnings) > 0 { log.Printf("warnings: %s\n", *warnings) } // Parse scan metadata fmt.Printf("Nmap version: %s\n", result.Version) fmt.Printf("Scan started: %s\n", result.StartStr) fmt.Printf("Command: %s\n", result.Args) fmt.Printf("Scan duration: %.2f seconds\n", result.Stats.Finished.Elapsed) // Iterate through discovered hosts for _, host := range result.Hosts { fmt.Printf("\nHost: %s\n", host.Addresses[0].Addr) fmt.Printf("Status: %s (reason: %s)\n", host.Status.State, host.Status.Reason) // Hostnames for _, hostname := range host.Hostnames { fmt.Printf("Hostname: %s (%s)\n", hostname.Name, hostname.Type) } // Port information for _, port := range host.Ports { fmt.Printf(" Port %d/%s: %s\n", port.ID, port.Protocol, port.State.State) // Service details if port.Service.Name != "" { fmt.Printf(" Service: %s", port.Service.Name) if port.Service.Product != "" { fmt.Printf(" (%s", port.Service.Product) if port.Service.Version != "" { fmt.Printf(" %s", port.Service.Version) } fmt.Printf(")") } fmt.Printf("\n") } } // OS detection results for _, osmatch := range host.OS.Matches { fmt.Printf(" OS: %s (accuracy: %d%%)\n", osmatch.Name, osmatch.Accuracy) for _, osclass := range osmatch.Classes { fmt.Printf(" Type: %s, Vendor: %s, Family: %s\n", osclass.Type, osclass.Vendor, osclass.Family) } } // Traceroute if len(host.Trace.Hops) > 0 { fmt.Printf(" Traceroute:\n") for _, hop := range host.Trace.Hops { fmt.Printf(" Hop %.0f: %s (%s) RTT: %s\n", hop.TTL, hop.Host, hop.IPAddr, hop.RTT) } } } fmt.Printf("\nHosts up: %d/%d\n", result.Stats.Hosts.Up, result.Stats.Hosts.Total) } ``` -------------------------------- ### Monitor Nmap Scan Progress in Real-Time Using Go Channels Source: https://context7.com/ullaakut/nmap/llms.txt This Go code snippet illustrates how to monitor the progress of an Nmap scan in real-time by utilizing a channel. It configures the scanner with target, ports, service information, and verbosity, then creates a `progress` channel. A separate goroutine reads from this channel to display the scan's progress percentage. The `Progress` method is used to link the channel to the scanner's execution, providing immediate feedback. ```go package main import ( "context" "fmt" "log" "github.com/Ullaakut/nmap/v3" ) func main() { scanner, err := nmap.NewScanner( context.Background(), nmap.WithTargets("localhost"), nmap.WithPorts("1-10000"), nmap.WithServiceInfo(), nmap.WithVerbosity(3), ) if err != nil { log.Fatalf("unable to create nmap scanner: %v", err) } progress := make(chan float32, 1) go func() { for p := range progress { fmt.Printf("Progress: %v %%\n", p) } }() result, warnings, err := scanner.Progress(progress).Run() if len(*warnings) > 0 { log.Printf("run finished with warnings: %s\n", *warnings) } if err != nil { log.Fatalf("unable to run nmap scan: %v", err) } fmt.Printf("Nmap done: %d hosts up scanned in %.2f seconds\n", len(result.Hosts), result.Stats.Finished.Elapsed) } ``` -------------------------------- ### Stream Nmap Scan Output to File (Go) Source: https://context7.com/ullaakut/nmap/llms.txt This Go code snippet demonstrates how to stream Nmap scan results directly to a file using the nmap Go library. It covers saving the full XML output and also streaming the output incrementally to an io.Writer interface, with basic error and warning handling. ```Go package main import ( "context" "log" "os" "github.com/Ullaakut/nmap/v3" ) func main() { ctx := context.Background() // Save XML output to file fileScanner, err := nmap.NewScanner( ctx, nmap.WithTargets("scanme.nmap.org"), nmap.WithPorts("80,443"), ) if err != nil { log.Fatalf("error: %v", err) } result, warnings, err := fileScanner.ToFile("/tmp/scan_results.xml").Run() if err != nil { log.Fatalf("scan failed: %v", err) } if len(*warnings) > 0 { log.Printf("warnings: %s\n", *warnings) } log.Printf("Scan saved to /tmp/scan_results.xml") // Stream output to io.Writer file, err := os.Create("/tmp/scan_stream.xml") if err != nil { log.Fatalf("error creating file: %v", err) } defer file.Close() streamScanner, err := nmap.NewScanner( ctx, nmap.WithTargets("192.168.1.1"), nmap.WithPorts("22,80,443"), ) if err != nil { log.Fatalf("error: %v", err) } result2, warnings2, err := streamScanner.Streamer(file).Run() if err != nil { log.Fatalf("scan failed: %v", err) } if len(*warnings2) > 0 { log.Printf("warnings: %s\n", *warnings2) } log.Printf("Found %d hosts, streamed to file\n", len(result2.Hosts)) // Export result back to file err = result.ToFile("/tmp/result_export.xml") if err != nil { log.Fatalf("export failed: %v", err) } log.Printf("Result exported successfully") } ``` -------------------------------- ### Nmap Scan with Service Detection and Custom Filtering in Go Source: https://context7.com/ullaakut/nmap/llms.txt This Go code illustrates how to configure an Nmap scanner for service version detection on a network range, applying custom filters for ports and hosts. It utilizes options like `WithServiceInfo`, `WithTimingTemplate`, `WithFilterPort`, and `WithFilterHost` to refine scan results. The code depends on the 'context', 'fmt', and 'log' packages, along with the 'nmap' library. ```go package main import ( "context" "fmt" "log" "github.com/Ullaakut/nmap/v3" ) func main() { scanner, err := nmap.NewScanner( context.Background(), nmap.WithTargets("192.168.0.0/24"), nmap.WithPorts("80", "554", "8554"), nmap.WithServiceInfo(), nmap.WithTimingTemplate(nmap.TimingAggressive), nmap.WithFilterPort(func(p nmap.Port) bool { return p.Service.Name == "rtsp" }), nmap.WithFilterHost(func(h nmap.Host) bool { for idx := range h.Ports { if h.Ports[idx].Status() == nmap.Open { return true } } return false }), ) if err != nil { log.Fatalf("unable to create nmap scanner: %v", err) } result, warnings, err := scanner.Run() if len(*warnings) > 0 { log.Printf("run finished with warnings: %s\n", *warnings) } if err != nil { log.Fatalf("nmap scan failed: %v", err) } for _, host := range result.Hosts { fmt.Printf("Host %s\n", host.Addresses[0]) for _, port := range host.Ports { fmt.Printf("\tPort %d open with RTSP service\n", port.ID) } } } ``` -------------------------------- ### Execute Nmap Scans Asynchronously in Go Source: https://context7.com/ullaakut/nmap/llms.txt This Go code snippet demonstrates how to perform Nmap scans asynchronously, preventing the main goroutine from being blocked. It uses the `nmap.NewScanner` function with target and port configurations, then initiates an asynchronous run using the `Async` method. The `done` channel is used to signal completion and retrieve results or errors, allowing other work to be performed concurrently. ```go package main import ( "context" "fmt" "log" "github.com/Ullaakut/nmap/v3" ) func main() { scanner, err := nmap.NewScanner( context.Background(), nmap.WithTargets("google.com", "facebook.com", "youtube.com"), nmap.WithPorts("80,443,843"), ) if err != nil { log.Fatalf("unable to create nmap scanner: %v", err) } done := make(chan error) result, warnings, err := scanner.Async(done).Run() if err != nil { log.Fatal(err) } // Perform other work here while scan runs in background if err := <-done; err != nil { if len(*warnings) > 0 { log.Printf("run finished with warnings: %s\n", *warnings) } log.Fatal(err) } for _, host := range result.Hosts { if len(host.Ports) == 0 || len(host.Addresses) == 0 { continue } fmt.Printf("Host %q:\n", host.Addresses[0]) for _, port := range host.Ports { fmt.Printf("\tPort %d/%s %s %s\n", port.ID, port.Protocol, port.State, port.Service.Name) } } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.