1
0
mirror of https://github.com/openshift/installer.git synced 2026-02-06 09:47:02 +01:00
Files
installer/pkg/ipnet/ipnet.go
staebler b2d6fa405b validate: simplify CIDR validation
Much of the code that made of the CIDR validation was there to give a custom
description of what made the CIDR provided invalid. This has been removed in
favor of using the error returned by the golang library's ParseCIDR function.

Additionally, the code to determine whether two CIDRs overlap was unnecessary
complex because it did not take advantage of the fact that CIDRs only overlap
if one is a subset of the other.

https://jira.coreos.com/browse/CORS-850
2018-12-14 19:21:05 -05:00

92 lines
2.1 KiB
Go

// Package ipnet wraps net.IPNet to get CIDR serialization.
package ipnet
import (
"encoding/json"
"net"
"reflect"
"github.com/pkg/errors"
)
var nullString = "null"
var nullBytes = []byte(nullString)
var emptyIPNet = net.IPNet{}
// IPNet wraps net.IPNet to get CIDR serialization.
type IPNet struct {
net.IPNet
}
// String returns a CIDR serialization of the subnet, or an empty
// string if the subnet is nil.
func (ipnet *IPNet) String() string {
if ipnet == nil {
return ""
}
return ipnet.IPNet.String()
}
// MarshalJSON interface for an IPNet
func (ipnet IPNet) MarshalJSON() (data []byte, err error) {
if reflect.DeepEqual(ipnet.IPNet, emptyIPNet) {
return nullBytes, nil
}
return json.Marshal(ipnet.String())
}
// UnmarshalJSON interface for an IPNet
func (ipnet *IPNet) UnmarshalJSON(b []byte) (err error) {
if string(b) == nullString {
ipnet.IP = net.IP{}
ipnet.Mask = net.IPMask{}
return nil
}
var cidr string
err = json.Unmarshal(b, &cidr)
if err != nil {
return errors.Wrap(err, "failed to Unmarshal string")
}
ip, net, err := net.ParseCIDR(cidr)
if err != nil {
return errors.Wrap(err, "failed to Parse cidr string to net.IPNet")
}
// This check is needed in order to work around a strange quirk in the Go
// standard library. All of the addresses returned by net.ParseCIDR() are
// 16-byte addresses. This does _not_ imply that they are IPv6 addresses,
// which is what some libraries (e.g. github.com/apparentlymart/go-cidr)
// assume. By forcing the address to be the expected length, we can work
// around these bugs.
if ip.To4() != nil {
ipnet.IP = ip.To4()
} else {
ipnet.IP = ip
}
ipnet.Mask = net.Mask
return nil
}
// ParseCIDR parses a CIDR from its string representation.
func ParseCIDR(s string) (*IPNet, error) {
_, cidr, err := net.ParseCIDR(s)
if err != nil {
return nil, err
}
return &IPNet{IPNet: *cidr}, nil
}
// MustParseCIDR parses a CIDR from its string representation. If the parse fails,
// the function will panic.
func MustParseCIDR(s string) *IPNet {
cidr, err := ParseCIDR(s)
if err != nil {
panic(err)
}
return cidr
}