Access Point Registration Table

Материал из noname.com.ua
Перейти к навигацииПерейти к поиску

Таблица уровней клиентов для точек доступа Cisco

Задача

Собирать данные о траффике и уровне сигнала с точек доступа

  • Клиенты динамические, их мак-адреса заранее не известны
  • SSID добавляются и удаляются по мере необходимости
  • Точки могут иметь как один интерфейс так и два


Для того что бы получить информацию по SNMP о клиентах подключенных к точке доступа, существует специальный MIB CISCO-DOT11-ASSOCIATION-MIB
Он доступен достаточно давно, как минимум он работает на точках 1200 и 1100 серий, ну и на более современных тоже.


Просмотр OID

Пример с использованием display-hint

# snmpwalk -v2c -c MON 192.168.77.2  .1.3.6.1.4.1.9.9.273.1.3.1   -OX
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientCurrentTxRateSet[1]["450"][STRING: da:20:60:64:36:95] = Hex-STRING: 07
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientCurrentTxRateSet[2]["450"][STRING: a4:45:19:5a:ef:48] = Hex-STRING: 01
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientUpTime[1]["450"][STRING: da:20:60:64:36:95] = Gauge32: 15898 second
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientUpTime[2]["450"][STRING: a4:45:19:5a:ef:48] = Gauge32: 425 second
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientSignalStrength[1]["450"][STRING: da:20:60:64:36:95] = INTEGER: -64 dBm
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientSignalStrength[2]["450"][STRING: a4:45:19:5a:ef:48] = INTEGER: -89 dBm
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientSigQuality[1]["450"][STRING: da:20:60:64:36:95] = Gauge32: 24 percentage
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientSigQuality[2]["450"][STRING: a4:45:19:5a:ef:48] = Gauge32: 9 percentage
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientAgingLeft[1]["450"][STRING: da:20:60:64:36:95] = Gauge32: 58 second
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientAgingLeft[2]["450"][STRING: a4:45:19:5a:ef:48] = Gauge32: 34 second
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientPacketsReceived[1]["450"][STRING: da:20:60:64:36:95] = Counter32: 149529 packet
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientPacketsReceived[2]["450"][STRING: a4:45:19:5a:ef:48] = Counter32: 346 packet
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientBytesReceived[1]["450"][STRING: da:20:60:64:36:95] = Counter32: 23101125 byte
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientBytesReceived[2]["450"][STRING: a4:45:19:5a:ef:48] = Counter32: 113287 byte
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientPacketsSent[1]["450"][STRING: da:20:60:64:36:95] = Counter32: 617733 packet
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientPacketsSent[2]["450"][STRING: a4:45:19:5a:ef:48] = Counter32: 251 packet
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientBytesSent[1]["450"][STRING: da:20:60:64:36:95] = Counter32: 745190393 byte
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientBytesSent[2]["450"][STRING: a4:45:19:5a:ef:48] = Counter32: 47693 byte
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientDuplicates[1]["450"][STRING: da:20:60:64:36:95] = Counter32: 2389 packet
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientDuplicates[2]["450"][STRING: a4:45:19:5a:ef:48] = Counter32: 12 packet
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientMsduRetries[1]["450"][STRING: da:20:60:64:36:95] = Counter32: 159859 packet
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientMsduRetries[2]["450"][STRING: a4:45:19:5a:ef:48] = Counter32: 331 packet
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientMsduFails[1]["450"][STRING: da:20:60:64:36:95] = Counter32: 0 packet
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientMsduFails[2]["450"][STRING: a4:45:19:5a:ef:48] = Counter32: 0 packet
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientWepErrors[1]["450"][STRING: da:20:60:64:36:95] = Counter32: 0 packet
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientWepErrors[2]["450"][STRING: a4:45:19:5a:ef:48] = Counter32: 0 packet
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientMicErrors[1]["450"][STRING: da:20:60:64:36:95] = Counter32: 0 error
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientMicErrors[2]["450"][STRING: a4:45:19:5a:ef:48] = Counter32: 0 error
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientMicMissingFrames[1]["450"][STRING: da:20:60:64:36:95] = Counter32: 0 packet
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientMicMissingFrames[2]["450"][STRING: a4:45:19:5a:ef:48] = Counter32: 0 packet

Или без использования

