summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xscripts/VyattaMisc.pm132
1 files changed, 132 insertions, 0 deletions
diff --git a/scripts/VyattaMisc.pm b/scripts/VyattaMisc.pm
index 45bd7d4..3a083ec 100755
--- a/scripts/VyattaMisc.pm
+++ b/scripts/VyattaMisc.pm
@@ -231,4 +231,136 @@ sub isClusteringEnabled {
}
}
+# $str: string representing a port number
+# returns ($success, $err)
+# $success: 1 if success. otherwise undef
+# $err: error message if failure. otherwise undef
+sub isValidPortNumber {
+ my $str = shift;
+ return (undef, "\"$str\" is not a valid port number")
+ if (!($str =~ /^\d+$/));
+ return (undef, "invalid port \"$str\" (must be between 1 and 65535)")
+ if ($str < 1 || $str > 65535);
+ return (1, undef);
+}
+
+# $str: string representing a port range
+# $sep: separator for range
+# returns ($success, $err)
+# $success: 1 if success. otherwise undef
+# $err: error message if failure. otherwise undef
+sub isValidPortRange {
+ my $str = shift;
+ my $sep = shift;
+ return (undef, "\"$str\" is not a valid port range")
+ if (!($str =~ /^(\d+)$sep(\d+)$/));
+ my ($start, $end) = ($1, $2);
+ my ($success, $err) = isValidPortNumber($start);
+ return (undef, $err) if (!defined($success));
+ ($success, $err) = isValidPortNumber($end);
+ return (undef, $err) if (!defined($success));
+ return (undef, "invalid port range ($end is not greater than $start)")
+ if ($end <= $start);
+ return (1, undef);
+}
+
+my %port_name_hash_tcp = ();
+my %port_name_hash_udp = ();
+sub buildPortNameHash {
+ open(IF, "</etc/services") or return 0;
+ while (<IF>) {
+ s/#.*$//;
+ my $is_tcp = /\d\/tcp\s/;
+ my @names = grep (!/\//, (split /\s/));
+ foreach my $name (@names) {
+ if ($is_tcp) {
+ $port_name_hash_tcp{$name} = 1;
+ } else {
+ $port_name_hash_udp{$name} = 1;
+ }
+ }
+ }
+ close IF;
+ return 1;
+}
+
+# $str: string representing a port name
+# $proto: protocol to check
+# returns ($success, $err)
+# $success: 1 if success. otherwise undef
+# $err: error message if failure. otherwise undef
+sub isValidPortName {
+ my $str = shift;
+ my $proto = shift;
+ return (undef, "\"\" is not a valid port name for protocol \"$proto\"")
+ if ($str eq '');
+ buildPortNameHash() if ((keys %port_name_hash_tcp) == 0);
+ return (1, undef) if ($proto eq 'tcp' && defined($port_name_hash_tcp{$str}));
+ return (1, undef) if ($proto eq '6' && defined($port_name_hash_tcp{$str}));
+ return (1, undef) if ($proto eq 'udp' && defined($port_name_hash_udp{$str}));
+ return (1, undef) if ($proto eq '17' && defined($port_name_hash_udp{$str}));
+ return (undef, "\"$str\" is not a valid port name for protocol \"$proto\"");
+}
+
+sub getPortRuleString {
+ my $port_str = shift;
+ my $can_use_port = shift;
+ my $prefix = shift;
+ my $proto = shift;
+ my $negate = '';
+ if ($port_str =~ /^!(.*)$/) {
+ $port_str = $1;
+ $negate = '! ';
+ }
+ $port_str =~ s/-/:/g;
+
+ my $num_ports = 0;
+ my @port_specs = split /,/, $port_str;
+ foreach my $port_spec (@port_specs) {
+ my ($success, $err) = (undef, undef);
+ if ($port_spec =~ /:/) {
+ ($success, $err) = isValidPortRange($port_spec, ':');
+ if (defined($success)) {
+ $num_ports += 2;
+ next;
+ } else {
+ return (undef, $err);
+ }
+ }
+ if ($port_spec =~ /^\d/) {
+ ($success, $err) = isValidPortNumber($port_spec);
+ if (defined($success)) {
+ $num_ports += 1;
+ next;
+ } else {
+ return (undef, $err);
+ }
+ }
+ ($success, $err) = isValidPortName($port_spec, $proto);
+ if (defined($success)) {
+ $num_ports += 1;
+ next;
+ } else {
+ return (undef, $err);
+ }
+ }
+
+ my $rule_str = '';
+ if (($num_ports > 0) && (!$can_use_port)) {
+ return (undef, "ports can only be specified when protocol is \"tcp\" "
+ . "or \"udp\" (currently \"$proto\")");
+ }
+ if ($num_ports > 15) {
+ return (undef, "source/destination port specification only supports "
+ . "up to 15 ports (port range counts as 2)");
+ }
+ if ($num_ports > 1) {
+ $rule_str = " -m multiport --${prefix}ports ${negate}${port_str}";
+ } elsif ($num_ports > 0) {
+ $rule_str = " --${prefix}port ${negate}${port_str}";
+ }
+
+ return ($rule_str, undef);
+}
+
return 1;