Saturday, May 16, 2009

Manipulating the bash directory stack

There are occasions when you traverse through so many directories stopping in each directory to work on something. After a few stops you may want to go back to one or all of the direcoties you have traversed. I can't remember a generic example to give you but we all come across this scenario many times. Bash provides a facility for addressing such issues and that is called the "bash directory stack"

In simplest terms directory stack is a list of recently visited directories, like your browser's favorite list. It acts like a conventional stack where you can push and pop items, but you can manipulate it further to reorder and remove items from the middle of the stack. Bash provides three 'directory stack built-in' commands to manipulate this stack, wiz pushd,popd and dirs.

pushd:

With a directory as argument, pushd will save(push) the current directory to the stack and change to the directory given by the argument.

popd:

Without any arguments, popd will remove the top entry from the stack and move to that directory.

dirs:

Displays the stack entries. With optional arguments, it can display selected directories from the stack.


Example:

Am going to add a few directories to the stack first.

safeer@penguinpower:~/bin$ pushd /etc/apache2/
/etc/apache2 ~/bin
safeer@penguinpower:/etc/apache2$ pushd /etc/cvsd
/etc/cvsd /etc/apache2 ~/bin
safeer@penguinpower:/etc/cvsd$ pushd /etc/cups/
/etc/cups /etc/cvsd /etc/apache2 ~/bin
safeer@penguinpower:/etc/cups$ pushd /etc/ldap/
/etc/ldap /etc/cups /etc/cvsd /etc/apache2 ~/bin

In practice pusdhd is done after working in a directory and then moving to another directory. Now let us see the stack contents using dirs command.

safeer@penguinpower:/etc/ldap$ dirs -l -v
0 /etc/ldap
1 /etc/cups
2 /etc/cvsd
3 /etc/apache2
4 /home/safeer/bin

The number associated with each directory shows the index of the corresponding directory in the stack with index zero being the present working directory.

Now let us try moving through the stack with popd.

safeer@penguinpower:/etc/ldap$ popd
/etc/cups /etc/cvsd /etc/apache2 ~/bin
safeer@penguinpower:/etc/cups$ popd
/etc/cvsd /etc/apache2 ~/bin
safeer@enjoyfast-lx:/etc/cvsd$

So I popped two directories out of the stack and now the contents of the stack becomes:

safeer@penguinpower:/etc/cvsd$ dirs -v -l
0 /etc/cvsd
1 /etc/apache2
2 /home/safeer/bin

This will give you a basic idea about stack manipulation. To see the full options for pushd/popd/dirs visit the GNU page for directory stack built-ins
A few more shortcuts and shell variables exists for manipulating the stack.

"$PWD" OR "$DIRSTACK" OR "~+" - Present working directory - Stack index zero
"$OLDPWD" OR "~-" - Previous working directory - Stack index one.
"$HOME" OR "~" - User's home directory

cd : Move to user's home directory. Alternatively use cd ~.
cd - : Move to $OLDPWD - pushd without any arguments will do the same. Or use cd ~-

Examples

safeer@penguinpower:/etc/cvsd$ echo ~{,-,+}
/home/safeer /etc/apache2 /etc/cvsd

which is equivalent to:

safeer@penguinpower:/etc/cvsd$ echo $HOME $OLDPWD $PWD
/home/safeer /etc/apache2 /etc/cvsd

Thursday, May 7, 2009

Cisco kron - the Cisco job scheduler

Cisco provides a job scheduler called "kron" which is similar to the unix crontab service. It allows us to schedule and run certain exec mode commands once or recurringly. The feature was first introduced in IOS version 12.3(1). The prerequisite for using kron is that Cisco clock time must be set - either locally or using an NTP source.

Check your IOS version first:

R1_Balancer#show version | include ^Cisco IOS(.+)Version
Cisco IOS Software, 3700 Software (C3725-ADVENTERPRISEK9-M), Version 12.4(18), RELEASE SOFTWARE (fc1)

The "kron" configuration has two parts, configuring "Scheduler Policy List" and then setting "Scheduler Occurrences". A scheduler policy list is similar to a shell script in unix. Every policy list will have a name and will contain one or more exec cli commands added sequentially. A scheduler occurrence is the setting that tells you when a policy list should be executed. You can associate one or more policy lists to a policy schedule.

