An easy way to loop through a CSV in BASH

In working on this painful DHCP migration, I needed a way to automate all the data into the script I built in my last post. BASH While loop to the rescue!

#!/bin/bash
INPUT=$1
OLDIFS=$IFS
IFS=,
[ ! -f $INPUT ] && { echo "$INPUT file not found"; exit 99; }
while read value1 value2 value3 value4
do
./netshDHCP.sh $value1 $value2 $value3 $value4
done < $INPUT
IFS=$OLDIFS

So i simply execute ./csvparser.sh test.csv and it will loop through each line and excute the command in between do and done. My CSV only had 4 values per line, but you could expand this on the while line as needed. Here is my sample test.csv for reference:

192.168.2.0,255.255.255.0,COOL_DATACENTER_NETWORK,data
192.168.3.128,255.255.255.128,SOME_OTHER_NETWORK,data
172.16.10.0,255.255.254.0,A_VOICE_NETWORK,voice

Cheers!

Exporting DHCP Scopes From Cisco CNR

So I’m migrating an old Cisco Network Registrar DHCP service (circa 1998 product version) to a Win2008R2 box, i found out quite quickly that Cisco does not provide a way to export configuration information for their CNR product… at least not directly. I doubt anyone else out there has such an old crap product but just in case, I spent a bit of time figuring things out and have found a viable way to pull the information out.

First, I utilized nrcmd.bat which comes with the CNR client and provides a very basic cli to the product. Unfortunately this cli doesn’t have a full dump for the DHCP configuration. I did however find a few commands that will provide the needed information to hopefully provide as an input to netsh after a bit of manipulation.

scope listnames
scope <name> listRanges
scope <name> listReservations

policy listnames
policy <name> listOptions

As you can probably tell, I needed a simple loop to actually generate everything. At first I feared this because, pulling the database from CNR (which the client does upon first command) takes 30 seconds. If I executed a loop from an OS level, each command would take 30 seconds to complete. In retrospect I could probably have run them in parallel but I decided to look for a better way.

I found it! The nrcmd.bat file is actually a bit better than expected. It provided a way to feed data directly into it’s cli.

C:\Program Files\Network Registrar\BIN>nrcmd.bat -h
Usage: nrcmd [-C cluster] [-N user] [-P password] [-h] [-r] [-v] [-b < script]
Options:
      -b < script  Process script file of nrcmd commands.
      -h           Print this help text.
      -r           Login as a read-only user.
      -v           Report the program version and exit.
Notes:
       Cluster defaults to localhost if not specfied.

       Single commands may be specified as arguments, for
       example 'nrcmd -N name -P password zone list'.

Cool, so now its just time to compile the lines to feed into nrcmd.bat. This was done by taking the output of scope listnames and policy listnames from nrcmd.bat and dropping it into file “inputfile” then a quick bash FOR loop did the rest as shown below.

Example inputfile:

Building1
Building2
Building3
Building4 Special Scope

By the way, because the last scope has spaces, I needed to do two additional things… I needed to set the IFS variable which controls the delimiter for the FOR loop, and I also needed to quote it as it was echo’d out for the nrcmd.bat script to know that the spaces were part of the names.

IFS=$'\n';
for l in `cat inputfile`;
do
  echo "scope \"$l\" listRanges";
  echo "scope \"$l\" listReservations";
done

Alright so all thats left is to take the output of this and feed it into nrcmd.bat! I put the output into a file called “scriptfile.txt” and issued this:

nrcmd.bat -C <CNRservername> -N <user> -P <pass> -r -b < scriptfile.txt > myoutput.txt

Sample output from a policy <name> listoptions just for reference:

nrcmdRO> policy system_default_policy listoptions
100 Ok
(27)all-subnets-local: FALSE
(35)arp-cache-timeout: 60
(28)broadcast-address: 1.1.1.255
(23)default-ip-ttl: 64
(37)default-tcp-ttl: 64
(51)dhcp-lease-time: 604800
(15)domain-name: domain.com
(6)domain-name-servers: 1.2.3.4,1.2.3.5
(36)ieee802.3-encapsulation: FALSE
(26)interface-mtu: 576
(30)mask-supplier: FALSE
(22)max-dgram-reassembly: 576
(5)name-servers: 1.2.3.4,1.2.3.5
(44)netbios-name-servers: 1.2.3.4,1.2.3.5
(46)netbios-node-type: 8
(20)non-local-source-routing: FALSE
(24)path-mtu-aging-timeout: 6000
(25)path-mtu-plateau-tables: 68,296,508,1006,1492,2002,4352,8166,17914,32000,65535
(29)perform-mask-discovery: FALSE
(31)router-discovery: TRUE
(32)router-solicitation-address: 224.0.0.2
(39)tcp-keepalive-garbage: FALSE
(38)tcp-keepalive-interval: 0
(34)trailer-encapsulation: FALSE

