Categories
SysOps

How to read interface statistics on Cisco Catalyst switch using SNMP protocol

Today, I will show you how to create a simple shell script to read and print interface statistics on the Cisco Catalyst switch using the SNMP protocol.

Shell script

The following shell script is well described, so I will just jump to the point.

#!/bin/sh
# simple shell script to demonstrate how to read interface statistics
# on Cisco Catalyst switch using SNMP protocol

# SNMP protocol version
snmp_proto="2c"

# SNMP community string
snmp_community="mycommunitystr"

# Cisco Catalyst switch IP address
snmp_addr="192.168.10.11"

# SNMP interface entry OID
snmp_oid="1.3.6.1.2.1.2.2.1"

# temporary filename
snmp_file=$(mktemp)


# read and store interface entries, exit on error
snmpwalk -On -v $snmp_proto -c $snmp_community $snmp_addr $snmp_oid > $snmp_file 2>/dev/null
if [ "$?" -ne "0" ]; then
  exit 1
fi

# get interface indexes
indexes=$(sed -n -e "s/.1.3.6.1.2.1.2.2.1.1.\([0-9]\+\).*/\1/p" $snmp_file)

# get and print statistics for each interface using collected indexes
for index in $indexes; do
  ifDescr=$(sed -n -e "s/.1.3.6.1.2.1.2.2.1.2.${index} = .*: \(.*\)/\1/p" $snmp_file | tr -d \")
  ifType=$(sed -n -e "s/.1.3.6.1.2.1.2.2.1.3.${index} = .*: \(.*\)/\1/p" $snmp_file)
  ifMTU=$(sed -n -e "s/.1.3.6.1.2.1.2.2.1.4.${index} = .*: \(.*\)/\1/p" $snmp_file)
  ifSpeed=$(sed -n -e "s/.1.3.6.1.2.1.2.2.1.5.${index} = .*: \(.*\)/\1/p" $snmp_file)
  ifPhysAddress=$(sed -n -e "s/.1.3.6.1.2.1.2.2.1.6.${index} = .*: \(.*\)/\1/p" $snmp_file | xargs | tr " " ":")
  ifAdminStatus=$(sed -n -e "s/.1.3.6.1.2.1.2.2.1.7.${index} = .*: \(.*\)/\1/p" $snmp_file)
  ifOperStatus=$(sed -n -e "s/.1.3.6.1.2.1.2.2.1.8.${index} = .*: \(.*\)/\1/p" $snmp_file)
  ifLastChange=$(sed -n -e "s/.1.3.6.1.2.1.2.2.1.9.${index} = .*: \(.*\)/\1/p" $snmp_file)
  inOct=$(sed -n -e "s/.1.3.6.1.2.1.2.2.1.10.${index} = .*: \(.*\)/\1/p" $snmp_file)
  inUcastPkts=$(sed -n -e "s/.1.3.6.1.2.1.2.2.1.11.${index} = .*: \(.*\)/\1/p" $snmp_file)
  inDiscards=$(sed -n -e "s/.1.3.6.1.2.1.2.2.1.13.${index} = .*: \(.*\)/\1/p" $snmp_file)
  inErrors=$(sed -n -e "s/.1.3.6.1.2.1.2.2.1.14.${index} = .*: \(.*\)/\1/p" $snmp_file)
  inUnkProt=$(sed -n -e "s/.1.3.6.1.2.1.2.2.1.15.${index} = .*: \(.*\)/\1/p" $snmp_file)
  outOct=$(sed -n -e "s/.1.3.6.1.2.1.2.2.1.16.${index} = .*: \(.*\)/\1/p" $snmp_file)
  outUcastPkts=$(sed -n -e "s/.1.3.6.1.2.1.2.2.1.17.${index} = .*: \(.*\)/\1/p" $snmp_file)
  outDiscards=$(sed -n -e "s/.1.3.6.1.2.1.2.2.1.19.${index} = .*: \(.*\)/\1/p" $snmp_file)
  outErrors=$(sed -n -e "s/.1.3.6.1.2.1.2.2.1.20.${index} = .*: \(.*\)/\1/p" $snmp_file)

  if [ -n "$ifMTU" ] && [ -n "$ifPhysAddress" ]; then
    printf "ifDescr: %s\tifType: %s\nifMTU: %s\tifSpeed: %s\nifPhysAddress: %s\nifAdminStatus: %s\tifOperStatus: %s\nifLastChange: %s\n" "$ifDescr" "$ifType" "$ifMTU" "$ifSpeed" "$ifPhysAddress" "$ifAdminStatus" "$ifOperStatus" "$ifLastChange"
    printf "inOct:  %12s\tinUcastPkts:  %12s\tinDiscards:  %12s\tinErrors:  %12s\n" "$inOct"  "$inUcastPkts"  "$inDiscards"  "$inErrors"
    printf "outOct: %12s\toutUcastPkts: %12s\toutDiscards: %12s\toutErrors: %12s\n" "$outOct" "$outUcastPkts" "$outDiscards" "$outErrors"
    printf "inUnkProt:  %s\n" "$inUnkProt"
  else
    printf "ifDescr: %s\tifType: %s\nifAdminStatus: %s\tifOperStatus: %s\n" "$ifDescr" "$ifType" "$ifAdminStatus" "$ifOperStatus"
  fi
  echo
done

# remove temporary file
unlink $snmp_file

Sample output

Store the above shell script as the read_interface_data.sh file and execute it after changing settings.

$ read_interface_data.sh
[..]
ifDescr: GigabitEthernet3/0/13  ifType: ethernetCsmacd(6)
ifMTU: 1500     ifSpeed: 10000000
ifPhysAddress: 3C:0E:23:19:11:8E
ifAdminStatus: up(1)    ifOperStatus: down(2)
ifLastChange: (542969009) 62 days, 20:14:50.09
inOct:             0    inUcastPkts:             0      inDiscards:             0       inErrors:             0
outOct:            0    outUcastPkts:            0      outDiscards:            0       outErrors:            0
inUnkProt:  0

ifDescr: GigabitEthernet3/0/14  ifType: ethernetCsmacd(6)
ifMTU: 1500     ifSpeed: 10000000
ifPhysAddress: 3C:0E:23:19:11:8F
ifAdminStatus: up(1)    ifOperStatus: up(1)
ifLastChange: (542977157) 62 days, 20:16:11.57
inOct:     148218577    inUcastPkts:       2315821      inDiscards:             0       inErrors:             1
outOct:    368154381    outUcastPkts:      2429378      outDiscards:            0       outErrors:            0
inUnkProt:  0
[..]

You can use standard Linux utilities to filter out desired data.

$ read_interface_data.sh | grep Virtual
ifDescr: Vlan200	ifType: propVirtual(53)
ifDescr: Vlan300	ifType: propVirtual(53)
ifDescr: StackPort1	ifType: propVirtual(53)
ifDescr: StackSub-St1-1	ifType: propVirtual(53)
ifDescr: StackSub-St1-2	ifType: propVirtual(53)
ifDescr: StackPort2	ifType: propVirtual(53)
ifDescr: StackSub-St2-1	ifType: propVirtual(53)
ifDescr: StackSub-St2-2	ifType: propVirtual(53)
ifDescr: StackPort3	ifType: propVirtual(53)
ifDescr: StackSub-St3-1	ifType: propVirtual(53)
ifDescr: StackSub-St3-2	ifType: propVirtual(53)
$ read_interface_data.sh | sed -n "/ifDescr/p;/Adm/{G;p}"
[..]
ifDescr: GigabitEthernet3/0/13	ifType: ethernetCsmacd(6)
ifAdminStatus: up(1)	ifOperStatus: down(2)

ifDescr: GigabitEthernet3/0/14	ifType: ethernetCsmacd(6)
ifAdminStatus: up(1)    ifOperStatus: up(1)
[..]

The idea is quite simple, so you can easily modify the shell script to iterate over a defined set of devices to gather health information like CPU, power supply, memory, and file-system usage.

References