Linux C 使用 libmaxminddb 獲取 IP 的地理位置
0 執行環境
-
Ubuntu 18 x64
-
libmaxminddb 1.4.3
1 準備工作
-
資料庫 : 解析 IP 地理位置的資料庫來自 GeoLite2 開源資料庫:https://dev.maxmind.com/geoip/geoip2/geolite2/
-
C 語言 API : 使用的 API 是 maxmind 官網的開源專案 libmaxminddb,地址是 https://github.com/maxmind/libmaxminddb
2 編譯 libmaxminddb
2.1 克隆 libmaxminddb
$ git clone --recursive https://github.com/maxmind/libmaxminddb
2.2 執行 bootstrap
$ cd libmaxminddb-1.3.1
$ ./bootstrap
在執行 bootstrap 的時候可能會報錯,如下所示:
./bootstrap: 7: ./bootstrap: autoreconf: not found
原因 linux 系統缺少 autoreconf 工具
2.2.1 安裝 autoreconf 工具
sudo apt-get install autoconf automake libtool
2.2.2 重新執行 bootstrap
2.3 執行 configure
$ ./configure
2.4 執行 make
$ make
看 make 命令後的編譯記錄,可以發現 libmaxminddb.a 靜態連結庫已經編譯好了, 並且放在了 libmaxminddb/src/.libs 目錄裡面。(注意該目錄為隱藏目錄)
ps:
ll
可以列出目錄下的所有檔案,包括以 . 開頭的隱含檔案。
2.5 檢視 libmaxminddb.a 靜態連結庫
$ ll src/.libs
3 示例程式碼
example.c:
#include <errno.h> #include "maxminddb.h" #include <stdlib.h> #include <string.h> #define xdebug(fmt, arg...) \ do{\ printf("%s %d : ", __FILE__, __LINE__); \ printf(fmt, ##arg); \ printf("\n"); \ }while(0) int main(int argc, char **argv) { if(argc < 2) { xdebug("Usage : %s dbfilename IP", argv[0]); } char *filename = argv[1]; char *ip_address = argv[2]; MMDB_s mmdb; int status = MMDB_open(filename, MMDB_MODE_MMAP, &mmdb); if (MMDB_SUCCESS != status) { fprintf(stderr, "\n Can't open %s - %s\n", filename, MMDB_strerror(status)); if (MMDB_IO_ERROR == status) { fprintf(stderr, " IO error: %s\n", strerror(errno)); } exit(1); } int gai_error, mmdb_error; MMDB_lookup_result_s result = MMDB_lookup_string(&mmdb, ip_address, &gai_error, &mmdb_error); if (0 != gai_error) { fprintf(stderr, "\n Error from getaddrinfo for %s - %s\n\n", ip_address, gai_strerror(gai_error)); exit(2); } if (MMDB_SUCCESS != mmdb_error) { fprintf(stderr, "\n Got an error from libmaxminddb: %s\n\n", MMDB_strerror(mmdb_error)); exit(3); } MMDB_entry_data_list_s *entry_data_list = NULL; int exit_code = 0; if (result.found_entry) { int status = MMDB_get_entry_data_list(&result.entry, &entry_data_list); if (MMDB_SUCCESS != status) { fprintf( stderr, "Got an error looking up the entry data - %s\n", MMDB_strerror(status)); exit_code = 4; goto end; } if (NULL != entry_data_list) { MMDB_dump_entry_data_list(stdout, entry_data_list, 2); } } else { fprintf( stderr, "\n No entry for this IP address (%s) was found\n\n", ip_address); exit_code = 5; } end: MMDB_free_entry_data_list(entry_data_list); MMDB_close(&mmdb); exit(exit_code); }
3.1 編譯示例程式碼
把 libmaxminddb 原始碼中的 libmaxminddb/include/maxminddb_config.h 和 libmaxminddb/include/maxminddb.h 放到 example.c 所在的目錄下。
還有 libmaxminddb/src/.libs/libmaxminddb.a 也要放進來。
然後再用 gcc 編譯
$ cd libmaxminddb/include/
$ mv maxminddb_config.h /home/zyw/GeoIP2
$ mv maxminddb.h /home/zyw/GeoIP2
$ cd --
$ cd libmaxminddb/src/.libs/
$ mv libmaxminddb.a /home/zyw/GeoIP2
$ cd --
$ cd /home/zyw/GeoIP2
$ gcc -o example example.c ./libmaxminddb.a
$ ls
4 下載 GeoLite2 開源資料庫
開源庫下載地址:https://dev.maxmind.com/geoip/geoip2/geolite2/
從 2019年12月30日開始,要獲得免費下載 GeoLite2 資料庫的訪問許可權,需要註冊一個 GeoLite2帳戶。
(賬號名為註冊時填寫的郵箱號)
點選 Download Databases 進入下載介面
我下載的是 GeoLite2 City 資料庫。選擇如下:
解壓後的檔案如下:
$ tar xzf GeoLite2-City_20201208.tar.gz
$ ls GeoLite2-City_20201208
這裡提供一個我下載好的 GeoLite2-City_20201208.tar.gz:
連結:https://pan.baidu.com/s/1gLOf1u68wIt9Wj50PfUJgw
提取碼:hhhh
5 測試示例程式碼
把 GeoLite2-City.mmdb 移動到 example.c 所在的目錄下。
$ cd GeoLite2-City_20201208/
$ mv GeoLite2-City.mmdb /home/zyw/GeoIP2/
$ cd --
$ cd GeoIP2/
$ ls
$ ./example GeoLite2-City.mmdb "139.199.212.133"
執行結果:
6 參考資料
1、[記錄] 安裝 maxminddb 擴充套件 - cnguu - https://learnku.com/articles/26915
2、使用 GeoIP2 獲取 IP 的地理位置 - fengbohello - https://www.cnblogs.com/fengbohello/p/8144788.html
3、libmaxminddb - https://github.com/maxmind/libmaxminddb
4、GeoLite2 開源資料庫下載地址:https://dev.maxmind.com/geoip/geoip2/geolite2/