Community discussions

MikroTik App
 
Bernhard
just joined
Topic Author
Posts: 9
Joined: Mon Apr 12, 2021 4:42 pm
Location: Vienna / Austria

Script to display clients in WLAN (with hostname and accesspoint)

Mon Oct 04, 2021 3:47 pm

Hello community - in CAPsMAN you can list all registered clients on all CAP Interfaces. You see MAC of client and Interface.
What you don't see, is the DHCP name of the client and to which access point it is connected.
I wrote a script to display exact this information. What you will get is:
MAC                IP               Client      AP              Signal TX Rate    RX Rate    Uptime        Bytes               Packets             Interface
FF:FF:FF:11:3E:9C  192.168.12.251   Client01    AccessPoint01   -53    117Mbps    12Mbps     5d01:54:54    68431014,22847922   286257,200633       cap14
FF:FF:FF:11:76:9A  192.168.12.250   Client02    AccessPoint03   -75    16Mbps     12Mbps     1d10:54:53    68123014,54347922   286257,200633       cap12
This is my script:
:global fill do={
	# this function fills up a string with a char up to a length - its used to make a tabular view of values
	# 3 parameters: #1 string to fill
	#               #2 length to fill up (or cut down)
	#               #3 char used to fill up (or as delimiter when cutting)
	# if the length of the string is more than the parameter length-1, the string will be cut by length-1 and one char will be appended as delimiter
	:local STR $1;
	:local LEN $2;
	:local CHAR $3;
	:if ([:len $STR] >= $LEN) do={
		# string has to be cut
		:set STR ([:pick $STR 0 ($LEN-1)].$CHAR);
	} else {
		# string has to be filled up to length
		:for i from=1 to=($LEN-[:len $STR]) step=1 do={
			:set STR ("$STR" . $CHAR);
		}
	}
	:return $STR;
}

:put ([$fill "MAC" 19 " "].[$fill "IP" 17 " "].[$fill "Client" 12 " "].[$fill "AP" 16 " "].[$fill "Signal" 7 " "].[$fill "TX Rate" 11 " "].[$fill "RX Rate" 11 " "].[$fill "Uptime" 14 " "].[$fill "Bytes" 20 " "].[$fill "Packets" 20 " "]."Interface");
:foreach i in=[/caps-man registration-table find .id] do={
	:local locMAC    [/caps-man registration-table get $i mac-address];
	:local locInt    [/caps-man registration-table get $i interface];
	:local locSignal [/caps-man registration-table get $i rx-signal];
	:local loctxRate [/caps-man registration-table get $i tx-rate];
	# reduce to relevant data: "173.3Mbps-20MHz/2S/SGI" --> "173.3Mbps"
	:if ([:find $loctxRate "-" -1] > 0) do={ :set loctxRate [:pick $loctxRate 0 [:find $loctxRate "-" -1]];}
	:local locrxRate [/caps-man registration-table get $i rx-rate];
	:if ([:find $locrxRate "-" -1] > 0) do={ :set locrxRate [:pick $locrxRate 0 [:find $locrxRate "-" -1]];}
	:local locUptime [/caps-man registration-table get $i uptime];
	:set locUptime   [:pick $locUptime 0 [:find $locUptime "." -1]];
	:local locBytes  [/caps-man registration-table get $i bytes];
	:local locPack   [/caps-man registration-table get $i packets];
	:local locRadMAC [/caps-man interface get [/caps-man interface find name=$locInt] radio-mac];
	:local locCAP    [/caps-man radio get [/caps-man radio find radio-mac=$locRadMAC] remote-cap-identity];
	:local locIP     [/ip dhcp-server lease get [/ip dhcp-server lease find mac-address=$locMAC] address];
	:local locName   [/ip dhcp-server lease get [/ip dhcp-server lease find mac-address=$locMAC] host-name];
	:put ([$fill $locMAC 19 " "].[$fill $locIP 17 " "].[$fill $locName 12 " "].[$fill $locCAP 16 " "].[$fill $locSignal 7 " "].[$fill $loctxRate 11 " "].[$fill $locrxRate 11 " "].[$fill $locUptime 14 " "].[$fill $locBytes 20 " "].[$fill $locPack 20 " "]."$locInt");
}
Best regards
Bernhard
 
