Иногда нужно узнать уровень сигнала в трансивере. Причины бывают разные: внезапное падение канала связи, подключение новых оптических кроссировок, мониторинг. Инженер с необходимым уровнем доступа решает этот вопрос меньше чем за одну минуту с помощью команды:
#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
Составим ответ по учебнику:
#!/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