dim/types/ip.go

61 lines
1.3 KiB
Go

package types
import (
"bytes"
"database/sql/driver"
"fmt"
"net"
)
type (
// Subnet is used to parse a subnet parameter.
Subnet net.IPNet
// IP is used to parse an IP parameter.
IP net.IP
)
// UnmarshalJSON parses a value into a subnet.
//
// It is also checked if the provided IP matches the network address
// of the subnet.
func (s *Subnet) UnmarshalJSON(in []byte) error {
in = bytes.Trim(in, `"`)
ip, ipnet, err := net.ParseCIDR(string(in))
if err != nil {
return fmt.Errorf("not a valid subnet")
}
if !ipnet.IP.Equal(ip) {
return fmt.Errorf("provided IP is not a subnet")
}
*s = Subnet(*ipnet)
return nil
}
// String returns the string representation of the subnet.
//
// The subnet is returned as the subnet address and prefix separated by `/`
// as defined in RFC 4632 and RFC 4291.
func (s *Subnet) String() string {
return (*net.IPNet)(s).String()
}
// Value implements the database Value interface.
//
// This function is needed so that a subnet can be inserted into
// the database without much casting.
func (s *Subnet) Value() (driver.Value, error) {
return s.String(), nil
}
func (i *IP) UnmarshalJSON(in []byte) error {
in = bytes.Trim(in, `"`)
ip := net.ParseIP(string(in))
if ip == nil {
return fmt.Errorf("not a valid ip")
}
*i = IP(ip)
return nil
}