/* RIP version 1 and 2.
 * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro <kunihiro@zebra.org>
 *
 * This file is part of GNU Zebra.
 *
 * GNU Zebra is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2, or (at your option) any
 * later version.
 *
 * GNU Zebra is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with GNU Zebra; see the file COPYING.  If not, write to the Free
 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 * 02111-1307, USA.  
 */

#include <zebra.h>

#include "if.h"
#include "command.h"
#include "prefix.h"
#include "table.h"
#include "thread.h"
#include "memory.h"
#include "log.h"
#include "stream.h"
#include "filter.h"
#include "sockunion.h"
#include "routemap.h"
#include "if_rmap.h"
#include "plist.h"
#include "distribute.h"
#include "md5-gnu.h"
#include "keychain.h"
#include "privs.h"

#include "ripd/ripd.h"
#include "ripd/rip_debug.h"

extern struct zebra_privs_t ripd_privs;

/* RIP Structure. */
struct rip *rip = NULL;

/* RIP neighbor address table. */
struct route_table *rip_neighbor_table;

/* RIP route changes. */
long rip_global_route_changes = 0;

/* RIP queries. */
long rip_global_queries = 0;

/* Prototypes. */
void rip_event (enum rip_event, int);

void rip_output_process (struct interface *, struct prefix *,
			 struct sockaddr_in *, int, u_char, 
                         struct connected *, struct prefix_ipv4 *);

/* RIP output routes type. */
enum
{
  rip_all_route,
  rip_changed_route
};

/* RIP command strings. */
struct message rip_msg[] = 
{
  {RIP_REQUEST,    "REQUEST"},
  {RIP_RESPONSE,   "RESPONSE"},
  {RIP_TRACEON,    "TRACEON"},
  {RIP_TRACEOFF,   "TRACEOFF"},
  {RIP_POLL,       "POLL"},
  {RIP_POLL_ENTRY, "POLL ENTRY"},
  {0,              NULL}
};

/* Each route type's strings and default preference. */
struct
{  
  int key;
  char *str;
  char *str_long;
} route_info[] =
{
  { ZEBRA_ROUTE_SYSTEM,  "X", "system"},
  { ZEBRA_ROUTE_KERNEL,  "K", "kernel"},
  { ZEBRA_ROUTE_CONNECT, "C", "connected"},
  { ZEBRA_ROUTE_STATIC,  "S", "static"},
  { ZEBRA_ROUTE_RIP,     "R", "rip"},
  { ZEBRA_ROUTE_RIPNG,   "R", "ripng"},
  { ZEBRA_ROUTE_OSPF,    "O", "ospf"},
  { ZEBRA_ROUTE_OSPF6,   "O", "ospf6"},
  { ZEBRA_ROUTE_BGP,     "B", "bgp"}
};

/* Utility function to set boradcast option to the socket. */
int
sockopt_broadcast (int sock)
{
  int ret;
  int on = 1;

  ret = setsockopt (sock, SOL_SOCKET, SO_BROADCAST, (char *) &on, sizeof on);
  if (ret < 0)
    {
      zlog_warn ("can't set sockopt SO_BROADCAST to socket %d", sock);
      return -1;
    }
  return 0;
}

int
rip_route_rte (struct rip_info *rinfo)
{
  return (rinfo->type == ZEBRA_ROUTE_RIP && rinfo->sub_type == RIP_ROUTE_RTE);
}

struct rip_info *
rip_info_new ()
{
  struct rip_info *new;

  new = XMALLOC (MTYPE_RIP_INFO, sizeof (struct rip_info));
  memset (new, 0, sizeof (struct rip_info));
  return new;
}

void
rip_info_free (struct rip_info *rinfo)
{
  XFREE (MTYPE_RIP_INFO, rinfo);
}

/* RIP route garbage collect timer. */
int
rip_garbage_collect (struct thread *t)
{
  struct rip_info *rinfo;
  struct route_node *rp;

  rinfo = THREAD_ARG (t);
  rinfo->t_garbage_collect = NULL;

  /* Off timeout timer. */
  RIP_TIMER_OFF (rinfo->t_timeout);
  
  /* Get route_node pointer. */
  rp = rinfo->rp;

  /* Unlock route_node. */
  rp->info = NULL;
  route_unlock_node (rp);

  /* Free RIP routing information. */
  rip_info_free (rinfo);

  return 0;
}

/* Timeout RIP routes. */
int
rip_timeout (struct thread *t)
{
  struct rip_info *rinfo;
  struct route_node *rn;

  rinfo = THREAD_ARG (t);
  rinfo->t_timeout = NULL;

  rn = rinfo->rp;

  /* - The garbage-collection timer is set for 120 seconds. */
  RIP_TIMER_ON (rinfo->t_garbage_collect, rip_garbage_collect, 
		rip->garbage_time);

  rip_zebra_ipv4_delete ((struct prefix_ipv4 *)&rn->p, &rinfo->nexthop,
			 rinfo->metric);
  /* - The metric for the route is set to 16 (infinity).  This causes
     the route to be removed from service. */
  rinfo->metric = RIP_METRIC_INFINITY;
  rinfo->flags &= ~RIP_RTF_FIB;

  /* - The route change flag is to indicate that this entry has been
     changed. */
  rinfo->flags |= RIP_RTF_CHANGED;

  /* - The output process is signalled to trigger a response. */
  rip_event (RIP_TRIGGERED_UPDATE, 0);

  return 0;
}

void
rip_timeout_update (struct rip_info *rinfo)
{
  if (rinfo->metric != RIP_METRIC_INFINITY)
    {
      RIP_TIMER_OFF (rinfo->t_timeout);
      RIP_TIMER_ON (rinfo->t_timeout, rip_timeout, rip->timeout_time);
    }
}

int
rip_incoming_filter (struct prefix_ipv4 *p, struct rip_interface *ri)
{
  struct distribute *dist;
  struct access_list *alist;
  struct prefix_list *plist;

  /* Input distribute-list filtering. */
  if (ri->list[RIP_FILTER_IN])
    {
      if (access_list_apply (ri->list[RIP_FILTER_IN], 
			     (struct prefix *) p) == FILTER_DENY)
	{
	  if (IS_RIP_DEBUG_PACKET)
	    zlog_info ("%s/%d filtered by distribute in",
		       inet_ntoa (p->prefix), p->prefixlen);
	  return -1;
	}
    }
  if (ri->prefix[RIP_FILTER_IN])
    {
      if (prefix_list_apply (ri->prefix[RIP_FILTER_IN], 
			     (struct prefix *) p) == PREFIX_DENY)
	{
	  if (IS_RIP_DEBUG_PACKET)
	    zlog_info ("%s/%d filtered by prefix-list in",
		       inet_ntoa (p->prefix), p->prefixlen);
	  return -1;
	}
    }

  /* All interface filter check. */
  dist = distribute_lookup (NULL);
  if (dist)
    {
      if (dist->list[DISTRIBUTE_IN])
	{
	  alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_IN]);
	    
	  if (alist)
	    {
	      if (access_list_apply (alist,
				     (struct prefix *) p) == FILTER_DENY)
		{
		  if (IS_RIP_DEBUG_PACKET)
		    zlog_info ("%s/%d filtered by distribute in",
			       inet_ntoa (p->prefix), p->prefixlen);
		  return -1;
		}
	    }
	}
      if (dist->prefix[DISTRIBUTE_IN])
	{
	  plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_IN]);
	  
	  if (plist)
	    {
	      if (prefix_list_apply (plist,
				     (struct prefix *) p) == PREFIX_DENY)
		{
		  if (IS_RIP_DEBUG_PACKET)
		    zlog_info ("%s/%d filtered by prefix-list in",
			       inet_ntoa (p->prefix), p->prefixlen);
		  return -1;
		}
	    }
	}
    }
  return 0;
}

int
rip_outgoing_filter (struct prefix_ipv4 *p, struct rip_interface *ri)
{
  struct distribute *dist;
  struct access_list *alist;
  struct prefix_list *plist;

  if (ri->list[RIP_FILTER_OUT])
    {
      if (access_list_apply (ri->list[RIP_FILTER_OUT],
			     (struct prefix *) p) == FILTER_DENY)
	{
	  if (IS_RIP_DEBUG_PACKET)
	    zlog_info ("%s/%d is filtered by distribute out",
		       inet_ntoa (p->prefix), p->prefixlen);
	  return -1;
	}
    }
  if (ri->prefix[RIP_FILTER_OUT])
    {
      if (prefix_list_apply (ri->prefix[RIP_FILTER_OUT],
			     (struct prefix *) p) == PREFIX_DENY)
	{
	  if (IS_RIP_DEBUG_PACKET)
	    zlog_info ("%s/%d is filtered by prefix-list out",
		       inet_ntoa (p->prefix), p->prefixlen);
	  return -1;
	}
    }

  /* All interface filter check. */
  dist = distribute_lookup (NULL);
  if (dist)
    {
      if (dist->list[DISTRIBUTE_OUT])
	{
	  alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_OUT]);
	    
	  if (alist)
	    {
	      if (access_list_apply (alist,
				     (struct prefix *) p) == FILTER_DENY)
		{
		  if (IS_RIP_DEBUG_PACKET)
		    zlog_info ("%s/%d filtered by distribute out",
			       inet_ntoa (p->prefix), p->prefixlen);
		  return -1;
		}
	    }
	}
      if (dist->prefix[DISTRIBUTE_OUT])
	{
	  plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_OUT]);
	  
	  if (plist)
	    {
	      if (prefix_list_apply (plist,
				     (struct prefix *) p) == PREFIX_DENY)
		{
		  if (IS_RIP_DEBUG_PACKET)
		    zlog_info ("%s/%d filtered by prefix-list out",
			       inet_ntoa (p->prefix), p->prefixlen);
		  return -1;
		}
	    }
	}
    }
  return 0;
}

/* Check nexthop address validity. */
static int
rip_nexthop_check (struct in_addr *addr)
{
  listnode node;
  listnode cnode;
  struct interface *ifp;
  struct connected *ifc;
  struct prefix *p;

  /* If nexthop address matches local configured address then it is
     invalid nexthop. */
  for (node = listhead (iflist); node; nextnode (node))
    {
      ifp = getdata (node);

      for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
	{	    
	  ifc = getdata (cnode);
	  p = ifc->address;

	  if (p->family == AF_INET
	      && IPV4_ADDR_SAME (&p->u.prefix4, addr))
	    return -1;
	}
    }
  return 0;
}

/* RIP add route to routing table. */
void
rip_rte_process (struct rte *rte, struct sockaddr_in *from,
                 struct interface *ifp)
{
  int ret;
  struct prefix_ipv4 p;
  struct route_node *rp;
  struct rip_info *rinfo, rinfotmp;
  struct rip_interface *ri;
  struct in_addr *nexthop;
  u_char oldmetric;
  int same = 0;

  /* Make prefix structure. */
  memset (&p, 0, sizeof (struct prefix_ipv4));
  p.family = AF_INET;
  p.prefix = rte->prefix;
  p.prefixlen = ip_masklen (rte->mask);

  /* Make sure mask is applied. */
  apply_mask_ipv4 (&p);

  /* Apply input filters. */
  ri = ifp->info;

  ret = rip_incoming_filter (&p, ri);
  if (ret < 0)
    return;

  /* Modify entry according to the interface routemap. */
  if (ri->routemap[RIP_FILTER_IN])
    {
      int ret;
      struct rip_info newinfo;

      memset (&newinfo, 0, sizeof (newinfo));
      newinfo.type = ZEBRA_ROUTE_RIP;
      newinfo.sub_type = RIP_ROUTE_RTE;
      newinfo.nexthop = rte->nexthop;
      newinfo.from = from->sin_addr;
      newinfo.ifindex = ifp->ifindex;
      newinfo.metric = rte->metric;
      newinfo.metric_out = rte->metric; /* XXX */
      newinfo.tag = ntohs (rte->tag);   /* XXX */

      /* The object should be of the type of rip_info */
      ret = route_map_apply (ri->routemap[RIP_FILTER_IN],
                             (struct prefix *) &p, RMAP_RIP, &newinfo);

      if (ret == RMAP_DENYMATCH)
        {
          if (IS_RIP_DEBUG_PACKET)
            zlog_info ("RIP %s/%d is filtered by route-map in",
                       inet_ntoa (p.prefix), p.prefixlen);
          return;
        }

      /* Get back the object */
      rte->nexthop = newinfo.nexthop_out;
      rte->tag = htons (newinfo.tag_out);       /* XXX */
      rte->metric = newinfo.metric_out; /* XXX: the routemap uses the metric_out field */
    }

  /* Once the entry has been validated, update the metric by
     adding the cost of the network on wich the message
     arrived. If the result is greater than infinity, use infinity
     (RFC2453 Sec. 3.9.2) */
  /* Zebra ripd can handle offset-list in. */
  ret = rip_offset_list_apply_in (&p, ifp, &rte->metric);

  /* If offset-list does not modify the metric use interface's
     metric. */
  if (!ret)
    rte->metric += ifp->metric;

  if (rte->metric > RIP_METRIC_INFINITY)
    rte->metric = RIP_METRIC_INFINITY;

  /* Set nexthop pointer. */
  if (rte->nexthop.s_addr == 0)
    nexthop = &from->sin_addr;
  else
    nexthop = &rte->nexthop;

  /* Check if nexthop address is myself, then do nothing. */
  if (rip_nexthop_check (nexthop) < 0)
    {
      if (IS_RIP_DEBUG_PACKET)
        zlog_info ("Nexthop address %s is myself", inet_ntoa (*nexthop));
      return;
    }

  /* Get index for the prefix. */
  rp = route_node_get (rip->table, (struct prefix *) &p);

  /* Check to see whether there is already RIP route on the table. */
  rinfo = rp->info;

  if (rinfo)
    {
      /* Redistributed route check. */
      if (rinfo->type != ZEBRA_ROUTE_RIP
          && rinfo->metric != RIP_METRIC_INFINITY)
        return;

      /* Local static route. */
      if (rinfo->type == ZEBRA_ROUTE_RIP
          && ((rinfo->sub_type == RIP_ROUTE_STATIC) ||
              (rinfo->sub_type == RIP_ROUTE_DEFAULT))
          && rinfo->metric != RIP_METRIC_INFINITY)
        return;
    }

