Showing posts with label cisco. Show all posts
Showing posts with label cisco. Show all posts

Thursday, March 17, 2011

Full mesh dial peers script

I wrote the following script to support the automated construction of a full-mesh configuration of dial-peers in Cisco IOS.

The original driver for this was a scalability issue with Cisco's Call Manager Express (CME) feature in that each time a new site, or range of DIDs for an existing site, was added to the network then every other router in the network would have to be touched to update the configuration with a new dial-peer for the new DID range. This isn't an issue really when you have a Unity Call Manager managing everything and acting as a centralized directory server. However, when you have no central source of directory information (like when you are trying to save money and implementing VoIP on a very tight budget) you need some efficient way to keep all of the routers in the network educated about all of the DID ranges in the network. The below script helped me do that and works great for my needs.

#!/bin/sh

VCC="voice class codec 1000
codec preference 1 g711ulaw
codec preference 2 g729r8 bytes 30
codec preference 3 g729br8 bytes 30"

cat dp_list.txt | while read a target_router b c;
do
 outfile="${target_router}_dp_config.txt"
 echo "!" >${outfile}
 echo "${VCC}" >>${outfile}
 echo "!" >>${outfile}
 cat dp_list.txt | grep -v ${target_router} | while read sequence hostname pattern ipv4_target;
 do
  echo "dial-peer voice ${sequence} voip" >> ${outfile}
  echo "descrip SEQ ${sequence} FOR ${pattern} TO ${hostname} AT ${ipv4_target}" >> ${outfile}
  echo "destination-pattern ${pattern}" >> ${outfile}
  echo "progress_ind setup enable 3" >> ${outfile}
  echo "voice-class codec 1000" >> ${outfile}
  echo "voice-class h323 1" >> ${outfile}
  echo "session target ipv4:${ipv4_target}" >> ${outfile}
  echo "dtmf-relay h245-alphanumeric" >> ${outfile}
  echo "ip qos dscp ef media" >> ${outfile}
  echo "ip qos dscp af41 signaling" >> ${outfile}
  echo "!" >> ${outfile}
 done
 echo "end" >> ${outfile}
 echo "" >> ${outfile}
done

Ok, so for this script you need to supply an input file with the following tab-delimited pieces of information:

  1. Sequential dial-peer numeric identifier. I start mine at 1000000 and increment by 10.
  2. Destination router hostname
  3. DID/Number range (regex encouraged!)
  4. IPv4 address of destination router

Here is a sample of that input:
1000270 router027 91859960.. 192.168.1.27
1000280 router028 9185826953 192.168.1.28
1000290 router029 9185831071 192.168.1.29
1000300 router030 86381680.. 192.168.1.30
1000310 router027 86381681.. 192.168.1.27
1000320 router029 863686[0-3][1-4].. 192.168.1.29

In this example, you can see that additional ranges were added to sites 27 and 29, but this is no problem for the script, it does the right thing. The most important part is keeping the sequence number unique. You could even make it more intuitive by embedding the site number into the sequence number, like 1XXXXYY, where XXXX is your site number (assuming you have <10k sites) and YY are the DID/number ranges for the site (assuming <=100 ranges per site). This would make the above sequence 1000290->1002900 and 1000320->1002901. You get the idea.

Of course, this can be extended in any way that meets your needs. The important part of the script is that it builds a config for each hostname that includes all rows from the input file that are from !hostname. Once the configurations are built, you can use SNMP & TFTP to get them loaded to each router in the network. Further still, using cron to run the script & TFTP load on a regular basis will always keep everything in sync. Let the machines do the work for you!

Leave me comments if you like, don't like, have ideas for improvement, etc. If you want, also give a visit to an advertiser.

Tuesday, December 7, 2010

No free VTYs

So, was working on a Nagios event handler to issue a NAT clear command to a Cisco router (half-baked IPSec VPN box issues, fail) and even though I had configured all of the rcmd stuff properly in IOS and locked it down to just the Nagios server for access it still didn't work. On the server side, when I issued the command I would get a single line of output:

No free VTYs.

So, I went back to the router and turned on 'debug ip tcp rcmd' and noticed that the rsh authentication (if you can call it that) was working but after accepting the command from the rsh client (router sends 'OK' to client), the router followed by immediately sending '' to the client. Ok, so let's look at the VTY line config.

All of my default VTYs are setup with 'transport input ssh' because I don't use telnet where I have the choice to use SSH. I changed that to 'transport input rlogin ssh' and no luck. Finally, I changed it to 'transport input ssh telnet' and bingo, the rcmd was working like a champ. I removed the telnet option for my main access lines and defined a new line, telnet only, with a much more restrictive access-class limited to the server running Nagios.

Wednesday, August 19, 2009

Retrieve ARP table from Cisco router, parse, spew

I had a colleague in need of an automated way to retrieve the ARP table from a lot of Cisco routers and format the output in a spreadsheet. Another colleague suggested using an Expect script, which is definitely cool because I love using Expect (seriously, it's a Swiss Army knife), but I wanted to take it a different direction. I looked up the SNMP MIB to retrieve the ARP table and then parsed the input to provide a two-column output consisting of the IP address and MAC address, one pair per line.

Here is the script:

snmpwalk -t 60 -v 1 -c MYCOMMSTRING routerhostname .1.3.6.1.2.1.4.22.1.2 | \
while read line; do \
IP_ADDR=`echo ${line} | \
awk '{print $1;}' | \
sed -e 's/^IP-MIB::ipNetToMediaPhysAddress.[0-9]*\.//'`; \
MAC_ADDR=`echo ${line} | \
awk '{print $4;}' | \
sed -e 's/^\([0-9a-f]\)/0\1/' \
-e 's/:\([0-9a-f]\):/:0\1:/g' \
-e 's/:\([0-9a-f]\):/:0\1:/g' \
-e 's/:\([0-9a-f]\)$/:0\1/' | \
tr '[:lower:]' '[:upper:]'`; \
echo "${IP_ADDR} ${MAC_ADDR}"; \
done


Notice that there are two mid-string sed matches, each with a 'g' matching command. The reason that this command needs to be listed twice is that a single iteration of 'g' doesn't mean global, it means to match up to two addresses within the stream. Since some of the MAC addresses I was dealing with were beyond that, such as "0:d:ed:c:7:5e", just using a single mid-string pattern with 'g' left me with "00:0d:ed:0c:7:5e" (note the :7: instead of the desired :07:). Adding the second iteration of mid-string matching fixed this issue by enabling matching of a third and fourth mid-string single-digit. I learned something new about sed, and learning something new is a good thing.