F_NONNULL static void do_lookup(const gdmaps_t* gdmaps, const char* map_name, const char* ip_arg) { dmn_assert(gdmaps); dmn_assert(map_name); dmn_assert(ip_arg); int map_idx = gdmaps_name2idx(gdmaps, map_name); if(map_idx < 0) { log_err("Mapping name '%s' not found in configuration", map_name); return; } client_info_t cinfo; // mostly ignored, but needs to be nonzero, and 150 is interesting in that // it easily differentiates source -> scope copies from actual database scope netmasks, // since it's larger than any legal netmask in the database. cinfo.edns_client_mask = 150U; const int addr_err = gdnsd_anysin_getaddrinfo(ip_arg, NULL, &cinfo.edns_client); if(addr_err) { log_err("Could not parse address '%s': %s", ip_arg, gai_strerror(addr_err)); return; } // To void gdmaps fallback pitfalls memcpy(&cinfo.dns_source, &cinfo.edns_client, sizeof(dmn_anysin_t)); // w/ edns_client_mask set, scope_mask should *always* be set by gdmaps_lookup(); // (and regardless, dclist should also always be set and contain something) unsigned scope_mask = 175U; const uint8_t* dclist = gdmaps_lookup(gdmaps, map_idx, &cinfo, &scope_mask); dmn_assert(scope_mask != 175U); dmn_assert(dclist); // Scope was set to Source. Since we always query as edns, this implies // the database was V4-only and the address input was a non-v4-compat v6 address, // and the lookup code fell back to the default dclist (1). if(scope_mask == 150U) { printf( "%s => %s => %s\n", map_name, dmn_logf_anysin_noport(&cinfo.edns_client), gdmaps_logf_dclist(gdmaps, map_idx, dclist) ); } else { printf( "%s => %s/%u => %s\n", map_name, dmn_logf_anysin_noport(&cinfo.edns_client), scope_mask, gdmaps_logf_dclist(gdmaps, map_idx, dclist) ); } dmn_fmtbuf_reset(); }
const char* gdnsd_logf_ipv6(const uint8_t* ipv6) { dmn_anysin_t tempsin; memset(&tempsin, 0, sizeof(dmn_anysin_t)); tempsin.sin.sin_family = AF_INET6; memcpy(tempsin.sin6.sin6_addr.s6_addr, ipv6, 16); tempsin.len = sizeof(struct sockaddr_in6); return dmn_logf_anysin_noport(&tempsin); }