From c63fee7d061bd762dd73c1fed206d5dcef2f5d2d Mon Sep 17 00:00:00 2001 From: sjlleo Date: Fri, 13 May 2022 14:28:58 +0800 Subject: [PATCH] =?UTF-8?q?Add:=20=E6=B7=BB=E5=8A=A0Table=E6=98=BE?= =?UTF-8?q?=E7=A4=BA=E6=A8=A1=E5=9D=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 7 +++ go.sum | 14 +++++ main.go | 17 +++++- util/printer/tableprinter.go | 107 +++++++++++++++++++++++++++++++++++ 4 files changed, 143 insertions(+), 2 deletions(-) create mode 100644 util/printer/tableprinter.go diff --git a/go.mod b/go.mod index a6f3942..bb6ad29 100644 --- a/go.mod +++ b/go.mod @@ -7,9 +7,16 @@ require ( golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 ) +require ( + github.com/mattn/go-colorable v0.1.9 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect +) + require ( github.com/davecgh/go-spew v1.1.0 // indirect + github.com/fatih/color v1.13.0 github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/rodaine/table v1.0.1 // indirect github.com/stretchr/testify v1.7.1 // indirect github.com/tidwall/gjson v1.14.1 // indirect github.com/tidwall/match v1.1.1 // indirect diff --git a/go.sum b/go.sum index 660d001..9953039 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,21 @@ github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= +github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8= github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo= +github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U= +github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rodaine/table v1.0.1 h1:U/VwCnUxlVYxw8+NJiLIuCxA/xa6jL38MY3FYysVWWQ= +github.com/rodaine/table v1.0.1/go.mod h1:UVEtfBsflpeEcD56nF4F5AocNFta0ZuolpSVdPtlmP4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY= github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/tidwall/gjson v1.14.1 h1:iymTbGkQBhveq21bEvAQ81I0LEBork8BFe1CUZXdyuo= @@ -24,6 +35,9 @@ golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e h1:fLOSk5Q00efkSvAm+4xcoXD+RRmLmmulPn5I3Y9F2EM= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 h1:nonptSpoQ4vQjyraW20DXPAglgQfVnM9ZC6MmNLMR60= diff --git a/main.go b/main.go index 6a379b5..095068c 100644 --- a/main.go +++ b/main.go @@ -19,6 +19,7 @@ var numMeasurements = flag.Int("q", 3, "Set the number of probes per each hop.") var parallelRequests = flag.Int("r", 18, "Set ParallelRequests number. It should be 1 when there is a multi-routing.") var maxHops = flag.Int("m", 30, "Set the max number of hops (max TTL to be reached).") var dataOrigin = flag.String("d", "LeoMoeAPI", "Choose IP Geograph Data Provider [LeoMoeAPI, IP.SB, IPInfo, IPInsight]") +var displayMode = flag.String("displayMode", "table", "Choose The Display Mode [table, Besttrace]") func main() { printer.PrintCopyRight() @@ -39,7 +40,13 @@ func main() { if err != nil { fmt.Println("请赋予 sudo (root) 权限运行本程序") } else { - printer.TraceroutePrinter(ip, *res, *dataOrigin) + if *displayMode == "Besttrace" { + printer.TraceroutePrinter(ip, *res, *dataOrigin) + } else if *displayMode == "table" { + printer.TracerouteTablePrinter(ip, *res, *dataOrigin) + } else { + printer.TracerouteTablePrinter(ip, *res, *dataOrigin) + } } } else { @@ -58,7 +65,13 @@ func main() { if err != nil { fmt.Println("请赋予 sudo (root) 权限运行本程序") } else { - printer.TraceroutePrinter(ip, *res, *dataOrigin) + if *displayMode == "Besttrace" { + printer.TraceroutePrinter(ip, *res, *dataOrigin) + } else if *displayMode == "table" { + printer.TracerouteTablePrinter(ip, *res, *dataOrigin) + } else { + printer.TracerouteTablePrinter(ip, *res, *dataOrigin) + } } } } diff --git a/util/printer/tableprinter.go b/util/printer/tableprinter.go new file mode 100644 index 0000000..7906600 --- /dev/null +++ b/util/printer/tableprinter.go @@ -0,0 +1,107 @@ +package printer + +import ( + "fmt" + "net" + + "github.com/fatih/color" + "github.com/rodaine/table" + "github.com/xgadget-lab/nexttrace/ipgeo" + "github.com/xgadget-lab/nexttrace/methods" +) + +type rowData struct { + Hop int64 + IP string + Latency string + Asnumber string + Country string + Prov string + City string + District string + Owner string +} + +func TracerouteTablePrinter(ip net.IP, res map[uint16][]methods.TracerouteHop, dataOrigin string) { + // 初始化表格 + tbl := New() + for hi := uint16(1); hi < 30; hi++ { + for _, v := range res[hi] { + data := tableDataGenerator(v) + tbl.AddRow(data.Hop, data.IP, data.Latency, data.Asnumber, data.Country, data.Prov, data.City, data.Owner) + if v.Address != nil && ip.String() == v.Address.String() { + hi = 31 + } + } + } + // 打印表格 + tbl.Print() +} + +func New() table.Table { + // 初始化表格 + headerFmt := color.New(color.FgGreen, color.Underline).SprintfFunc() + columnFmt := color.New(color.FgYellow).SprintfFunc() + + tbl := table.New("Hop", "IP", "Lantency", "ASN", "Country", "Province", "City", "Owner") + tbl.WithHeaderFormatter(headerFmt).WithFirstColumnFormatter(columnFmt) + return tbl +} + +func tableDataGenerator(v2 methods.TracerouteHop) *rowData { + if v2.Address == nil { + return &rowData{} + } else { + // 初始化变量 + var iPGeoData *ipgeo.IPGeoData + var err error + var lantency, IP string + + ipStr := v2.Address.String() + + // TODO: 判断 err 返回,并且在CLI终端提示错误 + if dataOrigin == "LeoMoeAPI" { + iPGeoData, err = ipgeo.LeoIP(ipStr) + } else if dataOrigin == "IP.SB" { + iPGeoData, err = ipgeo.IPSB(ipStr) + } else if dataOrigin == "IPInfo" { + iPGeoData, err = ipgeo.IPInfo(ipStr) + } else if dataOrigin == "IPInsight" { + iPGeoData, err = ipgeo.IPInSight(ipStr) + } else { + iPGeoData, err = ipgeo.LeoIP(ipStr) + } + + if err != nil { + fmt.Print("Error: ", err) + return &rowData{} + } else { + + ptr, err := net.LookupAddr(ipStr) + + lantency = fmt.Sprintf("%.2fms", v2.RTT.Seconds()*1000) + + if err != nil { + IP = fmt.Sprint(ipStr) + } else { + IP = fmt.Sprint(ptr[0], " (", ipStr, ") ") + } + + if iPGeoData.Owner == "" { + iPGeoData.Owner = iPGeoData.Isp + } + + return &rowData{ + Hop: int64(v2.TTL), + IP: IP, + Latency: lantency, + Asnumber: iPGeoData.Asnumber, + Country: iPGeoData.Country, + Prov: iPGeoData.Prov, + City: iPGeoData.City, + District: iPGeoData.District, + Owner: iPGeoData.Owner, + } + } + } +}