MAC address finder for Bay/Nortel switches

Our Minneapolis office has several Bay/Nortel 5000BH switches. Given a MAC address, we would like to search these switches for the switch, module, and port number location. I created an Expect script and Bourne shell wrapper on a Solaris system to accomplish this.

The Expect script takes three arguments:

(1) Bay/Nortel switch
(2) Temporary output file of switch CAM/bridging/FDB table
(3) Switch password, if applicable

MAC_search.exp

#!/usr/local/bin/expect
log_user 0
log_file -a [lindex $argv 1]
spawn telnet [lindex $argv 0]
expect "Please enter password:"
send "[lindex $argv 2]\r"
expect "Command >"
send "more disable\r"
expect "Command >"
send "show fdb mcp all\r"
expect "Command >"
log_file
send "logout\r"

The wrapper script is run with one or more MAC addresses. The MAC addresses may contain hyphens or colons, and uppercase or lowercase characters may be used.

MAC_search

#!/bin/sh

# Variables
EXPECT=/usr/local/bin/expect
EXPECT_SCRIPT=/opt/MAC_search/MAC_search.exp
OUTPUT_FILE=`basename $0`_output
# Solaris' awk apparently does not work with the "tolower" function
AWK=/vol.nsm/tools/bin/gawk

# Command-line argument(s)
MAC_ADDRESSES=`echo $@ | tr -d ':-' | $AWK '{print tolower($0)}'`
ARGV_LENGTH=`echo $MAC_ADDRESSES | wc -c`

# Make sure one or more valid (in length) MAC addresses were entered
if [ $# -lt 1 ] || [ "`echo $ARGV_LENGTH % 13 | bc`" -ne 0 ] ; then
   echo "Usage: `basename $0` MAC_address(es)"
   exit 1
fi

# Convert MAC_ADDRESSES to regex for egrep searching
MAC_ADDRESSES=`echo $MAC_ADDRESSES | tr ' ' '|'`

# Remove $OUTPUT_FILE if it exists
[ -f $OUTPUT_FILE ] && rm -f $OUTPUT_FILE

# Passwordless switches
$EXPECT_SCRIPT switch1 switch1_fdb_table
$EXPECT_SCRIPT switch2 switch2_fdb_table

# Password-enabled switches
$EXPECT_SCRIPT switch3 switch3_fdb_table switch3_password
$EXPECT_SCRIPT switch4 switch4_fdb_table switch4_password

# Clean-up data
printf "%-9s %-16s %-8s %-8s\n" "Switch" "MAC address" "Module" "Port" > $OUTPUT_FILE
printf "%-9s %-16s %-8s %-8s\n" "---------" "------------" "------" "----" >> $OUTPUT_FILE

for FILE in *_fdb_table
do
   SWITCH=`echo $FILE | cut -d_ -f1`
   $AWK '$7 != "n/a" && $7 ~ /[0-9]+/ {printf "%-9s %-16s %-8d %-8d\n", SWITCH, tolower($3), $7, $8 }' SWITCH=$SWITCH $FILE | sort | uniq >> $OUTPUT_FILE
done

if [ -n "`egrep $MAC_ADDRESSES $OUTPUT_FILE`" ] ; then
   head -n2 $OUTPUT_FILE
   egrep $MAC_ADDRESSES $OUTPUT_FILE
else
   echo "The MAC address(es) $@ were not found in the switches' bridging tables."
fi

# Remove temporary files
rm *_fdb_table

Example:

$ ./MAC_search 00:20:ED:B7:52:52 00:08:C7:A4:AF:28

Switch    MAC address      Module   Port   
--------- ------------     ------   ----   
switch1   0008c7a4af28     6        9      
switch2   0020edb75252     5        9      

Back to brandonhutchinson.com.
Last modified: 09/02/2004