Skip to content
Permalink
Browse files

Rework command building mechanism.

This is just housekeeping (that may introduce some issues of course). This
should help keeping the codebase a little bit cleaner.
  • Loading branch information...
respawner committed Feb 20, 2019
1 parent aeb57bc commit 40e002148ef507266cad7fe05b3e060c488976f4
@@ -1,10 +1,10 @@
language: php

php:
- 5.6
- 7.0
- 7.1
- 7.2
- 7.3
- hhvm

matrix:
@@ -0,0 +1,74 @@
<?php
/*
* Looking Glass - An easy to deploy Looking Glass
* Copyright (C) 2019 Guillaume Mazoyer <gmazoyer@gravitons.in>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
class CommandBuilder {
private $elements;
public function __construct() {
// Use an array instead of a string to help in element manipulations
$this->elements = array();
// Add elements given in constructor.
for ($i = 0; $i < func_num_args(); $i++) {
$this->add(func_get_arg($i));
}
}
/**
* Adds given parameters to the command.
*
* There are no parameters in this function signature but it stil uses them.
*
* @return CommandBuilder the instance used when calling this function.
*/
public function add() {
$this->elements = array_merge($this->elements, func_get_args());
return $this;
}
/**
* Returns a string of all the elements that have been used in the builder.
* Elements will be separated from each other by the given separator.
*
* @param string $separator the string to use as a separator, the default
* value is one space.
* @return string a single string containing all elements separated by a
* separator.
*/
public function to_string($separator = ' ') {
$string = '';
foreach ($this->elements as $element) {
$string .= $separator.$element;
}
return $string;
}
/**
* Returns a string of all the elements that have been used in the builder.
*
* @return string a single string with all elements separated by spaces.
*/
public function __toString() {
return $this->to_string();
}
}
// End of command_builder.php
@@ -138,16 +138,16 @@ function set_defaults_for_routers(&$parsed_config) {
// Tools used for some processing
'tools' => array(
// Options to be used when pinging from a UNIX host (case of BIRD
// and Quagga)
// Options to be used when pinging from a UNIX host (case of BIRD, Quagga,
// and others)
'ping_options' => '-A -c 10',
// Source option to use when pinging
'ping_source_option' => '-I',
// Traceroute tool to be used
'traceroute4' => 'traceroute -4',
'traceroute6' => 'traceroute -6',
// Options to be used when tracerouting from a UNIX host (case of BIRD
// and Quagga)
// Options to be used when tracerouting from a UNIX host (case of BIRD,
// Quagga, and others)
'traceroute_options' => '-A -q1 -N32 -w1 -m15',
// Source option to use when tracerouting
'traceroute_source_option' => '-s'
@@ -335,4 +335,14 @@ function log_to_file($log) {
file_put_contents($config['logs']['file'], $log, FILE_APPEND | LOCK_EX);
}
/**
* Return the given string surrounded by quotes.
*
* @param string $string the string to be quoted.
* @return string a string with double quotes at the beginning and at the end.
*/
function quote($string) {
return sprintf('"%s"', $string);
}
// End of utils.php
@@ -19,162 +19,65 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
require_once('router.php');
require_once('unix.php');
require_once('includes/command_builder.php');
require_once('includes/utils.php');
final class Bird extends Router {
protected function build_ping($destination) {
$ping = null;
if (match_hostname($destination)) {
$hostname = $destination;
$destination = hostname_to_ip_address($hostname, $this->config);
if (!$destination) {
throw new Exception('No record found for '.$hostname);
}
}
if (match_ipv6($destination)) {
$ping = 'ping6 '.$this->global_config['tools']['ping_options'].' '.
(isset($hostname) ? $hostname : $destination);
} else if (match_ipv4($destination)) {
$ping = 'ping '.$this->global_config['tools']['ping_options'].' '.
(isset($hostname) ? $hostname : $destination);
} else {
throw new Exception('The parameter does not resolve to an IP address.');
}
if (($ping != null) && $this->has_source_interface_id()) {
if (match_ipv6($destination) &&
($this->get_source_interface_id('ipv6') != null)) {
$ping .= ' '.$this->global_config['tools']['ping_source_option'].' '.
$this->get_source_interface_id('ipv6');
} else if (match_ipv4($destination) &&
($this->get_source_interface_id('ipv4') != null)) {
$ping .= ' '.$this->global_config['tools']['ping_source_option'].' '.
$this->get_source_interface_id('ipv4');
}
}
return $ping;
final class Bird extends UNIX {
private function get_bird_binary($ipv6 = true) {
return $ipv6 ? 'birdc6' : 'birdc';
}
protected function build_traceroute($destination) {
$traceroute = null;
private function get_aspath($parameter) {
$commands = array();
if (match_hostname($destination)) {
$hostname = $destination;
$destination = hostname_to_ip_address($hostname, $this->config);
foreach (array(true, false) as $ipv6_enabled) {
$cmd = new CommandBuilder();
$cmd->add($this->get_bird_binary($ipv6_enabled));
if (!$destination) {
throw new Exception('No record found for '.$hostname);
// Build the command to send to the binary
$cmd->add("'show route where bgp_path ~ [=", $parameter, '=]');
if ($this->config['bgp_detail']) {
$cmd->add('all');
}
}
if (match_ipv6($destination)) {
$traceroute = $this->global_config['tools']['traceroute6'].' '.
$this->global_config['tools']['traceroute_options'].' '.
(isset($hostname) ? $hostname : $destination);
} else if (match_ipv4($destination)) {
$traceroute = $this->global_config['tools']['traceroute4'].' '.
$this->global_config['tools']['traceroute_options'].' '.
(isset($hostname) ? $hostname : $destination);
} else {
throw new Exception('The parameter does not resolve to an IP address.');
}
$cmd("'");
if (($traceroute != null) && $this->has_source_interface_id()) {
if (match_ipv6($destination) &&
($this->get_source_interface_id('ipv6') != null)) {
$traceroute .= ' '.
$this->global_config['tools']['traceroute_source_option'].' '.
$this->get_source_interface_id('ipv6');
} else if (match_ipv4($destination) &&
($this->get_source_interface_id('ipv4') != null)) {
$traceroute .= ' '.
$this->global_config['tools']['traceroute_source_option'].' '.
$this->get_source_interface_id('ipv4');
}
$commands[] = $cmd;
}
return $traceroute;
return $commands;
}
protected function build_commands($command, $parameter) {
$commands = array();
protected function build_bgp($parameter) {
if (!is_valid_ip_address($parameter)) {
throw new Exception('The parameter is not an IP address.');
}
$birdc6 = 'birdc6';
$birdc = 'birdc';
$cmd = new CommandBuilder();
$cmd->add($this->get_bird_binary(match_ipv6($parameter, false)));
// Build the command to send to the binary
$cmd->add("'show route for", $parameter);
if ($this->config['bgp_detail']) {
$bgpdetail = ' all';
} else {
$bgpdetail = '';
$cmd->add('all');
}
$cmd("'");
switch ($command) {
case 'bgp':
if (match_ipv6($parameter, false)) {
$commands[] = $birdc6.' \'show route for '.$parameter.$bgpdetail.'\'';
} else if (match_ipv4($parameter, false)) {
$commands[] = $birdc.' \'show route for '.$parameter.$bgpdetail.'\'';
} else {
throw new Exception('The parameter is not an IP address.');
}
break;
case 'as-path-regex':
if (match_aspath_regexp($parameter)) {
if (!$this->config['disable_ipv6']) {
$commands[] = $birdc6.' \'show route where bgp_path ~ [= '.
$parameter.' =]'.$bgpdetail.'\'';
}
if (!$this->config['disable_ipv4']) {
$commands[] = $birdc.' \'show route where bgp_path ~ [= '.
$parameter.' =]'.$bgpdetail.'\'';
}
} else {
throw new Exception('The parameter is not an AS-Path regular expression.');
}
break;
case 'as':
if (match_as($parameter)) {
if (!$this->config['disable_ipv6']) {
$commands[] = $birdc6.' \'show route where bgp_path ~ [= '.
$parameter.' =]'.$bgpdetail.'\'';
}
if (!$this->config['disable_ipv4']) {
$commands[] = $birdc.' \'show route where bgp_path ~ [= '.
$parameter.' =]'.$bgpdetail.'\'';
}
} else {
throw new Exception('The parameter is not an AS number.');
}
break;
case 'ping':
try {
$commands[] = $this->build_ping($parameter);
} catch (Exception $e) {
throw $e;
}
break;
case 'traceroute':
try {
$commands[] = $this->build_traceroute($parameter);
} catch (Exception $e) {
throw $e;
}
break;
return array($cmd);
}
default:
throw new Exception('Command not supported.');
protected function build_aspath_regexp($parameter) {
if (!match_aspath_regexp($parameter)) {
throw new Exception('The parameter is not an AS-Path regular expression.');
}
return $this->get_aspath($parameter);
}
return $commands;
protected function build_as($parameter) {
if (!match_as($parameter)) {
throw new Exception('The parameter is not an AS number.');
}
return $this->get_aspath($parameter);
}
}
Oops, something went wrong.

0 comments on commit 40e0021

Please sign in to comment.
You can’t perform that action at this time.