require "${General::swroot}/location-functions.pl";
my $colour_multicast = "#A0A0A0";
-
my %settings = ();
-&General::readhash("/var/ipfire/ethernet/settings", \%settings);
+# Cache for ipcolour results to speed up lookups
+my %ipcolour_cache = ();
+&General::readhash("/var/ipfire/ethernet/settings", \%settings);
&Header::showhttpheaders();
# Collect all known networks
# Pre-sort networks for faster lookup
my @networks = reverse sort {
&Network::get_prefix($a) <=> &Network::get_prefix($b)
-} keys %networks;
+} grep { defined($_) && &Network::check_subnet($_) } keys %networks;
# Define zones and their corresponding colors
my %zones = (
# Read and sort the connection tracking table
my $connection_count = 0;
-open(CONNTRACK, "/usr/local/bin/getconntracktable | sort -k 5,5 --numeric-sort --reverse |")
- or die "Unable to read conntrack table";
+my @conntrack_data = &General::system_output("/usr/local/bin/getconntracktable");
+if (!@conntrack_data) {
+ print "<p><b>$Lang::tr{'connections unable to read conntrack table'}</b></p>\n";
+ &Header::closesection();
+ &Header::closebigbox();
+ &Header::closepage();
+ exit;
+}
+my @sorted_conntrack = sort { (split(' ', $b))[4] <=> (split(' ', $a))[4] } @conntrack_data;
-foreach my $line (<CONNTRACK>) {
+foreach my $line (@sorted_conntrack) {
my @conn = split(' ', $line);
# The first bit is the l3 protocol.
# Apply search filter
if ($search_enabled && ($search_ip || $search_port || $search_protocol)) {
my $matches_search = 1;
- if ($search_ip) {
+
+ if ($search_ip && $matches_search) {
$matches_search = 0;
if (($sip && $sip =~ /\Q$search_ip\E/i) ||
($sip_ret && $sip_ret =~ /\Q$search_ip\E/i) ||
$matches_search = 1;
}
}
- if ($search_port) {
+
+ if ($search_port && $matches_search) {
$matches_search = 0;
if (($sport && $sport eq $search_port) ||
($sport_ret && $sport_ret eq $search_port) ||
$matches_search = 1;
}
}
- if ($search_protocol) {
+
+ if ($search_protocol && $matches_search) {
$matches_search = 0;
if (lc($l4proto) eq lc($search_protocol)) {
$matches_search = 1;
}
}
+
next unless $matches_search;
}
$connection_count++;
}
-close(CONNTRACK);
-
# Print filter status
if (@selected_zones || $search_enabled) {
my @filter_parts;
sub ipcolour($) {
my $address = shift;
- # Sort all networks so we find the best match
- my @networks = reverse sort {
- &Network::get_prefix($a) <=> &Network::get_prefix($b)
- } keys %networks;
+ # Check cache first
+ if (exists $ipcolour_cache{$address}) {
+ return $ipcolour_cache{$address};
+ }
+ # Use pre-sorted and filtered networks
foreach my $network (@networks) {
- if (defined $network) {
- if (&Network::check_subnet($network)) {
- if (&Network::ip_address_in_network($address, $network)) {
- return $networks{$network};
- }
- }
+ if (&Network::ip_address_in_network($address, $network)) {
+ $ipcolour_cache{$address} = $networks{$network};
+ return $networks{$network};
}
}
# If we don't know the network, the address must be from the RED network
+ $ipcolour_cache{$address} = ${Header::colourred};
return ${Header::colourred};
}