magellan/internal/scan.go
David J. Allen 8faa570b0a Minor tweaks, changes, and fixes
Signed-off-by: David J. Allen <davidallendj@gmail.com>
2023-09-14 13:41:12 -06:00

96 lines
No EOL
1.9 KiB
Go

package magellan
import (
"fmt"
"net"
"sync"
"time"
)
func rawConnect(host string, ports []int, timeout int, keepOpenOnly bool) []BMCProbeResult {
results := []BMCProbeResult{}
for _, p := range ports {
result := BMCProbeResult{
Host: host,
Port: p,
Protocol: "tcp",
State: false,
}
t := time.Second * time.Duration(timeout)
port := fmt.Sprint(p)
conn, err := net.DialTimeout("tcp", net.JoinHostPort(host, port), t)
if err != nil {
result.State = false
// fmt.Println("Connecting error:", err)
}
if conn != nil {
result.State = true
defer conn.Close()
// fmt.Println("Opened", net.JoinHostPort(host, port))
}
if keepOpenOnly {
if result.State {
results = append(results, result)
}
} else {
results = append(results, result)
}
}
return results
}
func GenerateHosts(subnet string, begin uint8, end uint8) []string {
hosts := []string{}
ip := net.ParseIP(subnet).To4()
for i := begin; i < end; i++ {
ip[3] = byte(i)
hosts = append(hosts, fmt.Sprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]))
}
return hosts
}
func ScanForAssets(hosts []string, ports []int, threads int, timeout int) []BMCProbeResult {
results := make([]BMCProbeResult, 0, len(hosts))
done := make(chan struct{}, threads+1)
chanHost := make(chan string, threads+1)
// chanPort := make(chan int, threads+1)
var wg sync.WaitGroup
wg.Add(threads)
for i := 0; i < threads; i++ {
go func() {
for {
host, ok := <-chanHost
if !ok {
wg.Done()
return
}
s := rawConnect(host, ports, timeout, true)
results = append(results, s...)
}
}()
}
for _, host := range hosts {
chanHost <- host
}
go func() {
select {
case <-done:
wg.Done()
break
default:
time.Sleep(1000)
}
}()
close(chanHost)
wg.Wait()
close(done)
return results
}
func GetDefaultPorts() []int {
return []int{SSH_PORT, HTTPS_PORT, IPMI_PORT}
}