diff options
-rw-r--r-- | src/char/geoip.c | 173 | ||||
-rw-r--r-- | src/char/geoip.h | 14 | ||||
-rw-r--r-- | src/char/inter.c | 159 |
3 files changed, 171 insertions, 175 deletions
diff --git a/src/char/geoip.c b/src/char/geoip.c index 9a78c1ebd..34b731af8 100644 --- a/src/char/geoip.c +++ b/src/char/geoip.c @@ -6,22 +6,177 @@ #include "geoip.h" -#include <stdlib.h> +#include <errno.h> +#include <stdio.h> +#include <sys/stat.h> // for stat/lstat/fstat - [Dekamaster/Ultimate GM Tool] #include "../common/cbasetypes.h" -#include "../common/mmo.h" -#include "../common/random.h" +#include "../common/malloc.h" #include "../common/showmsg.h" -#include "../common/socket.h" -#include "../common/strlib.h" struct s_geoip geoip_data; -const char* geoip_getcountry(uint32 ipnum); -void geoip_final(bool shutdown); -void geoip_init(void); +struct geoip_interface geoip_s; -void geoip_defaults(void) { +/* [Dekamaster/Nightroad] */ +#define GEOIP_MAX_COUNTRIES 255 +#define GEOIP_STRUCTURE_INFO_MAX_SIZE 20 +#define GEOIP_COUNTRY_BEGIN 16776960 + +const char * geoip_countryname[GEOIP_MAX_COUNTRIES] = {"Unknown","Asia/Pacific Region","Europe","Andorra","United Arab Emirates","Afghanistan","Antigua and Barbuda","Anguilla","Albania","Armenia","Netherlands Antilles", + "Angola","Antarctica","Argentina","American Samoa","Austria","Australia","Aruba","Azerbaijan","Bosnia and Herzegovina","Barbados", + "Bangladesh","Belgium","Burkina Faso","Bulgaria","Bahrain","Burundi","Benin","Bermuda","Brunei Darussalam","Bolivia", + "Brazil","Bahamas","Bhutan","Bouvet Island","Botswana","Belarus","Belize","Canada","Cocos (Keeling) Islands","Congo, The Democratic Republic of the", + "Central African Republic","Congo","Switzerland","Cote D'Ivoire","Cook Islands","Chile","Cameroon","China","Colombia","Costa Rica", + "Cuba","Cape Verde","Christmas Island","Cyprus","Czech Republic","Germany","Djibouti","Denmark","Dominica","Dominican Republic", + "Algeria","Ecuador","Estonia","Egypt","Western Sahara","Eritrea","Spain","Ethiopia","Finland","Fiji", + "Falkland Islands (Malvinas)","Micronesia, Federated States of","Faroe Islands","France","France, Metropolitan","Gabon","United Kingdom","Grenada","Georgia","French Guiana", + "Ghana","Gibraltar","Greenland","Gambia","Guinea","Guadeloupe","Equatorial Guinea","Greece","South Georgia and the South Sandwich Islands","Guatemala", + "Guam","Guinea-Bissau","Guyana","Hong Kong","Heard Island and McDonald Islands","Honduras","Croatia","Haiti","Hungary","Indonesia", + "Ireland","Israel","India","British Indian Ocean Territory","Iraq","Iran, Islamic Republic of","Iceland","Italy","Jamaica","Jordan", + "Japan","Kenya","Kyrgyzstan","Cambodia","Kiribati","Comoros","Saint Kitts and Nevis","Korea, Democratic People's Republic of","Korea, Republic of","Kuwait", + "Cayman Islands","Kazakhstan","Lao People's Democratic Republic","Lebanon","Saint Lucia","Liechtenstein","Sri Lanka","Liberia","Lesotho","Lithuania", + "Luxembourg","Latvia","Libyan Arab Jamahiriya","Morocco","Monaco","Moldova, Republic of","Madagascar","Marshall Islands","Macedonia","Mali", + "Myanmar","Mongolia","Macau","Northern Mariana Islands","Martinique","Mauritania","Montserrat","Malta","Mauritius","Maldives", + "Malawi","Mexico","Malaysia","Mozambique","Namibia","New Caledonia","Niger","Norfolk Island","Nigeria","Nicaragua", + "Netherlands","Norway","Nepal","Nauru","Niue","New Zealand","Oman","Panama","Peru","French Polynesia", + "Papua New Guinea","Philippines","Pakistan","Poland","Saint Pierre and Miquelon","Pitcairn Islands","Puerto Rico","Palestinian Territory","Portugal","Palau", + "Paraguay","Qatar","Reunion","Romania","Russian Federation","Rwanda","Saudi Arabia","Solomon Islands","Seychelles","Sudan", + "Sweden","Singapore","Saint Helena","Slovenia","Svalbard and Jan Mayen","Slovakia","Sierra Leone","San Marino","Senegal","Somalia","Suriname", + "Sao Tome and Principe","El Salvador","Syrian Arab Republic","Swaziland","Turks and Caicos Islands","Chad","French Southern Territories","Togo","Thailand", + "Tajikistan","Tokelau","Turkmenistan","Tunisia","Tonga","Timor-Leste","Turkey","Trinidad and Tobago","Tuvalu","Taiwan", + "Tanzania, United Republic of","Ukraine","Uganda","United States Minor Outlying Islands","United States","Uruguay","Uzbekistan","Holy See (Vatican City State)","Saint Vincent and the Grenadines","Venezuela", + "Virgin Islands, British","Virgin Islands, U.S.","Vietnam","Vanuatu","Wallis and Futuna","Samoa","Yemen","Mayotte","Serbia","South Africa", + "Zambia","Montenegro","Zimbabwe","Anonymous Proxy","Satellite Provider","Other","Aland Islands","Guernsey","Isle of Man","Jersey", + "Saint Barthelemy", "Saint Martin", "Bonaire, Saint Eustatius and Saba", "South Sudan"}; + +/* [Dekamaster/Nightroad] */ +/* WHY NOT A DBMAP: There are millions of entries in GeoIP and it has its own algorithm to go quickly through them, a DBMap wouldn't be efficient */ +const char* geoip_getcountry(uint32 ipnum) +{ + int depth; + unsigned int x; + const unsigned char *buf; + unsigned int offset = 0; + + if( geoip->data->active == false ) + return geoip_countryname[0]; + + for (depth = 31; depth >= 0; depth--) { + buf = geoip->data->cache + (long)6 *offset; + if (ipnum & (1 << depth)) { + /* Take the right-hand branch */ + x = (buf[3*1 + 0] << (0*8)) + + (buf[3*1 + 1] << (1*8)) + + (buf[3*1 + 2] << (2*8)); + } else { + /* Take the left-hand branch */ + x = (buf[3*0 + 0] << (0*8)) + + (buf[3*0 + 1] << (1*8)) + + (buf[3*0 + 2] << (2*8)); + } + if (x >= GEOIP_COUNTRY_BEGIN) { + x = x-GEOIP_COUNTRY_BEGIN; + + if( x > GEOIP_MAX_COUNTRIES ) + return geoip_countryname[0]; + + return geoip_countryname[x]; + } + offset = x; + } + ShowError("geoip_getcountry(): Error traversing database for ipnum %d\n", ipnum); + ShowWarning("geoip_getcountry(): Possible database corruption!\n"); + + return geoip_countryname[0]; +} + +/** + * Disables GeoIP + * frees geoip.cache + **/ +void geoip_final(bool shutdown) +{ + if (geoip->data->cache) { + aFree(geoip->data->cache); + geoip->data->cache = NULL; + } + + if (geoip->data->active) { + if (!shutdown) + ShowStatus("GeoIP "CL_RED"disabled"CL_RESET".\n"); + geoip->data->active = false; + } +} + +/** + * Reads GeoIP database and stores it into memory + * geoip.cache should be freed after use! + * http://dev.maxmind.com/geoip/legacy/geolite/ + **/ +void geoip_init(void) +{ + int i, fno; + char db_type = 1; + unsigned char delim[3]; + struct stat bufa; + FILE *db; + + geoip->data->active = true; + + db = fopen("./db/GeoIP.dat","rb"); + if (db == NULL) { + ShowError("geoip_readdb: Error reading GeoIP.dat!\n"); + geoip->final(false); + return; + } + fno = fileno(db); + if (fstat(fno, &bufa) < 0) { + ShowError("geoip_readdb: Error stating GeoIP.dat! Error %d\n", errno); + geoip->final(false); + return; + } + geoip->data->cache = aMalloc( (sizeof(geoip->data->cache) * bufa.st_size) ); + if (fread(geoip->data->cache, sizeof(unsigned char), bufa.st_size, db) != bufa.st_size) { + ShowError("geoip_cache: Couldn't read all elements!\n"); + fclose(db); + geoip->final(false); + return; + } + + // Search database type + fseek(db, -3l, SEEK_END); + for (i = 0; i < GEOIP_STRUCTURE_INFO_MAX_SIZE; i++) { + if (fread(delim, sizeof(delim[0]), 3, db) != 3) { + db_type = 0; + break; + } + if (delim[0] == 255 && delim[1] == 255 && delim[2] == 255) { + if (fread(&db_type, sizeof(db_type), 1, db) != 1) { + db_type = 0; + } + break; + } else { + fseek(db, -4l, SEEK_CUR); + } + } + + fclose(db); + + if (db_type != 1) { + if (db_type) + ShowError("geoip_init(): Database type is not supported %d!\n", db_type); + else + ShowError("geoip_init(): GeoIP is corrupted!\n"); + + geoip->final(false); + return; + } + ShowStatus("Finished Reading "CL_GREEN"GeoIP"CL_RESET" Database.\n"); +} + +void geoip_defaults(void) +{ geoip = &geoip_s; geoip->data = &geoip_data; diff --git a/src/char/geoip.h b/src/char/geoip.h index c83d886b5..8cad2f73b 100644 --- a/src/char/geoip.h +++ b/src/char/geoip.h @@ -11,19 +11,19 @@ * GeoIP information **/ struct s_geoip { - unsigned char *cache; // GeoIP.dat information see geoip->init() - bool active; + unsigned char *cache; // GeoIP.dat information see geoip->init() + bool active; }; /** * geoip interface **/ struct geoip_interface { - struct s_geoip *data; - const char* (*getcountry) (uint32 ipnum); - void (*final) (bool shutdown); - void (*init) (void); -} geoip_s; + struct s_geoip *data; + const char* (*getcountry) (uint32 ipnum); + void (*final) (bool shutdown); + void (*init) (void); +}; struct geoip_interface *geoip; diff --git a/src/char/inter.c b/src/char/inter.c index 5ac065f23..1efe103c0 100644 --- a/src/char/inter.c +++ b/src/char/inter.c @@ -6,11 +6,9 @@ #include "inter.h" -#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <string.h> -#include <sys/stat.h> // for stat/lstat/fstat - [Dekamaster/Ultimate GM Tool] #include "char.h" #include "geoip.h" @@ -376,163 +374,6 @@ const char* inter_job_name(int class_) } } -/* [Dekamaster/Nightroad] */ -#define GEOIP_MAX_COUNTRIES 255 -#define GEOIP_STRUCTURE_INFO_MAX_SIZE 20 -#define GEOIP_COUNTRY_BEGIN 16776960 - -const char * geoip_countryname[GEOIP_MAX_COUNTRIES] = {"Unknown","Asia/Pacific Region","Europe","Andorra","United Arab Emirates","Afghanistan","Antigua and Barbuda","Anguilla","Albania","Armenia","Netherlands Antilles", - "Angola","Antarctica","Argentina","American Samoa","Austria","Australia","Aruba","Azerbaijan","Bosnia and Herzegovina","Barbados", - "Bangladesh","Belgium","Burkina Faso","Bulgaria","Bahrain","Burundi","Benin","Bermuda","Brunei Darussalam","Bolivia", - "Brazil","Bahamas","Bhutan","Bouvet Island","Botswana","Belarus","Belize","Canada","Cocos (Keeling) Islands","Congo, The Democratic Republic of the", - "Central African Republic","Congo","Switzerland","Cote D'Ivoire","Cook Islands","Chile","Cameroon","China","Colombia","Costa Rica", - "Cuba","Cape Verde","Christmas Island","Cyprus","Czech Republic","Germany","Djibouti","Denmark","Dominica","Dominican Republic", - "Algeria","Ecuador","Estonia","Egypt","Western Sahara","Eritrea","Spain","Ethiopia","Finland","Fiji", - "Falkland Islands (Malvinas)","Micronesia, Federated States of","Faroe Islands","France","France, Metropolitan","Gabon","United Kingdom","Grenada","Georgia","French Guiana", - "Ghana","Gibraltar","Greenland","Gambia","Guinea","Guadeloupe","Equatorial Guinea","Greece","South Georgia and the South Sandwich Islands","Guatemala", - "Guam","Guinea-Bissau","Guyana","Hong Kong","Heard Island and McDonald Islands","Honduras","Croatia","Haiti","Hungary","Indonesia", - "Ireland","Israel","India","British Indian Ocean Territory","Iraq","Iran, Islamic Republic of","Iceland","Italy","Jamaica","Jordan", - "Japan","Kenya","Kyrgyzstan","Cambodia","Kiribati","Comoros","Saint Kitts and Nevis","Korea, Democratic People's Republic of","Korea, Republic of","Kuwait", - "Cayman Islands","Kazakhstan","Lao People's Democratic Republic","Lebanon","Saint Lucia","Liechtenstein","Sri Lanka","Liberia","Lesotho","Lithuania", - "Luxembourg","Latvia","Libyan Arab Jamahiriya","Morocco","Monaco","Moldova, Republic of","Madagascar","Marshall Islands","Macedonia","Mali", - "Myanmar","Mongolia","Macau","Northern Mariana Islands","Martinique","Mauritania","Montserrat","Malta","Mauritius","Maldives", - "Malawi","Mexico","Malaysia","Mozambique","Namibia","New Caledonia","Niger","Norfolk Island","Nigeria","Nicaragua", - "Netherlands","Norway","Nepal","Nauru","Niue","New Zealand","Oman","Panama","Peru","French Polynesia", - "Papua New Guinea","Philippines","Pakistan","Poland","Saint Pierre and Miquelon","Pitcairn Islands","Puerto Rico","Palestinian Territory","Portugal","Palau", - "Paraguay","Qatar","Reunion","Romania","Russian Federation","Rwanda","Saudi Arabia","Solomon Islands","Seychelles","Sudan", - "Sweden","Singapore","Saint Helena","Slovenia","Svalbard and Jan Mayen","Slovakia","Sierra Leone","San Marino","Senegal","Somalia","Suriname", - "Sao Tome and Principe","El Salvador","Syrian Arab Republic","Swaziland","Turks and Caicos Islands","Chad","French Southern Territories","Togo","Thailand", - "Tajikistan","Tokelau","Turkmenistan","Tunisia","Tonga","Timor-Leste","Turkey","Trinidad and Tobago","Tuvalu","Taiwan", - "Tanzania, United Republic of","Ukraine","Uganda","United States Minor Outlying Islands","United States","Uruguay","Uzbekistan","Holy See (Vatican City State)","Saint Vincent and the Grenadines","Venezuela", - "Virgin Islands, British","Virgin Islands, U.S.","Vietnam","Vanuatu","Wallis and Futuna","Samoa","Yemen","Mayotte","Serbia","South Africa", - "Zambia","Montenegro","Zimbabwe","Anonymous Proxy","Satellite Provider","Other","Aland Islands","Guernsey","Isle of Man","Jersey", - "Saint Barthelemy", "Saint Martin", "Bonaire, Saint Eustatius and Saba", "South Sudan"}; - -/* [Dekamaster/Nightroad] */ -/* WHY NOT A DBMAP: There are millions of entries in GeoIP and it has its own algorithm to go quickly through them, a DBMap wouldn't be efficient */ -const char* geoip_getcountry(uint32 ipnum) -{ - int depth; - unsigned int x; - const unsigned char *buf; - unsigned int offset = 0; - - if( geoip->data->active == false ) - return geoip_countryname[0]; - - for (depth = 31; depth >= 0; depth--) { - buf = geoip->data->cache + (long)6 *offset; - if (ipnum & (1 << depth)) { - /* Take the right-hand branch */ - x = (buf[3*1 + 0] << (0*8)) - + (buf[3*1 + 1] << (1*8)) - + (buf[3*1 + 2] << (2*8)); - } else { - /* Take the left-hand branch */ - x = (buf[3*0 + 0] << (0*8)) - + (buf[3*0 + 1] << (1*8)) - + (buf[3*0 + 2] << (2*8)); - } - if (x >= GEOIP_COUNTRY_BEGIN) { - x = x-GEOIP_COUNTRY_BEGIN; - - if( x > GEOIP_MAX_COUNTRIES ) - return geoip_countryname[0]; - - return geoip_countryname[x]; - } - offset = x; - } - ShowError("geoip_getcountry(): Error traversing database for ipnum %d\n", ipnum); - ShowWarning("geoip_getcountry(): Possible database corruption!\n"); - - return geoip_countryname[0]; -} - -/** - * Disables GeoIP - * frees geoip.cache - **/ -void geoip_final(bool shutdown) -{ - if (geoip->data->cache) { - aFree(geoip->data->cache); - geoip->data->cache = NULL; - } - - if (geoip->data->active) { - if (!shutdown) - ShowStatus("GeoIP "CL_RED"disabled"CL_RESET".\n"); - geoip->data->active = false; - } -} - -/** - * Reads GeoIP database and stores it into memory - * geoip.cache should be freed after use! - * http://dev.maxmind.com/geoip/legacy/geolite/ - **/ -void geoip_init(void) -{ - int i, fno; - char db_type = 1; - unsigned char delim[3]; - struct stat bufa; - FILE *db; - - geoip->data->active = true; - - db = fopen("./db/GeoIP.dat","rb"); - if (db == NULL) { - ShowError("geoip_readdb: Error reading GeoIP.dat!\n"); - geoip->final(false); - return; - } - fno = fileno(db); - if (fstat(fno, &bufa) < 0) { - ShowError("geoip_readdb: Error stating GeoIP.dat! Error %d\n", errno); - geoip->final(false); - return; - } - geoip->data->cache = aMalloc( (sizeof(geoip->data->cache) * bufa.st_size) ); - if (fread(geoip->data->cache, sizeof(unsigned char), bufa.st_size, db) != bufa.st_size) { - ShowError("geoip_cache: Couldn't read all elements!\n"); - fclose(db); - geoip->final(false); - return; - } - - // Search database type - fseek(db, -3l, SEEK_END); - for (i = 0; i < GEOIP_STRUCTURE_INFO_MAX_SIZE; i++) { - if (fread(delim, sizeof(delim[0]), 3, db) != 3) { - db_type = 0; - break; - } - if (delim[0] == 255 && delim[1] == 255 && delim[2] == 255) { - if (fread(&db_type, sizeof(db_type), 1, db) != 1) { - db_type = 0; - } - break; - } else { - fseek(db, -4l, SEEK_CUR); - } - } - - fclose(db); - - if (db_type != 1) { - if (db_type) - ShowError("geoip_init(): Database type is not supported %d!\n", db_type); - else - ShowError("geoip_init(): GeoIP is corrupted!\n"); - - geoip->final(false); - return; - } - ShowStatus("Finished Reading "CL_GREEN"GeoIP"CL_RESET" Database.\n"); -} - /** * Argument-list version of inter_msg_to_fd * @see inter_msg_to_fd |