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

в 12:59, , рубрики: Cisco, snmp, оптический сенсор, Сетевые технологии, системное администрирование, трансивер

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

#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

Автор: Ceiyzr

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js