04-19-2012 07:19 AM
I need a way to list out the last mac address known to port-security per port in IOS, and EEM may be my answer.
The command "show port-security address" gets me close - it shows current mac on all up ports, like:
> AS5#show port-security address
> Secure Mac Address Table
> ------------------------------------------------------------------------
> Vlan Mac Address Type Ports Remaining Age
> (mins)
> ---- ----------- ---- ----- -------------
> 6 001d.e5ea.a1d5 SecureDynamic Gi1/0/26 < 1
> 6 0007.7d43.638b SecureDynamic Gi1/0/31 < 1
> 6 0050.6003.76ce SecureDynamic Gi1/0/40 < 1
> 1 0050.b607.c3a3 SecureDynamic Gi1/0/43 < 1
> 1 c42c.030c.05d4 SecureDynamic Gi1/0/44 < 1
> 1 0023.5e20.a48e SecureDynamic Gi1/0/45 < 1
> ------------------------------------------------------------------------
however, I also need the last mac known to the port. For example "show port-security int g7/11" has the info I need:
> DEVON-3RDFL-138-4#sh port-security int gi 7/11
> Port Security : Enabled
> Port Status : Secure-down
> Violation Mode : Restrict
> Aging Time : 1 mins
> Aging Type : Absolute
> Maximum MAC Addresses : 1
> Total MAC Addresses : 0
> Configured MAC Addresses : 0
> Sticky MAC Addresses : 0
> Last Source Address : d4be.d995.8159 <-- We are looking for > this, but we may not know which port it was last connected to...
> Last Source Address VlanId : 455
> Security Violation Count : 0
However, enumerating all ports on a switch to find which one has a specific mac address is painful.
So, my intent is to wrte an EEM script that will enumerate all ports on a switch and hold that in an array that I can then sequentially run commands again.
Surely someone has already written a script to enumerate all switch interfaces. Anyone know where to find it?
Thanks,
Neville
04-21-2012 10:56 AM
Assuming you just want to enumerate your port-security ports, this should work for you (in Tcl).
set output [cli_run [list "show port-security address"]]
set ports [list]
foreach line [split $output "\n"] {
set line [string trim line]
regsub -all {\s+} $line " " line
if { ! [regexp {^\d} $line] } {
continue
}
lappend ports [lindex $line 3]
}
foreach port $ports {
set output [cli_run [list "sh port-security int $port"]]
if { [regexp {Last Source Address\s+:\s+([a-fA-F0-9\.]+)} $output -> mac] } {
puts "Last MAC for $port is $mac"
}
}
04-23-2012 12:00 PM
Thanks Joseph!
With your code I got my script working! I'm attaching it here.
Some notes of mine.
1) I sure like PERL *a lot* more than TCL. I find TCL weird where I don't do a ; at the end of lines, don't declare my variables with $ and not having a conecpt of an @array is killing me!
2) I changed the 1st part of the script from port-security ports to all Ethernet interfaces. If a port is down it does not show in "show port-security adresses", where it will show with "show interface summary | inc Ethernet".
3) I added Catalyst switches output port-security info two ways: either "Last Source Address : aa.bb.cc.dd.ee.ff" (older code) or "Last Source Address:Vlan : aa.bb.cc.dd.ee.ff:1" (newer code). I added logic to deal with either output.
4) The script seems to run pretty slow. It takes ~15 seconds for a switch with 24 interfaces on it. In a stack I'd run into MAXRUN time issues for sure.
Again thanks Joseph! - Finished Script below:
::cisco::eem::event_register_none
#
# Written 2012 by Neville Aga (neaga@cisco.com)
#------------------------------------------------------------------
#
# Make an alias to trigger this script, such as
# "alias exec show-last-macs event manager run show_last_macs.tcl"
#
namespace import ::cisco::eem::*
namespace import ::cisco::lib::*
# Open the CLI
if [catch {cli_open} result] {
error $result $errorInfo
} else {
array set cli1 $result
}
# Go into enable mode
if [catch {cli_exec $cli1(fd) "en"} result] {
error $result $errorInfo
}
# Enumerate switch ethernet interfaces and put them into array..
# er list. TCL doesnt do arrays
# Enumerate all ports here
set output [cli_run [list "show interfaces summary | inc Ethernet"]]
set ports [list]
foreach line [split $output "\n"] {
regsub {\*} $line "" line
set line [string trim $line]
regsub -all {\s+} $line " " line
#puts "line is $line\n"
lappend ports [lindex $line 0]
}
puts "Last MAC associated with all port-security switch ports:"
puts "by Neville Aga (neaga@cisco.com). Follow me on twitter @nevilleaga"
foreach port $ports {
set output [cli_run [list "sh port-security int $port"]]
if { [regexp {Port Security\s+:\s(Enabled)} $output -> enabled] } {
if { [regexp {Port Status\s+:\s+(\S+)} $output -> portstatus] } {}
# This will get output returned like "Last Source Address : aa.bb.cc.dd.ee.ff" - 6500 typical
if { [regexp {Last Source Address\s+:\s+([a-fA-F0-9\.]+)} $output -> mac] } {
puts "Last MAC for $port is $mac -- $portstatus "
}
# This will get output returned like "Last Source Address:Vlan : aa.bb.cc.dd.ee.ff:1" - 3560 12.2.53
if { [regexp {Last Source Address:Vlan\s+:\s+([a-fA-F0-9\.]+)} $output -> mac] } {
puts "Last MAC for $port is $mac -- $portstatus"
}
}
}
# Close the CLI
if [catch {cli_close $cli1(fd) $cli1(tty_id)} result] {
error $result $errorInfo
}
04-23-2012 12:03 PM
Here is the output of the script against a test switch (with the shameless self-promotion removed):
AS1#show-last-macs
Last MAC associated with all port-security switch ports:
Last MAC for GigabitEthernet1/0/22 is 0014.22f4.85c8 -- Secure-up
Last MAC for GigabitEthernet1/0/23 is 0023.331c.3597 -- Secure-up
Last MAC for GigabitEthernet1/0/24 is 0007.7ddf.bcea -- Secure-down
AS1#
04-23-2012 02:28 PM
I like Perl more, too, but Tcl is fun and powerful. You can use ';' at the end of lines if you like. Tcl does support arrays and hashes. Arrays in Tcl are called lists. Perl hashes in Tcl are called arrays.
List:
set l [list {This} {is} {a} {test}]
puts [lindex $l 2]
==> a
Array:
set a [list]
set a(firstname) "Joe"
set a(lastname) "Clarke"
puts $a(firstname)
==> Joe
Discover and save your favorite ideas. Come back to expert answers, step-by-step guides, recent topics, and more.
New here? Get started with these tips. How to use Community New member guide