Уровень сигнала трансивера через SNMP в Cisco

от автора

Иногда нужно узнать уровень сигнала в трансивере. Причины бывают разные: внезапное падение канала связи, подключение новых оптических кроссировок, мониторинг. Инженер с необходимым уровнем доступа решает этот вопрос меньше чем за одну минуту с помощью команды:

#show interfaces Te1/49 transceiver !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!                                  Optical   Optical            Temperature  Voltage  Tx Power  Rx Power Port       (Celsius)    (Volts)  (dBm)     (dBm) ---------  -----------  -------  --------  -------- Te1/49       53.3       3.25      -4.3      -2.8 

Кому-то (у кого нет соответствующего доступа) приходится ждать этой минуты целую вечность. Например, когда канал упал в пиковые часы и на резервном линке какие-то потери, которые обнаружились только при загрузке линка трафиком. Или когда новый канал нужно было сдать вчера, а ничего не работает, потому что поставщик неправильно подписал оптику на CWDM-мультиплексоре, и требуется методом тыка отыскать «правильную волну». И все это происходит в условиях дефицита верховных сетевых инженеров и времени.

В статье рассматривается вариант того, как проверить сигнал, имея лишь read-only доступ по SNMP. Ждать при этом приходится не более 10 минут (обычный период обновления соответвтующей переменной). Выделение такого доступа кажется более безопаным логичным для ряда сотрудников, которые по тем или иным причинам не имеют CCNA или CCNP (инженеры мониторинга, операционисты, технические менеджеры). Так же информация может быть полезна при настройке систем мониторинга.

Дано

  • хост с IP-адресом, который имеет read-only доступ по SNMP к нескольким Cisco (7604, 7609, 4948-10GE)
  • IP-адрес устройства Cisco (например, 10.0.7.35)
  • номер порта (например, Te1/49)

Найти

  • уровень сигнала трансивера, установленного в заданный порт

Решение

Для начала найдем нужный OID. Он будет состоять из ID «entSensorValue» и «индекса» самого сенсора. Последний можно найти, выполнив следующий запрос с хоста, который имеет доступ по snmp к сетевому устройству с management IP 10.0.7.35:

$ snmpwalk -v 2c -c community 10.0.7.35  1.3.6.1.2.1.47.1.1.1.1.7 | grep Te1/49 SNMPv2-SMI::mib-2.47.1.1.1.1.7.1107 = STRING: "Te1/49 Module Temperature Sensor" SNMPv2-SMI::mib-2.47.1.1.1.1.7.1157 = STRING: "Te1/49 Supply Voltage Sensor" SNMPv2-SMI::mib-2.47.1.1.1.1.7.1207 = STRING: "Te1/49 Bias Current Sensor" SNMPv2-SMI::mib-2.47.1.1.1.1.7.1257 = STRING: "Te1/49 Transmit Power Sensor" SNMPv2-SMI::mib-2.47.1.1.1.1.7.1307 = STRING: "Te1/49 Receive Power Sensor" 

Воспользуемся последним числом в OID для «Te1/49 Transmit Power Sensor» и «Te1/49 Receive Power Sensor». Это соответственно 1257 и 1307. Используя эти числа, мы сразу можем получить уровень исходящего и входящего оптического сигнала (value):

$ snmpget -v 2c -c community 10.0.7.35 1.3.6.1.4.1.9.9.91.1.1.1.1.4.1257 SNMPv2-SMI::enterprises.9.9.91.1.1.1.1.4.1257 = INTEGER: -28 $ snmpget -v 2c -c community 10.0.7.35 1.3.6.1.4.1.9.9.91.1.1.1.1.4.1307 SNMPv2-SMI::enterprises.9.9.91.1.1.1.1.4.1307 = INTEGER: -35 

Комбинируя аналогичным образом «entSensorPrecision» и «индекс» сенсора, находим точность измерения (количество знаков после запятой):

$ snmpget -v 2c -c community 10.0.7.35 1.3.6.1.4.1.9.9.91.1.1.1.1.3.1257 SNMPv2-SMI::enterprises.9.9.91.1.1.1.1.3.1257 = INTEGER: 1 $ snmpget -v 2c -c community 10.0.7.35 1.3.6.1.4.1.9.9.91.1.1.1.1.3.1307 SNMPv2-SMI::enterprises.9.9.91.1.1.1.1.3.1307 = INTEGER: 1 

Цифра «1» в этом случае означает, что нужно поставить запятую перед одной цифрой справа в значении соответствующего сенсора.
Te1/49 Transmit Power = -2,8
Te1/49 Receive Power = -3,5

