From c2eebca25cba4fc6ca16dd46341656233f3b9fba Mon Sep 17 00:00:00 2001 From: tsosunchia <59512455+tsosunchia@users.noreply.github.com> Date: Thu, 2 Mar 2023 18:38:42 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E6=AD=A3IPInfo=20BUG=20=E5=92=8C?= =?UTF-8?q?=E5=A2=9E=E5=8A=A0IPInfoLocal?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 34 ++++++++++++++++------------- README_zh_CN.md | 44 +++++++++++++++++++++++-------------- cmd/cmd.go | 4 ++-- go.mod | 1 + go.sum | 2 ++ ipgeo/ipgeo.go | 2 ++ ipgeo/ipinfo.go | 5 +++-- ipgeo/ipinfoLocal.go | 52 ++++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 109 insertions(+), 35 deletions(-) create mode 100644 ipgeo/ipinfoLocal.go diff --git a/README.md b/README.md index 1c03507..72a62cc 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ nexttrace --no-rdns www.bbix.net nexttrace --route-path www.time.com.my ``` -`NextTrace` supports users to select their own IP API (currently supports: `LeoMoeAPI`, `IP.SB`, `IPInfo`, `IPInsight`, `IPAPI.com`) +`NextTrace` supports users to select their own IP API (currently supports: `LeoMoeAPI`, `IP.SB`, `IPInfo`, `IPInsight`, `IPAPI.com`, `Ip2region`, `IPInfoLocal`) ```bash # You can specify the IP database by yourself [IP.SB here], if not specified, LeoMoeAPI will be used @@ -158,18 +158,18 @@ All NextTrace IP geolocation `API DEMO` can refer to [here](https://github.com/x ### For full usage list, please refer to the usage menu ```shell -usage: nexttrace [-h|--help] [-T|--tcp] [-U|--udp] [-F|--fast-trace] [-p|--port +Usage: nexttrace [-h|--help] [-T|--tcp] [-U|--udp] [-F|--fast-trace] [-p|--port ] [-q|--queries ] [--parallel-requests ] [-m|--max-hops ] [-d|--data-provider - (IP.SB|IPInfo|IPInsight|IPAPI.com)] [-n|--no-rdns] - [-a|--always-rdns] [-P|--route-path] [-r|--report] - [-o|--output] [-t|--table] [-c|--classic] [-f|--first - ] [-M|--map] [-v|--version] [-s|--source ""] - [-D|--dev ""] [-R|--route] [-z|--send-time ] - [-i|--ttl-time ] [-g|--language (en|cn)] [IP Address - or Domain] - - An open source visual route tracking CLI tool + (Ip2region|ip2region|IP.SB|ip.sb|IPInfo|ipinfo|IPInsight|ipinsight|IPAPI.com|ip-api.com|IPInfoLocal|ipinfolocal)] + [-n|--no-rdns] [-a|--always-rdns] [-P|--route-path] + [-r|--report] [--dn42] [-o|--output] [-t|--table] + [-c|--classic] [-f|--first ] [-M|--map] + [-v|--version] [-s|--source ""] [-D|--dev ""] + [-R|--route] [-z|--send-time ] [-i|--ttl-time + ] [_positionalArg_nexttrace_25 ""] + [--dot-server (dnssb|aliyun|dnspod|google|cloudflare)] + [-g|--language (en|cn)] Arguments: @@ -194,9 +194,9 @@ Arguments: 18 -m --max-hops Set the max number of hops (max TTL to be reached). Default: 30 - -d --data-provider Choose IP Geograph Data Provider - [LeoMoeAPI,IP.SB, IPInfo, IPInsight, - IPAPI.com]. Default: LeoMoeAPI + -d --data-provider Choose IP Geograph Data Provider [IP.SB, + IPInfo, IPInsight, IP-API.com, Ip2region, + IPInfoLocal]. Default: LeoMoeAPI -n --no-rdns Do not resolve IP addresses to their domain names -a --always-rdns Always resolve IP addresses to their @@ -204,6 +204,7 @@ Arguments: -P --route-path Print traceroute hop path by ASN and location -r --report output using report mode + --dn42 DN42 Mode -o --output Write trace result to file (RealTimePrinter ONLY) -t --table Output trace results as table @@ -211,7 +212,7 @@ Arguments: BestTrace -f --first Start from the first_ttl hop (instead from 1). Default: 1 - -M --map Disable Print Trace Map Function + -M --map Disable Print Trace Map -v --version Print version info and exit -s --source Use source src_addr for outgoing packets -D --dev Use the following Network Devices as the @@ -224,6 +225,9 @@ Arguments: groups by TTL. Useful when some routers use rate-limit for ICMP messages. Default: 500 + --_positionalArg_nexttrace_25 IP Address or domain name + --dot-server Use DoT Server for DNS Parse [dnssb, + aliyun, dnspod, google, cloudflare] -g --language Choose the language for displaying [en, cn]. Default: cn ``` diff --git a/README_zh_CN.md b/README_zh_CN.md index b3ce6b5..c662613 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -141,13 +141,14 @@ nexttrace --no-rdns www.bbix.net nexttrace --route-path www.time.com.my ``` -`NextTrace`支持用户自主选择 IP 数据库(目前支持:`LeoMoeAPI`, `IP.SB`, `IPInfo`, `IPInsight`, `IPAPI.com`) +`NextTrace`支持用户自主选择 IP 数据库(目前支持:`LeoMoeAPI`, `IP.SB`, `IPInfo`, `IPInsight`, `IPAPI.com`, `Ip2region`, `IPInfoLocal`) ```bash # 可以自行指定IP数据库[此处为IP.SB],不指定则默认为LeoMoeAPI nexttrace --data-provider IP.SB ## 特别的:其中 ipinfo API 需要从 ipinfo 自行购买服务,如有需要可以 clone 本项目添加其提供的 token 自行编译 ## TOKEN填写路径:ipgeo/tokens.go +## 特别的:对于 `Ip2region`, `IPInfoLocal` ## 另外:由于IP.SB被滥用比较严重,会经常出现无法查询的问题,请知悉。 ## IPAPI.com限制调用较为严格,如有查询不到的情况,请几分钟后再试。 @@ -171,12 +172,16 @@ nexttrace -T -q 2 --parallel-requests 1 -t -R 2001:4860:4860::8888 Usage: nexttrace [-h|--help] [-T|--tcp] [-U|--udp] [-F|--fast-trace] [-p|--port ] [-q|--queries ] [--parallel-requests ] [-m|--max-hops ] [-d|--data-provider - (IP.SB|IPInfo|IPInsight|IPAPI.com)] [-n|--no-rdns] - [-r|--route-path] [-o|--output] [-t|--table] [-c|--classic] - [-f|--first ] [-M|--map] [-v|--version] [-s|--source - ""] [-D|--dev ""] [-R|--route] [-z|--send-time - ] [-i|--ttl-time ] - [IP Address or Domain name] + (Ip2region|ip2region|IP.SB|ip.sb|IPInfo|ipinfo|IPInsight|ipinsight|IPAPI.com|ip-api.com|IPInfoLocal|ipinfolocal)] + [-n|--no-rdns] [-a|--always-rdns] [-P|--route-path] + [-r|--report] [--dn42] [-o|--output] [-t|--table] + [-c|--classic] [-f|--first ] [-M|--map] + [-v|--version] [-s|--source ""] [-D|--dev ""] + [-R|--route] [-z|--send-time ] [-i|--ttl-time + ] [_positionalArg_nexttrace_25 ""] + [--dot-server (dnssb|aliyun|dnspod|google|cloudflare)] + [-g|--language (en|cn)] + Arguments: -h --help Print help information @@ -200,13 +205,17 @@ Arguments: 18 -m --max-hops Set the max number of hops (max TTL to be reached). Default: 30 - -d --data-provider Choose IP Geograph Data Provider - [LeoMoeAPI,IP.SB, IPInfo, IPInsight, - IPAPI.com]. Default: LeoMoeAPI - -n --no-rdns Do not resolve IP addresses to their + -d --data-provider Choose IP Geograph Data Provider [IP.SB, + IPInfo, IPInsight, IP-API.com, Ip2region, + IPInfoLocal]. Default: LeoMoeAPI + -n --no-rdns Do not resolve IP addresses to their domain names - -r --route-path Print traceroute hop path by ASN and + -a --always-rdns Always resolve IP addresses to their + domain names + -P --route-path Print traceroute hop path by ASN and location + -r --report output using report mode + --dn42 DN42 Mode -o --output Write trace result to file (RealTimePrinter ONLY) -t --table Output trace results as table @@ -214,7 +223,7 @@ Arguments: BestTrace -f --first Start from the first_ttl hop (instead from 1). Default: 1 - -M --map Disable Print Trace Map Function + -M --map Disable Print Trace Map -v --version Print version info and exit -s --source Use source src_addr for outgoing packets -D --dev Use the following Network Devices as the @@ -222,11 +231,14 @@ Arguments: -R --route Show Routing Table [Provided By BGP.Tools] -z --send-time Set the time interval for sending every packet. Useful when some routers use - rate-limit for ICMP messages.. Default: 0 + rate-limit for ICMP messages. Default: 100 -i --ttl-time Set the time interval for sending packets groups by TTL. Useful when some routers - use rate-limit for ICMP messages.. - Default: 500 + use rate-limit for ICMP messages. Default: + 500 + --_positionalArg_nexttrace_25 IP Address or domain name + --dot-server Use DoT Server for DNS Parse [dnssb, + aliyun, dnspod, google, cloudflare] -g --language Choose the language for displaying [en, cn]. Default: cn ``` diff --git a/cmd/cmd.go b/cmd/cmd.go index 57253c3..02b2a9e 100644 --- a/cmd/cmd.go +++ b/cmd/cmd.go @@ -37,8 +37,8 @@ func Excute() { 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)"}) - dataOrigin := parser.Selector("d", "data-provider", []string{"Ip2region", "ip2region", "IP.SB", "ip.sb", "IPInfo", "ipinfo", "IPInsight", "ipinsight", "IPAPI.com", "ip-api.com"}, &argparse.Options{Default: "LeoMoeAPI", - Help: "Choose IP Geograph Data Provider [IP.SB, IPInfo, IPInsight, IP-API.com, Ip2region]"}) + dataOrigin := parser.Selector("d", "data-provider", []string{"Ip2region", "ip2region", "IP.SB", "ip.sb", "IPInfo", "ipinfo", "IPInsight", "ipinsight", "IPAPI.com", "ip-api.com", "IPInfoLocal", "ipinfolocal"}, &argparse.Options{Default: "LeoMoeAPI", + Help: "Choose IP Geograph Data Provider [IP.SB, IPInfo, IPInsight, IP-API.com, Ip2region, IPInfoLocal]"}) noRdns := parser.Flag("n", "no-rdns", &argparse.Options{Help: "Do not resolve IP addresses to their domain names"}) alwaysRdns := parser.Flag("a", "always-rdns", &argparse.Options{Help: "Always resolve IP addresses to their domain names"}) routePath := parser.Flag("P", "route-path", &argparse.Options{Help: "Print traceroute hop path by ASN and location"}) diff --git a/go.mod b/go.mod index b37be71..16c9ceb 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.20 require ( github.com/akamensky/argparse v1.4.0 github.com/google/gopacket v1.1.19 + github.com/oschwald/maxminddb-golang v1.10.0 github.com/spf13/viper v1.15.0 github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635 golang.org/x/net v0.7.0 diff --git a/go.sum b/go.sum index 2d2cece..7024ea1 100644 --- a/go.sum +++ b/go.sum @@ -153,6 +153,8 @@ github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/Qd github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= 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.10.0 h1:Xp1u0ZhqkSuopaKmk1WwHtjF0H9Hd9181uj2MQ5Vndg= +github.com/oschwald/maxminddb-golang v1.10.0/go.mod h1:Y2ELenReaLAZ0b400URyGwvYxHV1dLIxBuyOsyYjHK0= github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU= github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= diff --git a/ipgeo/ipgeo.go b/ipgeo/ipgeo.go index 532c86d..3aca36d 100644 --- a/ipgeo/ipgeo.go +++ b/ipgeo/ipgeo.go @@ -45,6 +45,8 @@ func GetSource(s string) Source { return IPInfo case "IP2REGION": return IP2Region + case "IPINFOLOCAL": + return IPInfoLocal default: return LeoIP } diff --git a/ipgeo/ipinfo.go b/ipgeo/ipinfo.go index 4433248..746b078 100644 --- a/ipgeo/ipinfo.go +++ b/ipgeo/ipinfo.go @@ -3,6 +3,7 @@ package ipgeo import ( "io/ioutil" "net/http" + "strings" "github.com/tidwall/gjson" ) @@ -21,13 +22,13 @@ func IPInfo(ip string) (*IPGeoData, error) { res := gjson.ParseBytes(body) var country string - + country = res.Get("country").String() if res.Get("country").String() == "HK" || res.Get("country").String() == "TW" { country = "CN" } return &IPGeoData{ - Asnumber: res.Get("asn").Get("asn").String(), + Asnumber: strings.Fields(strings.TrimPrefix(res.Get("org").String(), "AS"))[0], Country: country, City: res.Get("city").String(), Prov: res.Get("region").String(), diff --git a/ipgeo/ipinfoLocal.go b/ipgeo/ipinfoLocal.go new file mode 100644 index 0000000..a3d75c0 --- /dev/null +++ b/ipgeo/ipinfoLocal.go @@ -0,0 +1,52 @@ +package ipgeo + +import ( + "errors" + "github.com/oschwald/maxminddb-golang" + "net" + "os" + "strings" +) + +const ( + ipinfoDataBasePath = "./ipinfoLocal.mmdb" +) + +func IPInfoLocal(ip string) (*IPGeoData, error) { + if _, err := os.Stat(ipinfoDataBasePath); os.IsNotExist(err) { + panic("Cannot find ipinfoLocal.mmdb") + } + region, err := maxminddb.Open(ipinfoDataBasePath) + if err != nil { + panic("Cannot find ipinfoLocal.mmdb") + } + defer func(region *maxminddb.Reader) { + err := region.Close() + if err != nil { + panic(err) + } + }(region) + var record interface{} + searchErr := region.Lookup(net.ParseIP(ip), &record) + if searchErr != nil { + return &IPGeoData{}, errors.New("no results") + } + recordMap := record.(map[string]interface{}) + country_name := recordMap["country_name"].(string) + prov := "" + if recordMap["country"].(string) == "HK" { + country_name = "China" + prov = "Hong Kong" + } + if recordMap["country"].(string) == "TW" { + country_name = "China" + prov = "Taiwan" + } + return &IPGeoData{ + Asnumber: strings.TrimPrefix(recordMap["asn"].(string), "AS"), + Country: country_name, + City: "", + Prov: prov, + Owner: recordMap["as_name"].(string), + }, nil +}