func GetPublicIP() (string, error) {
	publicIfs, err := GetPublicInterfaces()
	if err != nil {
		return "", err
	} else if len(publicIfs) < 1 {
		return "", nil
	}
	ifAddr := publicIfs[0]
	ip := *ToIPAddr(ifAddr.SockAddr)
	return ip.NetIP().String(), nil
}
GetPublicIP returns a string with a single IP address that is NOT part of RFC
6890 and has a default route.  If the system can't determine its IP address
or find a non RFC 6890 IP address, an empty string will be returned instead.
This function is the `eval` equivalent of:

```
$ sockaddr eval -r '{{GetPublicInterfaces | attr "address"}}'
/ ```
package sockaddr
import "strings"
var ifAddrAttrMap map[AttrName]func(IfAddr) string
var ifAddrAttrs []AttrName
func init() {
	ifAddrAttrInit()
}
func GetPrivateIP() (string, error) {
	privateIfs, err := GetPrivateInterfaces()
	if err != nil {
		return "", err
	}
	if len(privateIfs) < 1 {
		return "", nil
	}
	ifAddr := privateIfs[0]
	ip := *ToIPAddr(ifAddr.SockAddr)
	return ip.NetIP().String(), nil
}
func GetPrivateIPs() (string, error) {
	ifAddrs, err := GetAllInterfaces()
	if err != nil {
		return "", err
	} else if len(ifAddrs) < 1 {
		return "", nil
	}
	ifAddrs, _ = FilterIfByType(ifAddrs, TypeIP)
	if len(ifAddrs) == 0 {
		return "", nil
	}
	OrderedIfAddrBy(AscIfType, AscIfNetworkSize).Sort(ifAddrs)
	ifAddrs, _, err = IfByRFC("6890", ifAddrs)
	if err != nil {
		return "", err
	} else if len(ifAddrs) == 0 {
		return "", nil
	}
	_, ifAddrs, err = IfByRFC(ForwardingBlacklistRFC, ifAddrs)
	if err != nil {
		return "", err
	} else if len(ifAddrs) == 0 {
		return "", nil
	}
	ips := make([]string, 0, len(ifAddrs))
	for _, ifAddr := range ifAddrs {
		ip := *ToIPAddr(ifAddr.SockAddr)
		s := ip.NetIP().String()
		ips = append(ips, s)
	}
	return strings.Join(ips, " "), nil
}