Skip to content
Oct 11 / Greg

Parse Your Cisco Devices To Reconcile Customer Information

Since I work for a datacenter, we have a LOT of ports. Our customers hang off of a handful of pieces of equipment, but we have a lot of density on these devices. Every so often we run the numbers for how much bandwidth is subscribed to each customer as well as how much are they contracted for. We also check to see how much bandwidth we have subscribed in total.

As you can imagine, it takes forever and a day to run all this information…and I just don’t have the patience for that! I wrote two scripts. One goes out to a list of devices, logs in and dumps the configs as well as interface status to a text file. The second script goes through these and parses out the info and comma separates everything. I can then take the files and reconcile in just a couple hours…which is about all the patience I have for paperwork…hehehe.

Here’s the first script. You will need to create a text file for this guy to read devices from. Name the file devices.txt and put it in the program’s root folder. Entries will need to be like below:
If you are using ACS, make your entry like below:
core-router-1,1.1.1.1,ACS

If you are just using passwords, then make your entries like this:
core-router-2,2.2.2.2,password1,password2

You can mix and match passworded devices with ACS devices.

Here are the compiled files if you don’t want to compile it yourself: Cisco-Inventory (3495 downloads)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
; this was shamelessly borrowed from the forums...I have no idea who the original poster was!
#include <File.au3>
#include <Array.au3>
#include <GUIConstants.au3>
DirCreate(@ScriptDir & "\parse")
$MoveNext = 1
;TCP starten
TCPStartup ()
 
;GUI Creation
GuiCreate("Telnet Client", 500, 390,-1, -1 )
 
;----------> GUI Control Creation Anfang <----------
 
    ;Edit Control für Chat Text
    $Edit = GuiCtrlCreateEdit("", 10, 10, 480, 330)
 
    ;Input Control für Chat Text Eingabe
    $Input = GuiCtrlCreateInput("", 10, 360, 480, 20)
 
;-----------> GUI Control Creation Ende <-----------
 
;GUI sichtbar machen
GUISetState ()
Dim $aSwitches, $Connection, $eingabe
If Not _FileReadToArray(@ScriptDir & "\devices.txt",$aSwitches) Then
   MsgBox(4096,"Error", " Please create the file devices.txt in this folder.  It needs to have the format:" & @CRLF & "Description,IPaddress,ACS for acs clients or Description,IPAddress,Password1,Password2")
   Exit
EndIf
$UserName = ""
for $d = 1 to $aSwitches[0]
	if StringInStr($aSwitches[$d],",ACS") > 1 and $UserName == "" Then
		;this guy is an acs device, ask for username and password
		$UserName = InputBox("username","Put your friggin username here")
		$Password = InputBox("Password", "Put your friggin password here")
	EndIf
Next
For $x = 1 to $aSwitches[0]
	;pull with telnet
	ToolTip($aSwitches[$x],0,0)
	$MoveNext = 1
	_PullConfs()
Next
_CleanFiles()
 
 
 
Func _PullConfs ()
$Connection = TCPConnect ( StringMid($aSwitches[$x],StringInStr($aSwitches[$x],",") + 1,StringInStr($aSwitches[$x],",",0,2) - StringInStr($aSwitches[$x],",") - 1), 23 ) ;<<<<<<<<<< change the port
If @error Then Exit
$Uname = 0
$Pword = 0
$More = 0
$MoresHit = 0
While 1 = $MoveNext
    $msg = GuiGetMsg()
    If $msg = $GUI_EVENT_CLOSE Then Exit
    $recv = TCPRecv ( $Connection,2048 )
    If $recv <> "" Then
		if StringRight($recv,10) == "Username: " Then
			$Uname = 1
		EndIf
		if StringRight($recv,10) == "Password: " Then
			$Pword = 1
		EndIf
		if StringRight($recv,10) == " --More-- " Then
			$More = 1
		EndIf
 
 
	$text = GUICtrlRead ( $Edit )
    GUICtrlSetData ( $Edit,$text & $recv )
    ControlSend ( "Telnet Client","", $Edit, "{ENTER}")
	EndIf
 
	if StringRight($recv,1) == "#" Then
		if $MoresHit = 0 Then
			$MoresHit = 1
			_IssueCommand()
			sleep(1800)
			$eingabe = "show int | inc Ethernet"
			sleep(1000)
			_IssueCommand()
		else
		$eingabe = "exit"
		_IssueCommand()
		_WriteFile ()
		GUICtrlSetData ( $Edit,"")
		TCPCloseSocket($Connection)
		$MoveNext = 0
		EndIf
	EndIf
 
	if $More == 1 Then
		sleep(100)
		$eingabe = Chr ( 32 )
		TCPSend ( $Connection, $eingabe)
		$More = 0
	EndIf
 
	if $Uname == 1 Then
		$eingabe = $UserName
		_IssueCommand()
		$Uname = 0
	EndIf
 
	if $Pword == 1 Then
		if StringInStr($aSwitches[$x],",ACS") == 0 Then
			$eingabe = StringMid($aSwitches[$x],StringInStr($aSwitches[$x],",",0,2) + 1,StringInStr($aSwitches[$x],",",0,3) - StringInStr($aSwitches[$x],",",0,2) - 1)
			_IssueCommand()
			sleep(5000)
			$eingabe = "en"
			_IssueCommand()
			sleep(5000)
			$eingabe = stringmid($aSwitches[$x],StringInStr($aSwitches[$x],",",0,3) + 1)
			_IssueCommand()
		Else
			$eingabe = $Password
			sleep(800)
			_IssueCommand()
		EndIf
		$Pword = 0
		sleep(2000)
		$eingabe = @CRLF
		_IssueCommand()
		sleep(1000)
		$eingabe = "show run"
		_IssueCommand ()
		Sleep(1000)
	EndIf
