Initial Commit

This commit is contained in:
Spedoske 2020-07-05 13:19:53 +08:00 committed by GitHub
commit c4560cbacf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 224 additions and 0 deletions

39
IPRangeLoader.go Normal file
View File

@ -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
}

5
go.mod Normal file
View File

@ -0,0 +1,5 @@
module CloudflareIPScanner
go 1.14
require github.com/cheggaaa/pb/v3 v3.0.4

14
ip.txt Normal file
View File

@ -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

79
main.go Normal file
View File

@ -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)
}

87
tcping.go Normal file
View File

@ -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
}