How to Check if IP Address is in Private Network Space in Go

Created
Modified

Using IsPrivate Function

The IsPrivate() function reports whether ip is a private address, according to RFC 1918 (IPv4 addresses) and RFC 4193 (IPv6 addresses).

The following example should cover whatever you are trying to do:

// Go 1.17+
package main

import (
  "fmt"
  "net"
)

func main() {

  ip := "1.1.1.1"
  addr := net.ParseIP(ip)
  fmt.Println(addr.IsPrivate())

  ip = "10.3.4.0"
  addr = net.ParseIP(ip)
  fmt.Println(addr.IsPrivate())
}
false
true

This requires Go 1.17.

Using RFC1918

Here is an example with a list of RFC1918 address plus these others and a simple check against them as isPrivateIP(ip net.IP):

package main

import (
  "fmt"
  "net"
)

var privIPBlocks []*net.IPNet

func isPrivate(ip string) bool {
  // init blocks
  if len(privIPBlocks) == 0 {
    for _, cidr := range []string{
      "127.0.0.0/8",    // IPv4 loopback
      "10.0.0.0/8",     // RFC1918
      "172.16.0.0/12",  // RFC1918
      "192.168.0.0/16", // RFC1918
      "169.254.0.0/16", // RFC3927 link-local
      "::1/128",        // IPv6 loopback
      "fe80::/10",      // IPv6 link-local
      "fc00::/7",       // IPv6 unique local addr
    } {
      _, block, err := net.ParseCIDR(cidr)
      if err != nil {
        panic(fmt.Errorf("parse error on %q: %v", cidr, err))
      }
      privIPBlocks = append(privIPBlocks, block)
    }
  }

  addr := net.ParseIP(ip)
  if addr.IsLoopback() || addr.IsLinkLocalUnicast() || addr.IsLinkLocalMulticast() {
    return true
  }

  for _, block := range privIPBlocks {
    if block.Contains(addr) {
      return true
    }
  }

  return false
}

func main() {

  ip := "1.1.1.1"
  fmt.Println(isPrivate(ip))

  ip = "10.3.4.0"
  fmt.Println(isPrivate(ip))
}
false
true

Related Tags

#check# #ip# #network#