  if (!rinfo)
    {
      /* Now, check to see whether there is already an explicit route
         for the destination prefix.  If there is no such route, add
         this route to the routing table, unless the metric is
         infinity (there is no point in adding a route which
         unusable). */
      if (rte->metric != RIP_METRIC_INFINITY)
        {
          rinfo = rip_info_new ();

          /* - Setting the destination prefix and length to those in
             the RTE. */
          rinfo->rp = rp;

          /* - Setting the metric to the newly calculated metric (as
             described above). */
          rinfo->metric = rte->metric;
          rinfo->tag = ntohs (rte->tag);

          /* - Set the next hop address to be the address of the router
             from which the datagram came or the next hop address
             specified by a next hop RTE. */
          IPV4_ADDR_COPY (&rinfo->nexthop, nexthop);
          IPV4_ADDR_COPY (&rinfo->from, &from->sin_addr);
          rinfo->ifindex = ifp->ifindex;

          /* - Initialize the timeout for the route.  If the
             garbage-collection timer is running for this route, stop it
             (see section 2.3 for a discussion of the timers). */
          rip_timeout_update (rinfo);

          /* - Set the route change flag. */
          rinfo->flags |= RIP_RTF_CHANGED;

          /* - Signal the output process to trigger an update (see section
             2.5). */
          rip_event (RIP_TRIGGERED_UPDATE, 0);

          /* Finally, route goes into the kernel. */
          rinfo->type = ZEBRA_ROUTE_RIP;
          rinfo->sub_type = RIP_ROUTE_RTE;

          /* Set distance value. */
          rinfo->distance = rip_distance_apply (rinfo);

          rp->info = rinfo;
          rip_zebra_ipv4_add (&p, &rinfo->nexthop, rinfo->metric,
                              rinfo->distance);
          rinfo->flags |= RIP_RTF_FIB;
        }
    }
  else
    {
      /* Route is there but we are not sure the route is RIP or not. */
      rinfo = rp->info;

      /* If there is an existing route, compare the next hop address
         to the address of the router from which the datagram came.
         If this datagram is from the same router as the existing
         route, reinitialize the timeout.  */
      same = (IPV4_ADDR_SAME (&rinfo->from, &from->sin_addr)
              && (rinfo->ifindex == ifp->ifindex));

      if (same)
        rip_timeout_update (rinfo);


      /* Fill in a minimaly temporary rip_info structure, for a future
         rip_distance_apply() use) */
      memset (&rinfotmp, 0, sizeof (rinfotmp));
      IPV4_ADDR_COPY (&rinfotmp.from, &from->sin_addr);
      rinfotmp.rp = rinfo->rp;


      /* Next, compare the metrics.  If the datagram is from the same
         router as the existing route, and the new metric is different
         than the old one; or, if the new metric is lower than the old
         one, or if the tag has been changed; or if there is a route
         with a lower administrave distance; or an update of the
         distance on the actual route; do the following actions: */
      if ((same && rinfo->metric != rte->metric)
          || (rte->metric < rinfo->metric)
          || ((same)
              && (rinfo->metric == rte->metric)
              && ntohs (rte->tag) != rinfo->tag)
          || (rinfo->distance > rip_distance_apply (&rinfotmp))
          || ((rinfo->distance != rip_distance_apply (rinfo)) && same))
        {
          /* - Adopt the route from the datagram.  That is, put the
             new metric in, and adjust the next hop address (if
             necessary). */
          oldmetric = rinfo->metric;
          rinfo->metric = rte->metric;
          rinfo->tag = ntohs (rte->tag);
          IPV4_ADDR_COPY (&rinfo->from, &from->sin_addr);
          rinfo->ifindex = ifp->ifindex;
          rinfo->distance = rip_distance_apply (rinfo);

          /* Should a new route to this network be established
             while the garbage-collection timer is running, the
             new route will replace the one that is about to be
             deleted.  In this case the garbage-collection timer
             must be cleared. */

          if (oldmetric == RIP_METRIC_INFINITY &&
              rinfo->metric < RIP_METRIC_INFINITY)
            {
              rinfo->type = ZEBRA_ROUTE_RIP;
              rinfo->sub_type = RIP_ROUTE_RTE;

              RIP_TIMER_OFF (rinfo->t_garbage_collect);

              if (!IPV4_ADDR_SAME (&rinfo->nexthop, nexthop))
                IPV4_ADDR_COPY (&rinfo->nexthop, nexthop);

              rip_zebra_ipv4_add (&p, nexthop, rinfo->metric,
                                  rinfo->distance);
              rinfo->flags |= RIP_RTF_FIB;
            }

          /* Update nexthop and/or metric value.  */
          if (oldmetric != RIP_METRIC_INFINITY)
            {
              rip_zebra_ipv4_delete (&p, &rinfo->nexthop, oldmetric);
              rip_zebra_ipv4_add (&p, nexthop, rinfo->metric,
                                  rinfo->distance);
              rinfo->flags |= RIP_RTF_FIB;

              if (!IPV4_ADDR_SAME (&rinfo->nexthop, nexthop))
                IPV4_ADDR_COPY (&rinfo->nexthop, nexthop);
            }

          /* - Set the route change flag and signal the output process
             to trigger an update. */
          rinfo->flags |= RIP_RTF_CHANGED;
          rip_event (RIP_TRIGGERED_UPDATE, 0);

          /* - If the new metric is infinity, start the deletion
             process (described above); */
          if (rinfo->metric == RIP_METRIC_INFINITY)
            {
              /* If the new metric is infinity, the deletion process
                 begins for the route, which is no longer used for
                 routing packets.  Note that the deletion process is
                 started only when the metric is first set to
                 infinity.  If the metric was already infinity, then a
                 new deletion process is not started. */
              if (oldmetric != RIP_METRIC_INFINITY)
                {
                  /* - The garbage-collection timer is set for 120 seconds. */
                  RIP_TIMER_ON (rinfo->t_garbage_collect,
                                rip_garbage_collect, rip->garbage_time);
                  RIP_TIMER_OFF (rinfo->t_timeout);

                  /* - The metric for the route is set to 16
                     (infinity).  This causes the route to be removed
                     from service. */
                  rip_zebra_ipv4_delete (&p, &rinfo->nexthop, oldmetric);
                  rinfo->flags &= ~RIP_RTF_FIB;

                  /* - The route change flag is to indicate that this
                     entry has been changed. */
                  /* - The output process is signalled to trigger a
                     response. */
                  ;             /* Above processes are already done previously. */
                }
            }
          else
            {
              /* otherwise, re-initialize the timeout. */
              rip_timeout_update (rinfo);
            }
        }
      /* Unlock tempolary lock of the route. */
      route_unlock_node (rp);
    }
}

/* Dump RIP packet */
void
rip_packet_dump (struct rip_packet *packet, int size, char *sndrcv)
{
  caddr_t lim;
  struct rte *rte;
  char *command_str;
  char pbuf[BUFSIZ], nbuf[BUFSIZ];
  u_char netmask = 0;
  u_char *p;

  /* Set command string. */
  if (packet->command > 0 && packet->command < RIP_COMMAND_MAX)
    command_str = lookup (rip_msg, packet->command);
  else
    command_str = "unknown";

  /* Dump packet header. */
  zlog_info ("%s %s version %d packet size %d",
	     sndrcv, command_str, packet->version, size);

  /* Dump each routing table entry. */
  rte = packet->rte;
  
  for (lim = (caddr_t) packet + size; (caddr_t) rte < lim; rte++)
    {
      if (packet->version == RIPv2)
	{
	  netmask = ip_masklen (rte->mask);

          if (rte->family == htons (RIP_FAMILY_AUTH))
            {
              if (rte->tag == htons (RIP_AUTH_SIMPLE_PASSWORD))
		{
		  p = (u_char *)&rte->prefix;

		  zlog_info ("  family 0x%X type %d auth string: %s",
			     ntohs (rte->family), ntohs (rte->tag), p);
		}
              else if (rte->tag == htons (RIP_AUTH_MD5))
		{
		  struct rip_md5_info *md5;

		  md5 = (struct rip_md5_info *) &packet->rte;

		  zlog_info ("  family 0x%X type %d (MD5 authentication)",
			     ntohs (md5->family), ntohs (md5->type));
		  zlog_info ("    RIP-2 packet len %d Key ID %d"
                             " Auth Data len %d",
                             ntohs (md5->packet_len), md5->keyid,
                             md5->auth_len);
                  zlog_info ("    Sequence Number %ld",
                             (u_long) ntohl (md5->sequence));
		}
              else if (rte->tag == htons (RIP_AUTH_DATA))
		{
		  p = (u_char *)&rte->prefix;

		  zlog_info ("  family 0x%X type %d (MD5 data)",
			     ntohs (rte->family), ntohs (rte->tag));
		  zlog_info ("    MD5: %02X%02X%02X%02X%02X%02X%02X%02X"
			     "%02X%02X%02X%02X%02X%02X%02X",
                             p[0], p[1], p[2], p[3], p[4], p[5], p[6],
                             p[7], p[9], p[10], p[11], p[12], p[13],
                             p[14], p[15]);
		}
	      else
		{
		  zlog_info ("  family 0x%X type %d (Unknown auth type)",
			     ntohs (rte->family), ntohs (rte->tag));
		}
            }
	  else
	    zlog_info ("  %s/%d -> %s family %d tag %d metric %ld",
                       inet_ntop (AF_INET, &rte->prefix, pbuf, BUFSIZ),
                       netmask, inet_ntop (AF_INET, &rte->nexthop, nbuf,
                                           BUFSIZ), ntohs (rte->family),
                       ntohs (rte->tag), (u_long) ntohl (rte->metric));
	}
      else
	{
	  zlog_info ("  %s family %d tag %d metric %ld", 
		     inet_ntop (AF_INET, &rte->prefix, pbuf, BUFSIZ),
		     ntohs (rte->family), ntohs (rte->tag),
		     (u_long)ntohl (rte->metric));
	}
    }
}

/* Check if the destination address is valid (unicast; not net 0
   or 127) (RFC2453 Section 3.9.2 - Page 26).  But we don't
   check net 0 because we accept default route. */
int
rip_destination_check (struct in_addr addr)
{
  u_int32_t destination;

  /* Convert to host byte order. */
  destination = ntohl (addr.s_addr);

  if (IPV4_NET127 (destination))
    return 0;

  /* Net 0 may match to the default route. */
  if (IPV4_NET0 (destination) && destination != 0)
    return 0;

  /* Unicast address must belong to class A, B, C. */
  if (IN_CLASSA (destination))
    return 1;
  if (IN_CLASSB (destination))
    return 1;
  if (IN_CLASSC (destination))
    return 1;

  return 0;
}

/* RIP version 2 authentication. */
int
rip_auth_simple_password (struct rte *rte, struct sockaddr_in *from,
			  struct interface *ifp)
{
  struct rip_interface *ri;
  char *auth_str;

  if (IS_RIP_DEBUG_EVENT)
    zlog_info ("RIPv2 simple password authentication from %s",
	       inet_ntoa (from->sin_addr));

  ri = ifp->info;

  if (ri->auth_type != RIP_AUTH_SIMPLE_PASSWORD
      || rte->tag != htons(RIP_AUTH_SIMPLE_PASSWORD))
    return 0;

  /* Simple password authentication. */
  if (ri->auth_str)
    {
      auth_str = (char *) &rte->prefix;
	  
      if (strncmp (auth_str, ri->auth_str, 16) == 0)
	return 1;
    }
  if (ri->key_chain)
    {
      struct keychain *keychain;
      struct key *key;

      keychain = keychain_lookup (ri->key_chain);
      if (keychain == NULL)
	return 0;

      key = key_match_for_accept (keychain, (char *) &rte->prefix);
      if (key)
	return 1;
    }
  return 0;
}

/* RIP version 2 authentication with MD5. */
int
rip_auth_md5 (struct rip_packet *packet, struct sockaddr_in *from,
              int length, struct interface *ifp)
{
  struct rip_interface *ri;
  struct rip_md5_info *md5;
  struct rip_md5_data *md5data;
  struct keychain *keychain;
  struct key *key;
  struct md5_ctx ctx;
  u_char pdigest[RIP_AUTH_MD5_SIZE];
  u_char digest[RIP_AUTH_MD5_SIZE];
  u_int16_t packet_len;
  char *auth_str = NULL;
  
  if (IS_RIP_DEBUG_EVENT)
    zlog_info ("RIPv2 MD5 authentication from %s",
               inet_ntoa (from->sin_addr));

  ri = ifp->info;
  md5 = (struct rip_md5_info *) &packet->rte;

  /* Check auth type. */
  if (ri->auth_type != RIP_AUTH_MD5 || md5->type != htons(RIP_AUTH_MD5))
    return 0;

  /* If the authentication length is less than 16, then it must be wrong for
   * any interpretation of rfc2082. Some implementations also interpret
   * this as RIP_HEADER_SIZE+ RIP_AUTH_MD5_SIZE, aka RIP_AUTH_MD5_COMPAT_SIZE.
 */
  if ( !((md5->auth_len == RIP_AUTH_MD5_SIZE)
         || (md5->auth_len == RIP_AUTH_MD5_COMPAT_SIZE)))
    {
      if (IS_RIP_DEBUG_EVENT)
        zlog_warn ("RIPv2 MD5 authentication, strange authentication "
                   "length field %d", md5->auth_len);
    return 0;
    }

  /* grab and verify check packet length */
  packet_len = ntohs (md5->packet_len);

  if (packet_len > (length - RIP_HEADER_SIZE - RIP_AUTH_MD5_SIZE))
    {
      if (IS_RIP_DEBUG_EVENT)
        zlog_warn ("RIPv2 MD5 authentication, packet length field %d "
                   "greater than received length %d!",
                   md5->packet_len, length);
      return 0;
    }

  /* retrieve authentication data */
  md5data = (struct rip_md5_data *) (((u_char *) packet) + packet_len);

  if (ri->key_chain)
    {
      keychain = keychain_lookup (ri->key_chain);
      if (keychain == NULL)
	return 0;

      key = key_lookup_for_accept (keychain, md5->keyid);
      if (key == NULL)
	return 0;

      auth_str = key->string;
    }

  if (ri->auth_str)
    auth_str = ri->auth_str;

  if (! auth_str)
    return 0;

  /* MD5 digest authentication. */

  /* Save digest to pdigest. */
  memcpy (pdigest, md5data->digest, RIP_AUTH_MD5_SIZE);

  /* Overwrite digest by my secret. */
  memset (md5data->digest, 0, RIP_AUTH_MD5_SIZE);
  strncpy ((char *)md5data->digest, auth_str, RIP_AUTH_MD5_SIZE);

  md5_init_ctx (&ctx);
  md5_process_bytes (packet, packet_len + RIP_HEADER_SIZE + RIP_AUTH_MD5_SIZE,
    &ctx);
  md5_finish_ctx (&ctx, digest);

  if (memcmp (pdigest, digest, RIP_AUTH_MD5_SIZE) == 0)
    return packet_len;
  else
    return 0;
}

void
rip_auth_md5_set (struct stream *s, struct interface *ifp)
{
  struct rip_interface *ri;
  struct keychain *keychain = NULL;
  struct key *key = NULL;
  unsigned long len;
  struct md5_ctx ctx;
  unsigned char secret[RIP_AUTH_MD5_SIZE];
  unsigned char digest[RIP_AUTH_MD5_SIZE];
  char *auth_str = NULL;

  ri = ifp->info;

  /* Make it sure this interface is configured as MD5
     authentication. */
  if (ri->auth_type != RIP_AUTH_MD5)
    return;

  /* Lookup key chain. */
  if (ri->key_chain)
    {
      keychain = keychain_lookup (ri->key_chain);
      if (keychain == NULL)
	return;

      /* Lookup key. */
      key = key_lookup_for_send (keychain);
      if (key == NULL)
	return;

      auth_str = key->string;
    }

  if (ri->auth_str)
    auth_str = ri->auth_str;

  if (! auth_str)
    return;

  /* Get packet length. */
  len = s->putp;

  /* Check packet length. */
  if (len < (RIP_HEADER_SIZE + RIP_RTE_SIZE))
    {
      zlog_err ("rip_auth_md5_set(): packet length %ld is less than minimum length.", len);
      return;
    }

  /* Move RTE. */
  memmove (s->data + RIP_HEADER_SIZE + RIP_RTE_SIZE,
	   s->data + RIP_HEADER_SIZE,
	   len - RIP_HEADER_SIZE);
  
  /* Set pointer to authentication header. */
  stream_set_putp (s, RIP_HEADER_SIZE);
  len += RIP_RTE_SIZE;

  /* MD5 authentication. */
  stream_putw (s, RIP_FAMILY_AUTH);
  stream_putw (s, RIP_AUTH_MD5);

  /* RIP-2 Packet length.  Actual value is filled in
     rip_auth_md5_set(). */
  stream_putw (s, len);

  /* Key ID. */
  if (key)
    stream_putc (s, key->index % 256);
  else
    stream_putc (s, 1);

  /* Auth Data Len.  Set 16 for MD5 authentication data. Older ripds 
   * however expect RIP_HEADER_SIZE + RIP_AUTH_MD5_SIZE so we allow for this
   * to be configurable. 
   */
  stream_putc (s, ri->md5_auth_len);

  /* Sequence Number (non-decreasing). */
  /* RFC2080: The value used in the sequence number is
     arbitrary, but two suggestions are the time of the
     message's creation or a simple message counter. */
  stream_putl (s, time (NULL));
	      
  /* Reserved field must be zero. */
  stream_putl (s, 0);
  stream_putl (s, 0);

  /* Set pointer to authentication data. */
  stream_set_putp (s, len);

  /* Set authentication data. */
  stream_putw (s, RIP_FAMILY_AUTH);
  stream_putw (s, RIP_AUTH_DATA);

  /* Generate a digest for the RIP packet. */
  memset (secret, 0, RIP_AUTH_MD5_SIZE);
  strncpy ((char *)secret, auth_str, RIP_AUTH_MD5_SIZE);
  md5_init_ctx (&ctx);
  md5_process_bytes (s->data, s->endp, &ctx);
  md5_process_bytes (secret, RIP_AUTH_MD5_SIZE, &ctx);
  md5_finish_ctx (&ctx, digest);

  /* Copy the digest to the packet. */
  stream_write (s, digest, RIP_AUTH_MD5_SIZE);
}

