Community discussions

MikroTik App
 
MTNick
Member Candidate
Member Candidate
Topic Author
Posts: 106
Joined: Fri Nov 24, 2023 6:43 am

Re: Script to obtain vendor info from MAC addresses when bridge is bridgeLocal

Sun Nov 03, 2024 11:26 pm

Do you need this for ROS v6 or v7?

Give this a try
:local version "IP-Scanner-arp_v1.0"
:local note "Compatible with RouterOS versions 6.45.9 & above"
:local scanTime "30"
:local date [/system clock get date]
:local name [/system identity get name]
:put ""
:put "### $version"
:put "### $note"

{
# Convert date and time for the file name, needed for ROS version 6
:local simplercurrdatetimestr do={
    /system clock
    :local vdate [get date]
    :local vtime [get time]
    :local vdoff [:toarray "0,4,5,7,8,10"]
    :local MM    [:pick $vdate ($vdoff->2) ($vdoff->3)]
    :local M     [:tonum $MM]
    :if ($vdate ~ ".../../....") do={
        :set vdoff [:toarray "7,11,1,3,4,6"]
        :set M     ([:find "xxanebarprayunulugepctovecANEBARPRAYUNULUGEPCTOVEC" [:pick $vdate ($vdoff->2) ($vdoff->3)] -1] / 2)
        :if ($M>12) do={:set M ($M - 12)}
        :set MM    [:pick (100 + $M) 1 3]
    }
    :local yyyy [:pick $vdate ($vdoff->0) ($vdoff->1)]
    :local dd   [:pick $vdate ($vdoff->4) ($vdoff->5)]
    :local HH   [:pick $vtime 0  2]
    :local mm   [:pick $vtime 3  5]
    :local ss   [:pick $vtime 6  8]

    :return "$MM-$dd-$yyyy_$HH.$mm.$ss"
}

:local dateTime [$simplercurrdatetimestr]

# Gather network address from user & find the interface
:delay 2s
:put ""
:put "### Listing available address-list"
:put ""
/ip address print
:put ""
:local requestvalue do={:put $1 ; :return}
:local scanRange [$requestvalue "Enter the address of the interface to scan -- Example: 192.168.88.1/24"]
:put ""
:local scanInterface [/ip address get [find where address="$scanRange"] interface]
:put "### Found interface: $scanInterface"
:local fileName "$name_IP-Scan_$scanInterface_$dateTime"
/file remove [find where name=$"fileName".txt]
:delay 2s

# Clear the arp table
:put "### Clearing the arp table"
:local dumplist [/ip arp find]
:foreach i in=$dumplist do={
    /ip arp remove $i
}

# Scan the range, get macs, ip addresses, bridge host interface & ether name comments. Do a mac lookup for each item
:local ipScan   ""
:local buffer1   ""
:local vendor 
:local arpCount 0
:delay 2s
:put "### Scanning $scanRange for $scanTime seconds. Standby..."
:put ""
:delay 2s
:set $ipScan ($ipScan.[/tool ip-scan address-range="$scanRange" duration=$scanTime])
:put "### Looking up OUI vendor info. Standby...\r\n"
/ip arp
:foreach item in=[find interface=$scanInterface] do={
    :local mac   [get $item mac-address]
    :local arpIP   [get $item address]
    :local ipScanip "$ipScan$[get $item address]"
    :local ipScanmac "$ipScan$[get $item mac-address]"
    :if ([:len $mac] > 0) do={
      :do {
      :local int [/interface bridge host get [find where mac-address=$ipScanmac] interface]
      :local comment [/interface ethernet get [find where name=$int] comment]
      :local secBit [:pick "$ipScanmac" 1 2 ]
      :if ( ($secBit = "2") or ($secBit = "6") or ($secBit = "A") or ($secBit = "E") ) do={
        :set vendor "* LOCAL PRIVATE *"}  else={
        :local vendorResult [/tool fetch url=("https://api.maclookup.app/v2/macs/".[:pick $ipScanmac 0 8]."/company/name") as-value output=user]
        :if (($vendorResult->"status")="finished") do={:set vendor ($vendorResult->"data")}
        :delay 0.5}
          :if ($vendor = "IEEE Registration Authority") do={
          :local vendorResult2 [/tool fetch url=("https://api.maclookup.app/v2/macs/".[:pick $ipScanmac 0 10]."/company/name") as-value output=user]
          :if (($vendorResult2->"status")="finished") do={:set vendor ($vendorResult2->"data")}
          :delay 0.5}
            :if ($vendor = "IEEE Registration Authority") do={
            :local vendorResult3 [/tool fetch url=("https://api.maclookup.app/v2/macs/".[:pick $ipScanmac 0 13]."/company/name") as-value output=user]
            :if (($vendorResult3->"status")="finished") do={:set vendor ($vendorResult3->"data")}
            :delay 0.5}
    :set $buffer1 ($buffer1."IP: $ipScanip | MAC: $ipScanmac | Interface: $int | Comment: $comment | MLU: $vendor\r\n")
    :set arpCount ($arpCount + 1)
  } on-error={};
}}

# ARP Clean-up
/ip arp remove [find where !complete]

# Messages
:local title "Identity: $name | Scanned Interface: $scanInterface | Scanned Range: $scanRange | Date: $date | Version: $version\r\n"
:local detected "### Total devices with an address detected on '$scanInterface': $arpCount"

# List the results
:put "$detected"
:put "$buffer1"
:delay 1s

# Put the results in a file
:put "### Writing to file"
/file print file=$fileName
:delay 1s
:execute [/file set $fileName contents="$title\r\n$detected\r\n$buffer1"]

# Instructions
:put "### The file: '$fileName' is located in 'Files' (left sidebar menu)"
:put "### To download the file locally, right click on the file & select download"
:put "### Be sure to delete the file from this device once it's downloaded locally"
:put ""
}
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 4240
Joined: Sun May 01, 2016 7:12 pm
Location: California
Contact:

