Getting Started with Expect

NetCraftsmen®

 1. Reference Material

One of the best references for Expect is the “Exploring Expect” book published by O’Reilly. I’ll be adding page number references from the book to the sections below.

Another good reference is the included help files with ActiveState Expect.

 2. Downloading and Installing ActiveState TCL with Expect Extensions

One way to learn how to use Expect is to use the free version, from ActiveState, on your Windows PC. This provides the opportunity to learn how TCL and Expect work and test scripts before deploying within NCM. Use the following steps to download and install Expect

  1. Go to http://www.activestate.com and download the free TCL application
  2. Install TCL
  3. Open a command prompt
  4. Type “teacup install Expect” to install the Expect extension to TCL

 3. Create Your First Script

Now that TCL and Expect are installed, you can run through the following test script to see how Expect works. This test script shows how to telnet to a router and execute “show version”. Within the example script, replace anything in red with the appropriate information from your test router.

There are minor differences between this script and the script executed within NCM. The one main difference is the use of the “exp_send” command. Within NCM, this should just be “send”.

    1. Open Notepad
    2. Paste the following script into Notepad and save as sample.txt. This script assumes that you have AAA turned on an authorization set to have the user authorized into privileged exec mode. If this configuration is not already entered, you can add it by entering the following to add AAA with local authentication and authorization

aaa new-model

!

aaa authentication login default local

aaa authorization exec default local

!

username cisco privilege 15 password cisco

Script

#!/bin/sh

#

exec tclsh “$0″ ${1+”$@”}

package require Expect

log_user 1

spawn telnet 192.168.137.100

expect “Username” {

exp_send “cisco “

}

expect “assword” {

exp_send “cisco “

}

expect “R1#”

exp_send “terminal length 0 “

expect “R1#”

exp_send “sh version “

expect “R1#”

exp_send “exit “

    1. Run the script by opening a command prompt, navigating to the directory with the script, and executing “tclsh85 sample.txt”. The output of the script should look similar to the following

C:Tcl>tclsh85 showversion.txt

Welcome to Microsoft Telnet Client

Escape Character is ‘CTRL+]’

Connecting To 192.168.137.100…

Put something here

User Access Verification

Username: cisco

Password:

R1#terminal length 0

R1#sh version

Cisco IOS Software, 3600 Software (C3640-JK9O3S-M), Version 12.4(13a), RELEASE S

OFTWARE (fc1)

Technical Support: http://www.cisco.com/techsupport

Copyright (c) 1986-2007 by Cisco Systems, Inc.

Compiled Tue 06-Mar-07 20:25 by prod_rel_team

ROM: ROMMON Emulation Microcode

ROM: 3600 Software (C3640-JK9O3S-M), Version 12.4(13a), RELEASE SOFTWARE (fc1)

R1 uptime is 5 minutes

System returned to ROM by unknown reload cause – suspect boot_data[BOOT_COUNT] 0

x0, BOOT_COUNT 0, BOOTDATA 19

System image file is “tftp://255.255.255.255/unknown”

This product contains cryptographic features and is subject to United

States and local country laws governing import, export, transfer and

use. Delivery of Cisco cryptographic products does not imply

third-party authority to import, export, distribute or use encryption.

Importers, exporters, distributors and users are responsible for

compliance with U.S. and local country laws. By using this product you

agree to comply with applicable laws and regulations. If you are unable

to comply with U.S. and local laws, return this product immediately.

A summary of U.S. laws governing Cisco cryptographic products may be found at:

http://www.cisco.com/wwl/export/crypto/tool/stqrg.html

If you require further assistance please contact us by sending email to

export@cisco.com.

Cisco 3640 (R4700) processor (revision 0xFF) with 124928K/6144K bytes of memory.

Processor board ID 00000000

R4700 CPU at 100MHz, Implementation 33, Rev 1.2

17 FastEthernet interfaces

DRAM configuration is 64 bits wide with parity enabled.