/* RIP routing information. */
void
rip_response_process (struct rip_packet *packet, int size, 
		      struct sockaddr_in *from, struct interface *ifp)
{
  caddr_t lim;
  struct rte *rte;
  struct prefix_ipv4 ifaddr;
  struct prefix_ipv4 ifaddrclass;
  struct connected *c;
  int subnetted;
      
  /* We don't know yet. */
  subnetted = -1;

  /* The Response must be ignored if it is not from the RIP
     port. (RFC2453 - Sec. 3.9.2)*/
  if (from->sin_port != htons(RIP_PORT_DEFAULT))
    {
      zlog_info ("response doesn't come from RIP port: %d",
		 from->sin_port);
      rip_peer_bad_packet (from);
      return;
    }

  /* The datagram's IPv4 source address should be checked to see
     whether the datagram is from a valid neighbor; the source of the
     datagram must be on a directly connected network  */
  if (! if_valid_neighbor (from->sin_addr)) 
    {
      zlog_info ("This datagram doesn't came from a valid neighbor: %s",
		 inet_ntoa (from->sin_addr));
      rip_peer_bad_packet (from);
      return;
    }

  /* It is also worth checking to see whether the response is from one
     of the router's own addresses. */

  ; /* Alredy done in rip_read () */

  /* Update RIP peer. */
  rip_peer_update (from, packet->version);

  /* Set RTE pointer. */
  rte = packet->rte;

  for (lim = (caddr_t) packet + size; (caddr_t) rte < lim; rte++)
    {
      /* RIPv2 authentication check. */
      /* If the Address Family Identifier of the first (and only the
	 first) entry in the message is 0xFFFF, then the remainder of
	 the entry contains the authentication. */
      /* If the packet gets here it means authentication enabled */
      /* Check is done in rip_read(). So, just skipping it */
      if (packet->version == RIPv2 &&
	  rte == packet->rte &&
	  rte->family == htons(RIP_FAMILY_AUTH))
	continue;

      if (rte->family != htons(AF_INET))
	{
	  /* Address family check.  RIP only supports AF_INET. */
	  zlog_info ("Unsupported family %d from %s.",
		     ntohs (rte->family), inet_ntoa (from->sin_addr));
	  continue;
	}

      /* - is the destination address valid (e.g., unicast; not net 0
         or 127) */
      if (! rip_destination_check (rte->prefix))
        {
	  zlog_info ("Network is net 0 or net 127 or it is not unicast network");
	  rip_peer_bad_route (from);
	  continue;
	} 

      /* Convert metric value to host byte order. */
      rte->metric = ntohl (rte->metric);

      /* - is the metric valid (i.e., between 1 and 16, inclusive) */
      if (! (rte->metric >= 1 && rte->metric <= 16))
	{
	  zlog_info ("Route's metric is not in the 1-16 range.");
	  rip_peer_bad_route (from);
	  continue;
	}

      /* RIPv1 does not have nexthop value. */
      if (packet->version == RIPv1 && rte->nexthop.s_addr != 0)
	{
	  zlog_info ("RIPv1 packet with nexthop value %s",
		     inet_ntoa (rte->nexthop));
	  rip_peer_bad_route (from);
	  continue;
	}

      /* That is, if the provided information is ignored, a possibly
	 sub-optimal, but absolutely valid, route may be taken.  If
	 the received Next Hop is not directly reachable, it should be
	 treated as 0.0.0.0. */
      if (packet->version == RIPv2 && rte->nexthop.s_addr != 0)
	{
	  u_int32_t addrval;

	  /* Multicast address check. */
	  addrval = ntohl (rte->nexthop.s_addr);
	  if (IN_CLASSD (addrval))
	    {
	      zlog_info ("Nexthop %s is multicast address, skip this rte",
			 inet_ntoa (rte->nexthop));
	      continue;
	    }

	  if (! if_lookup_address (rte->nexthop))
	    {
	      struct route_node *rn;
	      struct rip_info *rinfo;

	      rn = route_node_match_ipv4 (rip->table, &rte->nexthop);

	      if (rn)
		{
		  rinfo = rn->info;

		  if (rinfo->type == ZEBRA_ROUTE_RIP
		      && rinfo->sub_type == RIP_ROUTE_RTE)
		    {
		      if (IS_RIP_DEBUG_EVENT)
			zlog_info ("Next hop %s is on RIP network.  Set nexthop to the packet's originator", inet_ntoa (rte->nexthop));
		      rte->nexthop = rinfo->from;
		    }
		  else
		    {
		      if (IS_RIP_DEBUG_EVENT)
			zlog_info ("Next hop %s is not directly reachable. Treat it as 0.0.0.0", inet_ntoa (rte->nexthop));
		      rte->nexthop.s_addr = 0;
		    }

		  route_unlock_node (rn);
		}
	      else
		{
		  if (IS_RIP_DEBUG_EVENT)
		    zlog_info ("Next hop %s is not directly reachable. Treat it as 0.0.0.0", inet_ntoa (rte->nexthop));
		  rte->nexthop.s_addr = 0;
		}

	    }
	}

     /* For RIPv1, there won't be a valid netmask.  

	This is a best guess at the masks.  If everyone was using old
	Ciscos before the 'ip subnet zero' option, it would be almost
	right too :-)
      
	Cisco summarize ripv1 advertisments to the classful boundary
	(/16 for class B's) except when the RIP packet does to inside
	the classful network in question.  */

      if ((packet->version == RIPv1 && rte->prefix.s_addr != 0) 
	  || (packet->version == RIPv2 
	      && (rte->prefix.s_addr != 0 && rte->mask.s_addr == 0)))
	{
	  u_int32_t destination;

	  if (subnetted == -1)
	    {
	      c = connected_lookup_address (ifp, from->sin_addr);
	      if (c != NULL)
		{
		  memcpy (&ifaddr, c->address, sizeof (struct prefix_ipv4));
		  memcpy (&ifaddrclass, &ifaddr, sizeof (struct prefix_ipv4));
		  apply_classful_mask_ipv4 (&ifaddrclass);
		  subnetted = 0;
		  if (ifaddr.prefixlen > ifaddrclass.prefixlen)
		    subnetted = 1;
		}
	    }

	  destination = ntohl (rte->prefix.s_addr);

	  if (IN_CLASSA (destination))
	      masklen2ip (8, &rte->mask);
	  else if (IN_CLASSB (destination))
	      masklen2ip (16, &rte->mask);
	  else if (IN_CLASSC (destination))
	      masklen2ip (24, &rte->mask);

	  if (subnetted == 1)
	    masklen2ip (ifaddrclass.prefixlen,
			(struct in_addr *) &destination);
	  if ((subnetted == 1) && ((rte->prefix.s_addr & destination) ==
	      ifaddrclass.prefix.s_addr))
	    {
	      masklen2ip (ifaddr.prefixlen, &rte->mask);
	      if ((rte->prefix.s_addr & rte->mask.s_addr) != rte->prefix.s_addr)
		masklen2ip (32, &rte->mask);
	      if (IS_RIP_DEBUG_EVENT)
		zlog_info ("Subnetted route %s", inet_ntoa (rte->prefix));
	    }
	  else
	    {
	      if ((rte->prefix.s_addr & rte->mask.s_addr) != rte->prefix.s_addr)
		continue;
	    }

	  if (IS_RIP_DEBUG_EVENT)
	    {
	      zlog_info ("Resultant route %s", inet_ntoa (rte->prefix));
	      zlog_info ("Resultant mask %s", inet_ntoa (rte->mask));
	    }
	}

      /* In case of RIPv2, if prefix in RTE is not netmask applied one
         ignore the entry.  */
      if ((packet->version == RIPv2) 
	  && (rte->mask.s_addr != 0) 
	  && ((rte->prefix.s_addr & rte->mask.s_addr) != rte->prefix.s_addr))
	{
	  zlog_warn ("RIPv2 address %s is not mask /%d applied one",
		     inet_ntoa (rte->prefix), ip_masklen (rte->mask));
	  rip_peer_bad_route (from);
	  continue;
	}

      /* Default route's netmask is ignored. */
      if (packet->version == RIPv2
	  && (rte->prefix.s_addr == 0)
	  && (rte->mask.s_addr != 0))
	{
	  if (IS_RIP_DEBUG_EVENT)
	    zlog_info ("Default route with non-zero netmask.  Set zero to netmask");
	  rte->mask.s_addr = 0;
	}
	  
      /* Routing table updates. */
      rip_rte_process (rte, from, ifp);
    }
}

/* RIP packet send to destination address. */
int
rip_send_packet (u_char * buf, int size, struct sockaddr_in *to, 
		 struct interface *ifp, struct connected *connected)
{
  int ret, send_sock;
  struct sockaddr_in sin;

  if (IS_RIP_DEBUG_PACKET)
    {
      char dst[20];
      if (to)
        {
          strcpy(dst, inet_ntoa(to->sin_addr));
        }
      else
        {
          sin.sin_addr.s_addr = htonl (INADDR_RIP_GROUP);
          strcpy(dst, inet_ntoa(sin.sin_addr));
        }
      zlog_info("rip_send_packet %s > %s (%s)",
                (connected ? inet_ntoa(connected->address->u.prefix4) : ""),
                dst, ifp->name);
    }
  if (connected && connected->flags & ZEBRA_IFA_SECONDARY)
    {
      /*
       * ZEBRA_IFA_SECONDARY is set on linux when an interface is configured
       * with multiple addresses on the same subnet: the first address
       * on the subnet is configured "primary", and all subsequent addresses
       * on that subnet are treated as "secondary" addresses. 
       * In order to avoid routing-table bloat on other rip listeners, 
       * we do not send out RIP packets with ZEBRA_IFA_SECONDARY source addrs.
       * XXX Since Linux is the only system for which the ZEBRA_IFA_SECONDARY
       * flag is set, we would end up sending a packet for a "secondary"
       * source address on non-linux systems.  
       */
      if (IS_RIP_DEBUG_PACKET)
        zlog_info("duplicate dropped");
      return 0;
    }

  /* Make destination address. */
  memset (&sin, 0, sizeof (struct sockaddr_in));
  sin.sin_family = AF_INET;
#ifdef HAVE_SIN_LEN
  sin.sin_len = sizeof (struct sockaddr_in);
#endif /* HAVE_SIN_LEN */

  /* When destination is specified, use it's port and address. */
  if (to)
    {
      sin.sin_port = to->sin_port;
      sin.sin_addr = to->sin_addr;
      send_sock = rip->sock;
    }
  else
    {

      sin.sin_port = htons (RIP_PORT_DEFAULT);
      sin.sin_addr.s_addr = htonl (INADDR_RIP_GROUP);

      /*
       * we have to open a new socket for each packet because this
       * is the most portable way to bind to a different source
       * ipv4 address for each packet. 
       */
      send_sock = socket(AF_INET, SOCK_DGRAM, 0);
      if (send_sock < 0)
        {
          zlog_warn("rip_send_packet could not create socket %s",
                    strerror(errno));
          return -1;
    }
      sockopt_broadcast (send_sock);
      sockopt_reuseaddr (send_sock);
      sockopt_reuseport (send_sock);
#ifdef RIP_RECVMSG
      setsockopt_pktinfo (send_sock);
#endif /* RIP_RECVMSG */
      rip_interface_multicast_set (send_sock, connected);
    }

  ret = sendto (send_sock, buf, size, 0, (struct sockaddr *)&sin,
		sizeof (struct sockaddr_in));

  if (IS_RIP_DEBUG_EVENT)
      zlog_info ("SEND to  %s.%d", inet_ntoa(sin.sin_addr), 
                  ntohs (sin.sin_port));

  if (ret < 0)
    zlog_warn ("can't send packet : %s", strerror (errno));

  if (!to)
    close(send_sock);

  return ret;
}

/* Add redistributed route to RIP table. */
void
rip_redistribute_add (int type, int sub_type, struct prefix_ipv4 *p, 
		      unsigned int ifindex, struct in_addr *nexthop)
{
  int ret;
  struct route_node *rp;
  struct rip_info *rinfo;

  /* Redistribute route  */
  ret = rip_destination_check (p->prefix);
  if (! ret)
    return;

  rp = route_node_get (rip->table, (struct prefix *) p);

  rinfo = rp->info;

  if (rinfo)
    {
      if (rinfo->type == ZEBRA_ROUTE_CONNECT 
	  && rinfo->sub_type == RIP_ROUTE_INTERFACE
	  && rinfo->metric != RIP_METRIC_INFINITY)
	{
	  route_unlock_node (rp);
	  return;
	}

      /* Manually configured RIP route check. */
      if (rinfo->type == ZEBRA_ROUTE_RIP 
	  && ((rinfo->sub_type == RIP_ROUTE_STATIC) ||
	      (rinfo->sub_type == RIP_ROUTE_DEFAULT)) )
	{
	  if (type != ZEBRA_ROUTE_RIP || ((sub_type != RIP_ROUTE_STATIC) &&
	                                  (sub_type != RIP_ROUTE_DEFAULT)))
	    {
	      route_unlock_node (rp);
	      return;
	    }
	}

      RIP_TIMER_OFF (rinfo->t_timeout);
      RIP_TIMER_OFF (rinfo->t_garbage_collect);

      if (rip_route_rte (rinfo))
	rip_zebra_ipv4_delete ((struct prefix_ipv4 *)&rp->p, &rinfo->nexthop,
			       rinfo->metric);
      rp->info = NULL;
      rip_info_free (rinfo);
      
      route_unlock_node (rp);      
    }

  rinfo = rip_info_new ();
    
  rinfo->type = type;
  rinfo->sub_type = sub_type;
  rinfo->ifindex = ifindex;
  rinfo->metric = 1;
  rinfo->rp = rp;

  if (nexthop)
    rinfo->nexthop = *nexthop;

  rinfo->flags |= RIP_RTF_FIB;
  rp->info = rinfo;

  rinfo->flags |= RIP_RTF_CHANGED;

  if (IS_RIP_DEBUG_EVENT) {
    if (!nexthop)
      zlog_info ("Redistribute new prefix %s/%d on the interface %s",
                 inet_ntoa(p->prefix), p->prefixlen,
                 ifindex2ifname(ifindex));
    else
      zlog_info ("Redistribute new prefix %s/%d with nexthop %s on the interface %s",
                 inet_ntoa(p->prefix), p->prefixlen, inet_ntoa(rinfo->nexthop),
                 ifindex2ifname(ifindex));
  }


  rip_event (RIP_TRIGGERED_UPDATE, 0);
}