Bernhard
just joined
Topic Author
Posts: 9
Joined: Mon Apr 12, 2021 4:42 pm
Location: Vienna / Austria

Re: Script to display clients in WLAN (with hostname and accesspoint)

Thu Mar 03, 2022 4:35 pm

Hi - I updated my script to also be able to diplay SSID and Clients on Slave Interfaces. When signal strength is below -70db the line is printed red. Also catched some Errors which stopped Script.
Looks like this now:
MAC                IP               Client      AP              Signal SSID               TX Rate    RX Rate    Uptime        Bytes               Packets             Interface
98:3B:8F:8B:27:E3  10.22.32.208     Client01    AP01_Floor1     -55    WLAN_Office        173.3Mbps  173.3Mbps  3d08:14:50    2079611693,36712726 5218249,3579269     cap56
E6:B0:C2:D6:D5:73  10.22.32.218     Client05    AP06_Floor4     -68    WLAN_Guest         173.3Mbps  78Mbps     2d03:50:14    15286043,30608002   46680,45932         cap68
Here the Script:
# Script wlan - gives a list of WLAN-clients with DHCP-names and signal strengt collected from 4 tables (caps-man registration-table, caps-man interface, caps-man radio, ip dhcp-server lease)
# v1.0 BV 2021-10-01 - first Version
# v2.0 BV 2021-12-02 - when signal equal or less -70db the line will be printed in red (bad signal)
# v2.1 BV 2022-03-03 - fixed Error with Slave Interfaces (we have to look for the Radio MAC of the Master Interface); inserted SSID

:global fill do={
    # this function fills up a string with a char up to a length - its used to make a tabular view of values
    # 3 parameters: 
	#    #1 string to fill
    #    #2 length to fill up (or cut down)
    #    #3 char used to fill up (or as delimiter when cutting)
    # if the length of the string is more than the parameter length-1, the string will be cut by length-1 and one char will be appended as delimiter
    :local STR $1;
    :local LEN $2;
    :local CHAR $3;
    :if ([:len $STR] >= $LEN) do={
        # string has to be cut
        :set STR ([:pick $STR 0 ($LEN-1)].$CHAR);
    } else {
        # string has to be filled up to length
        :for i from=1 to=($LEN-[:len $STR]) step=1 do={
            :set STR ("$STR" . $CHAR);
        }
    }
    :return $STR;
    }

