#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
+#include <stdbool.h>
#include <sys/types.h>
#ifdef HAVE_ERROR_H
#include <error.h>
}
#endif
+#ifdef ENABLE_IPV6
+static bool is_well_known_nat64(struct in6_addr *addr){
+ // 64:ff9b::
+ return addr->s6_addr[0] == 0x00 && addr->s6_addr[1] == 0x64 && addr->s6_addr[2] == 0xff && addr->s6_addr[3] == 0x9b;
+}
+#endif
+
static char *get_ipinfo(
struct mtr_ctl *ctl,
ip_t * addr)
if (ctl->af == AF_INET6) {
#ifdef ENABLE_IPV6
- reverse_host6(addr, key, NAMELEN);
- if (snprintf(lookup_key, NAMELEN, "%s.%s", key, ctl->ipinfo_provider6)
- >= NAMELEN)
- return NULL;
+ if (is_well_known_nat64(addr)) {
+ // Treats the final 4 bytes as IPv4 address
+ unsigned char buff[4];
+ memcpy(buff, addr->s6_addr + 12, 4);
+ if (snprintf
+ (key, NAMELEN, "%d.%d.%d.%d", buff[3], buff[2], buff[1],
+ buff[0]) >= NAMELEN)
+ return NULL;
+ if (snprintf(lookup_key, NAMELEN, "%s.%s", key, ctl->ipinfo_provider4)
+ >= NAMELEN)
+ return NULL;
+ } else {
+ reverse_host6(addr, key, NAMELEN);
+ if (snprintf(lookup_key, NAMELEN, "%s.%s", key, ctl->ipinfo_provider6)
+ >= NAMELEN)
+ return NULL;
+ }
#else
return NULL;
#endif