/* Delete redistributed route from RIP table. */
void
rip_redistribute_delete (int type, int sub_type, struct prefix_ipv4 *p, 
			   unsigned int ifindex)
{
  int ret;
  struct route_node *rp;
  struct rip_info *rinfo;

  ret = rip_destination_check (p->prefix);
  if (! ret)
    return;

  rp = route_node_lookup (rip->table, (struct prefix *) p);
  if (rp)
    {
      rinfo = rp->info;

      if (rinfo != NULL
	  && rinfo->type == type 
	  && rinfo->sub_type == sub_type 
	  && rinfo->ifindex == ifindex)
	{
	  /* Perform poisoned reverse. */
	  rinfo->metric = RIP_METRIC_INFINITY;
	  RIP_TIMER_ON (rinfo->t_garbage_collect, 
			rip_garbage_collect, rip->garbage_time);
	  RIP_TIMER_OFF (rinfo->t_timeout);
	  rinfo->flags |= RIP_RTF_CHANGED;

          if (IS_RIP_DEBUG_EVENT)
            zlog_info ("Poisone %s/%d on the interface %s with an infinity metric [delete]",
                       inet_ntoa(p->prefix), p->prefixlen,
                       ifindex2ifname(ifindex));

	  rip_event (RIP_TRIGGERED_UPDATE, 0);
	}
    }
}

/* Response to request called from rip_read ().*/
void
rip_request_process (struct rip_packet *packet, int size, 
		     struct sockaddr_in *from, struct interface *ifp)
{
  caddr_t lim;
  struct rte *rte;
  struct prefix_ipv4 p;
  struct route_node *rp;
  struct rip_info *rinfo;
  struct rip_interface *ri;

  /* Does not reponse to the requests on the loopback interfaces */
  if (if_is_loopback (ifp))
    return;

  /* Check RIP process is enabled on this interface. */
  ri = ifp->info;
  if (! ri->running)
    return;

  /* When passive interface is specified, suppress responses */
  if (ri->passive)
    return;

  /* RIP peer update. */
  rip_peer_update (from, packet->version);

  lim = ((caddr_t) packet) + size;
  rte = packet->rte;

  /* The Request is processed entry by entry.  If there are no
     entries, no response is given. */
  if (lim == (caddr_t) rte)
    return;

  /* There is one special case.  If there is exactly one entry in the
     request, and it has an address family identifier of zero and a
     metric of infinity (i.e., 16), then this is a request to send the
     entire routing table. */
  if (lim == ((caddr_t) (rte + 1)) &&
      ntohs (rte->family) == 0 &&
      ntohl (rte->metric) == RIP_METRIC_INFINITY)
    {	
      struct prefix_ipv4 saddr;

      /* saddr will be used for determining which routes to split-horizon.
         Since the source address we'll pick will be on the same subnet as the
         destination, for the purpose of split-horizoning, we'll
         pretend that "from" is our source address.  */
      saddr.family = AF_INET;
      saddr.prefixlen = IPV4_MAX_BITLEN;
      saddr.prefix = from->sin_addr;

      /* All route with split horizon */
      rip_output_process (ifp, NULL, from, rip_all_route, packet->version, 
                          NULL, &saddr);
    }
  else
    {
      /* Examine the list of RTEs in the Request one by one.  For each
	 entry, look up the destination in the router's routing
	 database and, if there is a route, put that route's metric in
	 the metric field of the RTE.  If there is no explicit route
	 to the specified destination, put infinity in the metric
	 field.  Once all the entries have been filled in, change the
	 command from Request to Response and send the datagram back
	 to the requestor. */
      p.family = AF_INET;

      for (; ((caddr_t) rte) < lim; rte++)
	{
	  p.prefix = rte->prefix;
	  p.prefixlen = ip_masklen (rte->mask);
	  apply_mask_ipv4 (&p);
	  
	  rp = route_node_lookup (rip->table, (struct prefix *) &p);
	  if (rp)
	    {
	      rinfo = rp->info;
	      rte->metric = htonl (rinfo->metric);
	      route_unlock_node (rp);
	    }
	  else
	    rte->metric = htonl (RIP_METRIC_INFINITY);
	}
      packet->command = RIP_RESPONSE;

      rip_send_packet ((u_char *)packet, size, from, ifp, NULL);
    }
  rip_global_queries++;
}

#if RIP_RECVMSG
/* Set IPv6 packet info to the socket. */
static int
setsockopt_pktinfo (int sock)
{
  int ret;
  int val = 1;
    
  ret = setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &val, sizeof(val));
  if (ret < 0)
    zlog_warn ("Can't setsockopt IP_PKTINFO : %s", strerror (errno));
  return ret;
}

/* Read RIP packet by recvmsg function. */
int
rip_recvmsg (int sock, u_char *buf, int size, struct sockaddr_in *from,
	     int *ifindex)
{
  int ret;
  struct msghdr msg;
  struct iovec iov;
  struct cmsghdr *ptr;
  char adata[1024];

  msg.msg_name = (void *) from;
  msg.msg_namelen = sizeof (struct sockaddr_in);
  msg.msg_iov = &iov;
  msg.msg_iovlen = 1;
  msg.msg_control = (void *) adata;
  msg.msg_controllen = sizeof adata;
  iov.iov_base = buf;
  iov.iov_len = size;

  ret = recvmsg (sock, &msg, 0);
  if (ret < 0)
    return ret;

  for (ptr = CMSG_FIRSTHDR(&msg); ptr != NULL; ptr = CMSG_NXTHDR(&msg, ptr))
    if (ptr->cmsg_level == IPPROTO_IP && ptr->cmsg_type == IP_PKTINFO) 
      {
	struct in_pktinfo *pktinfo;
	int i;

	pktinfo = (struct in_pktinfo *) CMSG_DATA (ptr);
	i = pktinfo->ipi_ifindex;
      }
  return ret;
}

/* RIP packet read function. */
int
rip_read_new (struct thread *t)
{
  int ret;
  int sock;
  char buf[RIP_PACKET_MAXSIZ];
  struct sockaddr_in from;
  unsigned int ifindex;
  
  /* Fetch socket then register myself. */
  sock = THREAD_FD (t);
  rip_event (RIP_READ, sock);

  /* Read RIP packet. */
  ret = rip_recvmsg (sock, buf, RIP_PACKET_MAXSIZ, &from, (int *)&ifindex);
  if (ret < 0)
    {
      zlog_warn ("Can't read RIP packet: %s", strerror (errno));
      return ret;
    }

  return ret;
}
#endif /* RIP_RECVMSG */

/* First entry point of RIP packet. */
int
rip_read (struct thread *t)
{
  int sock;
  int ret;
  int rtenum;
  union rip_buf rip_buf;
  struct rip_packet *packet;
  struct sockaddr_in from;
  int len;
  socklen_t fromlen;
  struct interface *ifp;
  struct rip_interface *ri;

  /* Fetch socket then register myself. */
  sock = THREAD_FD (t);
  rip->t_read = NULL;

  /* Add myself to tne next event */
  rip_event (RIP_READ, sock);

  /* RIPd manages only IPv4. */
  memset (&from, 0, sizeof (struct sockaddr_in));
  fromlen = sizeof (struct sockaddr_in);

  len = recvfrom (sock, (char *)&rip_buf.buf, sizeof (rip_buf.buf), 0, 
		  (struct sockaddr *) &from, &fromlen);
  if (len < 0) 
    {
      zlog_info ("recvfrom failed: %s", strerror (errno));
      return len;
    }

  /* Check is this packet comming from myself? */
  if (if_check_address (from.sin_addr)) 
    {
      if (IS_RIP_DEBUG_PACKET)
	zlog_warn ("ignore packet comes from myself");
      return -1;
    }

  /* Which interface is this packet comes from. */
  ifp = if_lookup_address (from.sin_addr);

  /* RIP packet received */
  if (IS_RIP_DEBUG_EVENT)
    zlog_info ("RECV packet from %s port %d on %s",
	       inet_ntoa (from.sin_addr), ntohs (from.sin_port),
	       ifp ? ifp->name : "unknown");

  /* If this packet come from unknown interface, ignore it. */
  if (ifp == NULL)
    {
      zlog_info ("packet comes from unknown interface");
      return -1;
    }

  /* Packet length check. */
  if (len < RIP_PACKET_MINSIZ)
    {
      zlog_warn ("packet size %d is smaller than minimum size %d",
		 len, RIP_PACKET_MINSIZ);
      rip_peer_bad_packet (&from);
      return len;
    }
  if (len > RIP_PACKET_MAXSIZ)
    {
      zlog_warn ("packet size %d is larger than max size %d",
		 len, RIP_PACKET_MAXSIZ);
      rip_peer_bad_packet (&from);
      return len;
    }

  /* Packet alignment check. */
  if ((len - RIP_PACKET_MINSIZ) % 20)
    {
      zlog_warn ("packet size %d is wrong for RIP packet alignment", len);
      rip_peer_bad_packet (&from);
      return len;
    }

  /* Set RTE number. */
  rtenum = ((len - RIP_PACKET_MINSIZ) / 20);

  /* For easy to handle. */
  packet = &rip_buf.rip_packet;

  /* RIP version check. */
  if (packet->version == 0)
    {
      zlog_info ("version 0 with command %d received.", packet->command);
      rip_peer_bad_packet (&from);
      return -1;
    }

  /* Dump RIP packet. */
  if (IS_RIP_DEBUG_RECV)
    rip_packet_dump (packet, len, "RECV");

  /* RIP version adjust.  This code should rethink now.  RFC1058 says
     that "Version 1 implementations are to ignore this extra data and
     process only the fields specified in this document.". So RIPv3
     packet should be treated as RIPv1 ignoring must be zero field. */
  if (packet->version > RIPv2)
    packet->version = RIPv2;

  /* Is RIP running or is this RIP neighbor ?*/
  ri = ifp->info;
  if (! ri->running && ! rip_neighbor_lookup (&from))
    {
      if (IS_RIP_DEBUG_EVENT)
	zlog_info ("RIP is not enabled on interface %s.", ifp->name);
      rip_peer_bad_packet (&from);
      return -1;
    }

  /* RIP Version check. */
  if (packet->command == RIP_RESPONSE)
    {
	  int vrecv = ((ri->ri_receive == RI_RIP_UNSPEC) ?
		       rip->version_recv : ri->ri_receive);
	  if (packet->version == RIPv1)
	    if (! (vrecv & RIPv1))
	      {
		if (IS_RIP_DEBUG_PACKET)
		  zlog_warn ("  packet's v%d doesn't fit to if version spec", 
			     packet->version);
		rip_peer_bad_packet (&from);
		return -1;
	      }
	  if (packet->version == RIPv2)
	    if (! (vrecv & RIPv2))
	      {
		if (IS_RIP_DEBUG_PACKET)
		  zlog_warn ("  packet's v%d doesn't fit to if version spec", 
			     packet->version);
		rip_peer_bad_packet (&from);
		return -1;
	      }
    }

  /* RFC2453 5.2 If the router is not configured to authenticate RIP-2
     messages, then RIP-1 and unauthenticated RIP-2 messages will be
     accepted; authenticated RIP-2 messages shall be discarded.  */

  if ((ri->auth_type == RIP_NO_AUTH) 
      && rtenum 
      && (packet->version == RIPv2) 
      && (packet->rte->family == htons(RIP_FAMILY_AUTH)))
    {
      if (IS_RIP_DEBUG_EVENT)
	zlog_warn ("packet RIPv%d is dropped because authentication disabled", 
		   packet->version);
      rip_peer_bad_packet (&from);
      return -1;
    }

  /* If the router is configured to authenticate RIP-2 messages, then
     RIP-1 messages and RIP-2 messages which pass authentication
     testing shall be accepted; unauthenticated and failed
     authentication RIP-2 messages shall be discarded.  For maximum
     security, RIP-1 messages should be ignored when authentication is
     in use (see section 4.1); otherwise, the routing information from
     authenticated messages will be propagated by RIP-1 routers in an
     unauthenticated manner. */

  if ((ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD 
       || ri->auth_type == RIP_AUTH_MD5) && rtenum)
    {
      /* We follow maximum security. */
      if (packet->version == RIPv1 
      && packet->rte->family == htons(RIP_FAMILY_AUTH))
	{
	  if (IS_RIP_DEBUG_PACKET)
            zlog_warn
              ("packet RIPv%d is dropped because authentication enabled",
               packet->version);
	  rip_peer_bad_packet (&from);
	  return -1;
	}

      /* Check RIPv2 authentication. */
      if (packet->version == RIPv2)
	{
          if (packet->rte->family == htons(RIP_FAMILY_AUTH))
	    {
              if (packet->rte->tag == htons(RIP_AUTH_SIMPLE_PASSWORD))
                {
		  ret = rip_auth_simple_password (packet->rte, &from, ifp);
		  if (! ret)
		    {
		      if (IS_RIP_DEBUG_EVENT)
                        zlog_warn
                          ("RIPv2 simple password authentication failed");
		      rip_peer_bad_packet (&from);
		      return -1;
		    }
		  else
		    {
		      if (IS_RIP_DEBUG_EVENT)
                        zlog_info
                          ("RIPv2 simple password authentication success");
		    }
                }
              else if (packet->rte->tag == htons(RIP_AUTH_MD5))
                {
                  ret = rip_auth_md5 (packet, &from, len, ifp);
		  if (! ret)
		    {
		      if (IS_RIP_DEBUG_EVENT)
			zlog_warn ("RIPv2 MD5 authentication failed");
		      rip_peer_bad_packet (&from);
		      return -1;
		    }
		  else
		    {
		      if (IS_RIP_DEBUG_EVENT)
			zlog_info ("RIPv2 MD5 authentication success");
		    }
		  /* Reset RIP packet length to trim MD5 data. */
		  len = ret; 
                }
	      else
		{
		  if (IS_RIP_DEBUG_EVENT)
		    zlog_warn ("Unknown authentication type %d",
			       ntohs (packet->rte->tag));
		  rip_peer_bad_packet (&from);
		  return -1;
		}
	    }
	  else
	    {
	      /* There is no authentication in the packet. */
	      if (ri->auth_str || ri->key_chain)
		{
		  if (IS_RIP_DEBUG_EVENT)
                    zlog_warn
                      ("RIPv2 authentication failed: no authentication in packet");
		  rip_peer_bad_packet (&from);
		  return -1;
		}
	    }
	}
    }
  
  /* Process each command. */
  switch (packet->command)
    {
    case RIP_RESPONSE:
      rip_response_process (packet, len, &from, ifp);
      break;
    case RIP_REQUEST:
    case RIP_POLL:
      rip_request_process (packet, len, &from, ifp);
      break;
    case RIP_TRACEON:
    case RIP_TRACEOFF:
      zlog_info ("Obsolete command %s received, please sent it to routed", 
		 lookup (rip_msg, packet->command));
      rip_peer_bad_packet (&from);
      break;
    case RIP_POLL_ENTRY:
      zlog_info ("Obsolete command %s received", 
		 lookup (rip_msg, packet->command));
      rip_peer_bad_packet (&from);
      break;
    default:
      zlog_info ("Unknown RIP command %d received", packet->command);
      rip_peer_bad_packet (&from);
      break;
    }

  return len;
}

