fix: 修复IPV6子网掩码识别错误的问题

This commit is contained in:
spiritlhl
2025-05-17 10:16:34 +00:00
parent 30eb9bc600
commit bf07ce0aa0
6 changed files with 87 additions and 116 deletions

View File

@@ -7,6 +7,7 @@ import (
"fmt"
"os/exec"
"regexp"
"strconv"
"strings"
)
@@ -17,20 +18,14 @@ func getPrefixFromIfconfig(interfaceName string) (string, error) {
if err != nil {
return "", err
}
// 匹配 inet6 地址和前缀长度
re := regexp.MustCompile(`inet6\s+([a-fA-F0-9:]+)%?\w*\s+prefixlen\s+(\d+)`)
matches := re.FindAllStringSubmatch(string(output), -1)
for _, match := range matches {
if len(match) < 3 {
continue
}
ipv6Addr := match[1]
prefixLen := match[2]
// 排除非公网地址前缀
if strings.HasPrefix(ipv6Addr, "fe80") || // 链路本地地址
strings.HasPrefix(ipv6Addr, "::1") || // 回环地址
strings.HasPrefix(ipv6Addr, "fc") || // 本地唯一地址
@@ -38,29 +33,26 @@ func getPrefixFromIfconfig(interfaceName string) (string, error) {
strings.HasPrefix(ipv6Addr, "ff") { // 组播地址
continue
}
prefixLenInt, err := strconv.Atoi(prefixLen)
if err != nil || prefixLenInt < 0 || prefixLenInt > 128 {
continue
}
return prefixLen, nil
}
return "", fmt.Errorf("未找到全局IPv6地址")
}
// macOS平台上使用networksetup命令获取更多信息
func getPrefixFromNetworksetup(interfaceName string) (string, error) {
// 首先需要获取网络服务名称
cmd := exec.Command("networksetup", "-listallhardwareports")
output, err := cmd.Output()
if err != nil {
return "", err
}
// 解析输出查找对应的网络服务名称
lines := strings.Split(string(output), "\n")
var serviceName string
for i := 0; i < len(lines); i++ {
if strings.Contains(lines[i], "Device: "+interfaceName) && i > 0 {
// 服务名称在上一行
serviceNameLine := lines[i-1]
if strings.HasPrefix(serviceNameLine, "Hardware Port: ") {
serviceName = strings.TrimPrefix(serviceNameLine, "Hardware Port: ")
@@ -68,35 +60,32 @@ func getPrefixFromNetworksetup(interfaceName string) (string, error) {
}
}
}
if serviceName == "" {
return "", fmt.Errorf("未找到网络接口对应的服务名称")
}
// 使用服务名称获取IPv6配置
cmd = exec.Command("networksetup", "-getinfo", serviceName)
output, err = cmd.Output()
if err != nil {
return "", err
}
// 查找IPv6前缀长度
re := regexp.MustCompile(`IPv6:\s*Automatic\s*\nIPv6\s*Address:\s*([a-fA-F0-9:]+)\s*\nIPv6\s*Prefix\s*Length:\s*(\d+)`)
match := re.FindStringSubmatch(string(output))
if len(match) >= 3 {
return match[2], nil
prefixLen := match[2]
prefixLenInt, err := strconv.Atoi(prefixLen)
if err != nil || prefixLenInt < 0 || prefixLenInt > 128 {
return "", fmt.Errorf("无效的IPv6前缀长度: %s", prefixLen)
}
return prefixLen, nil
}
return "", fmt.Errorf("未找到IPv6前缀长度信息")
}
// 获取 IPv6 子网掩码 - macOS 实现
// 获取 IPv6 子网掩码
func GetIPv6Mask(publicIPv6, language string) (string, error) {
if publicIPv6 == "" {
return "", fmt.Errorf("无公网IPV6地址")
}
// 获取网络接口
interfaceName, err := getInterface()
if err != nil || interfaceName == "" {
return "", fmt.Errorf("获取网络接口失败: %v", err)
@@ -111,6 +100,5 @@ func GetIPv6Mask(publicIPv6, language string) (string, error) {
if err == nil && prefixLen != "" {
return formatIPv6Mask(prefixLen, language), nil
}
// 如果以上方法都失败但确实有公网IPv6使用/128作为默认子网掩码
return formatIPv6Mask("128", language), nil
}