]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blame - config/firewall/firewall-lib.pl
Merge branch 'next'
[people/pmueller/ipfire-2.x.git] / config / firewall / firewall-lib.pl
CommitLineData
2a81ab0d
AM
1#!/usr/bin/perl
2###############################################################################
3# #
4# IPFire.org - A linux based firewall #
5bee9a9d 5# Copyright (C) 2013 Alexander Marx <amarx@ipfire.org> #
2a81ab0d
AM
6# #
7# This program is free software: you can redistribute it and/or modify #
8# it under the terms of the GNU General Public License as published by #
9# the Free Software Foundation, either version 3 of the License, or #
10# (at your option) any later version. #
11# #
12# This program is distributed in the hope that it will be useful, #
13# but WITHOUT ANY WARRANTY; without even the implied warranty of #
14# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
15# GNU General Public License for more details. #
16# #
17# You should have received a copy of the GNU General Public License #
18# along with this program. If not, see <http://www.gnu.org/licenses/>. #
19# #
20###############################################################################
2a81ab0d
AM
21
22use strict;
5653e551
AF
23use experimental 'smartmatch';
24
2a81ab0d
AM
25no warnings 'uninitialized';
26
27package fwlib;
28
29my %customnetwork=();
30my %customhost=();
31my %customgrp=();
b9ca2fa6 32my %customgeoipgrp=();
2a81ab0d
AM
33my %customservice=();
34my %customservicegrp=();
35my %ccdnet=();
36my %ccdhost=();
37my %ipsecconf=();
38my %ipsecsettings=();
39my %netsettings=();
40my %ovpnsettings=();
4e54e3c6 41my %aliases=();
2a81ab0d
AM
42
43require '/var/ipfire/general-functions.pl';
5cf83d56 44require '/var/ipfire/geoip-functions.pl';
2a81ab0d
AM
45
46my $confignet = "${General::swroot}/fwhosts/customnetworks";
47my $confighost = "${General::swroot}/fwhosts/customhosts";
48my $configgrp = "${General::swroot}/fwhosts/customgroups";
b9ca2fa6 49my $configgeoipgrp = "${General::swroot}/fwhosts/customgeoipgrp";
2a81ab0d
AM
50my $configsrv = "${General::swroot}/fwhosts/customservices";
51my $configsrvgrp = "${General::swroot}/fwhosts/customservicegrp";
52my $configccdnet = "${General::swroot}/ovpn/ccd.conf";
53my $configccdhost = "${General::swroot}/ovpn/ovpnconfig";
54my $configipsec = "${General::swroot}/vpn/config";
55my $configovpn = "${General::swroot}/ovpn/settings";
56my $val;
57my $field;
fd169d0a 58my $netsettings = "${General::swroot}/ethernet/settings";
2a81ab0d
AM
59
60&General::readhash("/var/ipfire/ethernet/settings", \%netsettings);
61&General::readhash("${General::swroot}/ovpn/settings", \%ovpnsettings);
62&General::readhash("${General::swroot}/vpn/settings", \%ipsecsettings);
2a81ab0d
AM
63
64&General::readhasharray("$confignet", \%customnetwork);
65&General::readhasharray("$confighost", \%customhost);
66&General::readhasharray("$configgrp", \%customgrp);
b9ca2fa6 67&General::readhasharray("$configgeoipgrp", \%customgeoipgrp);
2a81ab0d
AM
68&General::readhasharray("$configccdnet", \%ccdnet);
69&General::readhasharray("$configccdhost", \%ccdhost);
70&General::readhasharray("$configipsec", \%ipsecconf);
71&General::readhasharray("$configsrv", \%customservice);
72&General::readhasharray("$configsrvgrp", \%customservicegrp);
085a20ec 73&General::get_aliases(\%aliases);
2a81ab0d 74
dba780a7
SS
75# Get all available GeoIP locations.
76my @available_geoip_locations = &get_geoip_locations();
77
2a81ab0d
AM
78sub get_srv_prot
79{
80 my $val=shift;
992394d5 81 foreach my $key (sort {$a <=> $b} keys %customservice){
2a81ab0d
AM
82 if($customservice{$key}[0] eq $val){
83 if ($customservice{$key}[0] eq $val){
84 return $customservice{$key}[2];
85 }
86 }
87 }
88}
89sub get_srvgrp_prot
90{
91 my $val=shift;
92 my @ips=();
93 my $tcp;
94 my $udp;
95 my $icmp;
992394d5 96 foreach my $key (sort {$a <=> $b} keys %customservicegrp){
2a81ab0d
AM
97 if($customservicegrp{$key}[0] eq $val){
98 if (&get_srv_prot($customservicegrp{$key}[2]) eq 'TCP'){
99 $tcp=1;
100 }elsif(&get_srv_prot($customservicegrp{$key}[2]) eq 'UDP'){
101 $udp=1;
102 }elsif(&get_srv_prot($customservicegrp{$key}[2]) eq 'ICMP'){
103 $icmp=1;
82b837cf
AM
104 }else{
105 #Protocols used in servicegroups
106 push (@ips,$customservicegrp{$key}[2]);
107 }
2a81ab0d
AM
108 }
109 }
110 if ($tcp eq '1'){push (@ips,'TCP');}
111 if ($udp eq '1'){push (@ips,'UDP');}
112 if ($icmp eq '1'){push (@ips,'ICMP');}
113 my $back=join(",",@ips);
114 return $back;
115
116}
2a81ab0d
AM
117sub get_srv_port
118{
119 my $val=shift;
120 my $field=shift;
121 my $prot=shift;
992394d5 122 foreach my $key (sort {$a <=> $b} keys %customservice){
14bcb9a2
AM
123 if($customservice{$key}[0] eq $val && $customservice{$key}[2] eq $prot){
124 return $customservice{$key}[$field];
2a81ab0d
AM
125 }
126 }
127}
128sub get_srvgrp_port
129{
130 my $val=shift;
131 my $prot=shift;
132 my $back;
133 my $value;
134 my @ips=();
992394d5 135 foreach my $key (sort {$a <=> $b} keys %customservicegrp){
2a81ab0d
AM
136 if($customservicegrp{$key}[0] eq $val){
137 if ($prot ne 'ICMP'){
138 $value=&get_srv_port($customservicegrp{$key}[2],1,$prot);
139 }elsif ($prot eq 'ICMP'){
140 $value=&get_srv_port($customservicegrp{$key}[2],3,$prot);
141 }
142 push (@ips,$value) if ($value ne '') ;
143 }
144 }
145 if($prot ne 'ICMP'){
146 if ($#ips gt 0){$back="-m multiport --dports ";}else{$back="--dport ";}
147 }elsif ($prot eq 'ICMP'){
148 $back="--icmp-type ";
149 }
150
151 $back.=join(",",@ips);
152 return $back;
153}
154sub get_ipsec_net_ip
155{
156 my $val=shift;
157 my $field=shift;
992394d5 158 foreach my $key (sort {$a <=> $b} keys %ipsecconf){
8b20ca2d
AM
159 #adapt $val to reflect real name without subnet (if rule with only one ipsec subnet is created)
160 my @tmpval = split (/\|/, $val);
161 $val = $tmpval[0];
2a81ab0d
AM
162 if($ipsecconf{$key}[1] eq $val){
163 return $ipsecconf{$key}[$field];
164 }
165 }
166}
167sub get_ipsec_host_ip
168{
169 my $val=shift;
170 my $field=shift;
992394d5 171 foreach my $key (sort {$a <=> $b} keys %ipsecconf){
2a81ab0d
AM
172 if($ipsecconf{$key}[1] eq $val){
173 return $ipsecconf{$key}[$field];
174 }
175 }
176}
7ba652af
MT
177sub get_ipsec_id {
178 my $val = shift;
179
180 foreach my $key (keys %ipsecconf) {
181 if ($ipsecconf{$key}[1] eq $val) {
182 return $key;
183 }
184 }
185}
2a81ab0d
AM
186sub get_ovpn_n2n_ip
187{
188 my $val=shift;
189 my $field=shift;
992394d5 190 foreach my $key (sort {$a <=> $b} keys %ccdhost){
2a81ab0d
AM
191 if($ccdhost{$key}[1] eq $val){
192 return $ccdhost{$key}[$field];
193 }
194 }
195}
196sub get_ovpn_host_ip
197{
198 my $val=shift;
199 my $field=shift;
992394d5 200 foreach my $key (sort {$a <=> $b} keys %ccdhost){
2a81ab0d
AM
201 if($ccdhost{$key}[1] eq $val){
202 return $ccdhost{$key}[$field];
203 }
204 }
205}
206sub get_ovpn_net_ip
207{
208
209 my $val=shift;
210 my $field=shift;
992394d5 211 foreach my $key (sort {$a <=> $b} keys %ccdnet){
2a81ab0d
AM
212 if($ccdnet{$key}[0] eq $val){
213 return $ccdnet{$key}[$field];
214 }
215 }
216}
217sub get_grp_ip
218{
219 my $val=shift;
220 my $src=shift;
992394d5 221 foreach my $key (sort {$a <=> $b} keys %customgrp){
2a81ab0d
AM
222 if ($customgrp{$key}[0] eq $val){
223 &get_address($customgrp{$key}[3],$src);
224 }
225 }
226
227}
228sub get_std_net_ip
229{
230 my $val=shift;
ddcec9d3 231 my $con=shift;
2a81ab0d
AM
232 if ($val eq 'ALL'){
233 return "0.0.0.0/0.0.0.0";
234 }elsif($val eq 'GREEN'){
235 return "$netsettings{'GREEN_NETADDRESS'}/$netsettings{'GREEN_NETMASK'}";
236 }elsif($val eq 'ORANGE'){
237 return "$netsettings{'ORANGE_NETADDRESS'}/$netsettings{'ORANGE_NETMASK'}";
238 }elsif($val eq 'BLUE'){
239 return "$netsettings{'BLUE_NETADDRESS'}/$netsettings{'BLUE_NETMASK'}";
62fc8511 240 }elsif($val eq 'RED'){
48f07c19 241 return "0.0.0.0/0";
2a81ab0d
AM
242 }elsif($val =~ /OpenVPN/i){
243 return "$ovpnsettings{'DOVPN_SUBNET'}";
244 }elsif($val =~ /IPsec/i){
245 return "$ipsecsettings{'RW_NET'}";
5d7faa45
AM
246 }elsif($val eq 'IPFire'){
247 return ;
2a81ab0d
AM
248 }
249}
48f07c19
AM
250sub get_interface
251{
252 my $net=shift;
253 if($net eq "$netsettings{'GREEN_NETADDRESS'}/$netsettings{'GREEN_NETMASK'}"){
254 return "$netsettings{'GREEN_DEV'}";
255 }
256 if($net eq "$netsettings{'ORANGE_NETADDRESS'}/$netsettings{'ORANGE_NETMASK'}"){
257 return "$netsettings{'ORANGE_DEV'}";
258 }
259 if($net eq "$netsettings{'BLUE_NETADDRESS'}/$netsettings{'BLUE_NETMASK'}"){
260 return "$netsettings{'BLUE_DEV'}";
261 }
a21f2f6a
MT
262 if($net eq "0.0.0.0/0") {
263 return &get_external_interface();
48f07c19
AM
264 }
265 return "";
266}
2a81ab0d
AM
267sub get_net_ip
268{
269 my $val=shift;
992394d5 270 foreach my $key (sort {$a <=> $b} keys %customnetwork){
2a81ab0d
AM
271 if($customnetwork{$key}[0] eq $val){
272 return "$customnetwork{$key}[1]/$customnetwork{$key}[2]";
273 }
274 }
275}
276sub get_host_ip
277{
278 my $val=shift;
279 my $src=shift;
992394d5 280 foreach my $key (sort {$a <=> $b} keys %customhost){
2a81ab0d
AM
281 if($customhost{$key}[0] eq $val){
282 if ($customhost{$key}[1] eq 'mac' && $src eq 'src'){
283 return "-m mac --mac-source $customhost{$key}[2]";
284 }elsif($customhost{$key}[1] eq 'ip' && $src eq 'src'){
285 return "$customhost{$key}[2]";
286 }elsif($customhost{$key}[1] eq 'ip' && $src eq 'tgt'){
287 return "$customhost{$key}[2]";
288 }elsif($customhost{$key}[1] eq 'mac' && $src eq 'tgt'){
289 return "none";
290 }
291 }
292 }
293}
fd169d0a
AM
294sub get_addresses
295{
4e54e3c6
AM
296 my $hash = shift;
297 my $key = shift;
298 my $type = shift;
299
300 my @addresses = ();
301 my $addr_type;
302 my $value;
303 my $group_name;
304
305 if ($type eq "src") {
306 $addr_type = $$hash{$key}[3];
307 $value = $$hash{$key}[4];
308
309 } elsif ($type eq "tgt") {
310 $addr_type = $$hash{$key}[5];
311 $value = $$hash{$key}[6];
312 }
313
314 if ($addr_type ~~ ["cust_grp_src", "cust_grp_tgt"]) {
315 foreach my $grp (sort {$a <=> $b} keys %customgrp) {
316 if ($customgrp{$grp}[0] eq $value) {
317 my @address = &get_address($customgrp{$grp}[3], $customgrp{$grp}[2], $type);
318
b9ca2fa6
AM
319 if (@address) {
320 push(@addresses, @address);
321 }
322 }
323 }
324 }elsif ($addr_type ~~ ["cust_geoip_src", "cust_geoip_tgt"] && $value =~ "group:") {
325 $value=substr($value,6);
326 foreach my $grp (sort {$a <=> $b} keys %customgeoipgrp) {
327 if ($customgeoipgrp{$grp}[0] eq $value) {
328 my @address = &get_address($addr_type, $customgeoipgrp{$grp}[2], $type);
329
4e54e3c6
AM
330 if (@address) {
331 push(@addresses, @address);
332 }
333 }
334 }
335 } else {
336 my @address = &get_address($addr_type, $value, $type);
337
338 if (@address) {
339 push(@addresses, @address);
340 }
341 }
342
343 return @addresses;
344}
fd169d0a
AM
345sub get_address
346{
4e54e3c6
AM
347 my $key = shift;
348 my $value = shift;
349 my $type = shift;
350
351 my @ret = ();
352
353 # If the user manually typed an address, we just check if it is a MAC
354 # address. Otherwise, we assume that it is an IP address.
355 if ($key ~~ ["src_addr", "tgt_addr"]) {
356 if (&General::validmac($value)) {
48f07c19 357 push(@ret, ["-m mac --mac-source $value", ""]);
4e54e3c6 358 } else {
48f07c19 359 push(@ret, [$value, ""]);
4e54e3c6
AM
360 }
361
362 # If a default network interface (GREEN, BLUE, etc.) is selected, we
363 # try to get the corresponding address of the network.
364 } elsif ($key ~~ ["std_net_src", "std_net_tgt", "Standard Network"]) {
365 my $external_interface = &get_external_interface();
366
367 my $network_address = &get_std_net_ip($value, $external_interface);
48f07c19 368
4e54e3c6 369 if ($network_address) {
48f07c19
AM
370 my $interface = &get_interface($network_address);
371 push(@ret, [$network_address, $interface]);
4e54e3c6
AM
372 }
373
374 # Custom networks.
375 } elsif ($key ~~ ["cust_net_src", "cust_net_tgt", "Custom Network"]) {
376 my $network_address = &get_net_ip($value);
377 if ($network_address) {
48f07c19 378 push(@ret, [$network_address, ""]);
4e54e3c6
AM
379 }
380
381 # Custom hosts.
382 } elsif ($key ~~ ["cust_host_src", "cust_host_tgt", "Custom Host"]) {
383 my $host_address = &get_host_ip($value, $type);
384 if ($host_address) {
48f07c19 385 push(@ret, [$host_address, ""]);
4e54e3c6
AM
386 }
387
388 # OpenVPN networks.
389 } elsif ($key ~~ ["ovpn_net_src", "ovpn_net_tgt", "OpenVPN static network"]) {
390 my $network_address = &get_ovpn_net_ip($value, 1);
391 if ($network_address) {
48f07c19 392 push(@ret, [$network_address, ""]);
4e54e3c6
AM
393 }
394
395 # OpenVPN hosts.
396 } elsif ($key ~~ ["ovpn_host_src", "ovpn_host_tgt", "OpenVPN static host"]) {
397 my $host_address = &get_ovpn_host_ip($value, 33);
398 if ($host_address) {
48f07c19 399 push(@ret, [$host_address, ""]);
4e54e3c6
AM
400 }
401
402 # OpenVPN N2N.
403 } elsif ($key ~~ ["ovpn_n2n_src", "ovpn_n2n_tgt", "OpenVPN N-2-N"]) {
404 my $network_address = &get_ovpn_n2n_ip($value, 11);
405 if ($network_address) {
48f07c19 406 push(@ret, [$network_address, ""]);
4e54e3c6
AM
407 }
408
409 # IPsec networks.
410 } elsif ($key ~~ ["ipsec_net_src", "ipsec_net_tgt", "IpSec Network"]) {
8b20ca2d
AM
411 #Check if we have multiple subnets and only want one of them
412 if ( $value =~ /\|/ ){
413 my @parts = split(/\|/, $value);
414 push(@ret, [$parts[1], ""]);
415 }else{
7ba652af
MT
416 my $interface_mode = &get_ipsec_net_ip($value, 36);
417 if ($interface_mode ~~ ["gre", "vti"]) {
418 my $id = &get_ipsec_id($value);
419 push(@ret, ["0.0.0.0/0", "${interface_mode}${id}"]);
420 } else {
421 my $network_address = &get_ipsec_net_ip($value, 11);
422 my @nets = split(/\|/, $network_address);
423 foreach my $net (@nets) {
424 push(@ret, [$net, ""]);
425 }
8b20ca2d 426 }
4e54e3c6
AM
427 }
428
429 # The firewall's own IP addresses.
430 } elsif ($key ~~ ["ipfire", "ipfire_src"]) {
431 # ALL
432 if ($value eq "ALL") {
48f07c19 433 push(@ret, ["0/0", ""]);
4e54e3c6
AM
434
435 # GREEN
436 } elsif ($value eq "GREEN") {
48f07c19 437 push(@ret, [$netsettings{"GREEN_ADDRESS"}, ""]);
4e54e3c6
AM
438
439 # BLUE
440 } elsif ($value eq "BLUE") {
48f07c19 441 push(@ret, [$netsettings{"BLUE_ADDRESS"}, ""]);
4e54e3c6
AM
442
443 # ORANGE
444 } elsif ($value eq "ORANGE") {
48f07c19 445 push(@ret, [$netsettings{"ORANGE_ADDRESS"}, ""]);
4e54e3c6
AM
446
447 # RED
448 } elsif ($value ~~ ["RED", "RED1"]) {
449 my $address = &get_external_address();
450 if ($address) {
48f07c19 451 push(@ret, [$address, ""]);
4e54e3c6
AM
452 }
453
454 # Aliases
455 } else {
085a20ec
MT
456 my $alias = &get_alias($value);
457 if ($alias) {
48f07c19 458 push(@ret, [$alias, ""]);
4e54e3c6
AM
459 }
460 }
461
b9ca2fa6
AM
462 # Handle rule options with GeoIP as source.
463 } elsif ($key eq "cust_geoip_src") {
dba780a7
SS
464 # Check if the given GeoIP location is available.
465 if(&geoip_location_is_available($value)) {
466 # Get external interface.
467 my $external_interface = &get_external_interface();
b9ca2fa6 468
dba780a7
SS
469 push(@ret, ["-m geoip --src-cc $value", "$external_interface"]);
470 }
b9ca2fa6
AM
471
472 # Handle rule options with GeoIP as target.
473 } elsif ($key eq "cust_geoip_tgt") {
dba780a7
SS
474 # Check if the given GeoIP location is available.
475 if(&geoip_location_is_available($value)) {
476 # Get external interface.
477 my $external_interface = &get_external_interface();
b9ca2fa6 478
dba780a7
SS
479 push(@ret, ["-m geoip --dst-cc $value", "$external_interface"]);
480 }
b9ca2fa6 481
4e54e3c6
AM
482 # If nothing was selected, we assume "any".
483 } else {
48f07c19 484 push(@ret, ["0/0", ""]);
4e54e3c6
AM
485 }
486
487 return @ret;
488}
fd169d0a
AM
489sub get_external_interface()
490{
4e54e3c6
AM
491 open(IFACE, "/var/ipfire/red/iface") or return "";
492 my $iface = <IFACE>;
493 close(IFACE);
494
495 return $iface;
496}
fd169d0a
AM
497sub get_external_address()
498{
4e54e3c6
AM
499 open(ADDR, "/var/ipfire/red/local-ipaddress") or return "";
500 my $address = <ADDR>;
501 close(ADDR);
502
503 return $address;
504}
fd169d0a
AM
505sub get_alias
506{
4e54e3c6
AM
507 my $id = shift;
508
509 foreach my $alias (sort keys %aliases) {
510 if ($id eq $alias) {
085a20ec 511 return $aliases{$alias}{"IPT"};
4e54e3c6
AM
512 }
513 }
514}
085a20ec
MT
515
516sub get_nat_address {
4e54e3c6
AM
517 my $zone = shift;
518 my $source = shift;
519
520 # Any static address of any zone.
521 if ($zone eq "AUTO") {
fd169d0a 522 if ($source && ($source !~ m/mac/i )) {
4e54e3c6
AM
523 my $firewall_ip = &get_internal_firewall_ip_address($source, 1);
524 if ($firewall_ip) {
525 return $firewall_ip;
526 }
527
528 $firewall_ip = &get_matching_firewall_address($source, 1);
529 if ($firewall_ip) {
530 return $firewall_ip;
531 }
532 }
533
534 return &get_external_address();
535
536 } elsif ($zone eq "RED" || $zone eq "GREEN" || $zone eq "ORANGE" || $zone eq "BLUE") {
c71499d8 537 return $netsettings{$zone . "_ADDRESS"};
4e54e3c6 538
085a20ec 539 } elsif ($zone ~~ ["Default IP", "ALL"]) {
4e54e3c6
AM
540 return &get_external_address();
541
542 } else {
085a20ec
MT
543 my $alias = &get_alias($zone);
544 unless ($alias) {
545 $alias = &get_external_address();
546 }
547 return $alias;
4e54e3c6
AM
548 }
549
550 print_error("Could not find NAT address");
551}
085a20ec 552
fd169d0a
AM
553sub get_internal_firewall_ip_addresses
554{
4e54e3c6
AM
555 my $use_orange = shift;
556
557 my @zones = ("GREEN", "BLUE");
558 if ($use_orange) {
559 push(@zones, "ORANGE");
560 }
561
562 my @addresses = ();
563 for my $zone (@zones) {
c71499d8 564 next unless (exists $netsettings{$zone . "_ADDRESS"});
4e54e3c6 565
c71499d8 566 my $zone_address = $netsettings{$zone . "_ADDRESS"};
4e54e3c6
AM
567 push(@addresses, $zone_address);
568 }
569
570 return @addresses;
571}
fd169d0a
AM
572sub get_matching_firewall_address
573{
4e54e3c6
AM
574 my $addr = shift;
575 my $use_orange = shift;
576
577 my ($address, $netmask) = split("/", $addr);
578
579 my @zones = ("GREEN", "BLUE");
580 if ($use_orange) {
581 push(@zones, "ORANGE");
582 }
583
584 foreach my $zone (@zones) {
c71499d8 585 next unless (exists $netsettings{$zone . "_ADDRESS"});
4e54e3c6 586
c71499d8
AM
587 my $zone_subnet = $netsettings{$zone . "_NETADDRESS"};
588 my $zone_mask = $netsettings{$zone . "_NETMASK"};
4e54e3c6
AM
589
590 if (&General::IpInSubnet($address, $zone_subnet, $zone_mask)) {
c71499d8 591 return $netsettings{$zone . "_ADDRESS"};
4e54e3c6
AM
592 }
593 }
594
595 return 0;
596}
fd169d0a
AM
597sub get_internal_firewall_ip_address
598{
4e54e3c6
AM
599 my $subnet = shift;
600 my $use_orange = shift;
601
602 my ($net_address, $net_mask) = split("/", $subnet);
603 if ((!$net_mask) || ($net_mask ~~ ["32", "255.255.255.255"])) {
604 return 0;
605 }
606
aa5f4b65
MT
607 # Convert net mask into correct format for &General::IpInSubnet().
608 $net_mask = &General::iporsubtodec($net_mask);
609
4e54e3c6
AM
610 my @addresses = &get_internal_firewall_ip_addresses($use_orange);
611 foreach my $zone_address (@addresses) {
612 if (&General::IpInSubnet($zone_address, $net_address, $net_mask)) {
613 return $zone_address;
614 }
615 }
616
617 return 0;
618}
619
593c3227 620sub get_geoip_locations() {
8ff42d82 621 return &GeoIP::get_geoip_locations();
593c3227
SS
622}
623
dba780a7
SS
624# Function to check if a database of a given GeoIP location is
625# available.
626sub geoip_location_is_available($) {
627 my ($location) = @_;
628
629 # Loop through the global array of available GeoIP locations.
630 foreach my $geoip_location (@available_geoip_locations) {
631 # Check if the current processed location is the searched one.
632 if($location eq $geoip_location) {
633 # If it is part of the array, return "1" - True.
634 return 1;
635 }
636 }
637
638 # If we got here, the given location is not part of the array of available
639 # zones. Return nothing.
640 return;
641}
642
2a81ab0d 643return 1;