You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
95 lines
2.4 KiB
95 lines
2.4 KiB
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"net"
|
|
"os"
|
|
"os/exec"
|
|
"sort"
|
|
"strings"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
// PingResult holds the result of a ping operation
|
|
type PingResult struct {
|
|
IP net.IP
|
|
Message string
|
|
}
|
|
|
|
// parseIP parses the string IP to net.IP
|
|
func parseIP(ipStr string) net.IP {
|
|
return net.ParseIP(ipStr)
|
|
}
|
|
|
|
// pingIP pings an IP address and sends a PingResult to the results channel.
|
|
func pingIP(ipStr string, wg *sync.WaitGroup, results chan<- PingResult) {
|
|
defer wg.Done()
|
|
ip := parseIP(ipStr)
|
|
cmd := exec.Command("ping", "-c", "3", "-W", "5", ipStr)
|
|
if err := cmd.Run(); err != nil {
|
|
results <- PingResult{IP: ip, Message: fmt.Sprintf("\x1b[0m%s\x1b[0m is \x1b[1m\x1b[31mdown\x1b[0m", ipStr)}
|
|
} else {
|
|
results <- PingResult{IP: ip, Message: fmt.Sprintf("\x1b[1m%s\x1b[0m is \x1b[1m\x1b[32mup\x1b[0m", ipStr)}
|
|
}
|
|
}
|
|
|
|
func main() {
|
|
if len(os.Args) < 2 {
|
|
fmt.Println("Usage: chkip <IP1> <IP2> <IP3> ...")
|
|
return
|
|
}
|
|
|
|
var wg sync.WaitGroup
|
|
results := make(chan PingResult, len(os.Args)-1)
|
|
|
|
// Start the spinner in a goroutine
|
|
stopSpinner := make(chan struct{})
|
|
go func() {
|
|
spinner := []rune{'-', '\\', '|', '/'}
|
|
i := 0
|
|
for {
|
|
select {
|
|
case <-stopSpinner:
|
|
return
|
|
default:
|
|
fmt.Printf("\rPlease wait... %c", spinner[i%len(spinner)])
|
|
i++
|
|
time.Sleep(100 * time.Millisecond) // Adjust speed as needed
|
|
}
|
|
}
|
|
}()
|
|
|
|
// Start a goroutine for each IP address.
|
|
for _, ipStr := range os.Args[1:] {
|
|
wg.Add(1)
|
|
go pingIP(ipStr, &wg, results)
|
|
}
|
|
|
|
// Close the results channel once all goroutines have finished.
|
|
go func() {
|
|
wg.Wait()
|
|
close(results)
|
|
fmt.Printf("\r%s\r", strings.Repeat(" ", 16)) // Use enough spaces to cover the expected line length
|
|
|
|
}()
|
|
|
|
// Collect results
|
|
pingResults := make([]PingResult, 0, len(os.Args)-1)
|
|
for result := range results {
|
|
pingResults = append(pingResults, result)
|
|
}
|
|
|
|
// Sort results based on IP address
|
|
sort.Slice(pingResults, func(i, j int) bool {
|
|
return bytes.Compare(pingResults[i].IP, pingResults[j].IP) < 0
|
|
})
|
|
|
|
// Print sorted results
|
|
for _, result := range pingResults {
|
|
fmt.Println(result.Message)
|
|
}
|
|
}
|
|
|