golang CIDR prefix notation to IP address/subnet mask (dot-decimal)

7.2k views Asked by At

Is there something similar to 'npm netmask' in golang ? I need to convert i.e. 10.0.0.0/8 to 10.0.0.0/255.0.0.0 so basically netmask in CIDR format to dot-decimal.

var Netmask = require('netmask').Netmask
var block = new Netmask('10.0.0.0/8');
block.mask; // 255.0.0.0

I can't find it in /golang.org/src/net/ip.go

3

There are 3 answers

0
Stephen Weinberg On BEST ANSWER

The go standard library does not have a function to create that representation. That being said, it is not difficult to do yourself:

https://play.golang.org/p/XT_UXoy6ra

func main() {
    _, ipv4Net, err := net.ParseCIDR("10.0.0.0/8")
    if err != nil {
        log.Fatal(err)
    }
    fmt.Println(ipv4MaskString(ipv4Net.Mask))
}

func ipv4MaskString(m []byte) string {
    if len(m) != 4 {
        panic("ipv4Mask: len must be 4 bytes")
    }

    return fmt.Sprintf("%d.%d.%d.%d", m[0], m[1], m[2], m[3])
}

Keep in mind this format only works for ipv4 masks. If you were to pass an ipv6 mask, this would panic.

0
Sean F On

The following code works with both IPv4 and IPv6 using the IPAddress Go library. Disclaimer: I am the project manager.

func main() {
    convert("10.0.0.0/8")
    convert("10::/64")
}

func convert(cidrStr string) {
    cidr := ipaddr.NewIPAddressString(cidrStr).GetAddress()
    fmt.Println(cidr.GetNetworkMask())
}

Output:

255.0.0.0
ffff:ffff:ffff:ffff::
0
Ezbob On

You can use the golang standard library to get the dot representation like so:

ipaddr, ipv4Net, err := net.ParseCIDR("10.0.0.0/8")
// handle error
fmt.Println(net.IP(ipv4Net.Mask).String())

This works because both the mask and the IP is backed by a []byte slice (see the stdlib source), so you can convert between them by casting directly.