String will convert the IP to the appropriate family formatted string representation. In order to retain postgres compatibility we ensure IPv4-mapped IPv6 stays in IPv6 format, unlike net.Addr.String().
()
| 106 | // representation. In order to retain postgres compatibility we ensure |
| 107 | // IPv4-mapped IPv6 stays in IPv6 format, unlike net.Addr.String(). |
| 108 | func (ipAddr IPAddr) String() string { |
| 109 | ip := net.IP(uint128.Uint128(ipAddr.Addr).GetBytes()) |
| 110 | isIPv4MappedIPv6 := ipAddr.Family == IPv6family && ip.Equal(ip.To4()) |
| 111 | var maskSize byte |
| 112 | |
| 113 | if ipAddr.Family == IPv4family { |
| 114 | maskSize = 32 |
| 115 | } else { |
| 116 | maskSize = 128 |
| 117 | } |
| 118 | if ipAddr.Mask == maskSize && isIPv4MappedIPv6 { |
| 119 | return "::ffff:" + ip.String() |
| 120 | } else if ipAddr.Mask == maskSize { |
| 121 | return ip.String() |
| 122 | } else if isIPv4MappedIPv6 { |
| 123 | // Due to an issue with IPv4-mapped IPv6 the mask is also reduced to an IPv4 |
| 124 | // mask during net.IPNet.String, so we need to add the mask manually. |
| 125 | return "::ffff:" + ip.String() + "/" + strconv.Itoa(int(ipAddr.Mask)) |
| 126 | } |
| 127 | return ip.String() + "/" + strconv.Itoa(int(ipAddr.Mask)) |
| 128 | } |
| 129 | |
| 130 | // Compare two IPAddrs. IPv4-mapped IPv6 addresses are not equal to their IPv4 |
| 131 | // mapping. The order of order importance goes Family > Mask > IP-bytes. |
no test coverage detected