Page 1 of 1
Add new nat rule with PEAR2 PHP
Posted: Tue Oct 22, 2013 10:27 am
by Vyrtu
Hi guys, im scripting a new code to add nat rules on mikrotik, and i need some help :S
This is the code:
php code
<?php
//Listas desplegables
echo "</br>";
//Peticion a la API
$addRequest = $client->sendSync(new RouterOS\Request('/ip/firewall/nat/add'));
echo "<table align='center' border=2 bordercolor='000000'><form action='' method='POST'>";
echo "<tr bgcolor='#D8D8D8'><td align=left size=3>Accion</td><td align=left size=3>Direccion Origen</td><td size=3>Direccion Destino</td>
<td size=3>Protocolo</td><td size=3>Puerto Origen</td><td size=3>Puerto Salida</td><td align=left size=3>Agregar</td></tr>";
echo "<tr>
<td>
<input type='radio' value='srcnat' name='chain'>Src</input>
<input type='radio' value='dstnat' name='chain'>Dst</input></td>
<td>
<select name='src-address'>
<option value='192.168.2.2'>192.168.2.2</option>
<option value='192.168.2.3'>192.168.2.3</option>
<option value='192.168.2.4'>192.168.2.4</option>
<option value='192.168.2.5'>192.168.2.5</option>
</select></td>";
echo "<td><select name='to-addresses'>
<option value='65.23.23.1'>65.23.23.1</option>
<option value='65.23.23.2'>65.23.23.2</option>
<option value='65.23.23.3'>65.23.23.3</option>
<option value='65.23.23.4'>65.23.23.4</option>
</select></td>";
echo "<td><select name='protocol'>
<option value='tcp'>tcp</option>
<option value='udp'>udp</option>
<option value='gre'>gre</option>
<option value='icmp'>icmp</option></td>";
echo "<td><input type='number' min='1' max='65535' name='src-port' value='' /></td>";
echo "<td><input type='number' min='1' max='65535' name='to-ports' value='' /></td>";
echo "<td><button type='submit' name='add' value='add'>Agregar</button></td></tr>";
echo "</form></table>";
I need complete this code, but i dont know how..
P.D: I have this code too:
$addRequest = new RouterOS\Request('/ip/firewall/nat/add');
$addRequest->setArgument('chain', 'dstnat');
$addRequest->setArgument ('protocol', 'tcp');
$addRequest->setArgument('action', 'dst-nat');
$addRequest->setArgument('to-addresses', '192.168.2.3');
$addRequest->setArgument ('to-ports', '4562');
But now, how i can convert this in a form? :S
Thanks
![Smile :)](./images/smilies/icon_smile.gif)
Re: Add new nat rule with PEAR2 PHP
Posted: Tue Oct 22, 2013 2:13 pm
by boen_robot
This line alone
$addRequest = $client->sendSync(new RouterOS\Request('/ip/firewall/nat/add'));
doesn't really add anything, since add requests need to actually contain the properties to be added.
You need to inspect the $_POST array, and convert it to the arguments.
Alternatively, you can just use the Util class, to which you can pass the $_POST array, MINUS anything that isn't property/value pairs to be added. E.g.
php code
<?php
//Listas desplegables
echo "</br>";
$util = new RouterOS\Util($client);
$util->changeMenu('/ip/firewall/nat');
//Peticion a la API
if (isset($_POST['add'])) {
unset($_POST['add']);
if ('' == $util->add($_POST)) {
echo '<div class="error">Failed to add rule</div>';
}
}
echo "<table align='center' border=2 bordercolor='000000'><form action='' method='POST'>";
echo "<tr bgcolor='#D8D8D8'><td align=left size=3>Accion</td><td align=left size=3>Direccion Origen</td><td size=3>Direccion Destino</td>
<td size=3>Protocolo</td><td size=3>Puerto Origen</td><td size=3>Puerto Salida</td><td align=left size=3>Agregar</td></tr>";
echo "<tr>
<td>
<input type='radio' value='srcnat' name='chain'>Src</input>
<input type='radio' value='dstnat' name='chain'>Dst</input></td>
<td>
<select name='src-address'>
<option value='192.168.2.2'>192.168.2.2</option>
<option value='192.168.2.3'>192.168.2.3</option>
<option value='192.168.2.4'>192.168.2.4</option>
<option value='192.168.2.5'>192.168.2.5</option>
</select></td>";
echo "<td><select name='to-addresses'>
<option value='65.23.23.1'>65.23.23.1</option>
<option value='65.23.23.2'>65.23.23.2</option>
<option value='65.23.23.3'>65.23.23.3</option>
<option value='65.23.23.4'>65.23.23.4</option>
</select></td>";
echo "<td><select name='protocol'>
<option value='tcp'>tcp</option>
<option value='udp'>udp</option>
<option value='gre'>gre</option>
<option value='icmp'>icmp</option></td>";
echo "<td><input type='number' min='1' max='65535' name='src-port' value='' /></td>";
echo "<td><input type='number' min='1' max='65535' name='to-ports' value='' /></td>";
echo "<td><button type='submit' name='add' value='add'>Agregar</button></td></tr>";
echo "</form></table>";
(Though keep in mind that with that approach, you don't get the exact error messages from RouterOS - you only know if adding failed or not, but not why)
Re: Add new nat rule with PEAR2 PHP
Posted: Tue Oct 22, 2013 2:29 pm
by Vyrtu
I update the code, and its working, but i have another problem.
In radio buttons, when i choose src(chain srcnat), the action should be src-nat, and when i choose dst(chain dstnat), the action should be dst-nat
When i create a nat rule, it creates with action accept :S
Re: Add new nat rule with PEAR2 PHP
Posted: Tue Oct 22, 2013 2:46 pm
by boen_robot
Well then, simply express what you just said in code, right before you do the adding, i.e.
//Peticion a la API
if (isset($_POST['add'])) {
unset($_POST['add']);
if (isset($_POST['chain'])) {
if ('srcnat' === $_POST['chain']) {
$_POST['action'] = 'src-nat';
} elseif ('dstnat' === $_POST['chain']) {
$_POST['action'] = 'dst-nat';
}
}
if ('' == $util->add($_POST)) {
echo '<div class="error">Failed to add rule</div>';
}
}
Re: Add new nat rule with PEAR2 PHP
Posted: Tue Oct 22, 2013 3:58 pm
by Vyrtu
Hmm.. doesnt work, i post the complete code:
php code
<?php
use PEAR2\Net\RouterOS;
// require_once 'pear2\src\PEAR2\Autoload.php';
require_once 'PEAR2_Net_RouterOS-1.0.0b4.phar';
$client = new RouterOS\Client('192.168.150.161', 'admin', 'admin');
if (isset($_POST['act'])) {
foreach ($_POST['act'] as $act => $itemID) {
//Limit the action only to known ones, for security's sake
if (in_array($act, array('set', 'remove'))) {
$actionRequest = new RouterOS\Request("/ip/firewall/nat/{$act}");
$actionRequest->setArgument('numbers', $itemID);
if ('set' === $act) {
foreach ($_POST[$itemID] as $name => $value) {
$actionRequest->setArgument($name, $value);
}
}
$responses = $client->sendSync($actionRequest);
$errors = $responses->getAllOfType(RouterOS\Response::TYPE_ERROR);
if (0 === count($errors)) {
echo "<div>'{$act}' OK!</div>";
} else {
echo '<div><ul>';
foreach ($errors as $error) {
echo '<li>' . $error('message') . '</li>';
}
echo '</ul></div>';
}
}
}
}
// Tabla
echo "<table align='center' border=2 bordercolor='black'>";
echo "<form action='' method='POST'>";
echo "<tr bgcolor='#D8D8D8'><td align=left size=3>Accion</td><td align=left size=3>Direccion Origen</td><td size=3>Direccion Destino</td><td size=3>Protocolo</td><td size=3>Puerto Origen</td><td size=3>Puerto Salida</td><td align=left size=3>Modificar/Eliminar</td></tr>";
// Peticion a la API
$responses = $client->sendSync(new RouterOS\Request('/ip/firewall/nat/print'));
foreach ($responses as $response) {
if ($response->getType() === RouterOS\Response::TYPE_DATA) {
$id = $response('.id');
echo "<tr>";
echo "<td><input type='text' name='{$id}[action]' value='" . $response('action'). "' /></td>";
echo "<td><input type='text' name='{$id}[src-address]' value='" . $response('src-address'). "' /></td>";
echo "<td><input type='text' name='{$id}[to-addresses]' value='" . $response('to-addresses'). "' /></td>";
echo "<td><select name='{$id}[protocol]'>
<option value='". $response('protocol'). "'>".$response('protocol'). "</option>
<option value=''>--------------</option>
<option value='ddp'>ddp</option>
<option value='egp'>egp</option>
<option value='encap'>encap</option>
<option value='etherip'>etherip</option>
<option value='ggp'>ggp</option>
<option value='gre'>gre</option>
<option value='hmp'>hmp</option>
<option value='icmp'>icmp</option>
<option value='icmpv6'>icmpv6</option>
<option value='idpr-cmtp'>idpr-cmtp</option>
<option value='igmp'>igmp</option>
<option value='ipencap'>ipencap</option>
<option value='ipip'>ipip</option>
<option value='ipsec-ah'>ipsec-ah</option>
<option value='ipsec-esp'>ipsec-esp</option>
<option value='ipv6'>ipv6</option>
<option value='ipv6-frag'>ipv6-frag</option>
<option value='ipv6-nonxt'>ipv6-nonxt</option>
<option value='ipv6-opts'>ipv6-opts</option>
<option value='ipv6-route'>ipv6-route</option>
<option value='iso-tp4'>iso-tp4</option>
<option value='l2tp'>l2tp</option>
<option value='ospf'>ospf</option>
<option value='pim'>pim</option>
<option value='pup'>pup</option>
<option value='rdp'>rdp</option>
<option value='rspf'>rspf</option>
<option value='rsvp'>rsvp</option>
<option value='st'>st</option>
<option value='tcp'>tcp</option>
<option value='udp'>udp</option>
<option value='vmtp'>vmtp</option>
<option value='vrrp'>vrrp</option>
<option value='xns-idp'>xns-idp</option>
<option value='xtp'>xtp</option>
<option value='!'>!</option>
</select></td>";
echo "<td><input type='number' min='1' max='65535' name='{$id}[src-port]' value='" . $response('src-port'). "' /></td>";
echo "<td><input type='number' min='1' max='65535' name='{$id}[to-ports]' value='" . $response('to-ports'). "' /></td>";
//Boton Modificar
echo "<td><button type='submit' name='act[set]' value='{$id}'>Modificar</button>";
//Boton Borrar
echo "<button type='submit' name='act[remove]' value='{$id}'>Eliminar</button></td>";
echo "</tr>";
}
}
echo "</table>";
//Agregar Nat Rule
echo "</br>";
$util = new RouterOS\Util($client);
$util->changeMenu('/ip/firewall/nat');
//Peticion a la API
if (isset($_POST['add'])) {
unset($_POST['add']);
if (isset($_POST['chain'])) {
if ('srcnat' === $_POST['chain']) {
$_POST['action'] = 'src-nat';
} elseif ('dstnat' === $_POST['chain']) {
$_POST['action'] = 'dst-nat';
}
}
if ('' == $util->add($_POST)) {
echo '<div class="error">Failed to add rule</div>';
}
}
echo "<table align='center' border=2 bordercolor='000000'>";
echo "<tr bgcolor='#D8D8D8'><td align=left size=3>Accion</td><td align=left size=3>Direccion Origen</td><td size=3>Direccion Destino</td>
<td size=3>Protocolo</td><td size=3>Puerto Origen</td><td size=3>Puerto Salida</td><td align=left size=3>Agregar</td></tr>";
echo "<tr>
<td>
<input type='radio' value='srcnat' name='chain'>Src</input>
<input type='radio' value='dstnat' name='chain'>Dst</input></td>
<td>
<select name='src-address'>
<option value='192.168.2.2'>192.168.2.2</option>
<option value='192.168.2.3'>192.168.2.3</option>
<option value='192.168.2.4'>192.168.2.4</option>
<option value='192.168.2.5'>192.168.2.5</option>
</select></td>";
echo "<td><select name='to-addresses'>
<option value='65.23.23.1'>65.23.23.1</option>
<option value='65.23.23.2'>65.23.23.2</option>
<option value='65.23.23.3'>65.23.23.3</option>
<option value='65.23.23.4'>65.23.23.4</option>
</select></td>";
echo "<td><select name='protocol'>
<option value=''></option>
<option value='tcp'>tcp</option>
<option value='udp'>udp</option>
<option value='gre'>gre</option>
<option value='icmp'>icmp</option></td>";
echo "<td><input type='number' min='1' max='65535' name='src-port' value='' /></td>";
echo "<td><input type='number' min='1' max='65535' name='to-ports' value='' /></td>";
echo "<td><button type='submit' name='add' value='add'>Agregar</button></td></tr>";
echo "</table></form>";
?>
and the tables is something like that:
http://gyazo.com/5a871e913478c54f35b1435208b9e161
I need add nat rules without values too, without protocol, src and dst ports :S
The first table, with nat rules print, works very well, thanks to u too, but the new table to add new rules no :S
Re: Add new nat rule with PEAR2 PHP
Posted: Tue Oct 22, 2013 4:16 pm
by boen_robot
Wait... you're writing both forms on a single PHP page?
That complicates things a little bit, as you need to unambigiously select one action to do upon submitting, since both codes would be executed.
You could perhaps rename the "add" button to "act" and have its value be "add[]". After that, combining the two processings is a piece of cake:
php code
<?php
use PEAR2\Net\RouterOS;
// require_once 'pear2\src\PEAR2\Autoload.php';
require_once 'PEAR2_Net_RouterOS-1.0.0b4.phar';
$client = new RouterOS\Client('192.168.150.161', 'admin', 'admin');
if (isset($_POST['act'])) {
foreach ($_POST['act'] as $act => $itemID) {
//Limit the action only to known ones, for security's sake
if (in_array($act, array('set', 'remove', 'add'))) {
$actionRequest = new RouterOS\Request("/ip/firewall/nat/{$act}");
if ('add' !== $act) {
$actionRequest->setArgument('numbers', $itemID);
}
if ('set' === $act || 'add' === $act) {
if (isset($_POST[$itemID]['chain'])) {
if ('srcnat' === $_POST[$itemID]['chain']) {
$_POST[$itemID]['action'] = 'src-nat';
} elseif ('dstnat' === $_POST[$itemID]['chain']) {
$_POST[$itemID]['action'] = 'dst-nat';
}
}
foreach ($_POST[$itemID] as $name => $value) {
$actionRequest->setArgument($name, $value);
}
}
$responses = $client->sendSync($actionRequest);
$errors = $responses->getAllOfType(RouterOS\Response::TYPE_ERROR);
if (0 === count($errors)) {
echo "<div>'{$act}' OK!</div>";
} else {
echo '<div><ul>';
foreach ($errors as $error) {
echo '<li>' . $error('message') . '</li>';
}
echo '</ul></div>';
}
}
}
}
// Tabla
echo "<form action='' method='POST'>";
echo "<table align='center' border=2 bordercolor='black'>";
echo "<tr bgcolor='#D8D8D8'><td align=left size=3>Accion</td><td align=left size=3>Direccion Origen</td><td size=3>Direccion Destino</td><td size=3>Protocolo</td><td size=3>Puerto Origen</td><td size=3>Puerto Salida</td><td align=left size=3>Modificar/Eliminar</td></tr>";
// Peticion a la API
$responses = $client->sendSync(new RouterOS\Request('/ip/firewall/nat/print'));
foreach ($responses as $response) {
if ($response->getType() === RouterOS\Response::TYPE_DATA) {
$id = $response('.id');
echo "<tr>";
echo "<td><input type='text' name='{$id}[action]' value='" . $response('action'). "' /></td>";
echo "<td><input type='text' name='{$id}[src-address]' value='" . $response('src-address'). "' /></td>";
echo "<td><input type='text' name='{$id}[to-addresses]' value='" . $response('to-addresses'). "' /></td>";
echo "<td><select name='{$id}[protocol]'>
<option value='". $response('protocol'). "'>".$response('protocol'). "</option>
<option value=''>--------------</option>
<option value='ddp'>ddp</option>
<option value='egp'>egp</option>
<option value='encap'>encap</option>
<option value='etherip'>etherip</option>
<option value='ggp'>ggp</option>
<option value='gre'>gre</option>
<option value='hmp'>hmp</option>
<option value='icmp'>icmp</option>
<option value='icmpv6'>icmpv6</option>
<option value='idpr-cmtp'>idpr-cmtp</option>
<option value='igmp'>igmp</option>
<option value='ipencap'>ipencap</option>
<option value='ipip'>ipip</option>
<option value='ipsec-ah'>ipsec-ah</option>
<option value='ipsec-esp'>ipsec-esp</option>
<option value='ipv6'>ipv6</option>
<option value='ipv6-frag'>ipv6-frag</option>
<option value='ipv6-nonxt'>ipv6-nonxt</option>
<option value='ipv6-opts'>ipv6-opts</option>
<option value='ipv6-route'>ipv6-route</option>
<option value='iso-tp4'>iso-tp4</option>
<option value='l2tp'>l2tp</option>
<option value='ospf'>ospf</option>
<option value='pim'>pim</option>
<option value='pup'>pup</option>
<option value='rdp'>rdp</option>
<option value='rspf'>rspf</option>
<option value='rsvp'>rsvp</option>
<option value='st'>st</option>
<option value='tcp'>tcp</option>
<option value='udp'>udp</option>
<option value='vmtp'>vmtp</option>
<option value='vrrp'>vrrp</option>
<option value='xns-idp'>xns-idp</option>
<option value='xtp'>xtp</option>
<option value='!'>!</option>
</select></td>";
echo "<td><input type='number' min='1' max='65535' name='{$id}[src-port]' value='" . $response('src-port'). "' /></td>";
echo "<td><input type='number' min='1' max='65535' name='{$id}[to-ports]' value='" . $response('to-ports'). "' /></td>";
//Boton Modificar
echo "<td><button type='submit' name='act[set]' value='{$id}'>Modificar</button>";
//Boton Borrar
echo "<button type='submit' name='act[remove]' value='{$id}'>Eliminar</button></td>";
echo "</tr>";
}
}
echo "</table></form>";
//Agregar Nat Rule
echo "</br>";
echo "<form action='' method='POST'>";
echo "<table align='center' border=2 bordercolor='000000'>";
echo "<tr bgcolor='#D8D8D8'><td align=left size=3>Accion</td><td align=left size=3>Direccion Origen</td><td size=3>Direccion Destino</td>
<td size=3>Protocolo</td><td size=3>Puerto Origen</td><td size=3>Puerto Salida</td><td align=left size=3>Agregar</td></tr>";
echo "<tr>
<td>
<input type='radio' value='srcnat' name='*[chain]'>Src</input>
<input type='radio' value='dstnat' name='*[chain]'>Dst</input></td>
<td>
<select name='*[src-address]'>
<option value='192.168.2.2'>192.168.2.2</option>
<option value='192.168.2.3'>192.168.2.3</option>
<option value='192.168.2.4'>192.168.2.4</option>
<option value='192.168.2.5'>192.168.2.5</option>
</select></td>";
echo "<td><select name='*[to-addresses]'>
<option value='65.23.23.1'>65.23.23.1</option>
<option value='65.23.23.2'>65.23.23.2</option>
<option value='65.23.23.3'>65.23.23.3</option>
<option value='65.23.23.4'>65.23.23.4</option>
</select></td>";
echo "<td><select name='*[protocol]'>
<option value=''></option>
<option value='tcp'>tcp</option>
<option value='udp'>udp</option>
<option value='gre'>gre</option>
<option value='icmp'>icmp</option></td>";
echo "<td><input type='number' min='1' max='65535' name='*[src-port]' value='' /></td>";
echo "<td><input type='number' min='1' max='65535' name='*[to-ports]' value='' /></td>";
echo "<td><button type='submit' name='act[add]' value='*'>Agregar</button></td></tr>";
echo "</table></form>";
?>
Re: Add new nat rule with PEAR2 PHP
Posted: Tue Oct 22, 2013 4:41 pm
by Vyrtu
The script looks good, but when i try add a new rule, doesnt work and alerts me ("failure: no chain specified")
Re: Add new nat rule with PEAR2 PHP
Posted: Tue Oct 22, 2013 4:51 pm
by boen_robot
Apparently, an empty key name is not allowed... try the above now (where I've added a "*" in front of all fields on adding; I've also corrected the form itself - it should start before the table, and I've made the add form separate to avoid sending everything else when adding).
Re: Add new nat rule with PEAR2 PHP
Posted: Tue Oct 22, 2013 5:10 pm
by Vyrtu
It adds the rule with 'accept' action, and when i refresh the page, it adds again the same rule..
Re: Add new nat rule with PEAR2 PHP
Posted: Tue Oct 22, 2013 5:30 pm
by boen_robot
Opps. I missed altering the "chain" pre-processing bit...
I've fixed it above.
Re: Add new nat rule with PEAR2 PHP
Posted: Tue Oct 22, 2013 6:12 pm
by Vyrtu
Working, but we still have 2 problems, when i refresh after add, it add a new same rule, and i cant add new rule without protocol and ports. In winbox we can..
Re: Add new nat rule with PEAR2 PHP
Posted: Tue Oct 22, 2013 8:04 pm
by boen_robot
For the duplicate adding issue, replace
if (0 === count($errors)) {
echo "<div>'{$act}' OK!</div>";
with
if (0 === count($errors)) {
header('Location: http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
return;
The redirect will force the browser to go back to the same page, but without any $_POST data following it. We do this only on success, since you may otherwise try to retry a previously failed request by refreshing the page.
An for the adding without empty values issue, replace
foreach ($_POST[$itemID] as $name => $value) {
$actionRequest->setArgument($name, $value);
}
with
foreach ($_POST[$itemID] as $name => $value) {
if ('' != $value) {
$actionRequest->setArgument($name, $value);
}
}
Re: Add new nat rule with PEAR2 PHP
Posted: Wed Oct 23, 2013 10:44 am
by Vyrtu
Perfect, its working very well, thanks you so much again
![Smile :)](./images/smilies/icon_smile.gif)