package scan import ( "fmt" "net" "net/netip" "sync" "time" ) var PORT_MAP = map[int]string{ 22: "ssh", 23: "telnet", 53: "dns", 80: "http", 25: "smtp", 443: "https", 8080: "unknown", 8081: "unknown", 8082: "unknown", 8085: "unknown", 8090: "unknown", 8091: "unknown", 9010: "unknown", 9012: "unknown", 10000: "unknown", } type TcpScanHost struct { Host string `json:"host"` Ipv4Address netip.Addr `json:"ipv4_address"` PortsScanned []PortScanResult `json:"ports_scanned"` } type PortScanResult struct { PortNumber int `json:"port_number"` Service string `json:"service"` Protocol string `json:"protocol"` Listening bool `json:"listening"` } type PortScanDirective struct { Pairs map[int]string } func RetrieveScanDirectives() PortScanDirective { return PortScanDirective{Pairs: PORT_MAP} } /* Scans a single host on a single port :param addr: the address to dial :param port: the port number to dial */ func singlePortScan(addr string, port int, svcs string) *PortScanResult { //defer wg.Done() address := fmt.Sprintf("%v:%d", addr, port) conn, err := net.DialTimeout("tcp", address, 1*time.Second) if err != nil { return &PortScanResult{PortNumber: port, Protocol: "tcp", Service: svcs, Listening: false} } conn.Close() return &PortScanResult{PortNumber: port, Protocol: "tcp", Service: svcs, Listening: true} } /* Perform a TCP scan on the pointers host :param posts: a list of ports to scan against a host */ func (t *TcpScanHost) ScanPortRange(ports []int) []*PortScanResult { wg := &sync.WaitGroup{} out := make(chan *PortScanResult) var res []*PortScanResult wgOuter := &sync.WaitGroup{} wgOuter.Add(1) go func() { defer wgOuter.Done() ports := RetrieveScanDirectives() for p, s := range ports.Pairs { wg.Add(1) port := p svcs := s go func() { out <- singlePortScan(t.Ipv4Address.String(), port, svcs) wg.Done() }() } wg.Wait() close(out) }() for result := range out { if !result.Listening { continue } res = append(res, result) } wgOuter.Wait() return res } /* Evaluate whether the host has an entry in the ARP table */ func (h *TcpScanHost) IsOnline() bool { return false }