cancel
Showing results for 
Search instead for 
Did you mean: 
cancel
3698
Views
0
Helpful
4
Replies

Enumerate switch ports

neaga
Cisco Employee
Cisco Employee

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

4 Replies 4

Joe Clarke
Cisco Employee
Cisco Employee

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"

    }

}

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

}

neaga
Cisco Employee
Cisco Employee

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#

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