# snmpwalk -v2c -c MON 192.168.77.2  .1.3.6.1.4.1.9.9.273.1.3.1   -On
.1.3.6.1.4.1.9.9.273.1.3.1.1.1.1.3.52.53.48.218.32.96.100.54.149 = Hex-STRING: 05
.1.3.6.1.4.1.9.9.273.1.3.1.1.1.2.3.52.53.48.164.69.25.90.239.72 = Hex-STRING: 01
.1.3.6.1.4.1.9.9.273.1.3.1.1.2.1.3.52.53.48.218.32.96.100.54.149 = Gauge32: 15911 second
.1.3.6.1.4.1.9.9.273.1.3.1.1.2.2.3.52.53.48.164.69.25.90.239.72 = Gauge32: 439 second
.1.3.6.1.4.1.9.9.273.1.3.1.1.3.1.3.52.53.48.218.32.96.100.54.149 = INTEGER: -63 dBm
.1.3.6.1.4.1.9.9.273.1.3.1.1.3.2.3.52.53.48.164.69.25.90.239.72 = INTEGER: -89 dBm
.1.3.6.1.4.1.9.9.273.1.3.1.1.4.1.3.52.53.48.218.32.96.100.54.149 = Gauge32: 31 percentage
.1.3.6.1.4.1.9.9.273.1.3.1.1.4.2.3.52.53.48.164.69.25.90.239.72 = Gauge32: 10 percentage
.1.3.6.1.4.1.9.9.273.1.3.1.1.5.1.3.52.53.48.218.32.96.100.54.149 = Gauge32: 58 second
.1.3.6.1.4.1.9.9.273.1.3.1.1.5.2.3.52.53.48.164.69.25.90.239.72 = Gauge32: 51 second
.1.3.6.1.4.1.9.9.273.1.3.1.1.6.1.3.52.53.48.218.32.96.100.54.149 = Counter32: 149587 packet
.1.3.6.1.4.1.9.9.273.1.3.1.1.6.2.3.52.53.48.164.69.25.90.239.72 = Counter32: 347 packet
.1.3.6.1.4.1.9.9.273.1.3.1.1.7.1.3.52.53.48.218.32.96.100.54.149 = Counter32: 23109939 byte
.1.3.6.1.4.1.9.9.273.1.3.1.1.7.2.3.52.53.48.164.69.25.90.239.72 = Counter32: 113333 byte
.1.3.6.1.4.1.9.9.273.1.3.1.1.8.1.3.52.53.48.218.32.96.100.54.149 = Counter32: 618046 packet
.1.3.6.1.4.1.9.9.273.1.3.1.1.8.2.3.52.53.48.164.69.25.90.239.72 = Counter32: 251 packet
.1.3.6.1.4.1.9.9.273.1.3.1.1.9.1.3.52.53.48.218.32.96.100.54.149 = Counter32: 745583754 byte
.1.3.6.1.4.1.9.9.273.1.3.1.1.9.2.3.52.53.48.164.69.25.90.239.72 = Counter32: 47693 byte
.1.3.6.1.4.1.9.9.273.1.3.1.1.10.1.3.52.53.48.218.32.96.100.54.149 = Counter32: 2392 packet
.1.3.6.1.4.1.9.9.273.1.3.1.1.10.2.3.52.53.48.164.69.25.90.239.72 = Counter32: 12 packet
.1.3.6.1.4.1.9.9.273.1.3.1.1.11.1.3.52.53.48.218.32.96.100.54.149 = Counter32: 159964 packet
.1.3.6.1.4.1.9.9.273.1.3.1.1.11.2.3.52.53.48.164.69.25.90.239.72 = Counter32: 331 packet
.1.3.6.1.4.1.9.9.273.1.3.1.1.12.1.3.52.53.48.218.32.96.100.54.149 = Counter32: 0 packet
.1.3.6.1.4.1.9.9.273.1.3.1.1.12.2.3.52.53.48.164.69.25.90.239.72 = Counter32: 0 packet
.1.3.6.1.4.1.9.9.273.1.3.1.1.13.1.3.52.53.48.218.32.96.100.54.149 = Counter32: 0 packet
.1.3.6.1.4.1.9.9.273.1.3.1.1.13.2.3.52.53.48.164.69.25.90.239.72 = Counter32: 0 packet
.1.3.6.1.4.1.9.9.273.1.3.1.1.14.1.3.52.53.48.218.32.96.100.54.149 = Counter32: 0 error
.1.3.6.1.4.1.9.9.273.1.3.1.1.14.2.3.52.53.48.164.69.25.90.239.72 = Counter32: 0 error
.1.3.6.1.4.1.9.9.273.1.3.1.1.15.1.3.52.53.48.218.32.96.100.54.149 = Counter32: 0 packet
.1.3.6.1.4.1.9.9.273.1.3.1.1.15.2.3.52.53.48.164.69.25.90.239.72 = Counter32: 0 packet

Разбор OID

Как можно видеть, сам OID состоит из нескольких частей Для определенности рассмотрим уровни сигнала:

.1.3.6.1.4.1.9.9.273.1.3.1.1.3.1.3.52.53.48.218.32.96.100.54.149 = INTEGER: -63 dBm
.1.3.6.1.4.1.9.9.273.1.3.1.1.3.2.3.52.53.48.164.69.25.90.239.72 = INTEGER: -89 dBm
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientSignalStrength[1]["450"][STRING: da:20:60:64:36:95] = INTEGER: -64 dBm
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientSignalStrength[2]["450"][STRING: a4:45:19:5a:ef:48] = INTEGER: -89 dBm

Часть .1.3.6.1.4.1.9.9.273.1.3.1.1.3 это и есть OID CISCO-DOT11-ASSOCIATION и она общая Далее в самом OID закодировано значение "кому принадлежит сигнал", т е какому клиенту


Выделенное значение и его описание:

  • 2.3.52.53.48.164.69.25.90.239.72 - номер интерфейса, он же ifIndex, dot11Radio0 (1), или dot11Radio1 (2), в примере клиент подключен к 5Ghz интерфейсу (dot11Radio1)
  • 2.3.52.53.48.164.69.25.90.239.72 - Длинна SSID в байтах, в пример 3 символа (SSID в примере "450")
  • 2.3.52.53.48.164.69.25.90.239.72 - коды ASCII символов SSID, их три - "450"
  • 2.3.52.53.48.164.69.25.90.239.72 - мак-адрес, 6 байт, записаны в деятичной форме, "a4:45:19:5a:ef:48", например 164(десятичное) = a4(hex), 69(десятичное) = 45 (hex) и так далее.