/* Make socket for RIP protocol. */
int 
rip_create_socket ()
{
  int ret;
  int sock;
  struct sockaddr_in addr;
  struct servent *sp;

  memset (&addr, 0, sizeof (struct sockaddr_in));

  /* Set RIP port. */
  sp = getservbyname ("router", "udp");
  if (sp) 
    addr.sin_port = sp->s_port;
  else 
    addr.sin_port = htons (RIP_PORT_DEFAULT);

  /* Address shoud be any address. */
  addr.sin_family = AF_INET;
  addr.sin_addr.s_addr = INADDR_ANY;

  /* Make datagram socket. */
  sock = socket (AF_INET, SOCK_DGRAM, 0);
  if (sock < 0) 
    {
      perror ("socket");
      exit (1);
    }

  sockopt_broadcast (sock);
  sockopt_reuseaddr (sock);
  sockopt_reuseport (sock);
#ifdef RIP_RECVMSG
  setsockopt_pktinfo (sock);
#endif /* RIP_RECVMSG */

  if (ripd_privs.change (ZPRIVS_RAISE))
      zlog_err ("rip_create_socket: could not raise privs");
  ret = bind (sock, (struct sockaddr *) & addr, sizeof (addr));
  if (ret < 0)
    {
      perror ("bind");
      if (ripd_privs.change (ZPRIVS_LOWER))
        zlog_err ("rip_create_socket: could not lower privs");
      return ret;
    }
  if (ripd_privs.change (ZPRIVS_LOWER))
      zlog_err ("rip_create_socket: could not lower privs");
      
  return sock;
}

/* Write routing table entry to the stream and return next index of
   the routing table entry in the stream. */
int
rip_write_rte (int num, struct stream *s, struct prefix_ipv4 *p,
	       u_char version, struct rip_info *rinfo, struct interface *ifp)
{
  struct in_addr mask;
  struct rip_interface *ri;

  /* RIP packet header. */
  if (num == 0)
    {
      stream_putc (s, RIP_RESPONSE);
      stream_putc (s, version);
      stream_putw (s, 0);

      /* In case of we need RIPv2 authentication. */
      if (version == RIPv2 && ifp)
	{
	  ri = ifp->info;
	      
	  if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
	    {
	      if (ri->auth_str)
		{
		  stream_putw (s, RIP_FAMILY_AUTH);
		  stream_putw (s, RIP_AUTH_SIMPLE_PASSWORD);

		  memset ((s->data + s->putp), 0, 16);
		  strncpy ((char *)(s->data + s->putp), ri->auth_str, 16);
		  stream_set_putp (s, s->putp + 16);

		  num++;
		}
	      if (ri->key_chain)
		{
		  struct keychain *keychain;
		  struct key *key;

		  keychain = keychain_lookup (ri->key_chain);

		  if (keychain)
		    {
		      key = key_lookup_for_send (keychain);
		      
		      if (key)
			{
			  stream_putw (s, RIP_FAMILY_AUTH);
			  stream_putw (s, RIP_AUTH_SIMPLE_PASSWORD);

			  memset ((s->data + s->putp), 0, 16);
			  strncpy ((char *)(s->data + s->putp), 
				   key->string, 16);
			  stream_set_putp (s, s->putp + 16);

			  num++;
			}
		    }
		}
	    }
	}
    }

  /* Write routing table entry. */
  if (version == RIPv1)
    {
      stream_putw (s, AF_INET);
      stream_putw (s, 0);
      stream_put_ipv4 (s, p->prefix.s_addr);
      stream_put_ipv4 (s, 0);
      stream_put_ipv4 (s, 0);
      stream_putl (s, rinfo->metric_out);
    }
  else
    {
      masklen2ip (p->prefixlen, &mask);

      stream_putw (s, AF_INET);
      stream_putw (s, rinfo->tag_out);
      stream_put_ipv4 (s, p->prefix.s_addr);
      stream_put_ipv4 (s, mask.s_addr);
      stream_put_ipv4 (s, rinfo->nexthop_out.s_addr);
      stream_putl (s, rinfo->metric_out);
    }

  return ++num;
}

/* Send update to the ifp or spcified neighbor. */
void
rip_output_process (struct interface *ifp, struct prefix *ifaddr,
		    struct sockaddr_in *to, int route_type, u_char version,
                    struct connected *connected, struct prefix_ipv4 *saddr)
{
  int ret;
  struct stream *s;
  struct route_node *rp;
  struct rip_info *rinfo;
  struct rip_interface *ri;
  struct prefix_ipv4 *p;
  struct prefix_ipv4 classfull;
  struct prefix_ipv4 ifaddrclass;
  struct connected *c;
  int num;
  int rtemax;
  int subnetted = 0;

  /* Logging output event. */
  if (IS_RIP_DEBUG_EVENT)
    {
      if (to)
	zlog_info ("update routes to neighbor %s", inet_ntoa (to->sin_addr));
      else
	zlog_info ("update routes on interface %s ifindex %d",
		   ifp->name, ifp->ifindex);
    }

  /* Set output stream. */
  s = rip->obuf;

  /* Reset stream and RTE counter. */
  stream_reset (s);
  num = 0;
  rtemax = (RIP_PACKET_MAXSIZ - 4) / 20;

  /* Get RIP interface. */
  ri = ifp->info;
    
  /* If output interface is in simple password authentication mode, we
     need space for authentication data.  */
  if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
    rtemax -= 1;

  /* If output interface is in MD5 authentication mode, we need space
     for authentication header and data. */
  if (ri->auth_type == RIP_AUTH_MD5)
    rtemax -= 2;

  /* If output interface is in simple password authentication mode
     and string or keychain is specified we need space for auth. data */
  if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
    {
      if (ri->key_chain)
       {
         struct keychain *keychain;

         keychain = keychain_lookup (ri->key_chain);
         if (keychain)
           if (key_lookup_for_send (keychain))
             rtemax -=1;
       }
      else
       if (ri->auth_str)
         rtemax -=1;
    }

  if (version == RIPv1)
    {
      if (ifaddr == NULL)
	{
	  c = connected_lookup_address (ifp, to->sin_addr);
	  if (c != NULL)
	    ifaddr = c->address;
	}
      if (ifaddr == NULL)
	{
	  zlog_warn ("cannot find source address for packets to neighbor %s",
		     inet_ntoa (to->sin_addr));
	  return;
	}
      memcpy (&ifaddrclass, ifaddr, sizeof (struct prefix_ipv4));
      apply_classful_mask_ipv4 (&ifaddrclass);
      subnetted = 0;
      if (ifaddr->prefixlen > ifaddrclass.prefixlen)
        subnetted = 1;
    }

  for (rp = route_top (rip->table); rp; rp = route_next (rp))
    if ((rinfo = rp->info) != NULL)
      {
	/* For RIPv1, if we are subnetted, output subnets in our network    */
	/* that have the same mask as the output "interface". For other     */
	/* networks, only the classfull version is output.                  */
	
	if (version == RIPv1)
	  {
	    p = (struct prefix_ipv4 *) &rp->p;

	    if (IS_RIP_DEBUG_PACKET)
	      zlog_info("RIPv1 mask check, %s/%d considered for output",
			inet_ntoa (rp->p.u.prefix4), rp->p.prefixlen);

	    if (subnetted &&
		prefix_match ((struct prefix *) &ifaddrclass, &rp->p))
	      {
		if ((ifaddr->prefixlen != rp->p.prefixlen) &&
		    (rp->p.prefixlen != 32))
		  continue;
	      }
	    else
	      {
		memcpy (&classfull, &rp->p, sizeof(struct prefix_ipv4));
		apply_classful_mask_ipv4(&classfull);
		if (rp->p.u.prefix4.s_addr != 0 &&
		    classfull.prefixlen != rp->p.prefixlen)
		  continue;
	      }
	    if (IS_RIP_DEBUG_PACKET)
	      zlog_info("RIPv1 mask check, %s/%d made it through",
			inet_ntoa (rp->p.u.prefix4), rp->p.prefixlen);
	  }
	else 
	  p = (struct prefix_ipv4 *) &rp->p;

	/* Apply output filters. */
	ret = rip_outgoing_filter (p, ri);
	if (ret < 0)
	  continue;

	/* Changed route only output. */
	if (route_type == rip_changed_route &&
	    (! (rinfo->flags & RIP_RTF_CHANGED)))
	  continue;

	/* Split horizon. */
	/* if (split_horizon == rip_split_horizon) */
	if (ri->split_horizon == RIP_SPLIT_HORIZON)
	  {
	    /* 
	     * We perform split horizon for RIP and connected route. 
	     * For rip routes, we want to suppress the route if we would
             * end up sending the route back on the interface that we
             * learned it from, with a higher metric. For connected routes,
             * we suppress the route if the prefix is a subset of the
             * source address that we are going to use for the packet 
             * (in order to handle the case when multiple subnets are
             * configured on the same interface).
             */
	    if (rinfo->type == ZEBRA_ROUTE_RIP  &&
                 rinfo->ifindex == ifp->ifindex) 
	      continue;
	    if (rinfo->type == ZEBRA_ROUTE_CONNECT &&
                 prefix_match((struct prefix *)p, (struct prefix *)saddr))
	      continue;
	  }

	/* Preparation for route-map. */
	rinfo->metric_set = 0;
	rinfo->nexthop_out.s_addr = 0;
	rinfo->metric_out = rinfo->metric;
	rinfo->tag_out = rinfo->tag;
	rinfo->ifindex_out = ifp->ifindex;

	/* In order to avoid some local loops,
	 * if the RIP route has a nexthop via this interface, keep the nexthop,
	 * otherwise set it to 0. The nexthop should not be propagated
	 * beyond the local broadcast/multicast area in order
	 * to avoid an IGP multi-level recursive look-up.
	 * see (4.4)
	 */
	if (rinfo->ifindex == ifp->ifindex)
	  rinfo->nexthop_out = rinfo->nexthop;

	/* Interface route-map */
	if (ri->routemap[RIP_FILTER_OUT])
	  {
	    ret = route_map_apply (ri->routemap[RIP_FILTER_OUT], 
				     (struct prefix *) p, RMAP_RIP, 
				     rinfo);

	    if (ret == RMAP_DENYMATCH)
	      {
	        if (IS_RIP_DEBUG_PACKET)
	          zlog_info ("RIP %s/%d is filtered by route-map out",
			     inet_ntoa (p->prefix), p->prefixlen);
		  continue;
	      }
	  }
           
	/* Apply redistribute route map - continue, if deny */
	if (rip->route_map[rinfo->type].name
	    && rinfo->sub_type != RIP_ROUTE_INTERFACE)
	  {
	    ret = route_map_apply (rip->route_map[rinfo->type].map,
				   (struct prefix *)p, RMAP_RIP, rinfo);

	    if (ret == RMAP_DENYMATCH) 
	      {
		if (IS_RIP_DEBUG_PACKET)
		  zlog_info ("%s/%d is filtered by route-map",
			     inet_ntoa (p->prefix), p->prefixlen);
		continue;
	      }
	  }

	/* When route-map does not set metric. */
	if (! rinfo->metric_set)
	  {
	    /* If redistribute metric is set. */
	    if (rip->route_map[rinfo->type].metric_config
		&& rinfo->metric != RIP_METRIC_INFINITY)
	      {
		rinfo->metric_out = rip->route_map[rinfo->type].metric;
	      }
	    else
	      {
		/* If the route is not connected or localy generated
		   one, use default-metric value*/
		if (rinfo->type != ZEBRA_ROUTE_RIP 
		    && rinfo->type != ZEBRA_ROUTE_CONNECT
		    && rinfo->metric != RIP_METRIC_INFINITY)
		  rinfo->metric_out = rip->default_metric;
	      }
	  }

	/* Apply offset-list */
	if (rinfo->metric != RIP_METRIC_INFINITY)
	  rip_offset_list_apply_out (p, ifp, &rinfo->metric_out);

	if (rinfo->metric_out > RIP_METRIC_INFINITY)
	  rinfo->metric_out = RIP_METRIC_INFINITY;

	/* Perform split-horizon with poisoned reverse 
	 * for RIP and connected routes.
	 **/
	if (ri->split_horizon == RIP_SPLIT_HORIZON_POISONED_REVERSE) {
	    /* 
	     * We perform split horizon for RIP and connected route. 
	     * For rip routes, we want to suppress the route if we would
             * end up sending the route back on the interface that we
             * learned it from, with a higher metric. For connected routes,
             * we suppress the route if the prefix is a subset of the
             * source address that we are going to use for the packet 
             * (in order to handle the case when multiple subnets are
             * configured on the same interface).
             */
	  if (rinfo->type == ZEBRA_ROUTE_RIP  &&
	       rinfo->ifindex == ifp->ifindex)
	       rinfo->metric_out = RIP_METRIC_INFINITY;
	  if (rinfo->type == ZEBRA_ROUTE_CONNECT &&
              prefix_match((struct prefix *)p, (struct prefix *)saddr))
	       rinfo->metric_out = RIP_METRIC_INFINITY;
	}
 
	/* Write RTE to the stream. */
	num = rip_write_rte (num, s, p, version, rinfo, to ? NULL : ifp);
	if (num == rtemax)
	  {
	    if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5)
	      rip_auth_md5_set (s, ifp);

	    ret = rip_send_packet (STREAM_DATA (s), stream_get_endp (s),
				   to, ifp, connected);

	    if (ret >= 0 && IS_RIP_DEBUG_SEND)
	      rip_packet_dump ((struct rip_packet *)STREAM_DATA (s),
			       stream_get_endp(s), "SEND");
	    num = 0;
	    stream_reset (s);
	  }
      }

  /* Flush unwritten RTE. */
  if (num != 0)
    {
      if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5)
	rip_auth_md5_set (s, ifp);

      ret = rip_send_packet (STREAM_DATA (s), stream_get_endp (s), to, ifp, 
			     connected);

      if (ret >= 0 && IS_RIP_DEBUG_SEND)
	rip_packet_dump ((struct rip_packet *)STREAM_DATA (s),
			 stream_get_endp (s), "SEND");
      num = 0;
      stream_reset (s);
    }

  /* Statistics updates. */
  ri->sent_updates++;
}

/* Send RIP packet to the interface. */
void
rip_update_interface (struct interface *ifp, u_char version, int route_type,
                      struct connected *sconn)
{
  struct prefix_ipv4 *p;
  struct connected *connected;
  listnode node;
  struct sockaddr_in to;
  struct prefix_ipv4 *saddr = (struct prefix_ipv4 *) sconn->address;

  /* When RIP version is 2 and multicast enable interface. */
  if (version == RIPv2 && if_is_multicast (ifp)) 
    {
      if (IS_RIP_DEBUG_EVENT)
	zlog_info ("multicast announce on %s ", ifp->name);

      rip_output_process (ifp, NULL, NULL, route_type, version, 
                          sconn, saddr);
      return;
    }

