func (ipv4 IPv4Addr) CmpAddress(sa SockAddr) int {
	ipv4b, ok := sa.(IPv4Addr)
	if !ok {
		return sortDeferDecision
	}
	switch {
	case ipv4.Address == ipv4b.Address:
		return sortDeferDecision
	case ipv4.Address < ipv4b.Address:
		return sortReceiverBeforeArg
	default:
		return sortArgBeforeReceiver
	}
}
CmpAddress follows the Cmp() standard protocol and returns:

- -1 If the receiver should sort first because its address is lower than arg
- 0 if the SockAddr arg is equal to the receiving IPv4Addr or the argument is
of a different type.
- 1 If the argument should sort first.
package sockaddr
import (
	"encoding/binary"
	"fmt"
	"net"
	"regexp"
	"strconv"
	"strings"
)
type (
	IPv4Address uint32
	IPv4Network uint32
	IPv4Mask uint32
)
const IPv4HostMask = IPv4Mask(0xffffffff)
var ipv4AddrAttrMap map[AttrName]func(IPv4Addr) string
var ipv4AddrAttrs []AttrName
var trailingHexNetmaskRE *regexp.Regexp
type IPv4Addr struct {
	IPAddr
	Address IPv4Address
	Mask    IPv4Mask
	Port    IPPort
}
func init() {
	ipv4AddrInit()
	trailingHexNetmaskRE = regexp.MustCompile(`/([0f]{8})$`)
}
func NewIPv4Addr(ipv4Str string) (IPv4Addr, error) {
	trailingHexNetmaskRe := trailingHexNetmaskRE.Copy()
	if match := trailingHexNetmaskRe.FindStringIndex(ipv4Str); match != nil {
		ipv4Str = ipv4Str[:match[0]]
	}
	ipAddr, network, err := net.ParseCIDR(ipv4Str)
	if err == nil {
		ipv4 := ipAddr.To4()
		if ipv4 == nil {
			return IPv4Addr{}, fmt.Errorf("Unable to convert %s to an IPv4 address", ipv4Str)
		}
		netmaskSepPos := strings.LastIndexByte(ipv4Str, '/')
		if netmaskSepPos != -1 && netmaskSepPos+1 < len(ipv4Str) {
			netMask, err := strconv.ParseUint(ipv4Str[netmaskSepPos+1:], 10, 8)
			if err != nil {
				return IPv4Addr{}, fmt.Errorf("Unable to convert %s to an IPv4 address: unable to parse CIDR netmask: %v", ipv4Str, err)
			} else if netMask > 128 {
				return IPv4Addr{}, fmt.Errorf("Unable to convert %s to an IPv4 address: invalid CIDR netmask", ipv4Str)
			}
			if netMask >= 96 {
				network.Mask = net.CIDRMask(int(netMask-96), IPv4len*8)
			}
		}
		ipv4Addr := IPv4Addr{
			Address: IPv4Address(binary.BigEndian.Uint32(ipv4)),
			Mask:    IPv4Mask(binary.BigEndian.Uint32(network.Mask)),
		}
		return ipv4Addr, nil
	}
	tcpAddr, err := net.ResolveTCPAddr("tcp4", ipv4Str)
	if err == nil {
		ipv4 := tcpAddr.IP.To4()
		if ipv4 == nil {
			return IPv4Addr{}, fmt.Errorf("Unable to resolve %+q as an IPv4 address", ipv4Str)
		}
		ipv4Uint32 := binary.BigEndian.Uint32(ipv4)
		ipv4Addr := IPv4Addr{
			Address: IPv4Address(ipv4Uint32),
			Mask:    IPv4HostMask,
			Port:    IPPort(tcpAddr.Port),
		}
		return ipv4Addr, nil
	}
	ip := net.ParseIP(ipv4Str)
	if ip != nil {
		ipv4 := ip.To4()
		if ipv4 == nil {
			return IPv4Addr{}, fmt.Errorf("Unable to string convert %+q to an IPv4 address", ipv4Str)
		}
		ipv4Uint32 := binary.BigEndian.Uint32(ipv4)
		ipv4Addr := IPv4Addr{
			Address: IPv4Address(ipv4Uint32),
			Mask:    IPv4HostMask,
		}
		return ipv4Addr, nil
	}
	return IPv4Addr{}, fmt.Errorf("Unable to parse %+q to an IPv4 address: %v", ipv4Str, err)
}
func (ipv4 IPv4Addr) AddressBinString() string {
	return fmt.Sprintf("%032s", strconv.FormatUint(uint64(ipv4.Address), 2))
}
func (ipv4 IPv4Addr) AddressHexString() string {
	return fmt.Sprintf("%08s", strconv.FormatUint(uint64(ipv4.Address), 16))
}
func (ipv4 IPv4Addr) Broadcast() IPAddr {
	return IPv4Addr{
		Address: IPv4Address(ipv4.BroadcastAddress()),
		Mask:    IPv4HostMask,
	}
}
func (ipv4 IPv4Addr) BroadcastAddress() IPv4Network {
	return IPv4Network(uint32(ipv4.Address)&uint32(ipv4.Mask) | ^uint32(ipv4.Mask))
}