[SOLVED] Ping Via API

Hi.. i’m trying to do a ping via API, but i’m not getting to ping more than one time…

$API->write('/ping',false);
     $API->write("=address=$NASIPAddress"); 
     $API->write('=count=3');
     $API->write('=interval=1');
     $API->write('=ret=');
     $ARRAY4 = $API->read(false);
    print_r($ARRAY4);

I put =count=3 , because I need the avg from the ping…

but look the return of command

Array ( 
 [0] => !trap 
 [1] => =message=no such command prefix 
 [2] => !done
 [3] => !trap 
 [4] => =message=no such command prefix 
 [5] => !done 
 [6] => !trap 
 [7] => =message=no such command prefix 
 [8] => !done 
 [9] => !re 
 [10] => =host=192.168.2.5
 [11] => =size=56 
 [12] => =ttl=64 
 [13] => =time=00:00:00.001 
[b][color=#FF0000] [14] => =sent=1 [/color][/b]  (I put 3 on count... and its sending one..)
 [15] => =received=1
 [16] => =packet-loss=0 
 [17] => =min-rtt=00:00:00.001 
 [18] => =avg-rtt=00:00:00.001 
 [19] => =max-rtt=00:00:00.001 
)

Sorry I can’t help you with the PHP API library. But for anyone using the Ruby API library, it looks like:

require irb(main):001:0> require 'mtik'
=> true
irb(main):002:0> con = MTik::Connection.new(:host=>'10.0.0.1',:user=>'user',:pass=>'password')
=> #<MTik::Connection:0x000001009d2c80 @sock=#<TCPSocket:fd 5>, @requests={}, @host="10.0.0.1", @port=8728, @user="user", @pass="password", @conn_timeout=60, @cmd_timeout=60, @data="", @parsing=false>
irb(main):003:0> r = con.get_reply('/ping','=address=10.0.0.2','=count=3')
=> [{"!re"=>nil, "host"=>"10.0.0.2", "size"=>"56", "ttl"=>"255", "time"=>"00:00:00.006", "sent"=>"1", "received"=>"1", "packet-loss"=>"0", "min-rtt"=>"00:00:00.006", "avg-rtt"=>"00:00:00.006", "max-rtt"=>"00:00:00.006", ".tag"=>"6"}, {"!re"=>nil, "host"=>"10.0.0.2", "size"=>"56", "ttl"=>"255", "time"=>"00:00:00.003", "sent"=>"2", "received"=>"2", "packet-loss"=>"0", "min-rtt"=>"00:00:00.003", "avg-rtt"=>"00:00:00.004", "max-rtt"=>"00:00:00.006", ".tag"=>"6"}, {"!re"=>nil, "host"=>"10.0.0.1", "size"=>"56", "ttl"=>"255", "time"=>"00:00:00.003", "sent"=>"3", "received"=>"3", "packet-loss"=>"0", "min-rtt"=>"00:00:00.003", "avg-rtt"=>"00:00:00.004", "max-rtt"=>"00:00:00.006", ".tag"=>"6"}, {"!done"=>nil, ".tag"=>"6"}]
irb(main):004:0> puts "MINIMUM: #{r[-2]['min-rtt']}\tMAXIMUM #{r[-2]['max-rtt']}\tAVERAGE: #{r[-2]['avg-rtt']}"
MINIMUM: 00:00:00.003	MAXIMUM 00:00:00.006	AVERAGE: 00:00:00.004
=> nil

Or a Ruby script that takes 4 or 5 arguments, the MikroTik device IP to execute the API command, the username to authenticate as, the password, the IP to ping, and an optional integer ping packet count:

#!/usr/bin/env ruby

require 'mtik'

con    = MTik::Connection.new(:host => ARGV[0], :user => ARGV[1], :pass => ARGV[2])
count  = ARGV[4] || '5'
count  = count.to_i
result = con.get_reply('/ping', "=address=#{ARGV[3]}", "=count=#{count}")
sent     = result[-2]['sent'].to_i
received = result[-2]['received'].to_i
loss     = 100.0 * (sent - received) / sent.to_f
min      = result[-2]['min-rtt'] || '-'
max      = result[-2]['max-rtt'] || '-'
avg      = result[-2]['avg-rtt'] || '-'
puts "PING FROM #{ARGV[0]} => #{ARGV[3]} (#{count} packets):"
puts "SENT: #{sent}\tRECEIVED: #{received}\tPACKET LOSS: #{loss}%\tMINIMUM: #{min}\tMAXIMUM #{max}\tAVERAGE: #{avg}"

If the above script were named pingscript.rb in the current working directory, one might use it from a 'nix shell like this:

user@host:~$ ./pingscript.rb 10.0.0.1 'user' 'password' 10.0.0.2
PING FROM 10.0.0.1 => 10.0.0.2 (5 packets):
SENT: 5	RECEIVED: 5	PACKET LOSS: 0.0%	MINIMUM: 00:00:00.002	MAXIMUM 00:00:00.005	AVERAGE: 00:00:00.003
user@host:~$ ./pingscript.rb 10.0.0.1 'user' 'password' 10.0.0.2 20
PING FROM 10.0.0.1 => 10.0.0.2 (20 packets):
SENT: 20	RECEIVED: 20	PACKET LOSS: 0.0%	MINIMUM: 00:00:00.002	MAXIMUM 00:00:00.006	AVERAGE: 00:00:00.004
user@host:~$

in your code have "“sent”=>“3"”


in my I put 3 on count… but just sent one…

and I need to use src-address…

but.. don’t work…

I need to do

/ping count=3 src-address=192.168.1.1 address=192.168.1.2

via api…

Try This:

...init and conect ....
$API->write('/ping',false);
$API->write('=address=8.8.8.8',false); 
$API->write('=count=3',false);
$API->write('=interval=1');
$ARRAY4 = $API->read(false);
echo "<pre>". print_r($ARRAY4) ." </pre>";
$API->disconnect();

M.

and how to use the src-addres?

ping src-address=192.168.1.1 address=192.168.1.2

Just add src-address option

  $API->write('=src-address=192.168.1.1',false);

M.

I put this code

$API->write('/ping',false);
$API->write('=src-address=192.168.1.1',false);
$API->write('=address=192.168.1.2',false);
$API->write('=count=5',false);
$API->write('=interval=1');
$ARRAY4 = $API->read(false);
echo "<pre>". print_r($ARRAY4) ." </pre>";

but.. doesn’t work… stay loading… and don’t show anything

if I remove this line… works fine…

$API->write('=src-address=192.168.1.1',false);

if it works, give me karma :stuck_out_tongue:

M.

its working without $API->write(‘=src-address=192.168.1.1’,false);

i need to do with src-address but =\ dont work

My Code

$API->write('/ping',false);
$API->write("=src-address=192.168.1.1");	
$API->write("=address=192.168.1.2");	
$API->write('=count=3');
$API->write('=interval=2');
$API->write('=ret=');

its right? and don’t know How to use src-address

You need a ‘false’ as the second parameter to each write except the last one.

$API->write('/ping',false);    // send ping command and more is coming
$API->write('=src-address=192.168.1.1',false);   //more after this.
$API->write('=address=192.168.1.2',false);    //more...	
$API->write('=count=3',false);   //more...
$API->write('=interval=2');   // no false as this is the last write for this command.

look

without this line everything works fine…

I removed this line >

$API->write('=src-address=192.168.1.1',false);   //more after this.



$API->write('/ping',false);    // send ping command and more is coming
$API->write('=address=192.168.1.2',false);    //more...   
$API->write('=count=3',false);   //more...
$API->write('=interval=2');   // no false as this is the last write for this command.

but I need to put a src-addres because I need to test from server to mikrotik…

it is not clear for me what direction you want to ping? All you do is send ping from A to B, where A is router and B is your target, that hopefully responds to ICMP packets

And that is that, all you can check ir RTT from A to B and back and where is difference A to B or B to A. It should be the same.

can you send me the command to execute on mikrotik terminal?

only with addres e src-address?

can you send me the command to execute on mikrotik terminal?

only with addres e src-address?

my Mikrotik: 192.168.1.1
my server: 192.168.2.1
my customer: 192.168.3.1

I want to ping from the api on mikrotik 192.168.1.1(Routerboard)

the src-address: 192.168.2.1 (my server)
to address:192.168.3.1(customer)

/ping src-address=192.168.2.1 address=192.168.3.1

thats correct?

ICMP does not work that way.

ping command needs tha IP address to be on the host you are pinging from. So that host that sends out ICMP packets will receive the replies. Other use of ICMP just do not make sense.

You can go to /tool traffic-generator to make up packet as you wish (with whatever content of packet) and send them that way.

look..

I need to ping from server to customer…

so I need to use shell script?

I get it by system(“ping $customer”)

but its so slow… the ping of mikrotik is more fastest…

if you need to ping from server to customer you go to server and ping from server to customer, you do not go to other device to issue ICMP packets.

Ping tool is binding to IP address you set as src and will fail (as expected) since ip address is not present on the device and should not be present there. Even if ping too could bind to somewhere, somehow and send out these packets with src-address that it does not have, where would these ICMP packets go?

If you want to send random garbage in your network you can do so by using ‘/tool traffic-generator’ where you can set write content of the packet yourself, with MAC addresses and IP address, and IP flags and IP packet contents you like mimicking any packet you like and send them on interface of choice.

edit: If you have 3 hosts in your network A, B and C you cannot run ICMP from A to B from C. You actually have to be on A or B to use ICMP between them. Other way packets from C will reach destination that is either A or B but reply from host will go to original src-address and dropped there as host receiving reply did not issue the ICMP request in the first place.

thank you so much…

i’ve thought that was possible…

:slight_smile: