TCL scripting for ARP table display

ARP table display

Original Url  # http://wiki.nil.com/ARP_table_display

In a layer-3 switching environment, the ARP table displayed with the show arp command lists the logical (L3) interfaces, for example the VLAN or BVI interface. This Tcl script displays the logical as well as physical interface associated with each IP/MAC address. The show mac-address-table and show bridge commands are used to establish the mapping between MAC addresses and physical interfaces. The script has been tested on Catalyst 3500 switches running Cisco IOS release 12.2 and routers running Cisco IOS release 12.4.

Installation

Download the source file into flash:arp.tcl. Configure alias exec arp tclsh flash:arp.tcl. Invoke with arp [ip-address].

Usage guidelines

Usage: arp [ip-address]

Without the ip-address parameter, the script displays the whole ARP table. When an IP address is specified, only the corresponding ARP entry is displayed.

Author

Ivan Pepelnjak, © 2008 NIL Data Communications

Sample printout

router#arp

IP address      MAC address    Physical intf        Logical intf
=============== ============== ==================== ===========
192.168.200.193 001b.2ac8.61c6                      Vlan1
192.168.200.194 0004.2322.ba4c FastEthernet5        Vlan1
192.168.200.196 0016.41e6.dc2c FastEthernet5        Vlan1
192.168.200.198 0010.a4a8.6886 FastEthernet5        Vlan1
192.168.200.206 000f.fe83.bca9 FastEthernet4        Vlan1

router#arp 192.168.200.206

IP address      MAC address    Physical intf        Logical intf
=============== ============== ==================== ===========
192.168.200.206 000f.fe83.bca9 FastEthernet4        Vlan1

Source code

#
# Copyright (c) 2008 NIL Data Communications
# All rights reserved.
#
# by:   Ivan Pepelnjak, NIL Data Communications
# desc: Displays IP-to-MAC mappings with logical (VLAN) and physical interfaces
# name: arp.tcl
#
# ios config:
#
#           * download the file into flash:arp.tcl
#           * configure alias exec arp tclsh flash:arp.tcl
#
#           invoke with "arp [ip-address]"
#

if { ! [string equal $tcl_platform(os) "Cisco IOS"] } { source "exec.tcl" }

proc getMacTable {} {
  global macTable
  foreach line [split [exec "show mac-address-table"] "\n"] {
    if {[regexp -nocase {^([0-9a-f.]+).*?([a-z]+ethernet[0-9/.]+)} $line ignore mac intf]} {
      set macTable($mac) $intf
    }
    if {[regexp -nocase {^\s*(All|[0-9]+)\s+([0-9a-f.]+)\s+\w+\s+([a-z0-9/.]+)} $line ignore vlan mac intf]} {
      set macTable($mac) $intf
    }
   
  }
}

proc getBridgeTable {} {
  global macTable
  foreach line [split [exec "show bridge"] "\n"] {
    if {[regexp -nocase {^([0-9a-f.]+)\s+\w+\s+([a-z]+ethernet[0-9/.]+)} $line ignore mac intf]} {
      puts $ignore
      set macTable($mac) $intf
    }
  }
}

proc printInterface {dataName} {
  upvar $dataName data
  global lineFormat
  global paramActive
  if {! [array exists data]} { return }
  if {$paramActive != 0} { if {[string equal $data(IPADDR) "no address"]} { return } }
  puts [format $lineFormat $data(IFNAME) $data(IPADDR) $data(IPMASK) $data(IPMTU) $data(IFSTAT)]
}

proc printArpTable {ipaddr} {
  global macTable
  set lineFormat "%-15s %-14s %-20s %s"
  puts [format $lineFormat {IP address} {MAC address} {Physical intf} {Logical intf}]
  puts "=============== ============== ==================== ==========="
  set cmd "show arp[if {[string length $ipaddr] > 0} {subst { | include $ipaddr}}]"
  foreach line [split [exec $cmd] "\n"] {
    if {[regexp -nocase {^Internet\s+([0-9.]+)\s+[0-9-]+\s+([0-9a-f.]+)\s+\w+\s+([a-z0-9/.]+)} $line ignore ipaddr mac intf]} {
      set phy ""
      if {[regexp -nocase {ethernet} $intf]} {
        set phy $intf
        set intf ""
      } else {
        if {[info exists macTable($mac)]} { set phy $macTable($mac) }
      }
      puts [format $lineFormat $ipaddr $mac $phy $intf]
    }
  }
}

if {! [string equal $argv ""]} {
  if {![regexp {^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$} $argv]} {
    puts {Usage: arp [ip-address]}; return;
  }
}

set macTable(ffff.ffff.ffff) "invalid"
catch { getMacTable } err
catch { getBridgeTable } err

printArpTable $argv