假定你要收 trap 的 ip 是 192.168.1.254, 就打入
snmp trap add public 192.168.1.254
就可以了. 这样就应该在该机器可以收到相对的 snmp traps.
以上面 Hinet/SeedNet 两个线路来说, 如果要在同一网段上, 要先改变其中一个 ATU-R
的 ip 才可以, 内定都是 192.168.1.1, 我们把其中一个改成 192.168.1.2
然后在 192.168.1.254 机器上安装 snmptrapd, 修改 /etc/snmp/snmptrapd.conf
加上下面两行:
traphandle .1.3.6.1.6.3.1.1.5.2 /usr/local/bin/adsl_up
traphandle .1.3.6.1.6.3.1.1.5.3 /usr/local/bin/adsl_down
然后写 adsl_up, adsl_down 两个 script 来更改 route table.
内容大约是:
#!/bin/bash
read DUMMY_HOST
read ROUTE_IP
case "$ROUTE_IP" in
192.168.1.1)
ip route replace default ....
;;
*)
echo "snmp traps from unknown ip?"
esac
这样子就会在每次断线或恢复联机时收到 ATU-R 的通知了.
另外, 如果不想使用 snmp trap, 要使用 polling 的方式, 主动去查询线路情形,
可以使用 snmpwalk 来处理, 用上面的例子, 可以先执行
snmpwalk 192.168.1.1 public interfaces.ifTable.ifEntry
会出现一堆资料, 看一下 adsl 在的 index 是 20.
interfaces.ifTable.ifEntry.ifDescr.20 = ADSL physical interface
interfaces.ifTable.ifEntry.ifType.20 = adsl(94)
线路状态在
interfaces.ifTable.ifEntry.ifOperStatus.20 = up(1)
up(1) 表示联机中, 所以执行
snmpwalk 192.168.1.1 public interfaces.ifTable.ifEntry.ifOperStatus.20
会得到
interfaces.ifTable.ifEntry.ifOperStatus.20 = up(1)
当断线时, 上面就不会在 up(1) 的状态.
所以可以写个 adsl_test 的 script
snmpwalk 192.168.1.1 public interfaces.ifTable.ifEntry.ifOperStatus.20 |
grep "up(1)" | wc -l
如果得到 0 就是断线.
上面就是使用 snmpwalk 来查询线路的方法. 这个我在 arcatel 340 上面使用,
可以正确得知线路的情形. 另外, 在我家的 cisco 677 上, 在 bridge mode 下,
使用 snmpwalk 查询线路都是 up(1), 无法知道线路情形... 不过如有异动, 仍可
以收到对应的 snmp traps.
这两种方式各有利弊, 第一种方式无法得知一开始的状态, 第二种方式无法实时
得知状态的改变, 所以通常会同时利用两种方式来处理, 以上述的例子来说, 我
们可以使用下列的 script 来处理:
#!/bin/bash
# chk_adsl: check the status of ADSL and change routing table
# SNMP tree
SNMP_KEY="interfaces.ifTable.ifEntry.ifOperStatus.20"
# 对外网卡
EXT_IF="eth0"
# HiNet IP
EXT_ATUR1="192.168.1.1"
EXT_IP1="111.111.111.111"
EXT_MASK1="24"
GW1="111.111.111.1"
# SeedNet IP
EXT_ATUR2="192.168.1.2"
EXT_IP2="222.222.222.222"
EXT_MASK2="24"
GW2="222.222.222.1"
STATUS1=`snmpwalk $EXT_ATUR1 public $SNMP_KEY | grep "up(1)" | wc -l`
STATUS2=`snmpwalk $EXT_ATUR2 public $SNMP_KEY | grep "up(1)" | wc -l`
if [ "$STATUS1" = "0" ]; then
if [ "$STATUS2" = "0" ]; then
# ALL line down
echo -e "\nALL ADSL DOWN!\nDate: $(date)\nHost: $(hostname)\n" | /bin/mail -s "$(date) ALL ADSL DOWN!" root
else
# ATUR1 down, ATUR2 up
echo -e "\nADSL $EXT_ATUR1 DOWN!\nDate: $(date)\nHost: $(hostname)\n" | /bin/mail -s "$(date) ADSL $EXT_ATUR1 DOWN!" root
ip route relpace default via $GW2 dev $EXT_IF
ip route flush cache
fi
else
if [ "$STATUS2" = "0" ]; then
# ATUR1 up, ATUR2 down
echo -e "\nADSL $EXT_ATUR2 DOWN!\nDate: $(date)\nHost: $(hostname)\n" | /bin/mail -s "$(date) ADSL $EXT_ATUR2 DOWN!" root
ip route relpace default via $GW1 dev $EXT_IF
ip route flush cache
else
# All line up
echo -e "\nALL ADSL UP!\nDate: $(date)\nHost: $(hostname)\n" | /bin/mail -s "$(date) ALL ADSL UP!" root
ip route replace default equalize nexthop via $GW1 dev $EXT_IF nexthop via $GW2 dev $EXT_IF
ip route flush cache
fi
fi
利用上面的 script, 我们只要在 snmptrapd.conf 中将相关的 traphandle
指到这一个 script, 就可以依照线路的状态来做对应的处理. 当然, 如果你
的线路不只两条, 我想应该也可以照上面的作法自己试试看.
本文的最新版本可以由下列的网页取得:
http://www.teatime.com.tw/~tommy/doc/multipath.txt