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  }