Интеграция с Zabbix

SNMP autodiscovery

Есть дока но мне она не нравится =)

В целом идея такая:

  • В поле SNMP OID указываю discovery[{#S},1.3.6.1.4.1.9.9.273.1.3.1.1.3]
  • Заббикс сам делает snmpwalk 1.3.6.1.4.1.9.9.273.1.3.1.1.3 и в результате получает список клиентов и их сигналы
snmpwalk -v2c -c MON 192.168.77.2   1.3.6.1.4.1.9.9.273.1.3.1.1.3   -OX
Bad operator (INTEGER): At line 73 in /usr/share/snmp/mibs/ietf/SNMPv2-PDU
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientSignalStrength[1]["450"][STRING: 0:8:ca:2b:1:24] = INTEGER: -65 dBm
CISCO-DOT11-ASSOCIATION-MIB::cDot11ClientSignalStrength[2]["450"][STRING: a4:45:19:5a:ef:48] = INTEGER: -67 dBm

и на выходе формирует JSON в котором есть поля "{#SNMPINDEX}" - это часть которую нужно дописать к OID указанному в discovery что бы получить значение

[
  {
    "{#SNMPINDEX}": "1.3.52.53.48.0.8.202.43.1.36",
    "{#S}": "-66"
  },
  {
    "{#SNMPINDEX}": "2.3.52.53.48.164.69.25.90.239.72",
    "{#S}": "-66"
  }
] 

Это выглядит странновато, но суть этого - получить список суффиксов, которые потом можно использовать для получения других значений
В поле "{#S}" записан сигнал и его значение я нигде не использую, но в общем случае (для других MIB/OID) тут может быть что-то что можно использовать (в оригинальной документации это имена интерфейсов)
В общем случае можно указать несколько OID которые нужно обходить snmpwalk-ом, но при этом нужно держать в голове что SNMPINDEX должен совпадать - так работает для таблицы интерфейсов где по разным префиксам но с одним и тем же ifIndex можно получить данные с интерфейса - имя, дескрипшен, байты и т.п.

Если же указать 2 OID с разной структурой (например интерфейсы и таблицу регистрации клиентов) то ничего хорошего не получится - данные будут перемешаны (подробно я не смотрел код как именно и почему )


Далее при создании прототипов элементов данных можно использовать "{#SNMPINDEX}" и тогда все остальные переменны в JSON полученном при discovery будут доступны

Например, если при создании прототипа данныхь указать OID=.1.3.6.1.4.1.9.9.273.1.3.1.1.2.{#SNMPINDEX} то (для моего примера будет автоматически создано 2 элемента данных, в именах которых можно использовать например значение макроса "{$S}". Это хорошо ложиться на пример с интерфейсом, но в моем случае этот макрос как и остальные совершенно бесполезен так как вся статическая информация закодирована в OID который собственно доступен через макрос "{SNMPINDEX}"

Processing

Для того что бы получить нужные данные в удобном виде полученный при discovery JSON можно редактировать с помошью встроенного JavaScript

В моем случае на скорую руку вышел вот такой скрипт:

var records = JSON.parse(value);

for (i = 0; i < records.length; i++) {
    var OID = records[i]["{#SNMPINDEX}"].split('.')
    // IFINDEX AND IFNAME
    var dot1RadioIfIndex = OID.shift();
    records[i]['{#DOT1RADIO_IFINDEX}'] = dot1RadioIfIndex
    records[i]['{#DOT1RADIO_IFNAME}'] = "Dot11Radio" + (parseInt(dot1RadioIfIndex) - 1).toString()

    // get mac as 6 last digits converted dec -> hex and joined with ':'
    var MAC = ""
    var MACDigitHex
    for (j = 0; j < 6; j++) {
        MACDigitDec = OID.pop();

        MACDigitHex = parseInt(MACDigitDec).toString(16);
        MAC = MACDigitHex + " " + MAC
    }
    records[i]['{#MAC}'] = MAC.trim().split(" ").join(":")

    // SSID. The first octet is length, others are ASCII characters 
    SSID = ""
    ssidLength = OID.shift();
    
    for (j = 0; j < ssidLength; j++) {
      SSID += String.fromCharCode(parseInt(OID[j]));

    }
    records[i]['{#SSID}'] = SSID
}
return JSON.stringify(records);

Идея в том что бы добавить поля построенные на основе SNMPINDEX в Json, и в дальнейшем они будут доступны при создании элементов данных


В результате из исходного JSON получаю такой

[
  {
    "{#SNMPINDEX}": "1.3.52.53.48.0.8.202.43.1.36",
    "{#S}": "-62",
    "{#DOT1RADIO_IFINDEX}": "1",
    "{#DOT1RADIO_IFNAME}": "Dot11Radio0",
    "{#MAC}": "0:8:ca:2b:1:24",
    "{#SSID}": "450"
  },
  {
    "{#SNMPINDEX}": "2.3.52.53.48.164.69.25.90.239.72",
    "{#S}": "-79",
    "{#DOT1RADIO_IFINDEX}": "2",
    "{#DOT1RADIO_IFNAME}": "Dot11Radio1",
    "{#MAC}": "a4:45:19:5a:ef:48",
    "{#SSID}": "450"
  }
]

который уже содержит статическую информацию о клиенте и который можно использовать для создания элеметов данных

Прототпипы жлементов данных

Формируем имя и ключ на основе данных из Json, например

Name cDot11ClientSignalStrength [ {#MAC}@{#DOT1RADIO_IFNAME}:{#SSID} ]

где для кажого клиента будет создан отдельный элемент данных, при этом используются три уникальных значения, клиент с тем же маком но подключившись в другом диапазоне (другой интерфейс) рассматривается как другой клиент даже если используется один SSID для разных частот)

Темплейт

<?xml version="1.0" encoding="UTF-8"?>
<zabbix_export>
    <version>5.0</version>
    <date>2022-08-20T17:54:46Z</date>
    <groups>
        <group>
            <name>Templates/Modules</name>
        </group>
    </groups>
    <templates>
        <template>
            <template>Template Module Cisco CISCO-DOT11-ASSOCIATION-MIB</template>
            <name>Template Module Cisco CISCO-DOT11-ASSOCIATION-MIB</name>
            <groups>
                <group>
                    <name>Templates/Modules</name>
                </group>
            </groups>
            <applications>
                <application>
                    <name>cDot11ClientBytes</name>
                </application>
                <application>
                    <name>cDot11ClientErrors</name>
                </application>
                <application>
                    <name>cDot11ClientPackets</name>
                </application>
                <application>
                    <name>cDot11Clients</name>
                </application>
                <application>
                    <name>cDot11ClientSignal</name>
                </application>
            </applications>
            <discovery_rules>
                <discovery_rule>
                    <name>CISCO-DOT11-ASSOCIATION-MIB</name>
                    <type>SNMP_AGENT</type>
                    <snmp_oid>discovery[{#S},1.3.6.1.4.1.9.9.273.1.3.1.1.3]</snmp_oid>
                    <key>CISCO-DOT11-ASSOCIATION-MIB</key>
                    <lifetime>365d</lifetime>
                    <item_prototypes>
                        <item_prototype>
                            <name>07 cDot11ClientBytesReceived [ {#MAC}@{#DOT1RADIO_IFNAME}:{#SSID} ]</name>
                            <type>SNMP_AGENT</type>
                            <snmp_oid>.1.3.6.1.4.1.9.9.273.1.3.1.1.7.{#SNMPINDEX}</snmp_oid>
                            <key>cDot11ClientBytesReceived[{#MAC}@{#DOT1RADIO_IFNAME}:{#SSID}]</key>
                            <units>bytes/s</units>
                            <description>cDot11ClientBytesReceived OBJECT-TYPE&#13;
    SYNTAX          Counter32&#13;
    UNITS           "byte"&#13;
    MAX-ACCESS      read-only&#13;
    STATUS          current&#13;
    DESCRIPTION&#13;
        "The number of bytes received from this client."&#13;
    ::= { cDot11ClientStatisticEntry 7 }</description>
                            <applications>
                                <application>
                                    <name>cDot11ClientBytes</name>
                                </application>
                            </applications>
                            <preprocessing>
                                <step>
                                    <type>CHANGE_PER_SECOND</type>
                                    <params/>
                                </step>
                            </preprocessing>
                        </item_prototype>
                        <item_prototype>
                            <name>09 cDot11ClientBytesSent [ {#MAC}@{#DOT1RADIO_IFNAME}:{#SSID} ]</name>
                            <type>SNMP_AGENT</type>
                            <snmp_oid>.1.3.6.1.4.1.9.9.273.1.3.1.1.9.{#SNMPINDEX}</snmp_oid>
                            <key>cDot11ClientBytesSent[{#MAC}@{#DOT1RADIO_IFNAME}:{#SSID}]</key>
                            <units>bytes/s</units>
                            <description>cDot11ClientBytesSent OBJECT-TYPE&#13;
    SYNTAX          Counter32&#13;
    UNITS           "byte"&#13;
    MAX-ACCESS      read-only&#13;
    STATUS          current&#13;
    DESCRIPTION&#13;
        "The number of bytes sent to this client."&#13;
    ::= { cDot11ClientStatisticEntry 9 }</description>
                            <applications>
                                <application>
                                    <name>cDot11ClientBytes</name>
                                </application>
                            </applications>
                            <preprocessing>
                                <step>
                                    <type>CHANGE_PER_SECOND</type>
                                    <params/>
                                </step>
                            </preprocessing>
                        </item_prototype>
                        <item_prototype>
                            <name>10 cDot11ClientDuplicates [ {#MAC}@{#DOT1RADIO_IFNAME}:{#SSID} ]</name>
                            <type>SNMP_AGENT</type>
                            <snmp_oid>.1.3.6.1.4.1.9.9.273.1.3.1.1.10.{#SNMPINDEX}</snmp_oid>
                            <key>cDot11ClientDuplicates[{#MAC}@{#DOT1RADIO_IFNAME}:{#SSID}]</key>
                            <units>pps</units>
                            <description>cDot11ClientDuplicates OBJECT-TYPE&#13;
    SYNTAX          Counter32&#13;
    UNITS           "packet"&#13;
    MAX-ACCESS      read-only&#13;
    STATUS          current&#13;
    DESCRIPTION&#13;
        "This counter increments when a packet for this&#13;
        client is received and the Sequence Control field&#13;
        in the packet header indicates the packet is a&#13;
        duplicate."&#13;
    ::= { cDot11ClientStatisticEntry 10 }</description>
                            <applications>
                                <application>
                                    <name>cDot11ClientErrors</name>
                                </application>
                            </applications>
                            <preprocessing>
                                <step>
                                    <type>CHANGE_PER_SECOND</type>
                                    <params/>
                                </step>
                            </preprocessing>
                        </item_prototype>
                        <item_prototype>
                            <name>14 cDot11ClientMicErrors [ {#MAC}@{#DOT1RADIO_IFNAME}:{#SSID} ]</name>
                            <type>SNMP_AGENT</type>
                            <snmp_oid>.1.3.6.1.4.1.9.9.273.1.3.1.1.14.{#SNMPINDEX}</snmp_oid>
                            <key>cDot11ClientMicErrors[{#MAC}@{#DOT1RADIO_IFNAME}:{#SSID}]</key>
                            <units>pps</units>
                            <description>cDot11ClientMicErrors OBJECT-TYPE&#13;
    SYNTAX          Counter32&#13;
    UNITS           "error"&#13;
    MAX-ACCESS      read-only&#13;
    STATUS          current&#13;
    DESCRIPTION&#13;
        "This is the number of MIC errors for this client."&#13;
    ::= { cDot11ClientStatisticEntry 14 }</description>
                            <applications>
                                <application>
                                    <name>cDot11ClientErrors</name>
                                </application>
                            </applications>
                            <preprocessing>
                                <step>
                                    <type>CHANGE_PER_SECOND</type>
                                    <params/>
                                </step>
                            </preprocessing>
                        </item_prototype>
                        <item_prototype>
                            <name>15 cDot11ClientMicMissingFrames [ {#MAC}@{#DOT1RADIO_IFNAME}:{#SSID} ]</name>
                            <type>SNMP_AGENT</type>
                            <snmp_oid>.1.3.6.1.4.1.9.9.273.1.3.1.1.15.{#SNMPINDEX}</snmp_oid>
                            <key>cDot11ClientMicMissingFrames[{#MAC}@{#DOT1RADIO_IFNAME}:{#SSID}]</key>
                            <units>pps</units>
                            <description>cDot11ClientMicMissingFrames OBJECT-TYPE&#13;
    SYNTAX          Counter32&#13;
    UNITS           "packet"&#13;
    MAX-ACCESS      read-only&#13;
    STATUS          current&#13;
    DESCRIPTION&#13;
        "This is the number of missing MIC packets for&#13;
        this client.".&#13;
    ::= { cDot11ClientStatisticEntry 15 }</description>
                            <applications>
                                <application>
                                    <name>cDot11ClientErrors</name>
                                </application>
                            </applications>
                            <preprocessing>
                                <step>
                                    <type>CHANGE_PER_SECOND</type>
                                    <params/>
                                </step>
                            </preprocessing>
                        </item_prototype>
                        <item_prototype>
                            <name>12 cDot11ClientMsduFails [ {#MAC}@{#DOT1RADIO_IFNAME}:{#SSID} ]</name>
                            <type>SNMP_AGENT</type>
                            <snmp_oid>.1.3.6.1.4.1.9.9.273.1.3.1.1.12.{#SNMPINDEX}</snmp_oid>
                            <key>cDot11ClientMsduFails[{#MAC}@{#DOT1RADIO_IFNAME}:{#SSID}]</key>
                            <units>pps</units>
                            <description>cDot11ClientMsduFails OBJECT-TYPE&#13;
    SYNTAX          Counter32&#13;
    UNITS           "packet"&#13;
    MAX-ACCESS      read-only&#13;
    STATUS          current&#13;
    DESCRIPTION&#13;
        "This counter increments when an MSDU is not&#13;
        transmitted successfully for this client due to the&#13;
        number of transmit attempts exceeding some limit.&#13;
    ::= { cDot11ClientStatisticEntry 12 }</description>
                            <applications>
                                <application>
                                    <name>cDot11ClientErrors</name>
                                </application>
                            </applications>
                            <preprocessing>
                                <step>
                                    <type>CHANGE_PER_SECOND</type>
                                    <params/>
                                </step>
                            </preprocessing>
                        </item_prototype>
                        <item_prototype>
                            <name>11 cDot11ClientMsduRetries [ {#MAC}@{#DOT1RADIO_IFNAME}:{#SSID} ]</name>
                            <type>SNMP_AGENT</type>
                            <snmp_oid>.1.3.6.1.4.1.9.9.273.1.3.1.1.11.{#SNMPINDEX}</snmp_oid>
                            <key>cDot11ClientMsduRetries[{#MAC}@{#DOT1RADIO_IFNAME}:{#SSID}]</key>
                            <units>pps</units>
                            <description>cDot11ClientMsduRetries OBJECT-TYPE&#13;
    SYNTAX          Counter32&#13;
    UNITS           "packet"&#13;
    MAX-ACCESS      read-only&#13;
    STATUS          current&#13;
    DESCRIPTION&#13;
        "This counter increments when an MSDU is successfully&#13;
        transmitted after one or more retransmissions for this&#13;
        client."&#13;
    ::= { cDot11ClientStatisticEntry 11 }</description>
                            <applications>
                                <application>
                                    <name>cDot11ClientErrors</name>
                                </application>
                            </applications>
                            <preprocessing>
                                <step>
                                    <type>CHANGE_PER_SECOND</type>
                                    <params/>
                                </step>
                            </preprocessing>
                        </item_prototype>
                        <item_prototype>
                            <name>06 cDot11ClientPacketsReceived [ {#MAC}@{#DOT1RADIO_IFNAME}:{#SSID} ]</name>
                            <type>SNMP_AGENT</type>
                            <snmp_oid>.1.3.6.1.4.1.9.9.273.1.3.1.1.6.{#SNMPINDEX}</snmp_oid>
                            <key>cDot11ClientPacketsReceived[{#MAC}@{#DOT1RADIO_IFNAME}:{#SSID}]</key>
                            <units>pps</units>
                            <description>cDot11ClientPacketsReceived OBJECT-TYPE&#13;
    SYNTAX          Counter32&#13;
    UNITS           "packet"&#13;
    MAX-ACCESS      read-only&#13;
    STATUS          current&#13;
    DESCRIPTION&#13;
        "The number of packets received from this client."&#13;
    ::= { cDot11ClientStatisticEntry 6 }</description>
                            <applications>
                                <application>
                                    <name>cDot11ClientPackets</name>
                                </application>
                            </applications>
                            <preprocessing>
                                <step>
                                    <type>CHANGE_PER_SECOND</type>
                                    <params/>
                                </step>
                            </preprocessing>
                        </item_prototype>
                        <item_prototype>
                            <name>08 cDot11ClientPacketsSent [ {#MAC}@{#DOT1RADIO_IFNAME}:{#SSID} ]</name>
                            <type>SNMP_AGENT</type>
                            <snmp_oid>.1.3.6.1.4.1.9.9.273.1.3.1.1.8.{#SNMPINDEX}</snmp_oid>
                            <key>cDot11ClientPacketsSent[{#MAC}@{#DOT1RADIO_IFNAME}:{#SSID}]</key>
                            <units>pps</units>
                            <description>cDot11ClientPacketsSent OBJECT-TYPE&#13;
    SYNTAX          Counter32&#13;
    UNITS           "packet"&#13;
    MAX-ACCESS      read-only&#13;
    STATUS          current&#13;
    DESCRIPTION&#13;
        "The number of packets sent to this client.".&#13;
    ::= { cDot11ClientStatisticEntry 8 }</description>
                            <applications>
                                <application>
                                    <name>cDot11ClientPackets</name>
                                </application>
                            </applications>
                            <preprocessing>
                                <step>
                                    <type>CHANGE_PER_SECOND</type>
                                    <params/>
                                </step>
                            </preprocessing>
                        </item_prototype>
                        <item_prototype>
                            <name>03 cDot11ClientSignalStrength [ {#MAC}@{#DOT1RADIO_IFNAME}:{#SSID} ]</name>
                            <type>SNMP_AGENT</type>
                            <snmp_oid>.1.3.6.1.4.1.9.9.273.1.3.1.1.3.{#SNMPINDEX}</snmp_oid>
                            <key>cDot11ClientSignalStrength[{#MAC}@{#DOT1RADIO_IFNAME}:{#SSID}]</key>
                            <value_type>FLOAT</value_type>
                            <units>dBm</units>
                            <description>cDot11ClientSignalStrength OBJECT-TYPE&#13;
    SYNTAX          Integer32 (-100..0)&#13;
    UNITS           "dBm"&#13;
    MAX-ACCESS      read-only&#13;
    STATUS          current&#13;
    DESCRIPTION&#13;
        "This is a device-dependent measure of the signal&#13;
        strength of the most recently received packet from.&#13;
        this client.  It may be normalized or unnormalized.".&#13;
    ::= { cDot11ClientStatisticEntry 3 }</description>
                            <applications>
                                <application>
                                    <name>cDot11ClientSignal</name>
                                </application>
                            </applications>
                        </item_prototype>
                        <item_prototype>
                            <name>04 cDot11ClientSigQuality [ {#MAC}@{#DOT1RADIO_IFNAME}:{#SSID} ]</name>
                            <type>SNMP_AGENT</type>
                            <snmp_oid>.1.3.6.1.4.1.9.9.273.1.3.1.1.4.{#SNMPINDEX}</snmp_oid>
                            <key>cDot11ClientSigQuality[{#MAC}@{#DOT1RADIO_IFNAME}:{#SSID}]</key>
                            <units>%</units>
                            <description>cDot11ClientSigQuality OBJECT-TYPE&#13;
    SYNTAX          Unsigned32 (0..100)&#13;
    UNITS           "percentage"&#13;
    MAX-ACCESS      read-only&#13;
    STATUS          current&#13;
    DESCRIPTION&#13;
        "This is a device-dependent measure of the signal&#13;
        quality of the most recently received packet from.&#13;
        this client.".&#13;
    ::= { cDot11ClientStatisticEntry 4 }</description>
                            <applications>
                                <application>
                                    <name>cDot11ClientSignal</name>
                                </application>
                            </applications>
                        </item_prototype>
                        <item_prototype>
                            <name>02 cDot11ClientUpTime [ {#MAC}@{#DOT1RADIO_IFNAME}:{#SSID} ]</name>
                            <type>SNMP_AGENT</type>
                            <snmp_oid>.1.3.6.1.4.1.9.9.273.1.3.1.1.2.{#SNMPINDEX}</snmp_oid>
                            <key>cDot11ClientUpTime[{#MAC}@{#DOT1RADIO_IFNAME}:{#SSID}]</key>
                            <units>s</units>
                            <description>cDot11ClientUpTime OBJECT-TYPE&#13;
    SYNTAX          Unsigned32&#13;
    UNITS           "second"&#13;
    MAX-ACCESS      read-only&#13;
    STATUS          current&#13;
    DESCRIPTION&#13;
        "The time in seconds that this client has been&#13;
        associated with this device."&#13;
    ::= { cDot11ClientStatisticEntry 2 }</description>
                            <applications>
                                <application>
                                    <name>cDot11Clients</name>
                                </application>
                            </applications>
                        </item_prototype>
                    </item_prototypes>
                    <graph_prototypes>
                        <graph_prototype>
                            <name>cDot11ClientBytes [ {#MAC}@{#DOT1RADIO_IFNAME}:{#SSID} ]</name>
                            <graph_items>
                                <graph_item>
                                    <sortorder>1</sortorder>
                                    <color>1A7C11</color>
                                    <item>
                                        <host>Template Module Cisco CISCO-DOT11-ASSOCIATION-MIB</host>
                                        <key>cDot11ClientBytesReceived[{#MAC}@{#DOT1RADIO_IFNAME}:{#SSID}]</key>
                                    </item>
                                </graph_item>
                                <graph_item>
                                    <sortorder>2</sortorder>
                                    <color>F63100</color>
                                    <item>
                                        <host>Template Module Cisco CISCO-DOT11-ASSOCIATION-MIB</host>
                                        <key>cDot11ClientBytesSent[{#MAC}@{#DOT1RADIO_IFNAME}:{#SSID}]</key>
                                    </item>
                                </graph_item>
                            </graph_items>
                        </graph_prototype>
                        <graph_prototype>
                            <name>cDot11ClientErrors [ {#MAC}@{#DOT1RADIO_IFNAME}:{#SSID} ]</name>
                            <graph_items>
                                <graph_item>
                                    <sortorder>1</sortorder>
                                    <color>1A7C11</color>
                                    <item>
                                        <host>Template Module Cisco CISCO-DOT11-ASSOCIATION-MIB</host>
                                        <key>cDot11ClientDuplicates[{#MAC}@{#DOT1RADIO_IFNAME}:{#SSID}]</key>
                                    </item>
                                </graph_item>
                                <graph_item>
                                    <sortorder>2</sortorder>
                                    <color>F63100</color>
                                    <item>
                                        <host>Template Module Cisco CISCO-DOT11-ASSOCIATION-MIB</host>
                                        <key>cDot11ClientMsduRetries[{#MAC}@{#DOT1RADIO_IFNAME}:{#SSID}]</key>
                                    </item>
                                </graph_item>
                                <graph_item>
                                    <sortorder>3</sortorder>
                                    <color>2774A4</color>
                                    <item>
                                        <host>Template Module Cisco CISCO-DOT11-ASSOCIATION-MIB</host>
                                        <key>cDot11ClientMsduFails[{#MAC}@{#DOT1RADIO_IFNAME}:{#SSID}]</key>
                                    </item>
                                </graph_item>
                                <graph_item>
                                    <sortorder>4</sortorder>
                                    <color>A54F10</color>
                                    <item>
                                        <host>Template Module Cisco CISCO-DOT11-ASSOCIATION-MIB</host>
                                        <key>cDot11ClientMicErrors[{#MAC}@{#DOT1RADIO_IFNAME}:{#SSID}]</key>
                                    </item>
                                </graph_item>
                                <graph_item>
                                    <sortorder>5</sortorder>
                                    <color>FC6EA3</color>
                                    <item>
                                        <host>Template Module Cisco CISCO-DOT11-ASSOCIATION-MIB</host>
                                        <key>cDot11ClientMicMissingFrames[{#MAC}@{#DOT1RADIO_IFNAME}:{#SSID}]</key>
                                    </item>
                                </graph_item>
                            </graph_items>
                        </graph_prototype>
                        <graph_prototype>
                            <name>cDot11ClientPackets[ {#MAC}@{#DOT1RADIO_IFNAME}:{#SSID} ]</name>
                            <graph_items>
                                <graph_item>
                                    <sortorder>1</sortorder>
                                    <color>1A7C11</color>
                                    <item>
                                        <host>Template Module Cisco CISCO-DOT11-ASSOCIATION-MIB</host>
                                        <key>cDot11ClientPacketsReceived[{#MAC}@{#DOT1RADIO_IFNAME}:{#SSID}]</key>
                                    </item>
                                </graph_item>
                                <graph_item>
                                    <sortorder>2</sortorder>
                                    <color>F63100</color>
                                    <item>
                                        <host>Template Module Cisco CISCO-DOT11-ASSOCIATION-MIB</host>
                                        <key>cDot11ClientPacketsSent[{#MAC}@{#DOT1RADIO_IFNAME}:{#SSID}]</key>
                                    </item>
                                </graph_item>
                            </graph_items>
                        </graph_prototype>
                        <graph_prototype>
                            <name>cDot11ClientSignal [ {#MAC}@{#DOT1RADIO_IFNAME}:{#SSID} ]</name>
                            <graph_items>
                                <graph_item>
                                    <sortorder>1</sortorder>
                                    <color>1A7C11</color>
                                    <item>
                                        <host>Template Module Cisco CISCO-DOT11-ASSOCIATION-MIB</host>
                                        <key>cDot11ClientSignalStrength[{#MAC}@{#DOT1RADIO_IFNAME}:{#SSID}]</key>
                                    </item>
                                </graph_item>
                                <graph_item>
                                    <sortorder>2</sortorder>
                                    <color>F63100</color>
                                    <yaxisside>RIGHT</yaxisside>
                                    <item>
                                        <host>Template Module Cisco CISCO-DOT11-ASSOCIATION-MIB</host>
                                        <key>cDot11ClientSigQuality[{#MAC}@{#DOT1RADIO_IFNAME}:{#SSID}]</key>
                                    </item>
                                </graph_item>
                            </graph_items>
                        </graph_prototype>
                        <graph_prototype>
                            <name>cDot11ClientUpTime [ {#MAC}@{#DOT1RADIO_IFNAME}:{#SSID} ]</name>
                            <graph_items>
                                <graph_item>
                                    <sortorder>1</sortorder>
                                    <drawtype>FILLED_REGION</drawtype>
                                    <color>1A7C11</color>
                                    <item>
                                        <host>Template Module Cisco CISCO-DOT11-ASSOCIATION-MIB</host>
                                        <key>cDot11ClientUpTime[{#MAC}@{#DOT1RADIO_IFNAME}:{#SSID}]</key>
                                    </item>
                                </graph_item>
                            </graph_items>
                        </graph_prototype>
                    </graph_prototypes>
                    <preprocessing>
                        <step>
                            <type>JAVASCRIPT</type>
                            <params>debugPrefix = "TESTING\n"
Zabbix.Log(3, "------------------------")
Zabbix.Log(3, debugPrefix + "this is a log entry written with 'Warning' log level")
Zabbix.Log(3, debugPrefix  + value)
Zabbix.Log(3, "------------------------")


var records = JSON.parse(value);

for (i = 0; i < records.length; i++) {
    var OID = records[i]["{#SNMPINDEX}"].split('.')
    // IFINDEX AND IFNAME
    var dot1RadioIfIndex = OID.shift();
    records[i]['{#DOT1RADIO_IFINDEX}'] = dot1RadioIfIndex
    records[i]['{#DOT1RADIO_IFNAME}'] = "Dot11Radio" + (parseInt(dot1RadioIfIndex) - 1).toString()

    // get mac as 6 last digits converted dec -> hex and joined with ':'
    var MAC = ""
    var MACDigitHex
    for (j = 0; j < 6; j++) {
        MACDigitDec = OID.pop();

        MACDigitHex = parseInt(MACDigitDec).toString(16);
        MAC = MACDigitHex + " " + MAC
    }
    records[i]['{#MAC}'] = MAC.trim().split(" ").join(":")

    // SSID. The first octet is length, others are ASCII characters 
    SSID = ""
    ssidLength = OID.shift();
    
    for (j = 0; j < ssidLength; j++) {
      SSID += String.fromCharCode(parseInt(OID[j]));

    }
    records[i]['{#SSID}'] = SSID
}
Zabbix.Log(3, "------------------------")
Zabbix.Log(3, JSON.stringify(records))
return JSON.stringify(records);

//return value


</params>
                        </step>
                    </preprocessing>
                </discovery_rule>
            </discovery_rules>
            <screens>
                <screen>
                    <name>Clients</name>
                    <hsize>1</hsize>
                    <vsize>5</vsize>
                    <screen_items>
                        <screen_item>
                            <resourcetype>20</resourcetype>
                            <style>0</style>
                            <resource>
                                <name>cDot11ClientBytes [ {#MAC}@{#DOT1RADIO_IFNAME}:{#SSID} ]</name>
                                <host>Template Module Cisco CISCO-DOT11-ASSOCIATION-MIB</host>
                            </resource>
                            <width>1500</width>
                            <height>200</height>
                            <x>0</x>
                            <y>0</y>
                            <colspan>1</colspan>
                            <rowspan>1</rowspan>
                            <elements>0</elements>
                            <valign>0</valign>
                            <halign>0</halign>
                            <dynamic>0</dynamic>
                            <sort_triggers>0</sort_triggers>
                            <url/>
                            <application/>
                            <max_columns>3</max_columns>
                        </screen_item>
                        <screen_item>
                            <resourcetype>20</resourcetype>
                            <style>0</style>
                            <resource>
                                <name>cDot11ClientSignal [ {#MAC}@{#DOT1RADIO_IFNAME}:{#SSID} ]</name>
                                <host>Template Module Cisco CISCO-DOT11-ASSOCIATION-MIB</host>
                            </resource>
                            <width>1500</width>
                            <height>200</height>
                            <x>0</x>
                            <y>1</y>
                            <colspan>1</colspan>
                            <rowspan>1</rowspan>
                            <elements>0</elements>
                            <valign>0</valign>
                            <halign>0</halign>
                            <dynamic>0</dynamic>
                            <sort_triggers>0</sort_triggers>
                            <url/>
                            <application/>
                            <max_columns>3</max_columns>
                        </screen_item>
                    </screen_items>
                </screen>
            </screens>
        </template>
    </templates>
</zabbix_export>