Skip to content

Commit

Permalink
add: 对 Hop 的路由表展示
Browse files Browse the repository at this point in the history
  • Loading branch information
sjlleo committed Nov 18, 2022
1 parent 473ce3c commit d561063
Show file tree
Hide file tree
Showing 7 changed files with 184 additions and 9 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,8 @@ nexttrace -T -q 2 -r 1 -table -report 2001:4860:4860::8888

### IP Database

#### We use [bgp.tools](https://bgp.tools) as a data provider for routing tables.

NextTrace BackEnd is now open-source.

https://github.com/sjlleo/nexttrace-backend
Expand Down Expand Up @@ -196,6 +198,8 @@ Here is our recommended troubleshooting process:
## Credits
BGP.TOOLS provided some data support for this project and we would like to express our sincere gratitude.
[Vincent Young](https://github.com/missuo) ([email protected])
[Sam Sam](https://github.com/samleong123) ([email protected])
Expand Down
4 changes: 4 additions & 0 deletions README_zh_CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ nexttrace -T -q 2 -r 1 -table -report 2001:4860:4860::8888

### IP 数据库

我们使用[bgp.tools](https://bgp.tools)作为路由表功能的数据提供者。

✨NextTrace `LeoMoeAPI` 的后端也开源啦

[GitHub - sjlleo/nexttrace-backend: NextTrace BackEnd](https://github.com/sjlleo/nexttrace-backend)
Expand Down Expand Up @@ -186,6 +188,8 @@ https://github.com/OwO-Network/nexttrace-enhanced
## Thanks
BGP.TOOLS 提供了本项目的一些数据支持,在此表示由衷地感谢。
[Vincent Young](https://github.com/missuo) ([email protected])
[Sam Sam](https://github.com/samleong123) ([email protected])
Expand Down
2 changes: 1 addition & 1 deletion fast_trace/basic.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ var Guangzhou = BackBoneCollection{
Location: "广州",
CT163: ISPCollection{
ISPName: CT163,
IP: "106.37.67.1",
IP: "14.116.225.60",
IPv6: "240e:f9:8010::3:110:1",
},

Expand Down
21 changes: 13 additions & 8 deletions ipgeo/ipgeo.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,19 @@ import (
)

type IPGeoData struct {
Asnumber string
Country string
Prov string
City string
District string
Owner string
Isp string
Whois string
IP string `json:"ip"`
Asnumber string `json:"asnumber"`
Country string `json:"country"`
Prov string `json:"prov"`
City string `json:"city"`
District string `json:"district"`
Owner string `json:"owner"`
Isp string `json:"isp"`
Domain string `json:"domain"`
Whois string `json:"whois"`
Prefix string `json:"prefix"`
Router map[string][]string `json:"router"`
Source string `json:"source"`
}

type Source = func(ip string) (*IPGeoData, error)
Expand Down
6 changes: 6 additions & 0 deletions ipgeo/leo.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ipgeo

import (
"encoding/json"
"errors"
"sync"
"time"
Expand Down Expand Up @@ -52,6 +53,9 @@ func receiveParse() {
domain = res.Get("owner").String()
}

m := make(map[string][]string)
json.Unmarshal([]byte(res.Get("router").String()), &m)

IPPools.pool[gjson.Parse(data).Get("ip").String()] <- IPGeoData{
Asnumber: res.Get("asnumber").String(),
Country: res.Get("country").String(),
Expand All @@ -61,6 +65,8 @@ func receiveParse() {
Owner: domain,
Isp: res.Get("isp").String(),
Whois: res.Get("whois").String(),
Prefix: res.Get("prefix").String(),
Router: m,
}
}
}
Expand Down
4 changes: 4 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ var beginHop = fSet.Int("b", 1, "Set The Begin TTL")
var ver = fSet.Bool("V", false, "Print Version")
var src_addr = fSet.String("S", "", "Use the following IP address as the source address in outgoing packets")
var src_dev = fSet.String("D", "", "Use the following Network Devices as the source address in outgoing packets")
var router = fSet.Bool("R", false, "Show Routing Table [Provided By BGP.Tools]")

func printArgHelp() {
fmt.Println("\nArgs Error\nUsage : 'nexttrace [option...] HOSTNAME' or 'nexttrace HOSTNAME [option...]'\nOPTIONS: [-VTU] [-d DATAORIGIN.STR ] [ -m TTL ] [ -p PORT ] [ -q PROBES.COUNT ] [ -r PARALLELREQUESTS.COUNT ] [-rdns] [ -table ] -report")
Expand Down Expand Up @@ -162,6 +163,9 @@ func main() {
} else {
if *output {
conf.RealtimePrinter = tracelog.RealtimePrinter
} else if *router {
conf.RealtimePrinter = printer.RealtimePrinterWithRouter
fmt.Println("路由表数据源由 BGP.Tools 提供,在此特表感谢")
} else {
conf.RealtimePrinter = printer.RealtimePrinter
}
Expand Down
152 changes: 152 additions & 0 deletions printer/realtime_printer_router.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
package printer

import (
"fmt"
"net"
"strconv"
"strings"

"github.com/fatih/color"
"github.com/xgadget-lab/nexttrace/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),
)
}

}
}

0 comments on commit d561063

Please sign in to comment.