pinter-u-krovu-bot/ping/ping.go
2024-10-05 12:34:47 +02:00

82 lines
1.5 KiB
Go

package ping
import (
"fmt"
"net"
"os/exec"
"regexp"
"sync"
)
func PingLocal255() int {
localIP, err := getLocalIP()
if err != nil {
fmt.Println("Error getting local IP:", err)
return 0
}
network := getNetworkPrefix(localIP)
var wg sync.WaitGroup
deviceCount := 0
mu := &sync.Mutex{}
for i := 2; i < 255; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
addr := fmt.Sprintf("%s.%d", network[:len(network)-2], i)
if addr == localIP.String() {
return
}
if ping(addr) {
mu.Lock()
deviceCount++
mu.Unlock()
}
}(i)
}
wg.Wait()
return deviceCount
}
func getLocalIP() (net.IP, error) {
addrs, err := net.InterfaceAddrs()
if err != nil {
return nil, err
}
for _, addr := range addrs {
if ipnet, ok := addr.(*net.IPNet); ok && ipnet.IP.IsGlobalUnicast() {
return ipnet.IP, nil
}
}
return nil, fmt.Errorf("local IP not found")
}
func getNetworkPrefix(ip net.IP) string {
ip = ip.To4()
return fmt.Sprintf("%d.%d.%d.0", ip[0], ip[1], ip[2])
}
func isValidIPv4(ip string) bool {
ipv4Regex := `^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$`
re := regexp.MustCompile(ipv4Regex)
return re.MatchString(ip)
}
func ping(ip string) bool {
if !isValidIPv4(ip) {
return false
}
output, err := exec.Command("ping", "-c", "1", "-W", "1", ip).CombinedOutput()
if err != nil {
return false
}
_ = output
return true
}