125K bytes of NVRAM.

8192K bytes of processor board System flash (Read/Write)

Configuration register is 0x2102

R1#

C:Tcl>

 4. Regular Expressions

Expect scripts normally include the use of regular expressions to evaluate output from routers and switches. The best way to show how this works is through a simple example. Let’s take the output from “show interface fa1/0”. Here’s the output to use as a reference for the example to follow.

R1#sh int fa1/10

FastEthernet1/10 is up, line protocol is down

Hardware is Fast Ethernet, address is cc00.1264.f10a (bia cc00.1264.f10a)

MTU 1500 bytes, BW 100000 Kbit, DLY 100 usec,

reliability 255/255, txload 1/255, rxload 1/255

Encapsulation ARPA, loopback not set

Keepalive set (10 sec)

Auto-duplex, Auto-speed

ARP type: ARPA, ARP Timeout 04:00:00

Last input never, output never, output hang never

Last clearing of “show interface” counters never

Input queue: 0/75/0/0 (size/max/drops/flushes); Total output drops: 0

Queueing strategy: fifo

Output queue: 0/40 (size/max)

5 minute input rate 0 bits/sec, 0 packets/sec

5 minute output rate 0 bits/sec, 0 packets/sec

0 packets input, 0 bytes, 0 no buffer

Received 0 broadcasts, 0 runts, 0 giants, 0 throttles

0 input errors, 0 CRC, 0 frame, 0 overrun, 0 ignored

0 input packets with dribble condition detected

0 packets output, 0 bytes, 0 underruns

0 output errors, 0 collisions, 2 interface resets

0 babbles, 0 late collision, 0 deferred

0 lost carrier, 0 no carrier

0 output buffer failures, 0 output buffers swapped out

With this script, we want to evaluate the up/down state of the interface and line protocol and exit out of the script with an error message if either the interface or line are down.

#!/bin/sh

#

exec tclsh “$0″ ${1+”$@”}

package require Expect

log_user 1

spawn telnet 192.168.137.100

expect “Username” {

exp_send “cisco “

}

expect “assword” {

exp_send “cisco “

}

expect “R1#” {

exp_send “sh int fa1/10 “

}

expect {

-re “is ([a-z]*), line protocol is ([a-z]*)” {

set int_status $expect_out(1,string)

set line_status $expect_out(2,string)

exp_continue

}

“R1#” {

exp_send “exit “

}

}

if {$int_status == “down” || $line_status == “down”} {

puts ” !!!Interface is down!!! “

exit 1

}

else {

puts ” !!!Interface is up!!! “

exit 0

}

Let’s look at the regular expression portion of the script

expect {

-re “is ([a-z]*), line protocol is ([a-z]*)” {

set int_status $expect_out(1,string)

set line_status $expect_out(2,string)

exp_continue

}

“R1#” {

exp_send “exit “

}

}

The “-re” specifies that the next portion should be treated as a regular expression (pg 109 Exploring Expect). The portion [a-z] specifies a single character matching any lower case character. The “*” after the [a-z] specifies a match for the rest of the lower case characters that follow the initial character. You’ll notice that there is a before the first [. This is required, by Expect, to have the [ ] treated correctly as a regular expression delineator (pg 91 Exploring Expect). The () specifiy that anything within them should be treated as a variable. The variable is saved in the line after the regular expression with the line (pg 111 Exploring Expect).

set int_status $expect_out(1,string)

The “1” specifies that it is the first variable created by the (). The second () is captured as the variable “line_status”. You’ll notice that the “1” has been replaced by a “2” in this case (pg 111 Exploring Expect).

The next thing to notice is the “exp_continue” command. This specifies that the expect command that surrounds it should be run until there is no remaining input to be evaluated (pg 145 Exploring Expect).

Here is the output of the script

C:Tcl>tclsh85 sample.tcl

Welcome to Microsoft Telnet Client

Escape Character is ‘CTRL+]’

