2005-11-04 Paul Jakma <paul.jakma@sun.com>

	* snmptrap.texi: Contributed documentation, contributors name
	  is lost (please get in touch). Configuring SNMP for logging
	  traps.
	* snmp.texi: Minor formatting changes.
	* quagga.info: Update auto-built file
diff --git a/doc/ChangeLog b/doc/ChangeLog
index dd8b7ef..4e9ae35 100644
--- a/doc/ChangeLog
+++ b/doc/ChangeLog
@@ -1,3 +1,11 @@
+2005-11-04 Paul Jakma <paul.jakma@sun.com>
+
+	* snmptrap.texi: Contributed documentation, contributors name
+	  is lost (please get in touch). Configuring SNMP for logging
+	  traps.
+	* snmp.texi: Minor formatting changes.
+	* quagga.info: Update auto-built file
+
 2005-10-29 Paul Jakma <paul@dishone.st>
 
 	* ospfd.texi: Document the new spf and max-metric commands, and
diff --git a/doc/quagga.info b/doc/quagga.info
index f3ca189..ba1ccf8 100644
--- a/doc/quagga.info
+++ b/doc/quagga.info
Binary files differ
diff --git a/doc/snmp.texi b/doc/snmp.texi
index 96f080b..3f80cc5 100644
--- a/doc/snmp.texi
+++ b/doc/snmp.texi
@@ -1,16 +1,18 @@
 @node SNMP Support
 @chapter SNMP Support
 
-SNMP (Simple Network Managing Protocol) is a widely implemented feature for
-collecting network information from router and/or host. Quagga itself does not
-support SNMP agent (server daemon) functionality but is able to connect to a
-SNMP agent using the SMUX protocol (RFC1227) and make the routing protocol MIBs
-available through it.
+@acronym{SNMP,Simple Network Managing Protocol} is a widely implemented
+feature for collecting network information from router and/or host.
+Quagga itself does not support SNMP agent (server daemon) functionality
+but is able to connect to a SNMP agent using the SMUX protocol
+(@cite{RFC1227}) and make the routing protocol MIBs available through
+it.
 
 @menu
 * Getting and installing an SNMP agent::
 * SMUX configuration::
 * MIB and command reference::
+* Handling SNMP Traps::
 @end menu
 
 @node Getting and installing an SNMP agent
@@ -29,15 +31,16 @@
 To enable SMUX protocol support, Quagga must have been build with the
 @code{--enable-snmp} option.
 
-A separate connection has then to be established between between the SNMP agent
-(snmpd) and each of the Quagga daemons. This connections each use different OID
-numbers and passwords. Be aware that this OID number is not the one that is
-used in queries by clients, it is solely used for the intercommunication of the
-daemons.
+A separate connection has then to be established between between the
+SNMP agent (snmpd) and each of the Quagga daemons. This connections
+each use different OID numbers and passwords. Be aware that this OID
+number is not the one that is used in queries by clients, it is solely
+used for the intercommunication of the daemons.
 
-In the following example the ospfd daemon will be connected to the snmpd daemon
-using the password "quagga_ospfd". For testing it is recommending to take
-exactly the below snmpd.conf as wrong access restrictions can be hard to debug.
+In the following example the ospfd daemon will be connected to the
+snmpd daemon using the password "quagga_ospfd". For testing it is
+recommending to take exactly the below snmpd.conf as wrong access
+restrictions can be hard to debug.
 
 @example
 /etc/snmp/snmpd.conf:
@@ -109,3 +112,5 @@
 @deffn {Command} {smux peer @var{oid} @var{password}} {}
 @deffnx {Command} {no smux peer @var{oid} @var{password}} {}
 @end deffn
