package utils import ( "net" "net/netip" ) type ExtendedIPFlags uint type ExtendedIPNet struct { IP net.IP // network number Mask net.IPMask // network mask Flags ExtendedIPFlags } func (n *ExtendedIPNet) String() string { if n == nil { return "" } return (&net.IPNet{IP: n.IP, Mask: n.Mask}).String() } const ( FlagTemporary ExtendedIPFlags = 1 << iota FlagPermanent FlagNoPrefixRoute FlagManageTempAddress FlagStablePrivacy FlagDeprecated ) func GetOutboundIPv6() ([]netip.Addr, error) { ifaces, err := net.Interfaces() if err != nil { return nil, err } var addresses []netip.Addr for _, i := range ifaces { if (i.Flags&net.FlagRunning) > 0 && (i.Flags&net.FlagUp) > 0 && (i.Flags&net.FlagPointToPoint) == 0 && (i.Flags&net.FlagLoopback) == 0 { addrs, err := InterfaceAddrs(&i) if err != nil { continue } var mngTmpAddr []netip.Addr var noPrefixRouteAddr []netip.Addr var dhcpv6Addr []netip.Addr var tmpAddr []netip.Addr for _, a := range addrs { if addr, ok := netip.AddrFromSlice(a.IP); ok && addr.Is6() && !addr.Is4In6() { //Filter undesired addresses if addr.IsUnspecified() || addr.IsLoopback() || addr.IsLinkLocalMulticast() || addr.IsLinkLocalUnicast() || addr.IsInterfaceLocalMulticast() { continue } //Filter if (a.Flags & FlagDeprecated) > 0 { continue } if (a.Flags & FlagTemporary) > 0 { continue } //This is probably an address given by DHCPv6 if onesCount, _ := a.Mask.Size(); onesCount == 128 { dhcpv6Addr = append(dhcpv6Addr, netip.MustParseAddr(a.IP.String())) continue } if (a.Flags & FlagManageTempAddress) > 0 { mngTmpAddr = append(mngTmpAddr, netip.MustParseAddr(a.IP.String())) } if (a.Flags & FlagNoPrefixRoute) > 0 { noPrefixRouteAddr = append(noPrefixRouteAddr, netip.MustParseAddr(a.IP.String())) } tmpAddr = append(tmpAddr, netip.MustParseAddr(a.IP.String())) } } if len(mngTmpAddr) > 0 { addresses = append(addresses, mngTmpAddr...) } else if len(noPrefixRouteAddr) > 0 { addresses = append(addresses, noPrefixRouteAddr...) } else if len(dhcpv6Addr) > 0 { addresses = append(addresses, dhcpv6Addr...) } else { addresses = append(addresses, tmpAddr...) } } } return addresses, nil } var cgnatStart = netip.MustParseAddr("100.64.0.0") var cgnatEnd = netip.MustParseAddr("100.127.255.255") func NetIPIsCGNAT(addr netip.Addr) bool { return addr.Is4() && addr.Compare(cgnatStart) >= 0 && addr.Compare(cgnatEnd) <= 0 } func NetIPGetEUI48Information(addr netip.Addr) { if !addr.Is6() || addr.Is4In6() { return } }