diff --git a/examples/interface_print.php b/examples/interface_print.php new file mode 100644 index 0000000..31532f5 --- /dev/null +++ b/examples/interface_print.php @@ -0,0 +1,28 @@ +set('host', '192.168.1.3') + ->set('user', 'admin') + ->set('pass', 'admin'); + +// Initiate client with config object +$client = new Client($config); + +// Build query +$query = new Query('/interface/getall'); + +// Send query to RouterOS +$request = $client->write($query); + +// Read answer from RouterOS +$response = $client->read(); +print_r($response); diff --git a/examples/ip_address_print.php b/examples/ip_address_print.php index e52b589..dcb0e5c 100644 --- a/examples/ip_address_print.php +++ b/examples/ip_address_print.php @@ -25,4 +25,4 @@ $request = $client->write($query); // Read answer from RouterOS $response = $client->read(); -var_dump($response); +print_r($response); diff --git a/examples/system_packag_print.php b/examples/system_packag_print.php new file mode 100644 index 0000000..6200e3c --- /dev/null +++ b/examples/system_packag_print.php @@ -0,0 +1,28 @@ +set('host', '192.168.1.3') + ->set('user', 'admin') + ->set('pass', 'admin'); + +// Initiate client with config object +$client = new Client($config); + +// Build query +$query = new Query('/system/package/getall'); + +// Send query to RouterOS +$request = $client->write($query); + +// Read answer from RouterOS +$response = $client->read2(); +print_r($response); diff --git a/src/Client.php b/src/Client.php index 8ed5659..e7006e4 100644 --- a/src/Client.php +++ b/src/Client.php @@ -94,6 +94,46 @@ class Client implements Interfaces\ClientInterface } /** + * Read length of line + * + * @param int $byte + * @return int + */ + private function getLength(int $byte): int + { + // If the first bit is set then we need to remove the first four bits, shift left 8 + // and then read another byte in. + // We repeat this for the second and third bits. + // If the fourth bit is set, we need to remove anything left in the first byte + // and then read in yet another byte. + $length = 0; + if ($byte & 128) { + if (($byte & 192) === 128) { + $length = (($byte & 63) << 8) + \ord(fread($this->_socket, 1)); + } else { + if (($byte & 224) === 192) { + $length = (($byte & 31) << 8) + \ord(fread($this->_socket, 1)); + $length = ($length << 8) + \ord(fread($this->_socket, 1)); + } else { + if (($byte & 240) === 224) { + $length = (($byte & 15) << 8) + \ord(fread($this->_socket, 1)); + $length = ($length << 8) + \ord(fread($this->_socket, 1)); + $length = ($length << 8) + \ord(fread($this->_socket, 1)); + } else { + $length = \ord(fread($this->_socket, 1)); + $length = ($length << 8) + \ord(fread($this->_socket, 1)) * 3; + $length = ($length << 8) + \ord(fread($this->_socket, 1)); + $length = ($length << 8) + \ord(fread($this->_socket, 1)); + } + } + } + } else { + $length = $byte; + } + return $length; + } + + /** * Send write query to RouterOS (with or without tag) * * @param QueryInterface $query @@ -113,6 +153,25 @@ class Client implements Interfaces\ClientInterface return $this; } + public function read2(bool $parse = true): array + { + while (true) { + + $res = ''; + while ($buf = fread($this->_socket, 1)) { + if (substr($res, -5) === '!done') { + echo 'done'; + break 2; + } + echo "$buf\n"; + $res .= $buf; + } + $result[] = $res; + } + print_r($result); + die(); + } + /** * Read answer from server after query was executed * @@ -130,8 +189,11 @@ class Client implements Interfaces\ClientInterface // of the remaining reply. $byte = \ord(fread($this->_socket, 1)); + // Read length of line + $length = $this->getLength($byte); + // Save output line to response array - $response[] = stream_get_contents($this->_socket, $byte); + $response[] = stream_get_contents($this->_socket, $length); // If we get a !done line in response, change state of $isDone variable $isDone = ('!done' === end($response)); @@ -157,32 +219,27 @@ class Client implements Interfaces\ClientInterface */ private function parseResponse(array $response): array { - $parsed = []; - $single = null; - $current = null; - foreach ($response as $item) { - if (\in_array($item, ['!fatal', '!re', '!trap'])) { - if ($item === '!re') { - $current =& $parsed[]; - } else { - $current =& $parsed[$item][]; - } - } elseif ($item !== '!done') { - $matches = []; - if (preg_match_all('/^=(.*)=(.*)/', $item, $matches)) { - if ($matches[1][0] === 'ret') { - $single = $matches[2][0]; + print_r($response); + + $result = []; + $i = -1; + foreach ($response as $value) { + switch ($value) { + case '!re': + $i++; + break; + case '!fatal': + case '!trap': + case '!done': + break 2; + default: + if (preg_match_all('/^=(.*)=(.*)/', $value, $matches)) { + $result[$i][$matches[1][0]] = $matches[2][0]; } - $current[$matches[1][0]] = $matches[2][0] ?? ''; - } + break; } } - - if (empty($parsed) && null !== $single) { - $parsed[] = $single; - } - - return $parsed; + return $result; } /**