package Plugins import ( "bytes" "encoding/binary" "fmt" "net" "os" "os/exec" "os/user" "runtime" "strings" "sync" "time" ) var icmp ICMP var AliveHosts []string type ICMP struct { Type uint8 Code uint8 Checksum uint16 Identifier uint16 SequenceNum uint16 } type SystemInfo struct { OS string ARCH string HostName string Groupid string Userid string Username string UserHomeDir string } func GetSys() SystemInfo { var sysinfo SystemInfo sysinfo.OS = runtime.GOOS sysinfo.ARCH = runtime.GOARCH name, err := os.Hostname() if err == nil { sysinfo.HostName = name } u, err := user.Current() sysinfo.Groupid = u.Gid sysinfo.Userid = u.Uid sysinfo.Username = u.Username sysinfo.UserHomeDir = u.HomeDir return sysinfo } func isping(ip string) bool { icmp.Type = 8 icmp.Code = 0 icmp.Checksum = 0 icmp.Identifier = 0 icmp.SequenceNum = 0 recvBuf := make([]byte, 32) var buffer bytes.Buffer binary.Write(&buffer, binary.BigEndian, icmp) icmp.Checksum = CheckSum(buffer.Bytes()) buffer.Reset() binary.Write(&buffer, binary.BigEndian, icmp) Time, _ := time.ParseDuration("2s") conn, err := net.DialTimeout("ip4:icmp", ip, Time) if err != nil { return false } _, err = conn.Write(buffer.Bytes()) if err != nil { return false } conn.SetReadDeadline(time.Now().Add(time.Second * 2)) num, err := conn.Read(recvBuf) if err != nil { return false } conn.SetReadDeadline(time.Time{}) if string(recvBuf[0:num]) != "" { fmt.Printf("(ICMP) Target '%s' is alive\n",ip) return true } return false } func CheckSum(data []byte) uint16 { var ( sum uint32 length int = len(data) index int ) for length > 1 { sum += uint32(data[index])<<8 + uint32(data[index+1]) index += 2 length -= 2 } if length > 0 { sum += uint32(data[index]) } sum += (sum >> 16) return uint16(^sum) } func IcmpCheck(hostslist []string) { var wg sync.WaitGroup mutex := &sync.Mutex{} for _,host :=range hostslist{ wg.Add(1) go func(host string) { defer wg.Done() if isping(host){ mutex.Lock() AliveHosts = append(AliveHosts, host) mutex.Unlock() } }(host) } wg.Wait() } func ExecCommandPing(ip string,bsenv string) bool { command := exec.Command(bsenv, "-c", "ping -c 1 -w 1 "+ip+" >/dev/null && echo true || echo false") //ping -c 1 -i 0.5 -t 4 -W 2 -w 5 "+ip+" >/dev/null && echo true || echo false" outinfo := bytes.Buffer{} command.Stdout = &outinfo err := command.Start() if err != nil{ return false } if err = command.Wait();err!=nil{ return false }else{ if(strings.Contains(outinfo.String(), "true")) { return true }else { return false } } } func PingCMDcheck(hostslist []string,bsenv string) { var wg sync.WaitGroup mutex := &sync.Mutex{} limiter := make(chan struct{}, 40) //aliveHost := make(chan string, 20) //go func() { // for s := range aliveHost { // fmt.Println(s) // } //}() for _,host :=range hostslist{ wg.Add(1) limiter <- struct{}{} go func(host string) { defer wg.Done() if ExecCommandPing(host,bsenv){ mutex.Lock() fmt.Printf("(Ping) Target '%s' is alive\n",host) AliveHosts = append(AliveHosts, host) mutex.Unlock() } <-limiter }(host) } wg.Wait() //close(aliveHost) } func ICMPRun(hostslist []string) []string{ var sysinfo SystemInfo sysinfo = GetSys() if sysinfo.OS == "windows" { IcmpCheck(hostslist) }else if sysinfo.OS == "linux" { if (sysinfo.Groupid == "0" || sysinfo.Userid == "0" || sysinfo.Username == "root") { IcmpCheck(hostslist) }else { PingCMDcheck(hostslist,"/bin/bash") } }else if sysinfo.OS == "darwin" { if (sysinfo.Groupid == "0" || sysinfo.Userid == "0" || sysinfo.Username == "root") { IcmpCheck(hostslist) }else { PingCMDcheck(hostslist,"/usr/local/bin/bash") } } return AliveHosts }