Re: Script to obtain vendor info from MAC addresses when bridge is bridgeLocal

Mon Nov 04, 2024 1:56 am

Hmm, in a quick test it works on my test router using 7.17.
It might be the /tool/fetch that does the MAC address lookup that's failing... since that requires policy and test permissions, so if /system/script didn't allow those that be one reason it fail.

The on-error={} prevents errors from being shown, so hard to know... In newer V7, using the :onerror err in={} do={} syntax might be better since the script would get the error message.

You might try it from the CLI. If type a {, then paste script, and add a close }... and see if runs from there.
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 4240
Joined: Sun May 01, 2016 7:12 pm
Location: California
Contact:

Re: Script to obtain vendor info from MAC addresses when bridge is bridgeLocal

Mon Nov 04, 2024 2:02 am

192.168.0.37  F6:F5:AC:C6:61:E6  169ms                                                
192.168.0.30  E8:F4:08:E8:52:51                                                       
I don't know what the issue is with 192.168.0.30 no time ms
It could just be a timing issue (no pun), but the duration= is a hard cutoff, so it could be in the middle of getting the ARP from 192.168.0.30 when the duration= hits.
 
User avatar
Amm0
Forum Guru
Forum Guru
Posts: 4240
Joined: Sun May 01, 2016 7:12 pm
Location: California
Contact:

Re: Script to obtain vendor info from MAC addresses when bridge is bridgeLocal

Mon Nov 04, 2024 6:01 am

:local scanTime "30"

should be

:local scanTime 30s

near the top of the script
 
MTNick
Member Candidate
Member Candidate
Topic Author
Posts: 106
Joined: Fri Nov 24, 2023 6:43 am

Re: Script to obtain vendor info from MAC addresses when bridge is bridgeLocal

Mon Nov 04, 2024 5:46 pm

Give this a try

:local version "IP-Scanner-arp_v1.1.0"
:local note "Compatible with RouterOS versions 6.45.9 & above"
:local scanTime "60"
:local date [/system clock get date]
:local name [/system identity get name]
:put ""
:put "### $version"
:put "### $note"

