summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGuillaume Mazoyer <respawneral@gmail.com>2014-12-12 13:01:43 +0100
committerGuillaume Mazoyer <respawneral@gmail.com>2014-12-12 13:01:43 +0100
commit464ae23f92b5056cc1dc1bf7bf701a58187447c3 (patch)
tree4f4cb47d2cd129ec8358fe0c684d6d73ad81b307
parent7436934fe3e1d28ca4c1124ccec5bbcdecdc986f (diff)
Improve 'source-interface-id' option.
On software router, an IPv4 and IPv6 addresses need to be specified. Not specifying one of them or both will result in the router trying to use the best address to contact the destination. This fix the bug where software routers could not ping or traceroute IPv6 destination with only a IPv4 source address (obviously).
-rw-r--r--docs/configuration.md7
-rw-r--r--routers/bird.php152
-rw-r--r--routers/cisco.php58
-rw-r--r--routers/juniper.php71
-rw-r--r--routers/quagga.php152
-rw-r--r--routers/router.php31
6 files changed, 269 insertions, 202 deletions
diff --git a/docs/configuration.md b/docs/configuration.md
index 39257da..3c0061d 100644
--- a/docs/configuration.md
+++ b/docs/configuration.md
@@ -116,9 +116,12 @@ $config['routers']['router1']['source-interface-id'] = 'lo0';
```
for Cisco and Juniper routers (change lo0 with your interface), and with:
```php
-$config['routers']['router1']['source-interface-id'] = '192.168.1.1';
+$config['routers']['router1']['source-interface-id']['ipv4'] = '192.168.1.1';
+$config['routers']['router1']['source-interface-id']['ipv6'] = '2001:db8::1';
```
-for BIRD and Quagga routers (use your own IP address).
+for BIRD and Quagga routers (use your own IP addresses). Omitting the IPv4 or
+the IPv6 version of the source address will result in the router trying to use
+the best IP address to contact the destination.
After that you need to set the authentication information for the looking
glass to be able to log into the router. For this you select a type of
diff --git a/routers/bird.php b/routers/bird.php
index 71a8602..9ee2e7f 100644
--- a/routers/bird.php
+++ b/routers/bird.php
@@ -23,6 +23,72 @@ require_once('router.php');
require_once('includes/utils.php');
final class Bird extends Router {
+ protected function build_ping($destination) {
+ $ping = null;
+
+ if (match_fqdn($destination)) {
+ $fqdn = $destination;
+ $destination = fqdn_to_ip_address($fqdn);
+
+ if (!$destination) {
+ throw new Exception('No A or AAAA record found for '.$fqdn);
+ }
+ }
+
+ if (match_ipv4($destination)) {
+ $ping = 'ping -A -c 10 '.$destination;
+ } else if (match_ipv6($destination)) {
+ $ping = 'ping6 -A -c 10 '.$destination;
+ } else {
+ throw new Exception('The parameter is not an IPv4/IPv6 address or a FQDN.');
+ }
+
+ if (($ping != null) && $this->has_source_interface_id()) {
+ if (match_ipv4($destination) &&
+ ($this->get_source_interface_id('ipv4') != null)) {
+ $ping .= ' -I '.$this->get_source_interface_id('ipv4');
+ } else if (match_ipv6($destination) &&
+ ($this->get_source_interface_id('ipv6') != null)) {
+ $ping .= ' -I '.$this->get_source_interface_id('ipv6');
+ }
+ }
+
+ return $ping;
+ }
+
+ protected function build_traceroute($destination) {
+ $traceroute = null;
+
+ if (match_fqdn($destination)) {
+ $fqdn = $destination;
+ $destination = fqdn_to_ip_address($fqdn);
+
+ if (!$destination) {
+ throw new Exception('No A or AAAA record found for '.$fqdn);
+ }
+ }
+
+ if (match_ipv4($destination)) {
+ $traceroute = 'traceroute -4 -A -q1 -N32 -w1 -m15 '.$destination;
+ } else if (match_ipv6($destination)) {
+ $traceroute = 'traceroute -6 -A -q1 -N32 -w1 -m15 '.$destination;
+ } else {
+ throw new Exception('The parameter is not an IPv4/IPv6 address or a FQDN.');
+ }
+
+ if (($traceroute != null) && $this->has_source_interface_id()) {
+ if (match_ipv4($destination) &&
+ ($this->get_source_interface_id('ipv4') != null)) {
+ $traceroute .= ' -s '.$this->get_source_interface_id('ipv4');
+ } else if (match_ipv6($destination) &&
+ ($this->get_source_interface_id('ipv6') != null)) {
+ $traceroute .= ' -s '.$this->get_source_interface_id('ipv6');
+ }
+ }
+
+ return $traceroute;
+ }
+
protected function build_commands($command, $parameters) {
$commands = array();
@@ -63,88 +129,18 @@ final class Bird extends Router {
break;
case 'ping':
- $append = null;
- if (isset($this->config['source-interface-id'])) {
- $append = ' -I '.$this->config['source-interface-id'];
- }
-
- if (match_ipv4($parameters)) {
- $ping = 'ping -A -c 10 '.$parameters;
- if ($append != null) {
- $ping .= $append;
- }
- $commands[] = $ping;
- } else if (match_ipv6($parameters)) {
- $ping = 'ping6 -A -c 10 '.$parameters;
- if ($append != null) {
- $ping .= $append;
- }
- $commands[] = $ping;
- } else if (match_fqdn($parameters)) {
- $ip_address = fqdn_to_ip_address($parameters);
-
- if (!$ip_address) {
- throw new Exception('No A or AAAA record found for '.$parameters);
- }
-
- if (match_ipv4($ip_address)) {
- $ping = 'ping -A -c 10 '.$parameters;
- if ($append != null) {
- $ping .= $append;
- }
- $commands[] = $ping;
- } else if (match_ipv6($ip_address)) {
- $ping = 'ping6 -A -c 10 '.$parameters;
- if ($append != null) {
- $ping .= $append;
- }
- $commands[] = $ping;
- }
- } else {
- throw new Exception('The parameter is not an IPv4/IPv6 address.');
+ try {
+ $commands[] = $this->build_ping($parameters);
+ } catch (Exception $e) {
+ throw $e;
}
break;
case 'traceroute':
- $append = null;
- if (isset($this->config['source-interface-id'])) {
- $append = ' -s '.$this->config['source-interface-id'];
- }
-
- if (match_ipv4($parameters)) {
- $traceroute = 'traceroute -4 -A -q1 -N32 -w1 -m15 '.$parameters;
- if ($append != null) {
- $traceroute .= $append;
- }
- $commands[] = $traceroute;
- } else if (match_ipv6($parameters)) {
- $traceroute = 'traceroute -6 -A -q1 -N32 -w1 -m15 '.$parameters;
- if ($append != null) {
- $traceroute .= $append;
- }
- $commands[] = $traceroute;
- } else if (match_fqdn($parameters)) {
- $ip_address = fqdn_to_ip_address($parameters);
-
- if (!$ip_address) {
- throw new Exception('No A or AAAA record found for '.$parameters);
- }
-
- if (match_ipv4($ip_address)) {
- $traceroute = 'traceroute -4 -A -q1 -N32 -w1 -m15 '.$parameters;
- if ($append != null) {
- $traceroute .= $append;
- }
- $commands[] = $traceroute;
- } else if (match_ipv6($ip_address)) {
- $traceroute = 'traceroute -6 -A -q1 -N32 -w1 -m15 '.$parameters;
- if ($append != null) {
- $traceroute .= $append;
- }
- $commands[] = $traceroute;
- }
- } else {
- throw new Exception('The parameter is not an IPv4/IPv6 address.');
+ try {
+ $commands[] = $this->build_traceroute($parameters);
+ } catch (Exception $e) {
+ throw $e;
}
break;
diff --git a/routers/cisco.php b/routers/cisco.php
index 285653a..5a135c0 100644
--- a/routers/cisco.php
+++ b/routers/cisco.php
@@ -23,6 +23,40 @@ require_once('router.php');
require_once('includes/utils.php');
final class Cisco extends Router {
+ protected function build_ping($destination) {
+ $ping = null;
+
+ if (match_ipv4($destination) || match_ipv6($destination) ||
+ match_fqdn($destination)) {
+ $ping = 'ping '.$destination.' repeat 10';
+ } else {
+ throw new Exception('The parameter is not an IPv4/IPv6 address or a FQDN.');
+ }
+
+ if (($ping != null) && $this->has_source_interface_id()) {
+ $ping .= ' source '.$this->get_source_interface_id();
+ }
+
+ return $ping;
+ }
+
+ protected function build_traceroute($destination) {
+ $traceroute = null;
+
+ if (match_ipv4($destination) || match_ipv6($destination) ||
+ match_fqdn($destination)) {
+ $traceroute = 'traceroute '.$destination;
+ } else {
+ throw new Exception('The parameter is not an IPv4/IPv6 address or a FQDN.');
+ }
+
+ if (($traceroute != null) && $this->has_source_interface_id()) {
+ $traceroute .= ' source '.$this->get_source_interface_id();
+ }
+
+ return $traceroute;
+ }
+
protected function build_commands($command, $parameters) {
$commands = array();
@@ -56,26 +90,18 @@ final class Cisco extends Router {
break;
case 'ping':
- if (match_ipv4($parameters) || match_ipv6($parameters) || match_fqdn($parameters)) {
- $ping = 'ping '.$parameters.' repeat 10';
- if (isset($this->config['source-interface-id'])) {
- $ping .= ' source '.$this->config['source-interface-id'];
- }
- $commands[] = $ping;
- } else {
- throw new Exception('The parameter is not an IPv4/IPv6 address.');
+ try {
+ $commands[] = $this->build_ping($parameters);
+ } catch (Exception $e) {
+ throw $e;
}
break;
case 'traceroute':
- if (match_ipv4($parameters) || match_ipv6($parameters) || match_fqdn($parameters)) {
- $traceroute = 'traceroute '.$parameters;
- if (isset($this->config['source-interface-id'])) {
- $traceroute .= ' source '.$this->config['source-interface-id'];
- }
- $commands[] = $traceroute;
- } else {
- throw new Exception('The parameter is not an IPv4/IPv6 address.');
+ try {
+ $commands[] = $this->build_traceroute($parameters);
+ } catch (Exception $e) {
+ throw $e;
}
break;
diff --git a/routers/juniper.php b/routers/juniper.php
index fefdf1c..88ea182 100644
--- a/routers/juniper.php
+++ b/routers/juniper.php
@@ -23,6 +23,41 @@ require_once('router.php');
require_once('includes/utils.php');
final class Juniper extends Router {
+ protected function build_ping($destination) {
+ $ping = null;
+
+ if (match_ipv4($destination) || match_ipv6($destination) ||
+ match_fqdn($destination)) {
+ $ping = 'ping count 10 rapid '.$destination;
+ } else {
+ throw new Exception('The parameter is not an IPv4/IPv6 address or a FQDN.');
+ }
+
+ if (($ping != null) && $this->has_source_interface_id()) {
+ $ping .= ' interface '.$this->get_source_interface_id();
+ }
+
+ return $ping;
+ }
+
+ protected function build_traceroute($destination) {
+ $traceroute = null;
+
+ if (match_ipv4($destination)) {
+ $traceroute = 'traceroute as-number-lookup '.$destination;
+ } else if (match_ipv6($destination) || match_fqdn($destination)) {
+ $traceroute = 'traceroute '.$destination;
+ } else {
+ throw new Exception('The parameter is not an IPv4/IPv6 address or a FQDN.');
+ }
+
+ if (($traceroute != null) && $this->has_source_interface_id()) {
+ $traceroute .= ' interface '.$this->get_source_interface_id();
+ }
+
+ return $traceroute;
+ }
+
protected function build_commands($command, $parameters) {
$commands = array();
@@ -62,38 +97,18 @@ final class Juniper extends Router {
break;
case 'ping':
- if (match_ipv4($parameters) || match_ipv6($parameters) ||
- match_fqdn($parameters)) {
- $ping = 'ping count 10 rapid '.$parameters;
- if (isset($this->config['source-interface-id'])) {
- $ping .= ' interface '.$this->config['source-interface-id'];
- }
- $commands[] = $ping;
- } else {
- throw new Exception('The parameter is not an IPv4/IPv6 address or a FQDN.');
+ try {
+ $commands[] = $this->build_ping($parameters);
+ } catch (Exception $e) {
+ throw $e;
}
break;
case 'traceroute':
- $append = null;
- if (isset($this->config['source-interface-id'])) {
- $append = ' interface '.$this->config['source-interface-id'];
- }
-
- if (match_ipv4($parameters)) {
- $traceroute = 'traceroute as-number-lookup '.$parameters;
- if ($append != null) {
- $traceroute .= $append;
- }
- $commands[] = $traceroute;
- } else if (match_ipv6($parameters) || match_fqdn($parameters)) {
- $traceroute = 'traceroute '.$parameters;
- if ($append != null) {
- $traceroute .= $append;
- }
- $commands[] = $traceroute;
- } else {
- throw new Exception('The parameter is not an IPv4/IPv6 address or a FQDN.');
+ try {
+ $commands[] = $this->build_traceroute($parameters);
+ } catch (Exception $e) {
+ throw $e;
}
break;
diff --git a/routers/quagga.php b/routers/quagga.php
index d12c9e3..3dea33b 100644
--- a/routers/quagga.php
+++ b/routers/quagga.php
@@ -23,6 +23,72 @@ require_once('router.php');
require_once('includes/utils.php');
final class Quagga extends Router {
+ protected function build_ping($destination) {
+ $ping = null;
+
+ if (match_fqdn($destination)) {
+ $fqdn = $destination;
+ $destination = fqdn_to_ip_address($fqdn);
+
+ if (!$destination) {
+ throw new Exception('No A or AAAA record found for '.$fqdn);
+ }
+ }
+
+ if (match_ipv4($destination)) {
+ $ping = 'ping -A -c 10 '.$destination;
+ } else if (match_ipv6($destination)) {
+ $ping = 'ping6 -A -c 10 '.$destination;
+ } else {
+ throw new Exception('The parameter is not an IPv4/IPv6 address or a FQDN.');
+ }
+
+ if (($ping != null) && $this->has_source_interface_id()) {
+ if (match_ipv4($destination) &&
+ ($this->get_source_interface_id('ipv4') != null)) {
+ $ping .= ' -I '.$this->get_source_interface_id('ipv4');
+ } else if (match_ipv6($destination) &&
+ ($this->get_source_interface_id('ipv6') != null)) {
+ $ping .= ' -I '.$this->get_source_interface_id('ipv6');
+ }
+ }
+
+ return $ping;
+ }
+
+ protected function build_traceroute($destination) {
+ $traceroute = null;
+
+ if (match_fqdn($destination)) {
+ $fqdn = $destination;
+ $destination = fqdn_to_ip_address($fqdn);
+
+ if (!$destination) {
+ throw new Exception('No A or AAAA record found for '.$fqdn);
+ }
+ }
+
+ if (match_ipv4($destination)) {
+ $traceroute = 'traceroute -4 -A -q1 -N32 -w1 -m15 '.$destination;
+ } else if (match_ipv6($destination)) {
+ $traceroute = 'traceroute -6 -A -q1 -N32 -w1 -m15 '.$destination;
+ } else {
+ throw new Exception('The parameter is not an IPv4/IPv6 address or a FQDN.');
+ }
+
+ if (($traceroute != null) && $this->has_source_interface_id()) {
+ if (match_ipv4($destination) &&
+ ($this->get_source_interface_id('ipv4') != null)) {
+ $traceroute .= ' -s '.$this->get_source_interface_id('ipv4');
+ } else if (match_ipv6($destination) &&
+ ($this->get_source_interface_id('ipv6') != null)) {
+ $traceroute .= ' -s '.$this->get_source_interface_id('ipv6');
+ }
+ }
+
+ return $traceroute;
+ }
+
protected function build_commands($command, $parameters) {
$commands = array();
@@ -58,88 +124,18 @@ final class Quagga extends Router {
break;
case 'ping':
- $append = null;
- if (isset($this->config['source-interface-id'])) {
- $append = ' -I '.$this->config['source-interface-id'];
- }
-
- if (match_ipv4($parameters)) {
- $ping = 'ping -A -c 10 '.$parameters;
- if ($append != null) {
- $ping .= $append;
- }
- $commands[] = $ping;
- } else if (match_ipv6($parameters)) {
- $ping = 'ping6 -A -c 10 '.$parameters;
- if ($append != null) {
- $ping .= $append;
- }
- $commands[] = $ping;
- } else if (match_fqdn($parameters)) {
- $ip_address = fqdn_to_ip_address($parameters);
-
- if (!$ip_address) {
- throw new Exception('No A or AAAA record found for '.$parameters);
- }
-
- if (match_ipv4($ip_address)) {
- $ping = 'ping -A -c 10 '.$parameters;
- if ($append != null) {
- $ping .= $append;
- }
- $commands[] = $ping;
- } else if (match_ipv6($ip_address)) {
- $ping = 'ping6 -A -c 10 '.$parameters;
- if ($append != null) {
- $ping .= $append;
- }
- $commands[] = $ping;
- }
- } else {
- throw new Exception('The parameter is not an IPv4/IPv6 address.');
+ try {
+ $commands[] = $this->build_ping($parameters);
+ } catch (Exception $e) {
+ throw $e;
}
break;
case 'traceroute':
- $append = null;
- if (isset($this->config['source-interface-id'])) {
- $append = ' -s '.$this->config['source-interface-id'];
- }
-
- if (match_ipv4($parameters)) {
- $traceroute = 'traceroute -4 -A -q1 -N32 -w1 -m15 '.$parameters;
- if ($append != null) {
- $traceroute .= $append;
- }
- $commands[] .= $traceroute;
- } else if (match_ipv6($parameters)) {
- $traceroute = 'traceroute -6 -A -q1 -N32 -w1 -m15 '.$parameters;
- if ($append != null) {
- $traceroute .= $append;
- }
- $commands[] = $traceroute;
- } else if (match_fqdn($parameters)) {
- $ip_address = fqdn_to_ip_address($parameters);
-
- if (!$ip_address) {
- throw new Exception('No A or AAAA record found for '.$parameters);
- }
-
- if (match_ipv4($ip_address)) {
- $traceroute = 'traceroute -4 -A -q1 -N32 -w1 -m15 '.$parameters;
- if ($append != null) {
- $traceroute .= $append;
- }
- $commands[] .= $traceroute;
- } else if (match_ipv6($ip_address)) {
- $traceroute = 'traceroute -6 -A -q1 -N32 -w1 -m15 '.$parameters;
- if ($append != null) {
- $traceroute .= $append;
- }
- $commands[] = $traceroute;
- }
- } else {
- throw new Exception('The parameter is not an IPv4/IPv6 address.');
+ try {
+ $commands[] = $this->build_traceroute($parameters);
+ } catch (Exception $e) {
+ throw $e;
}
break;
diff --git a/routers/router.php b/routers/router.php
index c878342..d68c2f4 100644
--- a/routers/router.php
+++ b/routers/router.php
@@ -77,6 +77,37 @@ abstract class Router {
return $displayable;
}
+ protected function has_source_interface_id() {
+ return isset($this->config['source-interface-id']);
+ }
+
+ protected function get_source_interface_id($ip_version = null) {
+ // No source interface ID specified
+ if (!$this->has_source_interface_id()) {
+ return null;
+ }
+
+ $source_interface_id = $this->config['source-interface-id'];
+
+ // Generic interface ID (interface name)
+ if (!is_array($source_interface_id)) {
+ return $source_interface_id;
+ }
+
+ // Composed interface ID (IPv4 and IPv6 address)
+ if (($ip_version == null) || ($ip_version == 'ipv4')) {
+ return $source_interface_id['ipv4'];
+ } else if ($ip_version == 'ipv6') {
+ return $source_interface_id['ipv6'];
+ }
+
+ return null;
+ }
+
+ protected abstract function build_ping($destination);
+
+ protected abstract function build_traceroute($destination);
+
protected abstract function build_commands($command, $parameters);
public function send_command($command, $parameters) {