github.com/nxtrace/NTrace-core@v1.3.1-0.20240513132635-39169291e8c9/printer/realtime_printer_router.go (about) 1 package printer 2 3 import ( 4 "fmt" 5 "net" 6 "strconv" 7 "strings" 8 9 "github.com/fatih/color" 10 "github.com/nxtrace/NTrace-core/trace" 11 ) 12 13 func RealtimePrinterWithRouter(res *trace.Result, ttl int) { 14 fmt.Printf("%s ", color.New(color.FgHiYellow, color.Bold).Sprintf("%-2d", ttl+1)) 15 16 // 去重 17 var latestIP string 18 tmpMap := make(map[string][]string) 19 for i, v := range res.Hops[ttl] { 20 if v.Address == nil && latestIP != "" { 21 tmpMap[latestIP] = append(tmpMap[latestIP], fmt.Sprintf("%s ms", "*")) 22 continue 23 } else if v.Address == nil { 24 continue 25 } 26 27 if _, exist := tmpMap[v.Address.String()]; !exist { 28 tmpMap[v.Address.String()] = append(tmpMap[v.Address.String()], strconv.Itoa(i)) 29 // 首次进入 30 if latestIP == "" { 31 for j := 0; j < i; j++ { 32 tmpMap[v.Address.String()] = append(tmpMap[v.Address.String()], fmt.Sprintf("%s ms", "*")) 33 } 34 } 35 latestIP = v.Address.String() 36 } 37 38 tmpMap[v.Address.String()] = append(tmpMap[v.Address.String()], fmt.Sprintf("%.2f ms", v.RTT.Seconds()*1000)) 39 } 40 41 if latestIP == "" { 42 fmt.Fprintf(color.Output, "%s\n", 43 color.New(color.FgWhite, color.Bold).Sprintf("*"), 44 ) 45 return 46 } 47 48 var blockDisplay = false 49 for ip, v := range tmpMap { 50 if blockDisplay { 51 fmt.Printf("%4s", "") 52 } 53 if net.ParseIP(ip).To4() == nil { 54 fmt.Fprintf(color.Output, "%s", 55 color.New(color.FgWhite, color.Bold).Sprintf("%-25s", ip), 56 ) 57 } else { 58 fmt.Fprintf(color.Output, "%s", 59 color.New(color.FgWhite, color.Bold).Sprintf("%-15s", ip), 60 ) 61 } 62 63 i, _ := strconv.Atoi(v[0]) 64 65 if res.Hops[ttl][i].Geo.Asnumber != "" { 66 fmt.Fprintf(color.Output, " %s", color.New(color.FgHiGreen, color.Bold).Sprintf("AS%-6s", res.Hops[ttl][i].Geo.Asnumber)) 67 } else { 68 fmt.Printf(" %-8s", "*") 69 } 70 71 if net.ParseIP(ip).To4() != nil { 72 whoisFormat := strings.Split(res.Hops[ttl][i].Geo.Whois, "-") 73 if len(whoisFormat) > 1 { 74 whoisFormat[0] = strings.Join(whoisFormat[:2], "-") 75 } 76 77 if whoisFormat[0] != "" { 78 whoisFormat[0] = "[" + whoisFormat[0] + "]" 79 } 80 fmt.Fprintf(color.Output, " %s", color.New(color.FgHiGreen, color.Bold).Sprintf("%-16s", whoisFormat[0])) 81 } 82 83 if res.Hops[ttl][i].Geo.Country == "" { 84 res.Hops[ttl][i].Geo.Country = "LAN Address" 85 } 86 87 if net.ParseIP(ip).To4() != nil { 88 89 fmt.Fprintf(color.Output, " %s %s %s %s %s\n %s ", 90 color.New(color.FgWhite, color.Bold).Sprintf("%s", res.Hops[ttl][i].Geo.Country), 91 color.New(color.FgWhite, color.Bold).Sprintf("%s", res.Hops[ttl][i].Geo.Prov), 92 color.New(color.FgWhite, color.Bold).Sprintf("%s", res.Hops[ttl][i].Geo.City), 93 color.New(color.FgWhite, color.Bold).Sprintf("%s", res.Hops[ttl][i].Geo.District), 94 fmt.Sprintf("%-6s", res.Hops[ttl][i].Geo.Owner), 95 color.New(color.FgHiBlack, color.Bold).Sprintf("%-39s", res.Hops[ttl][i].Hostname), 96 ) 97 } else { 98 fmt.Fprintf(color.Output, " %s %s %s %s %s\n %s ", 99 color.New(color.FgWhite, color.Bold).Sprintf("%s", res.Hops[ttl][i].Geo.Country), 100 color.New(color.FgWhite, color.Bold).Sprintf("%s", res.Hops[ttl][i].Geo.Prov), 101 color.New(color.FgWhite, color.Bold).Sprintf("%s", res.Hops[ttl][i].Geo.City), 102 color.New(color.FgWhite, color.Bold).Sprintf("%s", res.Hops[ttl][i].Geo.District), 103 fmt.Sprintf("%-6s", res.Hops[ttl][i].Geo.Owner), 104 color.New(color.FgHiBlack, color.Bold).Sprintf("%-32s", res.Hops[ttl][i].Hostname), 105 ) 106 } 107 108 for j := 1; j < len(v); j++ { 109 if len(v) == 2 || j == 1 { 110 fmt.Fprintf(color.Output, "%s", 111 color.New(color.FgHiCyan, color.Bold).Sprintf("%s", v[j]), 112 ) 113 } else { 114 fmt.Fprintf(color.Output, " / %s", 115 color.New(color.FgHiCyan, color.Bold).Sprintf("%s", v[j]), 116 ) 117 } 118 } 119 i = 0 120 fmt.Println() 121 if res.Hops[ttl][i].Geo != nil && !blockDisplay { 122 fmt.Fprintf(color.Output, "%s %s %s %s %s\n", 123 color.New(color.FgWhite, color.Bold).Sprintf("-"), 124 color.New(color.FgHiYellow, color.Bold).Sprintf("%s", res.Hops[ttl][i].Geo.Prefix), 125 color.New(color.FgWhite, color.Bold).Sprintf("路由表"), 126 color.New(color.FgHiCyan, color.Bold).Sprintf("Beta"), 127 color.New(color.FgWhite, color.Bold).Sprintf("-"), 128 ) 129 GetRouter(&res.Hops[ttl][i].Geo.Router, "AS"+res.Hops[ttl][i].Geo.Asnumber) 130 } 131 blockDisplay = true 132 } 133 } 134 135 func GetRouter(r *map[string][]string, node string) { 136 routeMap := *r 137 for _, v := range routeMap[node] { 138 if len(routeMap[v]) != 0 { 139 fmt.Fprintf(color.Output, " %s %s %s\n", 140 color.New(color.FgWhite, color.Bold).Sprintf("%s", routeMap[v][0]), 141 color.New(color.FgWhite, color.Bold).Sprintf("%s", v), 142 color.New(color.FgHiBlue, color.Bold).Sprintf("%s", node), 143 ) 144 } else { 145 fmt.Fprintf(color.Output, " %s %s\n", 146 color.New(color.FgWhite, color.Bold).Sprintf("%s", v), 147 color.New(color.FgHiBlue, color.Bold).Sprintf("%s", node), 148 ) 149 } 150 151 } 152 }