Чтобы определить единицы измерения, воспользуемся «entSensorType» в комбинации с «индексом» сенсора:

$ snmpget -v 2c -c community 10.0.7.35 1.3.6.1.4.1.9.9.91.1.1.1.1.1.1257 SNMPv2-SMI::enterprises.9.9.91.1.1.1.1.1.1257 = INTEGER: 14 $ snmpget -v 2c -c community 10.0.7.35 1.3.6.1.4.1.9.9.91.1.1.1.1.1.1307 SNMPv2-SMI::enterprises.9.9.91.1.1.1.1.1.1307 = INTEGER: 14 

Значение 14 соответсвует единицам «dBm». Список значений дается в описании «entSensorType».
К единицам измерения может быть добавлена десятичная приставка. Какая именно — покажет «entSensorScale»:

$ snmpget -v 2c -c community 10.0.7.35 1.3.6.1.4.1.9.9.91.1.1.1.1.2.1257 SNMPv2-SMI::enterprises.9.9.91.1.1.1.1.2.1257 = INTEGER: 9 $ snmpget -v 2c -c community 10.0.7.35 1.3.6.1.4.1.9.9.91.1.1.1.1.2.1307 SNMPv2-SMI::enterprises.9.9.91.1.1.1.1.2.1307 = INTEGER: 9 

В данном случае приставка «Units» (которая соответствует числу 9) фактически означает отсутствие приставки.
Таким образом, мы получили уровень сигнала трансивера, установленного в порту Te1/49, на свиче с IP 10.0.7.35

Te1/49 Transmit Power = -2,8 dBm
Te1/49 Receive Power = -3,5 dBm

Составим ответ по учебнику:

light.bash