{
# Convert date and time for the file name, needed for ROS version 6
:local simplercurrdatetimestr do={
    /system clock
    :local vdate [get date]
    :local vtime [get time]
    :local vdoff [:toarray "0,4,5,7,8,10"]
    :local MM    [:pick $vdate ($vdoff->2) ($vdoff->3)]
    :local M     [:tonum $MM]
    :if ($vdate ~ ".../../....") do={
        :set vdoff [:toarray "7,11,1,3,4,6"]
        :set M     ([:find "xxanebarprayunulugepctovecANEBARPRAYUNULUGEPCTOVEC" [:pick $vdate ($vdoff->2) ($vdoff->3)] -1] / 2)
        :if ($M>12) do={:set M ($M - 12)}
        :set MM    [:pick (100 + $M) 1 3]
    }
    :local yyyy [:pick $vdate ($vdoff->0) ($vdoff->1)]
    :local dd   [:pick $vdate ($vdoff->4) ($vdoff->5)]
    :local HH   [:pick $vtime 0  2]
    :local mm   [:pick $vtime 3  5]
    :local ss   [:pick $vtime 6  8]

    :return "$MM-$dd-$yyyy_$HH.$mm.$ss"
}

:local dateTime [$simplercurrdatetimestr]

# Gather network address from user & find the interface
:put ""
:put "### Listing available address-list"
:put ""
/ip address print
:put ""
:local requestvalue do={:put $1 ; :return}
:local scanRange [$requestvalue "Enter the address of the interface to scan -- Example: 192.168.88.1/24"]
:put ""
:local interface [/ip address get [find where address="$scanRange"] interface]
:put "### Found interface: $interface"
:local fileName "$name_IP-Scan_$interface_$dateTime"
/file remove [find where name=$"fileName".txt]
:delay 2s

# Grab bridge from bridge-host
:local intMac [/interface get [find where name=$interface] mac-address] 
:local scanInterface [/interface bridge host get [find where mac-address=$intMac] bridge]
:put "### Found bridge: $scanInterface"

# Clear the arp table
:put "### Clearing the arp table"
:local dumplist [/ip arp find]
:foreach i in=$dumplist do={
    /ip arp remove $i
}

# Scan the range, get macs, ip addresses, bridge host interface & ether name comments. Do a mac lookup for each item
:local ipScan   ""
:local buffer1   ""
:local vendor 
:local arpCount 0
:delay 2s
:put "### Scanning $scanRange for $scanTime seconds. Standby..."
:put ""
:delay 2s
:set $ipScan ($ipScan.[/tool ip-scan address-range="$scanRange" duration=$scanTime])
:put "### Looking up OUI vendor info. Standby...\r\n"
/ip arp
:foreach item in=[find interface=$"scanInterface"] do={
    :local mac   [get $item mac-address]
    :local arpIP   [get $item address]
    :local ipScanip "$ipScan$[get $item address]"
    :local ipScanmac "$ipScan$[get $item mac-address]"
    :if ([:len $mac] > 0) do={
      :do {
      :local int [/interface bridge host get [find where mac-address=$ipScanmac] interface]
      :local bridge [/interface bridge host get [find where mac-address=$ipScanmac] bridge]
      :local comment [/interface ethernet get [find where name=$int] comment]
      :local secBit [:pick "$ipScanmac" 1 2 ]
      :if ( ($secBit = "2") or ($secBit = "6") or ($secBit = "A") or ($secBit = "E") ) do={
        :set vendor "* LOCAL PRIVATE *"}  else={
        :local vendorResult [/tool fetch url=("https://api.maclookup.app/v2/macs/".[:pick $ipScanmac 0 8]."/company/name") as-value output=user]
        :if (($vendorResult->"status")="finished") do={:set vendor ($vendorResult->"data")}
        :delay 0.5}
          :if ($vendor = "IEEE Registration Authority") do={
          :local vendorResult2 [/tool fetch url=("https://api.maclookup.app/v2/macs/".[:pick $ipScanmac 0 10]."/company/name") as-value output=user]
          :if (($vendorResult2->"status")="finished") do={:set vendor ($vendorResult2->"data")}
          :delay 0.5}
            :if ($vendor = "IEEE Registration Authority") do={
            :local vendorResult3 [/tool fetch url=("https://api.maclookup.app/v2/macs/".[:pick $ipScanmac 0 13]."/company/name") as-value output=user]
            :if (($vendorResult3->"status")="finished") do={:set vendor ($vendorResult3->"data")}
            :delay 0.5}
    :set $buffer1 ($buffer1."IP: $ipScanip | MAC: $ipScanmac | Interface: $int | Comment: $comment | MLU: $vendor\r\n")
    :set arpCount ($arpCount + 1)
  } on-error={};
}}

# ARP Clean-up
/ip arp remove [find where !complete]

# Messages
:local title "Identity: $name | Scanned Bridge: $scanInterface | Scanned Range: $scanRange | Date: $date | Version: $version\r\n"
:local detected "### Total devices with an address detected on '$scanInterface': $arpCount"

# List the results
:put "$detected"
:put "$buffer1"
:delay 1s

# Put the results in a file
:put "### Writing to file"
/file print file=$fileName
:delay 1s
:execute [/file set $fileName contents="$title\r\n$detected\r\n$buffer1"]

# Instructions
:put "### The file: '$fileName' is located in 'Files' (left sidebar menu)"
:put "### To download the file locally, right click on the file & select download"
:put "### Be sure to delete the file from this device once it's downloaded locally"
:put ""
}
 
