]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blame - html/cgi-bin/connections.cgi
Forward Firewall: added GPL header to all files
[people/teissler/ipfire-2.x.git] / html / cgi-bin / connections.cgi
CommitLineData
ac1cfefa 1#!/usr/bin/perl
70df8302
MT
2###############################################################################
3# #
4# IPFire.org - A linux based firewall #
75bc929e 5# Copyright (C) 2007-2012 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 21
75bc929e 22use strict;
ac1cfefa
MT
23
24use Net::IPv4Addr qw( :all );
75bc929e 25use Switch;
ac1cfefa
MT
26
27# enable only the following on debugging purpose
1465b127 28#use warnings;
cb5e9c6c 29#use CGI::Carp 'fatalsToBrowser';
ac1cfefa 30
986e08d9 31require '/var/ipfire/general-functions.pl';
ac1cfefa
MT
32require "${General::swroot}/lang.pl";
33require "${General::swroot}/header.pl";
34
c8a8778f
MT
35my $colour_multicast = "#A0A0A0";
36
9b37e91e
KMK
37# sort arguments for connection tracking table
38# the sort field. eg. 1=src IP, 2=dst IP, 3=src port, 4=dst port
39my $SORT_FIELD = 0;
40# the sort order. (a)scending orr (d)escending
41my $SORT_ORDER = 0;
42# cgi query arguments
43my %cgiin;
44# debug mode
45my $debug = 0;
46
47# retrieve query arguments
48# note: let a-z A-Z and 0-9 pass as value only
49if (length ($ENV{'QUERY_STRING'}) > 0){
50 my $name;
51 my $value;
52 my $buffer = $ENV{'QUERY_STRING'};
53 my @pairs = split(/&/, $buffer);
54 foreach my $pair (@pairs){
55 ($name, $value) = split(/=/, $pair);
56 $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; # e.g. "%20" => " "
57 $value =~ s/[^a-zA-Z0-9]*//g; # a-Z 0-9 will pass
58 $cgiin{$name} = $value;
59 }
60}
61
75bc929e
MT
62&Header::showhttpheaders();
63
64my @network=();
65my @masklen=();
66my @colour=();
67
68my %netsettings=();
69&General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
70
9b37e91e
KMK
71# output cgi query arrguments to browser on debug
72if ( $debug ){
73 &Header::openbox('100%', 'center', 'DEBUG');
74 my $debugCount = 0;
75 foreach my $line (sort keys %cgiin) {
76 print "$line = '$cgiin{$line}'<br />\n";
77 $debugCount++;
78 }
79 print "&nbsp;Count: $debugCount\n";
80 &Header::closebox();
81}
82
ac1cfefa
MT
83#workaround to suppress a warning when a variable is used only once
84my @dummy = ( ${Header::table1colour} );
85undef (@dummy);
86
9b37e91e
KMK
87# check sorting arguments
88if ( $cgiin{'sort_field'} ~~ [ '1','2','3','4','5','6','7','8','9' ] ) {
89 $SORT_FIELD = $cgiin{'sort_field'};
90
91 if ( $cgiin{'sort_order'} ~~ [ 'a','d','A','D' ] ) {
92 $SORT_ORDER = lc($cgiin{'sort_order'});
93 }
94}
95
96# Read and sort the connection tracking table
97# do sorting
98if ($SORT_FIELD and $SORT_ORDER) {
99 # field sorting when sorting arguments are sane
100 open(CONNTRACK, "/usr/local/bin/getconntracktable | /usr/local/bin/consort.sh $SORT_FIELD $SORT_ORDER |") or die "Unable to read conntrack table";
101} else {
102 # default sorting with no query arguments
103 open(CONNTRACK, "/usr/local/bin/getconntracktable | sort -k 5,5 --numeric-sort --reverse |") or die "Unable to read conntrack table";
104}
75bc929e
MT
105my @conntrack = <CONNTRACK>;
106close(CONNTRACK);
ac1cfefa 107
75bc929e 108# Collect data for the @network array.
ac1cfefa 109
75bc929e
MT
110# Add Firewall Localhost 127.0.0.1
111push(@network, '127.0.0.1');
112push(@masklen, '255.255.255.255');
113push(@colour, ${Header::colourfw});
ac1cfefa 114
2c42fe6a 115if (open(IP, "${General::swroot}/red/local-ipaddress")) {
75bc929e
MT
116 my $redip = <IP>;
117 close(IP);
118
119 chomp $redip;
120 push(@network, $redip);
121 push(@masklen, '255.255.255.255');
122 push(@colour, ${Header::colourfw});
2c42fe6a
MT
123}
124
75bc929e
MT
125# Add STATIC RED aliases
126if ($netsettings{'RED_DEV'}) {
127 my $aliasfile = "${General::swroot}/ethernet/aliases";
128 open(ALIASES, $aliasfile) or die 'Unable to open aliases file.';
129 my @aliases = <ALIASES>;
130 close(ALIASES);
131
132 # We have a RED eth iface
133 if ($netsettings{'RED_TYPE'} eq 'STATIC') {
134 # We have a STATIC RED eth iface
135 foreach my $line (@aliases) {
136 chomp($line);
137 my @temp = split(/\,/,$line);
138 if ($temp[0]) {
139 push(@network, $temp[0]);
140 push(@masklen, $netsettings{'RED_NETMASK'} );
141 push(@colour, ${Header::colourfw} );
142 }
143 }
144 }
145}
ac1cfefa
MT
146
147# Add Green Firewall Interface
148push(@network, $netsettings{'GREEN_ADDRESS'});
149push(@masklen, "255.255.255.255" );
150push(@colour, ${Header::colourfw} );
151
152# Add Green Network to Array
153push(@network, $netsettings{'GREEN_NETADDRESS'});
154push(@masklen, $netsettings{'GREEN_NETMASK'} );
155push(@colour, ${Header::colourgreen} );
156
157# Add Green Routes to Array
158my @routes = `/sbin/route -n | /bin/grep $netsettings{'GREEN_DEV'}`;
159foreach my $route (@routes) {
75bc929e
MT
160 chomp($route);
161 my @temp = split(/[\t ]+/, $route);
162 push(@network, $temp[0]);
163 push(@masklen, $temp[2]);
164 push(@colour, ${Header::colourgreen} );
5433e2c9
MT
165}
166
f9aaffa6
MT
167# Add Blue Firewall Interface
168push(@network, $netsettings{'BLUE_ADDRESS'});
169push(@masklen, "255.255.255.255" );
170push(@colour, ${Header::colourfw} );
171
5433e2c9
MT
172# Add Blue Network
173if ($netsettings{'BLUE_DEV'}) {
75bc929e
MT
174 push(@network, $netsettings{'BLUE_NETADDRESS'});
175 push(@masklen, $netsettings{'BLUE_NETMASK'} );
176 push(@colour, ${Header::colourblue} );
177
178 # Add Blue Routes to Array
179 @routes = `/sbin/route -n | /bin/grep $netsettings{'BLUE_DEV'}`;
180 foreach my $route (@routes) {
181 chomp($route);
182 my @temp = split(/[\t ]+/, $route);
183 push(@network, $temp[0]);
184 push(@masklen, $temp[2]);
185 push(@colour, ${Header::colourblue} );
186 }
187}
188
5ac2ed47
MT
189# Add Orange Firewall Interface
190push(@network, $netsettings{'ORANGE_ADDRESS'});
191push(@masklen, "255.255.255.255" );
192push(@colour, ${Header::colourfw} );
193
75bc929e
MT
194# Add Orange Network
195if ($netsettings{'ORANGE_DEV'}) {
196 push(@network, $netsettings{'ORANGE_NETADDRESS'});
197 push(@masklen, $netsettings{'ORANGE_NETMASK'} );
198 push(@colour, ${Header::colourorange} );
199 # Add Orange Routes to Array
200 @routes = `/sbin/route -n | /bin/grep $netsettings{'ORANGE_DEV'}`;
201 foreach my $route (@routes) {
202 chomp($route);
203 my @temp = split(/[\t ]+/, $route);
204 push(@network, $temp[0]);
205 push(@masklen, $temp[2]);
206 push(@colour, ${Header::colourorange} );
207 }
5433e2c9
MT
208}
209
c8a8778f
MT
210# Highlight multicast connections.
211push(@network, "224.0.0.0");
212push(@masklen, "239.0.0.0");
213push(@colour, $colour_multicast);
214
6e13d0a5
MT
215# Add OpenVPN net and RED/BLUE/ORANGE entry (when appropriate)
216if (-e "${General::swroot}/ovpn/settings") {
75bc929e
MT
217 my %ovpnsettings = ();
218 &General::readhash("${General::swroot}/ovpn/settings", \%ovpnsettings);
219 my @tempovpnsubnet = split("\/",$ovpnsettings{'DOVPN_SUBNET'});
220
221 # add OpenVPN net
222 push(@network, $tempovpnsubnet[0]);
223 push(@masklen, $tempovpnsubnet[1]);
224 push(@colour, ${Header::colourovpn} );
225
226 # add BLUE:port / proto
227 if (($ovpnsettings{'ENABLED_BLUE'} eq 'on') && $netsettings{'BLUE_DEV'}) {
228 push(@network, $netsettings{'BLUE_ADDRESS'} );
229 push(@masklen, '255.255.255.255' );
230 push(@colour, ${Header::colourovpn});
231 }
6e13d0a5 232
75bc929e
MT
233 # add ORANGE:port / proto
234 if (($ovpnsettings{'ENABLED_ORANGE'} eq 'on') && $netsettings{'ORANGE_DEV'}) {
235 push(@network, $netsettings{'ORANGE_ADDRESS'} );
236 push(@masklen, '255.255.255.255' );
237 push(@colour, ${Header::colourovpn} );
238 }
239}
6e13d0a5 240
03435d85 241open(IPSEC, "${General::swroot}/vpn/config");
75bc929e
MT
242my @ipsec = <IPSEC>;
243close(IPSEC);
7dbf47dc 244
75bc929e
MT
245foreach my $line (@ipsec) {
246 my @vpn = split(',', $line);
247 my ($network, $mask) = split("/", $vpn[12]);
6e13d0a5 248
75bc929e
MT
249 if (!&General::validip($mask)) {
250 $mask = ipv4_cidr2msk($mask);
251 }
ac1cfefa 252
75bc929e
MT
253 push(@network, $network);
254 push(@masklen, $mask);
255 push(@colour, ${Header::colourvpn});
ac1cfefa 256}
ac1cfefa 257
d9ac41d5
MT
258if (-e "${General::swroot}/ovpn/n2nconf") {
259 open(OVPNN2N, "${General::swroot}/ovpn/ovpnconfig");
260 my @ovpnn2n = <OVPNN2N>;
261 close(OVPNN2N);
262
263 foreach my $line (@ovpnn2n) {
264 my @ovpn = split(',', $line);
265 next if ($ovpn[4] ne 'net');
266
267 my ($network, $mask) = split("/", $ovpn[12]);
268 if (!&General::validip($mask)) {
269 $mask = ipv4_cidr2msk($mask);
270 }
271
272 push(@network, $network);
273 push(@masklen, $mask);
274 push(@colour, ${Header::colourovpn});
275 }
276}
277
75bc929e
MT
278# Show the page.
279&Header::openpage($Lang::tr{'connections'}, 1, '');
280&Header::openbigbox('100%', 'left');
281&Header::openbox('100%', 'left', $Lang::tr{'connection tracking'});
c2b15814 282
75bc929e
MT
283# Print legend.
284print <<END;
285 <table width='100%'>
286 <tr>
287 <td align='center'>
288 <b>$Lang::tr{'legend'} : </b>
289 </td>
290 <td align='center' bgcolor='${Header::colourgreen}'>
291 <b><font color='#FFFFFF'>$Lang::tr{'lan'}</font></b>
292 </td>
293 <td align='center' bgcolor='${Header::colourred}'>
294 <b><font color='#FFFFFF'>$Lang::tr{'internet'}</font></b>
295 </td>
296 <td align='center' bgcolor='${Header::colourorange}'>
297 <b><font color='#FFFFFF'>$Lang::tr{'dmz'}</font></b>
298 </td>
299 <td align='center' bgcolor='${Header::colourblue}'>
300 <b><font color='#FFFFFF'>$Lang::tr{'wireless'}</font></b>
301 </td>
302 <td align='center' bgcolor='${Header::colourfw}'>
303 <b><font color='#FFFFFF'>IPFire</font></b>
304 </td>
305 <td align='center' bgcolor='${Header::colourvpn}'>
306 <b><font color='#FFFFFF'>$Lang::tr{'vpn'}</font></b>
307 </td>
308 <td align='center' bgcolor='${Header::colourovpn}'>
309 <b><font color='#FFFFFF'>$Lang::tr{'OpenVPN'}</font></b>
310 </td>
c8a8778f
MT
311 <td align='center' bgcolor='$colour_multicast'>
312 <b><font color='#FFFFFF'>Multicast</font></b>
313 </td>
75bc929e
MT
314 </tr>
315 </table>
316 <br>
317END
c2b15814 318
9b37e91e
KMK
319if ($SORT_FIELD and $SORT_ORDER) {
320 my @sort_field_name = (
321 $Lang::tr{'source ip'},
322 $Lang::tr{'destination ip'},
323 $Lang::tr{'source port'},
324 $Lang::tr{'destination port'},
325 $Lang::tr{'protocol'},
326 $Lang::tr{'connection'}.' '.$Lang::tr{'status'},
327 $Lang::tr{'expires'}.' ('.$Lang::tr{'seconds'}.')',
328 $Lang::tr{'download'},
329 $Lang::tr{'upload'}
330 );
331 my $sort_order_name;
332 if (lc($SORT_ORDER) eq "a") {
333 $sort_order_name = $Lang::tr{'sort ascending'};
334 } else {
335 $sort_order_name = $Lang::tr{'sort descending'};
336 }
337
338print <<END
339 <div style="font-weight:bold;margin:10px;font-size: 70%">
340 $sort_order_name: $sort_field_name[$SORT_FIELD-1]
341 </div>
342END
343;
344}
345
75bc929e
MT
346# Print table header.
347print <<END;
348 <table width='100%'>
9b37e91e 349 <tr valign="top"">
75bc929e 350 <th align='center'>
9b37e91e
KMK
351 <a href="?sort_field=5&sort_order=d"><img style="width:10px" src="/images/up.gif"></a>
352 <a href="?sort_field=5&sort_order=a"><img style="width:10px" src="/images/down.gif"></a>
353 </th>
354 <th align='center' colspan="2">
355 <a href="?sort_field=1&sort_order=d"><img style="width:10px" src="/images/up.gif"></a>
356 <a href="?sort_field=1&sort_order=a"><img style="width:10px" src="/images/down.gif"></a>
357 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
358 <a href="?sort_field=3&sort_order=d"><img style="width:10px" src="/images/up.gif"></a>
359 <a href="?sort_field=3&sort_order=a"><img style="width:10px" src="/images/down.gif"></a>
360 </th>
361 <th align='center' colspan="2">
362 <a href="?sort_field=2&sort_order=d"><img style="width:10px" src="/images/up.gif"></a>
363 <a href="?sort_field=2&sort_order=a"><img style="width:10px" src="/images/down.gif"></a>
364 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
365 <a href="?sort_field=4&sort_order=d"><img style="width:10px" src="/images/up.gif"></a>
366 <a href="?sort_field=4&sort_order=a"><img style="width:10px" src="/images/down.gif"></a>
75bc929e
MT
367 </th>
368 <th align='center'>
9b37e91e
KMK
369 <a href="?sort_field=8&sort_order=d"><img style="width:10px" src="/images/up.gif"></a>
370 <a href="?sort_field=8&sort_order=a"><img style="width:10px" src="/images/down.gif"></a>
371 &nbsp;&nbsp;&nbsp;&nbsp;
372 <a href="?sort_field=9&sort_order=d"><img style="width:10px" src="/images/up.gif"></a>
373 <a href="?sort_field=9&sort_order=a"><img style="width:10px" src="/images/down.gif"></a>
374 </th>
375 <th align='center'>
376 <a href="?sort_field=6&sort_order=d"><img style="width:10px" src="/images/up.gif"></a>
377 <a href="?sort_field=6&sort_order=a"><img style="width:10px" src="/images/down.gif"></a>
75bc929e 378 </th>
75bc929e 379 <th align='center'>
9b37e91e
KMK
380 <a href="?sort_field=7&sort_order=d"><img style="width:10px" src="/images/up.gif"></a>
381 <a href="?sort_field=7&sort_order=a"><img style="width:10px" src="/images/down.gif"></a>
382 </th>
383 </tr>
384 <tr valign="top"">
385 <th align='center'>
386 $Lang::tr{'protocol'}
387 </th>
388 <th align='center' colspan="2">
389 $Lang::tr{'source ip and port'}
390 </th>
391 <th align='center' colspan="2">
75bc929e
MT
392 $Lang::tr{'dest ip and port'}
393 </th>
75bc929e
MT
394 <th align='center'>
395 $Lang::tr{'download'} /
396 <br>$Lang::tr{'upload'}
397 </th>
398 <th align='center'>
399 $Lang::tr{'connection'}<br>$Lang::tr{'status'}
400 </th>
401 <th align='center'>
402 $Lang::tr{'expires'}<br>($Lang::tr{'seconds'})
403 </th>
404 </tr>
405END
c2b15814 406
75bc929e
MT
407foreach my $line (@conntrack) {
408 my @conn = split(' ', $line);
c2b15814 409
75bc929e
MT
410 # The first bit is the l3 protocol.
411 my $l3proto = $conn[0];
c2b15814 412
75bc929e
MT
413 # Skip everything that is not IPv4.
414 if ($l3proto ne 'ipv4') {
415 next;
416 }
ac1cfefa 417
75bc929e
MT
418 # L4 protocol (tcp, udp, ...).
419 my $l4proto = $conn[2];
c2b15814 420
7d55ca0d 421 # Translate unknown protocols.
75bc929e 422 if ($l4proto eq 'unknown') {
7d55ca0d
MT
423 my $l4protonum = $conn[3];
424 if ($l4protonum eq '2') {
425 $l4proto = 'IGMP';
426 } elsif ($l4protonum eq '4') {
427 $l4proto = 'IPv4 Encap';
428 } elsif ($l4protonum eq '33') {
429 $l4proto = 'DCCP';
430 } elsif ($l4protonum eq '41') {
431 $l4proto = 'IPv6 Encap';
432 } elsif ($l4protonum eq '50') {
433 $l4proto = 'ESP';
434 } elsif ($l4protonum eq '51') {
435 $l4proto = 'AH';
436 } elsif ($l4protonum eq '132') {
437 $l4proto = 'SCTP';
438 } else {
439 $l4proto = $l4protonum;
440 }
441 } else {
442 $l4proto = uc($l4proto);
75bc929e 443 }
4809e64e 444
75bc929e
MT
445 # Source and destination.
446 my $sip;
c9e01c8c 447 my $sip_ret;
75bc929e 448 my $dip;
c9e01c8c 449 my $dip_ret;
75bc929e 450 my $sport;
c9e01c8c 451 my $sport_ret;
75bc929e 452 my $dport;
c9e01c8c 453 my $dport_ret;
75bc929e
MT
454 my @packets;
455 my @bytes;
456
457 my $ttl = $conn[4];
458 my $state;
7d55ca0d 459 if ($l4proto eq 'TCP') {
75bc929e
MT
460 $state = $conn[5];
461 }
c2b15814 462
75bc929e
MT
463 # Kick out everything that is not IPv4.
464 foreach my $item (@conn) {
465 my ($key, $val) = split('=', $item);
466
467 switch ($key) {
468 case "src" {
c9e01c8c
MT
469 if ($sip == "") {
470 $sip = $val;
471 } else {
472 $dip_ret = $val;
473 }
75bc929e
MT
474 }
475 case "dst" {
c9e01c8c
MT
476 if ($dip == "") {
477 $dip = $val;
478 } else {
479 $sip_ret = $val;
480 }
75bc929e
MT
481 }
482 case "sport" {
c9e01c8c
MT
483 if ($sport == "") {
484 $sport = $val;
485 } else {
486 $dport_ret = $val;
487 }
75bc929e
MT
488 }
489 case "dport" {
c9e01c8c
MT
490 if ($dport == "") {
491 $dport = $val;
492 } else {
493 $sport_ret = $val;
494 }
75bc929e
MT
495 }
496 case "packets" {
497 push(@packets, $val);
498 }
499 case "bytes" {
500 push(@bytes, $val);
501 }
502 }
503 }
1465b127 504
75bc929e
MT
505 my $sip_colour = ipcolour($sip);
506 my $dip_colour = ipcolour($dip);
1465b127 507
7d55ca0d
MT
508 my $sserv = '';
509 if ($sport < 1024) {
75bc929e 510 $sserv = uc(getservbyport($sport, lc($l4proto)));
7d55ca0d 511 }
1465b127 512
7d55ca0d
MT
513 my $dserv = '';
514 if ($dport < 1024) {
75bc929e 515 $dserv = uc(getservbyport($dport, lc($l4proto)));
7d55ca0d 516 }
1465b127 517
75bc929e
MT
518 my $bytes_in = format_bytes($bytes[0]);
519 my $bytes_out = format_bytes($bytes[1]);
520
521 # Format TTL
522 $ttl = format_time($ttl);
523
c9e01c8c
MT
524 my $sip_extra;
525 if ($sip ne $sip_ret) {
526 $sip_extra = "<font color='#FFFFFF'>&gt;</font> ";
527 $sip_extra .= "<a href='/cgi-bin/ipinfo.cgi?ip=$sip_ret'>";
528 $sip_extra .= " <font color='#FFFFFF'>$sip_ret</font>";
529 $sip_extra .= "</a>";
530 }
531
532 my $dip_extra;
533 if ($dip ne $dip_ret) {
534 $dip_extra = "<font color='#FFFFFF'>&gt;</font> ";
535 $dip_extra .= "<a href='/cgi-bin/ipinfo.cgi?ip=$dip_ret'>";
536 $dip_extra .= " <font color='#FFFFFF'>$dip_ret</font>";
537 $dip_extra .= "</a>";
538 }
539
540
541 my $sport_extra;
542 if ($sport ne $sport_ret) {
543 my $sserv_ret = '';
544 if ($sport_ret < 1024) {
545 $sserv_ret = uc(getservbyport($sport_ret, lc($l4proto)));
546 }
547
548 $sport_extra = "<font color='#FFFFFF'>&gt;</font> ";
549 $sport_extra .= "<a href='http://isc.sans.org/port_details.php?port=$sport_ret' target='top' title='$sserv_ret'>";
550 $sport_extra .= " <font color='#FFFFFF'>$sport_ret</font>";
551 $sport_extra .= "</a>";
552 }
553
554 my $dport_extra;
555 if ($dport ne $dport_ret) {
556 my $dserv_ret = '';
557 if ($dport_ret < 1024) {
558 $dserv_ret = uc(getservbyport($dport_ret, lc($l4proto)));
559 }
560
561 $dport_extra = "<font color='#FFFFFF'>&gt;</font> ";
562 $dport_extra .= "<a href='http://isc.sans.org/port_details.php?port=$dport_ret' target='top' title='$dserv_ret'>";
563 $dport_extra .= " <font color='#FFFFFF'>$dport_ret</font>";
564 $dport_extra .= "</a>";
565 }
566
75bc929e
MT
567 print <<END;
568 <tr>
569 <td align='center'>$l4proto</td>
570 <td align='center' bgcolor='$sip_colour'>
571 <a href='/cgi-bin/ipinfo.cgi?ip=$sip'>
572 <font color='#FFFFFF'>$sip</font>
573 </a>
c9e01c8c 574 $sip_extra
75bc929e
MT
575 </td>
576 <td align='center' bgcolor='$sip_colour'>
c9e01c8c
MT
577 <a href='http://isc.sans.org/port_details.php?port=$sport' target='top' title='$sserv'>
578 <font color='#FFFFFF'>$sport</font>
75bc929e 579 </a>
c9e01c8c 580 $sport_extra
75bc929e
MT
581 </td>
582 <td align='center' bgcolor='$dip_colour'>
583 <a href='/cgi-bin/ipinfo.cgi?ip=$dip'>
584 <font color='#FFFFFF'>$dip</font>
585 </a>
c9e01c8c 586 $dip_extra
75bc929e
MT
587 </td>
588 <td align='center' bgcolor='$dip_colour'>
c9e01c8c
MT
589 <a href='http://isc.sans.org/port_details.php?port=$dport' target='top' title='$dserv'>
590 <font color='#FFFFFF'>$dport</font>
75bc929e 591 </a>
c9e01c8c 592 $dport_extra
75bc929e
MT
593 </td>
594 <td align='center'>
595 $bytes_in / $bytes_out
596 </td>
597 <td align='center'>$state</td>
598 <td align='center'>$ttl</td>
599 </tr>
ac1cfefa 600END
ac1cfefa 601}
c2b15814 602
75bc929e
MT
603# Close the main table.
604print "</table>";
ac1cfefa
MT
605
606&Header::closebox();
607&Header::closebigbox();
608&Header::closepage();
609
75bc929e
MT
610sub format_bytes($) {
611 my $bytes = shift;
612 my @units = ("B", "k", "M", "G", "T");
613
614 foreach my $unit (@units) {
615 if ($bytes < 1024) {
616 return sprintf("%d%s", $bytes, $unit);
617 }
c2b15814 618
75bc929e
MT
619 $bytes /= 1024;
620 }
621
622 return sprintf("%d%s", $bytes, $units[$#units]);
c2b15814
MT
623}
624
75bc929e
MT
625sub format_time($) {
626 my $time = shift;
c2b15814 627
75bc929e
MT
628 my $seconds = $time % 60;
629 my $minutes = $time / 60;
c2b15814 630
75bc929e
MT
631 my $hours = 0;
632 if ($minutes >= 60) {
633 $hours = $minutes / 60;
634 $minutes %= 60;
635 }
636
637 return sprintf("%3d:%02d:%02d", $hours, $minutes, $seconds);
c2b15814
MT
638}
639
75bc929e
MT
640sub ipcolour($) {
641 my $id = 0;
642 my $colour = ${Header::colourred};
643 my ($ip) = $_[0];
644 my $found = 0;
645
646 foreach my $line (@network) {
647 if ($network[$id] eq '') {
648 $id++;
649 } else {
650 if (!$found && ipv4_in_network($network[$id], $masklen[$id], $ip) ) {
651 $found = 1;
652 $colour = $colour[$id];
653 }
654 $id++;
655 }
656 }
657
658 return $colour;
c2b15814
MT
659}
660
6611;