package Plugins import ( "fmt" "github.com/shadow1ng/fscan/common" "net" "strconv" "sync" "time" ) type Addr struct { ip string port int } func PortScan(hostslist []string, ports string, timeout int64) []string { var AliveAddress []string probePorts := common.ParsePort(ports) noPorts := common.ParsePort(common.NoPorts) if len(noPorts) > 0 { tmp := make(map[int]struct{}) var tmpPorts []int for _, port := range probePorts { for _, noport := range noPorts { if port != noport { if _, ok := tmp[port]; !ok { tmp[port] = struct{}{} tmpPorts = append(tmpPorts, port) } } } } probePorts = tmpPorts } workers := common.Threads Addrs := make(chan Addr, len(hostslist)*len(probePorts)) results := make(chan string, len(hostslist)*len(probePorts)) var wg sync.WaitGroup //接收结果 go func() { for found := range results { AliveAddress = append(AliveAddress, found) wg.Done() } }() //多线程扫描 for i := 0; i < workers; i++ { go func() { for addr := range Addrs { PortConnect(addr, results, timeout, &wg) wg.Done() } }() } //添加扫描目标 for _, port := range probePorts { for _, host := range hostslist { wg.Add(1) Addrs <- Addr{host, port} } } wg.Wait() close(Addrs) close(results) return AliveAddress } func PortConnect(addr Addr, respondingHosts chan<- string, adjustedTimeout int64, wg *sync.WaitGroup) { host, port := addr.ip, addr.port con, err := net.DialTimeout("tcp4", fmt.Sprintf("%s:%v", host, port), time.Duration(adjustedTimeout)*time.Second) if err == nil { con.Close() address := host + ":" + strconv.Itoa(port) result := fmt.Sprintf("%s open", address) common.LogSuccess(result) respondingHosts <- address wg.Add(1) } }