:put ([$fill "MAC" 19 " "].[$fill "IP" 17 " "].[$fill "Client" 12 " "].[$fill "AP" 16 " "].[$fill "Signal" 7 " "].[$fill "SSID" 19 " "].[$fill "TX Rate" 11 " "].[$fill "RX Rate" 11 " "].[$fill "Uptime" 14 " "].[$fill "Bytes" 20 " "].[$fill "Packets" 20 " "]."Interface");
:foreach i in=[/caps-man registration-table find .id] do={
    :local locMAC    [/caps-man registration-table get $i mac-address];
    :local locInt    [/caps-man registration-table get $i interface];
    :local locSSID   [/caps-man registration-table get $i ssid];
    :local locSignal [/caps-man registration-table get $i rx-signal];
    :local loctxRate [/caps-man registration-table get $i tx-rate];
    # reduce to relevant data: "173.3Mbps-20MHz/2S/SGI" --> "173.3Mbps"
    :if ([:find $loctxRate "-" -1] > 0) do={ :set loctxRate [:pick $loctxRate 0 [:find $loctxRate "-" -1]];}
    :local locrxRate [/caps-man registration-table get $i rx-rate];
    :if ([:find $locrxRate "-" -1] > 0) do={ :set locrxRate [:pick $locrxRate 0 [:find $locrxRate "-" -1]];}
    :local locUptime [/caps-man registration-table get $i uptime];
    :set locUptime    [:pick $locUptime 0 [:find $locUptime "." -1]];
    :local locBytes  [/caps-man registration-table get $i bytes];
    :local locPack    [/caps-man registration-table get $i packets];
	# if we are on a Slave Interface we have to take the Radio MAC from the Master Interface
	:local locMasterInt [/caps-man interface get [/caps-man interface find name=$locInt] master-interface];
	:local locRadioMAC;
	:if ($locMasterInt = "none") do={set locRadioMAC [/caps-man interface get [/caps-man interface find name=$locInt] radio-mac]} else={set locRadioMAC [/caps-man interface get [/caps-man interface find name=$locMasterInt] radio-mac]}
	:local locCAP;
    :do {set $locCAP  [/caps-man radio get [/caps-man radio find radio-mac=$locRadioMAC] remote-cap-identity]} on-error={:put ("ERROR - ".$locMAC." - ".$locCAPMAC)};
	# fetch IP and Name from DHCP Server (if present)
    :local locIP;
    :local locName;
    :if ([/ip dhcp-server lease find mac-address=$locMAC]) do={
	    set $locIP      [/ip dhcp-server lease get [/ip dhcp-server lease find mac-address=$locMAC] address];
        set $locName    [/ip dhcp-server lease get [/ip dhcp-server lease find mac-address=$locMAC] host-name];
    } else={
	    set $locIP "noIP";
		set $locName "noName";
	}
    :if ($locSignal <= -70) do={
        # bad signal - write line red
        :terminal style varname;
        :put ([$fill $locMAC 19 " "].[$fill $locIP 17 " "].[$fill $locName 12 " "].[$fill $locCAP 16 " "].[$fill $locSignal 7 " "].[$fill $locSSID 19 " "].[$fill $loctxRate 11 " "].[$fill $locrxRate 11 " "].[$fill $locUptime 14 " "].[$fill $locBytes 20 " "].[$fill $locPack 20 " "]."$locInt");
        :terminal style none;
    } else={
        :put ([$fill $locMAC 19 " "].[$fill $locIP 17 " "].[$fill $locName 12 " "].[$fill $locCAP 16 " "].[$fill $locSignal 7 " "].[$fill $locSSID 19 " "].[$fill $loctxRate 11 " "].[$fill $locrxRate 11 " "].[$fill $locUptime 14 " "].[$fill $locBytes 20 " "].[$fill $locPack 20 " "]."$locInt");
    }
}
 
Bernhard
just joined
Topic Author
Posts: 9
Joined: Mon Apr 12, 2021 4:42 pm
Location: Vienna / Austria

Re: Script to display clients in WLAN (with hostname and accesspoint)

Mon Feb 13, 2023 3:33 pm

Hi - I updated the script to catch duplicated DHCP-Entries errors.
# Script wlan - gives a list of WLAN-clients with DHCP-names and signal strengt collected from 4 tables (caps-man registration-table, caps-man interface, caps-man radio, ip dhcp-server lease)
# v1.0 BV 2021-10-01 - first Version
# v2.0 BV 2021-12-02 - when signal equal or less -70db the line will be printed in red (bad signal)
# v2.1 BV 2022-03-03 - fixed Error with Slave Interfaces (we have to look for the Radio MAC of the Master Interface); inserted SSID
# v2.2 BV 2022-03-28 - fixed Error with duplicate entries in DHCP
# v2.3 BV 2022-12-13 - adopting column width (AP, SSID, Bytes, Packets)