+
+@include snmptrap.texi
diff --git a/doc/snmptrap.texi b/doc/snmptrap.texi
new file mode 100644
index 0000000..a80b4d4
--- /dev/null
+++ b/doc/snmptrap.texi
@@ -0,0 +1,203 @@
+@node Handling SNMP Traps
+@section Handling SNMP Traps
+
+To handle snmp traps make sure your snmp setup of quagga works
+correctly as described in the quagga documentation in @xref{SNMP Support}.
+
+The BGP4 mib will send traps on peer up/down events. These should be
+visible in your snmp logs with a message similar to:
+
+@samp{snmpd[13733]: Got trap from peer on fd 14}
+
+To react on these traps they should be handled by a trapsink. Configure
+your trapsink by adding the following lines to @file{/etc/snmpd/snmpd.conf}:
+
+@example
+  # send traps to the snmptrapd on localhost
+  trapsink localhost
+@end example
+
+This will send all traps to an snmptrapd running on localhost. You can
+of course also use a dedicated management station to catch traps.
+Configure the snmptrapd daemon by adding the following line to
+@file{/etc/snmpd/snmptrapd.conf}:
+
+@example
+  traphandle .1.3.6.1.4.1.3317.1.2.2 /etc/snmp/snmptrap_handle.sh
+@end example
+
+This will use the bash script @file{/etc/snmp/snmptrap_handle.sh} to handle
+the BGP4 traps. To add traps for other protocol daemons, lookup their
+appropriate OID from their mib. (For additional information about which
+traps are supported by your mib, lookup the mib on
+@uref{http://www.oidview.com/mibs/detail.html}).
+
+Make sure snmptrapd is started.
+
+The snmptrap_handle.sh script I personally use for handling BGP4 traps
+is below. You can of course do all sorts of things when handling traps,
+like sound a siren, have your display flash, etc., be creative ;).
+
+@verbatim
+  #!/bin/bash
+
+  # routers name
+  ROUTER=`hostname -s`
+
+  #email address use to sent out notification
+  EMAILADDR="john@doe.com"
+  #email address used (allongside above) where warnings should be sent
+  EMAILADDR_WARN="sms-john@doe.com"
+
+  # type of notification
+  TYPE="Notice"
+
+  # local snmp community for getting AS belonging to peer
+  COMMUNITY="<community>"
+
+  # if a peer address is in $WARN_PEERS a warning should be sent
+  WARN_PEERS="192.0.2.1"
+
+
+  # get stdin
+  INPUT=`cat -`
+
+  # get some vars from stdin
+  uptime=`echo $INPUT | cut -d' ' -f5`
+  peer=`echo $INPUT | cut -d' ' -f8 | sed -e 's/SNMPv2-SMI::mib-2.15.3.1.14.//g'`
+  peerstate=`echo $INPUT | cut -d' ' -f13`
+  errorcode=`echo $INPUT | cut -d' ' -f9 | sed -e 's/\"//g'`
+  suberrorcode=`echo $INPUT | cut -d' ' -f10 | sed -e 's/\"//g'`
+  remoteas=`snmpget -v2c -c $COMMUNITY localhost SNMPv2-SMI::mib-2.15.3.1.9.$peer | cut -d' ' -f4`
+
+  WHOISINFO=`whois -h whois.ripe.net " -r AS$remoteas" | egrep '(as-name|descr)'`
+  asname=`echo "$WHOISINFO" | grep "^as-name:" | sed -e 's/^as-name://g' -e 's/  //g' -e 's/^ //g' | uniq`
+  asdescr=`echo "$WHOISINFO" | grep "^descr:" | sed -e 's/^descr://g' -e 's/  //g' -e 's/^ //g' | uniq`
+
+  # if peer address is in $WARN_PEER, the email should also
+  # be sent to $EMAILADDR_WARN
+  for ip in $WARN_PEERS; do
+    if [ "x$ip" == "x$peer" ]; then
+      EMAILADDR="$EMAILADDR,$EMAILADDR_WARN"
+      TYPE="WARNING"
+      break
+    fi
+  done
+  
+
+  # convert peer state
+  case "$peerstate" in
+    1) peerstate="Idle" ;;
+    2) peerstate="Connect" ;;
+    3) peerstate="Active" ;;
+    4) peerstate="Opensent" ;;
+    5) peerstate="Openconfirm" ;;
+    6) peerstate="Established" ;;
+    *) peerstate="Unknown" ;;
+  esac
+
+  # get textual messages for errors
+  case "$errorcode" in
+    00)
+      error="No error"
+      suberror=""
+      ;;
+    01)
+      error="Message Header Error"
+      case "$suberrorcode" in
+        01) suberror="Connection Not Synchronized" ;;
+        02) suberror="Bad Message Length" ;;
+        03) suberror="Bad Message Type" ;;
+        *) suberror="Unknown" ;;
+      esac
+      ;;
+    02)    
+      error="OPEN Message Error"
+      case "$suberrorcode" in
+        01) suberror="Unsupported Version Number" ;;
+        02) suberror="Bad Peer AS" ;;
+        03) suberror="Bad BGP Identifier" ;;
+        04) suberror="Unsupported Optional Parameter" ;;
+        05) suberror="Authentication Failure" ;;
+        06) suberror="Unacceptable Hold Time" ;;
+        *) suberror="Unknown" ;;
+      esac
+      ;;
+    03)
+      error="UPDATE Message Error"
+      case "$suberrorcode" in
+        01) suberror="Malformed Attribute List" ;;
+        02) suberror="Unrecognized Well-known Attribute" ;;
+        03) suberror="Missing Well-known Attribute" ;;
+        04) suberror="Attribute Flags Error" ;;
+        05) suberror="Attribute Length Error" ;;
+        06) suberror="Invalid ORIGIN Attribute" ;;
+        07) suberror="AS Routing Loop" ;;
+        08) suberror="Invalid NEXT_HOP Attribute" ;;
+        09) suberror="Optional Attribute Error" ;;
+        10) suberror="Invalid Network Field" ;;
+        11) suberror="Malformed AS_PATH" ;;
+        *) suberror="Unknown" ;;
+      esac
+      ;;
+    04)
+      error="Hold Timer Expired"
+      suberror=""
+      ;;
+    05)
+      error="Finite State Machine Error"
+      suberror=""
+      ;;
+    06)
+      error="Cease"
+      case "$suberrorcode" in
+        01) suberror="Maximum Number of Prefixes Reached" ;;
+        02) suberror="Administratively Shutdown" ;;
+        03) suberror="Peer Unconfigured" ;;
+        04) suberror="Administratively Reset" ;;
+        05) suberror="Connection Rejected" ;;
+        06) suberror="Other Configuration Change" ;;
+        07) suberror="Connection collision resolution" ;;
+        08) suberror="Out of Resource" ;;
+        09) suberror="MAX" ;;
+        *) suberror="Unknown" ;;
+      esac
+      ;;
+    *)
+      error="Unknown"
+      suberror=""
+      ;;
+  esac
+
+  # create textual message from errorcodes
+  if [ "x$suberror" == "x" ]; then
+    NOTIFY="$errorcode ($error)"
+  else
+    NOTIFY="$errorcode/$suberrorcode ($error/$suberror)"
+  fi
+ 
+
+  # form a decent subject
+  SUBJECT="$TYPE: $ROUTER [bgp] $peer is $peerstate: $NOTIFY"
+  # create the email body
+  MAIL=`cat << EOF
+  BGP notification on router $ROUTER.
+  
+  Peer: $peer
+  AS: $remoteas
+  New state: $peerstate
+  Notification: $NOTIFY
+
+  Info:
+  $asname
+  $asdescr
+ 
+  Snmpd uptime: $uptime
+  EOF`
+
+  # mail the notification
+  echo "$MAIL" | mail -s "$SUBJECT" $EMAILADDR
+@end verbatim
+
+@comment contributed by unknown contributer, please contact maintainers
+@comment for credit / attribution.