MTNick
Member Candidate
Member Candidate
Topic Author
Posts: 106
Joined: Fri Nov 24, 2023 6:43 am

Re: Script to obtain vendor info from MAC addresses when bridge is bridgeLocal

Tue Nov 05, 2024 3:12 pm

Alright. Run the below. Copy/paste as is & provide the output
{:local int [/ip address get [find where address="192.168.0.2/24"] interface]
:local intMac [/interface get [find where name=$int] mac-address]
:local intBr [/interface bridge host get [find where mac-address=$intMac] bridge]
:local brInt [/interface bridge host get [find where mac-address=$intMac] interface]
:put "$int"
:put "$intMac"
:put "$intBr"
:put "$brInt"}
 
MTNick
Member Candidate
Member Candidate
Topic Author
Posts: 106
Joined: Fri Nov 24, 2023 6:43 am

Re: Script to obtain vendor info from MAC addresses when bridge is bridgeLocal

Fri Nov 08, 2024 3:03 am

Greetings wfburton.

Try the below. We'll need to figure out what's failing
--- Leave these as is ---
:put [/tool ip-scan address-range="192.168.0.2/24" duration=50]
:put [/ip address get [find where address="192.168.0.2/24"] interface]
:put [/interface get [find where name=sfp-sfpplus1] comment] 
:put [/interface get [find where name=sfp-sfpplus1] mac-address]

--- Use the MAC address from the above output for the 2 below ---
:put [/interface bridge host get [find where mac-address=MAC FROM ABOVE] bridge]
:put [/interface bridge host get [find where mac-address=MAC FROM ABOVE] interface]

--- Leave this as is ---
:put [ip arp get [find where mac-address=F8:E4:3B:7F:DF:63] interface]
 
MTNick
Member Candidate
Member Candidate
Topic Author
Posts: 106
Joined: Fri Nov 24, 2023 6:43 am

Re: Script to obtain vendor info from MAC addresses when bridge is bridgeLocal

Sat Nov 09, 2024 12:55 am

According to the outputs that you provided, I'm not sure why it's failing. Those are what it needs to find & get it's data.

Give this a try
:local version "IP-Scanner-arp_v1.1.3"
:local note "Compatible with RouterOS versions 6.45.9 & above"
:local scanTime "40"
:local date [/system clock get date]
:local name [/system identity get name]
:put ""
:put "### $version"
:put "### $note"

