commit c4560cbacf550a1daad7f0395f420d0e49e3f54a Author: Spedoske <52339623+Spedoske@users.noreply.github.com> Date: Sun Jul 5 13:19:53 2020 +0800 Initial Commit diff --git a/IPRangeLoader.go b/IPRangeLoader.go new file mode 100644 index 0000000..1a66031 --- /dev/null +++ b/IPRangeLoader.go @@ -0,0 +1,39 @@ +package main + +import ( + "bufio" + "log" + "net" + "os" +) + +func loadFirstIPOfRangeFromFile() []net.IPAddr { + file, err := os.Open("ip.txt") + if err != nil { + log.Fatal(err) + } + firstIPs := make([]net.IPAddr, 0) + scanner := bufio.NewScanner(file) + scanner.Split(bufio.ScanLines) + for scanner.Scan() { + IPString := scanner.Text() + firstIP, IPRange, err := net.ParseCIDR(IPString) + if err != nil { + log.Fatal(err) + } + firstIP[15]=ipEndWith + for IPRange.Contains(firstIP) { + firstIPCopy := make([]byte, len(firstIP)) + copy(firstIPCopy, firstIP) + firstIPs = append(firstIPs, net.IPAddr{IP: firstIPCopy}) + firstIP[14]++ + if firstIP[14] == 0 { + firstIP[13]++ + if firstIP[13] == 0 { + firstIP[12]++ + } + } + } + } + return firstIPs +} diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..c16100f --- /dev/null +++ b/go.mod @@ -0,0 +1,5 @@ +module CloudflareIPScanner + +go 1.14 + +require github.com/cheggaaa/pb/v3 v3.0.4 diff --git a/ip.txt b/ip.txt new file mode 100644 index 0000000..ce04079 --- /dev/null +++ b/ip.txt @@ -0,0 +1,14 @@ +173.245.48.0/20 +103.21.244.0/22 +103.22.200.0/22 +103.31.4.0/22 +141.101.64.0/18 +108.162.192.0/18 +190.93.240.0/20 +188.114.96.0/20 +197.234.240.0/22 +198.41.128.0/17 +162.158.0.0/15 +104.16.0.0/12 +172.64.0.0/13 +131.0.72.0/22 \ No newline at end of file diff --git a/main.go b/main.go new file mode 100644 index 0000000..57d8f24 --- /dev/null +++ b/main.go @@ -0,0 +1,79 @@ +package main + +import ( + "encoding/csv" + "fmt" + "github.com/cheggaaa/pb/v3" + "log" + "os" + "sync" +) + +func ExportCsv(filePath string, data [][]string) { + fp, err := os.Create(filePath) + if err != nil { + log.Fatalf("创建文件["+filePath+"]句柄失败,%v", err) + return + } + defer fp.Close() + w := csv.NewWriter(fp) //创建一个新的写入文件流 + w.WriteAll(data) + w.Flush() +} + +var pingTime int +var pingRoutine int +const ipEndWith uint8 = 1 +type progressEvent int +const ( + NoAvailableIPFound progressEvent = iota + AvailableIPFound + NormalPing +) + +func handleProgressGenerator(pb *pb.ProgressBar)func (e progressEvent){ + return func(e progressEvent) { + switch e { + case NoAvailableIPFound: + pb.Add(pingTime) + case AvailableIPFound: + pb.Add(failTime) + case NormalPing: + pb.Increment() + } + } +} + +func handleUserInput(){ + fmt.Println("请输入扫描协程数(数字越大越快,默认100):") + fmt.Scanln(&pingRoutine) + if pingRoutine<=0{ + pingRoutine=100 + } + fmt.Println("请输入tcping次数(默认10):") + fmt.Scanln(&pingTime) + if pingTime<=0{ + pingTime=10 + } +} + +func main(){ + handleUserInput() + ips:=loadFirstIPOfRangeFromFile() + pingCount:=len(ips)*pingTime + bar := pb.StartNew(pingCount) + var wg sync.WaitGroup + var mu sync.Mutex + var data = make([][]string,0) + data = append(data,[]string{"IP Address","Ping received","Ping time"}) + control := make(chan bool,pingRoutine) + for _,ip :=range ips{ + wg.Add(1) + control<-false + handleProgress:=handleProgressGenerator(bar) + go tcpingGoroutine(&wg,&mu,ip,pingTime, &data,control,handleProgress) + } + wg.Wait() + bar.Finish() + ExportCsv("./result.csv",data) +} diff --git a/tcping.go b/tcping.go new file mode 100644 index 0000000..35eb44b --- /dev/null +++ b/tcping.go @@ -0,0 +1,87 @@ +package main + +import ( + "net" + "strconv" + "sync" + "time" +) + +const defaultTcpPort = 443 +const tcpConnectTimeout = time.Second * 1 +const failTime = 4 + +//bool connectionSucceed float64 time +func tcping(ip net.IPAddr) (bool, float64) { + startTime := time.Now() + conn, err := net.DialTimeout("tcp", ip.String()+":"+strconv.Itoa(defaultTcpPort), tcpConnectTimeout) + if err != nil { + return false, 0 + } else { + var endTime = time.Since(startTime) + var duration = float64(endTime.Microseconds()) / 1000.0 + _ = conn.Close() + return true, duration + } +} + +//pingReceived pingTotalTime +func checkConnection(ip net.IPAddr) (int, float64) { + pingRecv := 0 + pingTime := 0.0 + for i := 1; i <= failTime; i++ { + pingSucceed, pingTimeCurrent := tcping(ip) + if pingSucceed { + pingRecv++ + pingTime += pingTimeCurrent + } + } + return pingRecv, pingTime +} + +//return Success packetRecv averagePingTime specificIPAddr +func tcpingHandler(ip net.IPAddr, pingCount int, progressHandler func(e progressEvent)) (bool, int, float64, net.IPAddr) { + ipCanConnect := false + pingRecv := 0 + pingTime := 0.0 + for !ipCanConnect { + pingRecvCurrent, pingTimeCurrent := checkConnection(ip) + if pingRecvCurrent != 0 { + ipCanConnect = true + pingRecv = pingRecvCurrent + pingTime = pingTimeCurrent + } else { + ip.IP[15]++ + if ip.IP[15] == 0 { + break + } + break + } + } + if ipCanConnect { + progressHandler(AvailableIPFound) + for i := failTime; i < pingCount; i++ { + pingSuccess, pingTimeCurrent := tcping(ip) + progressHandler(NormalPing) + if pingSuccess { + pingRecv++ + pingTime += pingTimeCurrent + } + } + return true, pingRecv, pingTime / float64(pingRecv), ip + } else { + progressHandler(NoAvailableIPFound) + return false, 0, 0, net.IPAddr{} + } +} + +func tcpingGoroutine(wg *sync.WaitGroup, mutex *sync.Mutex, ip net.IPAddr, pingCount int, csv *[][]string, control chan bool, progressHandler func(e progressEvent)) { + defer wg.Done() + success, pingRecv, pingTimeAvg, currentIP := tcpingHandler(ip, pingCount, progressHandler) + if success { + mutex.Lock() + *csv = append(*csv, []string{currentIP.String(), strconv.Itoa(pingRecv), strconv.FormatFloat(pingTimeAvg, 'f', 4, 64)}) + mutex.Unlock() + } + <-control +}