This commit is contained in:
spiritysdx
2024-06-27 13:18:42 +08:00
parent 9fb670e67f
commit d882b4d183
2 changed files with 183 additions and 65 deletions

View File

@@ -5,7 +5,6 @@ import (
"github.com/fatih/color" "github.com/fatih/color"
"github.com/nxtrace/NTrace-core/fast_trace" "github.com/nxtrace/NTrace-core/fast_trace"
"github.com/nxtrace/NTrace-core/ipgeo" "github.com/nxtrace/NTrace-core/ipgeo"
"github.com/nxtrace/NTrace-core/printer"
"github.com/nxtrace/NTrace-core/trace" "github.com/nxtrace/NTrace-core/trace"
"github.com/nxtrace/NTrace-core/util" "github.com/nxtrace/NTrace-core/util"
"github.com/nxtrace/NTrace-core/wshandle" "github.com/nxtrace/NTrace-core/wshandle"
@@ -14,14 +13,10 @@ import (
"os" "os"
"os/signal" "os/signal"
"strconv" "strconv"
"strings"
"time" "time"
) )
type FastTracer struct {
TracerouteMethod trace.Method
ParamsFastTrace ParamsFastTrace
}
type ParamsFastTrace struct { type ParamsFastTrace struct {
SrcDev string SrcDev string
SrcAddr string SrcAddr string
@@ -36,143 +31,259 @@ type ParamsFastTrace struct {
DontFragment bool DontFragment bool
} }
type IpListElement struct { var (
Ip string GuangZhouCT = fastTrace.ISPCollection{
Desc string ISPName: "广州电信",
Version4 bool // true for IPv4, false for IPv6 IP: "58.60.188.222",
} IPv6: "240e:97c:2f:3000::44",
}
GuangZhouCU = fastTrace.ISPCollection{
ISPName: "广州联通",
IP: "210.21.196.6",
IPv6: "2408:8756:f50:1001::c",
}
GuangZhouCMCC = fastTrace.ISPCollection{
ISPName: "广州移动",
IP: "120.196.165.24",
IPv6: "2409:8c54:871:1001::12",
}
ShangHaiCT = fastTrace.ISPCollection{
ISPName: "上海电信",
IP: "202.96.209.133",
IPv6: "240e:e1:aa00:4000::24",
}
ShangHaiCU = fastTrace.ISPCollection{
ISPName: "上海联通",
IP: "210.22.97.1",
IPv6: "2408:80f1:21:5003::a",
}
ShangHaiCMCC = fastTrace.ISPCollection{
ISPName: "上海移动",
IP: "211.136.112.200",
IPv6: "2409:8c1e:75b0:3003::26",
}
BeiJingCT = fastTrace.ISPCollection{
ISPName: "北京电信",
IP: "219.141.140.10",
IPv6: "2400:89c0:1053:3::69",
}
BeiJingCU = fastTrace.ISPCollection{
ISPName: "北京联通",
IP: "202.106.195.68",
IPv6: "2400:89c0:1013:3::54",
}
BeiJingCMCC = fastTrace.ISPCollection{
ISPName: "北京移动",
IP: "221.179.155.161",
IPv6: "2409:8c00:8421:1303::55",
}
ChengDuCT = fastTrace.ISPCollection{
ISPName: "成都电信",
IP: "61.139.2.69",
IPv6: "",
}
ChengDuCU = fastTrace.ISPCollection{
ISPName: "成都联通",
IP: "119.6.6.6",
IPv6: "",
}
ChengDuCMCC = fastTrace.ISPCollection{
ISPName: "成都移动",
IP: "211.137.96.205",
IPv6: "",
}
)
func realtimePrinter(res *trace.Result, ttl int) { func realtimePrinter(res *trace.Result, ttl int) {
fmt.Printf("%s ", color.New(color.FgHiYellow, color.Bold).Sprintf("%-2d", ttl+1)) //fmt.Printf("%s ", color.New(color.FgHiYellow, color.Bold).Sprintf("%-2d", ttl+1))
var latestIP string var latestIP string
tmpMap := make(map[string][]string) tmpMap := make(map[string][]string)
for i, v := range res.Hops[ttl] { for i, v := range res.Hops[ttl] {
if v.Address == nil && latestIP != "" { if v.Address == nil && latestIP != "" {
tmpMap[latestIP] = append(tmpMap[latestIP], fmt.Sprintf("%s ms", "*")) tmpMap[latestIP] = append(tmpMap[latestIP], fmt.Sprintf("%-10s", fmt.Sprintf("%.2f ms", v.RTT.Seconds()*1000)))
continue continue
} else if v.Address == nil { } else if v.Address == nil {
continue continue
} }
if _, exist := tmpMap[v.Address.String()]; !exist { if _, exist := tmpMap[v.Address.String()]; !exist {
tmpMap[v.Address.String()] = append(tmpMap[v.Address.String()], strconv.Itoa(i)) tmpMap[v.Address.String()] = append(tmpMap[v.Address.String()], strconv.Itoa(i))
if latestIP == "" { if latestIP == "" {
for j := 0; j < i; j++ { for j := 0; j < i; j++ {
tmpMap[v.Address.String()] = append(tmpMap[v.Address.String()], fmt.Sprintf("%s ms", "*")) tmpMap[v.Address.String()] = append(tmpMap[v.Address.String()], fmt.Sprintf("%-10s", fmt.Sprintf("%.2f ms", v.RTT.Seconds()*1000)))
} }
} }
latestIP = v.Address.String() latestIP = v.Address.String()
} }
tmpMap[v.Address.String()] = append(tmpMap[v.Address.String()], fmt.Sprintf("%-10s", fmt.Sprintf("%.2f ms", v.RTT.Seconds()*1000)))
tmpMap[v.Address.String()] = append(tmpMap[v.Address.String()], fmt.Sprintf("%.2f ms", v.RTT.Seconds()*1000))
} }
if latestIP == "" { if latestIP == "" {
fmt.Fprintf(color.Output, "%s\n", fmt.Fprintf(color.Output, "%s\n",
color.New(color.FgWhite, color.Bold).Sprintf("1*"), color.New(color.FgWhite, color.Bold).Sprintf("*"),
) )
return return
} }
for ip, v := range tmpMap { for ip, v := range tmpMap {
i, _ := strconv.Atoi(v[0]) i, _ := strconv.Atoi(v[0])
rtt := v[1] rtt := v[1]
// 打印RTT // 打印RTT
fmt.Fprintf(color.Output, "%s ", color.New(color.FgHiCyan, color.Bold).Sprintf("%s", rtt)) fmt.Fprintf(color.Output, fmt.Sprintf("%-24s ", color.New(color.FgHiCyan, color.Bold).Sprintf("%s", rtt)))
// 打印AS号 // 打印AS号
if res.Hops[ttl][i].Geo.Asnumber != "" { if res.Hops[ttl][i].Geo.Asnumber != "" {
fmt.Fprintf(color.Output, "%s ", color.New(color.FgHiYellow, color.Bold).Sprintf("AS%s", res.Hops[ttl][i].Geo.Asnumber)) fmt.Fprintf(color.Output, fmt.Sprintf("%-24s ", color.New(color.FgHiYellow, color.Bold).Sprintf("AS%s", res.Hops[ttl][i].Geo.Asnumber)))
} else { } else {
fmt.Fprintf(color.Output, "%s ", color.New(color.FgWhite, color.Bold).Sprintf("2*")) fmt.Fprintf(color.Output, fmt.Sprintf("%-24s ", color.New(color.FgWhite, color.Bold).Sprintf("*")))
} }
// 打印地理信息 // 打印地理信息
if net.ParseIP(ip).To4() != nil { if net.ParseIP(ip).To4() != nil {
fmt.Fprintf(color.Output, "%s, %s, %s, %s", whoisFormat := strings.Split(res.Hops[ttl][i].Geo.Whois, "-")
color.New(color.FgWhite, color.Bold).Sprintf("%s", res.Hops[ttl][i].Geo.Country), if len(whoisFormat) > 1 {
color.New(color.FgWhite, color.Bold).Sprintf("%s", res.Hops[ttl][i].Geo.Prov), whoisFormat[0] = strings.Join(whoisFormat[:2], "-")
color.New(color.FgWhite, color.Bold).Sprintf("%s", res.Hops[ttl][i].Geo.City), }
color.New(color.FgWhite, color.Bold).Sprintf("%s", res.Hops[ttl][i].Geo.Owner)) if whoisFormat[0] != "" {
} else { //如果以RFC或DOD开头那么为空
fmt.Fprintf(color.Output, "%s, %s, %s, %s", if !(strings.HasPrefix(whoisFormat[0], "RFC") ||
color.New(color.FgWhite, color.Bold).Sprintf("%s", res.Hops[ttl][i].Geo.Country), strings.HasPrefix(whoisFormat[0], "DOD")) {
color.New(color.FgWhite, color.Bold).Sprintf("%s", res.Hops[ttl][i].Geo.Prov), whoisFormat[0] = "[" + whoisFormat[0] + "]"
color.New(color.FgWhite, color.Bold).Sprintf("%s", res.Hops[ttl][i].Geo.City), } else {
color.New(color.FgWhite, color.Bold).Sprintf("%s", res.Hops[ttl][i].Geo.Owner)) whoisFormat[0] = ""
}
}
// CMIN2, CUII, CN2, CUG 改为壕金色高亮
switch {
case res.Hops[ttl][i].Geo.Asnumber == "58807":
fallthrough
case res.Hops[ttl][i].Geo.Asnumber == "10099":
fallthrough
case res.Hops[ttl][i].Geo.Asnumber == "4809":
fallthrough
case res.Hops[ttl][i].Geo.Asnumber == "9929":
fallthrough
case res.Hops[ttl][i].Geo.Asnumber == "23764":
fallthrough
case whoisFormat[0] == "[CTG-CN]":
fallthrough
case whoisFormat[0] == "[CNC-BACKBONE]":
fallthrough
case whoisFormat[0] == "[CUG-BACKBONE]":
fallthrough
case whoisFormat[0] == "[CMIN2-NET]":
fallthrough
case strings.HasPrefix(res.Hops[ttl][i].Address.String(), "59.43."):
fmt.Fprintf(color.Output, "%s", color.New(color.FgHiYellow, color.Bold).Sprintf("%-18s", whoisFormat[0]))
default:
fmt.Fprintf(color.Output, "%s", color.New(color.FgHiGreen, color.Bold).Sprintf("%-18s", whoisFormat[0]))
}
var parts []string
country := res.Hops[ttl][i].Geo.Country
prov := res.Hops[ttl][i].Geo.Prov
city := res.Hops[ttl][i].Geo.City
owner := res.Hops[ttl][i].Geo.Owner
if country != "" {
parts = append(parts, color.New(color.FgWhite, color.Bold).Sprintf("%s", country))
}
if prov != "" {
parts = append(parts, color.New(color.FgWhite, color.Bold).Sprintf("%s", prov))
}
if city != "" {
parts = append(parts, color.New(color.FgWhite, color.Bold).Sprintf("%s", city))
}
if owner != "" {
parts = append(parts, color.New(color.FgWhite, color.Bold).Sprintf("%s", owner))
}
if len(parts) > 0 {
fmt.Fprintf(color.Output, strings.Join(parts, ", "))
}
} }
fmt.Println() fmt.Println()
} }
} }
func tracert(f fastTrace.FastTracer, ispCollection fastTrace.ISPCollection) { func tracert(f fastTrace.FastTracer, ispCollection fastTrace.ISPCollection) {
fmt.Fprintf(color.Output, "%s\n", color.New(color.FgYellow, color.Bold).Sprintf("『%s』", ispCollection.ISPName))
fmt.Printf("traceroute to %s, %d hops max, %d byte packets\n", ispCollection.IP, f.ParamsFastTrace.MaxHops, f.ParamsFastTrace.PktSize) fmt.Printf("traceroute to %s, %d hops max, %d byte packets\n", ispCollection.IP, f.ParamsFastTrace.MaxHops, f.ParamsFastTrace.PktSize)
ip, err := util.DomainLookUp(ispCollection.IP, "4", "", true) ip, err := util.DomainLookUp(ispCollection.IP, "4", "", true)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
var conf = trace.Config{ var conf = trace.Config{
BeginHop: f.ParamsFastTrace.BeginHop, BeginHop: 1,
DestIP: ip, DestIP: ip,
DestPort: 80, DestPort: 80,
MaxHops: f.ParamsFastTrace.MaxHops, MaxHops: 30,
NumMeasurements: 3, NumMeasurements: 3,
ParallelRequests: 18, ParallelRequests: 18,
RDns: f.ParamsFastTrace.RDns, RDns: f.ParamsFastTrace.RDns,
AlwaysWaitRDNS: f.ParamsFastTrace.AlwaysWaitRDNS, AlwaysWaitRDNS: f.ParamsFastTrace.AlwaysWaitRDNS,
PacketInterval: 100, PacketInterval: 50,
TTLInterval: 500, TTLInterval: 50,
IPGeoSource: ipgeo.GetSource("LeoMoeAPI"), IPGeoSource: ipgeo.GetSource("LeoMoeAPI"),
Timeout: f.ParamsFastTrace.Timeout, Timeout: time.Duration(1000) * time.Millisecond,
SrcAddr: f.ParamsFastTrace.SrcAddr, SrcAddr: f.ParamsFastTrace.SrcAddr,
PktSize: f.ParamsFastTrace.PktSize, PktSize: 52,
Lang: f.ParamsFastTrace.Lang, Lang: f.ParamsFastTrace.Lang,
DontFragment: f.ParamsFastTrace.DontFragment, DontFragment: f.ParamsFastTrace.DontFragment,
} }
conf.RealtimePrinter = realtimePrinter conf.RealtimePrinter = realtimePrinter
//conf.RealtimePrinter = printer.RealtimePrinter
//conf.RealtimePrinter = tracelog.RealtimePrinter
_, err = trace.Traceroute(f.TracerouteMethod, conf) _, err = trace.Traceroute(f.TracerouteMethod, conf)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
fmt.Println()
} }
func tracert_v6(f fastTrace.FastTracer, ispCollection fastTrace.ISPCollection) { func tracert_v6(f fastTrace.FastTracer, ispCollection fastTrace.ISPCollection) {
fmt.Printf("%s『%s』%s\n", printer.YELLOW_PREFIX, ispCollection.ISPName, printer.RESET_PREFIX)
fmt.Printf("traceroute to %s, %d hops max, %d byte packets\n", ispCollection.IPv6, f.ParamsFastTrace.MaxHops, f.ParamsFastTrace.PktSize) fmt.Printf("traceroute to %s, %d hops max, %d byte packets\n", ispCollection.IPv6, f.ParamsFastTrace.MaxHops, f.ParamsFastTrace.PktSize)
ip, err := util.DomainLookUp(ispCollection.IPv6, "6", "", true) ip, err := util.DomainLookUp(ispCollection.IPv6, "6", "", true)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
var conf = trace.Config{ var conf = trace.Config{
BeginHop: f.ParamsFastTrace.BeginHop, BeginHop: 1,
DestIP: ip, DestIP: ip,
DestPort: 80, DestPort: 80,
MaxHops: f.ParamsFastTrace.MaxHops, MaxHops: 30,
NumMeasurements: 3, NumMeasurements: 3,
ParallelRequests: 18, ParallelRequests: 18,
RDns: f.ParamsFastTrace.RDns, RDns: f.ParamsFastTrace.RDns,
AlwaysWaitRDNS: f.ParamsFastTrace.AlwaysWaitRDNS, AlwaysWaitRDNS: f.ParamsFastTrace.AlwaysWaitRDNS,
PacketInterval: 100, PacketInterval: 50,
TTLInterval: 500, TTLInterval: 50,
IPGeoSource: ipgeo.GetSource("LeoMoeAPI"), IPGeoSource: ipgeo.GetSource("LeoMoeAPI"),
Timeout: f.ParamsFastTrace.Timeout, Timeout: time.Duration(1000) * time.Millisecond,
SrcAddr: f.ParamsFastTrace.SrcAddr, SrcAddr: f.ParamsFastTrace.SrcAddr,
PktSize: f.ParamsFastTrace.PktSize, PktSize: 52,
Lang: f.ParamsFastTrace.Lang, Lang: f.ParamsFastTrace.Lang,
DontFragment: f.ParamsFastTrace.DontFragment, DontFragment: f.ParamsFastTrace.DontFragment,
} }
conf.RealtimePrinter = printer.RealtimePrinter conf.RealtimePrinter = realtimePrinter
//conf.RealtimePrinter = printer.RealtimePrinter
//conf.RealtimePrinter = tracelog.RealtimePrinter
_, err = trace.Traceroute(f.TracerouteMethod, conf) _, err = trace.Traceroute(f.TracerouteMethod, conf)
if err != nil { if err != nil {
log.Fatal(err) log.Fatal(err)
} }
fmt.Println()
} }
func TraceRoute() { func TraceRoute(language, location, testType string) {
if language == "zh" || language == "" {
language = "cn"
} else if language != "en" {
fmt.Println("Invalid language.")
return
}
var TL []fastTrace.ISPCollection
if location == "GZ" {
TL = []fastTrace.ISPCollection{GuangZhouCT, GuangZhouCU, GuangZhouCMCC}
} else if location == "BJ" {
TL = []fastTrace.ISPCollection{BeiJingCT, BeiJingCU, BeiJingCMCC}
} else if location == "SH" {
TL = []fastTrace.ISPCollection{ShangHaiCT, ShangHaiCU, ShangHaiCMCC}
} else if location == "CD" {
TL = []fastTrace.ISPCollection{ChengDuCT, ChengDuCU, ChengDuCMCC}
} else {
fmt.Println("Invalid location.")
return
}
pFastTrace := fastTrace.ParamsFastTrace{ pFastTrace := fastTrace.ParamsFastTrace{
SrcDev: "", SrcDev: "",
SrcAddr: "", SrcAddr: "",
@@ -180,7 +291,7 @@ func TraceRoute() {
MaxHops: 30, MaxHops: 30,
RDns: false, RDns: false,
AlwaysWaitRDNS: false, AlwaysWaitRDNS: false,
Lang: "", Lang: language,
PktSize: 52, PktSize: 52,
} }
ft := fastTrace.FastTracer{ParamsFastTrace: pFastTrace} ft := fastTrace.FastTracer{ParamsFastTrace: pFastTrace}
@@ -191,14 +302,21 @@ func TraceRoute() {
defer func() { defer func() {
w.Conn.Close() w.Conn.Close()
}() }()
fmt.Println("ICMP v4")
ft.TracerouteMethod = trace.ICMPTrace ft.TracerouteMethod = trace.ICMPTrace
DX := fastTrace.ISPCollection{ if TL != nil {
ISPName: "广州电信", for _, T := range TL {
IP: "58.60.188.222", if testType == "both" {
IPv6: "240e:97c:2f:3000::44", fmt.Fprintf(color.Output, "%s - ", color.New(color.FgHiBlue, color.Bold).Sprintf("%s - ICMP v4", T.ISPName))
tracert(ft, T)
fmt.Fprintf(color.Output, "%s - ", color.New(color.FgHiBlue, color.Bold).Sprintf("%s - ICMP v6", T.ISPName))
tracert_v6(ft, T)
} else if testType == "ipv4" {
fmt.Fprintf(color.Output, "%s - ", color.New(color.FgHiBlue, color.Bold).Sprintf("%s - ICMP v4", T.ISPName))
tracert(ft, T)
} else if testType == "ipv6" {
fmt.Fprintf(color.Output, "%s - ", color.New(color.FgHiBlue, color.Bold).Sprintf("%s - ICMP v6", T.ISPName))
tracert_v6(ft, T)
}
}
} }
tracert(ft, DX)
//fmt.Println("ICMP v6")
//tracert_v6(ft, DX)
} }

View File

@@ -4,5 +4,5 @@ import "testing"
// https://github.com/nxtrace/NTrace-core/blob/main/fast_trace/fast_trace.go // https://github.com/nxtrace/NTrace-core/blob/main/fast_trace/fast_trace.go
func TestTraceRoute(t *testing.T) { func TestTraceRoute(t *testing.T) {
TraceRoute() TraceRoute("en", "GZ", "ipv4")
} }