#!/bin/bash E_OPTERROR=65 verbose=0  get_type () {         if [ -z "$1" ]           # Length of argument is 0?         then                 exit $E_OPTERROR         elif [ "$1" -eq "1" ]         then truetype=other         elif [ "$1" -eq "2" ]         then truetype=unknown         elif [ "$1" -eq "3" ]         then truetype=voltsAC         elif [ "$1" -eq "4" ]         then truetype=voltsDC         elif [ "$1" -eq "5" ]         then truetype=amperes         elif [ "$1" -eq "6" ]         then truetype=watts         elif [ "$1" -eq "7" ]         then truetype=hertz         elif [ "$1" -eq "8" ]         then truetype=celsius         elif [ "$1" -eq "9" ]         then truetype=percentRH         elif [ "$1" -eq "10" ]         then truetype="rpm"         elif [ "$1" -eq "11" ]         then truetype=cmm         elif [ "$1" -eq "12" ]         then truetype=truthvalue         elif [ "$1" -eq "13" ]         then truetype=specialEnum         elif [ "$1" -eq "14" ]         then truetype=dBm         else echo type=$1,error; exit $E_OPTERROR         fi         return 0 }  get_scale () {         if [ -z "$1" ]     # Length of argument is 0?         then                 exit $E_OPTERROR         elif [ "$1" -eq "1" ]         then truescale=yocto         elif [ "$1" -eq "2" ]         then truescale=zepto         elif [ "$1" -eq "3" ]         then truescale=atto         elif [ "$1" -eq "4" ]         then truescale=femto         elif [ "$1" -eq "5" ]         then truescale=pico         elif [ "$1" -eq "6" ]         then truescale=nano         elif [ "$1" -eq "7" ]         then truescale=micro         elif [ "$1" -eq "8" ]         then truescale=milli         elif [ "$1" -eq "9" ]         then truescale=""         elif [ "$1" -eq "10" ]         then truescale=kilo         elif [ "$1" -eq "11" ]         then truescale=mega         elif [ "$1" -eq "12" ]         then truescale=giga         elif [ "$1" -eq "13" ]         then truescale=tera         elif [ "$1" -eq "14" ]         then truescale=exa         elif [ "$1" -eq "15" ]         then truescale=peta         elif [ "$1" -eq "16" ]         then truescale=zetta         elif [ "$1" -eq "17" ]         then truescale=yotta         else echo scale=$1,error; exit $E_OPTERROR         fi         return 0 } #reading the options while getopts ":c:h:i:v" Option do #echo $OPTIND   case $Option in     c     ) community=$OPTARG;;     h     ) host=$OPTARG;;     i     ) interface=$OPTARG;;     v     ) echo "Verbose mode is set";verbose=1;;     *     ) echo "Usage: `basename $0` -c community -h host -i interface"; exit $E_OPTERROR;;   # default options   esac done shift $(($OPTIND - 1)) #moving on to the next provided option if [ -z "$community" ] || [ -z $host ] || [ -z $interface ]  # if some of options is not submitted then           echo "Usage: `basename $0` -c community -h host -i interface"             exit $E_OPTERROR         fi if [ $verbose -eq 1 ] then         echo "community is \"$community\""         echo "host is \"$host\""         echo "interface is \"$interface\"" fi #looking for the index of sensor if [ $verbose -eq 1 ] then                 echo "executing snmpwalk" fi # step1: getiing information from device walksnmp=`snmpwalk -v 2c -c $community $host  1.3.6.1.2.1.47.1.1.1.1.7 | grep $interface` # step2: parse received string if [ $verbose -eq 1 ] then         echo "parsing snmpwalk result" fi rx_string=`echo $walksnmp | grep -o -e "[0-9]* = STRING: \"[ 0-9\/a-zA-Z]*Receive[ 0-9\/a-zA-Z]*\""` rx_sensor=`echo $walksnmp | grep -o -e "[0-9]* = STRING: \"[ 0-9\/a-zA-Z]*Receive[ 0-9\/a-zA-Z]*\"" | cut -f1 -d " "` tx_string=`echo $walksnmp | grep -o -e "[0-9]* = STRING: \"[ 0-9\/a-zA-Z]*Transmit[ 0-9\/a-zA-Z]*\""` tx_sensor=`echo $walksnmp | grep -o -e "[0-9]* = STRING: \"[ 0-9\/a-zA-Z]*Transmit[ 0-9\/a-zA-Z]*\"" | cut -f1 -d " "` if [ $verbose -eq 1 ] then         echo "index of rx_sensor parsed to $rx_sensor"         echo "index of tx_sensor parsed to $tx_sensor"         echo "$rx_string"         echo "$tx_string" fi #getting the sensor value if [ $verbose -eq 1 ] then         echo "getting the sensor value" fi rx_value=`snmpget -v 2c -c $community $host 1.3.6.1.4.1.9.9.91.1.1.1.1.4.$rx_sensor | grep -o -e "INTEGER: [-+0-9]*" | cut -f2 -d" "`   rx_precision=`snmpget -v 2c -c $community $host 1.3.6.1.4.1.9.9.91.1.1.1.1.3.$rx_sensor | grep -o -e "INTEGER: [-+0-9]*" | cut -f2 -d" "`     rx_type=`snmpget -v 2c -c $community $host 1.3.6.1.4.1.9.9.91.1.1.1.1.1.$rx_sensor | grep -o -e "INTEGER: [-+0-9]*" | cut -f2 -d" "`     get_type $rx_type     rx_type=$truetype       rx_scale=`snmpget -v 2c -c $community $host 1.3.6.1.4.1.9.9.91.1.1.1.1.2.$rx_sensor | grep -o -e "INTEGER: [-+0-9]*" | cut -f2 -d" "`       get_scale $rx_scale       rx_scale=$truescale tx_value=`snmpget -v 2c -c $community $host 1.3.6.1.4.1.9.9.91.1.1.1.1.4.$tx_sensor | grep -o -e "INTEGER: [-+0-9]*" | cut -f2 -d" "`   tx_precision=`snmpget -v 2c -c $community $host 1.3.6.1.4.1.9.9.91.1.1.1.1.3.$tx_sensor | grep -o -e "INTEGER: [-+0-9]*" | cut -f2 -d" "`     tx_type=`snmpget -v 2c -c $community $host 1.3.6.1.4.1.9.9.91.1.1.1.1.1.$tx_sensor | grep -o -e "INTEGER: [-+0-9]*" | cut -f2 -d" "`     get_type $tx_type     tx_type=$truetype       tx_scale=`snmpget -v 2c -c $community $host 1.3.6.1.4.1.9.9.91.1.1.1.1.2.$rx_sensor | grep -o -e "INTEGER: [-+0-9]*" | cut -f2 -d" "`       get_scale $tx_scale       tx_scale=$truescale let lengthrx=${#rx_value}-$rx_precision let lengthtx=${#tx_value}-$tx_precision echo RX=${rx_value:0:$lengthrx}.${rx_value:$lengthrx} $rx_scale$rx_type echo TX=${tx_value:0:$lengthtx}.${tx_value:$lengthtx} $tx_scale$tx_type exit 0 

ссылка на оригинал статьи http://habrahabr.ru/post/260721/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *