Last active
September 10, 2019 01:39
-
-
Save lxf1992521/ae4c398bde74edad5dc0ef5a0a600bf5 to your computer and use it in GitHub Desktop.
交换机-主机拓扑链路追踪脚本,使用 shell 语法完成
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# ============================================================ | |
# related links: | |
# http://www.cisco.com/c/en/us/support/docs/ip/simple-network-management-protocol-snmp/13492-cam-snmp.html | |
# ============================================================ | |
# ============ related MIB/OIDs ============================= | |
# CISCO-CDP-MIB::cdpCacheDeviceId | |
# CISCO-CDP-MIB::cdpCacheDevicePort | |
# SNMPv2-MIB::sysName.0 | |
# IF-MIB::ifName | |
# BRIDGE-MIB::dot1dBasePortIfIndex | |
# CISCO-VTP-MIB::vtpVlanState | |
# VALN: BRIDGE-MIB::dot1dTpFdbPort | |
# ============================================================ | |
# port-channel: CISCO-PAGP-MIB::pagpGroupIfIndex | |
# LACP portchannel: IEEE8023-LAG-MIB::dot3adAggPortSelectedAggID | |
# Linux: | |
# - bond0 配合 port-channel 一起使用; | |
# - bond1 只能显示当前激活的那个端口,另外一个无法得到; | |
# - bond4 配合 LACP portchannel 一起使用; | |
# - bond5/6 可以同时看到所有连接的端口; | |
# ============================================================ | |
cd -- "$(dirname -- "$0")" || exit | |
# set params | |
if [ "$1" == "-n" ]; then | |
switchmap=1 | |
shift | |
fi | |
siwtchlist="${1:-switch.list}" | |
hostmacmap="${2:-host.mac}" | |
asamacmap="${3:-asa.mac}" | |
commuity=XXXXXX | |
# get MIB to associative arrays | |
mibarray() { | |
[ -n "$3" ] && commuity="$commuity@$3" | |
snmpbulkwalk -OX -OQ -v 2c -c "$commuity" $1 $2 2> /dev/null | grep -v '= No Such Instance' | sed -r "s/$2\[([^]]+)\].* = ([^ ]+)$/[\1]=\2/" | tr "\n" " " | |
} | |
# Main function | |
switch_host_map() { | |
local switchip="$1" | |
# hostname | |
local switchname=$(snmpget -Ov -OQ -v 2c -c $commuity $switchip SNMPv2-MIB::sysName.0) | |
[ -n "$switchname" ] || return 1 | |
# ifname <--> port | |
eval local -A ifindex0ifname=( $(mibarray $switchip IF-MIB::ifName) ) | |
eval local -A ifport0ifindex=( $(mibarray $switchip BRIDGE-MIB::dot1dBasePortIfIndex) ) | |
# port-channel map | |
eval local -A ifindex0ifindex4lacpportchannel=( $(mibarray $switchip IEEE8023-LAG-MIB::dot3adAggPortSelectedAggID) ) | |
eval local -A ifindex0ifindex4portchannel=( $(mibarray $switchip CISCO-PAGP-MIB::pagpGroupIfIndex) ) | |
# CDP Info | |
eval local -A ifindex0cdpeviceid=( $(mibarray $switchip CISCO-CDP-MIB::cdpCacheDeviceId) ) | |
eval local -A ifindex0cdpeviceport=( $(mibarray $switchip CISCO-CDP-MIB::cdpCacheDevicePort) ) | |
# mac/ifport for every vlan | |
local vlanlist=$(snmpbulkwalk -Oq -v 2c -c $commuity $switchip CISCO-VTP-MIB::vtpVlanState | awk -F'[. ]' '$(NF-1) < 1002 {print $(NF-1) }') | |
local -A mac0ifport | |
for vlan in $vlanlist; do | |
eval mac0ifport+=( $(mibarray $switchip BRIDGE-MIB::dot1dTpFdbPort $vlan | tr : _) ) | |
done | |
# ifport <---> (cdp|mac|hostname) | |
echo -e "\n$switchname[$switchip]:" | |
for ifindex in $( xargs -n 1 <<<"${!ifindex0ifname[@]}" | sort -n); do | |
for ifport in ${!ifport0ifindex[@]}; do | |
[[ ${ifport0ifindex[$ifport]} == $ifindex ]] && break | |
unset ifport | |
done | |
ifname=${ifindex0ifname[$ifindex]} | |
# cdp | |
cdpeviceid=${ifindex0cdpeviceid[$ifindex]} | |
cdpeviceport=${ifindex0cdpeviceport[$ifindex]} | |
# mac | |
maclist="" | |
macnum=0 | |
for mac in ${!mac0ifport[@]}; do | |
[[ ${mac0ifport[$mac]} == $ifport ]] && { | |
maclist+="${mac//_/:}"$'\n' | |
((macnum++)) | |
} | |
done | |
# portchannel | |
local lacpportchannelifname="" | |
lacpportchannelifindex=${ifindex0ifindex4lacpportchannel[$ifindex]} | |
[ -n "$lacpportchannelifindex" ] && [ "$lacpportchannelifindex" != 0 ] && lacpportchannelifname=${ifindex0ifname[$lacpportchannelifindex]} | |
portchannelifindex=${ifindex0ifindex4portchannel[$ifindex]} | |
local portchannelifname="" | |
[ -n "$portchannelifindex" ] && [ "$portchannelifindex" != "$ifindex" ] && [ "$portchannelifindex" != 0 ] && | |
portchannelifname=${ifindex0ifname[$portchannelifindex]} | |
# interface info | |
if [ -n "$cdpeviceid" ]; then | |
echo -e "$ifname\t$cdpeviceid[$cdpeviceport]" | |
elif [ $macnum -eq 1 -o $macnum -eq 2 ]; then | |
host=$( | |
for mac in $maclist; do | |
grep -h -w $mac $hostmacmap $asamacmap | awk '{print $1}' | |
done | sort -u) | |
[ -z "$host" ] && host="<unknown>" | |
echo -e "$ifname\t"$host | |
elif [ $macnum -gt 1 ]; then | |
echo -e "$ifname\t<floading>" | |
elif [ -n "$portchannelifname" ]; then | |
echo -e "$ifname\t[$portchannelifname]" | |
elif [ -n "$lacpportchannelifname" ]; then | |
echo -e "$ifname\t[$lacpportchannelifname(LACP)]" | |
else | |
: | |
# echo -e "$ifname\t<down>" | |
fi | |
done | column -t | sed 's/^/\t/' | |
} | |
for switch in $(<$siwtchlist); do | |
switch_host_map $switch | |
done |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment