mirror of
https://github.com/nxtrace/NTrace-core.git
synced 2025-08-12 06:26:39 +00:00
Compare commits
11 Commits
v0.1.0a
...
v0.1.0-alp
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6792bafb02 | ||
|
|
70305caa1c | ||
|
|
671ad82780 | ||
|
|
e62575beba | ||
|
|
d92a1e10d3 | ||
|
|
971d68f93f | ||
|
|
f765dbafae | ||
|
|
ea7feab2f9 | ||
|
|
e941eaa167 | ||
|
|
46e32d697d | ||
|
|
97578e40f7 |
7
.github/workflows/build.yml
vendored
7
.github/workflows/build.yml
vendored
@@ -1,10 +1,11 @@
|
||||
on:
|
||||
push: # 每次 push 的时候触发
|
||||
push: # 每次带有 tag 的 push 候触发
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
name: Build Release
|
||||
jobs:
|
||||
release:
|
||||
if: startsWith(github.ref, 'refs/tags/') # 只有这次 Commit 是 创建 Tag 时,才进行后续发布操作
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master # checkout 代码
|
||||
@@ -24,4 +25,4 @@ jobs:
|
||||
dist/nexttrace_linux_amd64
|
||||
dist/nexttrace_linux_arm64
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GITHUB_TOKEN: ${{ secrets.GH_TOKEN }}
|
||||
|
||||
6
go.mod
6
go.mod
@@ -16,9 +16,9 @@ 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/rodaine/table v1.0.1
|
||||
github.com/stretchr/testify v1.7.1
|
||||
github.com/tidwall/gjson v1.14.1
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 // indirect
|
||||
|
||||
4
go.sum
4
go.sum
@@ -9,6 +9,7 @@ github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope
|
||||
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 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
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=
|
||||
@@ -38,13 +39,12 @@ golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
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=
|
||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
33
main.go
33
main.go
@@ -19,7 +19,8 @@ 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]")
|
||||
var displayMode = flag.String("displayMode", "table", "Choose The Display Mode [table, classic]")
|
||||
var rdnsenable = flag.Bool("rdns", false, "Set whether rDNS will be display")
|
||||
|
||||
func main() {
|
||||
printer.PrintCopyRight()
|
||||
@@ -40,13 +41,13 @@ func main() {
|
||||
if err != nil {
|
||||
fmt.Println("请赋予 sudo (root) 权限运行本程序")
|
||||
} else {
|
||||
if *displayMode == "Besttrace" {
|
||||
printer.TraceroutePrinter(ip, *res, *dataOrigin)
|
||||
} else if *displayMode == "table" {
|
||||
printer.TracerouteTablePrinter(ip, *res, *dataOrigin)
|
||||
} else {
|
||||
printer.TracerouteTablePrinter(ip, *res, *dataOrigin)
|
||||
}
|
||||
util.Printer(&util.PrinterConfig{
|
||||
IP: ip,
|
||||
DisplayMode: *displayMode,
|
||||
DataOrigin: *dataOrigin,
|
||||
Rdnsenable: *rdnsenable,
|
||||
Results: *res,
|
||||
})
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -65,13 +66,13 @@ func main() {
|
||||
if err != nil {
|
||||
fmt.Println("请赋予 sudo (root) 权限运行本程序")
|
||||
} else {
|
||||
if *displayMode == "Besttrace" {
|
||||
printer.TraceroutePrinter(ip, *res, *dataOrigin)
|
||||
} else if *displayMode == "table" {
|
||||
printer.TracerouteTablePrinter(ip, *res, *dataOrigin)
|
||||
} else {
|
||||
printer.TracerouteTablePrinter(ip, *res, *dataOrigin)
|
||||
}
|
||||
util.Printer(&util.PrinterConfig{
|
||||
IP: ip,
|
||||
DisplayMode: *displayMode,
|
||||
DataOrigin: *dataOrigin,
|
||||
Rdnsenable: *rdnsenable,
|
||||
Results: *res,
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -80,7 +81,7 @@ func flagApply() string {
|
||||
flag.Parse()
|
||||
ipArg := flag.Args()
|
||||
if flag.NArg() != 1 {
|
||||
fmt.Println("Args Error\nUsage : ./bettertrace [-T] [-d <dataOrigin> ] [ -m <hops> ] [ -p <port> ] [ -q <probes> ] [ -r <parallelrequests> ] <hostname>")
|
||||
fmt.Println("Args Error\nUsage : ./nexttrace [-T] [-rdns] [-displayMode <displayMode>] [-d <dataOrigin> ] [ -m <hops> ] [ -p <port> ] [ -q <probes> ] [ -r <parallelrequests> ] <hostname>")
|
||||
os.Exit(2)
|
||||
}
|
||||
return ipArg[0]
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
package util
|
||||
|
||||
import (
|
||||
"net"
|
||||
|
||||
"github.com/xgadget-lab/nexttrace/methods"
|
||||
"github.com/xgadget-lab/nexttrace/util/printer"
|
||||
)
|
||||
|
||||
type IPGeoData struct {
|
||||
Asnumber string `json:"asnumber"`
|
||||
Country string `json:"country"`
|
||||
@@ -9,3 +16,24 @@ type IPGeoData struct {
|
||||
Owner string `json:"owner"`
|
||||
Isp string `json:"isp"`
|
||||
}
|
||||
|
||||
type PrinterConfig struct {
|
||||
IP net.IP
|
||||
DataOrigin string
|
||||
DisplayMode string
|
||||
Rdnsenable bool
|
||||
Results map[uint16][]methods.TracerouteHop
|
||||
}
|
||||
|
||||
func Printer(config *PrinterConfig) {
|
||||
switch config.DisplayMode {
|
||||
case "table":
|
||||
printer.TracerouteTablePrinter(config.IP, config.Results, config.DataOrigin, config.Rdnsenable)
|
||||
case "classic":
|
||||
printer.TraceroutePrinter(config.IP, config.Results, config.DataOrigin, config.Rdnsenable)
|
||||
case "json":
|
||||
//TracerouteJSONPrinter(config.Results, config.DataOrigin)
|
||||
default:
|
||||
printer.TraceroutePrinter(config.IP, config.Results, config.DataOrigin, config.Rdnsenable)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import (
|
||||
)
|
||||
|
||||
func PrintCopyRight() {
|
||||
fmt.Println("NextTrace v0.1.0 Alpha \nxgadget-lab 实验室 zhsh (xzhsh.ch) & leo (leo.moe)")
|
||||
fmt.Println("NextTrace v0.1.0 Alpha \nxgadget-lab zhshch (xzhsh.ch) & leo (leo.moe)")
|
||||
}
|
||||
|
||||
func PrintTraceRouteNav(ip net.IP, domain string, dataOrigin string) {
|
||||
|
||||
@@ -11,11 +11,11 @@ import (
|
||||
|
||||
var dataOrigin string
|
||||
|
||||
func TraceroutePrinter(ip net.IP, res map[uint16][]methods.TracerouteHop, dataOrigin string) {
|
||||
func TraceroutePrinter(ip net.IP, res map[uint16][]methods.TracerouteHop, dataOrigin string, rdnsenable bool) {
|
||||
for hi := uint16(1); hi < 30; hi++ {
|
||||
fmt.Print(hi)
|
||||
for _, v := range res[hi] {
|
||||
hopPrinter(v)
|
||||
hopPrinter(v, rdnsenable)
|
||||
if v.Address != nil && ip.String() == v.Address.String() {
|
||||
hi = 31
|
||||
}
|
||||
@@ -23,7 +23,7 @@ func TraceroutePrinter(ip net.IP, res map[uint16][]methods.TracerouteHop, dataOr
|
||||
}
|
||||
}
|
||||
|
||||
func hopPrinter(v2 methods.TracerouteHop) {
|
||||
func hopPrinter(v2 methods.TracerouteHop, rdnsenable bool) {
|
||||
if v2.Address == nil {
|
||||
fmt.Println("\t*")
|
||||
} else {
|
||||
@@ -32,16 +32,17 @@ func hopPrinter(v2 methods.TracerouteHop) {
|
||||
|
||||
ipStr := v2.Address.String()
|
||||
|
||||
// TODO: 判断 err 返回,并且在CLI终端提示错误
|
||||
if dataOrigin == "LeoMoeAPI" {
|
||||
// 判断 err 返回,并且在CLI终端提示错误
|
||||
switch dataOrigin {
|
||||
case "LeoMoeAPI":
|
||||
iPGeoData, err = ipgeo.LeoIP(ipStr)
|
||||
} else if dataOrigin == "IP.SB" {
|
||||
case "IP.SB":
|
||||
iPGeoData, err = ipgeo.IPSB(ipStr)
|
||||
} else if dataOrigin == "IPInfo" {
|
||||
case "IPInfo":
|
||||
iPGeoData, err = ipgeo.IPInfo(ipStr)
|
||||
} else if dataOrigin == "IPInsight" {
|
||||
case "IPInsight":
|
||||
iPGeoData, err = ipgeo.IPInSight(ipStr)
|
||||
} else {
|
||||
default:
|
||||
iPGeoData, err = ipgeo.LeoIP(ipStr)
|
||||
}
|
||||
|
||||
@@ -52,14 +53,19 @@ func hopPrinter(v2 methods.TracerouteHop) {
|
||||
geo = formatIpGeoData(ipStr, iPGeoData)
|
||||
}
|
||||
|
||||
ptr, err := net.LookupAddr(ipStr)
|
||||
|
||||
txt := "\t"
|
||||
if err != nil {
|
||||
txt += fmt.Sprint(ipStr, " ", fmt.Sprintf("%.2f", v2.RTT.Seconds()*1000), "ms ", geo)
|
||||
|
||||
if rdnsenable {
|
||||
ptr, err := net.LookupAddr(ipStr)
|
||||
if err != nil {
|
||||
txt += fmt.Sprint(ipStr, " ", fmt.Sprintf("%.2f", v2.RTT.Seconds()*1000), "ms ", geo)
|
||||
} else {
|
||||
txt += fmt.Sprint(ptr[0], " (", ipStr, ") ", fmt.Sprintf("%.2f", v2.RTT.Seconds()*1000), "ms ", geo)
|
||||
}
|
||||
} else {
|
||||
txt += fmt.Sprint(ptr[0], " (", ipStr, ") ", fmt.Sprintf("%.2f", v2.RTT.Seconds()*1000), "ms ", geo)
|
||||
txt += fmt.Sprint(ipStr, " ", fmt.Sprintf("%.2f", v2.RTT.Seconds()*1000), "ms ", geo)
|
||||
}
|
||||
|
||||
fmt.Println(txt)
|
||||
}
|
||||
}
|
||||
@@ -74,9 +80,9 @@ func formatIpGeoData(ip string, data *ipgeo.IPGeoData) string {
|
||||
}
|
||||
|
||||
// TODO: 判断阿里云和腾讯云内网,数据不足,有待进一步完善
|
||||
if strings.HasPrefix(ip, "9.31.") || strings.HasPrefix(ip, "11.72.") {
|
||||
if strings.HasPrefix(ip, "9.") {
|
||||
res = append(res, "局域网", "腾讯云")
|
||||
} else if strings.HasPrefix(ip, "11.13.") {
|
||||
} else if strings.HasPrefix(ip, "11.") {
|
||||
res = append(res, "局域网", "阿里云")
|
||||
} else if data.Country == "" {
|
||||
res = append(res, "局域网")
|
||||
|
||||
@@ -3,6 +3,7 @@ package printer
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/rodaine/table"
|
||||
@@ -22,12 +23,12 @@ type rowData struct {
|
||||
Owner string
|
||||
}
|
||||
|
||||
func TracerouteTablePrinter(ip net.IP, res map[uint16][]methods.TracerouteHop, dataOrigin string) {
|
||||
func TracerouteTablePrinter(ip net.IP, res map[uint16][]methods.TracerouteHop, dataOrigin string, rdnsenable bool) {
|
||||
// 初始化表格
|
||||
tbl := New()
|
||||
for hi := uint16(1); hi < 30; hi++ {
|
||||
for _, v := range res[hi] {
|
||||
data := tableDataGenerator(v)
|
||||
data := tableDataGenerator(v, rdnsenable)
|
||||
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
|
||||
@@ -48,7 +49,7 @@ func New() table.Table {
|
||||
return tbl
|
||||
}
|
||||
|
||||
func tableDataGenerator(v2 methods.TracerouteHop) *rowData {
|
||||
func tableDataGenerator(v2 methods.TracerouteHop, rdnsenable bool) *rowData {
|
||||
if v2.Address == nil {
|
||||
return &rowData{
|
||||
Hop: int64(v2.TTL),
|
||||
@@ -62,29 +63,51 @@ func tableDataGenerator(v2 methods.TracerouteHop) *rowData {
|
||||
|
||||
ipStr := v2.Address.String()
|
||||
|
||||
if strings.HasPrefix(ipStr, "9.") {
|
||||
return &rowData{
|
||||
Hop: int64(v2.TTL),
|
||||
IP: ipStr,
|
||||
Latency: lantency,
|
||||
Country: "局域网",
|
||||
Owner: "腾讯云",
|
||||
}
|
||||
} else if strings.HasPrefix(ipStr, "11.") {
|
||||
return &rowData{
|
||||
Hop: int64(v2.TTL),
|
||||
IP: ipStr,
|
||||
Latency: lantency,
|
||||
Country: "局域网",
|
||||
Owner: "阿里云",
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: 判断 err 返回,并且在CLI终端提示错误
|
||||
if dataOrigin == "LeoMoeAPI" {
|
||||
switch dataOrigin {
|
||||
case "LeoMoeAPI":
|
||||
iPGeoData, err = ipgeo.LeoIP(ipStr)
|
||||
} else if dataOrigin == "IP.SB" {
|
||||
case "IP.SB":
|
||||
iPGeoData, err = ipgeo.IPSB(ipStr)
|
||||
} else if dataOrigin == "IPInfo" {
|
||||
case "IPInfo":
|
||||
iPGeoData, err = ipgeo.IPInfo(ipStr)
|
||||
} else if dataOrigin == "IPInsight" {
|
||||
case "IPInsight":
|
||||
iPGeoData, err = ipgeo.IPInSight(ipStr)
|
||||
} else {
|
||||
default:
|
||||
iPGeoData, err = ipgeo.LeoIP(ipStr)
|
||||
}
|
||||
|
||||
ptr, err_LookupAddr := net.LookupAddr(ipStr)
|
||||
if rdnsenable {
|
||||
ptr, err_LookupAddr := net.LookupAddr(ipStr)
|
||||
if err_LookupAddr != nil {
|
||||
IP = fmt.Sprint(ipStr)
|
||||
} else {
|
||||
IP = fmt.Sprint(ptr[0], " (", ipStr, ") ")
|
||||
}
|
||||
} else {
|
||||
IP = fmt.Sprint(ipStr)
|
||||
}
|
||||
|
||||
lantency = fmt.Sprintf("%.2fms", v2.RTT.Seconds()*1000)
|
||||
|
||||
if err_LookupAddr != nil {
|
||||
IP = fmt.Sprint(ipStr)
|
||||
} else {
|
||||
IP = fmt.Sprint(ptr[0], " (", ipStr, ") ")
|
||||
}
|
||||
|
||||
if iPGeoData.Owner == "" {
|
||||
iPGeoData.Owner = iPGeoData.Isp
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user