mirror of
https://github.com/nxtrace/NTrace-core.git
synced 2025-08-12 06:26:39 +00:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
991f66cfe4 | ||
|
|
5b91fac860 | ||
|
|
62e877e248 | ||
|
|
9e4b2ae577 | ||
|
|
b02572d6ff | ||
|
|
e5742e1603 | ||
|
|
70a727bee6 | ||
|
|
1261e243f2 | ||
|
|
49ce0cba8e | ||
|
|
9764533c8e | ||
|
|
d752385c29 | ||
|
|
bf005fb37a | ||
|
|
8dc5960d98 |
1
.github/workflows/publishNewFormula.yml
vendored
1
.github/workflows/publishNewFormula.yml
vendored
@@ -3,6 +3,7 @@ name: Publish New Formula
|
||||
# Controls when the action will run. Workflow runs when manually triggered using the UI
|
||||
# or API.
|
||||
on:
|
||||
push:
|
||||
workflow_dispatch:
|
||||
|
||||
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
|
||||
|
||||
21
README.md
21
README.md
@@ -54,6 +54,17 @@ nexttrace -f
|
||||
nexttrace -f -T
|
||||
```
|
||||
|
||||
`NextTrace` already supports route tracing for specified Network Devices
|
||||
|
||||
```bash
|
||||
# Use eth0 network interface
|
||||
nexttrace -D eth0 2606:4700:4700::1111
|
||||
|
||||
# Use eth0 network interface's IP
|
||||
# When using the network interface's IP for route tracing, note that the IP type to be traced should be the same as network interface's IP type (e.g. both IPv4)
|
||||
nexttrace -S 204.98.134.56 9.9.9.9
|
||||
```
|
||||
|
||||
`NextTrace` can also use `TCP` and `UDP` protocols to perform `Traceroute` requests, but these protocols only supports `IPv4` now
|
||||
|
||||
```bash
|
||||
@@ -154,7 +165,7 @@ Options:
|
||||
|
||||
## Project screenshot
|
||||
|
||||

|
||||

