miércoles, 12 de agosto de 2009

TCL y SNMP en routers Cisco

Posted by Nicolas | miércoles, 12 de agosto de 2009 | Category: , , |

TCL (Tool Command Language) es un lenguaje de programación cuya versión 8.3.4 puede ser ejecutada desde la línea de comandos (CLI) de un router Cisco, dependiendo eso si de la versión de IOS. Cisco documenta su uso en Cisco IOS Scripting with Tcl. Ivan Pepelnjak, por su parte, escribió un tutorial en Tclsh on Cisco IOS tutorial así como más de cincuenta posts al respecto en su blog.

Algunos comandos básicos son:

  • tclsh: Para ingresar al modo interactivo de TCL (debe ser ejecutado en modo EXEC privilegiado)
  • tclquit: Para salir al modo interactivo de TCL (debe ser ejecutado en modo EXEC privilegiado)
  • exec: Ejecuta comando en modo EXEC.
  • ios_config: Comandos en modo de configuración.
R3#tclsh
R3(tcl)#exec "show version | include IOS"
Cisco IOS Software, 7200 Software (C7200-ADVIPSERVICESK9-M), Version 12.4(22)T, RELEASE SOFTWARE (fc1)

R3(tcl)#ios_config "interface Loopback0" "shutdown"

R3(tcl)#
*Aug 11 12:31:00.645: %LINK-5-CHANGED: Interface Loopback0, changed state to administratively down
*Aug 11 12:31:01.645: %LINEPROTO-5-UPDOWN: Line protocol on Interface Loopback0, changed state to down

R3(tcl)#exec "show interface Loopback 0 | include protocol"
Loopback0 is administratively down, line protocol is down
0 unknown protocol drops

R3(tcl)#tclquit
R3#

No se entrará en más detalles de cómo programar en TCL puesto que se escapa de nuestro propósito. Se recomienda revisar por ejemplo la definición de TCL en Wikipedia en Español, para descubrir herramientas que permitan generar scripts más interesantes. Por ejemplo para un sencillo chequeo de conectividad se puede utilizar un código como el que sigue:

tclsh
proc PingTest {} {
for {set i 2} {$i < 5} {incr i} {
puts [ exec "ping 10.$i.$i.$i repeat 2"] }
}

Que aplicado genera:

R4#tclsh
R4(tcl)#proc PingTest {} {

+>(tcl)#for {set i 2} {$i < 5} {incr i} {
+>(tcl)#puts [ exec "ping 10.$i.$i.$i repeat 2"] }
+>(tcl)#}

R4(tcl)#PingTest

Type escape sequence to abort.
Sending 2, 100-byte ICMP Echos to 10.2.2.2, timeout is 2 seconds:
!!
Success rate is 100 percent (2/2), round-trip min/avg/max = 36/82/128 ms

Type escape sequence to abort.
Sending 2, 100-byte ICMP Echos to 10.3.3.3, timeout is 2 seconds:
!!
Success rate is 100 percent (2/2), round-trip min/avg/max = 192/204/216 ms

Type escape sequence to abort.
Sending 2, 100-byte ICMP Echos to 10.4.4.4, timeout is 2 seconds:
!!
Success rate is 100 percent (2/2), round-trip min/avg/max = 4/4/4 ms

R4#

Para ejemplos más complejos se puede revisar el documento escrito por Peter J. Welcher; TCL'ing Your Cisco Router.

Antes de entrelazar este lenguaje y el protocolo SNMP (RFC 1157) se verá una pequeña introducción a los OID de éste. La configuración del protocolo en sí para permitir que los sistemas de administración recopilen datos del equipo se detalla en Configuring SNMP Support.

Un buen lugar para comenzar es OID assignments from the top node, donde se puede explorar el árbol de las MIBs que los OID identifican. La mayoría de las MIBs que se utilizan parten con .1.3.6.1.2.1 (SNMP MIB-2), que en palabras (y números) sería: .iso(1).org(3).dod(6).internet(1).mgmt(2).mib-2(1). Entre otras MIBs acá se encuentran:

1.3.6.1.2.1.1 - SNMP MIB-2 System
1.3.6.1.2.1.2 - SNMP MIB-2 Interfaces
1.3.6.1.2.1.3 - at
1.3.6.1.2.1.4 - ip
1.3.6.1.2.1.5 - icmp
1.3.6.1.2.1.6 - tcp
1.3.6.1.2.1.7 - udp
1.3.6.1.2.1.8 - egp
1.3.6.1.2.1.9 - cmot
1.3.6.1.2.1.10 - transmission
1.3.6.1.2.1.11 - snmp
1.3.6.1.2.1.14 - OSPF Version 2 MIB
1.3.6.1.2.1.15 - BGPv4

Además cada vendor publica sus propias MIBs específicas a partir de .1.3.6.1.4.1 (IANA-registered Private Enterprises) cuya asignación se puede revisar en: PRIVATE ENTERPRISE NUMBERS. Entres otras se tiene:

1.3.6.1.4.1.2 - IBM
1.3.6.1.4.1.9 - Cisco
1.3.6.1.4.1.1991 - Foundry Networks
1.3.6.1.4.1.2011 - Huawei-3Com
1.3.6.1.4.1.2636 - JuniperMIB

