From 067fc0b8c96709a5046d6f8dc0d636df290cc696 Mon Sep 17 00:00:00 2001 From: Amir Date: Mon, 17 Jun 2024 18:51:50 +0300 Subject: [PATCH] init --- .gitignore | 2 ++ go.mod | 10 ++++++ go.sum | 10 ++++++ main.go | 59 +++++++++++++++++++++++++++++++++ rapaping/logging.go | 22 ++++++++++++ rapaping/ping.go | 81 +++++++++++++++++++++++++++++++++++++++++++++ rapaping/types.go | 26 +++++++++++++++ rapaping/util.go | 55 ++++++++++++++++++++++++++++++ 8 files changed, 265 insertions(+) create mode 100644 .gitignore create mode 100644 go.mod create mode 100644 go.sum create mode 100644 main.go create mode 100644 rapaping/logging.go create mode 100644 rapaping/ping.go create mode 100644 rapaping/types.go create mode 100644 rapaping/util.go diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fb195fc --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +*.bat +*.exe \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..0ea3650 --- /dev/null +++ b/go.mod @@ -0,0 +1,10 @@ +module tcp + +go 1.19 + +require github.com/gookit/color v1.5.4 + +require ( + github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 // indirect + golang.org/x/sys v0.17.0 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..76ea27f --- /dev/null +++ b/go.sum @@ -0,0 +1,10 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/gookit/color v1.5.4 h1:FZmqs7XOyGgCAxmWyPslpiok1k05wmY3SJTytgvYFs0= +github.com/gookit/color v1.5.4/go.mod h1:pZJOeOS8DM43rXbp4AZo1n9zCU2qjpcRko0b6/QJi9w= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778 h1:QldyIu/L63oPpyvQmHgvgickp1Yw510KJOqX7H24mg8= +github.com/xo/terminfo v0.0.0-20210125001918-ca9a967f8778/go.mod h1:2MuV+tbUrU1zIOPMxZ5EncGwgmMJsa+9ucAQZXxsObs= +golang.org/x/sys v0.17.0 h1:25cE3gD+tdBA7lp7QfhuV+rJiE9YXTcS3VG1SqssI/Y= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/main.go b/main.go new file mode 100644 index 0000000..f56d084 --- /dev/null +++ b/main.go @@ -0,0 +1,59 @@ +package main + +import ( + "log" + "net" + "os" + "strconv" + "strings" + "tcp/rapaping" + + "github.com/gookit/color" +) + +const ( + infoFormat = ` Address Details: + │ Address: [ %s ] + │ Hostname: [ %s ] + │ City: [ %s ] + │ Region: [ %s ] + │ Country: [ %s ] + │ ASN/ISP: [ %s ] + +` +) + +var logger = log.New(os.Stdout, "", 0) + +func main() { + if len(os.Args) != 3 { + color.Error.Printf("Usage: go run main.go ip port") + } + + host := os.Args[1] + port, err := strconv.Atoi(os.Args[2]) + if err != nil || !rapaping.IsValidPort(port) { + color.Error.Printf("Invalid port number:", err) + } + + logger.Println("rapaping v1.4.88 - Copyright (c) 1917 Big Armenian Daddy") + logger.Printf("\nConnecting to "+color.Green.Sprint("%s")+" on "+color.Green.Sprint("TCP %d")+":\n\n", host, port) + + ips, err := net.LookupIP(host) + if err != nil { + color.Error.Printf("Failed to resolve %s: %v", host, err) + os.Exit(1) + } else { + ipInfo, err := rapaping.GetIPInfo(ips[0].String()) + if err == nil { + logger.Printf(infoFormat, color.Green.Sprint(strings.Join(rapaping.TransformIPArray(ips), ", ")), color.Green.Sprint(ipInfo.Hostname), color.Green.Sprint(ipInfo.City), color.Green.Sprint(ipInfo.Region), color.Green.Sprint(ipInfo.Country), color.Green.Sprint(ipInfo.Org)) + } + } + + info := &rapaping.Info{ + Host: host, + Port: port, + } + + rapaping.Run(info) +} diff --git a/rapaping/logging.go b/rapaping/logging.go new file mode 100644 index 0000000..7f1462a --- /dev/null +++ b/rapaping/logging.go @@ -0,0 +1,22 @@ +package rapaping + +import ( + "log" + "os" + + "github.com/gookit/color" +) + +var logger = log.New(os.Stdout, "", 0) + +func printReport(stats *ConnectionStats) { + success := float64(stats.Connected) / float64(stats.Attempted) * 100 + logger.Printf("\nConnection statistics:\n") + logger.Printf(" Attempted = "+color.Cyan.Sprint("%d")+", Connected = "+color.Green.Sprint("%d")+", Failed = "+color.Red.Sprint("%d")+" ("+color.Red.Sprint("%.2f%%")+")\n", stats.Attempted, stats.Connected, stats.Failed, success) + logger.Printf("Approximate connection times:\n") + + if stats.Connected > 0 { + averageTime := float64(stats.TotalTime.Milliseconds()) / float64(stats.Connected) + logger.Printf(" Minimum = " + colorPing(float64(stats.MinTime.Milliseconds())) + ", Maximum = " + colorPing(float64(stats.MaxTime.Milliseconds())) + ", Average = " + colorPing(averageTime) + "\n\n") + } +} diff --git a/rapaping/ping.go b/rapaping/ping.go new file mode 100644 index 0000000..ef06406 --- /dev/null +++ b/rapaping/ping.go @@ -0,0 +1,81 @@ +package rapaping + +import ( + "fmt" + "math/rand" + "net" + "os" + "os/signal" + "syscall" + "time" + + "github.com/gookit/color" +) + +// var dialer proxy.Dialer + +func Run(info *Info) { + stats := &ConnectionStats{} + + // Interrupt + c := make(chan os.Signal, 1) + signal.Notify(c, os.Interrupt, syscall.SIGTERM) + go func() { + <-c + printReport(stats) + os.Exit(0) + }() + + // Proxy Dialer + // d, err := proxy.SOCKS5("tcp", info.Proxy, nil, &net.Dialer{Timeout: 5 * time.Second}) + // if err != nil { + // color.Error.Printf("proxy dead mazafaka kurwa: %v", err) + // } + // dialer = d + + // Ping Loop + for { + ping(info.Host, info.Port, stats) + time.Sleep(time.Millisecond * 1000) + } +} + +func ping(host string, port int, stats *ConnectionStats) { + // Resolve and roll DNS + ips, err := net.LookupIP(host) + if err != nil { + color.Error.Printf("Failed to resolve DNS for %s: %v\n", host, err) + stats.Failed++ + return + } + + rand.Seed(time.Now().UnixNano()) + ip := ips[rand.Intn(len(ips))] + + // Timer + startTime := time.Now() // Start timer + // conn, err := dialer.Dial("tcp", fmt.Sprintf("%s:%d", host, port)) + conn, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", ip, port), 5*time.Second) + if err != nil { + color.Error.Println("Connection timed out") + stats.Failed++ + return + } + defer conn.Close() + duration := time.Since(startTime) // Stop timer + + logger.Printf("Connected to "+color.Green.Sprint("%s")+": time="+colorPing(float64(duration.Milliseconds()))+" protocol="+color.Green.Sprint("TCP")+" port="+color.Green.Sprint("%d")+"\n", ip, port) + //logger.Printf("Connected to "+color.Green.Sprint("%s")+": time="+color.Green.Sprint("%.2fms")+ "\n", ip, float64(duration.Milliseconds())) + + // Stats + stats.Connected++ + stats.TotalTime += duration + + if stats.MinTime == 0 || duration < stats.MinTime { + stats.MinTime = duration + } + if duration > stats.MaxTime { + stats.MaxTime = duration + } + stats.Attempted++ +} diff --git a/rapaping/types.go b/rapaping/types.go new file mode 100644 index 0000000..512dbb0 --- /dev/null +++ b/rapaping/types.go @@ -0,0 +1,26 @@ +package rapaping + +import "time" + +type ConnectionStats struct { + Attempted int + Connected int + Failed int + MinTime time.Duration + MaxTime time.Duration + TotalTime time.Duration +} + +type Info struct { + Host string + Port int +} + +type IPInfo struct { + IP string `json:"ip"` + Hostname string `json:"hostname"` + City string `json:"city"` + Region string `json:"region"` + Country string `json:"country"` + Org string `json:"org"` +} diff --git a/rapaping/util.go b/rapaping/util.go new file mode 100644 index 0000000..fe0c8fe --- /dev/null +++ b/rapaping/util.go @@ -0,0 +1,55 @@ +package rapaping + +import ( + "encoding/json" + "fmt" + "net" + "net/http" + + "github.com/gookit/color" +) + +func colorPing(ping float64) string { + var colorFunc func(a ...any) string + + switch { + case ping < 200: + colorFunc = color.Green.Sprint + case ping < 400: + colorFunc = color.Yellow.Sprint + case ping < 1000: + colorFunc = color.Red.Sprint + default: + colorFunc = color.BgRed.Sprint + } + + return colorFunc(fmt.Sprintf("%.2fms", ping)) +} + +func TransformIPArray(ipArray []net.IP) []string { + s := make([]string,0) + for _, ip := range ipArray { + s = append(s, ip.String()) + } + return s +} + +func GetIPInfo(ip string) (*IPInfo, error) { + resp, err := http.Get(fmt.Sprintf("http://ipinfo.io/%s/json", ip)) + if err != nil { + return nil, err + } + defer resp.Body.Close() + + var ipInfo IPInfo + err = json.NewDecoder(resp.Body).Decode(&ipInfo) + if err != nil { + return nil, err + } + + return &ipInfo, nil +} + +func IsValidPort(port int) bool { + return port > 0 && port < 65536 +} \ No newline at end of file