Connecting To 192.168.137.100…

Put something here

User Access Verification

Username: cisco

Password:

R1#sh int fa1/10

FastEthernet1/10 is up, line protocol is down

Hardware is Fast Ethernet, address is cc00.1264.f10a (bia cc00.1264.f10a)

MTU 1500 bytes, BW 100000 Kbit, DLY 100 usec,

reliability 255/255, txload 1/255, rxload 1/255

Encapsulation ARPA, loopback not set

Keepalive set (10 sec)

Auto-duplex, Auto-speed

ARP type: ARPA, ARP Timeout 04:00:00

Last input never, output never, output hang never

Last clearing of “show interface” counters never

Input queue: 0/75/0/0 (size/max/drops/flushes); Total output drops: 0

Queueing strategy: fifo

Output queue: 0/40 (size/max)

5 minute input rate 0 bits/sec, 0 packets/sec

5 minute output rate 0 bits/sec, 0 packets/sec

0 packets input, 0 bytes, 0 no buffer

Received 0 broadcasts, 0 runts, 0 giants, 0 throttles

0 input errors, 0 CRC, 0 frame, 0 overrun, 0 ignored

0 input packets with dribble condition detected

0 packets output, 0 bytes, 0 underruns

0 output errors, 0 collisions, 2 interface resets

0 babbles, 0 late collision, 0 deferred

0 lost carrier, 0 no carrier

0 output buffer failures, 0 output buffers swapped out

R1#

!!!Interface is down!!!

 5. Limiting Script Output

In the first script, we saw that there was a lot of output. We could limit this output to specific information that we wanted to display. This is done by changing “log_user 1” to “log_user 0″(pg 175 Exploring Expect). Once this is done, specific output can be displayed using the “puts” command. Here is the script from the regular expression section that will only output the interface information

#!/bin/sh

#

exec tclsh “$0″ ${1+”$@”}

package require Expect

log_user 0

spawn telnet 192.168.137.100

expect “Username” {

exp_send “cisco “

}

expect “assword” {

exp_send “cisco “

}

expect “R1#” {

exp_send “sh int fa1/10 “

}

expect {

-re “is ([a-z]*), line protocol is ([a-z]*)” {

set int_status $expect_out(1,string)

set line_status $expect_out(2,string)

exp_continue

}

“R1#” {

exp_send “exit “

}

}

if {$int_status == “down” || $line_status == “down”} {

puts ” !!!Interface is down!!! “

exit 1

}

else {

puts ” !!!Interface is up!!! “

exit 0

}

Here is the output that is displayed in this case

C:Tcl>tclsh85 sample.tcl

!!!Interface is down!!!

I hope this helps.

