summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStig Thormodsrud <stig@vyatta.com>2008-08-02 19:13:03 -0700
committerStig Thormodsrud <stig@vyatta.com>2008-08-02 19:13:03 -0700
commitb4453ca528607b6bf9871c17c23048465de3768c (patch)
treef9ab2dd92b31cef86d8ccda95c996c26d284cf54
parentddc06ae69abd438b07afa679f5f3af4d9a8199d9 (diff)
downloadvyatta-nat-b4453ca528607b6bf9871c17c23048465de3768c.tar.gz
vyatta-nat-b4453ca528607b6bf9871c17c23048465de3768c.zip
Fix 522: Feature Request: add "show nat translations" command to list active NAT translations.
-rw-r--r--Makefile.am3
-rw-r--r--debian/control3
-rwxr-xr-xscripts/vyatta-nat-translations.pl254
-rw-r--r--templates-op/show/nat/translations/destination/address/node.def1
-rw-r--r--templates-op/show/nat/translations/destination/address/node.tag/node.def11
-rw-r--r--templates-op/show/nat/translations/destination/detail/node.def3
-rw-r--r--templates-op/show/nat/translations/destination/monitor/detail/node.def3
-rw-r--r--templates-op/show/nat/translations/destination/monitor/node.def3
-rw-r--r--templates-op/show/nat/translations/destination/node.def2
-rw-r--r--templates-op/show/nat/translations/detail/node.def2
-rw-r--r--templates-op/show/nat/translations/node.def2
-rw-r--r--templates-op/show/nat/translations/source/address/node.def1
-rw-r--r--templates-op/show/nat/translations/source/address/node.tag/node.def11
-rw-r--r--templates-op/show/nat/translations/source/detail/node.def3
-rw-r--r--templates-op/show/nat/translations/source/monitor/detail/node.def3
-rw-r--r--templates-op/show/nat/translations/source/monitor/node.def3
-rw-r--r--templates-op/show/nat/translations/source/node.def2
17 files changed, 308 insertions, 2 deletions
diff --git a/Makefile.am b/Makefile.am
index 70f85c2..63966e0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -8,7 +8,8 @@ curverdir = $(sysconfdir)/config-migrate/current
sbin_SCRIPTS = scripts/vyatta-update-nat.pl
sbin_SCRIPTS += scripts/vyatta-show-nat.pl
-bin_sudo_users_SCRIPTS = scripts/vyatta-clear-nat
+bin_sudo_users_SCRIPTS = scripts/vyatta-clear-nat
+bin_sudo_users_SCRIPTS += scripts/vyatta-nat-translations.pl
share_perl5_DATA = scripts/VyattaNatRule.pm
curver_DATA = cfg-version/nat@2
diff --git a/debian/control b/debian/control
index 31a487e..d82a8fe 100644
--- a/debian/control
+++ b/debian/control
@@ -11,6 +11,7 @@ Depends: vyatta-cfg,
vyatta-bash | bash (>= 3.1),
vyatta-op,
vyatta-op-xml,
- iptables
+ iptables,
+ conntrack
Description: Vyatta configuration/operational commands for NAT
Vyatta configuration and operational templates and scripts for NAT
diff --git a/scripts/vyatta-nat-translations.pl b/scripts/vyatta-nat-translations.pl
new file mode 100755
index 0000000..e5e9e64
--- /dev/null
+++ b/scripts/vyatta-nat-translations.pl
@@ -0,0 +1,254 @@
+#!/usr/bin/perl
+#
+# Module: vyatta-nat-translate.pl
+#
+# **** License ****
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# This code was originally developed by Vyatta, Inc.
+# Portions created by Vyatta are Copyright (C) 2007 Vyatta, Inc.
+# All Rights Reserved.
+#
+# Author: Stig Thormodsrud
+# Date: July 2008
+# Description: Script to display nat translations
+#
+# **** End License ****
+#
+
+use Getopt::Long;
+use XML::Simple;
+use Data::Dumper;
+use POSIX;
+
+use warnings;
+use strict;
+
+my $dump = 0;
+my ($xml_file, $verbose, $proto, $stats, $ipaddr, $pipe);
+my $mode='both';
+my $verbose_format = "%-20s %-18s %-20s %-18s\n";
+my $format = "%-20s %-20s %-4s %-4s %-8s";
+
+
+sub add_xml_root {
+ my $xml = shift;
+
+ $xml = '<data>' . $xml . '</data>';
+ return $xml;
+}
+
+sub read_xml_file {
+ my $file = shift;
+
+ local($/, *FD); # slurp mode
+ open FD, "<", $file or die "Couldn't open $file\n";
+ my $xml = <FD>;
+ close FD;
+ $xml = add_xml_root($xml);
+ return $xml;
+}
+
+sub print_xml {
+ my $data = shift;
+ print Dumper($data);
+}
+
+sub nat_print_xml {
+ my ($data, $mode) = @_;
+
+ my $flow = 0;
+
+ my %flowh;
+ while (1) {
+ my $meta = 0;
+ last if ! defined $data->{flow}[$flow];
+ my $flow_ref = $data->{flow}[$flow];
+ my $flow_type = $flow_ref->{type};
+ my (%src, %dst, %sport, %dport, %proto);
+ my (%packets, %bytes);
+ my $timeout = undef;
+ my $uses = undef;
+ while (1) {
+ my $meta_ref = $flow_ref->{meta}[$meta];
+ last if ! defined $meta_ref;
+ my $dir = $meta_ref->{direction};
+ if ($dir eq 'original' or $dir eq 'reply') {
+ my $l3_ref = $meta_ref->{layer3}[0];
+ my $l4_ref = $meta_ref->{layer4}[0];
+ my $count_ref = $meta_ref->{counters}[0];
+ if (defined $l3_ref) {
+ $src{$dir} = $l3_ref->{src}[0];
+ $dst{$dir} = $l3_ref->{dst}[0];
+ if (defined $l4_ref) {
+ $sport{$dir} = $l4_ref->{sport}[0];
+ $dport{$dir} = $l4_ref->{dport}[0];
+ $proto{$dir} = $l4_ref->{protoname};
+ }
+ }
+ if (defined $stats and defined $count_ref) {
+ $packets{$dir} = $count_ref->{packets}[0];
+ $bytes{$dir} = $count_ref->{bytes}[0];
+ }
+ } elsif ($dir eq 'independent') {
+ $timeout = $meta_ref->{timeout}[0];
+ $uses = $meta_ref->{'use'}[0];
+ }
+ $meta++;
+ }
+ my ($proto, $in_src, $in_dst, $out_src, $out_dst);
+ $proto = $proto{original};
+ $in_src = "$src{original}";
+ $in_src .= ":$sport{original}" if defined $sport{original};
+ $in_dst = "$dst{original}";
+ $in_dst .= ":$dport{original}" if defined $dport{original};
+ $out_src = "$dst{reply}";
+ $out_src .= ":$dport{reply}" if defined $dport{reply};
+ $out_dst = "$src{reply}";
+ $out_dst .= ":$sport{reply}" if defined $sport{reply};
+ if (defined $verbose) {
+ printf($verbose_format, $in_src, $in_dst, $out_src, $out_dst);
+ }
+ if (defined $mode) {
+ my ($from, $to);
+ if ($mode eq 'snat') {
+ $from = "$src{original}";
+ $to = "$dst{reply}";
+ if (defined $sport{original} and defined $dport{reply}) {
+ if ($sport{original} ne $dport{reply}) {
+ $from .= ":$sport{original}";
+ $to .= ":$dport{reply}";
+ }
+ }
+ } else {
+ $from = "$dst{original}";
+ $to = "$src{reply}";
+ if (defined $dport{original} and defined $sport{reply}) {
+ if ($dport{original} ne $sport{reply}) {
+ $from .= ":$dport{original}";
+ $to .= ":$sport{reply}";
+ }
+ }
+ }
+ if (defined $verbose) {
+ print " $proto: $mode: $from ==> $to";
+ } else {
+ my $timeout2 = "";
+ if (defined $timeout) {
+ $timeout2 = $timeout;
+ }
+ printf($format, $from, $to, $mode, $proto, $timeout2);
+ print " $flow_type" if defined $flow_type;
+ print "\n";
+ }
+ }
+ if (defined $verbose) {
+ print " timeout: $timeout" if defined $timeout;
+ print " use: $uses " if defined $uses;
+ print " type: $flow_type" if defined $flow_type;
+ print "\n";
+ }
+ if (defined $stats) {
+ foreach my $dir ('original', 'reply') {
+ if (defined $packets{$dir}) {
+ printf(" %-8s: packets %s, bytes %s\n",
+ $dir, $packets{$dir}, $bytes{$dir});
+ }
+ }
+ }
+ $flow++;
+ }
+ return $flow;
+}
+
+
+#
+# main
+#
+GetOptions("verbose" => \$verbose,
+ "proto=s" => \$proto,
+ "file=s" => \$xml_file,
+ "stats" => \$stats,
+ "mode=s" => \$mode,
+ "ipaddr=s" => \$ipaddr,
+ "pipe" => \$pipe,
+);
+
+my $conntrack = '/usr/sbin/conntrack';
+if (! -f $conntrack) {
+ die "Package [conntrack] not installed";
+}
+
+my $xs = XML::Simple->new(ForceArray => 1, KeepRoot => 0);
+my ($xml, $data);
+
+if (defined $xml_file) {
+ $xml = read_xml_file($xml_file);
+ $data = $xs->XMLin($xml);
+ if ($dump) {
+ print_xml($data);
+ exit;
+ }
+ if (defined $verbose) {
+ printf($verbose_format, 'Inside src', 'Inside dst',
+ 'Outside src', 'Outside dst');
+ } else {
+ printf($format, 'Pre-NAT', 'Post-NAT', 'Type', 'Prot', 'Timeout');
+ print "\n";
+ }
+ nat_print_xml($data, 'snat');
+
+} elsif (defined $pipe) {
+ # flush stdout after every write
+ $| = 1;
+ printf($format, 'Pre-NAT', 'Post-NAT', 'Type', 'Prot', 'Timeout');
+ print " Type\n";
+ while ($xml = <STDIN>) {
+ $xml = add_xml_root($xml);
+ $data = $xs->XMLin($xml);
+ nat_print_xml($data, $mode);
+ }
+} else {
+
+ if (defined $proto) {
+ $proto = "-p $proto"
+ } else {
+ $proto = "";
+ }
+ if (defined $verbose) {
+ printf($verbose_format, 'Inside src', 'Inside dst',
+ 'Outside src', 'Outside dst');
+ } else {
+ printf($format, 'Pre-NAT', 'Post-NAT', 'Type', 'Prot', 'Timeout');
+ print "\n";
+ }
+ if ($mode eq 'both' or $mode eq 'snat') {
+ my $ipopt = "";
+ if (defined $ipaddr) {
+ $ipopt = "--orig-src $ipaddr";
+ }
+ $xml = `sudo $conntrack -L -n $ipopt -o xml $proto`;
+ my $snat_xml = add_xml_root($xml);
+ $data = $xs->XMLin($snat_xml);
+ nat_print_xml($data, 'snat');
+ }
+ if ($mode eq 'both' or $mode eq 'dnat') {
+ my $ipopt = "";
+ if (defined $ipaddr) {
+ $ipopt = "--orig-dst $ipaddr";
+ }
+ $xml = `sudo $conntrack -L -g $ipopt -o xml $proto`;
+ my $dnat_xml = add_xml_root($xml);
+ $data = $xs->XMLin($dnat_xml);
+ nat_print_xml($data, 'dnat');
+ }
+}
+
+# end of file
diff --git a/templates-op/show/nat/translations/destination/address/node.def b/templates-op/show/nat/translations/destination/address/node.def
new file mode 100644
index 0000000..f103fe4
--- /dev/null
+++ b/templates-op/show/nat/translations/destination/address/node.def
@@ -0,0 +1 @@
+help: Show active NAT destination translations for an IP address
diff --git a/templates-op/show/nat/translations/destination/address/node.tag/node.def b/templates-op/show/nat/translations/destination/address/node.tag/node.def
new file mode 100644
index 0000000..0ae5846
--- /dev/null
+++ b/templates-op/show/nat/translations/destination/address/node.tag/node.def
@@ -0,0 +1,11 @@
+help: Show active NAT destination translations for an IP address
+allowed: echo -n '<x.x.x.x>'
+run: if /opt/vyatta/sbin/vyatta-validate-type.pl -q ipv4 $6
+ then
+ sudo ${vyatta_bindir}/sudo-users/vyatta-nat-translations.pl \
+ --mode=dnat \
+ --verbose \
+ --ipaddr="$6"
+ else
+ echo "Invalid IP address"
+ fi
diff --git a/templates-op/show/nat/translations/destination/detail/node.def b/templates-op/show/nat/translations/destination/detail/node.def
new file mode 100644
index 0000000..90990f2
--- /dev/null
+++ b/templates-op/show/nat/translations/destination/detail/node.def
@@ -0,0 +1,3 @@
+help: Show active NAT destination translations detail
+run: sudo ${vyatta_bindir}/sudo-users/vyatta-nat-translations.pl --mode=dnat \
+ --verbose
diff --git a/templates-op/show/nat/translations/destination/monitor/detail/node.def b/templates-op/show/nat/translations/destination/monitor/detail/node.def
new file mode 100644
index 0000000..f1d196f
--- /dev/null
+++ b/templates-op/show/nat/translations/destination/monitor/detail/node.def
@@ -0,0 +1,3 @@
+help: Show active NAT destination translations events detail
+run: echo Type control-C to quit
+ sudo /usr/sbin/conntrack -E -g -o xml | ${vyatta_bindir}/sudo-users/vyatta-nat-translations.pl --mode=dnat --pipe --verbose | ${VYATTA_PAGER:-cat}
diff --git a/templates-op/show/nat/translations/destination/monitor/node.def b/templates-op/show/nat/translations/destination/monitor/node.def
new file mode 100644
index 0000000..99cf715
--- /dev/null
+++ b/templates-op/show/nat/translations/destination/monitor/node.def
@@ -0,0 +1,3 @@
+help: Show active NAT destination translations events
+run: echo Type control-C to quit
+ sudo /usr/sbin/conntrack -E -g -o xml | ${vyatta_bindir}/sudo-users/vyatta-nat-translations.pl --mode=dnat --pipe | ${VYATTA_PAGER:-cat}
diff --git a/templates-op/show/nat/translations/destination/node.def b/templates-op/show/nat/translations/destination/node.def
new file mode 100644
index 0000000..347b034
--- /dev/null
+++ b/templates-op/show/nat/translations/destination/node.def
@@ -0,0 +1,2 @@
+help: Show active NAT destination translations
+run: sudo ${vyatta_bindir}/sudo-users/vyatta-nat-translations.pl --mode=dnat
diff --git a/templates-op/show/nat/translations/detail/node.def b/templates-op/show/nat/translations/detail/node.def
new file mode 100644
index 0000000..0635e6d
--- /dev/null
+++ b/templates-op/show/nat/translations/detail/node.def
@@ -0,0 +1,2 @@
+help: Show active NAT translations detail
+run: sudo ${vyatta_bindir}/sudo-users/vyatta-nat-translations.pl --verbose
diff --git a/templates-op/show/nat/translations/node.def b/templates-op/show/nat/translations/node.def
new file mode 100644
index 0000000..f71c365
--- /dev/null
+++ b/templates-op/show/nat/translations/node.def
@@ -0,0 +1,2 @@
+help: Show active NAT translations
+run: sudo ${vyatta_bindir}/sudo-users/vyatta-nat-translations.pl
diff --git a/templates-op/show/nat/translations/source/address/node.def b/templates-op/show/nat/translations/source/address/node.def
new file mode 100644
index 0000000..42bfbba
--- /dev/null
+++ b/templates-op/show/nat/translations/source/address/node.def
@@ -0,0 +1 @@
+help: Show active NAT source translations for a IP address
diff --git a/templates-op/show/nat/translations/source/address/node.tag/node.def b/templates-op/show/nat/translations/source/address/node.tag/node.def
new file mode 100644
index 0000000..0271dd1
--- /dev/null
+++ b/templates-op/show/nat/translations/source/address/node.tag/node.def
@@ -0,0 +1,11 @@
+help: Show active NAT source translations for an IP address
+allowed: echo -n '<x.x.x.x>'
+run: if /opt/vyatta/sbin/vyatta-validate-type.pl -q ipv4 $6
+ then
+ sudo ${vyatta_bindir}/sudo-users/vyatta-nat-translations.pl \
+ --mode=snat \
+ --verbose \
+ --ipaddr="$6"
+ else
+ echo "Invalid IP address"
+ fi
diff --git a/templates-op/show/nat/translations/source/detail/node.def b/templates-op/show/nat/translations/source/detail/node.def
new file mode 100644
index 0000000..5f8af5b
--- /dev/null
+++ b/templates-op/show/nat/translations/source/detail/node.def
@@ -0,0 +1,3 @@
+help: Show active NAT source translations detail
+run: sudo ${vyatta_bindir}/sudo-users/vyatta-nat-translations.pl --mode=snat \
+ --verbose
diff --git a/templates-op/show/nat/translations/source/monitor/detail/node.def b/templates-op/show/nat/translations/source/monitor/detail/node.def
new file mode 100644
index 0000000..cadd4bf
--- /dev/null
+++ b/templates-op/show/nat/translations/source/monitor/detail/node.def
@@ -0,0 +1,3 @@
+help: Show active NAT source translations events
+run: echo Type control-C to quit
+ sudo /usr/sbin/conntrack -E -n -o xml | ${vyatta_bindir}/sudo-users/vyatta-nat-translations.pl --mode=snat --pipe --verbose | ${VYATTA_PAGER:-cat} \ No newline at end of file
diff --git a/templates-op/show/nat/translations/source/monitor/node.def b/templates-op/show/nat/translations/source/monitor/node.def
new file mode 100644
index 0000000..b1fced2
--- /dev/null
+++ b/templates-op/show/nat/translations/source/monitor/node.def
@@ -0,0 +1,3 @@
+help: Show active NAT source translations events
+run: echo Type control-C to quit
+ sudo /usr/sbin/conntrack -E -n -o xml | ${vyatta_bindir}/sudo-users/vyatta-nat-translations.pl --mode=snat --pipe | ${VYATTA_PAGER:-cat}
diff --git a/templates-op/show/nat/translations/source/node.def b/templates-op/show/nat/translations/source/node.def
new file mode 100644
index 0000000..c14c955
--- /dev/null
+++ b/templates-op/show/nat/translations/source/node.def
@@ -0,0 +1,2 @@
+help: Show active NAT source translations
+run: sudo ${vyatta_bindir}/sudo-users/vyatta-nat-translations.pl --mode=snat