  /* If we can't send multicast packet, send it with unicast. */
  if (if_is_broadcast (ifp) || if_is_pointopoint (ifp))
    {
      for (node = listhead (ifp->connected); node; nextnode (node))
	{	    
	  connected = getdata (node);

	  /* Fetch broadcast address or poin-to-point destination
             address . */
	  p = (struct prefix_ipv4 *) connected->destination;

	  if (p->family == AF_INET)
	    {
	      /* Destination address and port setting. */
	      memset (&to, 0, sizeof (struct sockaddr_in));
	      to.sin_addr = p->prefix;
	      to.sin_port = htons (RIP_PORT_DEFAULT);

	      if (IS_RIP_DEBUG_EVENT)
		zlog_info ("%s announce to %s on %s",
			   if_is_pointopoint (ifp) ? "unicast" : "broadcast",
			   inet_ntoa (to.sin_addr), ifp->name);

	      rip_output_process (ifp, connected->address, &to, route_type,
				 version, connected, saddr);
	    }
	}
    }
}

/* Update send to all interface and neighbor. */
void
rip_update_process (int route_type)
{
  listnode node, ifnode;
  struct connected *connected;
  struct interface *ifp;
  struct rip_interface *ri;
  struct route_node *rp;
  struct sockaddr_in to;
  struct prefix_ipv4 *p;

  /* Send RIP update to each interface. */
  for (node = listhead (iflist); node; nextnode (node))
    {
      ifp = getdata (node);

      if (if_is_loopback (ifp))
	continue;

      if (! if_is_operative (ifp))
	continue;

      /* Fetch RIP interface information. */
      ri = ifp->info;

      /* When passive interface is specified, suppress announce to the
         interface. */
      if (ri->passive)
	continue;

      if (ri->running)
	{
	  if (IS_RIP_DEBUG_EVENT) 
	    {
	      if (ifp->name) 
		zlog_info ("SEND UPDATE to %s ifindex %d",
			   ifp->name, ifp->ifindex);
	      else
		zlog_info ("SEND UPDATE to _unknown_ ifindex %d",
			   ifp->ifindex);
	    }

          /* send update on each connected network */

	  LIST_LOOP(ifp->connected, connected, ifnode)
	    {
	      struct prefix_ipv4 *ifaddr;
              int done = 0;
	      /* 
               * If there is no version configuration in the interface,
               * use rip's version setting. 
               */
	      int vsend = ((ri->ri_send == RI_RIP_UNSPEC) ?
			   rip->version_send : ri->ri_send);

              ifaddr = (struct prefix_ipv4 *) connected->address;

	      if (ifaddr->family != AF_INET)
		continue;

              if ((vsend & RIPv1) && !done)
	        rip_update_interface (ifp, RIPv1, route_type, connected);
              if ((vsend & RIPv2) && if_is_multicast(ifp))
	        rip_update_interface (ifp, RIPv2, route_type, connected);
              done = 1;
              if (!(vsend & RIPv2) || !if_is_multicast(ifp))
                break;
		
	  }
	}
    }

  /* RIP send updates to each neighbor. */
  for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
    if (rp->info != NULL)
      {
	p = (struct prefix_ipv4 *) &rp->p;

	ifp = if_lookup_address (p->prefix);
	if (! ifp)
	  {
	    zlog_warn ("Neighbor %s doesn't exist direct connected network",
		       inet_ntoa (p->prefix));
	    continue;
	  }

	/* Set destination address and port */
	memset (&to, 0, sizeof (struct sockaddr_in));
	to.sin_addr = p->prefix;
	to.sin_port = htons (RIP_PORT_DEFAULT);

	/* RIP version is rip's configuration. */
	rip_output_process (ifp, NULL, &to, route_type, rip->version_send, 
                            NULL, p);
      }
}

/* RIP's periodical timer. */
int
rip_update (struct thread *t)
{
  /* Clear timer pointer. */
  rip->t_update = NULL;

  if (IS_RIP_DEBUG_EVENT)
    zlog_info ("update timer fire!");

  /* Process update output. */
  rip_update_process (rip_all_route);

  /* Triggered updates may be suppressed if a regular update is due by
     the time the triggered update would be sent. */
  if (rip->t_triggered_interval)
    {
      thread_cancel (rip->t_triggered_interval);
      rip->t_triggered_interval = NULL;
    }
  rip->trigger = 0;

  /* Register myself. */
  rip_event (RIP_UPDATE_EVENT, 0);

  return 0;
}

/* Walk down the RIP routing table then clear changed flag. */
void
rip_clear_changed_flag ()
{
  struct route_node *rp;
  struct rip_info *rinfo;

  for (rp = route_top (rip->table); rp; rp = route_next (rp))
    if ((rinfo = rp->info) != NULL)
      if (rinfo->flags & RIP_RTF_CHANGED)
	rinfo->flags &= ~RIP_RTF_CHANGED;
}

/* Triggered update interval timer. */
int
rip_triggered_interval (struct thread *t)
{
  int rip_triggered_update (struct thread *);

  rip->t_triggered_interval = NULL;

  if (rip->trigger)
    {
      rip->trigger = 0;
      rip_triggered_update (t);
    }
  return 0;
}     

/* Execute triggered update. */
int
rip_triggered_update (struct thread *t)
{
  int interval;

  /* Clear thred pointer. */
  rip->t_triggered_update = NULL;

  /* Cancel interval timer. */
  if (rip->t_triggered_interval)
    {
      thread_cancel (rip->t_triggered_interval);
      rip->t_triggered_interval = NULL;
    }
  rip->trigger = 0;

  /* Logging triggered update. */
  if (IS_RIP_DEBUG_EVENT)
    zlog_info ("triggered update!");

  /* Split Horizon processing is done when generating triggered
     updates as well as normal updates (see section 2.6). */
  rip_update_process (rip_changed_route);

  /* Once all of the triggered updates have been generated, the route
     change flags should be cleared. */
  rip_clear_changed_flag ();

  /* After a triggered update is sent, a timer should be set for a
   random interval between 1 and 5 seconds.  If other changes that
   would trigger updates occur before the timer expires, a single
   update is triggered when the timer expires. */
  interval = (random () % 5) + 1;

  rip->t_triggered_interval = 
    thread_add_timer (master, rip_triggered_interval, NULL, interval);

  return 0;
}

/* Withdraw redistributed route. */
void
rip_redistribute_withdraw (int type)
{
  struct route_node *rp;
  struct rip_info *rinfo;

  if (!rip)
    return;

  for (rp = route_top (rip->table); rp; rp = route_next (rp))
    if ((rinfo = rp->info) != NULL)
      {
	if (rinfo->type == type
	    && rinfo->sub_type != RIP_ROUTE_INTERFACE)
	  {
	    /* Perform poisoned reverse. */
	    rinfo->metric = RIP_METRIC_INFINITY;
	    RIP_TIMER_ON (rinfo->t_garbage_collect, 
			  rip_garbage_collect, rip->garbage_time);
	    RIP_TIMER_OFF (rinfo->t_timeout);
	    rinfo->flags |= RIP_RTF_CHANGED;

	    if (IS_RIP_DEBUG_EVENT) {
              struct prefix_ipv4 *p = (struct prefix_ipv4 *) &rp->p;

              zlog_info ("Poisone %s/%d on the interface %s with an infinity metric [withdraw]",
                         inet_ntoa(p->prefix), p->prefixlen,
                         ifindex2ifname(rinfo->ifindex));
	    }

	    rip_event (RIP_TRIGGERED_UPDATE, 0);
	  }
      }
}

/* Create new RIP instance and set it to global variable. */
int
rip_create ()
{
  rip = XMALLOC (MTYPE_RIP, sizeof (struct rip));
  memset (rip, 0, sizeof (struct rip));

  /* Set initial value. */
  rip->version_send = RI_RIP_VERSION_2;
  rip->version_recv = RI_RIP_VERSION_1_AND_2;
  rip->update_time = RIP_UPDATE_TIMER_DEFAULT;
  rip->timeout_time = RIP_TIMEOUT_TIMER_DEFAULT;
  rip->garbage_time = RIP_GARBAGE_TIMER_DEFAULT;
  rip->default_metric = RIP_DEFAULT_METRIC_DEFAULT;

  /* Initialize RIP routig table. */
  rip->table = route_table_init ();
  rip->route = route_table_init ();
  rip->neighbor = route_table_init ();

  /* Make output stream. */
  rip->obuf = stream_new (1500);

  /* Make socket. */
  rip->sock = rip_create_socket ();
  if (rip->sock < 0)
    return rip->sock;

  /* Create read and timer thread. */
  rip_event (RIP_READ, rip->sock);
  rip_event (RIP_UPDATE_EVENT, 1);

  return 0;
}

/* Sned RIP request to the destination. */
int
rip_request_send (struct sockaddr_in *to, struct interface *ifp,
		  u_char version, struct connected *connected)
{
  struct rte *rte;
  struct rip_packet rip_packet;
  listnode node;

  memset (&rip_packet, 0, sizeof (rip_packet));

  rip_packet.command = RIP_REQUEST;
  rip_packet.version = version;
  rte = rip_packet.rte;
  rte->metric = htonl (RIP_METRIC_INFINITY);

  if (connected) 
    {
      /* 
       * connected is only sent for ripv1 case, or when
       * interface does not support multicast.  Caller loops
       * over each connected address for this case.
       */
      if (rip_send_packet ((u_char *) &rip_packet, sizeof (rip_packet), 
                            to, ifp, connected) != sizeof (rip_packet))
        return -1;
      else
        return sizeof (rip_packet);
    }
	
  /* send request on each connected network */
  LIST_LOOP(ifp->connected, connected, node)
    {
      struct prefix_ipv4 *p;

      p = (struct prefix_ipv4 *) connected->address;

      if (p->family != AF_INET)
        continue;

      if (rip_send_packet ((u_char *) &rip_packet, sizeof (rip_packet), 
                            to, ifp, connected) != sizeof (rip_packet))
        return -1;
    }
  return sizeof (rip_packet);
}

int
rip_update_jitter (unsigned long time)
{
#define JITTER_BOUND 4
  /* We want to get the jitter to +/- 1/JITTER_BOUND the interval.
     Given that, we cannot let time be less than JITTER_BOUND seconds.
     The RIPv2 RFC says jitter should be small compared to
     update_time.  We consider 1/JITTER_BOUND to be small.
  */
  
  int jitter_input = time;
  int jitter;
  
  if (jitter_input < JITTER_BOUND)
    jitter_input = JITTER_BOUND;
  
  jitter = (((rand () % ((jitter_input * 2) + 1)) - jitter_input));  

  return jitter/JITTER_BOUND;
}

void
rip_event (enum rip_event event, int sock)
{
  int jitter = 0;

  switch (event)
    {
    case RIP_READ:
      rip->t_read = thread_add_read (master, rip_read, NULL, sock);
      break;
    case RIP_UPDATE_EVENT:
      if (rip->t_update)
	{
	  thread_cancel (rip->t_update);
	  rip->t_update = NULL;
	}
      jitter = rip_update_jitter (rip->update_time);
      rip->t_update = 
	thread_add_timer (master, rip_update, NULL, 
			  sock ? 2 : rip->update_time + jitter);
      break;
    case RIP_TRIGGERED_UPDATE:
      if (rip->t_triggered_interval)
	rip->trigger = 1;
      else if (! rip->t_triggered_update)
	rip->t_triggered_update = 
	  thread_add_event (master, rip_triggered_update, NULL, 0);
      break;
    default:
      break;
    }
}

DEFUN (router_rip,
       router_rip_cmd,
       "router rip",
       "Enable a routing process\n"
       "Routing Information Protocol (RIP)\n")
{
  int ret;

  /* If rip is not enabled before. */
  if (! rip)
    {
      ret = rip_create ();
      if (ret < 0)
	{
	  zlog_info ("Can't create RIP");
	  return CMD_WARNING;
	}
    }
  vty->node = RIP_NODE;
  vty->index = rip;

  return CMD_SUCCESS;
}

DEFUN (no_router_rip,
       no_router_rip_cmd,
       "no router rip",
       NO_STR
       "Enable a routing process\n"
       "Routing Information Protocol (RIP)\n")
{
  if (rip)
    rip_clean ();
  return CMD_SUCCESS;
}

DEFUN (rip_version,
       rip_version_cmd,
       "version <1-2>",
       "Set routing protocol version\n"
       "version\n")
{
  int version;

  version = atoi (argv[0]);
  if (version != RIPv1 && version != RIPv2)
    {
      vty_out (vty, "invalid rip version %d%s", version,
	       VTY_NEWLINE);
      return CMD_WARNING;
    }
  rip->version_send = version;
  rip->version_recv = version;

  return CMD_SUCCESS;
} 

DEFUN (no_rip_version,
       no_rip_version_cmd,
       "no version",
       NO_STR
       "Set routing protocol version\n")
{
  /* Set RIP version to the default. */
  rip->version_send = RI_RIP_VERSION_2;
  rip->version_recv = RI_RIP_VERSION_1_AND_2;

  return CMD_SUCCESS;
} 

ALIAS (no_rip_version,
       no_rip_version_val_cmd,
       "no version <1-2>",
       NO_STR
       "Set routing protocol version\n"
       "version\n")

DEFUN (rip_route,
       rip_route_cmd,
       "route A.B.C.D/M",
       "RIP static route configuration\n"
       "IP prefix <network>/<length>\n")
{
  int ret;
  struct prefix_ipv4 p;
  struct route_node *node;

  ret = str2prefix_ipv4 (argv[0], &p);
  if (ret < 0)
    {
      vty_out (vty, "Malformed address%s", VTY_NEWLINE);
      return CMD_WARNING;
    }
  apply_mask_ipv4 (&p);

  /* For router rip configuration. */
  node = route_node_get (rip->route, (struct prefix *) &p);

  if (node->info)
    {
      vty_out (vty, "There is already same static route.%s", VTY_NEWLINE);
      route_unlock_node (node);
      return CMD_WARNING;
    }

  node->info = "static";

  rip_redistribute_add (ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0, NULL);

  return CMD_SUCCESS;
}

DEFUN (no_rip_route,
       no_rip_route_cmd,
       "no route A.B.C.D/M",
       NO_STR
       "RIP static route configuration\n"
       "IP prefix <network>/<length>\n")
{
  int ret;
  struct prefix_ipv4 p;
  struct route_node *node;

  ret = str2prefix_ipv4 (argv[0], &p);
  if (ret < 0)
    {
      vty_out (vty, "Malformed address%s", VTY_NEWLINE);
      return CMD_WARNING;
    }
  apply_mask_ipv4 (&p);

  /* For router rip configuration. */
  node = route_node_lookup (rip->route, (struct prefix *) &p);
  if (! node)
    {
      vty_out (vty, "Can't find route %s.%s", argv[0],
	       VTY_NEWLINE);
      return CMD_WARNING;
    }

  rip_redistribute_delete (ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0);
  route_unlock_node (node);

  node->info = NULL;
  route_unlock_node (node);

  return CMD_SUCCESS;
}

void
rip_update_default_metric ()
{
  struct route_node *np;
  struct rip_info *rinfo;

  for (np = route_top (rip->table); np; np = route_next (np))
    if ((rinfo = np->info) != NULL)
      if (rinfo->type != ZEBRA_ROUTE_RIP && rinfo->type != ZEBRA_ROUTE_CONNECT)
        rinfo->metric = rip->default_metric;
}

DEFUN (rip_default_metric,
       rip_default_metric_cmd,
       "default-metric <1-16>",
       "Set a metric of redistribute routes\n"
       "Default metric\n")
{
  if (rip)
    {
      rip->default_metric = atoi (argv[0]);
      /* rip_update_default_metric (); */
    }
  return CMD_SUCCESS;
}

