mirror of
https://github.com/nxtrace/NTrace-core.git
synced 2025-08-12 06:26:39 +00:00
Compare commits
84 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ea2a6b596a | ||
|
|
2e9428ce76 | ||
|
|
052fe2dc06 | ||
|
|
24b7dae2d1 | ||
|
|
849cf488aa | ||
|
|
a539a4e079 | ||
|
|
efc19c4b7d | ||
|
|
f0a6c826fc | ||
|
|
9e05065a79 | ||
|
|
ade34e964a | ||
|
|
486cdfdc03 | ||
|
|
3260753a66 | ||
|
|
0c44e39a20 | ||
|
|
47870b1d9a | ||
|
|
57346f9db8 | ||
|
|
026460545f | ||
|
|
29b81d00ae | ||
|
|
c1cd80232a | ||
|
|
9c4505f9c7 | ||
|
|
e27c8bea77 | ||
|
|
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 | ||
|
|
ea60a671f2 | ||
|
|
0d6e894a4b | ||
|
|
20069ab9f3 | ||
|
|
4f05b57fc2 | ||
|
|
190111f6da | ||
|
|
c6eb9bbd2e | ||
|
|
cbc511f097 | ||
|
|
66422c4661 | ||
|
|
b6828b4db1 | ||
|
|
0a750bc6d0 | ||
|
|
47612c022d | ||
|
|
42bf45c2c8 | ||
|
|
8ac1a6bacd | ||
|
|
f96c3e5139 | ||
|
|
c46907b881 | ||
|
|
7afc4c5104 | ||
|
|
27e560fbde | ||
|
|
1dc18cfff8 | ||
|
|
b16dabac7c | ||
|
|
760e751076 | ||
|
|
a82be1b5cf | ||
|
|
4ba76c97fe | ||
|
|
9900bff41a | ||
|
|
e81a8f9fdc | ||
|
|
e3346ff901 | ||
|
|
70034a81f8 | ||
|
|
eb0ac2565d | ||
|
|
757ff4232b | ||
|
|
4dda237a57 | ||
|
|
cfec8df6a4 |
4
.github/workflows/build.yml
vendored
4
.github/workflows/build.yml
vendored
@@ -135,7 +135,7 @@ jobs:
|
||||
- name: Set up Go
|
||||
uses: actions/setup-go@v5
|
||||
with:
|
||||
go-version: '1.21'
|
||||
go-version: '1.22'
|
||||
- name: Get project dependencies
|
||||
run: go mod download
|
||||
- name: Build
|
||||
@@ -153,7 +153,7 @@ jobs:
|
||||
dist/${{ env.ASSET_NAME }}
|
||||
- name: Release
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
uses: softprops/action-gh-release@v1
|
||||
uses: softprops/action-gh-release@v2
|
||||
with: # 将下述可执行文件 release 上去
|
||||
draft: true # Release草稿
|
||||
files: |
|
||||
|
||||
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.21'
|
||||
check-latest: true
|
||||
go-version: '1.22'
|
||||
- name: Checkout codebase
|
||||
uses: actions/checkout@v4
|
||||
- name: Test with unix
|
||||
|
||||
56
README.md
56
README.md
@@ -24,9 +24,6 @@
|
||||
<a href="https://www.nxtrace.org/downloads">
|
||||
<img src="https://img.shields.io/github/release/nxtrace/Ntrace-V1/all.svg?style=flat-square">
|
||||
</a>
|
||||
<a href="https://telegram.dog/sjprojects">
|
||||
<img src="https://img.shields.io/endpoint?color=neon&style=flat-square&url=https%3A%2F%2Ftg.sumanjay.workers.dev%2Fnexttrace">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## IAAS Sponsor
|
||||
@@ -70,7 +67,12 @@ Please note, there are exceptions to this synchronization. If a version of NTrac
|
||||
```shell
|
||||
yay -S nexttrace-bin
|
||||
```
|
||||
* The AUR builds are maintained by ouuan
|
||||
* Build from source (only supports amd64)
|
||||
|
||||
```shell
|
||||
yay -S nexttrace
|
||||
```
|
||||
* The AUR builds are maintained by ouuan, huyz
|
||||
* Linuxbrew's installation command
|
||||
|
||||
Same as the macOS Homebrew's installation method (homebrew-core version only supports amd64)
|
||||
@@ -240,6 +242,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』」
|
||||
@@ -292,7 +297,7 @@ nexttrace -T -q 2 --parallel-requests 1 -t -P 2001:4860:4860::8888
|
||||
|
||||
### IP Database
|
||||
|
||||
#### We use [bgp.tools](https://bgp.tools) as a data provider for routing tables.
|
||||
We use [bgp.tools](https://bgp.tools) as a data provider for routing tables.
|
||||
|
||||
NextTrace BackEnd is now open-source.
|
||||
|
||||
@@ -332,16 +337,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
|
||||
@@ -353,9 +352,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
|
||||
@@ -382,16 +381,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]
|
||||
@@ -399,6 +397,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
|
||||
@@ -421,6 +421,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.
|
||||
@@ -440,12 +448,14 @@ We hope you can give us as much feedback as possible on IP geolocation errors (s
|
||||
|
||||
## JetBrain Support
|
||||
|
||||
#### This Project uses [JetBrain Open-Source Project License](https://jb.gg/OpenSourceSupport). We Proudly Develop By Goland.
|
||||
This Project uses [JetBrain Open-Source Project License](https://jb.gg/OpenSourceSupport). We Proudly Develop By `Goland`.
|
||||
|
||||
<img src="https://resources.jetbrains.com/storage/products/company/brand/logos/GoLand.png" title="" alt="GoLand logo" width="331">
|
||||
|
||||
## Credits
|
||||
|
||||
[Gubo](https://www.gubo.org) Reliable Host Recommendation Website
|
||||
|
||||
[IPInfo](https://ipinfo.io) Provided most of the data support for this project free of charge
|
||||
|
||||
[BGP.TOOLS](https://bgp.tools) Provided some data support for this project free of charge
|
||||
@@ -475,7 +485,7 @@ We hope you can give us as much feedback as possible on IP geolocation errors (s
|
||||
Although other third-party APIs are integrated in this project, please refer to the official website of the third-party APIs for specific TOS and AUP. If you encounter IP data errors, please contact them directly to correct them.
|
||||
|
||||
For feedback related to corrections about IP information, we currently have two channels available:
|
||||
>- [IP 错误报告汇总帖](https://github.com/nxtrace/NTrace-core/issues/41) in the GITHUB ISSUES section of this project (Recommended)
|
||||
>- [IP 错误报告汇总帖](https://github.com/orgs/nxtrace/discussions/222) in the GITHUB ISSUES section of this project (Recommended)
|
||||
>- This project's dedicated correction email: `correction@nxtrace.org` (Please note that this email is only for correcting IP-related information. For other feedback, please submit an ISSUE)
|
||||
|
||||
How to obtain the freshly baked binary executable of the latest commit?
|
||||
|
||||
@@ -25,9 +25,6 @@
|
||||
<a href="https://www.nxtrace.org/downloads">
|
||||
<img src="https://img.shields.io/github/release/nxtrace/Ntrace-V1/all.svg?style=flat-square">
|
||||
</a>
|
||||
<a href="https://telegram.dog/sjprojects">
|
||||
<img src="https://img.shields.io/endpoint?color=neon&style=flat-square&url=https%3A%2F%2Ftg.sumanjay.workers.dev%2Fnexttrace">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
## IAAS Sponsor
|
||||
@@ -63,8 +60,6 @@ Document Language: [English](README.md) | 简体中文
|
||||
|
||||
使用 NextTrace 之前,我们建议您先阅读 [#IP 数据以及精准度说明](https://github.com/nxtrace/NTrace-core/blob/main/README_zh_CN.md#ip-%E6%95%B0%E6%8D%AE%E4%BB%A5%E5%8F%8A%E7%B2%BE%E5%87%86%E5%BA%A6%E8%AF%B4%E6%98%8E),在了解您自己的对数据精准度需求以后再进行抉择。
|
||||
|
||||
[NextTrace 的Telegram频道](https://t.me/nexttrace)由项目成员负责,会传递一部分通知,也会发布一些成员自己分享的小工具。项目成员的意见可作为未来项目发展的可能方向,随着开发进度变化可能会有所改动,不代表未来一定会实装,正式定稿公告会发布于 Issue 中。
|
||||
|
||||
### Automated Install
|
||||
|
||||
* Linux
|
||||
@@ -78,9 +73,14 @@ Document Language: [English](README.md) | 简体中文
|
||||
* 直接下载bin包(仅支持amd64)
|
||||
|
||||
```shell
|
||||
yay -S nexttrace-bin`
|
||||
yay -S nexttrace-bin
|
||||
```
|
||||
* AUR 的构建分别由 ouuan 维护
|
||||
* 从源码构建(仅支持amd64)
|
||||
|
||||
```shell
|
||||
yay -S nexttrace
|
||||
```
|
||||
* AUR 的构建分别由 ouuan, huyz 维护
|
||||
* Linuxbrew 安装命令
|
||||
|
||||
同macOS Homebrew安装方法(homebrew-core版仅支持amd64)
|
||||
@@ -232,7 +232,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
|
||||
```
|
||||
|
||||
@@ -256,6 +256,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』」
|
||||
@@ -331,16 +334,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
|
||||
@@ -352,9 +349,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
|
||||
@@ -381,16 +378,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]
|
||||
@@ -398,6 +394,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
|
||||
```
|
||||
|
||||
## 项目截图
|
||||
@@ -431,8 +429,7 @@ nexttrace --pow-provider sakura
|
||||
|
||||
## OpenTrace
|
||||
|
||||
`OpenTrace`是 @Archeb 开发的`NextTrace`的跨平台`GUI`版本,带来您熟悉但更强大的用户体验。
|
||||
|
||||
`OpenTrace`是 @Archeb 开发的`NextTrace`的跨平台`GUI`版本,带来您熟悉但更强大的用户体验。
|
||||
该软件仍然处于早期开发阶段,可能存在许多缺陷和错误,需要您宝贵的使用反馈。
|
||||
|
||||
[https://github.com/Archeb/opentrace](https://github.com/Archeb/opentrace)
|
||||
@@ -443,8 +440,24 @@ 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>
|
||||
|
||||
## JetBrain Support
|
||||
|
||||
本项目受 [JetBrain Open-Source Project License](https://jb.gg/OpenSourceSupport) 支持。 很高兴使用`Goland`作为我们的开发工具。
|
||||
|
||||
<img src="https://resources.jetbrains.com/storage/products/company/brand/logos/GoLand.png" title="" alt="GoLand logo" width="331">
|
||||
|
||||
## Credits
|
||||
|
||||
[Gubo](https://www.gubo.org) 靠谱主机推荐
|
||||
|
||||
[IPInfo](https://ipinfo.io) 无偿提供了本项目大部分数据支持
|
||||
|
||||
[BGP.TOOLS](https://bgp.tools) 无偿提供了本项目的一些数据支持
|
||||
@@ -479,7 +492,7 @@ nexttrace --pow-provider sakura
|
||||
## IP 数据以及精准度说明
|
||||
|
||||
对于IP相关信息的纠错反馈,我们目前开放了两个渠道:
|
||||
>- 本项目的GITHUB ISSUES区中的[IP 错误报告汇总帖](https://github.com/nxtrace/NTrace-core/issues/41)
|
||||
>- 本项目的GITHUB ISSUES区中的[IP 错误报告汇总帖](https://github.com/orgs/nxtrace/discussions/222)
|
||||
>- 本项目的纠错专用邮箱: `correction@nxtrace.org` (请注意此邮箱仅供IP相关信息纠错专用,其他反馈请发送ISSUE)
|
||||
|
||||
NextTrace 有多个数据源可以选择,目前默认使用的 LeoMoeAPI 为我们项目维护的数据源。
|
||||
|
||||
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" {
|
||||
|
||||
@@ -2,6 +2,7 @@ package fastTrace
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/fatih/color"
|
||||
"github.com/nxtrace/NTrace-core/ipgeo"
|
||||
"github.com/nxtrace/NTrace-core/printer"
|
||||
"github.com/nxtrace/NTrace-core/trace"
|
||||
@@ -16,7 +17,7 @@ import (
|
||||
//var pFastTracer ParamsFastTrace
|
||||
|
||||
func (f *FastTracer) tracert_v6(location string, ispCollection ISPCollection) {
|
||||
fmt.Printf("%s『%s %s 』%s\n", printer.YELLOW_PREFIX, location, ispCollection.ISPName, printer.RESET_PREFIX)
|
||||
fmt.Fprintf(color.Output, "%s\n", color.New(color.FgYellow, color.Bold).Sprintf("『%s %s 』", location, ispCollection.ISPName))
|
||||
fmt.Printf("traceroute to %s, %d hops max, %d byte packets\n", ispCollection.IPv6, f.ParamsFastTrace.MaxHops, f.ParamsFastTrace.PktSize)
|
||||
|
||||
ip, err := util.DomainLookUp(ispCollection.IPv6, "6", "", true)
|
||||
@@ -39,6 +40,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 {
|
||||
|
||||
@@ -3,6 +3,7 @@ package fastTrace
|
||||
import (
|
||||
"bufio"
|
||||
"fmt"
|
||||
"github.com/fatih/color"
|
||||
"github.com/nxtrace/NTrace-core/ipgeo"
|
||||
"github.com/nxtrace/NTrace-core/printer"
|
||||
"github.com/nxtrace/NTrace-core/trace"
|
||||
@@ -33,6 +34,7 @@ type ParamsFastTrace struct {
|
||||
PktSize int
|
||||
Timeout time.Duration
|
||||
File string
|
||||
DontFragment bool
|
||||
}
|
||||
|
||||
type IpListElement struct {
|
||||
@@ -44,7 +46,7 @@ type IpListElement struct {
|
||||
var oe = false
|
||||
|
||||
func (f *FastTracer) tracert(location string, ispCollection ISPCollection) {
|
||||
fmt.Printf("%s『%s %s 』%s\n", printer.YELLOW_PREFIX, location, ispCollection.ISPName, printer.RESET_PREFIX)
|
||||
fmt.Fprintf(color.Output, "%s\n", color.New(color.FgYellow, color.Bold).Sprintf("『%s %s 』", location, ispCollection.ISPName))
|
||||
fmt.Printf("traceroute to %s, %d hops max, %d byte packets\n", ispCollection.IP, f.ParamsFastTrace.MaxHops, f.ParamsFastTrace.PktSize)
|
||||
|
||||
ip, err := util.DomainLookUp(ispCollection.IP, "4", "", true)
|
||||
@@ -67,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 {
|
||||
@@ -274,8 +277,14 @@ func testFile(paramsFastTrace ParamsFastTrace, tm bool) {
|
||||
}
|
||||
|
||||
for _, ip := range ipList {
|
||||
fmt.Printf("%s『%s』%s\n", printer.YELLOW_PREFIX, ip.Desc, printer.RESET_PREFIX)
|
||||
fmt.Printf("traceroute to %s, %d hops max, %d byte packets\n", ip.Ip, paramsFastTrace.MaxHops, paramsFastTrace.PktSize)
|
||||
fmt.Fprintf(color.Output, "%s\n",
|
||||
color.New(color.FgYellow, color.Bold).Sprint("『 "+ip.Desc+"』"),
|
||||
)
|
||||
if util.EnableHidDstIP == "" {
|
||||
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 payload\n", util.HideIPPart(ip.Ip), paramsFastTrace.MaxHops, paramsFastTrace.PktSize)
|
||||
}
|
||||
var srcAddr string
|
||||
if ip.Version4 {
|
||||
if paramsFastTrace.SrcDev != "" {
|
||||
|
||||
32
go.mod
32
go.mod
@@ -1,17 +1,17 @@
|
||||
module github.com/nxtrace/NTrace-core
|
||||
|
||||
go 1.21
|
||||
go 1.22.3
|
||||
|
||||
require (
|
||||
github.com/akamensky/argparse v1.4.0
|
||||
github.com/google/gopacket v1.1.19
|
||||
github.com/oschwald/maxminddb-golang v1.12.0
|
||||
github.com/spf13/viper v1.18.2
|
||||
github.com/stretchr/testify v1.8.4
|
||||
github.com/oschwald/maxminddb-golang v1.13.1
|
||||
github.com/spf13/viper v1.19.0
|
||||
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.19.0
|
||||
golang.org/x/sync v0.5.0
|
||||
github.com/tsosunchia/powclient v0.1.5
|
||||
golang.org/x/net v0.27.0
|
||||
golang.org/x/sync v0.7.0
|
||||
)
|
||||
|
||||
require (
|
||||
@@ -22,9 +22,9 @@ 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/locafero v0.6.0 // indirect
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
|
||||
github.com/sourcegraph/conc v0.3.0 // indirect
|
||||
github.com/spf13/afero v1.11.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-20231219180239-dc181d75b848 // indirect
|
||||
golang.org/x/text v0.14.0 // indirect
|
||||
golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 // indirect
|
||||
golang.org/x/text v0.16.0 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
)
|
||||
|
||||
require (
|
||||
github.com/fatih/color v1.16.0
|
||||
github.com/gorilla/websocket v1.5.1
|
||||
github.com/fatih/color v1.17.0
|
||||
github.com/gorilla/websocket v1.5.2
|
||||
github.com/lionsoul2014/ip2region v2.11.2+incompatible
|
||||
github.com/rodaine/table v1.1.0
|
||||
github.com/tidwall/gjson v1.17.0
|
||||
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.15.0 // indirect
|
||||
golang.org/x/sys v0.22.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
)
|
||||
|
||||
79
go.sum
79
go.sum
@@ -4,18 +4,18 @@ 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=
|
||||
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
|
||||
github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/gopacket v1.1.19 h1:ves8RnFZPGiFnTS0uPQStjwru6uO6h+nlr9j6fL7kF8=
|
||||
github.com/google/gopacket v1.1.19/go.mod h1:iJ8V8n6KS+z2U1A8pUwu8bW5SyEMkXJB8Yo/Vo+TKTo=
|
||||
github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY=
|
||||
github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY=
|
||||
github.com/gorilla/websocket v1.5.2 h1:qoW6V1GT3aZxybsbC6oLnailWnB+qTMVwMreOso9XUw=
|
||||
github.com/gorilla/websocket v1.5.2/go.mod h1:0n9H61RBAcf5/38py2MCYbxzPIY9rOkpvvMT24Rqs30=
|
||||
github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4=
|
||||
github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ=
|
||||
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
|
||||
@@ -31,23 +31,25 @@ github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovk
|
||||
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
|
||||
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
|
||||
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
|
||||
github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0=
|
||||
github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI=
|
||||
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
|
||||
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
|
||||
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
|
||||
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/oschwald/maxminddb-golang v1.13.1 h1:G3wwjdN9JmIK2o/ermkHM+98oX5fS+k5MbwsmL4MRQE=
|
||||
github.com/oschwald/maxminddb-golang v1.13.1/go.mod h1:K4pgV9N/GcK694KSTmVSDTODk4IsCNThNdTmnaBZ/F8=
|
||||
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/rodaine/table v1.1.0 h1:/fUlCSdjamMY8VifdQRIu3VWZXYLY7QHFkVorS8NTr4=
|
||||
github.com/rodaine/table v1.1.0/go.mod h1:Qu3q5wi1jTQD6B6HsP6szie/S4w1QUQ8pq22pz9iL8g=
|
||||
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/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ=
|
||||
github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4=
|
||||
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.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.6.0 h1:ON7AQg37yzcRPU69mt7gwhFEBwxI6P9T4Qu3N51bwOk=
|
||||
github.com/sagikazarmark/locafero v0.6.0/go.mod h1:77OmuIc6VTraTXKXIs/uvUxKGUXjE1GbemJYHqdNjX0=
|
||||
github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE=
|
||||
github.com/sagikazarmark/slog-shim v0.1.0/go.mod h1:SrcSrq8aKtyuqEI1uvTDTK1arOWRIczQRv+GVI1AkeQ=
|
||||
github.com/sourcegraph/conc v0.3.0 h1:OQTbbt6P72L20UqAkXXuLOj79LfEanQ+YQFNpLA9ySo=
|
||||
@@ -58,58 +60,59 @@ github.com/spf13/cast v1.6.0 h1:GEiTHELF+vaR5dhz3VqZfFSzZjYbgeKDpBxQVS4GYJ0=
|
||||
github.com/spf13/cast v1.6.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo=
|
||||
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
|
||||
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
|
||||
github.com/spf13/viper v1.18.2 h1:LUXCnvUvSM6FXAsj6nnfc8Q2tp1dIgUfY9Kc8GsSOiQ=
|
||||
github.com/spf13/viper v1.18.2/go.mod h1:EKmWIqdnk5lOcmR72yw6hS+8OPYcwD0jteitLMVB+yk=
|
||||
github.com/spf13/viper v1.19.0 h1:RWq5SEjt8o25SROyN3z2OrDB9l7RPd3lwTWU8EcEdcI=
|
||||
github.com/spf13/viper v1.19.0/go.mod h1:GQUN9bilAbhU/jgc1bKs99f/suXKeUMct8Adx5+Ntkg=
|
||||
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/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
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 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
|
||||
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
|
||||
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
|
||||
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
|
||||
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
|
||||
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 h1:kdXcSzyDtseVEc4yCz2qF8ZrQvIDBJLl4S1c3GCXmoI=
|
||||
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
|
||||
github.com/tidwall/gjson v1.17.0 h1:/Jocvlh98kcTfpN2+JzGQWQcqrPQwDrVEMApx/M5ZwM=
|
||||
github.com/tidwall/gjson v1.17.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U=
|
||||
github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
|
||||
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
|
||||
github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM=
|
||||
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-20231219180239-dc181d75b848 h1:+iq7lrkxmFNBM7xx+Rae2W6uyPfhPeDWD+n+JgppptE=
|
||||
golang.org/x/exp v0.0.0-20231219180239-dc181d75b848/go.mod h1:iRJReGqOEeBhDZGkGbynYwcHlctCvnjTYIamk7uXpHI=
|
||||
golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8 h1:LoYXNGAShUG3m/ehNk4iFctuhGX/+R1ZpfJ4/ia80JM=
|
||||
golang.org/x/exp v0.0.0-20240604190554-fc45aab8b7f8/go.mod h1:jj3sYF3dwk5D+ghuXyeI3r5MFf+NT2An6/9dOA95KSI=
|
||||
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.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
|
||||
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
|
||||
golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys=
|
||||
golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE=
|
||||
golang.org/x/sync v0.5.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.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
|
||||
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
|
||||
golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI=
|
||||
golang.org/x/sys v0.22.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.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4=
|
||||
golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI=
|
||||
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=
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
const (
|
||||
ipDataBasePath = "./ip2region.db"
|
||||
defaultDownURL = "1"
|
||||
originURL = "https://ghproxy.com/?q=https://github.com/bqf9979/ip2region/blob/master/data/ip2region.db?raw=true"
|
||||
originURL = "https://mirror.ghproxy.com/?q=https://github.com/bqf9979/ip2region/blob/master/data/ip2region.db?raw=true"
|
||||
)
|
||||
|
||||
func downloadDataBase() error {
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
)
|
||||
|
||||
func IPApiCom(ip string, timeout time.Duration, _ string, _ bool) (*IPGeoData, error) {
|
||||
url := "http://ip-api.com/json/" + ip + "?fields=status,message,country,regionName,city,isp,district,as,lat,lon"
|
||||
url := token.BaseOrDefault("http://ip-api.com/json/") + ip + "?fields=status,message,country,regionName,city,isp,district,as,lat,lon"
|
||||
client := &http.Client{
|
||||
// 2 秒超时
|
||||
Timeout: timeout,
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
)
|
||||
|
||||
func IPInfo(ip string, timeout time.Duration, _ string, _ bool) (*IPGeoData, error) {
|
||||
url := "http://ipinfo.io/" + ip + "?token=" + token.ipinfo
|
||||
url := token.BaseOrDefault("http://ipinfo.io/") + ip + "?token=" + token.ipinfo
|
||||
client := &http.Client{
|
||||
// 2 秒超时
|
||||
Timeout: timeout,
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -13,7 +13,7 @@ func IPInSight(ip string, timeout time.Duration, _ string, _ bool) (*IPGeoData,
|
||||
// 2 秒超时
|
||||
Timeout: timeout,
|
||||
}
|
||||
resp, err := client.Get("https://api.ipinsight.io/ip/" + ip + "?token=" + token.ipinsight)
|
||||
resp, err := client.Get(token.BaseOrDefault("https://api.ipinsight.io/ip/") + ip + "?token=" + token.ipinsight)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
)
|
||||
|
||||
func IPSB(ip string, timeout time.Duration, _ string, _ bool) (*IPGeoData, error) {
|
||||
url := "https://api.ip.sb/geoip/" + ip
|
||||
url := token.BaseOrDefault("https://api.ip.sb/geoip/") + ip
|
||||
client := &http.Client{
|
||||
// 2 秒超时
|
||||
Timeout: timeout,
|
||||
|
||||
@@ -6,10 +6,19 @@ type tokenData struct {
|
||||
ipinsight string
|
||||
ipinfo string
|
||||
ipleo string
|
||||
baseUrl string
|
||||
}
|
||||
|
||||
func (t *tokenData) BaseOrDefault(def string) string {
|
||||
if t.baseUrl == "" {
|
||||
return def
|
||||
}
|
||||
return t.baseUrl
|
||||
}
|
||||
|
||||
var token = tokenData{
|
||||
ipinsight: util.GetenvDefault("NEXTTRACE_IPINSIGHT_TOKEN", ""),
|
||||
ipinfo: util.GetenvDefault("NEXTTRACE_IPINFO_TOKEN", ""),
|
||||
baseUrl: util.GetenvDefault("NEXTTRACE_IPAPI_BASE", ""),
|
||||
ipleo: "NextTraceDemo",
|
||||
}
|
||||
|
||||
@@ -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,9 +150,10 @@ func (t *ICMPTracer) listenICMP() {
|
||||
}
|
||||
continue
|
||||
}
|
||||
packet_id := strconv.FormatInt(int64(binary.BigEndian.Uint16(msg.Msg[32:34])), 2)
|
||||
if process_id, ttl, 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) {
|
||||
// 匹配再继续解析包,否则直接丢弃
|
||||
@@ -201,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++
|
||||
@@ -266,20 +267,29 @@ func (t *ICMPTracer) send(ttl int) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
id := gernerateID(ttl)
|
||||
//id := gernerateID(ttl)
|
||||
id := gernerateID(0)
|
||||
// log.Println("发送的", id)
|
||||
|
||||
//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)
|
||||
|
||||
icmpHeader := icmp.Message{
|
||||
Type: ipv4.ICMPTypeEcho, Code: 0,
|
||||
Body: &icmp.Echo{
|
||||
ID: id,
|
||||
//Data: []byte("HELLO-R-U-THERE"),
|
||||
Data: append(bytes.Repeat([]byte{1}, t.Config.PktSize-4), 0x00, 0x00, 0x4f, 0xff),
|
||||
Data: data,
|
||||
Seq: ttl,
|
||||
},
|
||||
}
|
||||
|
||||
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 {
|
||||
@@ -321,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,9 +171,10 @@ func (t *ICMPTracerv6) listenICMP() {
|
||||
}
|
||||
|
||||
}
|
||||
packet_id := strconv.FormatInt(int64(binary.BigEndian.Uint16(msg.Msg[52:54])), 2)
|
||||
if process_id, ttl, 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() == "::" {
|
||||
@@ -260,14 +261,20 @@ func (t *ICMPTracerv6) send(ttl int) error {
|
||||
if t.final != -1 && ttl > t.final {
|
||||
return nil
|
||||
}
|
||||
id := gernerateID(ttl)
|
||||
//id := gernerateID(ttl)
|
||||
id := gernerateID(0)
|
||||
|
||||
//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)
|
||||
|
||||
icmpHeader := icmp.Message{
|
||||
Type: ipv6.ICMPTypeEchoRequest, Code: 0,
|
||||
Body: &icmp.Echo{
|
||||
ID: id,
|
||||
//Data: []byte("HELLO-R-U-THERE"),
|
||||
Data: append(bytes.Repeat([]byte{1}, t.Config.PktSize-4), 0x00, 0x00, 0x4f, 0xff),
|
||||
Data: data,
|
||||
Seq: ttl,
|
||||
},
|
||||
}
|
||||
@@ -275,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 {
|
||||
@@ -317,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
|
||||
}
|
||||
|
||||
@@ -253,7 +264,7 @@ func (t *TCPTracer) send(ttl int) error {
|
||||
return err
|
||||
}
|
||||
t.inflightRequestLock.Lock()
|
||||
hopCh := make(chan Hop)
|
||||
hopCh := make(chan Hop, 1)
|
||||
t.inflightRequest[int(sequenceNumber)] = hopCh
|
||||
t.inflightRequestLock.Unlock()
|
||||
/*
|
||||
@@ -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
|
||||
}
|
||||
@@ -244,7 +251,7 @@ func (t *TCPTracerv6) send(ttl int) error {
|
||||
}
|
||||
// log.Println(ttl, sequenceNumber)
|
||||
t.inflightRequestLock.Lock()
|
||||
hopCh := make(chan Hop)
|
||||
hopCh := make(chan Hop, 1)
|
||||
t.inflightRequest[int(sequenceNumber)] = hopCh
|
||||
t.inflightRequestLock.Unlock()
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
85
trace/udp.go
85
trace/udp.go
@@ -2,6 +2,7 @@ package trace
|
||||
|
||||
import (
|
||||
"log"
|
||||
"math/rand"
|
||||
"net"
|
||||
"sync"
|
||||
"time"
|
||||
@@ -53,7 +54,7 @@ func (t *UDPTracer) Execute() (*Result, error) {
|
||||
go t.listenICMP()
|
||||
|
||||
t.sem = semaphore.NewWeighted(int64(t.ParallelRequests))
|
||||
for ttl := 1; ttl <= t.MaxHops; ttl++ {
|
||||
for ttl := t.BeginHop; ttl <= t.MaxHops; ttl++ {
|
||||
// 如果到达最终跳,则退出
|
||||
if t.final != -1 && ttl > t.final {
|
||||
break
|
||||
@@ -167,53 +168,64 @@ 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
|
||||
}
|
||||
|
||||
// 在对inflightRequest进行写操作的时候应该加锁保护,以免多个goroutine协程试图同时写入造成panic
|
||||
t.inflightRequestLock.Lock()
|
||||
hopCh := make(chan Hop)
|
||||
hopCh := make(chan Hop, 1)
|
||||
t.inflightRequest[srcPort] = hopCh
|
||||
t.inflightRequestLock.Unlock()
|
||||
defer func() {
|
||||
@@ -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
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -75,6 +75,12 @@ func GetFastIP(domain string, port string, enableOutput bool) string {
|
||||
)
|
||||
}
|
||||
//}
|
||||
|
||||
//有些时候真的啥都不通,还是挑一个顶上吧
|
||||
if result.IP == "" {
|
||||
result.IP = "45.88.195.154"
|
||||
}
|
||||
|
||||
FastIpCache = result.IP
|
||||
return result.IP
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user