mirror of
https://github.com/nxtrace/NTrace-core.git
synced 2025-08-12 06:26:39 +00:00
102 lines
1.9 KiB
Go
102 lines
1.9 KiB
Go
package dn42
|
|
|
|
import (
|
|
"encoding/csv"
|
|
"net"
|
|
"os"
|
|
"sort"
|
|
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
type GeoFeedRow struct {
|
|
IPNet *net.IPNet
|
|
CIDR string
|
|
LtdCode string
|
|
ISO3166 string
|
|
City string
|
|
ASN string
|
|
IPWhois string
|
|
}
|
|
|
|
func GetGeoFeed(ip string) (GeoFeedRow, bool) {
|
|
rows, err := ReadGeoFeed()
|
|
if err != nil {
|
|
// 处理错误
|
|
panic(err)
|
|
}
|
|
|
|
row, find := FindGeoFeedRow(ip, rows)
|
|
return row, find
|
|
|
|
}
|
|
|
|
func ReadGeoFeed() ([]GeoFeedRow, error) {
|
|
path := viper.Get("geoFeedPath").(string)
|
|
f, err := os.Open(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
defer f.Close()
|
|
|
|
r := csv.NewReader(f)
|
|
rows, err := r.ReadAll()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// 将 CSV 中的每一行转换为 GeoFeedRow 类型,并保存到 rowsSlice 中
|
|
var rowsSlice []GeoFeedRow
|
|
for _, row := range rows {
|
|
cidr := row[0] // 假设第一列是 CIDR 字段
|
|
_, ipnet, err := net.ParseCIDR(cidr)
|
|
if err != nil {
|
|
// 如果解析 CIDR 失败,跳过这一行
|
|
continue
|
|
}
|
|
if len(row) == 4 {
|
|
rowsSlice = append(rowsSlice, GeoFeedRow{
|
|
IPNet: ipnet,
|
|
CIDR: cidr,
|
|
LtdCode: row[1],
|
|
ISO3166: row[2],
|
|
City: row[3],
|
|
})
|
|
} else {
|
|
rowsSlice = append(rowsSlice, GeoFeedRow{
|
|
IPNet: ipnet,
|
|
CIDR: cidr,
|
|
LtdCode: row[1],
|
|
ISO3166: row[2],
|
|
City: row[3],
|
|
ASN: row[4],
|
|
IPWhois: row[5],
|
|
})
|
|
}
|
|
|
|
}
|
|
// 根据 CIDR 范围从小到大排序,方便后面查找
|
|
sort.Slice(rowsSlice, func(i, j int) bool {
|
|
return rowsSlice[i].IPNet.Mask.String() > rowsSlice[j].IPNet.Mask.String()
|
|
})
|
|
|
|
return rowsSlice, nil
|
|
}
|
|
|
|
func FindGeoFeedRow(ipStr string, rows []GeoFeedRow) (GeoFeedRow, bool) {
|
|
ip := net.ParseIP(ipStr)
|
|
if ip == nil {
|
|
// 如果传入的 IP 无效,直接返回
|
|
return GeoFeedRow{}, false
|
|
}
|
|
|
|
// 遍历每个 CIDR 范围,找到第一个包含传入的 IP 的 CIDR
|
|
for _, row := range rows {
|
|
if row.IPNet.Contains(ip) {
|
|
return row, true
|
|
}
|
|
}
|
|
|
|
return GeoFeedRow{}, false
|
|
}
|