Compare commits

..

76 Commits

Author SHA1 Message Date
zhshch2002
c4ea506c35 update: .macos_compil.sh 2022-06-06 10:32:09 +08:00
zhshch2002
39e2471845 add: macOS homebrew 编译脚本 2022-06-06 10:18:11 +08:00
sjlleo
18a9eefec9 Revert "Revert "update: 脚本运行不需要保存在本地""
This reverts commit 3f0b14341a.
2022-06-05 15:51:38 +08:00
sjlleo
1b743d1f17 Revert "update: 移除 wget 依赖"
This reverts commit 8f77050fca.
2022-06-05 15:51:10 +08:00
sjlleo
3f0b14341a Revert "update: 脚本运行不需要保存在本地"
This reverts commit 2ffd7fdb58.
2022-06-05 15:50:45 +08:00
sjlleo
2ffd7fdb58 update: 脚本运行不需要保存在本地 2022-06-05 14:33:30 +08:00
sjlleo
8f77050fca update: 移除 wget 依赖 2022-06-05 14:29:41 +08:00
sjlleo
65652bd4e2 fix: 小问题 2022-06-05 14:22:24 +08:00
sjlleo
4176407a8a update: 精简安装脚本 2022-06-05 14:19:00 +08:00
sjlleo
6bc4abeaf8 update: TCP/UDP路由跟踪时,将不会再显示IPv6 IP 2022-06-04 21:42:44 +08:00
sjlleo
af0d886a02 update: yaml.v2 should direct. 2022-06-04 21:41:49 +08:00
sjlleo
09fdd2ac37 update: 现在偏好设置支持自定义数据源、自定义显示模式,以及对部分描述不当的参数说明进行了修正 2022-06-04 21:25:56 +08:00
sjlleo
2b9d8176d4 update: 现在默认无需配置即可使用,对于高阶用户,可以使用-c生成属于自己的偏好 2022-06-04 20:28:58 +08:00
tsosunchia
ed2f89310f Update README.md 2022-06-04 17:15:23 +08:00
tsosunchia
bd5a8902d4 更改部分提示信息 2022-06-04 17:02:26 +08:00
tsosunchia
e2a1bfe8cf 把部分选项隐藏放进了--expert选项 2022-06-04 16:59:07 +08:00
zhshch2002
356b782b3d update: screenshot 2022-06-04 11:04:42 +08:00
zhshch2002
40922ae13a update: screenshot 2022-06-04 10:45:33 +08:00
tsosunchia
8e90795a54 Update nt_install.sh 2022-06-03 19:48:47 +08:00
sjlleo
bbbb2377e1 fix: 当有多个路由跟踪实例,且跟踪通一个IP的时候的干扰问题 2022-06-03 19:28:53 +08:00
sjlleo
efdfd9d612 fix: 修复一个多线程路由跟踪错乱的问题 2022-06-03 16:26:01 +08:00
sjlleo
016f06bafd cleanup 2022-06-02 21:51:50 +08:00
sjlleo
1049986ebc cleanup 2022-06-02 21:48:19 +08:00
tsosunchia
80a75288d2 由于9.0.0.0/8 以及11.0.0.0/8大量用于其他IDC业务,因此清除特殊标记 2022-06-02 20:38:43 +08:00
tsosunchia
986b8ce300 Merge remote-tracking branch 'refs/remotes/origin/main'
fetch README
2022-05-31 21:00:07 +08:00
tsosunchia
ab774406ac 减少一处警告 2022-05-31 20:59:56 +08:00
sjlleo
9604b7befe update: announcement 2022-05-31 20:48:39 +08:00
tsosunchia
dc6537005a fix some bugs 2022-05-31 19:41:12 +08:00
tsosunchia
839d227770 fix some bugs 2022-05-31 19:15:39 +08:00
tsosunchia
84e989e71b fix some bugs 2022-05-31 19:15:29 +08:00
tsosunchia
3b74b302cc fix some bugs 2022-05-31 18:35:59 +08:00
tsosunchia
9b0e58359f 改善脚本在国内环境下的表现 2022-05-31 18:27:22 +08:00
tsosunchia
f0d7151144 Update README.md 2022-05-31 18:21:31 +08:00
tsosunchia
3c65c29eff 改善脚本在国内环境下的表现 2022-05-31 18:14:51 +08:00
sjlleo
3aa4696fa9 add: 新增配置文件模块 2022-05-30 21:15:22 +08:00
sjlleo
b4abaffc7c update: 让截图大小适中 2022-05-28 11:09:45 +08:00
sjlleo
c96fb4efa3 update: IP Database Copyright的IP占比信息用表格显示 2022-05-28 10:47:03 +08:00
sjlleo
876de6bde1 update: 完善描述 2022-05-28 10:26:31 +08:00
tsosunchia
7dbec0c7a1 update README.md 增加提示 2022-05-28 02:52:27 +08:00
tsosunchia
d690f680f5 增加一些平台支持 2022-05-28 02:29:18 +08:00
tsosunchia
e96686013d 增加一些平台支持 2022-05-28 02:07:45 +08:00
tsosunchia
6726b55fc9 Update .cross_compile.sh 2022-05-28 01:58:23 +08:00
tsosunchia
9f29c75491 增加一些平台支持 2022-05-28 01:51:30 +08:00
tsosunchia
2f5bf3f195 优化提示 2022-05-28 00:40:37 +08:00
tsosunchia
5981e82ee3 fix some bugs 2022-05-28 00:31:58 +08:00
tsosunchia
80f7857a65 Merge pull request #30 from tsosunchia/main
fix some bugs
2022-05-27 23:44:14 +08:00
tsosunchia
700d38de1c fix some bugs 2022-05-27 23:43:21 +08:00
tsosunchia
2dbf3f04a4 Merge pull request #29 from tsosunchia/main
fix some bugs
2022-05-27 23:10:46 +08:00
tsosunchia
45df06ea80 fix some bugs 2022-05-27 23:10:07 +08:00
tsosunchia
98953048ce fix some bugs 2022-05-27 22:54:07 +08:00
tsosunchia
eddd4226b0 Merge pull request #28 from tsosunchia/main
修补BUG
2022-05-27 22:45:55 +08:00
tsosunchia
5afd9eb09e Merge remote-tracking branch 'refs/remotes/origin/main' 2022-05-27 22:43:55 +08:00
tsosunchia
70006aaa13 优化逻辑结构 2022-05-27 22:43:28 +08:00
tsosunchia
497fb647c0 Merge pull request #27 from tsosunchia/main
优化逻辑结构
2022-05-27 22:31:44 +08:00
tsosunchia
be8552c3cd 优化逻辑结构 2022-05-27 22:30:54 +08:00
sjlleo
f320fd6202 update: 优化逻辑,废弃 realtime 参数 2022-05-27 21:27:26 +08:00
sjlleo
a42c5e3734 update: ttl 从 1 开始 2022-05-27 21:26:47 +08:00
sjlleo
e6480c84e0 Revert "update: 优化打印逻辑,废除 realtime 参数"
This reverts commit 126115c04e.
2022-05-27 21:14:16 +08:00
sjlleo
126115c04e update: 优化打印逻辑,废除 realtime 参数 2022-05-27 21:08:30 +08:00
tsosunchia
ea7fd2af0f Update quicklytest.sh 2022-05-27 19:55:54 +08:00
tsosunchia
3fc81f4e71 Merge pull request #26 from tsosunchia/main
修补之前再部分macOS设备出现的颜色显示问题:替换macOS中bash-3.1不支持的部分指令
2022-05-27 19:37:55 +08:00
tsosunchia
0c2b77bd81 Merge branch 'main' into main 2022-05-27 19:37:48 +08:00
tsosunchia
ac33c086c6 修补之前再部分macOS设备出现的颜色显示问题:替换macOS中bash-3.1不支持的部分指令 2022-05-27 19:34:35 +08:00
zhshch2002
fadfdc87d4 fix: nt_install.sh red color 2022-05-27 19:31:38 +08:00
tsosunchia
eb77a2b69b Merge pull request #25 from tsosunchia/main
替换macOS中bash-3.1不支持的部分指令
2022-05-27 19:14:44 +08:00
tsosunchia
02e6c6e1bf 替换macOS中bash-3.1不支持的部分指令 2022-05-27 19:13:05 +08:00
tsosunchia
838af3b7a1 Merge pull request #24 from tsosunchia/main
替换macOS下bash-3.1不兼容的部分指令 issues#21
2022-05-27 19:10:10 +08:00
tsosunchia
7cd16036a6 替换macOS中bash-3.1不支持的部分指令 2022-05-27 19:08:04 +08:00
tsosunchia
2ef4f61d7b Merge branch 'xgadget-lab:main' into main 2022-05-27 18:32:46 +08:00
tsosunchia
688622738f 整理排版 2022-05-27 18:32:23 +08:00
tsosunchia
83fe583f2a Merge pull request #23 from tsosunchia/main
fix some bugs
2022-05-27 18:30:49 +08:00
tsosunchia
4b32594c17 fix some bugs 2022-05-27 18:30:18 +08:00
tsosunchia
927b6d4035 Merge pull request #22 from tsosunchia/main
修正macOS下缺少md5sum导致的运行问题  issues#21
2022-05-27 18:16:59 +08:00
tsosunchia
aa651f30cc Merge branch 'xgadget-lab:main' into main 2022-05-27 18:15:38 +08:00
tsosunchia
ffec9a93cd update nt_install.sh 修正macOS下缺少md5sum导致的运行问题 issues#21 2022-05-27 18:15:10 +08:00
sjlleo
59a744b3b5 update: 修正文档里面有一个route-path错位的问题 2022-05-27 18:13:37 +08:00
25 changed files with 796 additions and 493 deletions