11 responses to “Getting Started with Expect

  1. i have a vanilla as 8.4/8.5 user installation on visita 64. the first script above fails at the spawn telnet line.

    C:Utilities cl>tclsh85 test1.txt
    The system cannot find the file specified.
    while executing
    "spawn telnet 192.168.1.1"
    (file "test1.txt" line 11)

    C:Utilities cl>

  2. the basic commands from the link for enabling the telnet client are shown below
    1. Click Start then select Control Panel.
    2. Select Programs and Features.
    3. Select Turn Windows features on or off.
    4. Select the Telnet Client option.
    5. Click OK.
    6. A dialog box will appear to confirm installation. The telnet command should now be available.

  3. Rob:

    Telnet was turned off. I turned it on, but it didn’t solve the problem. Thanks for the tip on the local client. I had never seen that before. The client has always worked on every Wintel computer I’ve ever used and I’ve always installed it on initial setup on Linux. It simply never occurred to me that it was turned off. Now I’ve learned a valuable lesson about Windoze. However, the script generates the same error.

  4. It must be a Vista security setting. I’ll take another look at it. It definitely works with Windows XP, though

  5. Rob:

    I swear I saw a post by you with modifications to the XP boot.ini file. However, when I went back through your archives I couldn’t find it. Can you aim me straight please. I’m determined to get this stuff to run. I know my boot.ini doesn’t contain the mods I saw because it contains only the boot disk variables.

  6. Rob:

    Based on your comment about Vista security settings I reinstalled TCL from the administrative command prompt (start> programs> accessories> command prompt run as administrator. The installation took much longer to execute because it verified a batch teacup entries. It now accepts the spawn telnet command. However, the simple script:

    puts "Hello, World
    ";
    set x 3;
    puts $x;
    package require Expect;
    spawn telnet 192.168.1.1;

    generates the following output:

    C:Utilities cl>tclsh85 test.txt
    Hello, World

    3
    The system cannot find the file specified.
    while executing
    "spawn telnet 192.168.1.1"
    (file "test.txt" line 5)

    C:Utilities cl>

    I thought the teacup activity during installation would pick up the telnet client package but apparently not. Do you know what I should try to download. I can’t find it referenced anywhere. Maybe a hint as tho how to use teacup in the windows environment if you feel generous.

    I installed the following both with elevated privileges.

    ActiveTcl8.4.19.2.291226-win32-ix86-threaded.exe
    ActiveTcl8.5.7.1.291226-win32-ix86-threaded.exe

    WRT to the question about the XP boot.ini file I found it. It is due to sschen elsewhere in the archive.

  7. I reinstalled with "run as administrator" and now I can find Expect. Now, I have gotten this response when executing the following script:

    The system cannot find the file specified. while executing "spawn telnet 192.168.1.1"

    puts "Hello, World
    ";
    set x 3;
    puts $x;
    #!/bin/sh
    #
    exec tclsh "$0" ${1+"$@"}
    package require Expect;
    spawn telnet 192.168.1.1;

    Any ideas?

  8. jcpljh Very, very nicely done!,[url=http://canadacoachhandbags.ca/]coach handbags canada[/url] canadacoachhandbags.ca 512241

Leave a Reply

 

Nick Kelly

Cybersecurity Engineer, Cisco

Nick has over 20 years of experience in Security Operations and Security Sales. He is an avid student of cybersecurity and regularly engages with the Infosec community at events like BSides, RVASec, Derbycon and more. The son of an FBI forensics director, Nick holds a B.S. in Criminal Justice and is one of Cisco’s Fire Jumper Elite members. When he’s not working, he writes cyberpunk and punches aliens on his Playstation.

 

Virgilio “BONG” dela Cruz Jr.

CCDP, CCNA V, CCNP, Cisco IPS Express Security for AM/EE
Field Solutions Architect, Tech Data

Virgilio “Bong” has sixteen years of professional experience in IT industry from academe, technical and customer support, pre-sales, post sales, project management, training and enablement. He has worked in Cisco Technical Assistance Center (TAC) as a member of the WAN and LAN Switching team. Bong now works for Tech Data as the Field Solutions Architect with a focus on Cisco Security and holds a few Cisco certifications including Fire Jumper Elite.

 

John Cavanaugh

CCIE #1066, CCDE #20070002, CCAr
Chief Technology Officer, Practice Lead Security Services, NetCraftsmen

John is our CTO and the practice lead for a talented team of consultants focused on designing and delivering scalable and secure infrastructure solutions to customers across multiple industry verticals and technologies. Previously he has held several positions including Executive Director/Chief Architect for Global Network Services at JPMorgan Chase. In that capacity, he led a team managing network architecture and services.  Prior to his role at JPMorgan Chase, John was a Distinguished Engineer at Cisco working across a number of verticals including Higher Education, Finance, Retail, Government, and Health Care.

He is an expert in working with groups to identify business needs, and align technology strategies to enable business strategies, building in agility and scalability to allow for future changes. John is experienced in the architecture and design of highly available, secure, network infrastructure and data centers, and has worked on projects worldwide. He has worked in both the business and regulatory environments for the design and deployment of complex IT infrastructures.