|
||||
|
||||
## NextTrace Enhanced
|
||||
|
||||
@@ -164,6 +175,14 @@ The `Enhanced` version supports many functions that the `lite` version does not
|
||||
|
||||
https://github.com/OwO-Network/nexttrace-enhanced
|
||||
|
||||
## Donate
|
||||
|
||||
In order to provide the most accurate IP geolocation as possible, the project team chose to build our own API (LeoMoeAPI) and purchased several IP geolocation data source APIs, and also fixed a lot of backbone IP geolocation errors, which cost a lot of time and money.
|
||||
|
||||
You can choose to donate to us to support our continuous development, we would like to express our gratitude in advance.
|
||||
|
||||
爱发电: https://afdian.net/@sjlleo
|
||||
|
||||
## FAQ Frequently Asked Questions
|
||||
|
||||
If you encounter problems while installing or using it, we do not recommend you to choose creating an `issue` as a preference
|
||||
|
||||
@@ -55,6 +55,19 @@ nexttrace -f
|
||||
nexttrace -f -T
|
||||
```
|
||||
|
||||
`NextTrace` 已支持指定网卡进行路由跟踪
|
||||
|
||||
```bash
|
||||
# 请注意 Lite 版本此参数不能和快速测试联用,如有需要请使用 enhanced 版本
|
||||
# 使用 eth0 网卡
|
||||
nexttrace -D eth0 2606:4700:4700::1111
|
||||
|
||||
# 使用 eth0 网卡IP
|
||||
# 网卡 IP 可以使用 ip a 或者 ifconfig 获取
|
||||
# 使用网卡IP进行路由跟踪时需要注意跟踪的IP类型应该和网卡IP类型一致(如都为 IPv4)
|
||||
nexttrace -S 204.98.134.56 9.9.9.9
|
||||
```
|
||||
|
||||
`NextTrace` 也可以使用`TCP`和`UDP`协议发起`Traceroute`请求,不过目前只支持`IPv4`
|
||||
|
||||
```bash
|
||||
@@ -130,6 +143,10 @@ NextTrace 所有的的 IP 地理位置`API DEMO`可以参考[这里](https://git
|
||||
Usage of nexttrace:
|
||||
'nexttrace [options] <hostname>' or 'nexttrace <hostname> [option...]'
|
||||
Options:
|
||||
-D string
|
||||
Use the following Network Devices as the source address in outgoing packets
|
||||
-S string
|
||||
Use the following IP address as the source address in outgoing packets
|
||||
-T Use TCP SYN for tracerouting (default port is 80)
|
||||
-U Use UDP Package for tracerouting (default port is 53 in UDP)
|
||||
-V Print Version
|
||||
@@ -155,7 +172,7 @@ Options:
|
||||
|
||||
## 项目截图
|
||||
|
||||

|
||||

|
||||
|
||||
## NextTrace Enhanced
|
||||
|
||||
@@ -165,6 +182,14 @@ Options:
|
||||
|
||||
https://github.com/OwO-Network/nexttrace-enhanced
|
||||
|
||||
## 捐助我们
|
||||
|
||||
为了能够尽可能提供精准的 IP 地理位置,项目组选择了自建 API (LeoMoeAPI) 并购买了多家 IP 地理位置的数据源 API,同时也修正的大量的骨干网 IP 地理位置错误,这需要耗费大量的时间和金钱。
|
||||
|
||||
您可以选择捐助我们,以支持我们的持续发展,在此先表示感谢了。
|
||||
|
||||
爱发电:https://afdian.net/@sjlleo
|
||||
|
||||
## FAQ 常见问题
|
||||
|
||||
如果你在安装或者使用的时候遇到了问题,我们建议你不要把新建一个 `issue` 作为首选项
|
||||
|
||||
BIN
asset/nexttrace021.png
Normal file
BIN
asset/nexttrace021.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 101 KiB |
4
go.mod
4
go.mod
@@ -17,9 +17,9 @@ require (
|
||||
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||
github.com/fatih/color v1.13.0
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||
github.com/lionsoul2014/ip2region v2.10.0+incompatible
|
||||
github.com/rodaine/table v1.0.1
|
||||
github.com/stretchr/testify v1.7.1
|
||||
github.com/stretchr/testify v1.7.1 // indirect
|
||||
github.com/tidwall/gjson v1.14.2
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.0 // indirect
|
||||
|
||||
12
go.sum
12
go.sum
@@ -7,7 +7,8 @@ github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF
|
||||
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
|
||||
github.com/gorilla/websocket v1.5.0 h1:PPwGk2jz7EePpoHN/+ClbZu8SPxiqlu12wZP/3sWmnc=
|
||||
github.com/gorilla/websocket v1.5.0/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/mattn/go-colorable v0.1.9 h1:sqDoxXbdeALODt0DAeJCVp38ps9ZogZEAXjus69YV3U=
|
||||
github.com/lionsoul2014/ip2region v2.10.0+incompatible h1:HpgN+54Korm/I0xXNX6I6owmvAwtPxrcI6cHYqXKtLw=
|
||||
github.com/lionsoul2014/ip2region v2.10.0+incompatible/go.mod h1:+ZBN7PBoh5gG6/y0ZQ85vJDBe21WnfbRrQQwTfliJJI=
|
||||
github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc=
|
||||
github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40=
|
||||
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
@@ -24,8 +25,6 @@ github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.1 h1:5TQK59W5E3v0r2duFAb7P95B6hEeOyEnHRa8MjYSMTY=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/tidwall/gjson v1.14.1 h1:iymTbGkQBhveq21bEvAQ81I0LEBork8BFe1CUZXdyuo=
|
||||
github.com/tidwall/gjson v1.14.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/gjson v1.14.2 h1:6BBkirS0rAHjumnjHF6qgy5d2YAJ1TLIaFE2lzfOLqo=
|
||||
github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
@@ -38,13 +37,9 @@ golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPI
|
||||
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA=
|
||||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220809012201-f428fae20770 h1:dIi4qVdvjZEjiMDv7vhokAZNGnz3kepwuXqFKYDdDMs=
|
||||
golang.org/x/net v0.0.0-20220809012201-f428fae20770/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29 h1:w8s32wxx3sY+OjLlv9qltkLU5yvJzxjjgiHWLjdIcw4=
|
||||
golang.org/x/sync v0.0.0-20220513210516-0976fa681c29/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
|
||||
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -53,14 +48,11 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6 h1:nonptSpoQ4vQjyraW20DXPAglgQfVnM9ZC6MmNLMR60=
|
||||
golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220808155132-1c4a2a72c664 h1:v1W7bwXHsnLLloWYTVEdvGvA7BHMeBYsPcF0GLDxIRs=
|
||||
golang.org/x/sys v0.0.0-20220808155132-1c4a2a72c664/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
|
||||
|
||||
77
ipgeo/ip2region.go
Normal file
77
ipgeo/ip2region.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package ipgeo
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/lionsoul2014/ip2region/v1.0/binding/golang/ip2region"
|
||||
)
|
||||
|
||||
const (
|
||||
ipDataBasePath = "./ip2region.db"
|
||||
defaultDownURL = "1"
|
||||
originURL = "https://ghproxy.com/?q=https://github.com/bqf9979/ip2region/blob/master/data/ip2region.db?raw=true"
|
||||
)
|
||||
|
||||
func downloadDataBase() error {
|
||||
fmt.Println("Downloading DataBase...")
|
||||
resp, err := http.Get(originURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
// Create the file
|
||||
out, err := os.Create(ipDataBasePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer out.Close()
|
||||
|
||||
// Write the body to file
|
||||
_, err = io.Copy(out, resp.Body)
|
||||
return err
|
||||
}
|
||||
|
||||
func IP2Region(ip string) (*IPGeoData, error) {
|
||||
if _, err := os.Stat(ipDataBasePath); os.IsNotExist(err) {
|
||||
if err = downloadDataBase(); err != nil {
|
||||
panic("Download Failed!")
|
||||
}
|
||||
}
|
||||
region, err := ip2region.New(ipDataBasePath)
|
||||
if err != nil {
|
||||
panic("Cannot find ip2region.db")
|
||||
}
|
||||
defer region.Close()
|
||||
info, searchErr := region.MemorySearch(ip)
|
||||
if searchErr != nil {
|
||||
return &IPGeoData{}, errors.New("no results")
|
||||
}
|
||||
|
||||
if info.Country == "0" {
|
||||
info.Country = ""
|
||||
}
|
||||
|
||||
if info.Province == "0" {
|
||||
info.Province = ""
|
||||
}
|
||||
|
||||
if info.City == "0" {
|
||||
info.City = ""
|
||||
}
|
||||
|
||||
if info.ISP == "0" {
|
||||
info.ISP = ""
|
||||
}
|
||||
|
||||
return &IPGeoData{
|
||||
Owner: info.ISP,
|
||||
Country: info.Country,
|
||||
Prov: info.Province,
|
||||
City: info.City,
|
||||
}, nil
|
||||
}
|
||||
@@ -38,6 +38,6 @@ func IPApiCom(ip string) (*IPGeoData, error) {
|
||||
Country: res.Get("country").String(),
|
||||
City: res.Get("city").String(),
|
||||
Prov: res.Get("regionName").String(),
|
||||
Isp: res.Get("isp").String(),
|
||||
Owner: res.Get("isp").String(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ type IPGeoData struct {
|
||||
District string
|
||||
Owner string
|
||||
Isp string
|
||||
Whois string
|
||||
}
|
||||
|
||||
type Source = func(ip string) (*IPGeoData, error)
|
||||
@@ -28,6 +29,8 @@ func GetSource(s string) Source {
|
||||
return IPApiCom
|
||||
case "IPINFO":
|
||||
return IPInfo
|
||||
case "IP2REGION":
|
||||
return IP2Region
|
||||
default:
|
||||
return LeoIP
|
||||
}
|
||||
|
||||
@@ -31,6 +31,6 @@ func IPInfo(ip string) (*IPGeoData, error) {
|
||||
Country: country,
|
||||
City: res.Get("city").String(),
|
||||
Prov: res.Get("region").String(),
|
||||
Isp: res.Get("asn").Get("domain").String(),
|
||||
Owner: res.Get("asn").Get("domain").String(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -37,6 +37,6 @@ func IPSB(ip string) (*IPGeoData, error) {
|
||||
Country: res.Get("country").String(),
|
||||
City: res.Get("city").String(),
|
||||
Prov: res.Get("region").String(),
|
||||
Isp: res.Get("isp").String(),
|
||||
Owner: res.Get("isp").String(),
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -60,6 +60,7 @@ func receiveParse() {
|
||||
District: res.Get("district").String(),
|
||||
Owner: domain,
|
||||
Isp: res.Get("isp").String(),
|
||||
Whois: res.Get("whois").String(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
15
main.go
15
main.go
@@ -34,6 +34,8 @@ var tablePrint = fSet.Bool("table", false, "Output trace results as table")
|
||||
var classicPrint = fSet.Bool("classic", false, "Classic Output trace results like BestTrace")
|
||||
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")
|
||||
|
||||
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")
|
||||
@@ -92,6 +94,18 @@ func main() {
|
||||
ip = util.DomainLookUp(domain, false)
|
||||
}
|
||||
|
||||
if *src_dev != "" {
|
||||
dev, _ := net.InterfaceByName(*src_dev)
|
||||
|
||||
if addrs, err := dev.Addrs(); err == nil {
|
||||
for _, addr := range addrs {
|
||||
if (addr.(*net.IPNet).IP.To4() == nil) == (ip.To4() == nil) {
|
||||
*src_addr = addr.(*net.IPNet).IP.String()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if strings.ToUpper(*dataOrigin) == "LEOMOEAPI" {
|
||||
w := wshandle.New()
|
||||
w.Interrupt = make(chan os.Signal, 1)
|
||||
@@ -119,6 +133,7 @@ func main() {
|
||||
}
|
||||
|
||||
var conf = trace.Config{
|
||||
SrcAddr: *src_addr,
|
||||
BeginHop: *beginHop,
|
||||
DestIP: ip,
|
||||
DestPort: *port,
|
||||
|
||||
@@ -2,7 +2,9 @@ package printer
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/fatih/color"
|
||||
"github.com/xgadget-lab/nexttrace/trace"
|
||||
@@ -48,9 +50,15 @@ func RealtimePrinter(res *trace.Result, ttl int) {
|
||||
if blockDisplay {
|
||||
fmt.Printf("%4s", "")
|
||||
}
|
||||
fmt.Fprintf(color.Output, "%s",
|
||||
color.New(color.FgWhite, color.Bold).Sprintf("%-15s", ip),
|
||||
)
|
||||
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])
|
||||
|
||||
@@ -60,18 +68,42 @@ func RealtimePrinter(res *trace.Result, ttl int) {
|
||||
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"
|
||||
}
|
||||
|
||||
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("%-22s", res.Hops[ttl][0].Hostname),
|
||||
)
|
||||
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 {
|
||||
|
||||
@@ -31,7 +31,7 @@ func (t *ICMPTracer) Execute() (*Result, error) {
|
||||
|
||||
var err error
|
||||
|
||||
t.icmpListen, err = net.ListenPacket("ip4:1", "0.0.0.0")
|
||||
t.icmpListen, err = net.ListenPacket("ip4:1", t.SrcAddr)
|
||||
if err != nil {
|
||||
return &t.res, err
|
||||
}
|
||||
|
||||
@@ -30,7 +30,7 @@ func (t *ICMPTracerv6) Execute() (*Result, error) {
|
||||
|
||||
var err error
|
||||
|
||||
t.icmpListen, err = net.ListenPacket("ip6:58", "::")
|
||||
t.icmpListen, err = net.ListenPacket("ip6:58", t.SrcAddr)
|
||||
if err != nil {
|
||||
return &t.res, err
|
||||
}
|
||||
|
||||
@@ -42,11 +42,16 @@ func (t *TCPTracer) Execute() (*Result, error) {
|
||||
t.SrcIP, _ = util.LocalIPPort(t.DestIP)
|
||||
|
||||
var err error
|
||||
t.tcp, err = net.ListenPacket("ip4:tcp", t.SrcIP.String())
|
||||
if t.SrcAddr != "" {
|
||||
t.tcp, err = net.ListenPacket("ip4:tcp", t.SrcAddr)
|
||||
} else {
|
||||
t.tcp, err = net.ListenPacket("ip4:tcp", t.SrcIP.String())
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t.icmp, err = icmp.ListenPacket("ip4:icmp", "0.0.0.0")
|
||||
t.icmp, err = icmp.ListenPacket("ip4:icmp", t.SrcAddr)
|
||||
if err != nil {
|
||||
return &t.res, err
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ var (
|
||||
)
|
||||
|
||||
type Config struct {
|
||||
SrcAddr string
|
||||
BeginHop int
|
||||
MaxHops int
|
||||
NumMeasurements int
|
||||
|
||||
@@ -37,7 +37,7 @@ func (t *UDPTracer) Execute() (*Result, error) {
|
||||
}
|
||||
|
||||
var err error
|
||||
t.icmp, err = icmp.ListenPacket("ip4:icmp", "0.0.0.0")
|
||||
t.icmp, err = icmp.ListenPacket("ip4:icmp", t.SrcAddr)
|
||||
if err != nil {
|
||||
return &t.res, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user