mirror of
https://github.com/nxtrace/NTrace-core.git
synced 2025-08-12 06:26:39 +00:00
153 lines
4.7 KiB
Go
153 lines
4.7 KiB
Go
package printer
|
|
|
|
import (
|
|
"fmt"
|
|
"net"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"github.com/fatih/color"
|
|
"github.com/nxtrace/NTrace-core/trace"
|
|
)
|
|
|
|
func RealtimePrinterWithRouter(res *trace.Result, ttl int) {
|
|
fmt.Printf("%s ", color.New(color.FgHiYellow, color.Bold).Sprintf("%-2d", ttl+1))
|
|
|
|
// 去重
|
|
var latestIP string
|
|
tmpMap := make(map[string][]string)
|
|
for i, v := range res.Hops[ttl] {
|
|
if v.Address == nil && latestIP != "" {
|
|
tmpMap[latestIP] = append(tmpMap[latestIP], fmt.Sprintf("%s ms", "*"))
|
|
continue
|
|
} else if v.Address == nil {
|
|
continue
|
|
}
|
|
|
|
if _, exist := tmpMap[v.Address.String()]; !exist {
|
|
tmpMap[v.Address.String()] = append(tmpMap[v.Address.String()], strconv.Itoa(i))
|
|
// 首次进入
|
|
if latestIP == "" {
|
|
for j := 0; j < i; j++ {
|
|
tmpMap[v.Address.String()] = append(tmpMap[v.Address.String()], fmt.Sprintf("%s ms", "*"))
|
|
}
|
|
}
|
|
latestIP = v.Address.String()
|
|
}
|
|
|
|
tmpMap[v.Address.String()] = append(tmpMap[v.Address.String()], fmt.Sprintf("%.2f ms", v.RTT.Seconds()*1000))
|
|
}
|
|
|
|
if latestIP == "" {
|
|
fmt.Fprintf(color.Output, "%s\n",
|
|
color.New(color.FgWhite, color.Bold).Sprintf("*"),
|
|
)
|
|
return
|
|
}
|
|
|
|
var blockDisplay = false
|
|
for ip, v := range tmpMap {
|
|
if blockDisplay {
|
|
fmt.Printf("%4s", "")
|
|
}
|
|
if net.ParseIP(ip).To4() == nil {
|
|
fmt.Fprintf(color.Output, "%s",
|
|
color.New(color.FgWhite, color.Bold).Sprintf("%-25s", ip),
|
|
)
|
|
} else {
|
|
fmt.Fprintf(color.Output, "%s",
|
|
color.New(color.FgWhite, color.Bold).Sprintf("%-15s", ip),
|
|
)
|
|
}
|
|
|
|
i, _ := strconv.Atoi(v[0])
|
|
|
|
if res.Hops[ttl][i].Geo.Asnumber != "" {
|
|
fmt.Fprintf(color.Output, " %s", color.New(color.FgHiGreen, color.Bold).Sprintf("AS%-6s", res.Hops[ttl][i].Geo.Asnumber))
|
|
} else {
|
|
fmt.Printf(" %-8s", "*")
|
|
}
|
|
|
|
if net.ParseIP(ip).To4() != nil {
|
|
whoisFormat := strings.Split(res.Hops[ttl][i].Geo.Whois, "-")
|
|
if len(whoisFormat) > 1 {
|
|
whoisFormat[0] = strings.Join(whoisFormat[:2], "-")
|
|
}
|
|
|
|
if whoisFormat[0] != "" {
|
|
whoisFormat[0] = "[" + whoisFormat[0] + "]"
|
|
}
|
|
fmt.Fprintf(color.Output, " %s", color.New(color.FgHiGreen, color.Bold).Sprintf("%-16s", whoisFormat[0]))
|
|
}
|
|
|
|
if res.Hops[ttl][i].Geo.Country == "" {
|
|
res.Hops[ttl][i].Geo.Country = "LAN Address"
|
|
}
|
|
|
|
if net.ParseIP(ip).To4() != nil {
|
|
|
|
fmt.Fprintf(color.Output, " %s %s %s %s %s\n %s ",
|
|
color.New(color.FgWhite, color.Bold).Sprintf("%s", res.Hops[ttl][i].Geo.Country),
|
|
color.New(color.FgWhite, color.Bold).Sprintf("%s", res.Hops[ttl][i].Geo.Prov),
|
|
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.District),
|
|
fmt.Sprintf("%-6s", res.Hops[ttl][i].Geo.Owner),
|
|
color.New(color.FgHiBlack, color.Bold).Sprintf("%-39s", res.Hops[ttl][i].Hostname),
|
|
)
|
|
} else {
|
|
fmt.Fprintf(color.Output, " %s %s %s %s %s\n %s ",
|
|
color.New(color.FgWhite, color.Bold).Sprintf("%s", res.Hops[ttl][i].Geo.Country),
|
|
color.New(color.FgWhite, color.Bold).Sprintf("%s", res.Hops[ttl][i].Geo.Prov),
|
|
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.District),
|
|
fmt.Sprintf("%-6s", res.Hops[ttl][i].Geo.Owner),
|
|
color.New(color.FgHiBlack, color.Bold).Sprintf("%-32s", res.Hops[ttl][i].Hostname),
|
|
)
|
|
}
|
|
|
|
for j := 1; j < len(v); j++ {
|
|
if len(v) == 2 || j == 1 {
|
|
fmt.Fprintf(color.Output, "%s",
|
|
color.New(color.FgHiCyan, color.Bold).Sprintf("%s", v[j]),
|
|
)
|
|
} else {
|
|
fmt.Fprintf(color.Output, " / %s",
|
|
color.New(color.FgHiCyan, color.Bold).Sprintf("%s", v[j]),
|
|
)
|
|
}
|
|
}
|
|
i = 0
|
|
fmt.Println()
|
|
if res.Hops[ttl][i].Geo != nil && !blockDisplay {
|
|
fmt.Fprintf(color.Output, "%s %s %s %s %s\n",
|
|
color.New(color.FgWhite, color.Bold).Sprintf("-"),
|
|
color.New(color.FgHiYellow, color.Bold).Sprintf("%s", res.Hops[ttl][i].Geo.Prefix),
|
|
color.New(color.FgWhite, color.Bold).Sprintf("路由表"),
|
|
color.New(color.FgHiCyan, color.Bold).Sprintf("Beta"),
|
|
color.New(color.FgWhite, color.Bold).Sprintf("-"),
|
|
)
|
|
GetRouter(&res.Hops[ttl][i].Geo.Router, "AS"+res.Hops[ttl][i].Geo.Asnumber)
|
|
}
|
|
blockDisplay = true
|
|
}
|
|
}
|
|
|
|
func GetRouter(r *map[string][]string, node string) {
|
|
routeMap := *r
|
|
for _, v := range routeMap[node] {
|
|
if len(routeMap[v]) != 0 {
|
|
fmt.Fprintf(color.Output, " %s %s %s\n",
|
|
color.New(color.FgWhite, color.Bold).Sprintf("%s", routeMap[v][0]),
|
|
color.New(color.FgWhite, color.Bold).Sprintf("%s", v),
|
|
color.New(color.FgHiBlue, color.Bold).Sprintf("%s", node),
|
|
)
|
|
} else {
|
|
fmt.Fprintf(color.Output, " %s %s\n",
|
|
color.New(color.FgWhite, color.Bold).Sprintf("%s", v),
|
|
color.New(color.FgHiBlue, color.Bold).Sprintf("%s", node),
|
|
)
|
|
}
|
|
|
|
}
|
|
}
|