mirror of
https://github.com/nxtrace/NTrace-core.git
synced 2025-08-12 06:26:39 +00:00
Compare commits
34 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f303397ce1 | ||
|
|
33239a78d1 | ||
|
|
e4fa907ed4 | ||
|
|
d0fb43e947 | ||
|
|
9dda330543 | ||
|
|
94372d9605 | ||
|
|
f50ca1f7f8 | ||
|
|
f06dba7458 | ||
|
|
d1e87c8a77 | ||
|
|
57d31a38f7 | ||
|
|
84b709de44 | ||
|
|
dad9282078 | ||
|
|
85b01ebfc6 | ||
|
|
a2b5cde829 | ||
|
|
f2536980b7 | ||
|
|
fae4b7b71a | ||
|
|
791dd45086 | ||
|
|
3751d9ce12 | ||
|
|
39169291e8 | ||
|
|
6937b54cdf | ||
|
|
742035cc0c | ||
|
|
7350d13850 | ||
|
|
970cff3b72 | ||
|
|
b053ee646b | ||
|
|
f6f90f3a5b | ||
|
|
e128fe1893 | ||
|
|
2cb13be378 | ||
|
|
7ae4eb13c9 | ||
|
|
d1a72458a6 | ||
|
|
5e3474d029 | ||
|
|
a93b7658b7 | ||
|
|
bbb905f113 | ||
|
|
5f44fc704d | ||
|
|
1257fe87b5 |
3
.github/workflows/test.yml
vendored
3
.github/workflows/test.yml
vendored
@@ -31,8 +31,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.22'
|
||||
check-latest: true
|
||||
go-version: '1.22.0'
|
||||
- name: Checkout codebase
|
||||
uses: actions/checkout@v4
|
||||
- name: Test with unix
|
||||
|
||||
38
README.md
38
README.md
@@ -237,6 +237,9 @@ nexttrace --no-rdns www.bbix.net
|
||||
# Set the payload size to 1024 bytes
|
||||
nexttrace --psize 1024 example.com
|
||||
|
||||
# Set the payload size and DF flag for TCP Trace
|
||||
nexttrace --psize 1024 --dont-fragment --tcp example.com
|
||||
|
||||
# Feature: print Route-Path diagram
|
||||
# Route-Path diagram example:
|
||||
# AS6453 Tata Communication「Singapore『Singapore』」
|
||||
@@ -329,16 +332,10 @@ Arguments:
|
||||
-T --tcp Use TCP SYN for tracerouting (default port
|
||||
is 80)
|
||||
-U --udp Use UDP SYN for tracerouting (default port
|
||||
is 53)
|
||||
is 33494)
|
||||
-F --fast-trace One-Key Fast Trace to China ISPs
|
||||
-p --port Set the destination port to use. It is
|
||||
either initial udp port value for
|
||||
"default"method (incremented by each
|
||||
probe, default is 33434), or initial seq
|
||||
for "icmp" (incremented as well, default
|
||||
from 1), or some constantdestination port
|
||||
for other methods (with default of 80 for
|
||||
"tcp", 53 for "udp", etc.)
|
||||
-p --port Set the destination port to use. With
|
||||
default of 80 for "tcp", 33494 for "udp"
|
||||
-q --queries Set the number of probes per each hop.
|
||||
Default: 3
|
||||
--parallel-requests Set ParallelRequests number. It should be
|
||||
@@ -350,9 +347,9 @@ Arguments:
|
||||
IPInfo, IPInsight, IP-API.com, Ip2region,
|
||||
IPInfoLocal, CHUNZHEN, disable-geoip].
|
||||
Default: LeoMoeAPI
|
||||
--pow-provider Choose PoW Provider [api.nxtrace.org, sakura]
|
||||
For China mainland users, please use
|
||||
sakura. Default: api.nxtrace.org
|
||||
--pow-provider Choose PoW Provider [api.nxtrace.org,
|
||||
sakura] For China mainland users, please
|
||||
use sakura. Default: api.nxtrace.org
|
||||
-n --no-rdns Do not resolve IP addresses to their
|
||||
domain names
|
||||
-a --always-rdns Always resolve IP addresses to their
|
||||
@@ -379,16 +376,15 @@ Arguments:
|
||||
-z --send-time Set how many [milliseconds] between
|
||||
sending each packet.. Useful when some
|
||||
routers use rate-limit for ICMP messages.
|
||||
Default: 100
|
||||
Default: 50
|
||||
-i --ttl-time Set how many [milliseconds] between
|
||||
sending packets groups by TTL. Useful when
|
||||
some routers use rate-limit for ICMP
|
||||
messages. Default: 500
|
||||
messages. Default: 50
|
||||
--timeout The number of [milliseconds] to keep probe
|
||||
sockets open before giving up on the
|
||||
connection.. Default: 1000
|
||||
--psize Set the packet size (payload size).
|
||||
Default: 52
|
||||
--psize Set the payload size. Default: 52
|
||||
--_positionalArg_nexttrace_32 IP Address or domain name
|
||||
--dot-server Use DoT Server for DNS Parse [dnssb,
|
||||
aliyun, dnspod, google, cloudflare]
|
||||
@@ -396,6 +392,8 @@ Arguments:
|
||||
cn]. Default: cn
|
||||
--file Read IP Address or domain name from file
|
||||
-C --nocolor Disable Colorful Output
|
||||
--dont-fragment Set the Don't Fragment bit (IPv4 TCP
|
||||
only). Default: false
|
||||
```
|
||||
|
||||
## Project screenshot
|
||||
@@ -418,6 +416,14 @@ This software is still in the early stages of development and may have many flaw
|
||||
|
||||
[https://github.com/nxtrace/nexttracewebapi](https://github.com/nxtrace/nexttracewebapi)
|
||||
|
||||
## NextTraceroute
|
||||
|
||||
`NextTraceroute` is a root-free Android route tracing application that defaults to using the `NextTrace API`, developed by @surfaceocean.
|
||||
Thank you to all the test users for your enthusiastic support. This app has successfully passed the closed testing phase and is now officially available on the Google Play Store.
|
||||
|
||||
[https://github.com/nxtrace/NextTraceroute](https://github.com/nxtrace/NextTraceroute)
|
||||
<a href='https://play.google.com/store/apps/details?id=com.surfaceocean.nexttraceroute&pcampaignid=pcampaignidMKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' width="128" height="48" src='https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png'/></a>
|
||||
|
||||
## LeoMoeAPI Credits
|
||||
|
||||
NextTrace focuses on Golang Traceroute implementations, and its LeoMoeAPI geolocation information is not supported by raw data, so a commercial version is not possible.
|
||||
|
||||
@@ -229,7 +229,7 @@ nexttrace --tcp --port 443 2001:4860:4860::8888
|
||||
# UDP Trace
|
||||
nexttrace --udp 1.0.0.1
|
||||
|
||||
# 可以自行指定端口[此处为5353],默认53端口
|
||||
# 可以自行指定端口[此处为5353],默认33494端口
|
||||
nexttrace --udp --port 5353 1.0.0.1
|
||||
```
|
||||
|
||||
@@ -253,6 +253,9 @@ nexttrace --no-rdns www.bbix.net
|
||||
# 设置载荷大小为1024字节
|
||||
nexttrace --psize 1024 example.com
|
||||
|
||||
# 设置载荷大小以及DF标志进行TCP Trace
|
||||
nexttrace --psize 1024 --dont-fragment --tcp example.com
|
||||
|
||||
# 特色功能:打印Route-Path图
|
||||
# Route-Path图示例:
|
||||
# AS6453 塔塔通信「Singapore『Singapore』」
|
||||
@@ -328,16 +331,10 @@ Arguments:
|
||||
-T --tcp Use TCP SYN for tracerouting (default port
|
||||
is 80)
|
||||
-U --udp Use UDP SYN for tracerouting (default port
|
||||
is 53)
|
||||
is 33494)
|
||||
-F --fast-trace One-Key Fast Trace to China ISPs
|
||||
-p --port Set the destination port to use. It is
|
||||
either initial udp port value for
|
||||
"default"method (incremented by each
|
||||
probe, default is 33434), or initial seq
|
||||
for "icmp" (incremented as well, default
|
||||
from 1), or some constantdestination port
|
||||
for other methods (with default of 80 for
|
||||
"tcp", 53 for "udp", etc.)
|
||||
-p --port Set the destination port to use. With
|
||||
default of 80 for "tcp", 33494 for "udp"
|
||||
-q --queries Set the number of probes per each hop.
|
||||
Default: 3
|
||||
--parallel-requests Set ParallelRequests number. It should be
|
||||
@@ -349,9 +346,9 @@ Arguments:
|
||||
IPInfo, IPInsight, IP-API.com, Ip2region,
|
||||
IPInfoLocal, CHUNZHEN, disable-geoip].
|
||||
Default: LeoMoeAPI
|
||||
--pow-provider Choose PoW Provider [api.nxtrace.org, sakura]
|
||||
For China mainland users, please use
|
||||
sakura. Default: api.nxtrace.org
|
||||
--pow-provider Choose PoW Provider [api.nxtrace.org,
|
||||
sakura] For China mainland users, please
|
||||
use sakura. Default: api.nxtrace.org
|
||||
-n --no-rdns Do not resolve IP addresses to their
|
||||
domain names
|
||||
-a --always-rdns Always resolve IP addresses to their
|
||||
@@ -378,16 +375,15 @@ Arguments:
|
||||
-z --send-time Set how many [milliseconds] between
|
||||
sending each packet.. Useful when some
|
||||
routers use rate-limit for ICMP messages.
|
||||
Default: 100
|
||||
Default: 50
|
||||
-i --ttl-time Set how many [milliseconds] between
|
||||
sending packets groups by TTL. Useful when
|
||||
some routers use rate-limit for ICMP
|
||||
messages. Default: 500
|
||||
messages. Default: 50
|
||||
--timeout The number of [milliseconds] to keep probe
|
||||
sockets open before giving up on the
|
||||
connection.. Default: 1000
|
||||
--psize Set the packet size (payload size).
|
||||
Default: 52
|
||||
--psize Set the payload size. Default: 52
|
||||
--_positionalArg_nexttrace_32 IP Address or domain name
|
||||
--dot-server Use DoT Server for DNS Parse [dnssb,
|
||||
aliyun, dnspod, google, cloudflare]
|
||||
@@ -395,6 +391,8 @@ Arguments:
|
||||
cn]. Default: cn
|
||||
--file Read IP Address or domain name from file
|
||||
-C --nocolor Disable Colorful Output
|
||||
--dont-fragment Set the Don't Fragment bit (IPv4 TCP
|
||||
only). Default: false
|
||||
```
|
||||
|
||||
## 项目截图
|
||||
@@ -428,8 +426,7 @@ nexttrace --pow-provider sakura
|
||||
|
||||
## OpenTrace
|
||||
|
||||
`OpenTrace`是 @Archeb 开发的`NextTrace`的跨平台`GUI`版本,带来您熟悉但更强大的用户体验。
|
||||
|
||||
`OpenTrace`是 @Archeb 开发的`NextTrace`的跨平台`GUI`版本,带来您熟悉但更强大的用户体验。
|
||||
该软件仍然处于早期开发阶段,可能存在许多缺陷和错误,需要您宝贵的使用反馈。
|
||||
|
||||
[https://github.com/Archeb/opentrace](https://github.com/Archeb/opentrace)
|
||||
@@ -440,6 +437,14 @@ nexttrace --pow-provider sakura
|
||||
|
||||
[https://github.com/nxtrace/nexttracewebapi](https://github.com/nxtrace/nexttracewebapi)
|
||||
|
||||
## NextTraceroute
|
||||
|
||||
`NextTraceroute`,一款默认使用`NextTrace API`的免`root`安卓版路由跟踪应用,由 @surfaceocean 开发。
|
||||
感谢所有测试用户的热情支持,本应用已经通过封闭测试,正式进入 Google Play 商店。
|
||||
|
||||
[https://github.com/nxtrace/NextTraceroute](https://github.com/nxtrace/NextTraceroute)
|
||||
<a href='https://play.google.com/store/apps/details?id=com.surfaceocean.nexttraceroute&pcampaignid=pcampaignidMKT-Other-global-all-co-prtnr-py-PartBadge-Mar2515-1'><img alt='Get it on Google Play' width="128" height="48" src='https://play.google.com/intl/en_us/badges/static/images/badges/en_badge_web_generic.png'/></a>
|
||||
|
||||
## Credits
|
||||
|
||||
[IPInfo](https://ipinfo.io) 无偿提供了本项目大部分数据支持
|
||||
|
||||
21
cmd/cmd.go
21
cmd/cmd.go
@@ -32,11 +32,9 @@ func Excute() {
|
||||
ipv4Only := parser.Flag("4", "ipv4", &argparse.Options{Help: "Use IPv4 only"})
|
||||
ipv6Only := parser.Flag("6", "ipv6", &argparse.Options{Help: "Use IPv6 only"})
|
||||
tcp := parser.Flag("T", "tcp", &argparse.Options{Help: "Use TCP SYN for tracerouting (default port is 80)"})
|
||||
udp := parser.Flag("U", "udp", &argparse.Options{Help: "Use UDP SYN for tracerouting (default port is 53)"})
|
||||
udp := parser.Flag("U", "udp", &argparse.Options{Help: "Use UDP SYN for tracerouting (default port is 33494)"})
|
||||
fast_trace := parser.Flag("F", "fast-trace", &argparse.Options{Help: "One-Key Fast Trace to China ISPs"})
|
||||
port := parser.Int("p", "port", &argparse.Options{Help: "Set the destination port to use. It is either initial udp port value for \"default\"" +
|
||||
"method (incremented by each probe, default is 33434), or initial seq for \"icmp\" (incremented as well, default from 1), or some constant" +
|
||||
"destination port for other methods (with default of 80 for \"tcp\", 53 for \"udp\", etc.)"})
|
||||
port := parser.Int("p", "port", &argparse.Options{Help: "Set the destination port to use. With default of 80 for \"tcp\", 33494 for \"udp\""})
|
||||
numMeasurements := parser.Int("q", "queries", &argparse.Options{Default: 3, Help: "Set the number of probes per each hop"})
|
||||
parallelRequests := parser.Int("", "parallel-requests", &argparse.Options{Default: 18, Help: "Set ParallelRequests number. It should be 1 when there is a multi-routing"})
|
||||
maxHops := parser.Int("m", "max-hops", &argparse.Options{Default: 30, Help: "Set the max number of hops (max TTL to be reached)"})
|
||||
@@ -61,10 +59,10 @@ func Excute() {
|
||||
srcAddr := parser.String("s", "source", &argparse.Options{Help: "Use source src_addr for outgoing packets"})
|
||||
srcDev := parser.String("D", "dev", &argparse.Options{Help: "Use the following Network Devices as the source address in outgoing packets"})
|
||||
//router := parser.Flag("R", "route", &argparse.Options{Help: "Show Routing Table [Provided By BGP.Tools]"})
|
||||
packetInterval := parser.Int("z", "send-time", &argparse.Options{Default: 100, Help: "Set how many [milliseconds] between sending each packet.. Useful when some routers use rate-limit for ICMP messages"})
|
||||
ttlInterval := parser.Int("i", "ttl-time", &argparse.Options{Default: 500, Help: "Set how many [milliseconds] between sending packets groups by TTL. Useful when some routers use rate-limit for ICMP messages"})
|
||||
packetInterval := parser.Int("z", "send-time", &argparse.Options{Default: 50, Help: "Set how many [milliseconds] between sending each packet.. Useful when some routers use rate-limit for ICMP messages"})
|
||||
ttlInterval := parser.Int("i", "ttl-time", &argparse.Options{Default: 50, Help: "Set how many [milliseconds] between sending packets groups by TTL. Useful when some routers use rate-limit for ICMP messages"})
|
||||
timeout := parser.Int("", "timeout", &argparse.Options{Default: 1000, Help: "The number of [milliseconds] to keep probe sockets open before giving up on the connection."})
|
||||
packetSize := parser.Int("", "psize", &argparse.Options{Default: 52, Help: "Set the packet size (payload size)"})
|
||||
packetSize := parser.Int("", "psize", &argparse.Options{Default: 52, Help: "Set the payload size"})
|
||||
str := parser.StringPositional(&argparse.Options{Help: "IP Address or domain name"})
|
||||
dot := parser.Selector("", "dot-server", []string{"dnssb", "aliyun", "dnspod", "google", "cloudflare"}, &argparse.Options{
|
||||
Help: "Use DoT Server for DNS Parse [dnssb, aliyun, dnspod, google, cloudflare]"})
|
||||
@@ -72,6 +70,7 @@ func Excute() {
|
||||
Help: "Choose the language for displaying [en, cn]"})
|
||||
file := parser.String("", "file", &argparse.Options{Help: "Read IP Address or domain name from file"})
|
||||
nocolor := parser.Flag("C", "nocolor", &argparse.Options{Help: "Disable Colorful Output"})
|
||||
dontFragment := parser.Flag("", "dont-fragment", &argparse.Options{Default: false, Help: "Set the Don't Fragment bit (IPv4 TCP only)"})
|
||||
|
||||
err := parser.Parse(os.Args)
|
||||
if err != nil {
|
||||
@@ -114,6 +113,7 @@ func Excute() {
|
||||
PktSize: *packetSize,
|
||||
Timeout: time.Duration(*timeout) * time.Millisecond,
|
||||
File: *file,
|
||||
DontFragment: *dontFragment,
|
||||
}
|
||||
|
||||
fastTrace.FastTest(*tcp, *output, paramsFastTrace)
|
||||
@@ -148,7 +148,7 @@ func Excute() {
|
||||
}
|
||||
// DOMAIN处理结束
|
||||
|
||||
capabilities_check()
|
||||
capabilitiesCheck()
|
||||
// return
|
||||
|
||||
var ip net.IP
|
||||
@@ -251,7 +251,7 @@ func Excute() {
|
||||
}
|
||||
|
||||
if !*tcp && *port == 80 {
|
||||
*port = 53
|
||||
*port = 33494
|
||||
}
|
||||
|
||||
util.DestIP = ip.String()
|
||||
@@ -272,6 +272,7 @@ func Excute() {
|
||||
IPGeoSource: ipgeo.GetSource(*dataOrigin),
|
||||
Timeout: time.Duration(*timeout) * time.Millisecond,
|
||||
PktSize: *packetSize,
|
||||
DontFragment: *dontFragment,
|
||||
}
|
||||
|
||||
// 暂时弃用
|
||||
@@ -357,7 +358,7 @@ func Excute() {
|
||||
}
|
||||
}
|
||||
|
||||
func capabilities_check() {
|
||||
func capabilitiesCheck() {
|
||||
|
||||
// Windows 判断放在前面,防止遇到一些奇奇怪怪的问题
|
||||
if runtime.GOOS == "windows" {
|
||||
|
||||
@@ -39,6 +39,7 @@ func (f *FastTracer) tracert_v6(location string, ispCollection ISPCollection) {
|
||||
SrcAddr: f.ParamsFastTrace.SrcAddr,
|
||||
PktSize: f.ParamsFastTrace.PktSize,
|
||||
Lang: f.ParamsFastTrace.Lang,
|
||||
DontFragment: f.ParamsFastTrace.DontFragment,
|
||||
}
|
||||
|
||||
if oe {
|
||||
|
||||
@@ -34,6 +34,7 @@ type ParamsFastTrace struct {
|
||||
PktSize int
|
||||
Timeout time.Duration
|
||||
File string
|
||||
DontFragment bool
|
||||
}
|
||||
|
||||
type IpListElement struct {
|
||||
@@ -68,6 +69,7 @@ func (f *FastTracer) tracert(location string, ispCollection ISPCollection) {
|
||||
SrcAddr: f.ParamsFastTrace.SrcAddr,
|
||||
PktSize: f.ParamsFastTrace.PktSize,
|
||||
Lang: f.ParamsFastTrace.Lang,
|
||||
DontFragment: f.ParamsFastTrace.DontFragment,
|
||||
}
|
||||
|
||||
if oe {
|
||||
@@ -279,9 +281,9 @@ func testFile(paramsFastTrace ParamsFastTrace, tm bool) {
|
||||
color.New(color.FgYellow, color.Bold).Sprint("『 "+ip.Desc+"』"),
|
||||
)
|
||||
if util.EnableHidDstIP == "" {
|
||||
fmt.Printf("traceroute to %s, %d hops max, %d bytes packets\n", ip.Ip, paramsFastTrace.MaxHops, paramsFastTrace.PktSize)
|
||||
fmt.Printf("traceroute to %s, %d hops max, %d bytes payload\n", ip.Ip, paramsFastTrace.MaxHops, paramsFastTrace.PktSize)
|
||||
} else {
|
||||
fmt.Printf("traceroute to %s, %d hops max, %d bytes packets\n", util.HideIPPart(ip.Ip), paramsFastTrace.MaxHops, paramsFastTrace.PktSize)
|
||||
fmt.Printf("traceroute to %s, %d hops max, %d bytes payload\n", util.HideIPPart(ip.Ip), paramsFastTrace.MaxHops, paramsFastTrace.PktSize)
|
||||
}
|
||||
var srcAddr string
|
||||
if ip.Version4 {
|
||||
|
||||
20
go.mod
20
go.mod
@@ -1,6 +1,6 @@
|
||||
module github.com/nxtrace/NTrace-core
|
||||
|
||||
go 1.22
|
||||
go 1.22.0
|
||||
|
||||
require (
|
||||
github.com/akamensky/argparse v1.4.0
|
||||
@@ -9,9 +9,9 @@ require (
|
||||
github.com/spf13/viper v1.18.2
|
||||
github.com/stretchr/testify v1.9.0
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635
|
||||
github.com/tsosunchia/powclient v0.1.4
|
||||
golang.org/x/net v0.22.0
|
||||
golang.org/x/sync v0.6.0
|
||||
github.com/tsosunchia/powclient v0.1.5
|
||||
golang.org/x/net v0.25.0
|
||||
golang.org/x/sync v0.7.0
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -22,7 +22,7 @@ require (
|
||||
github.com/mattn/go-colorable v0.1.13 // indirect
|
||||
github.com/mattn/go-isatty v0.0.20 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.1.1 // indirect
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
|
||||
github.com/sagikazarmark/locafero v0.4.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
@@ -32,19 +32,19 @@ require (
|
||||
github.com/spf13/pflag v1.0.5 // indirect
|
||||
github.com/subosito/gotenv v1.6.0 // indirect
|
||||
go.uber.org/multierr v1.11.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 // indirect
|
||||
golang.org/x/text v0.15.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/fatih/color v1.16.0
|
||||
github.com/fatih/color v1.17.0
|
||||
github.com/gorilla/websocket v1.5.1
|
||||
github.com/lionsoul2014/ip2region v2.11.2+incompatible
|
||||
github.com/rodaine/table v1.1.1
|
||||
github.com/rodaine/table v1.2.0
|
||||
github.com/tidwall/gjson v1.17.1
|
||||
github.com/tidwall/match v1.1.1 // indirect
|
||||
github.com/tidwall/pretty v1.2.1 // indirect
|
||||
golang.org/x/sys v0.18.0 // indirect
|
||||
golang.org/x/sys v0.20.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
45
go.sum
45
go.sum
@@ -4,8 +4,8 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
|
||||
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM=
|
||||
github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE=
|
||||
github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4=
|
||||
github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI=
|
||||
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
|
||||
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
|
||||
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
|
||||
@@ -37,17 +37,17 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua
|
||||
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
|
||||
github.com/oschwald/maxminddb-golang v1.12.0 h1:9FnTOD0YOhP7DGxGsq4glzpGy5+w7pq50AS6wALUMYs=
|
||||
github.com/oschwald/maxminddb-golang v1.12.0/go.mod h1:q0Nob5lTCqyQ8WT6FYgS1L7PXKVVbgiymefNwIjPzgY=
|
||||
github.com/pelletier/go-toml/v2 v2.1.1 h1:LWAJwfNvjQZCFIDKWYQaM62NcYeYViCmWIwmOStowAI=
|
||||
github.com/pelletier/go-toml/v2 v2.1.1/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM=
|
||||
github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
|
||||
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
|
||||
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
|
||||
github.com/rodaine/table v1.1.1 h1:zBliy3b4Oj6JRmncse2Z85WmoQvDrXOYuy0JXCt8Qz8=
|
||||
github.com/rodaine/table v1.1.1/go.mod h1:iqTRptjn+EVcrVBYtNMlJ2wrJZa3MpULUmcXFpfcziA=
|
||||
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
|
||||
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
|
||||
github.com/rodaine/table v1.2.0 h1:38HEnwK4mKSHQJIkavVj+bst1TEY7j9zhLMWu4QJrMA=
|
||||
github.com/rodaine/table v1.2.0/go.mod h1:wejb/q/Yd4T/SVmBSRMr7GCq3KlcZp3gyNYdLSBhkaE=
|
||||
github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8=
|
||||
github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4=
|
||||
github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
|
||||
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
|
||||
@@ -65,6 +65,7 @@ github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMV
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
|
||||
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
|
||||
github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA=
|
||||
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
@@ -81,37 +82,37 @@ github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JT
|
||||
github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4=
|
||||
github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU=
|
||||
github.com/tsosunchia/powclient v0.1.4 h1:iAXUOiGPLJJTnzVSD0PY+4kBWm+SEMQZzd5ntEk1t0c=
|
||||
github.com/tsosunchia/powclient v0.1.4/go.mod h1:Pm4MP3QqN74SfNskPpFIEyT+NQrcABGoXkkeRwjlMEE=
|
||||
github.com/tsosunchia/powclient v0.1.5 h1:hpixFWoPbWSEC0zc9osSltyjtr1+SnhCueZVLkEpyyU=
|
||||
github.com/tsosunchia/powclient v0.1.5/go.mod h1:yNlzyq+w9llYZV+0q7nrX83ULy4ghq2mCjpTLJFJ2pg=
|
||||
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
|
||||
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
|
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a h1:Q8/wZp0KX97QFTc2ywcOE0YRjZPVIx+MXInMzdvQqcA=
|
||||
golang.org/x/exp v0.0.0-20240119083558-1b970713d09a/go.mod h1:idGWGoKP1toJGkd5/ig9ZLuPcZBC3ewk7SzmH0uou08=
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842 h1:vr/HnozRka3pE4EsMEg1lgkXJkTFJCVUX+S/ZT6wYzM=
|
||||
golang.org/x/exp v0.0.0-20240506185415-9bf2ced13842/go.mod h1:XtvwrStGgqGPLc4cjQfWqZHG1YFdYs6swckp8vpsjnc=
|
||||
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
|
||||
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.22.0 h1:9sGLhx7iRIHEiX0oAJ3MRZMUCElJgy7Br1nO+AMN3Tc=
|
||||
golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg=
|
||||
golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac=
|
||||
golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ=
|
||||
golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
|
||||
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
|
||||
golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y=
|
||||
golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
|
||||
golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk=
|
||||
golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
|
||||
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/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
|
||||
@@ -16,13 +16,13 @@ import (
|
||||
// )
|
||||
|
||||
func TestXxx(t *testing.T) {
|
||||
const ID_FIXED_HEADER = "10"
|
||||
const IdFixedHeader = "10"
|
||||
var processID = fmt.Sprintf("%07b", os.Getpid()&0x7f) //取进程ID的前7位
|
||||
var ttl = fmt.Sprintf("%06b", 95) //取TTL的后6位
|
||||
fmt.Println(os.Getpid()&0x7f, 95)
|
||||
|
||||
var parity int
|
||||
id := ID_FIXED_HEADER + processID + ttl
|
||||
id := IdFixedHeader + processID + ttl
|
||||
for _, c := range id {
|
||||
if c == '1' {
|
||||
parity++
|
||||
@@ -33,8 +33,8 @@ func TestXxx(t *testing.T) {
|
||||
} else {
|
||||
id += "0"
|
||||
}
|
||||
process_id, ttl_r, _ := reverseID(id)
|
||||
log.Println(process_id, ttl_r)
|
||||
processId, ttlR, _ := reverseID(id)
|
||||
log.Println(processId, ttlR)
|
||||
}
|
||||
|
||||
func TestFilter(t *testing.T) {
|
||||
|
||||
@@ -33,19 +33,19 @@ func IPInfoLocal(ip string, _ time.Duration, _ string, _ bool) (*IPGeoData, erro
|
||||
return &IPGeoData{}, errors.New("no results")
|
||||
}
|
||||
recordMap := record.(map[string]interface{})
|
||||
country_name := recordMap["country_name"].(string)
|
||||
countryName := recordMap["country_name"].(string)
|
||||
prov := ""
|
||||
if recordMap["country"].(string) == "HK" {
|
||||
country_name = "China"
|
||||
countryName = "China"
|
||||
prov = "Hong Kong"
|
||||
}
|
||||
if recordMap["country"].(string) == "TW" {
|
||||
country_name = "China"
|
||||
countryName = "China"
|
||||
prov = "Taiwan"
|
||||
}
|
||||
return &IPGeoData{
|
||||
Asnumber: strings.TrimPrefix(recordMap["asn"].(string), "AS"),
|
||||
Country: country_name,
|
||||
Country: countryName,
|
||||
City: "",
|
||||
Prov: prov,
|
||||
Owner: recordMap["as_name"].(string),
|
||||
|
||||
@@ -80,12 +80,12 @@ func PrintTraceRouteNav(ip net.IP, domain string, dataOrigin string, maxHops int
|
||||
fmt.Println("IP Geo Data Provider: " + dataOrigin)
|
||||
if util.EnableHidDstIP == "" {
|
||||
if ip.String() == domain {
|
||||
fmt.Printf("traceroute to %s, %d hops max, %d bytes packets\n", ip.String(), maxHops, packetSize)
|
||||
fmt.Printf("traceroute to %s, %d hops max, %d bytes payload\n", ip.String(), maxHops, packetSize)
|
||||
} else {
|
||||
fmt.Printf("traceroute to %s (%s), %d hops max, %d bytes packets\n", ip.String(), domain, maxHops, packetSize)
|
||||
fmt.Printf("traceroute to %s (%s), %d hops max, %d bytes payload\n", ip.String(), domain, maxHops, packetSize)
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("traceroute to %s, %d hops max, %d bytes packets\n", util.HideIPPart(ip.String()), maxHops, packetSize)
|
||||
fmt.Printf("traceroute to %s, %d hops max, %d bytes payload\n", util.HideIPPart(ip.String()), maxHops, packetSize)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -150,10 +150,10 @@ func (t *ICMPTracer) listenICMP() {
|
||||
}
|
||||
continue
|
||||
}
|
||||
ttl := int(msg.Msg[36])
|
||||
packet_id := strconv.FormatInt(int64(binary.BigEndian.Uint16(msg.Msg[32:34])), 2)
|
||||
if process_id, _, err := reverseID(packet_id); err == nil {
|
||||
if process_id == int64(os.Getpid()&0x7f) {
|
||||
ttl := int64(binary.BigEndian.Uint16(msg.Msg[34:36]))
|
||||
packetId := strconv.FormatInt(int64(binary.BigEndian.Uint16(msg.Msg[32:34])), 2)
|
||||
if processId, _, err := reverseID(packetId); err == nil {
|
||||
if processId == int64(os.Getpid()&0x7f) {
|
||||
dstip := net.IP(msg.Msg[24:28])
|
||||
if dstip.Equal(t.DestIP) || dstip.Equal(net.IPv4zero) {
|
||||
// 匹配再继续解析包,否则直接丢弃
|
||||
@@ -202,13 +202,13 @@ func (t *ICMPTracer) handleICMPMessage(msg ReceivedMessage, icmpType int8, data
|
||||
}
|
||||
}
|
||||
|
||||
func gernerateID(ttl_int int) int {
|
||||
const ID_FIXED_HEADER = "10"
|
||||
func gernerateID(ttlInt int) int {
|
||||
const IdFixedHeader = "10"
|
||||
var processID = fmt.Sprintf("%07b", os.Getpid()&0x7f) //取进程ID的前7位
|
||||
var ttl = fmt.Sprintf("%06b", ttl_int) //取TTL的后6位
|
||||
var ttl = fmt.Sprintf("%06b", ttlInt) //取TTL的后6位
|
||||
|
||||
var parity int
|
||||
id := ID_FIXED_HEADER + processID + ttl
|
||||
id := IdFixedHeader + processID + ttl
|
||||
for _, c := range id {
|
||||
if c == '1' {
|
||||
parity++
|
||||
@@ -271,7 +271,8 @@ func (t *ICMPTracer) send(ttl int) error {
|
||||
id := gernerateID(0)
|
||||
// log.Println("发送的", id)
|
||||
|
||||
data := []byte{byte(ttl)}
|
||||
//data := []byte{byte(ttl)}
|
||||
data := []byte{byte(0)}
|
||||
data = append(data, bytes.Repeat([]byte{1}, t.Config.PktSize-5)...)
|
||||
data = append(data, 0x00, 0x00, 0x4f, 0xff)
|
||||
|
||||
@@ -285,7 +286,10 @@ func (t *ICMPTracer) send(ttl int) error {
|
||||
},
|
||||
}
|
||||
|
||||
ipv4.NewPacketConn(t.icmpListen).SetTTL(ttl)
|
||||
err := ipv4.NewPacketConn(t.icmpListen).SetTTL(ttl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
wb, err := icmpHeader.Marshal(nil)
|
||||
if err != nil {
|
||||
@@ -327,7 +331,10 @@ func (t *ICMPTracer) send(ttl int) error {
|
||||
|
||||
t.fetchLock.Lock()
|
||||
defer t.fetchLock.Unlock()
|
||||
h.fetchIPData(t.Config)
|
||||
err := h.fetchIPData(t.Config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.res.add(h)
|
||||
case <-time.After(t.Timeout):
|
||||
|
||||
@@ -171,10 +171,10 @@ func (t *ICMPTracerv6) listenICMP() {
|
||||
}
|
||||
|
||||
}
|
||||
ttl := int(msg.Msg[56])
|
||||
packet_id := strconv.FormatInt(int64(binary.BigEndian.Uint16(msg.Msg[52:54])), 2)
|
||||
if process_id, _, err := reverseID(packet_id); err == nil {
|
||||
if process_id == int64(os.Getpid()&0x7f) {
|
||||
ttl := int64(binary.BigEndian.Uint16(msg.Msg[54:56]))
|
||||
packetId := strconv.FormatInt(int64(binary.BigEndian.Uint16(msg.Msg[52:54])), 2)
|
||||
if processId, _, err := reverseID(packetId); err == nil {
|
||||
if processId == int64(os.Getpid()&0x7f) {
|
||||
dstip := net.IP(msg.Msg[32:48])
|
||||
// 无效包本地环回包
|
||||
if dstip.String() == "::" {
|
||||
@@ -264,7 +264,8 @@ func (t *ICMPTracerv6) send(ttl int) error {
|
||||
//id := gernerateID(ttl)
|
||||
id := gernerateID(0)
|
||||
|
||||
data := []byte{byte(ttl)}
|
||||
//data := []byte{byte(ttl)}
|
||||
data := []byte{byte(0)}
|
||||
data = append(data, bytes.Repeat([]byte{1}, t.Config.PktSize-5)...)
|
||||
data = append(data, 0x00, 0x00, 0x4f, 0xff)
|
||||
|
||||
@@ -281,7 +282,10 @@ func (t *ICMPTracerv6) send(ttl int) error {
|
||||
p := ipv6.NewPacketConn(t.icmpListen)
|
||||
|
||||
icmpHeader.Body.(*icmp.Echo).Seq = ttl
|
||||
p.SetHopLimit(ttl)
|
||||
err := p.SetHopLimit(ttl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
wb, err := icmpHeader.Marshal(nil)
|
||||
if err != nil {
|
||||
@@ -323,7 +327,10 @@ func (t *ICMPTracerv6) send(ttl int) error {
|
||||
|
||||
t.fetchLock.Lock()
|
||||
defer t.fetchLock.Unlock()
|
||||
h.fetchIPData(t.Config)
|
||||
err := h.fetchIPData(t.Config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.res.add(h)
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ func ListenICMP(network string, laddr string) (net.PacketConn, error) {
|
||||
proto = syscall.IPPROTO_ICMPV6
|
||||
}
|
||||
|
||||
var ifIndex int = -1
|
||||
var ifIndex = -1
|
||||
if laddr != "" {
|
||||
la := net.ParseIP(laddr)
|
||||
if ifaces, err := net.Interfaces(); err == nil {
|
||||
@@ -70,11 +70,17 @@ func ListenICMP(network string, laddr string) (net.PacketConn, error) {
|
||||
if ifIndex != -1 {
|
||||
if proto == syscall.IPPROTO_ICMP {
|
||||
return c.Control(func(fd uintptr) {
|
||||
syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_BOUND_IF, ifIndex)
|
||||
err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IP, syscall.IP_BOUND_IF, ifIndex)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return c.Control(func(fd uintptr) {
|
||||
syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IPV6, syscall.IPV6_BOUND_IF, ifIndex)
|
||||
err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_IPV6, syscall.IPV6_BOUND_IF, ifIndex)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -217,6 +217,10 @@ func (t *TCPTracer) send(ttl int) error {
|
||||
DstIP: t.DestIP,
|
||||
Protocol: layers.IPProtocolTCP,
|
||||
TTL: uint8(ttl),
|
||||
//Flags: layers.IPv4DontFragment, // 我感觉没必要
|
||||
}
|
||||
if t.DontFragment {
|
||||
ipHeader.Flags = layers.IPv4DontFragment
|
||||
}
|
||||
// 使用Uint16兼容32位系统,防止在rand的时候因使用int32而溢出
|
||||
sequenceNumber := uint32(r.Intn(math.MaxUint16))
|
||||
@@ -237,9 +241,16 @@ func (t *TCPTracer) send(ttl int) error {
|
||||
|
||||
desiredPayloadSize := t.Config.PktSize
|
||||
payload := make([]byte, desiredPayloadSize)
|
||||
copy(buf.Bytes(), payload)
|
||||
// 设置随机种子
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
if err := gopacket.SerializeLayers(buf, opts, tcpHeader); err != nil {
|
||||
// 填充随机数
|
||||
for i := range payload {
|
||||
payload[i] = byte(rand.Intn(256))
|
||||
}
|
||||
//copy(buf.Bytes(), payload)
|
||||
|
||||
if err := gopacket.SerializeLayers(buf, opts, tcpHeader, gopacket.Payload(payload)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -293,7 +304,10 @@ func (t *TCPTracer) send(ttl int) error {
|
||||
|
||||
t.fetchLock.Lock()
|
||||
defer t.fetchLock.Unlock()
|
||||
h.fetchIPData(t.Config)
|
||||
err := h.fetchIPData(t.Config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.res.add(h)
|
||||
|
||||
|
||||
@@ -227,13 +227,20 @@ func (t *TCPTracerv6) send(ttl int) error {
|
||||
|
||||
desiredPayloadSize := t.Config.PktSize
|
||||
payload := make([]byte, desiredPayloadSize)
|
||||
copy(buf.Bytes(), payload)
|
||||
// 设置随机种子
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
if err := gopacket.SerializeLayers(buf, opts, tcpHeader); err != nil {
|
||||
// 填充随机数
|
||||
for i := range payload {
|
||||
payload[i] = byte(rand.Intn(256))
|
||||
}
|
||||
//copy(buf.Bytes(), payload)
|
||||
|
||||
if err := gopacket.SerializeLayers(buf, opts, tcpHeader, gopacket.Payload(payload)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
ipv6.NewPacketConn(t.tcp).SetHopLimit(ttl)
|
||||
err = ipv6.NewPacketConn(t.tcp).SetHopLimit(ttl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -42,6 +42,7 @@ type Config struct {
|
||||
AsyncPrinter func(res *Result)
|
||||
PktSize int
|
||||
Maptrace bool
|
||||
DontFragment bool
|
||||
}
|
||||
|
||||
type Method string
|
||||
@@ -81,6 +82,7 @@ func Traceroute(method Method, config Config) (*Result, error) {
|
||||
if config.DestIP.To4() != nil {
|
||||
tracer = &UDPTracer{Config: config}
|
||||
} else {
|
||||
//TODO: IPv6 UDP trace 在做了,指新建文件夹(
|
||||
return nil, errors.New("IPv6 UDP Traceroute is not supported")
|
||||
}
|
||||
case TCPTrace:
|
||||
|
||||
81
trace/udp.go
81
trace/udp.go
@@ -2,6 +2,7 @@ package trace
|
||||
|
||||
import (
|
||||
"log"
|
||||
"math/rand"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -167,47 +168,58 @@ func (t *UDPTracer) send(ttl int) error {
|
||||
}
|
||||
|
||||
srcIP, srcPort, udpConn := t.getUDPConn(0)
|
||||
defer udpConn.Close()
|
||||
|
||||
var payload []byte
|
||||
if t.Quic {
|
||||
payload = GenerateQuicPayloadWithRandomIds()
|
||||
} else {
|
||||
ipHeader := &layers.IPv4{
|
||||
SrcIP: srcIP,
|
||||
DstIP: t.DestIP,
|
||||
Protocol: layers.IPProtocolTCP,
|
||||
TTL: uint8(ttl),
|
||||
}
|
||||
|
||||
udpHeader := &layers.UDP{
|
||||
SrcPort: layers.UDPPort(srcPort),
|
||||
DstPort: layers.UDPPort(t.DestPort),
|
||||
}
|
||||
_ = udpHeader.SetNetworkLayerForChecksum(ipHeader)
|
||||
buf := gopacket.NewSerializeBuffer()
|
||||
opts := gopacket.SerializeOptions{
|
||||
ComputeChecksums: true,
|
||||
FixLengths: true,
|
||||
}
|
||||
|
||||
desiredPayloadSize := t.Config.PktSize
|
||||
payload := make([]byte, desiredPayloadSize)
|
||||
copy(buf.Bytes(), payload)
|
||||
|
||||
if err := gopacket.SerializeLayers(buf, opts, udpHeader); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
payload = buf.Bytes()
|
||||
//var payload []byte
|
||||
//if t.Quic {
|
||||
// payload = GenerateQuicPayloadWithRandomIds()
|
||||
//} else {
|
||||
ipHeader := &layers.IPv4{
|
||||
SrcIP: srcIP,
|
||||
DstIP: t.DestIP,
|
||||
Protocol: layers.IPProtocolUDP,
|
||||
TTL: uint8(ttl),
|
||||
}
|
||||
|
||||
udpHeader := &layers.UDP{
|
||||
SrcPort: layers.UDPPort(srcPort),
|
||||
DstPort: layers.UDPPort(t.DestPort),
|
||||
}
|
||||
_ = udpHeader.SetNetworkLayerForChecksum(ipHeader)
|
||||
buf := gopacket.NewSerializeBuffer()
|
||||
opts := gopacket.SerializeOptions{
|
||||
ComputeChecksums: true,
|
||||
FixLengths: true,
|
||||
}
|
||||
|
||||
desiredPayloadSize := t.Config.PktSize
|
||||
if desiredPayloadSize-8 > 0 {
|
||||
desiredPayloadSize -= 8
|
||||
}
|
||||
payload := make([]byte, desiredPayloadSize)
|
||||
// 设置随机种子
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
|
||||
// 填充随机数
|
||||
for i := range payload {
|
||||
payload[i] = byte(rand.Intn(256))
|
||||
}
|
||||
//copy(buf.Bytes(), payload)
|
||||
|
||||
if err := gopacket.SerializeLayers(buf, opts, udpHeader, gopacket.Payload(payload)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
//payload = buf.Bytes()
|
||||
//}
|
||||
|
||||
err = ipv4.NewPacketConn(udpConn).SetTTL(ttl)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
start := time.Now()
|
||||
if _, err := udpConn.WriteTo(payload, &net.UDPAddr{IP: t.DestIP, Port: t.DestPort}); err != nil {
|
||||
if _, err := udpConn.WriteTo(buf.Bytes(), &net.UDPAddr{IP: t.DestIP, Port: t.DestPort}); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -264,7 +276,10 @@ func (t *UDPTracer) send(ttl int) error {
|
||||
|
||||
t.fetchLock.Lock()
|
||||
defer t.fetchLock.Unlock()
|
||||
h.fetchIPData(t.Config)
|
||||
err := h.fetchIPData(t.Config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
t.res.add(h)
|
||||
|
||||
|
||||
@@ -27,8 +27,8 @@ func RealtimePrinter(res *trace.Result, ttl int) {
|
||||
multiWriter := io.MultiWriter(os.Stdout, f)
|
||||
log.SetOutput(multiWriter)
|
||||
log.SetFlags(0)
|
||||
var res_str string
|
||||
res_str += fmt.Sprintf("%-2d ", ttl+1)
|
||||
var resStr string
|
||||
resStr += fmt.Sprintf("%-2d ", ttl+1)
|
||||
|
||||
// 去重
|
||||
var latestIP string
|
||||
@@ -56,28 +56,28 @@ func RealtimePrinter(res *trace.Result, ttl int) {
|
||||
}
|
||||
|
||||
if latestIP == "" {
|
||||
res_str += fmt.Sprintf("%s\n", "*")
|
||||
log.Print(res_str)
|
||||
resStr += fmt.Sprintf("%s\n", "*")
|
||||
log.Print(resStr)
|
||||
return
|
||||
}
|
||||
|
||||
var blockDisplay = false
|
||||
for ip, v := range tmpMap {
|
||||
if blockDisplay {
|
||||
res_str += fmt.Sprintf("%4s", "")
|
||||
resStr += fmt.Sprintf("%4s", "")
|
||||
}
|
||||
if net.ParseIP(ip).To4() == nil {
|
||||
res_str += fmt.Sprintf("%-25s ", ip)
|
||||
resStr += fmt.Sprintf("%-25s ", ip)
|
||||
} else {
|
||||
res_str += fmt.Sprintf("%-15s ", ip)
|
||||
resStr += fmt.Sprintf("%-15s ", ip)
|
||||
}
|
||||
|
||||
i, _ := strconv.Atoi(v[0])
|
||||
|
||||
if res.Hops[ttl][i].Geo.Asnumber != "" {
|
||||
res_str += fmt.Sprintf("AS%-7s", res.Hops[ttl][i].Geo.Asnumber)
|
||||
resStr += fmt.Sprintf("AS%-7s", res.Hops[ttl][i].Geo.Asnumber)
|
||||
} else {
|
||||
res_str += fmt.Sprintf(" %-8s", "*")
|
||||
resStr += fmt.Sprintf(" %-8s", "*")
|
||||
}
|
||||
|
||||
if net.ParseIP(ip).To4() != nil {
|
||||
@@ -89,7 +89,7 @@ func RealtimePrinter(res *trace.Result, ttl int) {
|
||||
if whoisFormat[0] != "" {
|
||||
whoisFormat[0] = "[" + whoisFormat[0] + "]"
|
||||
}
|
||||
res_str += fmt.Sprintf("%-16s", whoisFormat[0])
|
||||
resStr += fmt.Sprintf("%-16s", whoisFormat[0])
|
||||
}
|
||||
|
||||
if res.Hops[ttl][i].Geo.Country == "" {
|
||||
@@ -98,19 +98,19 @@ func RealtimePrinter(res *trace.Result, ttl int) {
|
||||
|
||||
if net.ParseIP(ip).To4() != nil {
|
||||
|
||||
res_str += fmt.Sprintf(" %s %s %s %s %-6s\n %-39s ", res.Hops[ttl][i].Geo.Country, res.Hops[ttl][i].Geo.Prov, res.Hops[ttl][i].Geo.City, res.Hops[ttl][i].Geo.District, res.Hops[ttl][i].Geo.Owner, res.Hops[ttl][i].Hostname)
|
||||
resStr += fmt.Sprintf(" %s %s %s %s %-6s\n %-39s ", res.Hops[ttl][i].Geo.Country, res.Hops[ttl][i].Geo.Prov, res.Hops[ttl][i].Geo.City, res.Hops[ttl][i].Geo.District, res.Hops[ttl][i].Geo.Owner, res.Hops[ttl][i].Hostname)
|
||||
} else {
|
||||
res_str += fmt.Sprintf(" %s %s %s %s %-6s\n %-35s ", res.Hops[ttl][i].Geo.Country, res.Hops[ttl][i].Geo.Prov, res.Hops[ttl][i].Geo.City, res.Hops[ttl][i].Geo.District, res.Hops[ttl][i].Geo.Owner, res.Hops[ttl][i].Hostname)
|
||||
resStr += fmt.Sprintf(" %s %s %s %s %-6s\n %-35s ", res.Hops[ttl][i].Geo.Country, res.Hops[ttl][i].Geo.Prov, res.Hops[ttl][i].Geo.City, res.Hops[ttl][i].Geo.District, res.Hops[ttl][i].Geo.Owner, res.Hops[ttl][i].Hostname)
|
||||
}
|
||||
|
||||
for j := 1; j < len(v); j++ {
|
||||
if len(v) == 2 || j == 1 {
|
||||
res_str += v[j]
|
||||
resStr += v[j]
|
||||
} else {
|
||||
res_str += fmt.Sprintf("/ %s", v[j])
|
||||
resStr += fmt.Sprintf("/ %s", v[j])
|
||||
}
|
||||
}
|
||||
log.Print(res_str)
|
||||
log.Print(resStr)
|
||||
blockDisplay = true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ func newDoTResolver(serverName string, addrs string) *net.Resolver {
|
||||
Timeout: 1000 * time.Millisecond,
|
||||
}
|
||||
|
||||
tls_config := &tls.Config{
|
||||
tlsConfig := &tls.Config{
|
||||
// 设置 TLS Server Name 以确保证书能和域名对应
|
||||
ServerName: serverName,
|
||||
}
|
||||
@@ -26,7 +26,7 @@ func newDoTResolver(serverName string, addrs string) *net.Resolver {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return tls.Client(conn, tls_config), nil
|
||||
return tls.Client(conn, tlsConfig), nil
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user