Entendiendo esto se puede añadir a los scripts de TCL información específica del equipo. A continuación un par de ejemplos sencillos. Primero veremos cómo obtener la utilización de CPU de nuestro router Cisco. En How to Collect CPU Utilization on Cisco IOS Devices Using SNMP se especifican los OID cpmCPUTotal1minRev (.1.3.6.1.4.1.9.9.109.1.1.1.1.7) y cpmCPUTotal5minRev (.1.3.6.1.4.1.9.9.109.1.1.1.1.8) para IOS 12.2(3.5) o posterior. Se obtendrán estos valores utilizando snmp_getnext.

router#sh proc cpu sort | e 0.00
CPU utilization for five seconds: 6%/2%; one minute: 6%; five minutes: 7%
PID Runtime(ms) Invoked uSecs 5Sec 1Min 5Min TTY Process
161 112248 327754883 0 1.06% 1.09% 1.13% 0 HQF Shaper Backg
190 1704 1854 919 0.90% 0.23% 0.24% 514 Virtual Exec
3 51154976 98581304 518 0.40% 0.63% 0.72% 0 Skinny Msg Serve
102 40918976 113690709 359 0.24% 0.35% 0.33% 0 IP Input
101 52780 578783459 0 0.16% 0.12% 0.09% 0 IP ARP Retry Age
95 56116 578783464 0 0.08% 0.11% 0.14% 0 ACCT Periodic Pr
2 10964 3715535 2 0.08% 0.04% 0.02% 0 Load Meter
19 6485540 24835008 261 0.08% 0.02% 0.01% 0 ARP Input

Gateway#tclsh                             
Gateway(tcl)#snmp_getnext SNMP 1.3.6.1.4.1.9.9.109.1.1.1.1.7
{<obj oid='cpmCPUTotalTable.1.7.1' val='6'/>}
Gateway(tcl)#snmp_getnext SNMP 1.3.6.1.4.1.9.9.109.1.1.1.1.8
{<obj oid='cpmCPUTotalTable.1.8.1' val='7'/>}
Gateway(tcl)#tclquit
Gateway#

A continuación un nuevo output utilizando snmp_getbulk.

R3(tcl)#$snmp_getbulk SNMP 1 14 1.3.6.1.2.1.2.1  1.3.6.1.2.1.2.2.1.2 1.3.6.1.2.1.2.2.1.8
{<obj oid="'ifNumber.0'" val="'14'/">}
{<obj oid="'ifDescr.1'" val="'FastEthernet0/0'/">}
{<obj oid="'ifOperStatus.1'" val="'2'/">}
{<obj oid="'ifDescr.2'" val="'Serial1/0'/">}
{<obj oid="'ifOperStatus.2'" val="'2'/">}
{<obj oid="'ifDescr.3'" val="'Serial1/1'/">}
{<obj oid="'ifOperStatus.3'" val="'1'/">}
{<obj oid="'ifDescr.4'" val="'Serial1/2'/">}
{<obj oid="'ifOperStatus.4'" val="'2'/">}
{<obj oid="'ifDescr.5'" val="'Serial1/3'/">}
{<obj oid="'ifOperStatus.5'" val="'2'/">}
...

El primer OID (1.3.6.1.2.1.2.1) corresponde a ifNumber que según la descripción del RFC 2863 corresponde a "The number of network interfaces (regardless of their current state) present on this system", que en nuestro caso son 14 (por eso se utilizó ese valor en los argumentos de snmp_getbulk). El segundo OID (1.3.6.1.2.1.2.2.1.2) corresponde a ifDescr y el tercero (1.3.6.1.2.1.2.2.1.8) a ifOperStatus. Si revisamos la definición (formato ASN.1) de este último en el RFC 2863 se tiene:

ifOperStatus OBJECT-TYPE
SYNTAX INTEGER {
up(1), -- ready to pass packets
down(2),
testing(3), -- in some test mode
unknown(4), -- status can not be determined
-- for some reason.
dormant(5),
notPresent(6), -- some component is missing
lowerLayerDown(7) -- down due to state of
-- lower-layer interface(s)
}
...

Por lo que del output anterior se tiene que la interface Serial1/1 está arriba (up).

Por último un par de comandos en Unix que pueden ser útiles para trabajar con SNMP; snmpwalk y snmptranslate.

nicolas@server:~$ snmpwalk -v1 -On -c SNMP X.X.X.X  interfaces.ifTable.ifEntry.ifDescr
.1.3.6.1.2.1.2.2.1.2.1 = STRING: FastEthernet0/0
.1.3.6.1.2.1.2.2.1.2.2 = STRING: FastEthernet0/1
.1.3.6.1.2.1.2.2.1.2.3 = STRING: Null0
.1.3.6.1.2.1.2.2.1.2.4 = STRING: FastEthernet0/1.80-802.1Q vLAN subif
.1.3.6.1.2.1.2.2.1.2.5 = STRING: FastEthernet0/1.350-802.1Q vLAN subif

nicolas@server:~$ snmptranslate -Of .1.3.6.1.2.1.2.2.1.8
.iso.org.dod.internet.mgmt.mib-2.interfaces.ifTable.ifEntry.ifOperStatus

En total 0 comentarios:


Leave a Reply