Now let us create a kron policy with policy name my_policy_1. The commands that can be added in a policy should not generate any prompt or have the ability to be terminated using keystrokes. The simplest command that I can remember is write, which will save the running config to startup config( you can't use "copy running-config startup-config" since it will ask you to confirm the destination file name )

R1_Balancer(config)#kron policy-list my_policy_1
R1_Balancer(config-kron-policy)#cli write
R1_Balancer(config-kron-policy)#exit

You can view the policy from running configuration.

R1_Balancer#sh run | section include kron
kron policy-list my_policy_1
cli write

Let us create a schedule called schedule_1 now. This is set to run once at next Sunday night 11.45

R1_Balancer(config)#kron occurrence schedule_1 at 23:45 sun oneshot
Clock currently not set it reads 02:58:44 UTC Fri Mar 1 2002

If the clock is not set properly you will get a message as above. So set the time.

R1_Balancer#clock set 22:14:20 may 10 2009
R1_Balancer#show clock
22:17:29.487 UTC Sun May 10 2009

R1_Balancer(config)#kron occurrence schedule_1 at 23:45 sun oneshot
R1_Balancer(config-kron-occurrence)#policy-list my_policy_1
R1_Balancer(config-kron-occurrence)#exit

In the schedule you can optionally specify a user under which the kron should run. Now let us see the full kron configurations.

R1_Balancer#show run | section include kron
kron occurrence schedule_1 at 23:45 Sun oneshot
policy-list my_policy_1
kron policy-list my_policy_1
cli write

To view the schedule you can run this command:

R1_Balancer#show kron schedule
Kron Occurrence Schedule
schedule_1 inactive, will run once in 0 days 01:24:51 at 23:45 on Sun

For detailed information on kron, visit this Cisco link.

Sunday, May 3, 2009

Connect GNS3 to your Linux desktop

This post assumes the reader has basic working knowledge with GNS3 GUI. For those who don't know about GNS3 - the graphical network simulator for Cisco platforms, please visit http://www.gns3.net/.

On windows GNS comes with a script for connecting to local machine, but it don't have a Linux equivalent. Here we will see how to achieve that.

First of all, create a basic network map with a single router. Here I am adding a 3600 series router with two slots, NM-1FE-TX ( one fast ethernet port) and NM-4E (four ethernet ports ). Once added, start the router and go to exec mode to list the router interfaces.

Router(config)#hostname R0
R0(config)#show ip interface brief
Interface IP-Address OK? Method Status Protocol
FastEthernet0/0 unassigned YES unset administratively down down
Ethernet1/0 unassigned YES unset administratively down down
Ethernet1/1 unassigned YES unset administratively down down
Ethernet1/2 unassigned YES unset administratively down down
Ethernet1/3 unassigned YES unset administratively down down

Now we need to connect any one of these interfaces to the local desktop. To do this, from the GUI save the map first. I am going to save my router to /home/safeer/GNS/local-connect.net. Now let us examine the contents of the saved network file.

safeer@penguinepower:~$ cat ~/GNS/local-connect.net
autostart = False
[localhost:7200]
workingdir = /tmp
[[3620]]
image = /home/safeer/.gns3/CiscoImages/c3620-i-mz.121-5.T92.bin
idlepc = 0x6012c108
ghostios = True
chassis = 3620
[[ROUTER R0]]
model = 3620
console = 2000
slot0 = NM-1FE-TX
slot1 = NM-4E
x = -29.0
y = -266.0


Now we need to connect this to the local machine using a virtual network interface. To create a virtual network adapter in linux, you need User Mode Linux. On my Ubuntu box, I can get it with apt-get.

safeer@penguinepower:~$ sudo apt-get install uml-utilities

On a Redhat based machines, you can get it via Yum. For more details visit the UML home page http://user-mode-linux.sourceforge.net/

Now add a virtual interface with name tap0 and assign an ip 172.16.1.1 to it.

safeer@penguinepower:~$ sudo tunctl -t tap0 -u safeer
Set 'tap0' persistent and owned by uid 1000
safeer@penguinepower:~$ sudo ifconfig tap0 172.16.1.1 up
safeer@penguinepower:~$ ifconfig tap0
tap0 Link encap:Ethernet HWaddr 72:e7:97:e6:e4:2c
inet addr:172.168.1.1 Bcast:172.168.255.255 Mask:255.255.0.0
inet6 addr: fe80::70e7:97ff:fee6:e42c/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:19 overruns:0 carrier:0
collisions:0 txqueuelen:500
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

Now we going to connect this tap0 interface to router R0's fast ethernet 0/0 interface. For this, Close the network map in GUI and open its previously saved network file and add this line to the end of [ROUTER R0] section in the configuration.

f0/0 = nio_tap:tap0

The file will look like:

safeer@penguinepower:~$ cat ~/GNS/local-connect.net
autostart = False
[localhost:7200]
workingdir = /tmp
[[3620]]
image = /home/safeer/.gns3/CiscoImages/c3620-i-mz.121-5.T92.bin
idlepc = 0x6012c108
ghostios = True
chassis = 3620
[[ROUTER R0]]
model = 3620
console = 2000
slot0 = NM-1FE-TX
slot1 = NM-4E
x = -29.0
y = -266.0
f0/0 = nio_tap:tap0

Now save the file and open the network map in GUI. You will see a cloud connected to the f0/0 interface of the router. Now tap0 interface of the host machine is connected to f0/0 of R0 in GNS3. To complete the configuration, start R0 and configure an IP for f0/0 that belong to the same network as tap0.

R0(config)#interface f0/0
R0(config-if)#ip address 172.16.1.2 255.255.0.0
R0(config-if)#no shutdown

Now try pinging the local machine from R0.

R0#ping 172.16.1.1

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

That is all, you can access R0 ( and other routers connected to R0) from your local machine now. If you have enabled ip forwarding/routing on your local box, these routers will be accessible in your local network.

Note: Sometimes GNS may have permission issue in accessing tap0 interface, in that case launch GNS3 as sudo.