#!/usr/bin/perl use strict; use lib "/opt/vyatta/share/perl5"; use Vyatta::Config; use Vyatta::NatRule; sub numerically { $a <=> $b; } exit 1 if ($#ARGV != 0); my $xsl_file = $ARGV[0]; if (! -e $xsl_file) { print "Invalid XSL file \"$xsl_file\"\n"; exit 1; } my %stats = ( source => [ ], destination => [ ], ); open(STATS, "sudo /sbin/iptables -t nat -L -vn |") or exit 1; my $skey = ""; my ($rule_tcp_pkts, $rule_tcp_bytes, $rule_pkts, $rule_bytes); my $tcp_done = 0; while () { if (m/^Chain PREROUTING/) { $skey = "destination"; } elsif (m/^Chain POSTROUTING/) { $skey = "source"; } elsif (m/^Chain /) { $skey = ""; } if ($skey ne "" && (m/SNAT/ || m/DNAT/ || m/MASQUERADE/ || m/RETURN/ || m/NETMAP/)) { m/^\s*(\d+[KMG]?)\s+(\d+[KMG]?)\s/; $rule_pkts = $1; $rule_bytes = $2; if (m/tcp_udp/) { # protocol is tcp_udp, 2 rules in iptables for it if ($tcp_done == 0) { $rule_tcp_pkts = $rule_pkts; $rule_tcp_bytes = $rule_bytes; $tcp_done = 1; next; } else { $rule_pkts += $rule_tcp_pkts; $rule_bytes += $rule_tcp_bytes; $tcp_done = 0; } } push @{$stats{$skey}}, ($rule_pkts, $rule_bytes); } } close STATS; open(RENDER, "| /opt/vyatta/sbin/render_xml $xsl_file") or exit 1; # begin print RENDER "\n"; # get rid of the stats for PRE_SNAT_HOOK splice @{$stats{'source'}}, 0, 2; my $config = new Vyatta::Config; $config->setLevel("service nat rule"); my @rules_pre = $config->listOrigNodes(); my $rule; my @rules = sort numerically @rules_pre; for $rule (@rules) { my $nrule = new Vyatta::NatRule; $nrule->setupOrig("service nat rule $rule"); next if defined $nrule->{_disable}; my $ntype = $nrule->orig_type(); print RENDER " \n"; print RENDER " $rule\n"; my $pkts = shift @{$stats{$ntype}}; my $bytes = shift @{$stats{$ntype}}; print RENDER " $pkts\n"; print RENDER " $bytes\n"; $nrule->outputXml(*RENDER{IO}); print RENDER " \n"; } # end print RENDER "\n"; close RENDER; exit 0;