The aim of this guide is to demonstrate integrating the IP2Location C library within the D programming language. In our example, we will be using the Linux environment.
First of all, you will need to install the IP2Location C library.
Follow the instructions at https://ip2location.com/developers/c to install the IP2Location C library.
Next, install the D compiler on your Linux. We are using the DMD compiler.
Follow the instructions at https://dlang.org/download.html to install the DMD compiler.
Next, you will need to download the IP2Location BIN file.
Download at https://www.ip2location.com/database/ip2location
Extract out the BIN file and copy to the folder where you will store your D codes.
Creating the D codes
Create a text file called IP2Location.d and paste the following codes into it. Our example uses the DB24 BIN file.
The code does the following:
- Dynamically loads the IP2Location C library for use in the D codes.
- Exposing the required functions from the IP2Location C library.
- Initializing the IP2Location object with the specified BIN database path.
- Performing geolocation query for the specified IP address and displaying the results.
- Performs cleanup and unload the IP2Location C library.
NOTE: Modify the dbLit variable to store your own path to your BIN database file. Modify the ipAddressLit variable to store the IP address you wish to query.
module IP2Location;
import std.stdio;
import core.stdc.string;
import core.sys.posix.dlfcn;
extern (C)
{
struct IP2Location {
FILE *filehandle;
ubyte databasetype;
ubyte databasecolumn;
ubyte databaseday;
ubyte databasemonth;
ubyte databaseyear;
uint databasecount;
uint databaseaddr;
uint ipversion;
uint ipv4databasecount;
uint ipv4databaseaddr;
uint ipv6databasecount;
uint ipv6databaseaddr;
uint ipv4indexbaseaddr;
uint ipv6indexbaseaddr;
}
struct IP2LocationRecord {
char* country_short;
char* country_long;
char* region;
char* city;
char* isp;
float latitude;
float longitude;
char* domain;
char* zipcode;
char* timezone;
char* netspeed;
char* iddcode;
char* areacode;
char* weatherstationcode;
char* weatherstationname;
char* mcc;
char* mnc;
char* mobilebrand;
float elevation;
char* usagetype;
}
enum IP2Location_mem_type {
IP2LOCATION_FILE_IO,
IP2LOCATION_CACHE_MEMORY,
IP2LOCATION_SHARED_MEMORY
}
}
int main() {
// load the IP2Location C library
auto lib = dlopen("libIP2Location.so".ptr, RTLD_LAZY | RTLD_LOCAL);
if (lib is null) {
return -1;
}
// exposing the required functions from the IP2Location C library
extern (C) IP2Location* function(const char* db) IP2Location_open = cast(IP2Location* function(const char* db))dlsym(lib, "IP2Location_open");
extern (C) int function(IP2Location* loc, IP2Location_mem_type mem_type) IP2Location_open_mem = cast(int function(IP2Location* loc, IP2Location_mem_type mem_type))dlsym(lib, "IP2Location_open_mem");
extern (C) int function(IP2Location* loc) IP2Location_close = cast(int function(IP2Location* loc))dlsym(lib, "IP2Location_close");
extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_country_short = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_country_short");
extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_country_long = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_country_long");
extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_region = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_region");
extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_city = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_city");
extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_isp = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_isp");
extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_latitude = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_latitude");
extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_longitude = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_longitude");
extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_domain = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_domain");
extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_zipcode = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_zipcode");
extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_timezone = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_timezone");
extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_netspeed = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_netspeed");
extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_iddcode = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_iddcode");
extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_areacode = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_areacode");
extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_weatherstationcode = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_weatherstationcode");
extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_weatherstationname = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_weatherstationname");
extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_mcc = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_mcc");
extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_mnc = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_mnc");
extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_mobilebrand = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_mobilebrand");
extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_elevation = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_elevation");
extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_usagetype = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_usagetype");
extern (C) IP2LocationRecord* function(IP2Location* loc, const char* ip) IP2Location_get_all = cast(IP2LocationRecord* function(IP2Location* loc, const char* ip))dlsym(lib, "IP2Location_get_all");
extern (C) void function(IP2LocationRecord* record) IP2Location_free_record = cast(void function(IP2LocationRecord* record))dlsym(lib, "IP2Location_free_record");
extern (C) void function() IP2Location_delete_shm = cast(void function())dlsym(lib, "IP2Location_delete_shm");
extern (C) ulong function() IP2Location_api_version_num = cast(ulong function())dlsym(lib, "IP2Location_api_version_num");
extern (C) char* function() IP2Location_api_version_string = cast(char* function())dlsym(lib, "IP2Location_api_version_string");
// the path to the IP2Location BIN database (modify this to your own path)
string dbLit = "./IPV6-COUNTRY-REGION-CITY-LATITUDE-LONGITUDE-ZIPCODE-TIMEZONE-ISP-DOMAIN-NETSPEED-AREACODE-WEATHER-MOBILE-ELEVATION-USAGETYPE.BIN";
// IP address to query (modify this to the IP address you wish to query)
string ipAddressLit = "8.8.8.8";
// converting string literal to char pointer for use with IP2Location functions
const char *ipAddress = ipAddressLit.dup.ptr;
const char* db = dbLit.dup.ptr;
// initializing the IP2Location object with BIN database path
IP2Location* IP2LocationObj = IP2Location_open(db);
if (IP2LocationObj is null) {
printf("Please install the database in the correct path.\n");
return -1;
}
// uncomment this section if you want to load BIN database into cached memory
// if (IP2Location_open_mem(IP2LocationObj, IP2Location_mem_type.IP2LOCATION_CACHE_MEMORY) == -1) {
// printf("Unable to load data into cache memory.\n");
// return -1;
// }
// uncomment this section if you want to load BIN database into shared memory
// if (IP2Location_open_mem(IP2LocationObj, IP2Location_mem_type.IP2LOCATION_SHARED_MEMORY) == -1) {
// printf("Unable to load data into shared memory.\n");
// return -1;
// }
// performs IP2Location geolocation query for the specified IP address
IP2LocationRecord* record = null;
record = IP2Location_get_all(IP2LocationObj, ipAddress);
// display results if IP address is found in the BIN database
if (record is null) {
printf("Unable to locate IP address in the current database.\n");
}
else {
printf("IP Address: %s\n", ipAddress);
printf("Country Code: %s\n", record.country_short);
printf("Country Name: %s\n", record.country_long);
printf("Region: %s\n", record.region);
printf("City: %s\n", record.city);
printf("ISP: %s\n", record.isp);
printf("Latitude: %f\n", record.latitude);
printf("Longitude: %f\n", record.longitude);
printf("Domain: %s\n", record.domain);
printf("ZIP Code: %s\n", record.zipcode);
printf("Timezone: %s\n", record.timezone);
printf("Netspeed: %s\n", record.netspeed);
printf("IDD Code: %s\n", record.iddcode);
printf("Area Code: %s\n", record.areacode);
printf("Weather Station Code: %s\n", record.weatherstationcode);
printf("Weather Station Name: %s\n", record.weatherstationname);
printf("MCC: %s\n", record.mcc);
printf("MNC: %s\n", record.mnc);
printf("Mobile Brand: %s\n", record.mobilebrand);
printf("Elevation: %f\n", record.elevation);
printf("Usage Type: %s\n", record.usagetype);
printf("API Version (String): %s\n", IP2Location_api_version_string());
}
// free any allocated memory
IP2Location_free_record(record);
// close BIN database file handle
IP2Location_close(IP2LocationObj);
// delete shared memory if it was used
IP2Location_delete_shm();
// unload the IP2Location C library
if (dlclose(lib) == 0) {
return 0;
}
else {
return -1;
}
}
Compiling the IP2Location.d
At the command prompt, run the following command:
dmd IP2Location.d |
Run the program
At the command prompt, run the following command:
./IP2Location |
You should see something like below if everything goes well.