DEFUN (no_rip_default_metric,
       no_rip_default_metric_cmd,
       "no default-metric",
       NO_STR
       "Set a metric of redistribute routes\n"
       "Default metric\n")
{
  if (rip)
    {
      rip->default_metric = RIP_DEFAULT_METRIC_DEFAULT;
      /* rip_update_default_metric (); */
    }
  return CMD_SUCCESS;
}

ALIAS (no_rip_default_metric,
       no_rip_default_metric_val_cmd,
       "no default-metric <1-16>",
       NO_STR
       "Set a metric of redistribute routes\n"
       "Default metric\n")

DEFUN (rip_timers,
       rip_timers_cmd,
       "timers basic <5-2147483647> <5-2147483647> <5-2147483647>",
       "Adjust routing timers\n"
       "Basic routing protocol update timers\n"
       "Routing table update timer value in second. Default is 30.\n"
       "Routing information timeout timer. Default is 180.\n"
       "Garbage collection timer. Default is 120.\n")
{
  unsigned long update;
  unsigned long timeout;
  unsigned long garbage;
  char *endptr = NULL;
  unsigned long RIP_TIMER_MAX = 2147483647;
  unsigned long RIP_TIMER_MIN = 5;

  update = strtoul (argv[0], &endptr, 10);
  if (update > RIP_TIMER_MAX || update < RIP_TIMER_MIN || *endptr != '\0')  
    {
      vty_out (vty, "update timer value error%s", VTY_NEWLINE);
      return CMD_WARNING;
    }
  
  timeout = strtoul (argv[1], &endptr, 10);
  if (timeout > RIP_TIMER_MAX || timeout < RIP_TIMER_MIN || *endptr != '\0') 
    {
      vty_out (vty, "timeout timer value error%s", VTY_NEWLINE);
      return CMD_WARNING;
    }
  
  garbage = strtoul (argv[2], &endptr, 10);
  if (garbage > RIP_TIMER_MAX || garbage < RIP_TIMER_MIN || *endptr != '\0') 
    {
      vty_out (vty, "garbage timer value error%s", VTY_NEWLINE);
      return CMD_WARNING;
    }

  /* Set each timer value. */
  rip->update_time = update;
  rip->timeout_time = timeout;
  rip->garbage_time = garbage;

  /* Reset update timer thread. */
  rip_event (RIP_UPDATE_EVENT, 0);

  return CMD_SUCCESS;
}

DEFUN (no_rip_timers,
       no_rip_timers_cmd,
       "no timers basic",
       NO_STR
       "Adjust routing timers\n"
       "Basic routing protocol update timers\n")
{
  /* Set each timer value to the default. */
  rip->update_time = RIP_UPDATE_TIMER_DEFAULT;
  rip->timeout_time = RIP_TIMEOUT_TIMER_DEFAULT;
  rip->garbage_time = RIP_GARBAGE_TIMER_DEFAULT;

  /* Reset update timer thread. */
  rip_event (RIP_UPDATE_EVENT, 0);

  return CMD_SUCCESS;
}

ALIAS (no_rip_timers,
       no_rip_timers_val_cmd,
       "no timers basic <0-65535> <0-65535> <0-65535>",
       NO_STR
       "Adjust routing timers\n"
       "Basic routing protocol update timers\n"
       "Routing table update timer value in second. Default is 30.\n"
       "Routing information timeout timer. Default is 180.\n"
       "Garbage collection timer. Default is 120.\n")


struct route_table *rip_distance_table;

struct rip_distance
{
  /* Distance value for the IP source prefix. */
  u_char distance;

  /* Name of the access-list to be matched. */
  char *access_list;
};

struct rip_distance *
rip_distance_new ()
{
  struct rip_distance *new;
  new = XMALLOC (MTYPE_RIP_DISTANCE, sizeof (struct rip_distance));
  memset (new, 0, sizeof (struct rip_distance));
  return new;
}

void
rip_distance_free (struct rip_distance *rdistance)
{
  XFREE (MTYPE_RIP_DISTANCE, rdistance);
}

int
rip_distance_set (struct vty *vty, char *distance_str, char *ip_str,
		  char *access_list_str)
{
  int ret;
  struct prefix_ipv4 p;
  u_char distance;
  struct route_node *rn;
  struct rip_distance *rdistance;

  ret = str2prefix_ipv4 (ip_str, &p);
  if (ret == 0)
    {
      vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
      return CMD_WARNING;
    }

  distance = atoi (distance_str);

  /* Get RIP distance node. */
  rn = route_node_get (rip_distance_table, (struct prefix *) &p);
  if (rn->info)
    {
      rdistance = rn->info;
      route_unlock_node (rn);
    }
  else
    {
      rdistance = rip_distance_new ();
      rn->info = rdistance;
    }

  /* Set distance value. */
  rdistance->distance = distance;

  /* Reset access-list configuration. */
  if (rdistance->access_list)
    {
      free (rdistance->access_list);
      rdistance->access_list = NULL;
    }
  if (access_list_str)
    rdistance->access_list = strdup (access_list_str);

  return CMD_SUCCESS;
}

int
rip_distance_unset (struct vty *vty, char *distance_str, char *ip_str,
		    char *access_list_str)
{
  int ret;
  struct prefix_ipv4 p;
  u_char distance;
  struct route_node *rn;
  struct rip_distance *rdistance;

  ret = str2prefix_ipv4 (ip_str, &p);
  if (ret == 0)
    {
      vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
      return CMD_WARNING;
    }

  distance = atoi (distance_str);

  rn = route_node_lookup (rip_distance_table, (struct prefix *)&p);
  if (! rn)
    {
      vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
      return CMD_WARNING;
    }

  rdistance = rn->info;

  if (rdistance->access_list)
    free (rdistance->access_list);
  rip_distance_free (rdistance);

  rn->info = NULL;
  route_unlock_node (rn);
  route_unlock_node (rn);

  return CMD_SUCCESS;
}

void
rip_distance_reset ()
{
  struct route_node *rn;
  struct rip_distance *rdistance;

  for (rn = route_top (rip_distance_table); rn; rn = route_next (rn))
    if ((rdistance = rn->info) != NULL)
      {
	if (rdistance->access_list)
	  free (rdistance->access_list);
	rip_distance_free (rdistance);
	rn->info = NULL;
	route_unlock_node (rn);
      }
}

/* Apply RIP information to distance method. */
u_char
rip_distance_apply (struct rip_info *rinfo)
{
  struct route_node *rn;
  struct prefix_ipv4 p;
  struct rip_distance *rdistance;
  struct access_list *alist;

  if (! rip)
    return 0;

  memset (&p, 0, sizeof (struct prefix_ipv4));
  p.family = AF_INET;
  p.prefix = rinfo->from;
  p.prefixlen = IPV4_MAX_BITLEN;

  /* Check source address. */
  rn = route_node_match (rip_distance_table, (struct prefix *) &p);
  if (rn)
    {
      rdistance = rn->info;
      route_unlock_node (rn);

      if (rdistance->access_list)
	{
	  alist = access_list_lookup (AFI_IP, rdistance->access_list);
	  if (alist == NULL)
	    return 0;
	  if (access_list_apply (alist, &rinfo->rp->p) == FILTER_DENY)
	    return 0;

	  return rdistance->distance;
	}
      else
	return rdistance->distance;
    }

  if (rip->distance)
    return rip->distance;

  return 0;
}

void
rip_distance_show (struct vty *vty)
{
  struct route_node *rn;
  struct rip_distance *rdistance;
  int header = 1;
  char buf[BUFSIZ];
  
  vty_out (vty, "  Distance: (default is %d)%s",
	   rip->distance ? rip->distance :ZEBRA_RIP_DISTANCE_DEFAULT,
	   VTY_NEWLINE);

  for (rn = route_top (rip_distance_table); rn; rn = route_next (rn))
    if ((rdistance = rn->info) != NULL)
      {
	if (header)
	  {
	    vty_out (vty, "    Address           Distance  List%s",
		     VTY_NEWLINE);
	    header = 0;
	  }
	sprintf (buf, "%s/%d", inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen);
	vty_out (vty, "    %-20s  %4d  %s%s",
		 buf, rdistance->distance,
		 rdistance->access_list ? rdistance->access_list : "",
		 VTY_NEWLINE);
      }
}

DEFUN (rip_distance,
       rip_distance_cmd,
       "distance <1-255>",
       "Administrative distance\n"
       "Distance value\n")
{
  rip->distance = atoi (argv[0]);
  return CMD_SUCCESS;
}

DEFUN (no_rip_distance,
       no_rip_distance_cmd,
       "no distance <1-255>",
       NO_STR
       "Administrative distance\n"
       "Distance value\n")
{
  rip->distance = 0;
  return CMD_SUCCESS;
}

DEFUN (rip_distance_source,
       rip_distance_source_cmd,
       "distance <1-255> A.B.C.D/M",
       "Administrative distance\n"
       "Distance value\n"
       "IP source prefix\n")
{
  rip_distance_set (vty, argv[0], argv[1], NULL);
  return CMD_SUCCESS;
}

DEFUN (no_rip_distance_source,
       no_rip_distance_source_cmd,
       "no distance <1-255> A.B.C.D/M",
       NO_STR
       "Administrative distance\n"
       "Distance value\n"
       "IP source prefix\n")
{
  rip_distance_unset (vty, argv[0], argv[1], NULL);
  return CMD_SUCCESS;
}

DEFUN (rip_distance_source_access_list,
       rip_distance_source_access_list_cmd,
       "distance <1-255> A.B.C.D/M WORD",
       "Administrative distance\n"
       "Distance value\n"
       "IP source prefix\n"
       "Access list name\n")
{
  rip_distance_set (vty, argv[0], argv[1], argv[2]);
  return CMD_SUCCESS;
}

DEFUN (no_rip_distance_source_access_list,
       no_rip_distance_source_access_list_cmd,
       "no distance <1-255> A.B.C.D/M WORD",
       NO_STR
       "Administrative distance\n"
       "Distance value\n"
       "IP source prefix\n"
       "Access list name\n")
{
  rip_distance_unset (vty, argv[0], argv[1], argv[2]);
  return CMD_SUCCESS;
}

/* Print out routes update time. */
void
rip_vty_out_uptime (struct vty *vty, struct rip_info *rinfo)
{
  struct timeval timer_now;
  time_t clock;
  struct tm *tm;
#define TIME_BUF 25
  char timebuf [TIME_BUF];
  struct thread *thread;

  gettimeofday (&timer_now, NULL);

  if ((thread = rinfo->t_timeout) != NULL)
    {
      clock = thread->u.sands.tv_sec - timer_now.tv_sec;
      tm = gmtime (&clock);
      strftime (timebuf, TIME_BUF, "%M:%S", tm);
      vty_out (vty, "%5s", timebuf);
    }
  else if ((thread = rinfo->t_garbage_collect) != NULL)
    {
      clock = thread->u.sands.tv_sec - timer_now.tv_sec;
      tm = gmtime (&clock);
      strftime (timebuf, TIME_BUF, "%M:%S", tm);
      vty_out (vty, "%5s", timebuf);
    }
}

char *
rip_route_type_print (int sub_type)
{
  switch (sub_type)
    {
      case RIP_ROUTE_RTE:
	return "n";
      case RIP_ROUTE_STATIC:
	return "s";
      case RIP_ROUTE_DEFAULT:
	return "d";
      case RIP_ROUTE_REDISTRIBUTE:
	return "r";
      case RIP_ROUTE_INTERFACE:
	return "i";
      default:
	return "?";
    }
}

