#!/bin/perl package PerlSvc; use strict; #no strict 'refs'; use Net::IP::AddrRanges; use Sys::HostAddr; my $VPNStoppCmdLine=""; my $service = 'VPNConnect'; my $configfile = 'c:\VPNConnect\VPNConnect.conf'; my $delay = 30; my @CONF; my $LOG; my @options = ('config=s' => \$configfile ); # turn on autoflush $|=1; (my $progname = $0) =~ s/.*?([^\\]+?)(\.\w+)$/$1/; our(%Config,$Verbose); #open FH, "<$configfile"; #@CONF=; #close FH; #Main(); sub get_options { require Getopt::Long; my @options = @_; my $usage = pop @options; $SIG{__WARN__} = sub { print "$usage\n$_[0]"; exit 1 }; Getopt::Long::GetOptions(@options); $SIG{__WARN__} = 'DEFAULT'; } sub configure { %Config = (ServiceName => "$service", DisplayName => "$service", Parameters => "--config $configfile", Description => "Automatically connect to given VPN Gateway"); } sub Startup { get_options(@options, <<__USAGE__); Try `$progname --help` to get a list of valid options. __USAGE__ #Log("\n$Config{DisplayName} starting at: ".localtime); open FH, "<$configfile"; @CONF=; close FH; while (ContinueRun($delay)) { Main(); } DLog("$service and connection stopped"); ServiceStopp(); #Log("$Config{DisplayName} stopped at: ".localtime); } sub Install { #get_options('name=s' => \$service, @options, <<__USAGE__); get_options(@options, <<__INSTALL__); Valid --install suboptions are: auto automatically start service --config config file name [$configfile] For example: $progname --install auto --config configfile __INSTALL__ configure(); } sub Help { print <<__HELP__; Automatically connects to VPN Gateway given in configfile Install it as a service: $progname --install auto --config configfile net start $service You can pause and resume the service with: net pause $service net continue $service To remove the service from your system, stop und uninstall it: net stop $service $progname --remove configfile defaults to c:\\VPNConnect\\VPNConnect.conf __HELP__ # Don't display standard PerlSvc help text $Verbose = 0; } sub Pause { #Log("$Config{ServiceName} is about to pause at ".localtime); } sub Continue { #Log("$Config{ServiceName} is continuing at ".localtime); } sub Remove { get_options('service=s' => \$service, <<__REMOVE__); No valid --remove suboptions For example: $progname --remove __REMOVE__ $Config{ServiceName} = "$service"; $Config{DisplayName} = "$service"; } sub Main { my @LocalSubnets; my $LogPath; my $VPNClientPath; my $VPNProfile; my $VPNXauthUser; my $VPNXauthPassword; my $VPNStatusCmdLine; my $VPNStatus; my $VPNStatusString; my $VPNStartCmdLine; foreach my $line (@CONF) { chomp $line; next if ($line =~ /^#/); my($k,$v) = split (/=/,$line); if ($k eq "LocalSubnet") { push @LocalSubnets,$v; } if ($k eq "LogPath") { $LogPath = $v; } if ($k eq "VPNClientPath") { $VPNClientPath = $v; } if ($k eq "VPNProfile") { $VPNProfile = $v; } if ($k eq "VPNXauthUser") { $VPNXauthUser = $v; } if ($k eq "VPNXauthPassword") { $VPNXauthPassword = $v; } if ($k eq "VPNStatusCmdLine") { $VPNStatusCmdLine = $v; } if ($k eq "VPNStatus") { $VPNStatus = $v; } if ($k eq "VPNStatusString") { $VPNStatusString = $v; } if ($k eq "VPNStartCmdLine") { $VPNStartCmdLine = $v; } if ($k eq "VPNStoppCmdLine") { $VPNStoppCmdLine = $v; } } $LOG=$LogPath; # Variablen in Commandlinestrings ersetzen my @Vars = qw /VPNProfile VPNXauthUser VPNXauthPassword/; foreach my $v (@Vars) { my $a; $a=$VPNProfile if ($v eq "VPNProfile"); $a=$VPNXauthUser if ($v eq "VPNXauthUser"); $a=$VPNXauthPassword if ($v eq "VPNXauthPassword"); $VPNStatusCmdLine =~ s/\$$v/$a/; $VPNStartCmdLine =~ s/\$$v/$a/; $VPNStoppCmdLine =~ s/\$$v/$a/; } # lokale adresse ermitteln my $sysaddr = Sys::HostAddr->new(); my $ip; my $noiperr=eval { $ip = $sysaddr->main_ip('route'); }; if ($noiperr) { # in einem netz in LocalSubnets? my $ranges = Net::IP::AddrRanges->new(); $ranges->add(@LocalSubnets); if (!$ranges->find($ip)) { # nein # vpn status abfragen chdir($VPNClientPath); my @ret=`$VPNStatusCmdLine`; # Statusmeldung durchlaufen my $found=0; foreach (@ret) { # und nach Suchstring suchen if ($_ =~ /$VPNStatusString/) { # gefunden! $found=1; } } # Suchstring gefunden? my $connected; if ($found == 1) { # ja $connected = 1 if ($VPNStatus == 1); # Suchstring zeigt aufgebaute Verbindung an $connected = 0 if ($VPNStatus == 0); # Suchstring zeigt abgebaute Verbindung an if (!$connected) { # verbindung nicht hergestellt, aufbauen! DLog("Connection start"); `$VPNStartCmdLine`; } else { # verbunden! } } } else { DLog("In range, no connection will be built"); } } else { DLog ("No IP found"); } } sub ServiceStopp { `$VPNStoppCmdLine`; } sub DLog { my $path="$LOG"."vpnconnect.debug.log"; open FH, ">>$path"; print FH "$_[0]\n"; close FH; }