static void check_illegal_index(MMDB_entry_s * entry, int idx) { MMDB_return_s result; char string[256]; snprintf(string, sizeof(string), "%d", idx); MMDB_get_value(entry, &result, string, NULL); ok(result.offset == 0, "Great nothing found"); }
void test_simple_structure(int mode, const char *mode_desc) { const char *filename = "MaxMind-DB-test-decoder.mmdb"; const char *path = test_database_path(filename); MMDB_s *mmdb = open_ok(path, mode, mode_desc); free((void *)path); const char *ip = "1.1.1.1"; MMDB_lookup_result_s result = lookup_string_ok(mmdb, ip, filename, mode_desc); { MMDB_entry_data_s entry_data; const char *lookup_path[] = { "array", "0", NULL }; int status = MMDB_aget_value(&result.entry, &entry_data, lookup_path); test_array_0_result(status, entry_data, "MMDB_aget_value"); status = MMDB_get_value(&result.entry, &entry_data, "array", "0", NULL); test_array_0_result(status, entry_data, "MMDB_get_value"); status = call_vget_value(&result.entry, &entry_data, "array", "0", NULL); test_array_0_result(status, entry_data, "MMDB_vget_value"); } { MMDB_entry_data_s entry_data; const char *lookup_path[] = { "array", "2", NULL }; int status = MMDB_aget_value(&result.entry, &entry_data, lookup_path); test_array_2_result(status, entry_data, "MMDB_aget_value"); status = MMDB_get_value(&result.entry, &entry_data, "array", "2", NULL); test_array_2_result(status, entry_data, "MMDB_get_value"); status = call_vget_value(&result.entry, &entry_data, "array", "2", NULL); test_array_2_result(status, entry_data, "MMDB_vget_value"); } MMDB_close(mmdb); free(mmdb); }
int main(void) { int gai_error, mmdb_error; MMDB_s mmdb; char *ip = "8.8.8.8"; int status = MMDB_open("/home/lannister/Documentos/GeoLite2-City.mmdb", MMDB_MODE_MMAP, &mmdb); if (MMDB_SUCCESS != status) { printf("Fail WTF"); } MMDB_lookup_result_s result = MMDB_lookup_string(&mmdb, ip, &gai_error, &mmdb_error); if (MMDB_SUCCESS != mmdb_error) { printf("Fail WTF2"); } int exit_code = 0; char *country = NULL; MMDB_entry_data_s entry_data; status = MMDB_get_value(&result.entry, &entry_data,"city","names","es", NULL); if (entry_data.has_data) { country = strndup(entry_data.utf8_string, entry_data.data_size); printf("%s\n", country); }else{ printf("No city"); } status = MMDB_get_value(&result.entry, &entry_data,"country","names","es", NULL); if (entry_data.has_data) { country = strndup(entry_data.utf8_string, entry_data.data_size); printf("%s\n", country); } MMDB_close(&mmdb); return 0; }
void test_entry_data(MMDB_s *mmdb, MMDB_entry_s *entry, uint32_t node_number, char * node_record) { MMDB_entry_data_s entry_data; int status = MMDB_get_value(entry, &entry_data, "ip", NULL); cmp_ok(status, "==", MMDB_SUCCESS, "successful data lookup for node"); cmp_ok( entry_data.type, "==", MMDB_DATA_TYPE_UTF8_STRING, "returned entry type is UTF8_STRING for %s record of node %i", node_record, node_number); }
void Worker( GeoIPData *data ) { int error = -1, gai_error = -1; MMDB_lookup_result_s result = MMDB_lookup_string( handle, data->getIp().c_str(), &gai_error, &error ); if ( error != MMDB_SUCCESS || gai_error != 0 ) { std::string *str = data->getData(); *str = MMDB_strerror( error ); data->setStatus( 0 ); // error return; } if ( result.found_entry ) { MMDB_entry_s entry = result.entry; MMDB_entry_data_s entry_data; if ( (error = MMDB_get_value( &entry, &entry_data, "names", "en", NULL )) != MMDB_SUCCESS ) { std::string *str = data->getData(); *str = MMDB_strerror( error ); data->setStatus( 0 ); // error return; } if ( entry_data.has_data ) { std::string *str = data->getData(); *str = entry_data.utf8_string; data->setStatus( 1 ); return; } else { *data->getData() = "Unknown"; data->setStatus( 1 ); return; } } else { *data->getData() = "Unknown"; data->setStatus( 1 ); return; } }
int pv_get_geoip2(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { geoip2_pv_t *gpv; MMDB_entry_data_s entry_data; if(msg==NULL || param==NULL) return -1; gpv = (geoip2_pv_t*)param->pvn.u.dname; if(gpv==NULL) return -1; if(gpv->item==NULL) return pv_get_null(msg, param, res); switch(gpv->type) { case 1: /* tz */ if(gpv->item->r.time_zone.s==NULL) { if(gpv->item->r.flags&1) return pv_get_null(msg, param, res); if(MMDB_get_value(&gpv->item->r.record.entry, &entry_data, "location","time_zone", NULL ) != MMDB_SUCCESS) return pv_get_null(msg, param, res); if(entry_data.has_data && entry_data.type == MMDB_DATA_TYPE_UTF8_STRING) { gpv->item->r.time_zone.s = (char *)entry_data.utf8_string; gpv->item->r.time_zone.len = entry_data.data_size; } gpv->item->r.flags |= 1; } return pv_get_strval(msg, param, res, &gpv->item->r.time_zone); case 2: /* zip */ if(gpv->item->r.zip.s==NULL) { if(gpv->item->r.flags&32) return pv_get_null(msg, param, res); if(MMDB_get_value(&gpv->item->r.record.entry, &entry_data, "postal","code", NULL) != MMDB_SUCCESS) return pv_get_null(msg, param, res); if(entry_data.has_data && entry_data.type == MMDB_DATA_TYPE_UTF8_STRING) { gpv->item->r.zip.s = (char *)entry_data.utf8_string; gpv->item->r.zip.len = entry_data.data_size; } gpv->item->r.flags |= 32; } return pv_get_strval(msg, param, res, &gpv->item->r.zip); case 3: /* lat */ if((gpv->item->r.flags&2)==0) { gpv->item->r.latitude[0] = '\0'; if(MMDB_get_value(&gpv->item->r.record.entry, &entry_data, "location","latitude", NULL) != MMDB_SUCCESS) return pv_get_null(msg, param, res); if(entry_data.has_data && entry_data.type == MMDB_DATA_TYPE_DOUBLE) snprintf(gpv->item->r.latitude, 15, "%f", entry_data.double_value); gpv->item->r.flags |= 2; } return pv_geoip2_get_strzval(msg, param, res, gpv->item->r.latitude); case 4: /* lon */ if((gpv->item->r.flags&4)==0) { gpv->item->r.latitude[0] = '\0'; if(MMDB_get_value(&gpv->item->r.record.entry, &entry_data, "location","longitude", NULL) != MMDB_SUCCESS) return pv_get_null(msg, param, res); if(entry_data.has_data && entry_data.type == MMDB_DATA_TYPE_DOUBLE) snprintf(gpv->item->r.longitude, 15, "%f", entry_data.double_value); gpv->item->r.flags |= 4; } return pv_geoip2_get_strzval(msg, param, res, gpv->item->r.longitude); case 6: /* contc */ if(gpv->item->r.cont_code.s==NULL) { if(gpv->item->r.flags&16) return pv_get_null(msg, param, res); if(MMDB_get_value(&gpv->item->r.record.entry, &entry_data, "continent","code", NULL ) != MMDB_SUCCESS) return pv_get_null(msg, param, res); if(entry_data.has_data && entry_data.type == MMDB_DATA_TYPE_UTF8_STRING) { gpv->item->r.cont_code.s = (char *)entry_data.utf8_string; gpv->item->r.cont_code.len = entry_data.data_size; } gpv->item->r.flags |= 16; } return pv_get_strval(msg, param, res, &gpv->item->r.cont_code); case 8: /* city */ if(gpv->item->r.city.s==NULL) { if(gpv->item->r.flags&64) return pv_get_null(msg, param, res); if(MMDB_get_value(&gpv->item->r.record.entry, &entry_data, "city","names","en", NULL ) != MMDB_SUCCESS) return pv_get_null(msg, param, res); if(entry_data.has_data && entry_data.type == MMDB_DATA_TYPE_UTF8_STRING) { gpv->item->r.city.s = (char *)entry_data.utf8_string; gpv->item->r.city.len = entry_data.data_size; } gpv->item->r.flags |= 64; } return pv_get_strval(msg, param, res, &gpv->item->r.city); case 10: /* regc */ if(gpv->item->r.region_code.s==NULL) { if(gpv->item->r.flags&128) return pv_get_null(msg, param, res); if(MMDB_get_value(&gpv->item->r.record.entry, &entry_data, "subdivisions","0","iso_code", NULL ) != MMDB_SUCCESS) return pv_get_null(msg, param, res); if(entry_data.has_data && entry_data.type == MMDB_DATA_TYPE_UTF8_STRING) { gpv->item->r.region_code.s = (char *)entry_data.utf8_string; gpv->item->r.region_code.len = entry_data.data_size; } gpv->item->r.flags |= 128; } return pv_get_strval(msg, param, res, &gpv->item->r.region_code); case 11: /* regn */ if(gpv->item->r.region_name.s==NULL) { if(gpv->item->r.flags&16) return pv_get_null(msg, param, res); if(MMDB_get_value(&gpv->item->r.record.entry, &entry_data, "subdivisions","0","names","en", NULL ) != MMDB_SUCCESS) return pv_get_null(msg, param, res); if(entry_data.has_data && entry_data.type == MMDB_DATA_TYPE_UTF8_STRING) { gpv->item->r.region_name.s = (char *)entry_data.utf8_string; gpv->item->r.region_name.len = entry_data.data_size; } gpv->item->r.flags |= 16; } return pv_get_strval(msg, param, res, &gpv->item->r.region_name); case 12: /* metro */ if((gpv->item->r.flags&256)==0) { gpv->item->r.metro[0] = '\0'; if(MMDB_get_value(&gpv->item->r.record.entry, &entry_data, "location","metro_code", NULL) != MMDB_SUCCESS) return pv_get_null(msg, param, res); if(entry_data.has_data && entry_data.type == MMDB_DATA_TYPE_UINT16) snprintf(gpv->item->r.metro, 15, "%hd", entry_data.uint16); gpv->item->r.flags |= 256; } return pv_geoip2_get_strzval(msg, param, res, gpv->item->r.metro); case 13: /* nmask */ if((gpv->item->r.flags&1024)==0) { gpv->item->r.nmask[0] = '\0'; snprintf(gpv->item->r.nmask, 8, "%hd", gpv->item->r.record.netmask); gpv->item->r.flags |= 1024; } return pv_geoip2_get_strzval(msg, param, res, gpv->item->r.nmask); default: /* cc */ if(gpv->item->r.country.s==NULL) { if(gpv->item->r.flags&512) return pv_get_null(msg, param, res); if(MMDB_get_value(&gpv->item->r.record.entry, &entry_data, "country","iso_code", NULL ) != MMDB_SUCCESS && MMDB_get_value(&gpv->item->r.record.entry, &entry_data, "registered_country","iso_code", NULL ) != MMDB_SUCCESS ) return pv_get_null(msg, param, res); if(entry_data.has_data && entry_data.type == MMDB_DATA_TYPE_UTF8_STRING) { gpv->item->r.country.s = (char *)entry_data.utf8_string; gpv->item->r.country.len = entry_data.data_size; } if(MMDB_get_value(&gpv->item->r.record.entry, &entry_data, "traits","is_anonymous_proxy", NULL) == MMDB_SUCCESS && entry_data.has_data && entry_data.type == MMDB_DATA_TYPE_BOOLEAN && entry_data.boolean) { gpv->item->r.country.s = "A1"; gpv->item->r.country.len = 2; } gpv->item->r.flags |= 512; } return pv_get_strval(msg, param, res, &gpv->item->r.country); } }
void test_mmdb(MMDB_s * mmdb) { char *ipstr; char *(*ip_string)[2] = mmdb->depth == 32 ? ip4_string : ip6_string; for (int i = 0; (ipstr = ip_string[i][0]); i++) { in_addrX ipnum; MMDB_root_entry_s root = {.entry.mmdb = mmdb }; ip_to_num(mmdb, ipstr, &ipnum); int err = mmdb->depth == 32 ? MMDB_lookup_by_ipnum(ipnum.v4.s_addr, &root) : MMDB_lookup_by_ipnum_128(ipnum.v6, &root); ok(err == MMDB_SUCCESS, "Search for %s SUCCESSFUL", ipstr); ok(root.entry.offset == 0, "No entries found for %s good", ipstr); ipstr = ip_string[i][1]; ip_to_num(mmdb, ipstr, &ipnum); err = mmdb->depth == 32 ? MMDB_lookup_by_ipnum(ipnum.v4.s_addr, &root) : MMDB_lookup_by_ipnum_128(ipnum.v6, &root); ok(err == MMDB_SUCCESS, "Search for %s SUCCESSFUL", ipstr); ok(root.entry.offset > 0, "Found something %s good", ipstr); MMDB_return_s country; MMDB_get_value(&root.entry, &country, "country", NULL); ok(country.offset > 0, "Found country hash for %s", ipstr); if (country.offset) { MMDB_entry_s country_hash = {.mmdb = mmdb,.offset = country.offset }; MMDB_return_s result; MMDB_get_value(&country_hash, &result, "iso_code", NULL); ok(result.offset > 0, "Found country code for %s", ipstr); if (result.offset > 0) { ok(MMDB_strcmp_result(mmdb, &result, "US") == 0, "Country code is US for %s", ipstr); } MMDB_get_value(&country_hash, &result, "names", "ascii", NULL); if (result.offset > 0) { ok(MMDB_strcmp_result(mmdb, &result, "United States") == 0, "Country name ascii match United States for %s", ipstr); } MMDB_get_value(&country_hash, &result, "names", "de", NULL); if (result.offset > 0) { ok(MMDB_strcmp_result(mmdb, &result, "USA") == 0, "Country name de is USA for %s", ipstr); } MMDB_get_value(&country_hash, &result, "names", "es", NULL); if (result.offset > 0) { ok(MMDB_strcmp_result(mmdb, &result, "Estados Unidos") == 0, "Country name es is Estados Unidos for %s", ipstr); } MMDB_get_value(&country_hash, &result, "names", "whatever", NULL); ok(result.offset == 0, "Country name whatever is not found for %s", ipstr); MMDB_return_s military, cellular, flt, dbl; MMDB_get_value(&root.entry, &military, "traits", "is_military", NULL); ok(military.offset != 0, "traits/is_military _is_ found for %s", ipstr); ok(military.type == MMDB_DTYPE_BOOLEAN, "is_military.type _is_ MMDB_DTYPE_BOOLEAN for %s", ipstr); ok(military.uinteger == 0, "traits/is_military _is_ 0"); MMDB_get_value(&root.entry, &cellular, "traits", "cellular", NULL); ok(cellular.offset != 0, "traits/cellular _is_ found for %s", ipstr); ok(cellular.type == MMDB_DTYPE_BOOLEAN, "cellular.type _is_ MMDB_DTYPE_BOOLEAN for %s", ipstr); ok(cellular.uinteger == 1, "traits/is_cellular _is_ 1"); MMDB_get_value(&root.entry, &flt, "test_data", "max", "float_t", NULL); ok(flt.offset != 0, "test_data/max/float_t _is_ found for %s", ipstr); ok(flt.type == MMDB_DTYPE_IEEE754_FLOAT, "flt.type _is_ MMDB_DTYPE_IEEE754_FLOAT for %s", ipstr); ok(!dbl_cmp(flt.float_value, 9999.99), "test_data/max/float_t _is_ nearly 9999.99"); MMDB_get_value(&root.entry, &dbl, "test_data", "max", "double_t", NULL); ok(dbl.offset != 0, "test_data/max/double_t _is_ found for %s", ipstr); ok(dbl.type == MMDB_DTYPE_IEEE754_DOUBLE, "dbl.type _is_ MMDB_DTYPE_IEEE754_DOUBLE for %s", ipstr); ok(!dbl_cmp(dbl.double_value, 999999999.9999), "test_data/max/double_t _is_ nearly 999999999.9999"); { double expect[] = { 0.000000, 0.000000, 1.000000, 0.100000, 0.123000, 10.000000, 7.990000, 1000000000.000000, -1.000000, -0.100000, -0.123000, -10.000000, -7.990000, -1000000000.000000 }; int cnt = sizeof(expect) / sizeof(double); MMDB_return_s got; MMDB_get_value(&root.entry, &dbl, "test_data", "tst", "array_ieee754_double_t", NULL); ok(dbl.offset > 0, "Found it"); if (dbl.offset > 0) { MMDB_entry_s dbl_array = {.mmdb = mmdb,.offset = dbl.offset }; for (int i = 0; i < cnt; i++) { char idx[256]; snprintf(idx, sizeof(idx), "%d", i); MMDB_get_value(&dbl_array, &got, idx, NULL); ok(got.offset != 0, "Found something"); ok(got.type == MMDB_DTYPE_IEEE754_DOUBLE, "type ok (is %d)", got.type); ok(!dbl_cmp(got.double_value, expect[i]), "test_data/max/double_t _is_ nearly %f", expect[i]); } check_illegal_index(&dbl_array, -1); check_illegal_index(&dbl_array, cnt); } } } } } int main(void) { char *fnames[] = { "./data/v4-24.mmdb", "./data/v4-28.mmdb", "./data/v4-32.mmdb", "./data/v6-24.mmdb", "./data/v6-28.mmdb", "./data/v6-32.mmdb", NULL }; char *fname; for (char **ptr = fnames; (fname = *ptr++);) { struct stat sstat; int err = stat(fname, &sstat); ok(err == 0, "%s exists", fname); MMDB_s *mmdb_m = MMDB_open(fname, MMDB_MODE_MEMORY_CACHE); ok(mmdb_m != NULL, "MMDB_open successful ( MMDB_MODE_MEMORY_CACHE )"); if (mmdb_m) { test_mmdb(mmdb_m); MMDB_close(mmdb_m); } MMDB_s *mmdb_s = MMDB_open(fname, MMDB_MODE_STANDARD); ok(mmdb_s != NULL, "MMDB_open successful ( MMDB_MODE_STANDARD )"); if (mmdb_s) { test_mmdb(mmdb_s); MMDB_close(mmdb_s); } } done_testing(); }
void test_nested_structure(int mode, const char *mode_desc) { const char *filename = "MaxMind-DB-test-nested.mmdb"; const char *path = test_database_path(filename); MMDB_s *mmdb = open_ok(path, mode, mode_desc); free((void *)path); const char *ip = "1.1.1.1"; MMDB_lookup_result_s result = lookup_string_ok(mmdb, ip, filename, mode_desc); { MMDB_entry_data_s entry_data; const char *lookup_path[] = { "map1", "map2", "array", "0", "map3", "a", NULL }; int status = MMDB_aget_value(&result.entry, &entry_data, lookup_path); test_complex_map_a_result(status, entry_data, "MMDB_aget_value"); status = MMDB_get_value(&result.entry, &entry_data, "map1", "map2", "array", "0", "map3", "a", NULL); test_complex_map_a_result(status, entry_data, "MMDB_get_value"); status = call_vget_value(&result.entry, &entry_data, "map1", "map2", "array", "0", "map3", "a", NULL); test_complex_map_a_result(status, entry_data, "MMDB_vget_value"); } { MMDB_entry_data_s entry_data; const char *lookup_path[] = { "map1", "map2", "array", "0", "map3", "c", NULL }; int status = MMDB_aget_value(&result.entry, &entry_data, lookup_path); test_complex_map_c_result(status, entry_data, "MMDB_aget_value"); status = MMDB_get_value(&result.entry, &entry_data, "map1", "map2", "array", "0", "map3", "c", NULL); test_complex_map_c_result(status, entry_data, "MMDB_get_value"); status = call_vget_value(&result.entry, &entry_data, "map1", "map2", "array", "0", "map3", "c", NULL); test_complex_map_c_result(status, entry_data, "MMDB_vget_value"); } { MMDB_entry_data_s entry_data; const char *lookup_path[] = { "map1", "map42", "array", "0", "map3", "c", NULL }; int status = MMDB_aget_value(&result.entry, &entry_data, lookup_path); test_no_result(status, entry_data, "MMDB_aget_value", "map1{map42}{array}[0]{map3}{c}"); status = MMDB_get_value(&result.entry, &entry_data, "map1", "map42", "array", "0", "map3", "c", NULL); test_no_result(status, entry_data, "MMDB_get_value", "map1{map42}{array}[0]{map3}{c}"); status = call_vget_value(&result.entry, &entry_data, "map1", "map42", "array", "0", "map3", "c", NULL); test_no_result(status, entry_data, "MMDB_vget_value", "map1{map42}{array}[0]{map3}{c}"); } { MMDB_entry_data_s entry_data; const char *lookup_path[] = { "map1", "map2", "array", "9", "map3", "c", NULL }; int status = MMDB_aget_value(&result.entry, &entry_data, lookup_path); test_no_result(status, entry_data, "MMDB_aget_value", "map1{map42}{array}[9]{map3}{c}"); status = MMDB_get_value(&result.entry, &entry_data, "map1", "map2", "array", "9", "map3", "c", NULL); test_no_result(status, entry_data, "MMDB_get_value", "map1{map42}{array}[9]{map3}{c}"); status = call_vget_value(&result.entry, &entry_data, "map1", "map2", "array", "9", "map3", "c", NULL); test_no_result(status, entry_data, "MMDB_vget_value", "map1{map42}{array}[9]{map3}{c}"); } MMDB_close(mmdb); free(mmdb); }