if address is embedded IPv4, convert it to normal IPv4
| 253 | |
| 254 | // if address is embedded IPv4, convert it to normal IPv4 |
| 255 | inline void SockAddr::unmapV4() |
| 256 | { |
| 257 | if (family() != AF_INET6) |
| 258 | return; |
| 259 | |
| 260 | // IPv6 mapped IPv4 addresses are ::ffff:0:0/32 |
| 261 | static const unsigned char v4mapped_pfx[12] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff}; |
| 262 | |
| 263 | if (memcmp(data.inet6.sin6_addr.s6_addr, v4mapped_pfx, sizeof(v4mapped_pfx)) != 0) |
| 264 | return; |
| 265 | |
| 266 | unsigned short port = ntohs(data.inet6.sin6_port); |
| 267 | struct in_addr addr; |
| 268 | memcpy(&addr, (char*)(&data.inet6.sin6_addr.s6_addr) + sizeof(v4mapped_pfx), sizeof(addr)); |
| 269 | |
| 270 | data.inet.sin_family = AF_INET; |
| 271 | data.inet.sin_port = htons(port); |
| 272 | data.inet.sin_addr.s_addr = addr.s_addr; |
| 273 | len = sizeof(struct sockaddr_in); |
| 274 | } |
| 275 | |
| 276 | |
| 277 | #endif // REMOTE_SOCKADDR_H |