neko-u-krovu-bot/ping/ping.go

82 lines
1.5 KiB
Go
Raw Normal View History

2024-10-03 13:52:06 +00:00
package ping
import (
"fmt"
"net"
"os/exec"
2024-10-03 15:46:43 +00:00
"regexp"
2024-10-03 13:52:06 +00:00
"sync"
)
2024-10-03 14:19:54 +00:00
func PingLocal255() int {
2024-10-03 13:52:06 +00:00
localIP, err := getLocalIP()
if err != nil {
fmt.Println("Error getting local IP:", err)
return 0
}
network := getNetworkPrefix(localIP)
2024-10-03 14:19:54 +00:00
2024-10-03 13:52:06 +00:00
var wg sync.WaitGroup
deviceCount := 0
mu := &sync.Mutex{}
2024-10-05 10:34:47 +00:00
for i := 2; i < 255; i++ {
2024-10-03 13:52:06 +00:00
wg.Add(1)
go func(i int) {
defer wg.Done()
addr := fmt.Sprintf("%s.%d", network[:len(network)-2], i)
2024-10-05 10:34:47 +00:00
if addr == localIP.String() {
return
}
2024-10-03 13:52:06 +00:00
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])
}
2024-10-03 15:46:43 +00:00
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)
}
2024-10-03 13:52:06 +00:00
func ping(ip string) bool {
2024-10-03 15:46:43 +00:00
if !isValidIPv4(ip) {
return false
}
2024-10-03 14:19:54 +00:00
output, err := exec.Command("ping", "-c", "1", "-W", "1", ip).CombinedOutput()
if err != nil {
return false
}
_ = output
return true
}