diff options
author | Guillaume Mazoyer <respawneral@gmail.com> | 2014-12-12 13:01:43 +0100 |
---|---|---|
committer | Guillaume Mazoyer <respawneral@gmail.com> | 2014-12-12 13:01:43 +0100 |
commit | 464ae23f92b5056cc1dc1bf7bf701a58187447c3 (patch) | |
tree | 4f4cb47d2cd129ec8358fe0c684d6d73ad81b307 | |
parent | 7436934fe3e1d28ca4c1124ccec5bbcdecdc986f (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.md | 7 | ||||
-rw-r--r-- | routers/bird.php | 152 | ||||
-rw-r--r-- | routers/cisco.php | 58 | ||||
-rw-r--r-- | routers/juniper.php | 71 | ||||
-rw-r--r-- | routers/quagga.php | 152 | ||||
-rw-r--r-- | routers/router.php | 31 |
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) { |