{
# Convert date and time for the file name, needed for ROS version 6
:local simplercurrdatetimestr do={
    /system clock
    :local vdate [get date]
    :local vtime [get time]
    :local vdoff [:toarray "0,4,5,7,8,10"]
    :local MM    [:pick $vdate ($vdoff->2) ($vdoff->3)]
    :local M     [:tonum $MM]
    :if ($vdate ~ ".../../....") do={
        :set vdoff [:toarray "7,11,1,3,4,6"]
        :set M     ([:find "xxanebarprayunulugepctovecANEBARPRAYUNULUGEPCTOVEC" [:pick $vdate ($vdoff->2) ($vdoff->3)] -1] / 2)
        :if ($M>12) do={:set M ($M - 12)}
        :set MM    [:pick (100 + $M) 1 3]
    }
    :local yyyy [:pick $vdate ($vdoff->0) ($vdoff->1)]
    :local dd   [:pick $vdate ($vdoff->4) ($vdoff->5)]
    :local HH   [:pick $vtime 0  2]
    :local mm   [:pick $vtime 3  5]
    :local ss   [:pick $vtime 6  8]

    :return "$MM-$dd-$yyyy_$HH.$mm.$ss"
}

:local dateTime [$simplercurrdatetimestr]

# Gather network address from user & find the interface
:put ""
:put "### Listing available address-list"
:put ""
/ip address print
:put ""
:local requestvalue do={:put $1 ; :return}
:local scanRange [$requestvalue "Enter the address of the interface to scan -- Example: 192.168.88.1/24"]
:put ""
:local interface [/ip address get [find where address="$scanRange"] interface]
:put "### Found interface: $interface"
:local fileName "$name_IP-Scan_$interface_$dateTime"
/file remove [find where name=$"fileName".txt]
:delay 2s

# Grab bridge from bridge-host
:local intMac [/interface get [find where name=$interface] mac-address] 
:local scanInterface [/interface bridge host get [find where mac-address=$intMac] bridge]
:put "### Found bridge: $scanInterface"

# Clear the arp table
:put "### Clearing the arp table"
:local dumplist [/ip arp find]
:foreach i in=$dumplist do={
    /ip arp remove $i
}

# Scan the range, get macs, ip addresses, bridge host interface & ether name comments. Do a mac lookup for each item
:local ipScan   ""
:local buffer1   ""
:local vendor 
:local arpCount 0
:delay 2s
:put "### Scanning $scanRange for $scanTime seconds. Standby..."
:put ""
:delay 2s
:set $ipScan ($ipScan.[/tool ip-scan address-range="$scanRange" duration=$scanTime])
:put "### Looking up OUI vendor info. Standby...\r\n"
/ip arp
:foreach item in=[find interface=$"scanInterface"] do={
    :local mac   [get $item mac-address]
    :local arpIP   [get $item address]
    :local ipScanip "$ipScan$[get $item address]"
    :local ipScanmac "$ipScan$[get $item mac-address]"
    :if ([:len $mac] > 0) do={
      :do {
      :local int [/interface bridge host get [find where mac-address=$mac] interface]
      :local comment [/interface get [find where name=$int] comment]
      :local secBit [:pick "$mac" 1 2 ]
      :if ( ($secBit = "2") or ($secBit = "6") or ($secBit = "A") or ($secBit = "E") ) do={
        :set vendor "* LOCAL PRIVATE *"}  else={
        :local vendorResult [/tool fetch url=("https://api.maclookup.app/v2/macs/".[:pick $mac 0 8]."/company/name") as-value output=user]
        :if (($vendorResult->"status")="finished") do={:set vendor ($vendorResult->"data")}
        :delay 0.5}
          :if ($vendor = "IEEE Registration Authority") do={
          :local vendorResult2 [/tool fetch url=("https://api.maclookup.app/v2/macs/".[:pick $mac 0 10]."/company/name") as-value output=user]
          :if (($vendorResult2->"status")="finished") do={:set vendor ($vendorResult2->"data")}
          :delay 0.5}
            :if ($vendor = "IEEE Registration Authority") do={
            :local vendorResult3 [/tool fetch url=("https://api.maclookup.app/v2/macs/".[:pick $mac 0 13]."/company/name") as-value output=user]
            :if (($vendorResult3->"status")="finished") do={:set vendor ($vendorResult3->"data")}
            :delay 0.5}
    :set $buffer1 ($buffer1."IP: $arpIP | MAC: $mac | Interface: $int | Comment: $comment | MLU: $vendor\r\n")
    :set arpCount ($arpCount + 1)
  } on-error={};
}}

# ARP Clean-up
/ip arp remove [find where !complete]

# Messages
:local title "Identity: $name | Scanned Bridge: $scanInterface | Scanned Range: $scanRange | Date: $date | Version: $version\r\n"
:local detected "### Total devices with an address detected on '$scanInterface': $arpCount"

# List the results
:put "$detected"
:put "$buffer1"
:delay 1s

# Put the results in a file
:put "### Writing to file"
/file print file=$fileName
:delay 1s
:execute [/file set $fileName contents="$title\r\n$detected\r\n$buffer1"]

# Instructions
:put "### The file: '$fileName' is located in 'Files' (left sidebar menu)"
:put "### To download the file locally, right click on the file & select download"
:put "### Be sure to delete the file from this device once it's downloaded locally"
:put ""
}
 
MTNick
Member Candidate
Member Candidate
Topic Author
Posts: 106
Joined: Fri Nov 24, 2023 6:43 am

Re: Script to obtain vendor info from MAC addresses when bridge is bridgeLocal

Sun Nov 10, 2024 5:06 pm

That's strange & odd behavior. I've tested the script (all these scripts :wink: ) on various versions (6.45.9, 6.49.10, 7.15.2, 7.15.3, 7.16.1) and various types from commercial to consumer (CCR, CRS, RB, hEX), without a single failure. hmmmm not sure what's going on
 
MTNick
Member Candidate
Member Candidate
Topic Author
Posts: 106
Joined: Fri Nov 24, 2023 6:43 am

Re: Script to obtain vendor info from MAC addresses when bridge is bridgeLocal

Thu Nov 21, 2024 12:21 am

That's good news!

Ah the tinkering. Gets me sometimes as well lol. Reconfigure this and that. It never ends

Let me know if you get any file creation issues due to the amount of devices. I ended up splitting the file if it has more than 30 devices.

Who is online

Users browsing this forum: flapviv and 11 guests