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 Cisco Catalyst switch using 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 defined set of devices to gather health information like CPU, power supply, memory and file-system usage.

References

Milosz Galazka's Picture

About Milosz Galazka

Milosz is a Linux Foundation Certified Engineer working for a successful Polish company as a system administrator and a long time supporter of Free Software Foundation and Debian operating system.

Gdansk, Poland https://sleeplessbeastie.eu