View File

@@ -5,7 +5,7 @@ set -e
DIST_PREFIX="nexttrace"
DEBUG_MODE=${2}
TARGET_DIR="dist"
PLATFORMS="darwin/amd64 darwin/arm64 linux/amd64 linux/arm64 linux/mips"
PLATFORMS="darwin/amd64 darwin/arm64 linux/386 linux/amd64 linux/arm64 linux/mips openbsd/amd64 openbsd/arm64 freebsd/amd64 freebsd/arm64"
BUILD_VERSION="$(git describe --tags --always)"
BUILD_DATE="$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
@@ -38,3 +38,23 @@ for pl in ${PLATFORMS}; do
fi
done
export GOOS='linux'
export GOARCH='arm'
export GOARM='7'
export TARGET=${TARGET_DIR}/${DIST_PREFIX}_${GOOS}_${GOARCH}v7
echo "build => ${TARGET}"
if [ "${DEBUG_MODE}" == "debug" ]; then
go build -trimpath -gcflags "all=-N -l" -o ${TARGET} \
-ldflags "-X 'github.com/xgadget-lab/nexttrace/printer.version=${BUILD_VERSION}' \
-X 'github.com/xgadget-lab/nexttrace/printer.buildDate=${BUILD_DATE}' \
-X 'github.com/xgadget-lab/nexttrace/printer.commitID=${COMMIT_SHA1}'\
-w -s"
else
go build -trimpath -o ${TARGET} \
-ldflags "-X 'github.com/xgadget-lab/nexttrace/printer.version=${BUILD_VERSION}' \
-X 'github.com/xgadget-lab/nexttrace/printer.buildDate=${BUILD_DATE}' \
-X 'github.com/xgadget-lab/nexttrace/printer.commitID=${COMMIT_SHA1}'\
-w -s"
fi

View File

@@ -36,8 +36,14 @@ jobs:
files: |
dist/nexttrace_darwin_amd64
dist/nexttrace_darwin_arm64
dist/nexttrace_linux_386
dist/nexttrace_linux_amd64
dist/nexttrace_linux_arm64
dist/nexttrace_linux_armv7
dist/nexttrace_linux_mips
dist/nexttrace_openbsd_amd64
dist/nexttrace_openbsd_arm64
dist/nexttrace_freebsd_amd64
dist/nexttrace_freebsd_arm64
env:
GITHUB_TOKEN: ${{ secrets.GT_Token }}

12
.macos_compil.sh Normal file
View File

@@ -0,0 +1,12 @@
#!/usr/bin/env bash
set -e
BUILD_VERSION=$1
BUILD_DATE="$(date -u +'%Y-%m-%dT%H:%M:%SZ')"
COMMIT_SHA1=""
go build -trimpath -ldflags "-X 'github.com/xgadget-lab/nexttrace/printer.version=${BUILD_VERSION}' \
-X 'github.com/xgadget-lab/nexttrace/printer.buildDate=${BUILD_DATE}' \
-X 'github.com/xgadget-lab/nexttrace/printer.commitID=${COMMIT_SHA1}'\
-w -s"

101
README.md
View File

