How to get IP, MAC, EtherPort for all currently active EtherPorts?

How to get IP, MAC, EtherPort for all currently active EtherPorts?
Ie. for ports of router/switch that have active/alive devices attached? I of course mean the IP and MAC of the attached device, and the EtherPort of the router/switch.

/ip arp print

or

/ip arp print detail

You can try this script which will list all needed data into a file.

{
:local ethlist {"ether1-WAN1";"ether2-WAN2";"ether3-LAN1";"ether4-LAN2"};
:local buffer;
:local fileName "address-list";

:foreach a in=$ethlist do={
	:if ([/interface ethernet print as-value where name=$a && running=yes]) do={
		:foreach i in=[/ip arp print as-value where interface=$a] do={
			:set $buffer ($buffer." address=".$i->"address"." - mac-address=".$i->"mac-address"." - ETH=".$a."\n");
		}
	}
}

/file print file=$fileName where name="";
delay 1s;
/file set $fileName contents=$buffer;
}

You need to set your values for variable ethlist (this is an example), adding all of your ETH interfaces; the script will list only addresses from those that are running.

Armando.

Hi @Jotne, thanks. This is indeed good, but it says for all active interfaces just “interface=bridge”.
I need also the name of the raw interface, ie. “etherX”.

Hi @accarda, thanks for the script.
But I need this on CRS switch devices.These devices have 24+ or even 48+ interfaces (aka ports), so it is impractical to define all the interfaces manually. Isn’t there a method to get all the interfaces as a list or as an array and put it programmatically into your “ethlist” above?
Other than that I just need the output to be printed, ie. putting the result into a file is not required. But this is no problem as I can replace that by a “:put …”

You can try in this way.

{
:local ethlist;
:local buffer;
:local fileName "address-list";

:foreach i1 in [/interface ethernet find where running=yes] do={
	:set $ethlist [/interface ethernet get $i1 name];
	:foreach i2 in=$ethlist do={
		:foreach i3 in=[/ip arp print as-value where interface=$i2] do={
			:set $buffer ($buffer." address=".$i3->"address"." - mac-address=".$i3->"mac-address"." - ETH=".$i2."\n");
		}
	}
}

/file print file=$fileName where name="";
delay 1s;
/file set $fileName contents=$buffer;
}

Armando

@Armando, thx, but something isn’t working here as the output is empty, s.b.
I added it to “/system script” under the name “myTest2”. The editor in RouterOS said that there is a missing “=” in the first foreach line, I fixed it, and let it run, but the result is an empty output file:

[admin2@CRS326] /system/script> print       
Flags: I - invalid 
 0   name="myTest1" owner="admin2" policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon dont-require-permissions=no last-started=may/09/2020 10:54:53 run-count=6 
 ...
 1   name="myTest2" owner="admin2" policy=ftp,reboot,read,write,policy,test,password,sniff,sensitive,romon dont-require-permissions=no run-count=0 source=
       {
         :local ethlist;
         :local buffer;
         :local fileName "address-list";
       
         :foreach i1 in=[/interface ethernet find where running=yes] do={
           :set $ethlist [/interface ethernet get $i1 name];
           :foreach i2 in=$ethlist do={
               :foreach i3 in=[/ip arp print as-value where interface=$i2] do={
                       :set $buffer ($buffer." address=".$i3->"address"." - mac-address=".$i3->"mac-address"." - ETH=".$i2."\n");
               }
           }
         }
       
       /file print file=$fileName where name="";
       delay 1s;
       /file set $fileName contents=$buffer;
       }
[admin2@CRS326] /system/script> run myTest2
[admin2@CRS326] /system/script> /file/print 
Columns: NAME, TYPE, SIZE, CREATION-TIME
  #  NAME              TYPE       SIZE     CREATION-TIME       
  ...
  1  address-list.txt  .txt file  0        may/16/2020 12:40:26
  ...

I don’t know if it’s about some wrong character during copy/past into this forum.
However I have tried it again on my router directly from the terminal.

So let me past it again without using the code tag and see if you can copy/paste it on the terminal (and hit return to apply last curly bracket) to see that it creates a file with those info in there.
I know you don’t need to write to file, but that was just a simple output to test it out.