WEnd
EndFunc
 
Func _IssueCommand ()
        TCPSend ( $Connection, $eingabe & Chr ( 10 ) )
 
        If @error Then
            MsgBox (0,"","Error")
            Exit
 
        EndIf
EndFunc
 
Func _WriteFile ()
$file = FileOpen(FileGetShortName(@ScriptDir) & "\parse\" & StringLeft($aSwitches[$x],StringInStr($aSwitches[$x],",") - 1) & ".txt", 2)
 
; Check if file opened for writing OK
If $file = -1 Then
    MsgBox(0, "Error", "Unable to open file.")
    Exit
EndIf
FileWrite($file, GUICtrlRead ( $Edit ))
;ToolTip(GUICtrlRead ( $Edit ),0,0)
FileClose($file)
 
EndFunc
 
Func _CleanFiles ()
 
For $x = 1 to $aSwitches[0]
	Dim $aCleaners
	;MsgBox(0,"",@ScriptDir & "\" & $aSwitches[$x] & "\.txt")
	If Not _FileReadToArray(@ScriptDir & "\parse\" & StringLeft($aSwitches[$x],StringInStr($aSwitches[$x],",") - 1) & ".txt",$aCleaners) Then
	MsgBox(4096,"Error", " Error reading log to Array     error:" & @error)
	Exit
	EndIf
	For $z = 1 to $aCleaners[0]
		;Msgbox(0,'Record:' & $z, $aCleaners[$z])
		$aCleaners[$z] = StringReplace($aCleaners[$z],"        ","")
		; --More--
		$aCleaners[$z] = StringReplace($aCleaners[$z]," --More-- ","")
	Next
	_FileWriteFromArray(@ScriptDir & "\parse\" & StringLeft($aSwitches[$x],StringInStr($aSwitches[$x],",") - 1) & ".txt",$aCleaners,1)
Next
MsgBox(0,"Done","pulledem all")
Exit
EndFunc

Here’s the script that actually parses the config. It creates a CSV file that is listed as thus:
hostname,interface,description,ip address,subnet mask,bandwidth,port status

Bandwidth is whatever the port is configured to with a service policy. If there is no service policy, then it uses the ports physical rate limit. If the port is down or admin down, it sets this value to 0.

Port status is up, down or admin down.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
;here we gooooooooooo
#include <file.au3>
#Include <Array.au3>
 
;#########parse the pulled file#######################
 
$FileList=_FileListToArray(@ScriptDir & "\parse")
If @Error=1 Then
    MsgBox (0,"","No Files\Folders Found.")
    Exit
EndIf
 
for $y = 1 to $FileList[0]
	$hostname = ""
	$interface = ""
	$ipAddress = ""
	$subnet = ""
	$ratelimit = ""
	$interfaceDesc = ""
	$intStarted = 0
	$exclimationMarks = 0
	Local $aCompleted[1]
	$aCompleted[0] = "0"
 
 
	Dim $aParse
	If Not _FileReadToArray(@ScriptDir & "\parse\" & $FileList[$y],$aParse) Then
		MsgBox(4096,"Error", " Error reading log to Array     error:" & @error)
		Exit
	EndIf
	For $x = 1 to $aParse[0]
		;find hostname
		if StringInStr("-" & $aParse[$x], "hostname") > 1 and stringInStr("-" & $aParse[$x], "hostname") < 4 Then
			;found hostname
			$hostname = StringMid($aParse[$x],9)
		EndIf
		;look for interfaces
		if StringInStr("-" & $aParse[$x], "interface") > 1 Then
			;mark that we have found the first interface
			$intStarted = 1
			$exclimationMarks = 0
			;set interface name
			$interface = StringMid($aParse[$x],10)
			;set default rate limit based on interface name
			if StringInStr("-" & $aParse[$x], "Giga") > 1 Then
				;gigabit interface, set the RL to 1000
				$ratelimit = 1000
			Elseif StringInStr("-" & $aParse[$x], "Fast") > 1 Then
				$ratelimit = 100
			Else
				$ratelimit = 0
			EndIf
		EndIf
		;look for description
		if StringInStr("-" & $aParse[$x], "description") > 1 Then
			;found desc
			$interfaceDesc = StringMid($aParse[$x],13)
		EndIf
		;look for ip address
		if StringInStr("-" & $aParse[$x], "ip address") > 1 and StringInStr("-" & $aParse[$x], "ip address") < 4 Then
			;found address
			$subnet = StringMid($aParse[$x],StringInStr($aParse[$x],"255"))
			$ipAddress = StringMid($aParse[$x], 12, StringInStr($aParse[$x]," ",0,4) - 12)
		EndIf
		;look for rate limit
		if StringInStr("-" & $aParse[$x], "service-policy") > 1 Then
			;found SP
			$ratelimit = StringMid($aParse[$x],StringInStr($aParse[$x]," ",0,3) + 1)
			$ratelimit = StringLeft($ratelimit,StringLen($ratelimit) - 3)
		EndIf
		;look for switch port with access vlan
		if StringInStr("-" & $aParse[$x], "switchport access vlan") > 1 Then
			;found access port
			$ipAddress = "vlan" & StringMid($aParse[$x],StringInStr($aParse[$x]," ", 0,4) + 1)
		EndIf
		;look for switch port set as trunk
		if StringInStr("-" & $aParse[$x], "switchport mode trunk") > 1 Then
			;found trunk port
			$ratelimit = 0
			$ipAddress = "trunk port"
		EndIf
		;look for ! that signals the end of interface
		if StringInStr("-" & $aParse[$x], "!") > 1 Then
			;found !
			$exclimationMarks = $exclimationMarks + 1
			;write all this good stuff, then clear
			if $intStarted == 1 and $exclimationMarks == 1 Then
				$aCompleted[0] = $aCompleted[0] + 1
				_ArrayAdd($aCompleted, $hostname & "," & $interface & "," & $interfaceDesc & "," & $ipAddress & "," & $subnet & "," & $ratelimit)
			EndIf
			$interface = ""
			$ipAddress = ""
			$subnet = ""
			$ratelimit = ""
			$interfaceDesc = ""
 
		EndIf
		;###start the parse of "show int | inc Ethernet"
		if StringInStr("-" & $aParse[$x], "line protocol") > 1 Then
			;found interface info.  Search through our existing array to find a match.
			for $z = 1 to $aCompleted[0] - 1
				if StringInStr("-" & $aCompleted[$z], StringLeft($aParse[$x], StringInStr($aParse[$x], " ") - 1) & ",") > 1 Then
					;we have our match!  Append the status
					if StringInStr("-" & $aParse[$x], "administratively") > 1 Then
						$aCompleted[$z] = StringLeft($aCompleted[$z], StringInStr($aCompleted[$z],",",0,5)) & "0,admin down"
						;also clear out RL
					elseif StringInStr("-" & $aParse[$x], "line protocol is down") > 1 Then
						;also clear out RL
						$aCompleted[$z] = StringLeft($aCompleted[$z], StringInStr($aCompleted[$z],",",0,5)) & "0,down"
					elseif StringInStr("-" & $aParse[$x], "line protocol is up") > 1 Then
						$aCompleted[$z] = $aCompleted[$z] & ",up"
					EndIf
 
				EndIf
			Next
		EndIf
 
 
 
	Next
	FileDelete(@ScriptDir & "\" & StringLeft($FileList[$y],StringLen($FileList[$y]) - 4) & ".csv")
	_FileWriteFromArray(@ScriptDir & "\" & StringLeft($FileList[$y],StringLen($FileList[$y]) - 4) & ".csv",$aCompleted,1)
Next
Oct 7 / Greg

My MUM Presentation – Troubleshooting

It’s over here on tiktube. I haven’t watched it…I can’t stand to see myself on video…hehe.

If you recall I did a post called Leap of Faith. Most everyone was worked in, and Andrew sent me a personal picture response…I thought I would share it.

I had no idea that Australian high fashion included monocles these days…though I do love the mustache. A very Mario look 😉

Oct 6 / Greg

What Is The Hidden Node Problem And How Does TDMA Fix This?

With the roll out of TDMA(time devision multiple access – AKA Nstreme2) I’ve heard mention of the hidden node problem…though, no one bothers to mention what the hidden node problem is…it seems the answer to the hidden problem is hidden.

Here’s my two second rendition of the issue:

Basic hidden node configuration. One user can't hear the radio transmissions from other users due to directional antennas.


Two users can transmit at the same time...which will cause collisions. PS, that's bad 😉


802.11 uses CSMA/CA to handle collisions. Collisions occur on half duplex connections (like wireless) when multiple parties send at the same time. CSMA attempts to listen for others transmitting and wait for a clear time to send. If other users can’t hear you sending, they assume no one else is sending and it is ok for them to transmit. Thus, the other nodes or users are hidden from you and may cause collisions.

The 802.11 RTS/CTS mechanism was added to help alleviate this issue, but doesn’t completely solve the problem. It basically does a request to send and a clear to send signaling method. This does also lower overall throughput.

With TDMA, each user is given a time slice to speak in, so the fact they can't sense each other's radio transmissions doesn't matter.


TDMA creates time slices. Each user is allowed only to send in his time slice. This effectively eliminates the hidden node issue! It doesn’t matter if you can hear the other nodes or not, you only send in your designated time slot.

Oct 5 / Greg

MUM 2010 On Tiktube

Pop over to tiktube. They are starting to upload the new MUM presentations.

Looks like the only thing they have so far is the intro presentation: what we sell now, and new stuff.

Oct 1 / Greg

MUM Phoenix – Update1

I’m at the MUM! I’ve had my head down because I’ve been taking train the trainers…which I passed, BTW 😉

I’ve made a lot of new friends, and finally met some in person. JJ, it’s been a real pleasure and thanks for bringing Sam…he is like a cross of Mr. Wizard, a hippie and my personal hero MacGyver. I’m also told he loves tape…perhaps an unhealthy love of it.

Rick and Jason, you guys are pretty alright and it was a lot of fun meeting you.

I actually got a chance to get to know Janis, and I think I’ve made a pretty good friend 😉

I got a chance to talk to Sergejs for just a little while, and he’s a pretty cool kid! Hopefully I’ll be able to keep in touch with him too!

To all of you guys that I didn’t mention here, it was a REAL pleasure to meet you. Anyone who shook my hand and said they have read my blog and also didn’t say that it sucks, thanks…hehehe

I’ll compile my notes and post soon…though here are a few teasers.

493GAH was announced…looks just like the standard 493 only with all gigabit ports.

wwwwweeeeeeeeeee


RoS V5:

  • Added TOP command. You can now see what processes are taking up your CPU!
  • GRE Tunnel support. I saw this just before it was announced. I’ve also asked how it is working and they say that it is working pretty well and once the full release of 5 is out it should be solid.
  • SSTP – VPN built into Windows 7
  • IPSec FQDN – Allows you to enter a DNS name in your IPSec peer statements instead of having to use IP addresses. This means we don’t have to have scripts that update our peer/policy entries when using dynamic IPs.
  • IPv6 PPPoE and SSH improvements…I think they did this just to shut Andrew up
  • There’s supposed to be some SNMP bug fixes
  • Flashfig – This is a new utility that is supposed to be able to push configs to multiple routers at a high rate! I’ll be demoing this here pretty soon.
  • Running kernel V2.6.35 now which includes some new drivers
  • That should be enough for you kids right now…:) Check back soon for updates.

    BTW, thanks to JJ for these terrible pictures 😛

    Sep 24 / Greg

    Symbolic Link In Linux

    Creating a symbolic link in linux is pretty straight forward. I created a link to port my videos to the new site with a single command:

    1
    
    ln -s /usr/src/test /usr/src/linux/test
    Sep 23 / Greg

    Motorized Stand For Show Display

    As some of you know, my wife an I are photographers. We do the bridal shows every six months or so. We usually go for a minimalist display. We went with a square display that has a center post coming out the top with a couple of back to back pictures spinning.

    I took a piece of 1.5″ PVC pipe and cut slits in the top. I then broke the bottom off of an electric screwdriver and wired straight into the motor. I used a pipe clamp to squeeze the screw driver into the pipe. The bottom of the pipe has a floor drain on it to create a stable base. I then used a couple of 10 pound weights to hold it down.

    I took to 5 gallon bucket stir sticks and pop riveted them together. I also pop riveted a spade bit in between the sticks. The spade bit then sticks down on to the screw driver.

    I had an arduino lying around, so I used that with a custom shield to fire a relay for 7 milliseconds to rotate the motor. I also used a 12 volt regulater to kick the power down, even though the arduino can handle up to 20 volts I figured I would take it easy on the lil guy. I used one of my ryobi drill batteries to power the whole thing.

    Here’s a video of the stand after construction:


    Here’s the finished product:

    Isn’t that awesome how I made it defy gravity in the video…hehehe.

    I don’t have a lot of build pictures because I waited until the last minute to build it and didn’t take time to document anything…hehehe. 😛