:global fill do={
    # this function fills up a string with a char up to a length - its used to make a tabular view of values
    # 3 parameters: 
    #    #1 string to fill
    #    #2 length to fill up (or cut down)
    #    #3 char used to fill up (or as delimiter when cutting)
    # if the length of the string is more than the parameter length-1, the string will be cut by length-1 and one char will be appended as delimiter
    :local STR $1;
    :local LEN $2;
    :local CHAR $3;
    :if ([:len $STR] >= $LEN) do={
        # string has to be cut
        :set STR ([:pick $STR 0 ($LEN-1)].$CHAR);
    } else {
        # string has to be filled up to length
        :for i from=1 to=($LEN-[:len $STR]) step=1 do={
            :set STR ("$STR" . $CHAR);
        }
    }
    :return $STR;
}
:put ([$fill "MAC" 19 " "].[$fill "IP" 17 " "].[$fill "Client" 12 " "].[$fill "AP" 10 " "].[$fill "Signal" 7 " "].[$fill "SSID" 18 " "].[$fill "TX Rate" 11 " "].[$fill "RX Rate" 11 " "].[$fill "Uptime" 14 " "].[$fill "Bytes" 21 " "].[$fill "Packets" 15 " "]."Interface");
:foreach i in=[/caps-man registration-table find .id] do={
    :local locMAC    [/caps-man registration-table get $i mac-address];
    :local locInt    [/caps-man registration-table get $i interface];
    :local locSSID   [/caps-man registration-table get $i ssid];
    :local locSignal [/caps-man registration-table get $i rx-signal];
    :local loctxRate [/caps-man registration-table get $i tx-rate];
    # reduce to relevant data: "173.3Mbps-20MHz/2S/SGI" --> "173.3Mbps"
    :if ([:find $loctxRate "-" -1] > 0) do={ :set loctxRate [:pick $loctxRate 0 [:find $loctxRate "-" -1]];}
    :local locrxRate [/caps-man registration-table get $i rx-rate];
    :if ([:find $locrxRate "-" -1] > 0) do={ :set locrxRate [:pick $locrxRate 0 [:find $locrxRate "-" -1]];}
    :local locUptime [/caps-man registration-table get $i uptime];
    :set locUptime    [:pick $locUptime 0 [:find $locUptime "." -1]];
    :local locBytes  [/caps-man registration-table get $i bytes];
    :local locPack    [/caps-man registration-table get $i packets];
    # if we are on a Slave Interface we have to take the Radio MAC from the Master Interface
    :local locMasterInt [/caps-man interface get [/caps-man interface find name=$locInt] master-interface];
    :local locRadioMAC;
    :if ($locMasterInt = "none") do={set locRadioMAC [/caps-man interface get [/caps-man interface find name=$locInt] radio-mac]} else={set locRadioMAC [/caps-man interface get [/caps-man interface find name=$locMasterInt] radio-mac]}
    :local locCAP;
    :do {set $locCAP  [/caps-man radio get [/caps-man radio find radio-mac=$locRadioMAC] remote-cap-identity]} on-error={:put ("ERROR - ".$locMAC." - ".$locRadioMAC)};
    # fetch IP and Name from DHCP Server (if present)
    :local locIP;
    :local locName;
    :if ([/ip dhcp-server lease find mac-address=$locMAC]) do={
        :do {set $locIP   [/ip dhcp-server lease get [/ip dhcp-server lease find mac-address=$locMAC] address]}   on-error={set $locIP "DCHP-Err"; put ("ERROR with ".$locMAC." - Please check DHCP for duplicate entries")};
        :do {set $locName [/ip dhcp-server lease get [/ip dhcp-server lease find mac-address=$locMAC] host-name]} on-error={set $locName "DHCP-Err"};
    } else={
        set $locIP "noDHCP";
        set $locName "noDHCP";
    }
    :if ($locSignal <= -70) do={
        # bad signal - write line red
        :terminal style varname;
        :put ([$fill $locMAC 19 " "].[$fill $locIP 17 " "].[$fill $locName 12 " "].[$fill $locCAP 10 " "].[$fill $locSignal 7 " "].[$fill $locSSID 18 " "].[$fill $loctxRate 11 " "].[$fill $locrxRate 11 " "].[$fill $locUptime 14 " "].[$fill $locBytes 21 " "].[$fill $locPack 15 " "].$locInt);
        :terminal style none;
    } else={
        :put ([$fill $locMAC 19 " "].[$fill $locIP 17 " "].[$fill $locName 12 " "].[$fill $locCAP 10 " "].[$fill $locSignal 7 " "].[$fill $locSSID 18 " "].[$fill $loctxRate 11 " "].[$fill $locrxRate 11 " "].[$fill $locUptime 14 " "].[$fill $locBytes 21 " "].[$fill $locPack 15 " "].$locInt);
    }
}
 