------------------------------ COPY / PASTE ---------------------------
{
:local ethlist;
:local buffer;
:local fileName “address-list”;

:foreach i1 in [/interface ethernet find where running=yes] do={
:set $ethlist [/interface ethernet get $i1 name];
:foreach i2 in=$ethlist do={
:foreach i3 in=[/ip arp print as-value where interface=$i2] do={
:set $buffer ($buffer." address=“.$i3->“address”.” - mac-address=“.$i3->“mac-address”.” - ETH=“.$i2.”\n");
}
}
}

/file print file=$fileName where name=“”;
delay 1s;
/file set $fileName contents=$buffer;
}


Armando

It seems it’s supposed to work also without “=”:
[admin2@CRS326] /system/script> :foreach i1 in [/interface ethernet find where running=yes] do={ :put $i1; }
1
f
[admin2@CRS326] /system/script> :foreach i1 in
=**[/interface ethernet find where running=yes] do={ :put $i1; }
*1
*f

But, the error must be somewhere else as it does not print any final results.
Ok, I’ll try to debug the script.
Thx for your help.

Btw, I’m using the 7.0beta5, maybe an issue it?..

Update:
Tried the code in your last posting, but unfortunately the address-list.txt file is still empty :frowning:

Ok, no problem.
I 'm running it on a RB4011 with ROS 6.46.6 and it works fine, it creates all those info based on each ETH.

Armando

just FYI, I have tried to add the = sign in the first couple of foreach and I have got the same syntax error even with ROS 6.46.6.
So I don’t think it’s about the beta that you are using.

Armando

Thx, but there seems to be the following bug in this beta:

[admin2@CRS326] /system/script> /ip arp print                                  
Flags: D - DYNAMIC, P - PUBLISHED; C - COMPLETE
Columns: ADDRESS, MAC-ADDRESS, INTERFACE
  #      ADDRESS          MAC-ADDRESS        INTERF
  0  DC  192.168.20.1     20:1A:06:5F:C0:3D  bridge
  1  DC  192.168.127.254  24:A4:3C:06:6C:2D  bridge
  2  DC  192.168.90.1     00:40:F4:A6:CE:E2  bridge
[admin2@CRS326] /system/script> /ip arp print as-value where interface="bridge"
[admin2@CRS326] /system/script> /ip arp print as-value where address="192.168.90.1"
[admin2@CRS326] /system/script> /ip arp print as-value where address=192.168.90.1

Ie. it prints nothing. Why not I wonder. A bug in this 7.0beta5 ?

Oops, I think I’ll have to embed this in a “:put …” :slight_smile:
Ok, now this works, for example:

:put [/ip arp print as-value where address "192.168.90.1"]                     
.id=*1;address=192.168.20.1;comment=;interface=bridge;mac-address=20:1A:06:5F:C0:3D;.id=*2;address=192.168.127.254;comment=;interface=bridge;mac-address=24:A4:3C:06:6C:2D;.id=*3;address=192.168.90.1;comment=;interface=bridge;mac-address=00:40:F4:A6:CE:E2

Hmm. this can’t be true, as it prints all, not the just selected one with “where”… Funny & Possibly Buggy :slight_smile:

Ok, the following works:

:put [/ip arp print as-value where address="192.168.90.1"] 
.id=*3;address=192.168.90.1;comment=;interface=bridge;mac-address=00:40:F4:A6:CE:E2

The minor difference is, again, the “=” :slight_smile:
Ok, I think this result should help me to get the script fixed to be run in this beta.

Actually I have just tried here from the terminal as well, adding the equal sign and I get only one record, as expected.

[user@rb0] > :put [/ip arp print as-value where address="192.168.0.1"]
.id=*10;address=192.168.0.1;comment=;interface=ether2-;mac-address=A8:7D:10:21:FB:2A
[user@rb0] >

Do you get the same ?
This is done with 6.46.6. So that will work also in your beta.
At this point if you try the script that I have sent you (last one), I guess it should work to print out all fields, or do you still get syntax error ?