I did have to do this separately for the scope and policy as their names were not the same :( .. never the less, i now have all the information needed to build my netsh scripts! I’ll probably add to this / follow up as I finish that part as well.

Determining port to ASIC Mapping on your Cisco gear

Ever wondered what ASIC your interface Te1/1/1 is on? I did… heres how to figure it out.

First to see the available asics on a given switch issue sh platform port-asic version
Heres the output from a 3750 platform:

Port-Asic Version Info:
========================
ASIC-0: Version:4 DeviceType:0x30A
ASIC-1: Version:4 DeviceType:0x30A
ASIC-2: Version:4 DeviceType:0x30A

Now that we see we have 3 ASICs on this device, lets check the mappings of the interfaces to them!
Take the output below for example, using the ‘port’ column, this is read as ASIC/port.

SWITCH1#sh platform pm if-numbers

interface gid  gpn  lpn  port slot unit slun port-type lpn-idb gpn-idb
----------------------------------------------------------------------
Gi1/0/1   1    1    1    1/1  1    1    1    local     Yes     Yes
Gi1/0/2   2    2    2    1/0  1    2    2    local     Yes     Yes
Gi1/0/3   3    3    3    1/3  1    3    3    local     Yes     Yes
Gi1/0/4   4    4    4    1/2  1    4    4    local     Yes     Yes
Gi1/0/5   5    5    5    1/5  1    5    5    local     Yes     Yes
Gi1/0/6   6    6    6    1/4  1    6    6    local     Yes     Yes
Gi1/0/7   7    7    7    1/9  1    7    7    local     Yes     Yes
Gi1/0/8   8    8    8    1/8  1    8    8    local     Yes     Yes
Gi1/0/9   9    9    9    1/11 1    9    9    local     Yes     Yes
Gi1/0/10  10   10   10   1/10 1    10   10   local     Yes     Yes
Gi1/0/11  11   11   11   1/13 1    11   11   local     Yes     Yes
Gi1/0/12  12   12   12   1/12 1    12   12   local     Yes     Yes
Gi1/0/13  13   13   13   1/15 1    13   13   local     Yes     Yes
Gi1/0/14  14   14   14   1/14 1    14   14   local     Yes     Yes
Gi1/0/15  15   15   15   1/17 1    15   15   local     Yes     Yes
Gi1/0/16  16   16   16   1/16 1    16   16   local     Yes     Yes
Gi1/0/17  17   17   17   1/19 1    17   17   local     Yes     Yes
Gi1/0/18  18   18   18   1/18 1    18   18   local     Yes     Yes
Gi1/0/19  19   19   19   1/23 1    19   19   local     Yes     Yes
Gi1/0/20  20   20   20   1/22 1    20   20   local     Yes     Yes

interface gid  gpn  lpn  port slot unit slun port-type lpn-idb gpn-idb
----------------------------------------------------------------------
Gi1/0/21  21   21   21   1/25 1    21   21   local     Yes     Yes
Gi1/0/22  22   22   22   1/24 1    22   22   local     Yes     Yes
Gi1/0/23  23   23   23   1/27 1    23   23   local     Yes     Yes
Gi1/0/24  24   24   24   1/26 1    24   24   local     Yes     Yes
Gi1/0/25  25   25   25   2/1  1    25   25   local     Yes     Yes
Gi1/0/26  26   26   26   2/0  1    26   26   local     Yes     Yes
Gi1/0/27  27   27   27   2/3  1    27   27   local     Yes     Yes
Gi1/0/28  28   28   28   2/2  1    28   28   local     Yes     Yes
Gi1/0/29  29   29   29   2/5  1    29   29   local     Yes     Yes
Gi1/0/30  30   30   30   2/4  1    30   30   local     Yes     Yes
Gi1/0/31  31   31   31   2/9  1    31   31   local     Yes     Yes
Gi1/0/32  32   32   32   2/8  1    32   32   local     Yes     Yes
Gi1/0/33  33   33   33   2/11 1    33   33   local     Yes     Yes
Gi1/0/34  34   34   34   2/10 1    34   34   local     Yes     Yes
Gi1/0/35  35   35   35   2/13 1    35   35   local     Yes     Yes
Gi1/0/36  36   36   36   2/12 1    36   36   local     Yes     Yes
Gi1/0/37  37   37   37   2/15 1    37   37   local     Yes     Yes
Gi1/0/38  38   38   38   2/14 1    38   38   local     Yes     Yes
Gi1/0/39  39   39   39   2/17 1    39   39   local     Yes     Yes
Gi1/0/40  40   40   40   2/16 1    40   40   local     Yes     Yes
Gi1/0/41  41   41   41   2/19 1    41   41   local     Yes     Yes
Gi1/0/42  42   42   42   2/18 1    42   42   local     Yes     Yes
Gi1/0/43  43   43   43   2/23 1    43   43   local     Yes     Yes

interface gid  gpn  lpn  port slot unit slun port-type lpn-idb gpn-idb
----------------------------------------------------------------------
Gi1/0/44  44   44   44   2/22 1    44   44   local     Yes     Yes
Gi1/0/45  45   45   45   2/25 1    45   45   local     Yes     Yes
Gi1/0/46  46   46   46   2/24 1    46   46   local     Yes     Yes
Gi1/0/47  47   47   47   2/27 1    47   47   local     Yes     Yes
Gi1/0/48  48   48   48   2/26 1    48   48   local     Yes     Yes
Gi1/1/1   49   49   49   0/6  1    49   49   local     Yes     Yes
Gi1/1/2   50   50   50   0/7  1    50   50   local     Yes     Yes
Gi1/1/3   51   51   51   0/20 1    51   51   local     Yes     Yes
Gi1/1/4   52   52   52   0/21 1    52   52   local     Yes     Yes
Te1/1/1   53   53   53   0/0  1    1    53   local     Yes     Yes
Te1/1/2   54   54   54   0/14 1    2    54   local     Yes     Yes

So now we know that ports 1-24 are on ASIC1, 25-48 on ASIC2, and the expansion card’s intefaces on the 3750X platforms have a dedicated ASIC all to their self!

2012 resolutions… coming to fruition

I’m not normally one to make resolutions. I tend to think they are never followed through on and are only temporary at best. However, I desperately need to write things down in my life. More as a resource to myself at later points in time than anything. So here’s to standing up a blog and registering a domain for this cause!