int GeoIPLocIP(ftval *ip, enum ftype itype, float *latitude, float *longitude, char **country_code) { GeoIPRecord *gir; geoipv6_t gv6; const char *ccode; gir = NULL; ccode = NULL; switch (itype) { case FT_IPv4: if (gi == NULL) return -1; pthread_mutex_lock(&atom); if (city) { gir = GeoIP_record_by_ipnum(gi, ntohl(ip->uint32)); if (gir != NULL) { ccode = gir->country_code; } } else { ccode = GeoIP_country_code_by_ipnum(gi, ntohl(ip->uint32)); } pthread_mutex_unlock(&atom); break; case FT_IPv6: if (giv6 == NULL) return -1; memcpy(gv6.s6_addr, ip->ipv6, 16); pthread_mutex_lock(&atom6); if (cityv6) { gir = GeoIP_record_by_ipnum_v6(giv6, gv6); if (gir != NULL) ccode = gir->country_code; } else { ccode = GeoIP_country_code_by_ipnum_v6(giv6, gv6); } pthread_mutex_unlock(&atom6); break; default: LogPrintf(LV_ERROR, "GeoIP IP type error"); } if (gir != NULL) { *latitude = gir->latitude; *longitude = gir->longitude; if (country_code != NULL) *country_code = (char *)ccode; GeoIPRecord_delete(gir); return 0; } if (country_code != NULL && ccode != NULL) { *country_code = (char *)ccode; return 0; } return -1; }
/* * Country lookups are performed if the previous lookup was from a * different IP address than the current, or was for a search of a * different subtype. */ static const char * country_lookup(GeoIP *db, dns_geoip_subtype_t subtype, unsigned int family, isc_uint32_t ipnum, const geoipv6_t *ipnum6) { geoip_state_t *prev_state = NULL; const char *text = NULL; REQUIRE(db != NULL); #ifndef HAVE_GEOIP_V6 /* no IPv6 support? give up now */ if (family == AF_INET6) return (NULL); #endif prev_state = get_state_for(family, ipnum, ipnum6); if (prev_state != NULL && prev_state->subtype == subtype) text = prev_state->text; if (text == NULL) { switch (subtype) { case dns_geoip_country_code: if (family == AF_INET) text = GeoIP_country_code_by_ipnum(db, ipnum); #ifdef HAVE_GEOIP_V6 else text = GeoIP_country_code_by_ipnum_v6(db, *ipnum6); #endif break; case dns_geoip_country_code3: if (family == AF_INET) text = GeoIP_country_code3_by_ipnum(db, ipnum); #ifdef HAVE_GEOIP_V6 else text = GeoIP_country_code3_by_ipnum_v6(db, *ipnum6); #endif break; case dns_geoip_country_name: if (family == AF_INET) text = GeoIP_country_name_by_ipnum(db, ipnum); #ifdef HAVE_GEOIP_V6 else text = GeoIP_country_name_by_ipnum_v6(db, *ipnum6); #endif break; default: INSIST(0); } set_state(family, ipnum, ipnum6, subtype, NULL, NULL, NULL, text, 0); } return (text); }