It accepts it with or without the said “=”, but here in this beta the result is an empty file.
I’m at the moment trying to figure out the cause, ie. trying to get it working by finding a workaround for this beta.
Regarding “:put [/ip arp print …” : I had already posted my output in prev posting. Yes they look similar in both versions.

Armando, my debug analysis indicates that “/ip arp” does not have a unique (ie. common in both) key/value pair for lookup in “/interface ethernet”,
so then it seems it can’t be done with “/interface ethernet”.
There must be some other location like bridge or switch …

Update:
see also this related new feature request I just made: https://forum.mikrotik.com/viewtopic.php?f=1&t=161253

Since all your ethernet port are slaved to the bridge, only the bridge will show as the interface. You can change the script to:

{
:local ethlist;
:local buffer;
:local fileName "address-list";
:foreach i1 in=[/interface find running=yes] do={:set $ethlist [/interface get $i1 value-name=name];
:foreach i2 in=$ethlist do={:foreach i3 in=[/ip arp print as-value where interface=$i2] do={:set $buffer ($buffer." address=".$i3->"address"." - mac-address=".$i3->"mac-address"." - interface=".$i2."\n")}}};
/file print file=$fileName where name="";
delay 1s;
/file set $fileName contents=$buffer;
}

And it will output a populated file, but the result will not be what you are originally asked for. It will not show what devices are connected to each ether port.

An alternate would be to use something like:

/interface bridge host print

:smiley:

It won’t get you the address, but it will get you mac-address and interface it is on. You could then combine this with data from the /ip dhcp-server lease of your router.

I don’t use DHCP, but this still looks very interesting! I’ve an idea: with a little bit tricky programming this could serve as the basis for the solution… Will try it out. Thx!

Update:

/interface bridge host print
Flags: D - DYNAMIC; L - LOCAL; E - EXTERNAL
Columns: MAC-ADDRESS, ON-INTERFACE, BRIDGE

MAC-ADDRESS ON-INTE BRIDGE

0 D E 20:1A:06:5F:C0:3D ether15 bridge
1 D E 24:A4:3C:06:6C:2D ether1 bridge
2 DL C4:AD:34:78:E1:88 bridge bridge
3 DL C4:AD:34:78:E1:96 ether15 bridge

Why does the below command not print the above Flags? It is the key for the solution!

/system/script> :foreach i in=[/interface/bridge/host print detail as-value show-ids ] do={ :put $i; }
.id=*38;bridge=bridge;comment=;interface=ether15;mac-address=20:1A:06:5F:C0:3D;on-interface=ether15
.id=*36;bridge=bridge;comment=;interface=ether1;mac-address=24:A4:3C:06:6C:2D;on-interface=ether1
.id=*39;bridge=bridge;comment=;interface=bridge;mac-address=C4:AD:34:78:E1:88;on-interface=bridge
.id=*37;bridge=bridge;comment=;interface=ether15;mac-address=C4:AD:34:78:E1:96;on-interface=ether15

Anybody know how to get also the Flags? (ie. especially the L und E flags)
Then combining that with the “/ip arp” values would be the solution!

Update-2:
I’ve another new idea based on this… :slight_smile:

Algorithm (pseudo code):

foreach i in /interface/bridge/host
f1 = is $i->MAC in /ip/arp ?
f2 = is $i->MAC not in /interface/ethernet ?
fOk = f1 AND f2
if fOK print IP, MAC, interface

>

This seems to work:

{
	:local ip
	/interface bridge host 
	:foreach ID in=[find] do={
		:local inf [get $ID interface]
		:local mac [get $ID mac-address]
		:local idmac [/ip arp find mac-address="$mac"]
		:if ([:len $idmac] > 0) do={
			:set ip [/ip arp get $idmac address]
		}
		:put "interface=$inf mac=$mac ip=$ip"
	}
}

It does get all mac address and what interface they are connected to on the router using /interface bridge host
Then using /ip arp to find what IP the mac-address do belongs to.

If you do not like to show lines where there are no IP, this will do:

{
	:local ip
	/interface bridge host 
	:foreach ID in=[find] do={
		:local inf [get $ID interface]
		:local mac [get $ID mac-address]
		:local idmac [/ip arp find mac-address="$mac"]
		:if ([:len $idmac] > 0) do={
			:set ip [/ip arp get $idmac address]
			:put "interface=$inf mac=$mac ip=$ip"
		}
	}
}

PS I guess you need to use some form of bridge for this to work.

Actually in my case I don’t use the bridge (each port is an independed interface), so what I tested was based on that.
Now I see all these differences that you have seen so far, beside the initial errors.