Parse ip scan output

Hello,

I am writing a script to do some performance tests on a mesh network.
In this context, I would like to create an array having the IP addresses of the computers that are connected to my network.
If I understand well, ip scan is the perfect tool to do this.
However, I am unable to parse ip scan’s output to extract the ip addresses.

Does anyone have an idea of how to do this ?
Am I missing something ?

Indeed, when I execute :
ip-scan duration=2 address-range=192.168.2.11-192.168.2.31 interface=ether1

I obtain :
Flags: D - dhcp
ADDRESS MAC-ADDRESS TIME DNS SNMP NETBIOS
192.168.2.11 5ms
192.168.2.12 7ms

Which is unusable inside a script.

Is there a documentation somewhere on ip scan ?

Thanks,
Javier

seems like ip-scan is interactive tool, so you cannot use it in scripts…

Hello Chupaka,

Thank you for your reply.

Indeed, ip-scan is an interactive tool and cannot be used inside a script.

However, I found a better way to get the list of IP addresses accessible through each RouterBoard.
It is to take a look at the IP neighbors table. This method is quite nice and it is easy to use in a script :

{

Get the IP list of neighbors

:local nr;
:local idx;
:local nb;
:set nr [/ip neighbor print count-only];
:for idx from=0 to=($nr-1) do={:set nb ($nb , [/ip neighbor get value-name=address number=$idx])}
}

My goal is to write a tool to evaluate the performance of a HWMP mesh network.
The first indicator I am trying to measure is BandWidth between each pair of nodes (AB, AC, AD, BC, BD, CD).
At each measure all the network is allowed to one pair. The multi-hop route of the packets is obtained using the Mesh Traceroute tool.
Finally, the tests should be run locally and automatically, on each RouterBoard, using scripting.

Cheers,
Javier

more correct way is this, I believe:

{:local nb; :foreach i in=[/ip neighbor find] do={:set nb (nb, [ip neighbor get $i address ])}; :put $nb};

Thanks, this is much better.

Javier

You can pipe output from interactive commands in scripts using EXECUTE

It WORKS - but since it is interactive, and it is terminal-formatted output and not pure text output, you get several copies in the file. Something to be worked on.

{

Remove output file from last run if any

/file remove [find where name=“scan.csv.txt”]

Define script for doing IP-Scan on local subnet for 10 seconds

/sys script add name=ipscan source=“{\r
\nlocal ipnetwork [/ip address get 0 value-name=network]\r
\nlocal ipaddress [/ip address get 0 value-name=address]\r
\nlocal ipnetmask [:pick $ipaddress ([:find $ipaddress "/"]) [:len $ipaddress] ]\r
\n/tool ip-scan interface=bridge1 duration=10s address="$ipnetwork$ipnetmask"\r
\n}\r
\n”

Put that script into a variable

:local src

Execute the script-variable, output into scan.csv.txt

:local outfile “scan.csv”
execute script=[/system script get ipscan source] file=$outfile

Clean up

/sys script remove [find where name=ipscan]
}

Can “freeze-frame-interval=9s” help? (Looks like setting freeze-frame-interval= to the same value as duration= produces empty output)

EDIT: Disabled arp-ping parameter (arp table is not updated) and increased ARP timeout

You’re absolutely right :slight_smile: I have already done that. Dura minus 1 sec.
However, IP-scan seems inherently unstable. It doesn’t find all hosts in the first run.

I’m doing something else now - that isn’t an interactive tool: Pinging and reading ARP lookups!
It seems VERY reliable this way; It will also find hosts that cannot be pinged.

DISCLAIMER: This will only work on a 24-bit network, and will only scan the interface for the first IP address on the router. I’m using it for LAN devices only, not internet routers.

#Cannot ping 254 hosts before ARP expire, so set temporary non-default timeout
/ip settings set arp-timeout=5:00:00
/ip settings set icmp-rate-limit=0

#We need router-name for textfile name
local name [/sys id get name]
/file remove [find where name=“$name.txt”]

#Find interface for first IP address
local br [/ip addr get 0 value-name=interface]
local ipnetwork [/ip address get 0 value-name=network]
local ipaddress [/ip address get 0 value-name=address]
local ipnetmask [:pick $ipaddress ([:find $ipaddress “/”]) [:len $ipaddress] ]
local iph [:pick $ipnetwork 0 ([:len $ipnetwork]-1) ]

#Ping from 1 to 254 on current network. ASSUMING 24 BIT NETWORK.
:for ip from= 1 to= 254 do={ /ping (“$iph”.“$ip”) count=1 interface=$br interval=0.1s size=32 }

:delay 2

#Print ARP entires that 1) are non-empty, and 2) are from the same interface as the 1st IP address on the router
/ip arp print file=$name where (interface=$br && !(mac-address=))

#Upload the damn thing somewhere
/tool fetch upload=yes url=“ftp://blabla.bla/$name.txt” address=“blabla.bla” keep-result=no dst-path=“$name.txt” src-path=“$name.txt” user=bla password=bla check-certificate=no

#reset ARP timeout to normal
/ip settings set arp-timeout=0:30:00
/ip settings set icmp-rate-limit=10