]>
Commit | Line | Data |
---|---|---|
0d6cc79d SF |
1 | #!/usr/bin/perl |
2 | # | |
3 | ############################################################################### | |
4 | # # | |
5 | # IPFire.org - A linux based firewall # | |
a25c95b3 | 6 | # Copyright (C) 2017-2018 Stephan Feddersen <sfeddersen@ipfire.org> # |
0d6cc79d SF |
7 | # All Rights Reserved. # |
8 | # # | |
9 | # This program is free software: you can redistribute it and/or modify # | |
10 | # it under the terms of the GNU General Public License as published by # | |
11 | # the Free Software Foundation, either version 3 of the License, or # | |
12 | # (at your option) any later version. # | |
13 | # # | |
14 | # This program is distributed in the hope that it will be useful, # | |
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of # | |
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # | |
17 | # GNU General Public License for more details. # | |
18 | # # | |
19 | # You should have received a copy of the GNU General Public License # | |
20 | # along with this program. If not, see <http://www.gnu.org/licenses/>. # | |
21 | # # | |
22 | ############################################################################### | |
23 | # | |
a25c95b3 | 24 | # Version: 2017/08/04 18:55:23 |
0d6cc79d SF |
25 | # |
26 | # This wio.pl is based on the Code from the IPCop WIO Addon | |
27 | # and is extremly adapted to work with IPFire. | |
28 | # | |
29 | # Autor: Stephan Feddersen | |
30 | # Co-Autor: Alexander Marx | |
31 | # Co-Autor: Frank Mainz | |
32 | # | |
33 | ||
34 | # enable only the following on debugging purpose | |
35 | #use warnings; | |
36 | ||
37 | use strict; | |
38 | use POSIX qw(strftime); | |
39 | use Time::HiRes qw(gettimeofday tv_interval); | |
40 | use Net::Ping; | |
41 | use RRDs; | |
42 | use Fatal qw/ open /; | |
43 | ||
44 | require '/var/ipfire/general-functions.pl'; | |
45 | require '/var/ipfire/lang.pl'; | |
46 | require '/usr/lib/wio/wio-lib.pl'; | |
47 | ||
48 | my ( $debug, $i, $t, $ib, $tb, $ivpn, $tvpn ) = ''; | |
49 | my $logdir = "/var/log/wio"; | |
50 | my $owner = getpwnam "nobody"; | |
51 | my $group = getgrnam "nobody"; | |
52 | my $ipadrfile = "$logdir/wioips"; | |
53 | ||
54 | unless ( -e $ipadrfile ) { print ( "The file $ipadrfile doesn't exist!\n" ); exit; } | |
55 | ||
56 | foreach (@ARGV) { | |
57 | if ( $_ eq '-d' || $_ eq '--debug') { $debug = 1; } | |
58 | if ( $_ eq '-h' || $_ eq '--help' ) { die help(); } | |
59 | } | |
60 | ||
61 | my ( %wiosettings, %mainsettings, %mailsettings, %netsettings ) = (); | |
62 | ||
63 | &General::readhash('/var/ipfire/main/settings', \%mainsettings); | |
64 | &General::readhash('/var/ipfire/ethernet/settings', \%netsettings); | |
65 | &General::readhash('/var/ipfire/dma/mail.conf', \%mailsettings); | |
66 | &General::readhash("/var/ipfire/wio/wio.conf", \%wiosettings); | |
67 | ||
68 | my $now = strftime "%a, %d.%m.%Y %H:%M:%S", localtime; | |
69 | my $logging = $wiosettings{'LOGGING'}; | |
70 | my $mailstyle = $wiosettings{'MAILSTYLE'}; | |
71 | my $mailremark = $wiosettings{'MAILREMARK'}; | |
72 | my $timeout = $wiosettings{'TIMEOUT'}; | |
73 | my $shutdown = $wiosettings{'SHUTDOWN'}; | |
74 | my $rrddir = "/var/log/rrd/wio"; | |
75 | my $onoffip = "$logdir/wioscip"; | |
76 | my $hostname = "$mainsettings{'HOSTNAME'}.$mainsettings{'DOMAINNAME'}"; | |
77 | my $redactive = "/var/ipfire/red/active"; | |
78 | my $rediface = "/var/ipfire/red/iface"; | |
79 | my $reddev = ''; | |
80 | ||
81 | if ( -e $rediface ) { | |
82 | $reddev = &General::get_red_interface; | |
83 | } | |
84 | ||
85 | my $redip = $hostname; | |
86 | my $vpnpid = ( -e "/var/run/charon.pid" ? `awk '{print $1}' /var/run/charon.pid`: ''); | |
87 | my $ovpnpid = ( -e "/var/run/openvpn.pid" ? `awk '{print $1}' /var/run/openvpn.pid`: ''); | |
88 | ||
89 | my $steptime = $wiosettings{'CRON'} *= 60; | |
90 | my $i_ping = 'icmp'; | |
91 | my $t_ping = 'tcp'; | |
92 | ||
93 | my $nr = 1; | |
94 | my $poweroff = 0; | |
95 | ||
96 | my ( $togglestat, $arp, $time, $start, $timestamp ) = 0; | |
97 | my ( $id, $ipadr, $ipadrnew, $host, $hostnew, $enable, $remark, $dyndns, $dyndnsip ) = ''; | |
98 | my ( $mail, $mailon, $mailoff, $ping, $on, $httphost, $mailen ) = ''; | |
99 | my ( $msg, $logmsg, $mailmsg, $smailtxt, $infomsg, $client, $mode, $onbak, $arpclient ) = ''; | |
100 | my ( $ping_i, $ping_t, $ping_ib, $ping_tb, $ping_iv, $ping_tv, $pingmode ) = ''; | |
101 | my ( @tmp, @arptmp, @myarray, @status, @arpclients ) = ''; | |
102 | my @ifaces = ('GREEN','BLUE','ORANGE'); | |
103 | ||
104 | ||
105 | if ( $mailsettings{'USEMAIL'} eq 'on' ) { $mailen = 'on'; } | |
106 | else { $mailen = 'off'; } | |
107 | ||
108 | if ( -e $redactive ) { | |
109 | open(IPADDR, "/var/ipfire/red/local-ipaddress"); | |
110 | $redip = <IPADDR>; | |
111 | close IPADDR; | |
112 | chomp($redip); | |
113 | } | |
114 | ||
115 | if ($debug) { | |
116 | $start = [gettimeofday]; | |
117 | startdebug(); | |
118 | } | |
119 | ||
120 | foreach (@ifaces) { | |
121 | if ( $netsettings{"${_}_DEV"} ne '' && $netsettings{"${_}_DEV"} ne 'disabled' ) { | |
122 | my $output = `ifconfig $netsettings{"${_}_DEV"}`; | |
123 | ||
124 | if ( grep (/RX bytes:0/, $output) ) { next; } | |
125 | else { | |
126 | @arptmp = `/usr/local/bin/wioscan -s $netsettings{"${_}_DEV"}`; | |
127 | ||
128 | foreach $arpclient (@arptmp) { | |
129 | push (@arpclients, (split (/\,/,$arpclient))[1]); | |
130 | } | |
131 | } | |
132 | $output = ''; | |
133 | undef(@arptmp); | |
134 | } | |
135 | } | |
136 | ||
137 | if ( -e "$onoffip" ) { open( FILE, "< $onoffip" ); } | |
138 | else { open( FILE, "< $ipadrfile" ); } | |
139 | @myarray = <FILE>; | |
140 | close(FILE); | |
141 | ||
142 | # ping all clients | |
143 | ||
144 | foreach (@myarray) { | |
145 | chomp; | |
146 | @tmp = split( /\,/, $_ ); | |
147 | ||
148 | ($id,$timestamp,$ipadr,$host,$enable,$remark,$dyndns,$mailon,$mailoff,$ping,$on,$httphost) = @tmp; | |
149 | ||
150 | $timestamp = strftime "%d.%m.%Y - %H:%M:%S", localtime; | |
151 | ||
152 | if ( $enable ne 'on' ) { | |
153 | push (@status, "$id,$timestamp,$ipadr,$host,$enable,$remark,$dyndns,$mailon,$mailoff,$ping,$on,$httphost\n"); | |
154 | next; | |
155 | } | |
156 | ||
157 | if ( defined($dyndns) && ( $dyndns =~ 'on' ) ) { | |
158 | ($dyndnsip, $infomsg) = &WIO::getdyndnsip($host, @myarray); | |
159 | if ($dyndnsip ne $ipadr) { $ipadr = $dyndnsip; } | |
160 | } | |
161 | ||
162 | $ping_i = $ping_t = $ping_ib = $ping_tb = $ping_iv = $ping_tv = $pingmode = $arp = 0; | |
163 | ||
164 | foreach (@arpclients) { | |
165 | chomp; | |
166 | unless ( $ipadr eq $_ ) | |
167 | { | |
168 | $i = Net::Ping->new( $i_ping, $timeout ); | |
169 | unless ( defined $i ) { die "Can't create Net::Ping object $!"; } | |
170 | ||
171 | $t = Net::Ping->new( $t_ping, $timeout ); | |
172 | unless ( defined $t ) { die "Can't create Net::Ping object $!"; } | |
173 | ||
174 | $ib = Net::Ping->new( $i_ping, $timeout ); | |
175 | unless ( defined $ib ) { die "Can't create Net::Ping object $!"; } | |
176 | $ib->bind($redip); | |
177 | ||
178 | $tb = Net::Ping->new( $t_ping, $timeout ); | |
179 | unless ( defined $tb ) { die "Can't create Net::Ping object $!"; } | |
180 | $tb->bind($redip); | |
181 | ||
182 | if ($ovpnpid || $vpnpid) | |
183 | { | |
184 | $ivpn = Net::Ping->new( $i_ping, $timeout ); | |
185 | unless ( defined $ivpn ) { die "Can't create Net::Ping object $!"; } | |
186 | $ivpn->bind($hostname); | |
187 | ||
188 | $tvpn = Net::Ping->new( $t_ping, $timeout ); | |
189 | unless ( defined $tvpn ) { die "Can't create Net::Ping object $!"; } | |
190 | $tvpn->bind($hostname); | |
191 | } | |
192 | } | |
193 | else { $arp = 1 } | |
194 | } | |
195 | ||
196 | $client = ( ( $dyndns eq 'on' || $ping eq 'fqdn' ) ? $host : $ipadr ); | |
197 | ||
198 | if ($debug) { | |
199 | printf "%2s %15s", $nr++, ($client ne $ipadr ? $ipadr : $client ); | |
200 | $time = [gettimeofday]; | |
201 | } | |
202 | ||
203 | if ( $arp == 1 | |
204 | || ($ping_i = $i->ping($client)) | |
205 | || ($ping_t = $t->ping($client)) | |
206 | || ($ping_ib = $ib->ping($client)) | |
207 | || ($ping_tb = $tb->ping($client)) | |
208 | || ($ovpnpid?($ping_iv = $ivpn->ping($client)) : 0) | |
209 | || ($vpnpid?($ping_tv = $tvpn->ping($client)) : 0) ) | |
210 | { | |
211 | $mode = 100; | |
212 | $msg = "$Lang::tr{'wio up'}"; | |
213 | $onbak = $on; | |
214 | $togglestat = ( $on ne 'on' ) ? 1 : 0; | |
215 | $on = 'on'; | |
216 | } | |
217 | else { | |
218 | $mode = 0; | |
219 | $msg = "$Lang::tr{'wio down'}"; | |
220 | $onbak = $on; | |
221 | $togglestat = ( $on ne 'off' ) ? 1 : 0; | |
222 | $on = 'off'; | |
223 | } | |
224 | ||
225 | push (@status, "$id,$timestamp,$ipadr,$host,$enable,$remark,$dyndns,$mailon,$mailoff,$ping,$on,$httphost\n"); | |
226 | ||
227 | if ($debug) { | |
228 | $mail = '----'; | |
229 | if ( $mailon eq 'on' && $togglestat == 1 && $mode == 100 ) { $mail = 'Online'; } | |
230 | if ( $mailoff eq 'on' && $togglestat == 1 && $mode == 0 ) { $mail = 'Offline'; } | |
231 | if ( $dyndns ne 'on' ) { $dyndns = 'off'; } | |
232 | ||
233 | $pingmode = $arp ? 'ARPSCAN' : $ping_i ? 'ICMP' : $ping_t ? 'TCP' : $ping_ib ? 'ICMP+BIND' : $ping_tb ? 'TCP+BIND' : $ping_iv ? 'VPN ICMP' : $ping_tv ? 'VPN TCP' : 'NO ECHO'; | |
234 | printf "%7s%8s%9s%10s %.4f sek%12s\n", $ping, $dyndns, $msg, $mail, tv_interval($time), $pingmode; | |
235 | } | |
236 | ||
237 | if ( $host eq '' ) { $hostnew = 'n/a'; } else { $hostnew = $host; } | |
238 | if ( $ipadr eq '' ) { $ipadrnew = 'n/a'; } else { $ipadrnew = $ipadr; } | |
239 | ||
240 | if ( $logging eq 'on' ) { | |
241 | $logmsg = "Client: $hostnew - IP: $ipadrnew - Status: $msg"; | |
242 | &General::log("wio","$logmsg"); | |
243 | } | |
244 | ||
245 | if ( $mailen eq 'on' && $togglestat == 1 && ($mailon eq 'on' || $mailoff eq 'on')) { | |
246 | ||
247 | if ( $mailstyle eq 'email' || ($mailstyle eq 'smail' && $smailtxt eq '') ) { $mailmsg .= "Date\t : $now\n\n"; } | |
248 | ||
249 | $mailmsg .= "Client\t : $hostnew\nIP\t : $ipadrnew\nStatus\t : $msg\n"; | |
250 | ||
251 | if ( $mailremark eq 'on' && $remark ne '' ) { | |
252 | $mailmsg .= "Remark : $remark\n\n"; | |
253 | } | |
254 | ||
255 | if ( $mailstyle eq 'email' ) { | |
256 | &WIO::mailsender("WIO - $host - $msg", $mailmsg); | |
257 | undef ($mailmsg); | |
258 | } | |
259 | elsif ( $mailstyle eq 'smail' ) { | |
260 | $smailtxt .= $mailmsg."\n"; | |
261 | undef ($mailmsg); | |
262 | } | |
263 | } | |
264 | ||
265 | if ( $ping ne 'fqdn' ) { $client = $host; } | |
266 | if ( $host eq '' ) { $client = $ipadr; } | |
267 | ||
268 | updatewiodata("$id"); | |
269 | ||
270 | if ( $arp == 0 ) { | |
271 | $i->close(); | |
272 | $t->close(); | |
273 | $ib->close(); | |
274 | $tb->close(); | |
275 | } | |
276 | ||
277 | if ( ( -e $ovpnpid || -e $vpnpid ) && $arp == 0 ) { | |
278 | $ivpn->close(); | |
279 | $tvpn->close(); | |
280 | } | |
281 | } | |
282 | ||
283 | # write adressfile new | |
284 | ||
285 | if ( !-e $onoffip ) { | |
286 | open( FILE, "> $ipadrfile" ); | |
287 | print FILE @status; | |
288 | close(FILE); | |
289 | } | |
290 | else { | |
291 | system("/bin/sed -i 's#$tmp[0],$tmp[1],$tmp[2],$tmp[3],$tmp[4],$tmp[5],$tmp[6],$tmp[7],$tmp[8],$tmp[9],$tmp[10],$tmp[11]#$id,$timestamp,$ipadr,$host,$enable,$remark,$dyndns,$mailon,$mailoff,$ping,$on,$httphost#g' $ipadrfile"); | |
292 | chmod ( 0644, $ipadrfile ); | |
293 | chown ( $owner, $group, $ipadrfile ); | |
294 | } | |
295 | ||
296 | if ($debug) { | |
297 | printf ("\n$Lang::tr{'wio_scriptruntime'}: %.4f $Lang::tr{'age ssecond'}\n\n", tv_interval($start)); | |
298 | } | |
299 | ||
300 | if ( $smailtxt ne '' ) { &WIO::mailsender($Lang::tr{'wio_sub'}, $smailtxt); } | |
301 | ||
302 | if ($shutdown eq 'on') { | |
303 | foreach (@status) { | |
304 | chomp; | |
305 | @tmp = split( /\,/, $_ ); | |
306 | ||
307 | ($id,$timestamp,$ipadr,$host,$enable,$remark,$dyndns,$mailon,$mailoff,$ping,$on,$httphost) = @tmp; | |
308 | ||
309 | if ( $on eq 'on' ) { | |
310 | $poweroff = 0; | |
311 | last; | |
312 | } | |
313 | else { | |
314 | $poweroff = 1; | |
315 | next; | |
316 | } | |
317 | } | |
318 | ||
319 | if ($poweroff == 1) { | |
320 | if ($debug) { | |
321 | printf "$Lang::tr{'shutting down ipfire'}!\n\n"; | |
322 | } | |
323 | ||
324 | &General::log("wio","$Lang::tr{'shutting down ipfire'}!"); | |
325 | system '/usr/local/bin/ipfirereboot down'; | |
326 | } | |
327 | } | |
328 | ||
329 | undef (@tmp); | |
330 | undef (@myarray); | |
331 | undef (@status); | |
332 | undef (@arptmp); | |
333 | undef (@arpclients); | |
334 | ||
335 | if ( -e $onoffip ) { unlink($onoffip); } | |
336 | ||
337 | sub updatewiodata { | |
338 | my $id = $_[0]; | |
339 | ||
340 | if ( !-e "$rrddir/$id.rrd" ) { | |
341 | RRDs::create( | |
342 | "$rrddir/$id.rrd", "--step=$steptime", | |
343 | "DS:mode:GAUGE:3600:0:100", "RRA:AVERAGE:0.5:1:576", | |
344 | "RRA:AVERAGE:0.5:6:672", "RRA:AVERAGE:0.5:24:732", | |
345 | "RRA:AVERAGE:0.5:144:1460" | |
346 | ); | |
347 | my $ERROR = RRDs::error; | |
348 | print "Error in RRD::create for Who Is Online: $ERROR\n" if $ERROR; | |
349 | } | |
350 | ||
351 | RRDs::update( "$rrddir/$id.rrd", "-t", "mode", "N:$mode" ); | |
352 | ||
353 | my $error = RRDs::error; | |
354 | ||
355 | if ($error) { &General::log("wio","$error"); } | |
356 | } | |
357 | ||
358 | sub startdebug { | |
359 | ||
360 | printf " | |
361 | HOSTNAME : $hostname | |
362 | TIMEOUT : $timeout $Lang::tr{'age ssecond'} | |
363 | MAILSTYLE : $mailstyle | |
364 | RED TYPE : $netsettings{'RED_TYPE'} | |
365 | RED DEVICE : $reddev | |
366 | RED ADDRESS : $redip | |
367 | SHUTDOWN : $shutdown | |
368 | "; | |
369 | if ($ovpnpid) {printf "OVPN PID : $ovpnpid"} | |
370 | if ($vpnpid) {printf "VPN PID : $vpnpid"} | |
371 | printf " | |
372 | $Lang::tr{'wio_search'} | |
373 | ||
374 | %3s%17s%7s%8s%9s%10s%15s%12s | |
375 | --------------------------------------------------------------------------------- | |
376 | ","ID ", "$Lang::tr{'wio ipadress'}", "Ping", "DynDNS", "Status", "Mail", "$Lang::tr{'wio_answer_time'}", "$Lang::tr{'wio_answer'}"; | |
377 | } | |
378 | ||
379 | sub help { | |
380 | return " | |
381 | Who Is Online? for IPFire | |
382 | ||
383 | use option -d for debugging | |
384 | use option -h for help\n\n"; | |
385 | } |