mirror of
https://github.com/sigcn/pg.git
synced 2025-09-27 04:30:13 +08:00
138 lines
2.8 KiB
Go
138 lines
2.8 KiB
Go
package disco
|
|
|
|
import (
|
|
"log/slog"
|
|
"net"
|
|
"net/netip"
|
|
"slices"
|
|
"strings"
|
|
)
|
|
|
|
type cidrs []net.IPNet
|
|
|
|
func (cs *cidrs) Contains(ip net.IP) bool {
|
|
for _, cidr := range *cs {
|
|
if cidr.Contains(ip) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
type interfaceNamePrefixs []string
|
|
|
|
func (inp *interfaceNamePrefixs) HasPrefix(interfaceName string) bool {
|
|
for _, ifaceNamePrefix := range *inp {
|
|
if strings.HasPrefix(interfaceName, ifaceNamePrefix) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
var (
|
|
ignoredLocalCIDRs cidrs
|
|
ignoredLocalInterfaceNamePrefixs interfaceNamePrefixs
|
|
localIPs []net.IP
|
|
)
|
|
|
|
func SetIgnoredLocalCIDRs(cidrs ...string) {
|
|
ignoredLocalCIDRs = ignoredLocalCIDRs[:0]
|
|
AddIgnoredLocalCIDRs(cidrs...)
|
|
}
|
|
|
|
func AddIgnoredLocalCIDRs(cidrs ...string) {
|
|
for _, cidr := range cidrs {
|
|
_, _cidr, err := net.ParseCIDR(cidr)
|
|
if err != nil {
|
|
slog.Debug("SetIgnoredLocalCIDRs parse cidr failed", "err", err)
|
|
continue
|
|
}
|
|
if _cidr.IP.IsUnspecified() {
|
|
continue
|
|
}
|
|
slog.Debug("IgnoreLocalCIDR " + cidr)
|
|
ignoredLocalCIDRs = append(ignoredLocalCIDRs, *_cidr)
|
|
}
|
|
}
|
|
|
|
func RemoveIgnoredLocalCIDRs(cidrs ...string) {
|
|
var filterd []net.IPNet
|
|
for _, cidr := range ignoredLocalCIDRs {
|
|
if !slices.Contains(cidrs, cidr.String()) {
|
|
filterd = append(filterd, cidr)
|
|
}
|
|
}
|
|
ignoredLocalCIDRs = filterd
|
|
}
|
|
|
|
func IsIgnoredLocalIP(ip net.IP) bool {
|
|
return ignoredLocalCIDRs.Contains(ip)
|
|
}
|
|
|
|
func GetIgnoredLocalCIDRs() []net.IPNet {
|
|
return slices.Clone(ignoredLocalCIDRs)
|
|
}
|
|
|
|
func SetIgnoredLocalInterfaceNamePrefixs(prefixs ...string) {
|
|
ignoredLocalInterfaceNamePrefixs = prefixs
|
|
for _, prefix := range prefixs {
|
|
slog.Debug("IgnoreInterface", "prefix", prefix)
|
|
}
|
|
}
|
|
|
|
func SetLocalIPs(ips ...net.IP) {
|
|
localIPs = ips
|
|
}
|
|
|
|
func GetIgnoredLocalInterfaceNamePrefixs() []string {
|
|
return slices.Clone(ignoredLocalInterfaceNamePrefixs)
|
|
}
|
|
|
|
func ListLocalIPs() ([]net.IP, error) {
|
|
if len(localIPs) > 0 {
|
|
return localIPs, nil
|
|
}
|
|
ifaces, err := net.Interfaces()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
var ips []net.IP
|
|
for _, iface := range ifaces {
|
|
if iface.Flags&net.FlagRunning != net.FlagRunning {
|
|
continue
|
|
}
|
|
if ignoredLocalInterfaceNamePrefixs.HasPrefix(iface.Name) {
|
|
continue
|
|
}
|
|
addrs, err := iface.Addrs()
|
|
if err != nil {
|
|
continue
|
|
}
|
|
for _, addr := range addrs {
|
|
if ipnet, ok := addr.(*net.IPNet); ok {
|
|
if ipnet.IP.IsLoopback() {
|
|
continue
|
|
}
|
|
if ipnet.IP.IsLinkLocalUnicast() {
|
|
continue
|
|
}
|
|
if ignoredLocalCIDRs.Contains(ipnet.IP) {
|
|
continue
|
|
}
|
|
ips = append(ips, ipnet.IP)
|
|
}
|
|
}
|
|
}
|
|
return ips, nil
|
|
}
|
|
|
|
var carrierGradeNAT = netip.MustParsePrefix("100.64.0.0/10")
|
|
|
|
func IsCGN(ip net.IP) bool {
|
|
if ip.To4() == nil {
|
|
return false
|
|
}
|
|
return carrierGradeNAT.Contains(netip.AddrFrom4([4]byte(ip.To4())))
|
|
}
|