--- /dev/null
+#!/usr/bin/perl\r
+# extended geoip.pm by Sven Strickroth <email@cs-ware.de>\r
+#-----------------------------------------------------------------------------\r
+# GeoIP Maxmind AWStats plugin with IPv6 support\r
+# This plugin allow you to get country report with countries detected\r
+# from a Geographical database (GeoIP internal database) instead of domain\r
+# hostname suffix.\r
+# This works with IPv4 and also IPv6\r
+# Needs the IPv6 country database from Maxmind (free).\r
+#-----------------------------------------------------------------------------\r
+# Perl Required Modules: Geo::IP (Geo::IP::PurePerl does not support IPv6 yet)\r
+#-----------------------------------------------------------------------------\r
+\r
+# <-----\r
+# ENTER HERE THE USE COMMAND FOR ALL REQUIRED PERL MODULES\r
+use vars qw/ $type /;\r
+$type='geoip';\r
+if (!eval ('require "Geo/IP.pm";')) {\r
+ $error1=$@;\r
+# $type='geoippureperl';\r
+# if (!eval ('require "Geo/IP/PurePerl.pm";')) {\r
+# $error2=$@;\r
+# $ret=($error1||$error2)?"Error:\n$error1$error2":"";\r
+ $ret.="Error: Need Perl module Geo::IP";\r
+ return $ret;\r
+# }\r
+} else {\r
+ Geo::IP->VERSION >= 1.40 || die("Requires Geo/IP.pm >= 1.40");\r
+}\r
+# ----->\r
+#use strict;\r
+no strict "refs";\r
+\r
+\r
+\r
+#-----------------------------------------------------------------------------\r
+# PLUGIN VARIABLES\r
+#-----------------------------------------------------------------------------\r
+# <-----\r
+# ENTER HERE THE MINIMUM AWSTATS VERSION REQUIRED BY YOUR PLUGIN\r
+# AND THE NAME OF ALL FUNCTIONS THE PLUGIN MANAGE.\r
+my $PluginNeedAWStatsVersion="5.4";\r
+my $PluginHooksFunctions="GetCountryCodeByAddr GetCountryCodeByName ShowInfoHost";\r
+my $PluginName = "geoip6";\r
+my $LoadedOverride=0;\r
+my $OverrideFile="";\r
+my %TmpDomainLookup;\r
+# ----->\r
+\r
+# <-----\r
+# IF YOUR PLUGIN NEED GLOBAL VARIABLES, THEY MUST BE DECLARED HERE.\r
+use vars qw/\r
+$gi\r
+/;\r
+# ----->\r
+\r
+\r
+#-----------------------------------------------------------------------------\r
+# PLUGIN FUNCTION: Init_pluginname\r
+#-----------------------------------------------------------------------------\r
+sub Init_geoip6 {\r
+ my $InitParams=shift;\r
+ my $checkversion=&Check_Plugin_Version($PluginNeedAWStatsVersion);\r
+\r
+ # <-----\r
+ # ENTER HERE CODE TO DO INIT PLUGIN ACTIONS\r
+ debug(" Plugin $PluginName: InitParams=$InitParams",1);\r
+ my ($mode,$tmpdatafile)=split(/\s+/,$InitParams,2);\r
+ my ($datafile,$override)=split(/\+/,$tmpdatafile,2);\r
+ if (! $datafile) { $datafile="$PluginName.dat"; }\r
+ else { $datafile =~ s/%20/ /g; }\r
+ if ($type eq 'geoippureperl') {\r
+ if ($mode eq '' || $mode eq 'GEOIP_MEMORY_CACHE') { $mode=Geo::IP::PurePerl::GEOIP_MEMORY_CACHE(); }\r
+ else { $mode=Geo::IP::PurePerl::GEOIP_STANDARD(); }\r
+ } else {\r
+ if ($mode eq '' || $mode eq 'GEOIP_MEMORY_CACHE') { $mode=Geo::IP::GEOIP_MEMORY_CACHE(); }\r
+ else { $mode=Geo::IP::GEOIP_STANDARD(); }\r
+ }\r
+ if ($override){$OverrideFile=$override;}\r
+ %TmpDomainLookup=();\r
+ debug(" Plugin $PluginName: GeoIP initialized type=$type mode=$mode override=$override",1);\r
+ if ($type eq 'geoippureperl') {\r
+ $gi = Geo::IP::PurePerl->open($datafile, $mode);\r
+ } else {\r
+ $gi = Geo::IP->open($datafile, $mode);\r
+ }\r
+\r
+# Fails on some GeoIP version\r
+# debug(" Plugin geoip6: GeoIP initialized database_info=".$gi->database_info());\r
+ # ----->\r
+\r
+ return ($checkversion?$checkversion:"$PluginHooksFunctions");\r
+}\r
+\r
+\r
+#-----------------------------------------------------------------------------\r
+# PLUGIN FUNCTION: GetCountryCodeByAddr_pluginname\r
+# UNIQUE: YES (Only one plugin using this function can be loaded)\r
+# GetCountryCodeByAddr is called to translate an ip into a country code in lower case.\r
+#-----------------------------------------------------------------------------\r
+sub GetCountryCodeByAddr_geoip6 {\r
+ my $param="$_[0]";\r
+ # <-----\r
+ if (! $param) { return ''; }\r
+ my $searchkey;\r
+ if ($param =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { # IPv4 address\r
+ $searchkey = '::'.$param;\r
+ } else {\r
+ $searchkey = $param;\r
+ }\r
+ my $res= TmpLookup_geoip6($param);\r
+ if (! $res) {\r
+ $res=lc($gi->country_code_by_addr_v6($searchkey)) || 'unknown';\r
+ $TmpDomainLookup{$param}=$res;\r
+ if ($Debug) { debug(" Plugin $PluginName: GetCountryCodeByAddr for $searchkey: [$res]",5); }\r
+ }\r
+ elsif ($Debug) { debug(" Plugin $PluginName: GetCountryCodeByAddr for $param: Already resolved to [$res]",5); }\r
+ # ----->\r
+ return $res;\r
+}\r
+\r
+\r
+#-----------------------------------------------------------------------------\r
+# PLUGIN FUNCTION: GetCountryCodeByName_pluginname\r
+# UNIQUE: YES (Only one plugin using this function can be loaded)\r
+# GetCountryCodeByName is called to translate a host name into a country code in lower case.\r
+#-----------------------------------------------------------------------------\r
+sub GetCountryCodeByName_geoip6 {\r
+ my $param="$_[0]";\r
+ # <-----\r
+ if (! $param) { return ''; }\r
+ my $res = TmpLookup_geoip6($param);\r
+ if (! $res) {\r
+ $res=lc($gi->country_code_by_name_v6($param)) || 'unknown';\r
+ $TmpDomainLookup{$param}=$res;\r
+ if ($Debug) { debug(" Plugin $PluginName: GetCountryCodeByName for $param: [$res]",5); }\r
+ }\r
+ elsif ($Debug) { debug(" Plugin $PluginName: GetCountryCodeByName for $param: Already resolved to [$res]",5); }\r
+ # ----->\r
+ return $res;\r
+}\r
+\r
+\r
+#-----------------------------------------------------------------------------\r
+# PLUGIN FUNCTION: ShowInfoHost_pluginname\r
+# UNIQUE: NO (Several plugins using this function can be loaded)\r
+# Function called to add additionnal columns to the Hosts report.\r
+# This function is called when building rows of the report (One call for each\r
+# row). So it allows you to add a column in report, for example with code :\r
+# print "<TD>This is a new cell for $param</TD>";\r
+# Parameters: Host name or ip\r
+#-----------------------------------------------------------------------------\r
+sub ShowInfoHost_geoip6 {\r
+ my $param="$_[0]";\r
+ # <-----\r
+ if ($param eq '__title__') {\r
+ my $NewLinkParams=${QueryString};\r
+ $NewLinkParams =~ s/(^|&)update(=\w*|$)//i;\r
+ $NewLinkParams =~ s/(^|&)output(=\w*|$)//i;\r
+ $NewLinkParams =~ s/(^|&)staticlinks(=\w*|$)//i;\r
+ $NewLinkParams =~ s/(^|&)framename=[^&]*//i;\r
+ my $NewLinkTarget='';\r
+ if ($DetailedReportsOnNewWindows) { $NewLinkTarget=" target=\"awstatsbis\""; }\r
+ if (($FrameName eq 'mainleft' || $FrameName eq 'mainright') && $DetailedReportsOnNewWindows < 2) {\r
+ $NewLinkParams.="&framename=mainright";\r
+ $NewLinkTarget=" target=\"mainright\"";\r
+ }\r
+ $NewLinkParams =~ tr/&/&/s; $NewLinkParams =~ s/^&//; $NewLinkParams =~ s/&$//;\r
+ if ($NewLinkParams) { $NewLinkParams="${NewLinkParams}&"; }\r
+\r
+ print "<th width=\"80\">";\r
+ print "<a href=\"#countries\">GeoIP<br />Country</a>";\r
+ print "</th>";\r
+ }\r
+ elsif ($param) {\r
+ my $ip=0;\r
+ my $key;\r
+ if ($param =~ /^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) { # IPv4 address\r
+ $ip=4;\r
+ $key='::'.$param;\r
+ }\r
+ elsif ($param =~ /^[0-9A-F]*:/i) { # IPv6 address\r
+ $ip=6;\r
+ $key=$param;\r
+ }\r
+ print "<td>";\r
+ if ($key) {\r
+ my $res = TmpLookup_geoip6($param);\r
+ if (!$res && $gi) {\r
+ $res=lc($gi->country_code_by_addr_v6($key));\r
+ }\r
+ if ($Debug) { debug(" Plugin $PluginName: GetCountryByIp for $key: [$res]",5); }\r
+ if ($res) { print $DomainsHashIDLib{$res}?$DomainsHashIDLib{$res}:"<span style=\"color: #$color_other\">$Message[0]</span>"; }\r
+ else { print "<span style=\"color: #$color_other\">$Message[0]</span>"; }\r
+ }\r
+ else {\r
+ my $res = TmpLookup_geoip6($param);\r
+ if (!$res){$res=lc($gi->country_code_by_name_v6($param)) if $gi;}\r
+ if ($Debug) { debug(" Plugin $PluginName: GetCountryByHostname for $param: [$res]",5); }\r
+ if ($res) { print $DomainsHashIDLib{$res}?$DomainsHashIDLib{$res}:"<span style=\"color: #$color_other\">$Message[0]</span>"; }\r
+ else { print "<span style=\"color: #$color_other\">$Message[0]</span>"; }\r
+ }\r
+ print "</td>";\r
+ }\r
+ else {\r
+ print "<td> </td>";\r
+ }\r
+ return 1;\r
+ # ----->\r
+}\r
+\r
+#-----------------------------------------------------------------------------\r
+# PLUGIN FUNCTION: LoadOverrideFile\r
+# Attempts to load a comma delimited file that will override the GeoIP database\r
+# Useful for Intranet records\r
+# CSV format: IP,2-char Country code\r
+#-----------------------------------------------------------------------------\r
+sub LoadOverrideFile_geoip6{\r
+ my $filetoload="";\r
+ if ($OverrideFile){\r
+ if (!open(GEOIPFILE, $OverrideFile)){\r
+ debug("Plugin $PluginName: Unable to open override file: $OverrideFile");\r
+ $LoadedOverride = 1;\r
+ return;\r
+ }\r
+ }else{\r
+ my $conf = (exists(&Get_Config_Name) ? Get_Config_Name() : $SiteConfig);\r
+ if ($conf && open(GEOIPFILE,"$DirData/$PluginName.$conf.txt")) { $filetoload="$DirData/$PluginName.$conf.txt"; }\r
+ elsif (open(GEOIPFILE,"$DirData/$PluginName.txt")) { $filetoload="$DirData/$PluginName.txt"; }\r
+ else { debug("No override file \"$DirData/$PluginName.txt\": $!"); }\r
+ }\r
+ if ($filetoload)\r
+ {\r
+ # This is the fastest way to load with regexp that I know\r
+ while (<GEOIPFILE>){\r
+ chomp $_;\r
+ s/\r//;\r
+ my @record = split(",", $_);\r
+ # replace quotes if they were used in the file\r
+ foreach (@record){ $_ =~ s/"//g; }\r
+ # store in hash\r
+ $TmpDomainLookup{$record[0]} = $record[1];\r
+ }\r
+ close GEOIPFILE;\r
+ debug(" Plugin $PluginName: Overload file loaded: ".(scalar keys %TmpDomainLookup)." entries found.");\r
+ }\r
+ $LoadedOverride = 1;\r
+ return;\r
+}\r
+\r
+#-----------------------------------------------------------------------------\r
+# PLUGIN FUNCTION: TmpLookup\r
+# Searches the temporary hash for the parameter value and returns the corresponding\r
+# GEOIP entry\r
+#-----------------------------------------------------------------------------\r
+sub TmpLookup_geoip6(){\r
+ $param = shift;\r
+ if (!$LoadedOverride){&LoadOverrideFile_geoip6();}\r
+ #my $val;\r
+ #if ($gi &&\r
+ #(($type eq 'geoip' && $gi->VERSION >= 1.30) || \r
+ # $type eq 'geoippureperl' && $gi->VERSION >= 1.17)){\r
+ # $val = $TmpDomainLookup{$gi->get_ip_address($param)};\r
+ #}\r
+ #else {$val = $TmpDomainLookup{$param};}\r
+ #return $val || '';\r
+ return $TmpDomainLookup{$param}||'';\r
+}\r
+\r
+1; # Do not remove this line\r