]> git.ipfire.org Git - ipfire-2.x.git/blob - config/cfgroot/geoip-functions.pl
9f86a09ba7b5a5ab4b7abb1d6c40223b8e6f3da3
[ipfire-2.x.git] / config / cfgroot / geoip-functions.pl
1 #!/usr/bin/perl -w
2 ############################################################################
3 # #
4 # This file is part of the IPFire Firewall. #
5 # #
6 # IPFire is free software; you can redistribute it and/or modify #
7 # it under the terms of the GNU General Public License as published by #
8 # the Free Software Foundation; either version 2 of the License, or #
9 # (at your option) any later version. #
10 # #
11 # IPFire is distributed in the hope that it will be useful, #
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of #
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
14 # GNU General Public License for more details. #
15 # #
16 # You should have received a copy of the GNU General Public License #
17 # along with IPFire; if not, write to the Free Software #
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA #
19 # #
20 # Copyright (C) 2015 IPFire Team <info@ipfire.org>. #
21 # #
22 ############################################################################
23
24 package GeoIP;
25
26 require '/var/ipfire/network-functions.pl';
27
28 use Locale::Codes::Country;
29
30 # Path where all the GeoIP related databases are stored.
31 my $geoip_database_dir = "/var/lib/GeoIP";
32
33 # Database which contains all IPv4 networks.
34 my $address_ipv4_database = "GeoLite2-Country-Blocks-IPv4.csv";
35
36 # Database wich contains the locations data.
37 my $location_database = "GeoLite2-Country-Locations-en.csv";
38
39 sub lookup($) {
40 my $address = shift;
41 my $location_id;
42 my $country_code;
43
44 # Check if the given address is valid.
45 unless(&Network::check_ip_address($address)) {
46 return;
47 }
48
49 # Open the address database.
50 open(ADDRESS, "$geoip_database_dir/$address_ipv4_database") or die "Could not open $geoip_database_dir/$address_ipv4_database. $!\n";
51
52 # Loop through the file.
53 while(my $line = <ADDRESS>) {
54 # Remove newlines.
55 chomp($line);
56
57 # Split the line content.
58 my ($network, $geoname_id, $registered_country_geoname_id, $represented_country_geoname_id, $is_anonymous_proxy, $is_satellite_provider) = split(/\,/, $line);
59
60 # Check if the given address is part of the current processed network.
61 if (&Network::ip_address_in_network($address, $network)) {
62 # Store the geoname_id for this address.
63 $location_id = $geoname_id;
64
65 # Break loop.
66 last;
67 }
68 }
69
70 # Return nothing if no location_id could be found.
71 return unless($location_id);
72
73 # Close filehandle.
74 close(ADDRESS);
75
76 # Open the location database.
77 open(LOCATION, "$geoip_database_dir/$location_database") or die "Could not open $geoip_database_dir/$location_database. $!\n";
78
79 # Loop through the file.
80 while(my $line = <LOCATION>) {
81 # Remove newlines.
82 chomp($line);
83
84 # Split the line content.
85 my ($geoname_id, $locale_code, $continent_code, $continent_name, $country_iso_code, $country_name, $is_in_european_union) = split(/\,/, $line);
86
87 # Check if the correct location_id has been found.
88 if ($geoname_id eq $location_id) {
89 # Store the county code.
90 $country_code = $country_iso_code;
91
92 # Break loop.
93 last;
94 }
95 }
96
97 # Close filehandle.
98 close(LOCATION);
99
100 # Return the obtained country code.
101 return $country_code;
102 }
103
104 # Function to get the flag icon for a specified country code.
105 sub get_flag_icon($) {
106 my ($input) = @_;
107
108 # Webserver's root dir. (Required for generating full path)
109 my $webroot = "/srv/web/ipfire/html";
110
111 # Directory which contains the flag icons.
112 my $flagdir = "/images/flags";
113
114 # File extension of the country flags.
115 my $ext = "png";
116
117 # Remove whitespaces.
118 chomp($input);
119
120 # Convert given country code to upper case.
121 my $ccode = uc($input);
122
123 # Generate filename, based on the contry code in lower case
124 # and the defined file extension.
125 my $file = join('.', $ccode,$ext);
126
127 # Generate path inside webroot to the previously generated file.
128 my $flag_icon = join('/', $flagdir,$file);
129
130 # Generate absolute path to the icon file.
131 my $absolute_path = join('', $webroot,$flag_icon);
132
133 # Check if the a icon file exists.
134 if (-e "$absolute_path") {
135 # Return content of flag_icon.
136 return $flag_icon;
137 } else {
138 # If no icon for the specified country exists, try to use
139 # the icon for "unknown".
140 my $ccode = "unknown";
141
142 # Redoing all the stuff from above for the "unknown" icon.
143 my $file = join('.', $ccode, $ext);
144 my $flag_icon = join('/', $flagdir, $file);
145 my $absolute_path = join('', $webroot, $flag_icon);
146
147 # Check if the icon is present.
148 if (-e "$absolute_path") {
149 # Return "unknown" icon.
150 return $flag_icon;
151 }
152 }
153 }
154
155 # Function to get the county name by a given country code.
156 sub get_full_country_name($) {
157 my ($input) = @_;
158 my $name;
159
160 # Remove whitespaces.
161 chomp($input);
162
163 # Convert input into lower case format.
164 my $code = lc($input);
165
166 # Handle country codes which are not in the list.
167 if ($code eq "a1") { $name = "Anonymous Proxy" }
168 elsif ($code eq "a2") { $name = "Satellite Provider" }
169 elsif ($code eq "o1") { $name = "Other Country" }
170 elsif ($code eq "ap") { $name = "Asia/Pacific Region" }
171 elsif ($code eq "eu") { $name = "Europe" }
172 elsif ($code eq "yu") { $name = "Yugoslavia" }
173 else {
174 # Use perl built-in module to get the country code.
175 $name = &Locale::Codes::Country::code2country($code);
176 }
177
178 return $name;
179 }
180
181 # Function to get all available GeoIP locations.
182 sub get_geoip_locations() {
183 my @locations;
184
185 # Open the location database.
186 open(LOCATION, "$geoip_database_dir/$location_database") or die "Could not open $geoip_database_dir/$location_database. $!\n";
187
188 # Loop through the file.
189 while(my $line = <LOCATION>) {
190 # Remove newlines.
191 chomp($line);
192
193 # Split the line content.
194 my ($geoname_id, $locale_code, $continent_code, $continent_name, $country_iso_code, $country_name, $is_in_european_union) = split(/\,/, $line);
195
196 # Check if the country_iso_code is upper case.
197 if($country_iso_code =~ /[A-Z]/) {
198 # Add the current ISO code.
199 push(@locations, $country_iso_code);
200 }
201 }
202
203 # Close filehandle.
204 close(LOCATION);
205
206 # Sort locations array in alphabetical order.
207 my @sorted_locations = sort(@locations);
208
209 # Return the array..
210 return @sorted_locations;
211 }
212
213
214 1;