User avatar
rextended
Forum Guru
Forum Guru
Posts: 11967
Joined: Tue Feb 25, 2014 12:49 pm
Location: Italy
Contact:

Re: Script to display clients in WLAN (with hostname and accesspoint)

Mon Feb 13, 2023 6:55 pm

Check for errors and some optimization...

See this:
:global fill do={
    :local STR  $1
    :local LEN  $2
    :local CHAR $3
    :if ([:len $STR] >= $LEN) do={
        :set STR "$[:pick $STR 0 ($LEN-1)]$CHAR"
    } else={
        :for i from=1 to=($LEN-[:len $STR]) step=1 do={
            :set STR "$STR$CHAR"
        }
    }
    :return $STR
}


:put "$[$fill "MAC" 19 " "]$[$fill "IP" 17 " "]$[$fill "Client" 12 " "]$[$fill "AP" 10 " "]$[$fill "Signal" 7 " "]$[$fill "SSID" 18 " "]$[$fill "TX Rate" 11 " "]$[$fill "RX Rate" 11 " "]$[$fill "Uptime" 14 " "]$[$fill "Bytes" 21 " "]$[$fill "Packets" 15 " "]Interface"
/caps-man registration-table
:foreach i in=[find] do={
    :local locMAC    [get $i mac-address]
    :local locInt    [get $i interface]
    :local locSSID   [get $i ssid]
    :local locSignal [get $i rx-signal]
    :local loctxRate [get $i tx-rate]
    :if ([:find $loctxRate "-" -1] > 0) do={:set loctxRate [:pick $loctxRate 0 [:find $loctxRate "-" -1]]}
    :local locrxRate [get $i rx-rate]
    :if ([:find $locrxRate "-" -1] > 0) do={:set locrxRate [:pick $locrxRate 0 [:find $locrxRate "-" -1]]}
    :local locUptime [get $i uptime]
    :set   locUptime [:pick $locUptime 0 [:find $locUptime "." -1]]
    :local locBytes  [get $i bytes]
    :local locPack   [get $i packets]
    /caps-man interface
    :local locMasterInt [get [find where name=$locInt] master-interface]
    :local locRadioMAC  "00:00:00:00:00:00"
    :if ($locMasterInt = "none") do={:set locRadioMAC [get [find where name=$locInt] radio-mac]} else={:set locRadioMAC [get [find where name=$locMasterInt] radio-mac]}
    :local locCAP ""
    /caps-man radio
    :do {:set locCAP [get [find where radio-mac=$locRadioMAC] remote-cap-identity]} on-error={:put "ERROR - $locMAC - $locRadioMAC"}
    :local locIP   "noDHCP"
    :local locName "noDHCP"
    /ip dhcp-server lease
    :if ([find where mac-address=$locMAC]) do={
        :do {:set locIP   [get [find where mac-address=$locMAC] address  ]} on-error={:set locIP   "DCHP-Err"; :put "ERROR with $locMAC - Please check DHCP for duplicate entries"}
        :do {:set locName [get [find where mac-address=$locMAC] host-name]} on-error={:set locName "DHCP-Err"}
    }
    :if ($locSignal <= -70) do={:terminal style varname} else={:terminal style none}
    :put "$[$fill $locMAC 19 " "]$[$fill $locIP 17 " "]$[$fill $locName 12 " "]$[$fill $locCAP 10 " "]$[$fill $locSignal 7 " "]$[$fill $locSSID 18 " "]$[$fill $loctxRate 11 " "]$[$fill $locrxRate 11 " "]$[$fill $locUptime 14 " "]$[$fill $locBytes 21 " "]$[$fill $locPack 15 " "]$locInt"
}

Who is online

Users browsing this forum: No registered users and 20 guests