DEFUN (show_ip_rip,
       show_ip_rip_cmd,
       "show ip rip",
       SHOW_STR
       IP_STR
       "Show RIP routes\n")
{
  struct route_node *np;
  struct rip_info *rinfo;

  if (! rip)
    return CMD_SUCCESS;

  vty_out (vty, "Codes: R - RIP, C - connected, S - Static, O - OSPF, B - BGP%s"
	   "Sub-codes:%s"
           "      (n) - normal, (s) - static, (d) - default, (r) - redistribute,%s"
	   "      (i) - interface%s%s"
	   "     Network            Next Hop         Metric From            Tag Time%s",
	   VTY_NEWLINE, VTY_NEWLINE,  VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
  
  for (np = route_top (rip->table); np; np = route_next (np))
    if ((rinfo = np->info) != NULL)
      {
	int len;

	len = vty_out (vty, "%s(%s) %s/%d",
		       /* np->lock, For debugging. */
		       route_info[rinfo->type].str,
		       rip_route_type_print (rinfo->sub_type),
		       inet_ntoa (np->p.u.prefix4), np->p.prefixlen);
	
	len = 24 - len;

	if (len > 0)
	  vty_out (vty, "%*s", len, " ");

        if (rinfo->nexthop.s_addr) 
	  vty_out (vty, "%-20s %2d ", inet_ntoa (rinfo->nexthop),
		   rinfo->metric);
        else
	  vty_out (vty, "0.0.0.0              %2d ", rinfo->metric);

	/* Route which exist in kernel routing table. */
	if ((rinfo->type == ZEBRA_ROUTE_RIP) && 
	    (rinfo->sub_type == RIP_ROUTE_RTE))
	  {
	    vty_out (vty, "%-15s ", inet_ntoa (rinfo->from));
	    vty_out (vty, "%3d ", rinfo->tag);
	    rip_vty_out_uptime (vty, rinfo);
	  }
	else if (rinfo->metric == RIP_METRIC_INFINITY)
	  {
	    vty_out (vty, "self            ");
	    vty_out (vty, "%3d ", rinfo->tag);
	    rip_vty_out_uptime (vty, rinfo);
	  }
	else
	  {
	    vty_out (vty, "self            ");
	    vty_out (vty, "%3d", rinfo->tag);
	  }

	vty_out (vty, "%s", VTY_NEWLINE);
      }
  return CMD_SUCCESS;
}

/* Return next event time. */
int
rip_next_thread_timer (struct thread *thread)
{
  struct timeval timer_now;

  gettimeofday (&timer_now, NULL);

  return thread->u.sands.tv_sec - timer_now.tv_sec;
}

/* Vincent: formerly, it was show_ip_protocols_rip: "show ip protocols" */
DEFUN (show_ip_rip_status,
       show_ip_rip_status_cmd,
       "show ip rip status",
       SHOW_STR
       IP_STR
       "Show RIP routes\n"
       "IP routing protocol process parameters and statistics\n")
{
  listnode node;
  struct interface *ifp;
  struct rip_interface *ri;
  extern struct message ri_version_msg[];
  char *send_version;
  char *receive_version;

  if (! rip)
    return CMD_SUCCESS;

  vty_out (vty, "Routing Protocol is \"rip\"%s", VTY_NEWLINE);
  vty_out (vty, "  Sending updates every %ld seconds with +/-50%%,",
	   rip->update_time);
  vty_out (vty, " next due in %d seconds%s", 
	   rip_next_thread_timer (rip->t_update),
	   VTY_NEWLINE);
  vty_out (vty, "  Timeout after %ld seconds,", rip->timeout_time);
  vty_out (vty, " garbage collect after %ld seconds%s", rip->garbage_time,
	   VTY_NEWLINE);

  /* Filtering status show. */
  config_show_distribute (vty);
		 
  /* Default metric information. */
  vty_out (vty, "  Default redistribution metric is %d%s",
	   rip->default_metric, VTY_NEWLINE);

  /* Redistribute information. */
  vty_out (vty, "  Redistributing:");
  config_write_rip_redistribute (vty, 0);
  vty_out (vty, "%s", VTY_NEWLINE);

  vty_out (vty, "  Default version control: send version %s,",
	   lookup(ri_version_msg,rip->version_send));
  if (rip->version_recv == RI_RIP_VERSION_1_AND_2)
    vty_out (vty, " receive any version %s", VTY_NEWLINE);
  else
    vty_out (vty, " receive version %s %s",
	     lookup(ri_version_msg,rip->version_recv), VTY_NEWLINE);

  vty_out (vty, "    Interface        Send  Recv   Key-chain%s", VTY_NEWLINE);

  for (node = listhead (iflist); node; node = nextnode (node))
    {
      ifp = getdata (node);
      ri = ifp->info;

      if (ri->enable_network || ri->enable_interface)
	{
	  if (ri->ri_send == RI_RIP_UNSPEC)
	    send_version = lookup (ri_version_msg, rip->version_send);
	  else
	    send_version = lookup (ri_version_msg, ri->ri_send);

	  if (ri->ri_receive == RI_RIP_UNSPEC)
	    receive_version = lookup (ri_version_msg, rip->version_recv);
	  else
	    receive_version = lookup (ri_version_msg, ri->ri_receive);
	
	  vty_out (vty, "    %-17s%-3s   %-3s    %s%s", ifp->name,
		   send_version,
		   receive_version,
		   ri->key_chain ? ri->key_chain : "",
		   VTY_NEWLINE);
	}
    }

  vty_out (vty, "  Routing for Networks:%s", VTY_NEWLINE);
  config_write_rip_network (vty, 0);  

  {
    int found_passive = 0;
    for (node = listhead (iflist); node; node = nextnode (node))
      {
	ifp = getdata (node);
	ri = ifp->info;

	if ((ri->enable_network || ri->enable_interface) && ri->passive)
	  {
	    if (!found_passive)
	      {
		vty_out (vty, "  Passive Interface(s):%s", VTY_NEWLINE);
		found_passive = 1;
	      }
	    vty_out (vty, "    %s%s", ifp->name, VTY_NEWLINE);
	  }
      }
  }

  vty_out (vty, "  Routing Information Sources:%s", VTY_NEWLINE);
  vty_out (vty, "    Gateway          BadPackets BadRoutes  Distance Last Update%s", VTY_NEWLINE);
  rip_peer_display (vty);

  rip_distance_show (vty);

  return CMD_SUCCESS;
}

/* RIP configuration write function. */
int
config_write_rip (struct vty *vty)
{
  int write = 0;
  struct route_node *rn;
  struct rip_distance *rdistance;

  if (rip)
    {
      /* Router RIP statement. */
      vty_out (vty, "router rip%s", VTY_NEWLINE);
      write++;
  
      /* RIP version statement.  Default is RIP version 2. */
      if (rip->version_send != RI_RIP_VERSION_2
	  || rip->version_recv != RI_RIP_VERSION_1_AND_2)
	vty_out (vty, " version %d%s", rip->version_send,
		 VTY_NEWLINE);
 
      /* RIP timer configuration. */
      if (rip->update_time != RIP_UPDATE_TIMER_DEFAULT 
	  || rip->timeout_time != RIP_TIMEOUT_TIMER_DEFAULT 
	  || rip->garbage_time != RIP_GARBAGE_TIMER_DEFAULT)
	vty_out (vty, " timers basic %lu %lu %lu%s",
		 rip->update_time,
		 rip->timeout_time,
		 rip->garbage_time,
		 VTY_NEWLINE);

      /* Default information configuration. */
      if (rip->default_information)
	{
	  if (rip->default_information_route_map)
	    vty_out (vty, " default-information originate route-map %s%s",
		     rip->default_information_route_map, VTY_NEWLINE);
	  else
	    vty_out (vty, " default-information originate%s",
		     VTY_NEWLINE);
	}

      /* Redistribute configuration. */
      config_write_rip_redistribute (vty, 1);

      /* RIP offset-list configuration. */
      config_write_rip_offset_list (vty);

      /* RIP enabled network and interface configuration. */
      config_write_rip_network (vty, 1);
			
      /* RIP default metric configuration */
      if (rip->default_metric != RIP_DEFAULT_METRIC_DEFAULT)
        vty_out (vty, " default-metric %d%s",
		 rip->default_metric, VTY_NEWLINE);

      /* Distribute configuration. */
      write += config_write_distribute (vty);

      /* Interface routemap configuration */
      write += config_write_if_rmap (vty);

      /* Distance configuration. */
      if (rip->distance)
	vty_out (vty, " distance %d%s", rip->distance, VTY_NEWLINE);

      /* RIP source IP prefix distance configuration. */
      for (rn = route_top (rip_distance_table); rn; rn = route_next (rn))
	if ((rdistance = rn->info) != NULL)
	  vty_out (vty, " distance %d %s/%d %s%s", rdistance->distance,
		   inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
		   rdistance->access_list ? rdistance->access_list : "",
		   VTY_NEWLINE);

      /* RIP static route configuration. */
      for (rn = route_top (rip->route); rn; rn = route_next (rn))
	if (rn->info)
	  vty_out (vty, " route %s/%d%s", 
		   inet_ntoa (rn->p.u.prefix4),
		   rn->p.prefixlen,
		   VTY_NEWLINE);

    }
  return write;
}

/* RIP node structure. */
struct cmd_node rip_node =
{
  RIP_NODE,
  "%s(config-router)# ",
  1
};

/* Distribute-list update functions. */
void
rip_distribute_update (struct distribute *dist)
{
  struct interface *ifp;
  struct rip_interface *ri;
  struct access_list *alist;
  struct prefix_list *plist;

  if (! dist->ifname)
    return;

  ifp = if_lookup_by_name (dist->ifname);
  if (ifp == NULL)
    return;

  ri = ifp->info;

  if (dist->list[DISTRIBUTE_IN])
    {
      alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_IN]);
      if (alist)
	ri->list[RIP_FILTER_IN] = alist;
      else
	ri->list[RIP_FILTER_IN] = NULL;
    }
  else
    ri->list[RIP_FILTER_IN] = NULL;

  if (dist->list[DISTRIBUTE_OUT])
    {
      alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_OUT]);
      if (alist)
	ri->list[RIP_FILTER_OUT] = alist;
      else
	ri->list[RIP_FILTER_OUT] = NULL;
    }
  else
    ri->list[RIP_FILTER_OUT] = NULL;

  if (dist->prefix[DISTRIBUTE_IN])
    {
      plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_IN]);
      if (plist)
	ri->prefix[RIP_FILTER_IN] = plist;
      else
	ri->prefix[RIP_FILTER_IN] = NULL;
    }
  else
    ri->prefix[RIP_FILTER_IN] = NULL;

  if (dist->prefix[DISTRIBUTE_OUT])
    {
      plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_OUT]);
      if (plist)
	ri->prefix[RIP_FILTER_OUT] = plist;
      else
	ri->prefix[RIP_FILTER_OUT] = NULL;
    }
  else
    ri->prefix[RIP_FILTER_OUT] = NULL;
}

void
rip_distribute_update_interface (struct interface *ifp)
{
  struct distribute *dist;

  dist = distribute_lookup (ifp->name);
  if (dist)
    rip_distribute_update (dist);
}

/* Update all interface's distribute list. */
/* ARGSUSED */
void
rip_distribute_update_all (struct prefix_list *notused)
{
  struct interface *ifp;
  listnode node;

  for (node = listhead (iflist); node; nextnode (node))
    {
      ifp = getdata (node);
      rip_distribute_update_interface (ifp);
    }
}
/* ARGSUSED */
void
rip_distribute_update_all_wrapper(struct access_list *notused)
{
        rip_distribute_update_all(NULL);
}

/* Delete all added rip route. */
void
rip_clean ()
{
  int i;
  struct route_node *rp;
  struct rip_info *rinfo;

  if (rip)
    {
      /* Clear RIP routes */
      for (rp = route_top (rip->table); rp; rp = route_next (rp))
	if ((rinfo = rp->info) != NULL)
	  {
	    if (rinfo->type == ZEBRA_ROUTE_RIP &&
		rinfo->sub_type == RIP_ROUTE_RTE)
	      rip_zebra_ipv4_delete ((struct prefix_ipv4 *)&rp->p,
				     &rinfo->nexthop, rinfo->metric);
	
	    RIP_TIMER_OFF (rinfo->t_timeout);
	    RIP_TIMER_OFF (rinfo->t_garbage_collect);

	    rp->info = NULL;
	    route_unlock_node (rp);

	    rip_info_free (rinfo);
	  }

      /* Cancel RIP related timers. */
      RIP_TIMER_OFF (rip->t_update);
      RIP_TIMER_OFF (rip->t_triggered_update);
      RIP_TIMER_OFF (rip->t_triggered_interval);

      /* Cancel read thread. */
      if (rip->t_read)
	{
	  thread_cancel (rip->t_read);
	  rip->t_read = NULL;
	}

      /* Close RIP socket. */
      if (rip->sock >= 0)
	{
	  close (rip->sock);
	  rip->sock = -1;
	}

      /* Static RIP route configuration. */
      for (rp = route_top (rip->route); rp; rp = route_next (rp))
	if (rp->info)
	  {
	    rp->info = NULL;
	    route_unlock_node (rp);
	  }

      /* RIP neighbor configuration. */
      for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
	if (rp->info)
	  {
	    rp->info = NULL;
	    route_unlock_node (rp);
	  }

      /* Redistribute related clear. */
      if (rip->default_information_route_map)
	free (rip->default_information_route_map);

      for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
	if (rip->route_map[i].name)
	  free (rip->route_map[i].name);

      XFREE (MTYPE_ROUTE_TABLE, rip->table);
      XFREE (MTYPE_ROUTE_TABLE, rip->route);
      XFREE (MTYPE_ROUTE_TABLE, rip->neighbor);
      
      XFREE (MTYPE_RIP, rip);
      rip = NULL;
    }

  rip_clean_network ();
  rip_passive_nondefault_clean ();
  rip_offset_clean ();
  rip_interface_clean ();
  rip_distance_reset ();
  rip_redistribute_clean ();
}

/* Reset all values to the default settings. */
void
rip_reset ()
{
  /* Reset global counters. */
  rip_global_route_changes = 0;
  rip_global_queries = 0;

  /* Call ripd related reset functions. */
  rip_debug_reset ();
  rip_route_map_reset ();

  /* Call library reset functions. */
  vty_reset ();
  access_list_reset ();
  prefix_list_reset ();

  distribute_list_reset ();

  rip_interface_reset ();
  rip_distance_reset ();

  rip_zclient_reset ();
}

void
rip_if_rmap_update (struct if_rmap *if_rmap)
{
  struct interface *ifp;
  struct rip_interface *ri;
  struct route_map *rmap;

  ifp = if_lookup_by_name (if_rmap->ifname);
  if (ifp == NULL)
    return;

  ri = ifp->info;

  if (if_rmap->routemap[IF_RMAP_IN])
    {
      rmap = route_map_lookup_by_name (if_rmap->routemap[IF_RMAP_IN]);
      if (rmap)
	ri->routemap[IF_RMAP_IN] = rmap;
      else
	ri->routemap[IF_RMAP_IN] = NULL;
    }
  else
    ri->routemap[RIP_FILTER_IN] = NULL;

  if (if_rmap->routemap[IF_RMAP_OUT])
    {
      rmap = route_map_lookup_by_name (if_rmap->routemap[IF_RMAP_OUT]);
      if (rmap)
	ri->routemap[IF_RMAP_OUT] = rmap;
      else
	ri->routemap[IF_RMAP_OUT] = NULL;
    }
  else
    ri->routemap[RIP_FILTER_OUT] = NULL;
}

void
rip_if_rmap_update_interface (struct interface *ifp)
{
  struct if_rmap *if_rmap;

  if_rmap = if_rmap_lookup (ifp->name);
  if (if_rmap)
    rip_if_rmap_update (if_rmap);
}

void
rip_routemap_update_redistribute (void)
{
  int i;

  if (rip)
    {
      for (i = 0; i < ZEBRA_ROUTE_MAX; i++) 
	{
	  if (rip->route_map[i].name)
	    rip->route_map[i].map = 
	      route_map_lookup_by_name (rip->route_map[i].name);
	}
    }
}

/* ARGSUSED */
void
rip_routemap_update (char *notused)
{
  struct interface *ifp;
  listnode node;

  for (node = listhead (iflist); node; nextnode (node))
    {
      ifp = getdata (node);
      rip_if_rmap_update_interface (ifp);
    }

  rip_routemap_update_redistribute ();
}

/* Allocate new rip structure and set default value. */
void
rip_init ()
{
  /* Randomize for triggered update random(). */
  srand (time (NULL));

  /* Install top nodes. */
  install_node (&rip_node, config_write_rip);

  /* Install rip commands. */
  install_element (VIEW_NODE, &show_ip_rip_cmd);
  install_element (VIEW_NODE, &show_ip_rip_status_cmd);
  install_element (ENABLE_NODE, &show_ip_rip_cmd);
  install_element (ENABLE_NODE, &show_ip_rip_status_cmd);
  install_element (CONFIG_NODE, &router_rip_cmd);
  install_element (CONFIG_NODE, &no_router_rip_cmd);

  install_default (RIP_NODE);
  install_element (RIP_NODE, &rip_version_cmd);
  install_element (RIP_NODE, &no_rip_version_cmd);
  install_element (RIP_NODE, &no_rip_version_val_cmd);
  install_element (RIP_NODE, &rip_default_metric_cmd);
  install_element (RIP_NODE, &no_rip_default_metric_cmd);
  install_element (RIP_NODE, &no_rip_default_metric_val_cmd);
  install_element (RIP_NODE, &rip_timers_cmd);
  install_element (RIP_NODE, &no_rip_timers_cmd);
  install_element (RIP_NODE, &no_rip_timers_val_cmd);
  install_element (RIP_NODE, &rip_route_cmd);
  install_element (RIP_NODE, &no_rip_route_cmd);
  install_element (RIP_NODE, &rip_distance_cmd);
  install_element (RIP_NODE, &no_rip_distance_cmd);
  install_element (RIP_NODE, &rip_distance_source_cmd);
  install_element (RIP_NODE, &no_rip_distance_source_cmd);
  install_element (RIP_NODE, &rip_distance_source_access_list_cmd);
  install_element (RIP_NODE, &no_rip_distance_source_access_list_cmd);

  /* Debug related init. */
  rip_debug_init ();

  /* SNMP init. */
#ifdef HAVE_SNMP
  rip_snmp_init ();
#endif /* HAVE_SNMP */

  /* Access list install. */
  access_list_init ();
  access_list_add_hook (rip_distribute_update_all_wrapper);
  access_list_delete_hook (rip_distribute_update_all_wrapper);

  /* Prefix list initialize.*/
  prefix_list_init ();
  prefix_list_add_hook (rip_distribute_update_all);
  prefix_list_delete_hook (rip_distribute_update_all);

  /* Distribute list install. */
  distribute_list_init (RIP_NODE);
  distribute_list_add_hook (rip_distribute_update);
  distribute_list_delete_hook (rip_distribute_update);

  /* Route-map */
  rip_route_map_init ();
  rip_offset_init ();

  route_map_add_hook (rip_routemap_update);
  route_map_delete_hook (rip_routemap_update);

  if_rmap_init (RIP_NODE);
  if_rmap_hook_add (rip_if_rmap_update);
  if_rmap_hook_delete (rip_if_rmap_update);

  /* Distance control. */
  rip_distance_table = route_table_init ();
}
