]>
Commit | Line | Data |
---|---|---|
ac1cfefa | 1 | #!/usr/bin/perl |
70df8302 MT |
2 | ############################################################################### |
3 | # # | |
4 | # IPFire.org - A linux based firewall # | |
73c7eff8 | 5 | # Copyright (C) 2007-2011 IPFire Team <info@ipfire.org> # |
70df8302 MT |
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 | ############################################################################### | |
ac1cfefa MT |
21 | |
22 | my @network=(); | |
23 | my @masklen=(); | |
24 | my @colour=(); | |
25 | ||
26 | use Net::IPv4Addr qw( :all ); | |
27 | ||
28 | use strict; | |
29 | ||
30 | # enable only the following on debugging purpose | |
1465b127 | 31 | #use warnings; |
cb5e9c6c | 32 | #use CGI::Carp 'fatalsToBrowser'; |
ac1cfefa | 33 | |
986e08d9 | 34 | require '/var/ipfire/general-functions.pl'; |
ac1cfefa MT |
35 | require "${General::swroot}/lang.pl"; |
36 | require "${General::swroot}/header.pl"; | |
37 | ||
38 | #workaround to suppress a warning when a variable is used only once | |
39 | my @dummy = ( ${Header::table1colour} ); | |
40 | undef (@dummy); | |
41 | ||
42 | # Read various files | |
43 | ||
44 | my %netsettings=(); | |
45 | &General::readhash("${General::swroot}/ethernet/settings", \%netsettings); | |
46 | ||
f65b2fb8 | 47 | open (ACTIVE, '/usr/local/bin/getiptstate |') or die 'Unable to open ip_conntrack'; |
ac1cfefa MT |
48 | my @active = <ACTIVE>; |
49 | close (ACTIVE); | |
50 | ||
2c42fe6a MT |
51 | if (open(IP, "${General::swroot}/red/local-ipaddress")) { |
52 | my $redip = <IP>; | |
53 | close(IP); | |
54 | chomp $redip; | |
55 | push(@network, $redip); | |
56 | push(@masklen, '255.255.255.255' ); | |
57 | push(@colour, ${Header::colourfw} ); | |
58 | } | |
59 | ||
73c7eff8 | 60 | my @vpn = `/usr/local/bin/ipsecctrl I 2>/dev/null|grep erouted|cut -d"]" -f3|cut -d"=" -f4|cut -d";" -f1| sed "s|/| |g"`; |
18322edf CS |
61 | foreach my $route (@vpn) { |
62 | chomp($route); | |
63 | my @temp = split(/[\t ]+/, $route); | |
2c42fe6a | 64 | if ( $temp[0] eq '$redip' ){next;} |
18322edf CS |
65 | push(@network, $temp[0]); |
66 | push(@masklen, $temp[1]); | |
67 | push(@colour, ${Header::colourvpn} ); | |
68 | } | |
ac1cfefa MT |
69 | |
70 | my $aliasfile = "${General::swroot}/ethernet/aliases"; | |
71 | open(ALIASES, $aliasfile) or die 'Unable to open aliases file.'; | |
72 | my @aliases = <ALIASES>; | |
73 | close(ALIASES); | |
74 | ||
75 | # Add Green Firewall Interface | |
76 | push(@network, $netsettings{'GREEN_ADDRESS'}); | |
77 | push(@masklen, "255.255.255.255" ); | |
78 | push(@colour, ${Header::colourfw} ); | |
79 | ||
80 | # Add Green Network to Array | |
81 | push(@network, $netsettings{'GREEN_NETADDRESS'}); | |
82 | push(@masklen, $netsettings{'GREEN_NETMASK'} ); | |
83 | push(@colour, ${Header::colourgreen} ); | |
84 | ||
85 | # Add Green Routes to Array | |
86 | my @routes = `/sbin/route -n | /bin/grep $netsettings{'GREEN_DEV'}`; | |
87 | foreach my $route (@routes) { | |
f9aaffa6 MT |
88 | chomp($route); |
89 | my @temp = split(/[\t ]+/, $route); | |
90 | push(@network, $temp[0]); | |
91 | push(@masklen, $temp[2]); | |
92 | push(@colour, ${Header::colourgreen} ); | |
ac1cfefa MT |
93 | } |
94 | ||
95 | # Add Firewall Localhost 127.0.0.1 | |
96 | push(@network, '127.0.0.1'); | |
97 | push(@masklen, '255.255.255.255' ); | |
98 | push(@colour, ${Header::colourfw} ); | |
99 | ||
5433e2c9 MT |
100 | # Add Orange Network |
101 | if ($netsettings{'ORANGE_DEV'}) { | |
f9aaffa6 MT |
102 | push(@network, $netsettings{'ORANGE_NETADDRESS'}); |
103 | push(@masklen, $netsettings{'ORANGE_NETMASK'} ); | |
104 | push(@colour, ${Header::colourorange} ); | |
105 | # Add Orange Routes to Array | |
106 | @routes = `/sbin/route -n | /bin/grep $netsettings{'ORANGE_DEV'}`; | |
107 | foreach my $route (@routes) { | |
108 | chomp($route); | |
109 | my @temp = split(/[\t ]+/, $route); | |
110 | push(@network, $temp[0]); | |
111 | push(@masklen, $temp[2]); | |
112 | push(@colour, ${Header::colourorange} ); | |
113 | } | |
5433e2c9 MT |
114 | } |
115 | ||
f9aaffa6 MT |
116 | # Add Blue Firewall Interface |
117 | push(@network, $netsettings{'BLUE_ADDRESS'}); | |
118 | push(@masklen, "255.255.255.255" ); | |
119 | push(@colour, ${Header::colourfw} ); | |
120 | ||
5433e2c9 MT |
121 | # Add Blue Network |
122 | if ($netsettings{'BLUE_DEV'}) { | |
f9aaffa6 MT |
123 | push(@network, $netsettings{'BLUE_NETADDRESS'}); |
124 | push(@masklen, $netsettings{'BLUE_NETMASK'} ); | |
125 | push(@colour, ${Header::colourblue} ); | |
126 | # Add Blue Routes to Array | |
127 | @routes = `/sbin/route -n | /bin/grep $netsettings{'BLUE_DEV'}`; | |
128 | foreach my $route (@routes) { | |
129 | chomp($route); | |
130 | my @temp = split(/[\t ]+/, $route); | |
131 | push(@network, $temp[0]); | |
132 | push(@masklen, $temp[2]); | |
133 | push(@colour, ${Header::colourblue} ); | |
134 | } | |
5433e2c9 MT |
135 | } |
136 | ||
6e13d0a5 MT |
137 | # Add OpenVPN net and RED/BLUE/ORANGE entry (when appropriate) |
138 | if (-e "${General::swroot}/ovpn/settings") { | |
139 | my %ovpnsettings = (); | |
140 | &General::readhash("${General::swroot}/ovpn/settings", \%ovpnsettings); | |
141 | my @tempovpnsubnet = split("\/",$ovpnsettings{'DOVPN_SUBNET'}); | |
142 | ||
143 | # add OpenVPN net | |
f9aaffa6 MT |
144 | push(@network, $tempovpnsubnet[0]); |
145 | push(@masklen, $tempovpnsubnet[1]); | |
146 | push(@colour, ${Header::colourovpn} ); | |
6e13d0a5 | 147 | |
7dbf47dc | 148 | |
6e13d0a5 MT |
149 | if ( ($ovpnsettings{'ENABLED_BLUE'} eq 'on') && $netsettings{'BLUE_DEV'} ) { |
150 | # add BLUE:port / proto | |
f9aaffa6 MT |
151 | push(@network, $netsettings{'BLUE_ADDRESS'} ); |
152 | push(@masklen, '255.255.255.255' ); | |
153 | push(@colour, ${Header::colourovpn} ); | |
6e13d0a5 MT |
154 | } |
155 | if ( ($ovpnsettings{'ENABLED_ORANGE'} eq 'on') && $netsettings{'ORANGE_DEV'} ) { | |
156 | # add ORANGE:port / proto | |
f9aaffa6 MT |
157 | push(@network, $netsettings{'ORANGE_ADDRESS'} ); |
158 | push(@masklen, '255.255.255.255' ); | |
159 | push(@colour, ${Header::colourovpn} ); | |
6e13d0a5 MT |
160 | } |
161 | } | |
162 | ||
ac1cfefa MT |
163 | # Add STATIC RED aliases |
164 | if ($netsettings{'RED_DEV'}) { | |
f9aaffa6 MT |
165 | # We have a RED eth iface |
166 | if ($netsettings{'RED_TYPE'} eq 'STATIC') { | |
167 | # We have a STATIC RED eth iface | |
168 | foreach my $line (@aliases) | |
169 | { | |
170 | chomp($line); | |
171 | my @temp = split(/\,/,$line); | |
172 | if ( $temp[0] ) { | |
173 | push(@network, $temp[0]); | |
174 | push(@masklen, $netsettings{'RED_NETMASK'} ); | |
175 | push(@colour, ${Header::colourfw} ); | |
176 | } | |
177 | } | |
178 | } | |
ac1cfefa MT |
179 | } |
180 | ||
181 | # Add VPNs | |
182 | if ( $vpn[0] ne 'none' ) { | |
f9aaffa6 MT |
183 | foreach my $line (@vpn) { |
184 | my @temp = split(/[\t ]+/,$line); | |
185 | my @temp1 = split(/[\/:]+/,$temp[3]); | |
186 | push(@network, $temp1[0]); | |
187 | push(@masklen, ipv4_cidr2msk($temp1[1])); | |
188 | push(@colour, ${Header::colourvpn} ); | |
189 | } | |
ac1cfefa | 190 | } |
ac1cfefa | 191 | |
c2b15814 MT |
192 | #Establish simple filtering&sorting boxes on top of table |
193 | ||
194 | our %cgiparams; | |
195 | &Header::getcgihash(\%cgiparams); | |
196 | ||
197 | my @list_proto = ($Lang::tr{'all'}, 'icmp', 'udp', 'tcp'); | |
198 | my @list_state = ($Lang::tr{'all'}, 'SYN_SENT', 'SYN_RECV', 'ESTABLISHED', 'FIN_WAIT', | |
f9aaffa6 | 199 | 'CLOSE_WAIT', 'LAST_ACK', 'TIME_WAIT', 'CLOSE', 'LISTEN'); |
c2b15814 MT |
200 | my @list_mark = ($Lang::tr{'all'}, '[ASSURED]', '[UNREPLIED]'); |
201 | my @list_sort = ('orgsip','protocol', 'expires', 'status', 'orgdip', 'orgsp', | |
f9aaffa6 | 202 | 'orgdp', 'exsip', 'exdip', 'exsp', 'exdp', 'marked'); |
c2b15814 MT |
203 | |
204 | # init or silently correct unknown value... | |
205 | if ( ! grep ( /^$cgiparams{'SEE_PROTO'}$/ , @list_proto )) { $cgiparams{'SEE_PROTO'} = $list_proto[0] }; | |
206 | if ( ! grep ( /^$cgiparams{'SEE_STATE'}$/ , @list_state )) { $cgiparams{'SEE_STATE'} = $list_state[0] }; | |
5433e2c9 MT |
207 | if ( ($cgiparams{'SEE_MARK'} ne $Lang::tr{'all'}) && # ok the grep should work but it doesn't because of |
208 | ($cgiparams{'SEE_MARK'} ne '[ASSURED]') && # the '[' & ']' interpreted as list separator. | |
209 | ($cgiparams{'SEE_MARK'} ne '[UNREPLIED]') # So, explicitly enumerate items. | |
210 | ) { $cgiparams{'SEE_MARK'} = $list_mark[0] }; | |
c2b15814 MT |
211 | if ( ! grep ( /^$cgiparams{'SEE_SORT'}$/ , @list_sort )) { $cgiparams{'SEE_SORT'} = $list_sort[0] }; |
212 | # *.*.*.* or a valid IP | |
213 | if ( $cgiparams{'SEE_SRC'} !~ /^(\*\.\*\.\*\.\*\.|\d+\.\d+\.\d+\.\d+)$/) { $cgiparams{'SEE_SRC'} = '*.*.*.*' }; | |
214 | if ( $cgiparams{'SEE_DEST'} !~ /^(\*\.\*\.\*\.\*\.|\d+\.\d+\.\d+\.\d+)$/) { $cgiparams{'SEE_DEST'} = '*.*.*.*' }; | |
215 | ||
216 | ||
217 | our %entries = (); # will hold the lines analyzed correctly | |
218 | my $unknownlines = ''; # should be empty all the time... | |
219 | my $index = 0; # just a counter to make unique entryies in entries | |
ac1cfefa | 220 | |
c2b15814 MT |
221 | &Header::showhttpheaders(); |
222 | &Header::openpage($Lang::tr{'connections'}, 1, ''); | |
223 | &Header::openbigbox('100%', 'left'); | |
224 | &Header::openbox('100%', 'left', $Lang::tr{'connection tracking'}); | |
225 | ||
1465b127 MT |
226 | # Build listbox objects |
227 | my $menu_proto = &make_select ('SEE_PROTO', $cgiparams{'SEE_PROTO'}, @list_proto); | |
228 | my $menu_state = &make_select ('SEE_STATE', $cgiparams{'SEE_STATE'}, @list_state); | |
229 | ||
c2b15814 | 230 | print <<END |
5433e2c9 | 231 | <form method='post' action='$ENV{'SCRIPT_NAME'}'> |
4809e64e | 232 | <table width='100%'> |
c2b15814 MT |
233 | <tr><td align='center'><b>$Lang::tr{'legend'} : </b></td> |
234 | <td align='center' bgcolor='${Header::colourgreen}'><b><font color='#FFFFFF'>$Lang::tr{'lan'}</font></b></td> | |
235 | <td align='center' bgcolor='${Header::colourred}'><b><font color='#FFFFFF'>$Lang::tr{'internet'}</font></b></td> | |
236 | <td align='center' bgcolor='${Header::colourorange}'><b><font color='#FFFFFF'>$Lang::tr{'dmz'}</font></b></td> | |
237 | <td align='center' bgcolor='${Header::colourblue}'><b><font color='#FFFFFF'>$Lang::tr{'wireless'}</font></b></td> | |
78331e30 | 238 | <td align='center' bgcolor='${Header::colourfw}'><b><font color='#FFFFFF'>IPFire</font></b></td> |
c2b15814 | 239 | <td align='center' bgcolor='${Header::colourvpn}'><b><font color='#FFFFFF'>$Lang::tr{'vpn'}</font></b></td> |
6e13d0a5 | 240 | <td align='center' bgcolor='${Header::colourovpn}'><b><font color='#FFFFFF'>$Lang::tr{'OpenVPN'}</font></b></td> |
c2b15814 MT |
241 | </tr> |
242 | </table> | |
1465b127 | 243 | <br /> |
4809e64e | 244 | <table width='100%'> |
1465b127 MT |
245 | <tr><td align='center'><font size=2>$Lang::tr{'source ip and port'}</font></td> |
246 | <td> </td> | |
247 | <td align='center'><font size=2>$Lang::tr{'dest ip and port'}</font></td> | |
248 | <td> </td> | |
249 | <td align='center'><font size=2>$Lang::tr{'protocol'}</font></td> | |
250 | <td align='center'><font size=2>$Lang::tr{'connection'}<br></br>$Lang::tr{'status'}</font></td> | |
4809e64e | 251 | <td align='center'><font size=2>$Lang::tr{'expires'}<br></br>($Lang::tr{'seconds'})</font></td> |
1465b127 | 252 | |
c2b15814 | 253 | </tr> |
1465b127 MT |
254 | <tr><td colspan='4'> </td> |
255 | <td align='center'>$menu_proto</td> | |
c2b15814 | 256 | <td align='center'>$menu_state</td> |
1465b127 | 257 | <td> </td> |
c2b15814 | 258 | </tr> |
4809e64e | 259 | <tr> |
1465b127 | 260 | <td align='center' colspan='7'></td> |
4809e64e MT |
261 | </tr> |
262 | <tr> | |
1465b127 | 263 | <td align='center' colspan='7'><input type='submit' value="$Lang::tr{'update'}" /></td> |
4809e64e MT |
264 | </tr> |
265 | ||
c2b15814 MT |
266 | END |
267 | ; | |
268 | ||
1465b127 MT |
269 | my $i=0; |
270 | foreach my $line (@active) { | |
271 | $i++; | |
272 | if ($i < 3) { | |
273 | next; | |
274 | } | |
275 | chomp($line); | |
276 | my @temp = split(' ',$line); | |
277 | ||
278 | my ($sip, $sport) = split(':', $temp[0]); | |
279 | my ($dip, $dport) = split(':', $temp[1]); | |
280 | my $proto = $temp[2]; | |
7dbf47dc CS |
281 | my $state; my $ttl; |
282 | if ( $proto eq "esp" ){$state = "";$ttl = $temp[3];} | |
283 | elsif ( $proto eq "icmp" ){$state = "";$ttl = $temp[4];} | |
284 | else{$state = $temp[3];$ttl = $temp[4];} | |
1465b127 MT |
285 | |
286 | next if( !( | |
287 | (($cgiparams{'SEE_PROTO'} eq $Lang::tr{'all'}) || ($proto eq $cgiparams{'SEE_PROTO'} )) | |
288 | && (($cgiparams{'SEE_STATE'} eq $Lang::tr{'all'}) || ($state eq $cgiparams{'SEE_STATE'} )) | |
289 | && (($cgiparams{'SEE_SRC'} eq "*.*.*.*") || ($sip eq $cgiparams{'SEE_SRC'} )) | |
290 | && (($cgiparams{'SEE_DEST'} eq "*.*.*.*") || ($dip eq $cgiparams{'SEE_DEST'} )) | |
291 | )); | |
292 | ||
293 | if (($proto eq 'udp') && ($ttl eq '')) { | |
294 | $ttl = $state; | |
295 | $state = ' '; | |
296 | } | |
297 | ||
298 | my $sipcol = ipcolour($sip); | |
299 | my $dipcol = ipcolour($dip); | |
300 | ||
301 | my $sserv = ''; | |
302 | if ($sport < 1024) { | |
303 | $sserv = uc(getservbyport($sport, lc($proto))); | |
304 | if ($sserv ne '') { | |
305 | $sserv = " ($sserv)"; | |
306 | } | |
307 | } | |
308 | ||
309 | my $dserv = ''; | |
310 | if ($dport < 1024) { | |
311 | $dserv = uc(getservbyport($dport, lc($proto))); | |
312 | if ($dserv ne '') { | |
313 | $dserv = " ($dserv)"; | |
314 | } | |
315 | } | |
316 | ||
317 | print <<END | |
318 | <tr > | |
319 | <td align='center' bgcolor='$sipcol'> | |
320 | <a href='/cgi-bin/ipinfo.cgi?ip=$sip'> | |
321 | <font color='#FFFFFF'>$sip</font> | |
322 | </a> | |
323 | </td> | |
324 | <td align='center' bgcolor='$sipcol'> | |
325 | <a href='http://isc.sans.org/port_details.php?port=$sport' target='top'> | |
326 | <font color='#FFFFFF'>$sport$sserv</font> | |
327 | </a> | |
328 | </td> | |
329 | <td align='center' bgcolor='$dipcol'> | |
330 | <a href='/cgi-bin/ipinfo.cgi?ip=$dip'> | |
331 | <font color='#FFFFFF'>$dip</font> | |
332 | </a> | |
333 | </td> | |
334 | <td align='center' bgcolor='$dipcol'> | |
335 | <a href='http://isc.sans.org/port_details.php?port=$dport' target='top'> | |
336 | <font color='#FFFFFF'>$dport$dserv</font> | |
337 | </a> | |
338 | </td> | |
339 | <td align='center'>$proto</td> | |
f2fdd0c1 | 340 | <td align='center'>$state</td> |
1465b127 MT |
341 | <td align='center'>$ttl</td> |
342 | </tr> | |
ac1cfefa | 343 | END |
c2b15814 | 344 | ; |
ac1cfefa | 345 | } |
c2b15814 | 346 | |
1465b127 | 347 | print "</table></form>"; |
ac1cfefa MT |
348 | |
349 | &Header::closebox(); | |
350 | &Header::closebigbox(); | |
351 | &Header::closepage(); | |
352 | ||
353 | sub ipcolour($) { | |
f9aaffa6 MT |
354 | my $id = 0; |
355 | my $line; | |
356 | my $colour = ${Header::colourred}; | |
357 | my ($ip) = $_[0]; | |
c2b15814 MT |
358 | my $found = 0; |
359 | foreach $line (@network) { | |
1465b127 MT |
360 | if ($network[$id] eq '') { |
361 | $id++; | |
362 | } else { | |
363 | if (!$found && ipv4_in_network( $network[$id] , $masklen[$id], $ip) ) { | |
364 | $found = 1; | |
365 | $colour = $colour[$id]; | |
366 | } | |
367 | $id++; | |
368 | } | |
f9aaffa6 MT |
369 | } |
370 | return $colour | |
ac1cfefa | 371 | } |
c2b15814 MT |
372 | |
373 | # Create a string containing a complete SELECT html object | |
374 | # param1: name | |
375 | # param2: current value selected | |
376 | # param3: field list | |
377 | sub make_select ($,$,$) { | |
f9aaffa6 MT |
378 | my $select_name = shift; |
379 | my $selected = shift; | |
380 | my $select = "<select name='$select_name'>"; | |
381 | ||
382 | foreach my $value (@_) { | |
383 | my $check = $selected eq $value ? "selected='selected'" : ''; | |
384 | $select .= "<option $check value='$value'>$value</option>"; | |
385 | } | |
386 | $select .= "</select>"; | |
387 | return $select; | |
c2b15814 MT |
388 | } |
389 | ||
390 | # Build a list of IP obtained from the %entries hash | |
391 | # param1: IP field name | |
392 | sub get_known_ips ($) { | |
f9aaffa6 MT |
393 | my $field = shift; |
394 | my $qs = $cgiparams{'SEE_SORT'}; # switch the sort order | |
395 | $cgiparams{'SEE_SORT'} = $field; | |
c2b15814 | 396 | |
f9aaffa6 MT |
397 | my @liste=('*.*.*.*'); |
398 | foreach my $entry ( sort sort_entries keys %entries) { | |
399 | push (@liste, $entries{$entry}->{$field}) if (! grep (/^$entries{$entry}->{$field}$/,@liste) ); | |
400 | } | |
c2b15814 | 401 | |
f9aaffa6 | 402 | $cgiparams{'SEE_SORT'} = $qs; #restore sort order |
c2b15814 MT |
403 | return @liste; |
404 | } | |
405 | ||
406 | # Used to sort the table containing the lines displayed. | |
407 | sub sort_entries { #Reverse is not implemented | |
408 | my $qs=$cgiparams{'SEE_SORT'}; | |
409 | if ($qs =~ /orgsip|orgdip|exsip|exdip/) { | |
f9aaffa6 MT |
410 | my @a = split(/\./,$entries{$a}->{$qs}); |
411 | my @b = split(/\./,$entries{$b}->{$qs}); | |
412 | ($a[0]<=>$b[0]) || | |
413 | ($a[1]<=>$b[1]) || | |
414 | ($a[2]<=>$b[2]) || | |
415 | ($a[3]<=>$b[3]); | |
416 | } elsif ($qs =~ /expire|orgsp|orgdp|exsp|exdp/) { | |
417 | $entries{$a}->{$qs} <=> $entries{$b}->{$qs}; | |
418 | } else { | |
419 | $entries{$a}->{$qs} cmp $entries{$b}->{$qs}; | |
420 | } | |
c2b15814 MT |
421 | } |
422 | ||
423 | 1; |