@@ -13,26 +13,19 @@
### Automated Install
```bash
#下载nt_install.sh
curl -Ls https://github.com/xgadget-lab/nexttrace/raw/main/nt_install.sh -O
#执行nt_install.sh
sudo bash nt_install.sh
# Linux 一键安装脚本
bash <(curl -Ls https://raw.githubusercontent.com/xgadget-lab/nexttrace/main/nt_install.sh)
# GHPROXY 镜像(国内使用)
bash <(curl -Ls https://ghproxy.com/https://raw.githubusercontent.com/xgadget-lab/nexttrace/main/nt_install.sh)
```
### Alternative methods
如果你的目的只是为了快速测试服务器的到中国内地的线路,没有手动使用 NextTrace 的需求,那么建议你直接使用本仓库的 `quicklytest.sh`
```bash
#下载quicklytest.sh
curl -Ls https://github.com/xgadget-lab/nexttrace/raw/main/quicklytest.sh -O
#执行quicklytest.sh
sudo bash quicklytest.sh
```
- `Release`里面为很多系统以及不同架构提供了编译好的二进制可执行文件,如果没有可以自行编译。
- 一些本项目的必要依赖在`Windows``Golang`底层实现不完全,所以目前`NextTrace``Windows`平台不可用。
### Get Started
`NextTrace`默认使用`icmp`协议发起`TraceRoute`请求,该协议同时支持`IPv4``IPv6`
`NextTrace`默认使用`ICMP`协议发起`TraceRoute`请求,该协议同时支持`IPv4``IPv6`
```bash
# IPv4 ICMP Trace
@@ -40,8 +33,6 @@ nexttrace 1.0.0.1
# 表格打印一次性输出全部跳数需等待20-40秒
nexttrace -table 1.0.0.1
# 实时打印 (-realtime与-table不能同时选择)
nexttrace -realtime 1.0.0.1
# IPv6 ICMP Trace
nexttrace 2606:4700:4700::1111
@@ -78,15 +69,15 @@ nexttrace -rdns www.bbix.net
# Route-Path图示例
# AS6453 塔塔通信「Singapore『Singapore』」
# ╭╯
# ╰AS9299 Philippine Long Distance Telephone Co.「Philippines『Metro Manila』」
# ╭╯
# ╰AS36776 Five9 Inc.「Philippines『Metro Manila』」
# ╭╯
# ╰AS37963 阿里云「ALIDNS.COM『ALIDNS.COM』」
# ╰AS9299 Philippine Long Distance Telephone Co.「Philippines『Metro Manila』」
# ╭╯
# ╰AS36776 Five9 Inc.「Philippines『Metro Manila』」
# ╭╯
# ╰AS37963 阿里云「ALIDNS.COM『ALIDNS.COM』」
nexttrace -report www.time.com.my
```
`NextTrace`支持用户自主选择 IP 数据库(目前支持:`LeoMoeAPI`, `IP.SB`, `IPInfo`, `IPInsight`
`NextTrace`支持用户自主选择 IP 数据库(目前支持:`LeoMoeAPI`, `IP.SB`, `IPInfo`, `IPInsight`, `IPAPI.com`
```bash
# 可以自行指定IP数据库[此处为IP.SB]不指定则默认为LeoMoeAPI
@@ -94,14 +85,15 @@ nexttrace -d IP.SB
## 特别的:其中 ipinfo API 需要从ipinfo自行购买服务如有需要可以clone本项目添加其提供的token自行编译
## TOKEN填写路径ipgeo/tokens.go
## 另外由于IP.SB被滥用比较严重会经常出现无法查询的问题请知悉。
## IPAPI.com限制调用较为严格如有查询不到的情况请几分钟后再试。
```
`NextTrace`支持参数混合使用
```bash
Example:
nexttrace -d IPInsight -m 20 -p 443 -q 5 -r 20 -rdns -table 1.1.1.1
nexttrace -T -q 2 -r 1 -rdns -realtime -report 2001:4860:4860::8888
nexttrace -d IPInsight -m 20 -p 443 -q 5 -r 20 -rdns 1.1.1.1
nexttrace -T -q 2 -r 1 -rdns -table -report 2001:4860:4860::8888
```
### IP 数据库
@@ -122,7 +114,7 @@ Options:
-U Use UDP Package for tracerouting (default port is 53 in UDP)
-V Check Version
-d string
Choose IP Geograph Data Provider [LeoMoeAPI, IP.SB, IPInfo, IPInsight] (default "LeoMoeAPI")
Choose IP Geograph Data Provider [LeoMoeAPI, IP.SB, IPInfo, IPInsight, IPAPI.com] (default "LeoMoeAPI")
-m int
Set the max number of hops (max TTL to be reached). (default 30)
-p int
@@ -133,8 +125,6 @@ Options:
Set ParallelRequests number. It should be 1 when there is a multi-routing. (default 18)
-rdns
Set whether rDNS will be display
-realtime
Output trace results in runtime
-table
Output trace results as table
-report
@@ -144,17 +134,21 @@ Options:
## 项目截图
![NextTrace Screenshot](asset/screenshot.png)
<div align="center">
<img src=asset/screenshot.png alt="NextTrace Screenshot" height="688" />
</div>
## FAQ 常见问题
如果你在安装或者使用的时候遇到了问题,我们建议你不要把新建一个 `issue` 作为首选项
或许可以在这里找到答案 -> [前往 Github Wiki](https://github.com/xgadget-lab/nexttrace/wiki/FAQ---%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E8%A7%A3%E7%AD%94)
以下是我们推荐的排错流程:
如果在搜索引擎WiKi 处还是没有解决,可以试试在本项目讨论区交流 -> [前往 Github Discussions](https://github.com/xgadget-lab/nexttrace/discussions)
最终如果你确认遇到的是 BUG、上述方法都不能解决的话请按照提供好的模版在 Issues 区提出问题 -> [前往 Github Issues](https://github.com/xgadget-lab/nexttrace/issues)
1. 查看是否为常见问题 -> [前往 Github Wiki](https://github.com/xgadget-lab/nexttrace/wiki/FAQ---%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E8%A7%A3%E7%AD%94)
2. 不会软件的参数使用 -> [前往 Github Discussions](https://github.com/xgadget-lab/nexttrace/discussions)
3. 疑似 BUG、或者功能建议 -> [前往 Github Issues](https://github.com/xgadget-lab/nexttrace/issues)
## Thanks
@@ -162,36 +156,43 @@ Options:
[Sam Sam](https://github.com/samleong123) (samsam123@samsam123.name.my)
[waiting4new](https://github.com/waiting4new)、[FFEE_CO](https://github.com/fkx4-p)、[nsnnns](https://github.com/tsosunchia)
[tsosunchia](https://github.com/tsosunchia)
[waiting4new](https://github.com/waiting4new)
[FFEE_CO](https://github.com/fkx4-p)
## IP Database Copyright
### IPv4 Database
#### China MainLand
#### China
- 项目组自行维护 ~ 御三家骨干网数据 ~ 5%
- 埃文科技 Paid Database ~ 95%
**这里有朋友就要问了,为什么不全部使用埃文的付费库?**
埃文的库一直都不是最优选择IPIP.NET 才是,但是因为他们不对私,所以我们只能选择价格更便宜的埃文库。
埃文家的数据库,在骨干网这块,准度可以说是非常糟糕,作为一款可视化的路由跟踪工具,骨干网的数据库准度非常重要。
所以我们选择了尝试自行去校准一部分骨干网数据,但是由于我们缺乏检测节点以及志愿者,所以这项工作可能会进展的尤其缓慢。
| ISP | 类型 | 数据源 | 占比 |
| :------------: | :----: | :-------: | :--: |
| 电信/联通/移动 | 骨干网 | NextTrace | 10% |
| 电信/联通/移动 | 城域网 | 埃文科技 | 90% |
#### WorldWide
- 埃文科技 Paid Database ~ 15%
| ISP | 类型 | 数据源 | 占比 |
| :-----: | :----: | :-------: | :--: |
| Tier-01 | 骨干网 | IPInfo | 2% |
| Tier-01 | 骨干网 | 埃文科技 | 3% |
| Tier-01 | 骨干网 | IPInSight | 5% |
| Tier-01 | 城域网 | IPInSight | 90% |
- IpInfo Free ~ 15%
- IPInSight Free ~ 70%
| ISP | 类型 | 数据源 | 占比 |
| :----: | :----: | :-------: | :--: |
| Others | 骨干网 | IPInSight | 5% |
| Others | 城域网 | IPInSight | 95% |
### IPv6 Database
| ISP | 类型 | 数据源 | 占比 |
| :-: | :--: | :--------------: | :--: |
| All | 全部 | IP2Location Lite | 100% |
This product includes IP2Location LITE data available from <a href="https://lite.ip2location.com">https://lite.ip2location.com</a>.
### Others

Binary file not shown.

Before

Width:  |  Height:  |  Size: 907 KiB

After

Width:  |  Height:  |  Size: 1.3 MiB

35
config/config.go Normal file
View File

@@ -0,0 +1,35 @@
package config
import "os"
type tracerConfig struct {
Token `yaml:"Token"`
Preference `yaml:"Preference"`
}
type Token struct {
LeoMoeAPI string `yaml:"LeoMoeAPI"`
IPInfo string `yaml:"IPInfo"`
}
type Preference struct {
NoRDNS bool `yaml:"NoRDNS"`
DataOrigin string `yaml:"DataOrigin"`
AlwaysRoutePath bool `yaml:"AlwaysRoutePath"`
TablePrintDefault bool `yaml:"TablePrintDefault"`
TraceMethod string `yaml:"TraceMethod"`
}
type configPath func() (string, error)
func configFromRunDir() (string, error) {
return "./", nil
}
func configFromUserHomeDir() (string, error) {
dir, err := os.UserHomeDir()
if err != nil {
return "", err
}
return dir + "/.nexttrace/", nil
}

18
config/config_test.go Normal file
View File

@@ -0,0 +1,18 @@
package config
import (
"testing"
"log"
)
func TestReadConfig(t *testing.T) {
if res, err := Read(); err != nil {
log.Println(err)
} else {
log.Println(res)
}
}
func TestGenerateConfig(t *testing.T) {
Generate()
}

160
config/generate_config.go Normal file
View File

@@ -0,0 +1,160 @@
package config
import (
"fmt"
"io/ioutil"
"os"
"gopkg.in/yaml.v2"
)
func pathExists(path string) (bool, error) {
_, err := os.Stat(path)
if err == nil {
return true, nil
}
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
func writeFile(content []byte) error {
var err error
var path string
path, err = configFromUserHomeDir()
if err != nil {
path, err = configFromRunDir()
if err != nil {
return err
}
}
if exist, _ := pathExists(path); !exist {
err := os.Mkdir(path, os.ModePerm)
if err != nil {
return err
}
}
if err = ioutil.WriteFile(path+"ntraceConfig.yml", []byte(content), 0644); err != nil {
return err
}
return nil
}
func AutoGenerate() (*tracerConfig, error) {
token := Token{
LeoMoeAPI: "NextTraceDemo",
IPInfo: "",
}
preference := Preference{
AlwaysRoutePath: false,
TablePrintDefault: false,
DataOrigin: "LEOMOEAPI",
}
finalConfig := tracerConfig{
Token: token,
Preference: preference,
}
yamlData, err := yaml.Marshal(&finalConfig)
if err != nil {
return nil, err
}
if err = writeFile(yamlData); err != nil {
return nil, err
} else {
return &finalConfig, nil
}
}
func Generate() (*tracerConfig, error) {
var leotoken string
var iPInfoToken string
var tmpInput string
fmt.Println("欢迎使用高阶自定义功能,这是一个配置向导,我们会帮助您生成配置文件。您的配置文件会被放在 ~/.nexttrace/ntraceConfig.yml 中,您也可以通过编辑这个文件来自定义配置。")
fmt.Println("请输入您的LeoMoeAPI Token您可以回车以便继续使用公共Token")
fmt.Scanln(&leotoken)
if leotoken == "" {
fmt.Println("检测到您的输入为空您将使用公共Token。")
leotoken = "NextTraceDemo"
}
fmt.Println("请输入您的IPInfo Token如果您不需要使用IPInfo可以直接回车")
fmt.Scanln(&iPInfoToken)
token := Token{
LeoMoeAPI: leotoken,
IPInfo: iPInfoToken,
}
var preference Preference
var AlwaysRoutePath bool
var tablePrintDefault bool
var dataOrigin string
fmt.Print("我希望默认在路由跟踪完毕后不绘制Route-Path图 (y/n) [y]")
fmt.Scanln(&tmpInput)
if tmpInput == "n" || tmpInput == "N" || tmpInput == "no" || tmpInput == "No" || tmpInput == "NO" {
AlwaysRoutePath = true
} else {
AlwaysRoutePath = false
}
fmt.Print("我希望路由跟踪默认实时显示,而不使用制表模式 (y/n) [y]")
fmt.Scanln(&tmpInput)
if tmpInput == "n" || tmpInput == "N" || tmpInput == "no" || tmpInput == "No" || tmpInput == "NO" {
tablePrintDefault = true
} else {
tablePrintDefault = false
}
fmt.Println("请选择默认的IP地理位置API数据源\n1. LeoMoe\n2. IPInfo\n3. IPInsight\n4. IP.SB\n5. IP-API.COM")
fmt.Print("请输入您的选择:")
fmt.Scanln(&tmpInput)
switch tmpInput {
case "1":
dataOrigin = "LEOMOEAPI"
case "2":
dataOrigin = "IPINFO"
case "3":
dataOrigin = "IPINSIGHT"
case "4":
dataOrigin = "IP.SB"
case "5":
dataOrigin = "IPAPI.COM"
default:
dataOrigin = "LEOMOEAPI"
}
preference = Preference{
AlwaysRoutePath: AlwaysRoutePath,
TablePrintDefault: tablePrintDefault,
DataOrigin: dataOrigin,
}
finalConfig := tracerConfig{
Token: token,
Preference: preference,
}
yamlData, err := yaml.Marshal(&finalConfig)
if err != nil {
return nil, err
}
if err = writeFile(yamlData); err != nil {
return nil, err
} else {
fmt.Println("配置文件已经更新,在下次路由跟踪时,将会使用您的偏好。")
return &finalConfig, nil
}
}

47
config/read_config.go Normal file
View File

@@ -0,0 +1,47 @@
package config
import (
"io/ioutil"
"log"
"gopkg.in/yaml.v2"
)
func (c *tracerConfig) Parse(data []byte) error {
return yaml.Unmarshal(data, c)
}
func readFile(cp configPath) ([]byte, error) {
var content []byte
path, err := cp()
if err != nil {
log.Println(err)
return nil, err
}
content, err = ioutil.ReadFile(path + "ntraceConfig.yml")
if err != nil {
return nil, err
}
return content, nil
}
func Read() (*tracerConfig, error) {
var data []byte
var err error
data, err = readFile(configFromRunDir)
if err != nil {
data, err = readFile(configFromUserHomeDir)
if err != nil {
return nil, err
}
}
var config tracerConfig
if err := config.Parse(data); err != nil {
return nil, err
}
return &config, err
}

1
go.mod
View File

@@ -11,6 +11,7 @@ require (
require (
github.com/mattn/go-colorable v0.1.9 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
gopkg.in/yaml.v2 v2.4.0 // direct
)
require (

2
go.sum
View File

@@ -49,6 +49,8 @@ golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapK
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

View File

@@ -26,7 +26,9 @@ func GetSource(s string) Source {
return IPInSight
case "IPAPI.COM":
return IPApiCom
case "IPINFO":
return IPInfo
default:
return nil
return LeoIP
}
}

View File

@@ -8,7 +8,6 @@ import (
)
func IPInfo(ip string) (*IPGeoData, error) {
resp, err := http.Get("https://ipinfo.io/" + ip + "?token=" + token.ipinfo)
if err != nil {
return nil, err

View File

@@ -1,5 +1,7 @@
package ipgeo
import "github.com/xgadget-lab/nexttrace/config"
type tokenData struct {
ipinsight string
ipinfo string
@@ -11,3 +13,9 @@ var token = tokenData{
ipinfo: "",
ipleo: "NextTraceDemo",
}
func SetToken(c config.Token) {
token.ipleo = c.LeoMoeAPI
token.ipinfo = c.IPInfo
}

76
main.go
View File

@@ -4,10 +4,12 @@ import (
"flag"
"fmt"
"log"
"net"
"os"
"strings"
"time"
"github.com/xgadget-lab/nexttrace/config"
"github.com/xgadget-lab/nexttrace/ipgeo"
"github.com/xgadget-lab/nexttrace/printer"
"github.com/xgadget-lab/nexttrace/reporter"
@@ -18,19 +20,19 @@ import (
var fSet = flag.NewFlagSet("", flag.ExitOnError)
var tcpSYNFlag = fSet.Bool("T", false, "Use TCP SYN for tracerouting (default port is 80)")
var udpPackageFlag = fSet.Bool("U", false, "Use UDP Package for tracerouting (default port is 53 in UDP)")
var port = flag.Int("p", 80, "Set SYN Traceroute Port")
var port = fSet.Int("p", 80, "Set SYN Traceroute Port")
var manualConfig = fSet.Bool("c", false, "Manual Config [Advanced]")
var numMeasurements = fSet.Int("q", 3, "Set the number of probes per each hop.")
var parallelRequests = fSet.Int("r", 18, "Set ParallelRequests number. It should be 1 when there is a multi-routing.")
var maxHops = fSet.Int("m", 30, "Set the max number of hops (max TTL to be reached).")
var dataOrigin = fSet.String("d", "LeoMoeAPI", "Choose IP Geograph Data Provider [LeoMoeAPI, IP.SB, IPInfo, IPInsight]")
var rdnsenable = fSet.Bool("rdns", false, "Set whether rDNS will be display")
var dataOrigin = fSet.String("d", "", "Choose IP Geograph Data Provider [LeoMoeAPI, IP.SB, IPInfo, IPInsight, IPAPI.com]")
var noRdns = fSet.Bool("n", false, "Disable IP Reverse DNS lookup")
var routePath = fSet.Bool("report", false, "Route Path")
var realtimePrint = fSet.Bool("realtime", false, "Output trace results in runtime")
var tablePrint = fSet.Bool("table", false, "Output trace results as table")
var ver = fSet.Bool("V", false, "Check Version")
func printArgHelp() {
fmt.Println("\nArgs Error\nUsage : 'nexttrace [option...] HOSTNAME' or 'nexttrace HOSTNAME [option...]'\nOPTIONS: [-VTU] [-d DATAORIGIN.STR ] [ -m TTL ] [ -p PORT ] [ -q PROBES.COUNT ] [ -r PARALLELREQUESTS.COUNT ] [-rdns] [ -realtime | -table ] -report")
fmt.Println("\nArgs Error\nUsage : 'nexttrace [option...] HOSTNAME' or 'nexttrace HOSTNAME [option...]'\nOPTIONS: [-VTU] [-d DATAORIGIN.STR ] [ -m TTL ] [ -p PORT ] [ -q PROBES.COUNT ] [ -r PARALLELREQUESTS.COUNT ] [-rdns] [ -table ] -report")
fSet.PrintDefaults()
os.Exit(2)
}
@@ -49,9 +51,19 @@ func flagApply() string {
fSet.Parse(os.Args[1:])
target = fSet.Arg(0)
}
if *ver {
os.Exit(0)
}
// Advanced Config
if *manualConfig {
if _, err := config.Generate(); err != nil {
log.Fatal(err)
}
os.Exit(0)
}
if target == "" {
printArgHelp()
}
@@ -66,7 +78,32 @@ func main() {
log.Fatalln("Traceroute requires root/sudo privileges.")
}
ip := util.DomainLookUp(domain)
configData, err := config.Read()
// Initialize Default Config
if err != nil || configData.DataOrigin == "" {
if configData, err = config.AutoGenerate(); err != nil {
log.Fatal(err)
}
}
// Set Token from Config
ipgeo.SetToken(configData.Token)
// Check Whether User has specified IP Geograph Data Provider
if *dataOrigin == "" {
// Use Default Data Origin with Config
*dataOrigin = configData.DataOrigin
}
var ip net.IP
if *tcpSYNFlag || *udpPackageFlag {
ip = util.DomainLookUp(domain, true)
} else {
ip = util.DomainLookUp(domain, false)
}
printer.PrintTraceRouteNav(ip, domain, *dataOrigin)
var m trace.Method = ""
@@ -90,7 +127,7 @@ func main() {
MaxHops: *maxHops,
NumMeasurements: *numMeasurements,
ParallelRequests: *parallelRequests,
RDns: *rdnsenable,
RDns: !*noRdns,
IPGeoSource: ipgeo.GetSource(*dataOrigin),
Timeout: 2 * time.Second,
}
@@ -105,25 +142,14 @@ func main() {
log.Fatalln(err)
}
if *routePath {
// 如果为TCP SYN也打印路由跟踪结果
if *tcpSYNFlag {
printer.TracerouteTablePrinter(res)
}
if (*tcpSYNFlag && *udpPackageFlag) || *tablePrint || configData.TablePrintDefault {
printer.TracerouteTablePrinter(res)
} else if *tcpSYNFlag || *udpPackageFlag {
printer.TraceroutePrinter(res)
}
if *routePath || configData.AlwaysRoutePath {
r := reporter.New(res, ip.String())
r.Print()
return
}
if m == trace.ICMPTrace && *tablePrint {
printer.TracerouteTablePrinter(res)
}
if m == trace.TCPTrace || m == trace.UDPTrace {
if *realtimePrint {
printer.TraceroutePrinter(res)
} else {
printer.TracerouteTablePrinter(res)
}
}
}

View File

@@ -1,259 +1,123 @@
#!/bin/bash
auto=False
#是否忽略一切警告,按默认执行
if [[ $1 == "--auto" ]]; then
auto=True
echo "自动运行中"
fi
usrPath="/usr/local/bin"
function red() {
echo -e "\e[1;31m$1\e[0m"
}
Green_font="\033[32m"
Yellow_font="\033[33m"
Red_font="\033[31m"
Font_suffix="\033[0m"
Info="${Green_font}[Info]${Font_suffix}"
Error="${Red_font}[Error]${Font_suffix}"
Tips="${Green_font}[Tips]${Font_suffix}"
Temp_path="/var/tmp/nexttrace"
checkRootPermit() {
[[ $EUID -ne 0 ]] && red "请使用sudo/root权限运行本脚本" && exit 1
}
ask_if() {
local choice=""
while [ "$choice" != "y" ] && [ "$choice" != "n" ]; do
red $1
read choice
done
[ $choice == y ] && return 0
return 1
}
#检查脚本更新
check_script_update() {
[ "$(md5sum "${BASH_SOURCE[0]}" | awk '{print $1}')" == "$(md5sum <(curl -sL "https://github.com/xgadget-lab/nexttrace/raw/main/nt_install.sh") | awk '{print $1}')" ] && return 1 || return 0
}
#更新脚本
update_script() {
if curl -sL -o "${BASH_SOURCE[0]}" "https://github.com/xgadget-lab/nexttrace/raw/main/nt_install.sh" || curl -sL -o "${BASH_SOURCE[0]}" "https://github.com/xgadget-lab/nexttrace/raw/main/nt_install.sh"; then
red "脚本更新完成,正在重启脚本..."
exec bash ${BASH_SOURCE[0]} --auto
else
red "更新脚本失败!"
exit 1
fi
}
ask_update_script() {
if check_script_update; then
red "脚本可升级"
[[ $auto == True ]] && update_script
ask_if "是否升级脚本?(y/n)" && update_script
else
red "脚本已经是最新版本"
fi
[[ $EUID -ne 0 ]] && echo -e "${Error} 请使用sudo/root权限运行本脚本" && exit 1
}
checkSystemArch() {
arch=$(uname -m)
case $arch in
'x86_64')
archParam='amd64'
;;
'mips')
archParam='mips'
;;
'arm64' | 'aarch64')
archParam="arm64"
;;
*)
red "未知的系统架构,请联系开发者."
exit 1
;;
esac
if [[ $arch == "x86_64" ]]; then
archParam="amd64"
fi
if [[ $arch == "aarch64" ]]; then
archParam="arm64"
fi
}
checkSystemDistribution() {
case "$OSTYPE" in
darwin*)
osDistribution="darwin"
downPath="/var/tmp/nexttrace"
;;
linux*)
osDistribution="linux"
downPath="/var/tmp/nexttrace"
;;
linux*)
osDistribution="linux"
downPath="/usr/local/bin/nexttrace"
;;
*)
red "unknown: $OSTYPE"
exit 1
;;
echo "unknown: $OSTYPE"
exit 1
;;
esac
}
getLocation() {
red "正在获取地理位置信息..."
countryCode=$(curl -s "http://ip-api.com/line/?fields=countryCode")
}
checkPackageManger() {
if [[ "$(which brew)" ]]; then #务必将brew置于第一位,macOS的apt是假的
# brew update
PACKAGE_MANAGEMENT_INSTALL='brew install'
PACKAGE_MANAGEMENT_REMOVE='brew uninstall'
elif [[ "$(which apt)" ]]; then
apt-get update
PACKAGE_MANAGEMENT_INSTALL='apt-get -y --no-install-recommends install'
PACKAGE_MANAGEMENT_REMOVE='apt-get purge'
elif [[ "$(which dnf)" ]]; then
dnf check-update
PACKAGE_MANAGEMENT_INSTALL='dnf -y install'
PACKAGE_MANAGEMENT_REMOVE='dnf remove'
elif [[ "$(which yum)" ]]; then
PACKAGE_MANAGEMENT_INSTALL='yum -y install'
PACKAGE_MANAGEMENT_REMOVE='yum remove'
elif [[ "$(which zypper)" ]]; then
zypper refresh
PACKAGE_MANAGEMENT_INSTALL='zypper install -y --no-recommends'
PACKAGE_MANAGEMENT_REMOVE='zypper remove'
elif [[ "$(which pacman)" ]]; then
PACKAGE_MANAGEMENT_INSTALL='pacman -Syu --noconfirm'
PACKAGE_MANAGEMENT_REMOVE='pacman -Rsn'
else
red "error: The script does not support the package manager in this operating system."
exit 1
installWgetPackage() {
echo -e "${Info} wget 正在安装中..."
# try apt
apt -h &> /dev/null
if [ $? -eq 0 ]; then
# 先更新一下数据源有些机器数据源比较老可能会404
apt update -y &> /dev/null
apt install wget -y &> /dev/null
fi
# try yum
yum -h &> /dev/null
if [ $? -eq 0 ]; then
yum install wget -y &> /dev/null
fi
# try dnf
dnf -h &> /dev/null
if [ $? -eq 0 ]; then
dnf install wget -y &> /dev/null
fi
# try pacman
pacman -h &> /dev/null
if [ $? -eq 0 ]; then
pacman -Sy
pacman -S wget
fi
}
install_software() {
package_name="$1"
which "$package_name" >/dev/null 2>&1 && return
[[ ${osDistribution} == "darwin" ]] && echo -e "由于macOS brew的权限限制请以非root权限执行下面一行提示的命令后再次运行本脚本(注意不要在该命令加sudo!):\nbrew update && ${PACKAGE_MANAGEMENT_INSTALL} $package_name " && exit 0
red "${package_name} 正在安装中...(此步骤时间可能较长,请耐心等待)"
if ${PACKAGE_MANAGEMENT_INSTALL} "$package_name"; then
red "info: $package_name is installed."
else
red "error: Installation of $package_name failed, please check your network."
exit 1
fi
}
checkVersion() {
nexttrace -h &>/dev/null
checkWgetPackage() {
wget -h &> /dev/null
if [ $? -ne 0 ]; then
return 0
installWgetPackage
fi
red "正在检查版本..."
version=$(curl -sL https://api.github.com/repos/xgadget-lab/nexttrace/releases/latest | jq -r '.tag_name')
if [[ $version == "" ]]; then
red "获取版本失败,请检查网络连接"
exit 1
fi
currentVersion=$(nexttrace -V | head -n 1 | awk '{print $2}') &>/dev/null
if [[ $currentVersion == $version ]]; then
red "当前版本已是最新版本"
exit 0
fi
red 当前最新release版本${version}
red 您当前的版本:${currentVersion}
if [[ $auto == True ]]; then
return 0
fi
read -r -p "是否更新软件? (y/n)" input
case $input in
[yY][eE][sS] | [yY])
return 0
;;
[nN][oO] | [nN])
red "您选择了取消更新,脚本即将退出"
exit 1
;;
*)
return 0
;;
esac
}
downloadBinrayFile() {
red "正在获取最新版的 NextTrace 发行版文件信息..."
echo -e "${Info} 获取最新版的 NextTrace 发行版文件信息"
# 简单说明一下Github提供了一个API可以获取最新发行版本的二进制文件下载地址对应的是browser_download_url根据刚刚测得的osDistribution、archParam获取对应的下载地址
# red nexttrace_${osDistribution}_${archParam}
latestURL=$(curl -s https://api.github.com/repos/xgadget-lab/nexttrace/releases/latest | jq ".assets[] | select(.name == \"nexttrace_${osDistribution}_${archParam}\") | .browser_download_url")
latestURL=${latestURL:1:-1}
latestURL=$(curl -s https://api.github.com/repos/xgadget-lab/nexttrace/releases/latest | grep -i "browser_download_url.*${osDistribution}.*${archParam}" | awk -F '"' '{print $4}')
if [ "$countryCode" == "CN" ]; then
if [[ $auto == True ]]; then
latestURL="https://ghproxy.com/"$latestURL
else
read -r -p "检测到国内网络环境,是否使用镜像下载以加速(y/n)" input
case $input in
[yY][eE][sS] | [yY])
latestURL="https://ghproxy.com/"$latestURL
;;
[nN][oO] | [nN])
red "您选择了不使用镜像,下载可能会变得异常缓慢,或者失败"
;;
*)
latestURL="https://ghproxy.com/"$latestURL
;;
esac
fi
echo -e "${Info} 检测到国内环境,正在使用镜像下载"
latestURL="https://ghproxy.com/"$latestURL
fi
red "正在下载 NextTrace 二进制文件..."
wget -O ${downPath} ${latestURL} &>/dev/null
if [ $? -eq 0 ]; then
red "NextTrace 现在已经在您的系统中可用"
changeMode
mv ${downPath} ${usrPath}
echo -e "${Info} 正在下载 NextTrace 二进制文件..."
wget -O ${Temp_path} ${latestURL} &> /dev/null
if [ $? -eq 0 ];
then
changeMode
mv ${Temp_path} ${downPath}
echo -e "${Info} NextTrace 现在已经在您的系统中可用"
else
red "NextTrace 下载失败,请检查您的网络是否正常"
exit 1
echo -e "${Error} NextTrace 下载失败,请检查您的网络是否正常"
exit 1
fi
}
changeMode() {
chmod +x ${downPath} &>/dev/null
[[ ${osDistribution} == "darwin" ]] && xattr -r -d com.apple.quarantine ${downPath}
chmod +x ${Temp_path} &> /dev/null
}
runBinrayFileHelp() {
if [ -e ${usrPath} ]; then
${usrPath}/nexttrace -h
if [ -e ${downPath} ]; then
${downPath} -V
echo -e "${Tips} 一切准备就绪!使用命令 nexttrace 1.1.1.1 开始您的第一次路由测试吧~ 更多进阶命令玩法可以用 nexttrace -h 查看哦\n 关于软件卸载因为nexttrace是绿色版单文件卸载只需输入命令 rm /usr/local/bin/nexttrace 即可"
fi
red "You may need to execute a command to remove dependent software: $PACKAGE_MANAGEMENT_REMOVE wget jq"
}
addCronTask() {
read -r -p "是否添加自动更新任务?(y/n)" input
case $input in
[yY][eE][sS] | [yY])
if [[ ${osDistribution} == "darwin" ]]; then
crontab -l >crontab.bak 2>/dev/null
sed -i '' '/nt_install.sh/d' crontab.bak
elif [[ ${osDistribution} == "linux" ]]; then
crontab -l >crontab.bak 2>/dev/null
sed -i '/nt_install.sh/d' crontab.bak
else
red "暂不支持您的系统,无法自动添加crontab任务"
return 0
fi
echo "1 1 * * * $(dirname $(readlink -f "$0"))/nt_install.sh --auto >> /var/log/nt_install.log" >>crontab.bak
crontab crontab.bak
rm -f crontab.bak
;;
[nN][oO] | [nN])
red "您选择了不添加自动更新任务,您也可以通过命令 再次执行此脚本 手动更新"
;;
*)
red "您选择了不添加自动更新任务,您可以通过命令 再次执行此脚本 手动更新"
;;
esac
}
# Check Procedure
checkRootPermit
ask_update_script
checkSystemDistribution
checkSystemArch
checkPackageManger
install_software wget
install_software jq
checkVersion
checkWgetPackage
# Download Procedure
getLocation
@@ -261,4 +125,3 @@ downloadBinrayFile
# Run Procedure
runBinrayFileHelp
[[ $auto != True ]] && addCronTask

View File

@@ -52,11 +52,11 @@ func formatIpGeoData(ip string, data *ipgeo.IPGeoData) string {
// TODO: 判断阿里云和腾讯云内网,数据不足,有待进一步完善
// TODO: 移动IDC判断到Hop.fetchIPData函数减少API调用
if strings.HasPrefix(ip, "9.") {
res = append(res, "局域网", "腾讯云")
res = append(res, "LAN Address")
} else if strings.HasPrefix(ip, "11.") {
res = append(res, "局域网", "阿里云")
res = append(res, "LAN Address")
} else if data.Country == "" {
res = append(res, "局域网")
res = append(res, "LAN Address")
} else {
// 有些IP的归属信息为空这个时候将ISP的信息填入
if data.Owner == "" {

View File

@@ -2,16 +2,17 @@ package printer
import (
"errors"
"github.com/xgadget-lab/nexttrace/ipgeo"
"github.com/xgadget-lab/nexttrace/trace"
"github.com/xgadget-lab/nexttrace/util"
"net"
"testing"
"time"
"github.com/xgadget-lab/nexttrace/ipgeo"
"github.com/xgadget-lab/nexttrace/trace"
"github.com/xgadget-lab/nexttrace/util"
)
func TestPrintTraceRouteNav(t *testing.T) {
PrintTraceRouteNav(util.DomainLookUp("1.1.1.1"), "1.1.1.1", "dataOrigin")
PrintTraceRouteNav(util.DomainLookUp("1.1.1.1", false), "1.1.1.1", "dataOrigin")
}
var testGeo = &ipgeo.IPGeoData{

View File

@@ -7,7 +7,7 @@ import (
)
func RealtimePrinter(res *trace.Result, ttl int) {
fmt.Print(ttl)
fmt.Print(ttl + 1)
for i := range res.Hops[ttl] {
HopPrinter(res.Hops[ttl][i])
}

View File

@@ -2,9 +2,10 @@ package printer
import (
"fmt"
"github.com/xgadget-lab/nexttrace/ipgeo"
"strings"
"github.com/xgadget-lab/nexttrace/ipgeo"
"github.com/xgadget-lab/nexttrace/trace"
"github.com/fatih/color"
@@ -38,7 +39,7 @@ func TracerouteTablePrinter(res *trace.Result) {
if data.City != "" {
tbl.AddRow(data.Hop, data.IP, data.Latency, data.Asnumber, data.Country+", "+data.Prov+", "+data.City, data.Owner)
} else {
tbl.AddRow(data.Hop, data.IP, data.Latency, data.Asnumber, data.Country, data.Owner)
tbl.AddRow(data.Hop, data.IP, data.Latency, data.Asnumber, data.Country + ", " + data.Prov, data.Owner)
}
}
@@ -73,16 +74,18 @@ func tableDataGenerator(h trace.Hop) *rowData {
Hop: fmt.Sprint(h.TTL),
IP: IP,
Latency: lantency,
Country: "局域网",
Owner: "腾讯云",
Country: "LAN Address",
Prov: "LAN Address",
Owner: "",
}
} else if strings.HasPrefix(IP, "11.") {
return &rowData{
Hop: fmt.Sprint(h.TTL),
IP: IP,
Latency: lantency,
Country: "局域网",
Owner: "阿里云",
Country: "LAN Address",
Prov: "LAN Address",
Owner: "",
}
}

View File

@@ -1,6 +1,12 @@
#!/bin/bash
PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
export PATH
expert=False
#是否开启全部选项
if [[ $1 == "--expert" ]]; then
expert=True
echo "已开启全部选项"
fi
Green_font="\033[32m" && Red_font="\033[31m" && Font_suffix="\033[0m"
Info="${Green_font}[Info]${Font_suffix}"
Error="${Red_font}[Error]${Font_suffix}"
@@ -17,229 +23,302 @@ echo -e "${Green_font}
${Font_suffix}"
check_root() {
[[ "$(id -u)" != "0" ]] && echo -e "${Error} must be root user !" && exit 1
[[ "$(id -u)" != "0" ]] && echo -e "${Error} must be root user !" && exit 1
}
checkNexttrace() {
echo -e "${Info} 正在检查Nexttrace..."
if curl -sL -O "https://github.com/xgadget-lab/nexttrace/raw/main/nt_install.sh" || curl -sL -O "https://github.com/xgadget-lab/nexttrace/raw/main/nt_install.sh"; then
bash nt_install.sh --auto > /dev/null
if $(which nexttrace >/dev/null 2>&1); then
echo -e "${Info} 您已安装NextTrace,是否检查更新?"
if ask_if "输入n/y以选择:[n]"; then
echo -e "${Info} 正在检查更新..."
else
return
fi
}
ask_if()
{
local choice=""
while [ "$choice" != "y" ] && [ "$choice" != "n" ]
do
echo -e "${Info} $1"
read choice
done
[ $choice == y ] && return 0
return 1
else
echo -e "${Info} 您未安装NextTrace正在开始安装..."
mkdir -p ~/.nexttrace/
cat >~/.nexttrace/ntraceConfig.yml <<EOF
Token:
LeoMoeAPI: NextTraceDemo
IPInfo: ""
Preference:
AlwaysRoutePath: true
EOF
fi
if curl -sL -O ${URLprefix}"https://raw.githubusercontent.com/xgadget-lab/nexttrace/main/nt_install.sh" || curl -sL -O ${URLprefix}"https://raw.githubusercontent.com/xgadget-lab/nexttrace/main/nt_install.sh"; then
bash nt_install.sh #--auto #>/dev/null
fi
}
getLocation() {
echo -e "${Info} 正在获取地理位置信息..."
countryCode=$(curl -s "http://ip-api.com/line/?fields=countryCode")
if [ "$countryCode" == "CN" ]; then
read -r -p "检测到国内网络环境,是否使用镜像下载以加速(n/y)[y]" input
case $input in
[yY][eE][sS] | [yY])
URLprefix="https://ghproxy.com/"
;;
[nN][oO] | [nN])
URLprefix=""
echo -e "${Info} 您选择了不使用镜像,下载可能会变得异常缓慢,或者失败"
;;
*)
URLprefix="https://ghproxy.com/"
;;
esac
fi
}
ask_if() {
local choice=""
echo -e "${Info} $1"
read -r choice
[[ $choice == y ]] && return 0
return 1
}
checkSystemDistribution() {
case "$OSTYPE" in
darwin*)
osDistribution="darwin"
;;
linux*)
osDistribution="linux"
;;
*)
echo -e "${Info} unknown: $OSTYPE"
exit 1
;;
esac
}
#检查脚本更新
check_script_update()
{
[ "$(md5sum "${BASH_SOURCE[0]}" | awk '{print $1}')" == "$(md5sum <(curl -sL "https://github.com/xgadget-lab/nexttrace/raw/main/quicklytest.sh") | awk '{print $1}')" ] && return 1 || return 0
check_script_update() {
if [[ ${osDistribution} == "darwin" ]]; then
[ "$(md5 <"${BASH_SOURCE[0]}")" == "$(curl -sL ${URLprefix}"https://raw.githubusercontent.com/xgadget-lab/nexttrace/main/quicklytest.sh" | md5)" ] && return 1 || return 0
else
[ "$(md5sum "${BASH_SOURCE[0]}" | awk '{print $1}')" == "$(md5sum <(curl -sL ${URLprefix}"https://raw.githubusercontent.com/xgadget-lab/nexttrace/main/quicklytest.sh") | awk '{print $1}')" ] && return 1 || return 0
fi
}
#更新脚本
update_script()
{
if curl -sL -o "${BASH_SOURCE[0]}" "https://github.com/xgadget-lab/nexttrace/raw/main/quicklytest.sh" || curl -sL -o "${BASH_SOURCE[0]}" "https://github.com/xgadget-lab/nexttrace/raw/main/quicklytest.sh"; then
echo -e "${Info} 脚本更新完成,正在重启脚本..."
exec bash ${BASH_SOURCE[0]}
else
echo -e "${Info} 更新脚本失败!"
exit 1
fi
update_script() {
if curl -sL -o "${BASH_SOURCE[0]}" ${URLprefix}"https://raw.githubusercontent.com/xgadget-lab/nexttrace/main/quicklytest.sh" || curl -sL -o "${BASH_SOURCE[0]}" ${URLprefix}"https://raw.githubusercontent.com/xgadget-lab/nexttrace/main/quicklytest.sh"; then
echo -e "${Info} quickylytest.sh更新完成,正在重启脚本..."
exec bash "${BASH_SOURCE[0]}"
else
echo -e "${Info} 更新quickylytest.sh失败"
exit 1
fi
}
ask_update_script()
{
if check_script_update; then
echo -e "${Info} 脚本可升级"
ask_if "是否升级脚本?(y/n)" && update_script
else
echo -e "${Info} 脚本已经是最新版本"
fi
ask_update_script() {
if check_script_update; then
echo -e "${Info} quickylytest.sh可升级"
ask_if "是否升级脚本?(n/y)[n]" && update_script
else
echo -e "${Info} quickylytest.sh已经是最新版本"
fi
}
check_mode() {
echo -e "${Info} Nexttrace目前支持以下三种协议发起Traceroute请求:\n1.ICMP\n2.TCP(速度最快,但部分节点不支持)\n3.UDP\n(IPv6暂只支持ICMP模式)" && read -p "输入数字以选择:" node
while [[ ! "${node}" =~ ^[1-3]$ ]]; do
echo -e "${Error} 无效输入"
echo -e "${Info} 请重新选择" && read -p "输入数字以选择:" node
done
if [[ $expert != True ]] ; then
TRACECMD="nexttrace"
return;
fi
echo -e "${Info} Nexttrace目前支持以下三种协议发起Traceroute请求:\n1.ICMP\n2.TCP(速度最快,但部分节点不支持)\n3.UDP\n(IPv6暂只支持ICMP模式)" && read -r -p "输入数字以选择:" node
[[ "${node}" == "1" ]] && TRACECMD="nexttrace"
[[ "${node}" == "2" ]] && TRACECMD="nexttrace -T"
[[ "${node}" == "3" ]] && TRACECMD="nexttrace -U"
while [[ ! "${node}" =~ ^[1-3]$ ]]; do
echo -e "${Error} 无效输入"
echo -e "${Info} 请重新选择" && read -r -p "输入数字以选择:" node
done
[[ "${node}" == "1" ]] && TRACECMD="nexttrace"
[[ "${node}" == "2" ]] && TRACECMD="nexttrace -T"
[[ "${node}" == "3" ]] && TRACECMD="nexttrace -U"
echo -e "${Info} 结果是否制表?(制表模式为非实时显示)"
if ask_if "输入n/y以选择模式:[n]"; then
TRACECMD=${TRACECMD}" -rdns -table"
# ##Route-Path功能还未完善,临时替代:
# [[ "${node}" == "2" ]] && TRACECMD=${TRACECMD}" -report"
# ##
else
TRACECMD=${TRACECMD}" -rdns"
# ##Route-Path功能还未完善,临时替代:
# [[ "${node}" == "1" ]] && TRACECMD=${TRACECMD}" -report"
# [[ "${node}" == "2" ]] && TRACECMD=${TRACECMD}" -report"
# ##
fi
# echo -e "${Info} 是否输出Route-Path?"
# ask_if "输入n/y以选择模式:[n]" && TRACECMD=${TRACECMD}" -report"
echo -e "${Info} 结果是否制表?(制表模式为非实时显示)"
if ask_if "输入y/n以选择模式:" ; then
TRACECMD=${TRACECMD}" -rdns -table"
##Route-Path功能还未完善,临时替代:
[[ "${node}" == "2" ]] && TRACECMD=${TRACECMD}" -report"
##
else
TRACECMD=${TRACECMD}" -rdns -realtime"
##Route-Path功能还未完善,临时替代:
[[ "${node}" == "1" ]] && TRACECMD=${TRACECMD}" -report"
##
fi
#echo -e "${Info} 是否输出Route-Path?"
#ask_if "输入y/n以选择模式:" && TRACECMD=${TRACECMD}" -report"
}
test_single() {
echo -e "${Info} 请输入你要测试的目标 ip :"
read -p "输入 ip 地址:" ip
echo -e "${Info} 请输入你要测试的目标 ip :"
read -r -p "输入 ip 地址:" ip
while [[ -z "${ip}" ]]; do
echo -e "${Error} 无效输入"
echo -e "${Info} 请重新输入" && read -p "输入 ip 地址:" ip
done
while [[ -z "${ip}" ]]; do
echo -e "${Error} 无效输入"
echo -e "${Info} 请重新输入" && read -r -p "输入 ip 地址:" ip
done
${TRACECMD} ${ip} | grep -v -E 'NextTrace|XGadget-lab|Data\ Provider'
${TRACECMD} "${ip}" | grep -v -E 'NextTrace|XGadget-lab|Data\ Provider'
repeat_test_single
repeat_test_single
}
repeat_test_single() {
echo -e "${Info} 是否继续测试其他目标 ip ?"
if ask_if "输入y/n以选择:" ; then
test_single
else
echo -e "${Info} 退出脚本 ..." && exit 0
fi
echo -e "${Info} 是否继续测试其他目标 ip ?"
if ask_if "输入n/y以选择:[n]"; then
test_single
else
echo -e "${Info} 退出脚本 ..." && exit 0
fi
}
test_alternative() {
select_alternative
set_alternative
result_alternative
select_alternative
set_alternative
result_alternative
}
select_alternative() {
echo -e "${Info} 选择需要测速的目标网络: \n1.中国电信\n2.中国联通\n3.中国移动\n4.教育网"
read -p "输入数字以选择:" ISP
echo -e "${Info} 选择需要测速的目标网络: \n1.中国电信\n2.中国联通\n3.中国移动\n4.教育网"
read -r -p "输入数字以选择:" ISP
while [[ ! "${ISP}" =~ ^[1-4]$ ]]; do
echo -e "${Error} 无效输入"
echo -e "${Info} 请重新选择" && read -p "输入数字以选择:" ISP
done
while [[ ! "${ISP}" =~ ^[1-4]$ ]]; do
echo -e "${Error} 无效输入"
echo -e "${Info} 请重新选择" && read -r -p "输入数字以选择:" ISP
done
}
set_alternative() {
[[ "${ISP}" == "1" ]] && node_1
[[ "${ISP}" == "2" ]] && node_2
[[ "${ISP}" == "3" ]] && node_3
[[ "${ISP}" == "4" ]] && node_4
[[ "${ISP}" == "1" ]] && node_1
[[ "${ISP}" == "2" ]] && node_2
[[ "${ISP}" == "3" ]] && node_3
[[ "${ISP}" == "4" ]] && node_4
}
node_1() {
echo -e "1.上海电信(天翼云)\n2.厦门电信CN2\n3.北京电信\n4.江苏电信\n5.广东深圳电信\n6.广州电信(天翼云)\n7.浙江电信" && read -p "输入数字以选择:" node
echo -e "1.上海电信(天翼云)\n2.厦门电信CN2\n3.北京电信\n4.江苏电信\n5.广东深圳电信\n6.广州电信(天翼云)\n7.浙江电信" && read -r -p "输入数字以选择:" node
while [[ ! "${node}" =~ ^[1-7]$ ]]; do
echo -e "${Error} 无效输入"
echo -e "${Info} 请重新选择" && read -p "输入数字以选择:" node
done
while [[ ! "${node}" =~ ^[1-7]$ ]]; do
echo -e "${Error} 无效输入"
echo -e "${Info} 请重新选择" && read -r -p "输入数字以选择:" node
done
[[ "${node}" == "1" ]] && ISP_name="上海电信" && ip=101.89.132.9
[[ "${node}" == "2" ]] && ISP_name="厦门电信CN2" && ip=117.28.254.129
[[ "${node}" == "3" ]] && ISP_name="北京电信" && ip=120.92.180.135
[[ "${node}" == "4" ]] && ISP_name="江苏电信" && ip=221.229.173.233
[[ "${node}" == "5" ]] && ISP_name="广东深圳电信" && ip=116.6.211.41
[[ "${node}" == "6" ]] && ISP_name="广州电信(天翼云)" && ip=14.215.116.1
[[ "${node}" == "7" ]] && ISP_name="浙江电信" && ip=115.236.169.86
[[ "${node}" == "1" ]] && ISP_name="上海电信" && ip=101.89.132.9
[[ "${node}" == "2" ]] && ISP_name="厦门电信CN2" && ip=117.28.254.129
[[ "${node}" == "3" ]] && ISP_name="北京电信" && ip=120.92.180.135
[[ "${node}" == "4" ]] && ISP_name="江苏电信" && ip=221.229.173.233
[[ "${node}" == "5" ]] && ISP_name="广东深圳电信" && ip=116.6.211.41
[[ "${node}" == "6" ]] && ISP_name="广州电信(天翼云)" && ip=14.215.116.1
[[ "${node}" == "7" ]] && ISP_name="浙江电信" && ip=115.236.169.86
}
node_2() {
echo -e "1.上海联通\n2.重庆联通\n3.北京联通\n4.安徽合肥联通\n5.江苏南京联通\n6.浙江杭州联通\n7.广东联通" && read -p "输入数字以选择:" node
echo -e "1.上海联通\n2.重庆联通\n3.北京联通\n4.安徽合肥联通\n5.江苏南京联通\n6.浙江杭州联通\n7.广东联通" && read -r -p "输入数字以选择:" node
while [[ ! "${node}" =~ ^[1-7]$ ]]; do
echo -e "${Error} 无效输入"
echo -e "${Info} 请重新选择" && read -p "输入数字以选择:" node
done
while [[ ! "${node}" =~ ^[1-7]$ ]]; do
echo -e "${Error} 无效输入"
echo -e "${Info} 请重新选择" && read -r -p "输入数字以选择:" node
done
[[ "${node}" == "1" ]] && ISP_name="上海联通" && ip=220.196.252.174
[[ "${node}" == "2" ]] && ISP_name="重庆联通" && ip=113.207.32.65
[[ "${node}" == "3" ]] && ISP_name="北京联通" && ip=202.106.54.150
[[ "${node}" == "4" ]] && ISP_name="安徽合肥联通" && ip=112.122.10.26
[[ "${node}" == "5" ]] && ISP_name="江苏联通" && ip=112.85.231.129
[[ "${node}" == "6" ]] && ISP_name="浙江联通" && ip=60.12.214.156
[[ "${node}" == "7" ]] && ISP_name="广东联通" && ip=58.252.2.194
[[ "${node}" == "1" ]] && ISP_name="上海联通" && ip=220.196.252.174
[[ "${node}" == "2" ]] && ISP_name="重庆联通" && ip=113.207.32.65
[[ "${node}" == "3" ]] && ISP_name="北京联通" && ip=202.106.54.150
[[ "${node}" == "4" ]] && ISP_name="安徽合肥联通" && ip=112.122.10.26
[[ "${node}" == "5" ]] && ISP_name="江苏联通" && ip=112.85.231.129
[[ "${node}" == "6" ]] && ISP_name="浙江联通" && ip=60.12.214.156
[[ "${node}" == "7" ]] && ISP_name="广东联通" && ip=58.252.2.194
}
node_3() {
echo -e "1.上海移动\n2.四川成都移动\n3.北京移动\n4.浙江杭州移动\n5.广东移动\n6.江苏移动\n7.浙江移动" && read -p "输入数字以选择:" node
echo -e "1.上海移动\n2.四川成都移动\n3.北京移动\n4.浙江杭州移动\n5.广东移动\n6.江苏移动\n7.浙江移动" && read -r -p "输入数字以选择:" node
while [[ ! "${node}" =~ ^[1-7]$ ]]; do
echo -e "${Error} 无效输入"
echo -e "${Info} 请重新选择" && read -p "输入数字以选择:" node
done
while [[ ! "${node}" =~ ^[1-7]$ ]]; do
echo -e "${Error} 无效输入"
echo -e "${Info} 请重新选择" && read -r -p "输入数字以选择:" node
done
[[ "${node}" == "1" ]] && ISP_name="上海移动" && ip=117.184.42.114
[[ "${node}" == "2" ]] && ISP_name="四川成都移动" && ip=183.221.247.9
[[ "${node}" == "3" ]] && ISP_name="北京移动" && ip=111.13.217.125
[[ "${node}" == "4" ]] && ISP_name="浙江移动" && ip=183.246.69.139
[[ "${node}" == "5" ]] && ISP_name="广东移动" && ip=221.179.44.57
[[ "${node}" == "6" ]] && ISP_name="江苏移动" && ip=120.195.6.129
[[ "${node}" == "7" ]] && ISP_name="浙江移动" && ip=183.246.69.139
[[ "${node}" == "1" ]] && ISP_name="上海移动" && ip=117.184.42.114
[[ "${node}" == "2" ]] && ISP_name="四川成都移动" && ip=183.221.247.9
[[ "${node}" == "3" ]] && ISP_name="北京移动" && ip=111.13.217.125
[[ "${node}" == "4" ]] && ISP_name="浙江移动" && ip=183.246.69.139
[[ "${node}" == "5" ]] && ISP_name="广东移动" && ip=221.179.44.57
[[ "${node}" == "6" ]] && ISP_name="江苏移动" && ip=120.195.6.129
[[ "${node}" == "7" ]] && ISP_name="浙江移动" && ip=183.246.69.139
}
node_4() {
ISP_name="北京教育网" && ip=211.68.69.240
ISP_name="北京教育网" && ip=211.68.69.240
}
result_alternative() {
echo -e "${Info} 测试路由 到 ${ISP_name} 中 ..."
${TRACECMD} ${ip} | grep -v -E 'NextTrace|XGadget-lab|Data\ Provider'
echo -e "${Info} 测试路由 到 ${ISP_name} 完成 "
repeat_test_alternative
result_alternative() {
echo -e "${Info} 测试路由 到 ${ISP_name} 中 ..."
${TRACECMD} ${ip} | grep -v -E 'NextTrace|XGadget-lab|Data\ Provider'
echo -e "${Info} 测试路由 到 ${ISP_name} 完成 "
repeat_test_alternative
}
repeat_test_alternative() {
echo -e "${Info} 是否继续测试其他节点?"
if ask_if "输入y/n以选择:" ; then
test_alternative
else
echo -e "${Info} 退出脚本 ..." && exit 0
fi
echo -e "${Info} 是否继续测试其他节点?"
if ask_if "输入n/y以选择:[n]"; then
test_alternative
else
echo -e "${Info} 退出脚本 ..." && exit 0
fi
}
test_all() {
result_all '116.6.211.41' '广东东莞CN2'
result_all '116.6.211.41' '广东东莞CN2'
result_all '101.95.110.149' '上海电信'
result_all '101.95.110.149' '上海电信'
result_all '112.85.231.129' '江苏徐州联通'
result_all '112.85.231.129' '江苏徐州联通'
result_all '120.199.239.1' '浙江杭州移动'
result_all '120.199.239.1' '浙江杭州移动'
result_all '211.68.69.240' '北京教育网'
result_all '211.68.69.240' '北京教育网'
echo -e "${Info} 四网路由快速测试 已完成 "
echo -e "${Info} 四网路由快速测试 已完成 "
}
result_all() {
ISP_name=$2
echo -e "${Info} 测试路由 到 ${ISP_name} 中 ..."
${TRACECMD} $1 | grep -v -E 'NextTrace|XGadget-lab|Data\ Provider'
echo -e "${Info} 测试路由 到 ${ISP_name} 完成 "
ISP_name=$2
echo -e "${Info} 测试路由 到 ${ISP_name} 中 ..."
${TRACECMD} "${1}" | grep -v -E 'NextTrace|XGadget-lab|Data\ Provider'
echo -e "${Info} 测试路由 到 ${ISP_name} 完成 "
}
check_root
checkSystemDistribution
getLocation
ask_update_script
checkNexttrace
check_mode
echo -e "${Info} 选择你要使用的功能: "
echo -e "1.选择一个节点进行测试\n2.四网路由快速测试\n3.手动输入 ip 进行测试"
read -p "输入数字以选择:" function
read -r -p "输入数字以选择:" function
while [[ ! "${function}" =~ ^[1-3]$ ]]; do
echo -e "${Error} 缺少或无效输入"
echo -e "${Info} 请重新选择" && read -p "输入数字以选择:" function
echo -e "${Error} 缺少或无效输入"
echo -e "${Info} 请重新选择" && read -r -p "输入数字以选择:" function
done
if [[ "${function}" == "1" ]]; then
test_alternative
test_alternative
elif [[ "${function}" == "2" ]]; then
test_all
test_all
else
test_single
test_single
fi

View File

@@ -1,6 +1,7 @@
package trace
import (
"encoding/binary"
"log"
"net"
"os"
@@ -74,19 +75,32 @@ func (t *ICMPTracer) listenICMP() {
if msg.N == nil {
continue
}
rm, err := icmp.ParseMessage(1, msg.Msg[:*msg.N])
if err != nil {
log.Println(err)
continue
if binary.BigEndian.Uint16(msg.Msg[32:34]) != uint16(os.Getpid()&0xffff) {
// 如果类型为应答消息且应答消息包的进程ID与主进程相同时不跳过
if msg.Msg[0] != 0 || binary.BigEndian.Uint16(msg.Msg[4:6]) != uint16(os.Getpid()&0xffff) {
continue
}
}
switch rm.Type {
case ipv4.ICMPTypeTimeExceeded:
t.handleICMPMessage(msg, 0, rm.Body.(*icmp.TimeExceeded).Data)
case ipv4.ICMPTypeEchoReply:
t.handleICMPMessage(msg, 1, rm.Body.(*icmp.Echo).Data)
default:
// log.Println("received icmp message of unknown type", rm.Type)
dstip := net.IP(msg.Msg[24:28])
if dstip.Equal(t.DestIP) || dstip.Equal(net.IPv4zero) {
// 匹配再继续解析包,否则直接丢弃
rm, err := icmp.ParseMessage(1, msg.Msg[:*msg.N])
if err != nil {
log.Println(err)
continue
}
switch rm.Type {
case ipv4.ICMPTypeTimeExceeded:
t.handleICMPMessage(msg, 0, rm.Body.(*icmp.TimeExceeded).Data)
case ipv4.ICMPTypeEchoReply:
t.handleICMPMessage(msg, 1, rm.Body.(*icmp.Echo).Data)
default:
// log.Println("received icmp message of unknown type", rm.Type)
}
}
}
}

View File

@@ -88,18 +88,21 @@ func (t *TCPTracer) listenICMP() {
if msg.N == nil {
continue
}
rm, err := icmp.ParseMessage(1, msg.Msg[:*msg.N])
if err != nil {
log.Println(err)
continue
}
switch rm.Type {
case ipv4.ICMPTypeTimeExceeded:
t.handleICMPMessage(msg, rm.Body.(*icmp.TimeExceeded).Data)
case ipv4.ICMPTypeDestinationUnreachable:
t.handleICMPMessage(msg, rm.Body.(*icmp.DstUnreach).Data)
default:
//log.Println("received icmp message of unknown type", rm.Type)
dstip := net.IP(msg.Msg[24:28])
if dstip.Equal(t.DestIP) {
rm, err := icmp.ParseMessage(1, msg.Msg[:*msg.N])
if err != nil {
log.Println(err)
continue
}
switch rm.Type {
case ipv4.ICMPTypeTimeExceeded:
t.handleICMPMessage(msg, rm.Body.(*icmp.TimeExceeded).Data)
case ipv4.ICMPTypeDestinationUnreachable:
t.handleICMPMessage(msg, rm.Body.(*icmp.DstUnreach).Data)
default:
//log.Println("received icmp message of unknown type", rm.Type)
}
}
}
}

View File

@@ -39,11 +39,11 @@ func formatIpGeoData(ip string, data *ipgeo.IPGeoData) string {
// TODO: 判断阿里云和腾讯云内网,数据不足,有待进一步完善
// TODO: 移动IDC判断到Hop.fetchIPData函数减少API调用
if strings.HasPrefix(ip, "9.") {
res = append(res, "局域网", "腾讯云")
res = append(res, "LAN Address", "")
} else if strings.HasPrefix(ip, "11.") {
res = append(res, "局域网", "阿里云")
res = append(res, "LAN Address", "")
} else if data.Country == "" {
res = append(res, "局域网")
res = append(res, "LAN Address")
} else {
// 有些IP的归属信息为空这个时候将ISP的信息填入
if data.Owner == "" {

View File

@@ -25,7 +25,7 @@ func LocalIPPort(dstip net.IP) (net.IP, int) {
return nil, -1
}
func DomainLookUp(host string) net.IP {
func DomainLookUp(host string, ipv4Only bool) net.IP {
ips, err := net.LookupIP(host)
if err != nil {
fmt.Println("Domain " + host + " Lookup Fail.")
@@ -36,17 +36,20 @@ func DomainLookUp(host string) net.IP {
var ipv6Flag = false
for _, ip := range ips {
ipSlice = append(ipSlice, ip)
// 仅返回ipv4的ip
// if ip.To4() != nil {
// ipSlice = append(ipSlice, ip)
// } else {
// ipv6Flag = true
// }
if ipv4Only {
// 仅返回ipv4的ip
if ip.To4() != nil {
ipSlice = append(ipSlice, ip)
} else {
ipv6Flag = true
}
} else {
ipSlice = append(ipSlice, ip)
}
}
if ipv6Flag {
fmt.Println("[Info] IPv6 Traceroute is not supported right now.")
fmt.Println("[Info] IPv6 TCP/UDP Traceroute is not supported right now.")
if len(ipSlice) == 0 {
os.Exit(0)
}