consul/ipaddr/detect.go
hashicorp-copywrite[bot] 5fb9df1640
[COMPLIANCE] License changes (#18443)
* Adding explicit MPL license for sub-package

This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository.

* Adding explicit MPL license for sub-package

This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository.

* Updating the license from MPL to Business Source License

Going forward, this project will be licensed under the Business Source License v1.1. Please see our blog post for more details at <Blog URL>, FAQ at www.hashicorp.com/licensing-faq, and details of the license at www.hashicorp.com/bsl.

* add missing license headers

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

* Update copyright file headers to BUSL-1.1

---------

Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com>
2023-08-11 09:12:13 -04:00

142 lines
3.4 KiB
Go

// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package ipaddr
import (
"fmt"
"net"
)
// GetPrivateIPv4 returns the list of private network IPv4 addresses on
// all active interfaces.
func GetPrivateIPv4() ([]*net.IPAddr, error) {
addresses, err := activeInterfaceAddresses()
if err != nil {
return nil, fmt.Errorf("Failed to get interface addresses: %v", err)
}
var addrs []*net.IPAddr
for _, rawAddr := range addresses {
var ip net.IP
switch addr := rawAddr.(type) {
case *net.IPAddr:
ip = addr.IP
case *net.IPNet:
ip = addr.IP
default:
continue
}
if ip.To4() == nil {
continue
}
if !isPrivate(ip) {
continue
}
addrs = append(addrs, &net.IPAddr{IP: ip})
}
return addrs, nil
}
// GetPublicIPv6 returns the list of all public IPv6 addresses
// on all active interfaces.
func GetPublicIPv6() ([]*net.IPAddr, error) {
addresses, err := net.InterfaceAddrs()
if err != nil {
return nil, fmt.Errorf("Failed to get interface addresses: %v", err)
}
var addrs []*net.IPAddr
for _, rawAddr := range addresses {
var ip net.IP
switch addr := rawAddr.(type) {
case *net.IPAddr:
ip = addr.IP
case *net.IPNet:
ip = addr.IP
default:
continue
}
if ip.To4() != nil {
continue
}
if isPrivate(ip) {
continue
}
addrs = append(addrs, &net.IPAddr{IP: ip})
}
return addrs, nil
}
// privateBlocks contains non-forwardable address blocks which are used
// for private networks. RFC 6890 provides an overview of special
// address blocks.
var privateBlocks = []*net.IPNet{
parseCIDR("10.0.0.0/8"), // RFC 1918 IPv4 private network address
parseCIDR("100.64.0.0/10"), // RFC 6598 IPv4 shared address space
parseCIDR("127.0.0.0/8"), // RFC 1122 IPv4 loopback address
parseCIDR("169.254.0.0/16"), // RFC 3927 IPv4 link local address
parseCIDR("172.16.0.0/12"), // RFC 1918 IPv4 private network address
parseCIDR("192.0.0.0/24"), // RFC 6890 IPv4 IANA address
parseCIDR("192.0.2.0/24"), // RFC 5737 IPv4 documentation address
parseCIDR("192.168.0.0/16"), // RFC 1918 IPv4 private network address
parseCIDR("::1/128"), // RFC 1884 IPv6 loopback address
parseCIDR("fe80::/10"), // RFC 4291 IPv6 link local addresses
parseCIDR("fc00::/7"), // RFC 4193 IPv6 unique local addresses
parseCIDR("fec0::/10"), // RFC 1884 IPv6 site-local addresses
parseCIDR("2001:db8::/32"), // RFC 3849 IPv6 documentation address
}
func parseCIDR(s string) *net.IPNet {
_, block, err := net.ParseCIDR(s)
if err != nil {
panic(fmt.Sprintf("Bad CIDR %s: %s", s, err))
}
return block
}
func isPrivate(ip net.IP) bool {
for _, priv := range privateBlocks {
if priv.Contains(ip) {
return true
}
}
return false
}
// Returns addresses from interfaces that is up
func activeInterfaceAddresses() ([]net.Addr, error) {
var upAddrs []net.Addr
var loAddrs []net.Addr
interfaces, err := net.Interfaces()
if err != nil {
return nil, fmt.Errorf("Failed to get interfaces: %v", err)
}
for _, iface := range interfaces {
// Require interface to be up
if iface.Flags&net.FlagUp == 0 {
continue
}
addresses, err := iface.Addrs()
if err != nil {
return nil, fmt.Errorf("Failed to get interface addresses: %v", err)
}
if iface.Flags&net.FlagLoopback != 0 {
loAddrs = append(loAddrs, addresses...)
continue
}
upAddrs = append(upAddrs, addresses...)
}
if len(upAddrs) == 0 {
return loAddrs, nil
}
return upAddrs, nil
}