ripd.c
上传用户:xiaozhuqw
上传日期:2009-11-15
资源大小:1338k
文件大小:88k
源码类别:

网络

开发平台:

Unix_Linux

  1. /* RIP version 1 and 2.
  2.  * Copyright (C) 1997, 98, 99 Kunihiro Ishiguro <kunihiro@zebra.org>
  3.  *
  4.  * This file is part of GNU Zebra.
  5.  *
  6.  * GNU Zebra is free software; you can redistribute it and/or modify it
  7.  * under the terms of the GNU General Public License as published by the
  8.  * Free Software Foundation; either version 2, or (at your option) any
  9.  * later version.
  10.  *
  11.  * GNU Zebra is distributed in the hope that it will be useful, but
  12.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with GNU Zebra; see the file COPYING.  If not, write to the Free
  18.  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  19.  * 02111-1307, USA.  
  20.  */
  21. #include <zebra.h>
  22. #include "if.h"
  23. #include "command.h"
  24. #include "prefix.h"
  25. #include "table.h"
  26. #include "thread.h"
  27. #include "memory.h"
  28. #include "log.h"
  29. #include "stream.h"
  30. #include "filter.h"
  31. #include "sockunion.h"
  32. #include "routemap.h"
  33. #include "plist.h"
  34. #include "distribute.h"
  35. #include "md5-gnu.h"
  36. #include "keychain.h"
  37. #include "ripd/ripd.h"
  38. #include "ripd/rip_debug.h"
  39. /* RIP Structure. */
  40. struct rip *rip = NULL;
  41. /* RIP neighbor address table. */
  42. struct route_table *rip_neighbor_table;
  43. /* RIP route changes. */
  44. long rip_global_route_changes = 0;
  45. /* RIP queries. */
  46. long rip_global_queries = 0;
  47. /* Prototypes. */
  48. void rip_event (enum rip_event, int);
  49. void rip_output_process (struct interface *, struct sockaddr_in *, 
  50.  int, u_char);
  51. /* RIP output routes type. */
  52. enum
  53.   {
  54.     rip_all_route,
  55.     rip_changed_route
  56.   };
  57. /* RIP command strings. */
  58. struct message rip_msg[] = 
  59.   {
  60.     {RIP_REQUEST,    "REQUEST"},
  61.     {RIP_RESPONSE,   "RESPONSE"},
  62.     {RIP_TRACEON,    "TRACEON"},
  63.     {RIP_TRACEOFF,   "TRACEOFF"},
  64.     {RIP_POLL,       "POLL"},
  65.     {RIP_POLL_ENTRY, "POLL ENTRY"},
  66.     {0,              NULL}
  67.   };
  68. /* Each route type's strings and default preference. */
  69. struct
  70. {  
  71.   int key;
  72.   char *str;
  73.   char *str_long;
  74. } route_info[] =
  75.   {
  76.     { ZEBRA_ROUTE_SYSTEM,  "X", "system"},
  77.     { ZEBRA_ROUTE_KERNEL,  "K", "kernel"},
  78.     { ZEBRA_ROUTE_CONNECT, "C", "connected"},
  79.     { ZEBRA_ROUTE_STATIC,  "S", "static"},
  80.     { ZEBRA_ROUTE_RIP,     "R", "rip"},
  81.     { ZEBRA_ROUTE_RIPNG,   "R", "ripng"},
  82.     { ZEBRA_ROUTE_OSPF,    "O", "ospf"},
  83.     { ZEBRA_ROUTE_OSPF6,   "O", "ospf6"},
  84.     { ZEBRA_ROUTE_BGP,     "B", "bgp"}
  85.   };
  86. /* Utility function to set boradcast option to the socket.  */
  87. int
  88. sockopt_broadcast (int sock)
  89. {
  90.   int ret;
  91.   int on = 1;
  92.   ret = setsockopt (sock, SOL_SOCKET, SO_BROADCAST, (char *) &on, sizeof on);
  93.   if (ret < 0)
  94.     {
  95.       zlog_warn ("can't set sockopt SO_BROADCAST to socket %d: %s",
  96.  sock, strerror (errno));
  97.       return ret;
  98.     }
  99.   return 0;
  100. }
  101. /* Utility function to set size of UDP SO_RCVBUF.  */
  102. static int
  103. sockopt_recvbuf (int sock, int size)
  104. {
  105.   int ret;
  106.   
  107.   ret = setsockopt (sock, SOL_SOCKET, SO_RCVBUF, (char *) &size, sizeof (int));
  108.   if (ret < 0)
  109.     zlog_warn ("can't setsockopt SO_RCVBUF to socket %d: %s",
  110.        sock, strerror (errno));
  111.   return ret;
  112. }
  113. int
  114. rip_route_rte (struct rip_info *rinfo)
  115. {
  116.   return (rinfo->type == ZEBRA_ROUTE_RIP && rinfo->sub_type == RIP_ROUTE_RTE);
  117. }
  118. struct rip_info *
  119. rip_info_new ()
  120. {
  121.   struct rip_info *new;
  122.   new = XMALLOC (MTYPE_RIP_INFO, sizeof (struct rip_info));
  123.   memset (new, 0, sizeof (struct rip_info));
  124.   return new;
  125. }
  126. void
  127. rip_info_free (struct rip_info *rinfo)
  128. {
  129.   XFREE (MTYPE_RIP_INFO, rinfo);
  130. }
  131. /* RIP route garbage collect timer. */
  132. int
  133. rip_garbage_collect (struct thread *t)
  134. {
  135.   struct rip_info *rinfo;
  136.   struct route_node *rp;
  137.   rinfo = THREAD_ARG (t);
  138.   rinfo->t_garbage_collect = NULL;
  139.   /* Off timeout timer. */
  140.   RIP_TIMER_OFF (rinfo->t_timeout);
  141.   
  142.   /* Get route_node pointer. */
  143.   rp = rinfo->rp;
  144.   /* Unlock route_node. */
  145.   rp->info = NULL;
  146.   route_unlock_node (rp);
  147.   /* Free RIP routing information. */
  148.   rip_info_free (rinfo);
  149.   return 0;
  150. }
  151. /* Timeout RIP routes. */
  152. int
  153. rip_timeout (struct thread *t)
  154. {
  155.   struct rip_info *rinfo;
  156.   struct route_node *rn;
  157.   rinfo = THREAD_ARG (t);
  158.   rinfo->t_timeout = NULL;
  159.   rn = rinfo->rp;
  160.   /* - The garbage-collection timer is set for 120 seconds. */
  161.   RIP_TIMER_ON (rinfo->t_garbage_collect, rip_garbage_collect, 
  162. rip->garbage_time);
  163.   rip_zebra_ipv4_delete ((struct prefix_ipv4 *)&rn->p, &rinfo->nexthop,
  164.  rinfo->metric);
  165.   /* - The metric for the route is set to 16 (infinity).  This causes
  166.      the route to be removed from service. */
  167.   rinfo->metric = RIP_METRIC_INFINITY;
  168.   rinfo->flags &= ~RIP_RTF_FIB;
  169.   /* - The route change flag is to indicate that this entry has been
  170.      changed. */
  171.   rinfo->flags |= RIP_RTF_CHANGED;
  172.   /* - The output process is signalled to trigger a response. */
  173.   rip_event (RIP_TRIGGERED_UPDATE, 0);
  174.   return 0;
  175. }
  176. void
  177. rip_timeout_update (struct rip_info *rinfo)
  178. {
  179.   if (rinfo->metric != RIP_METRIC_INFINITY)
  180.     {
  181.       RIP_TIMER_OFF (rinfo->t_timeout);
  182.       RIP_TIMER_ON (rinfo->t_timeout, rip_timeout, rip->timeout_time);
  183.     }
  184. }
  185. int
  186. rip_incoming_filter (struct prefix_ipv4 *p, struct rip_interface *ri)
  187. {
  188.   struct distribute *dist;
  189.   struct access_list *alist;
  190.   struct prefix_list *plist;
  191.   /* Input distribute-list filtering. */
  192.   if (ri->list[RIP_FILTER_IN])
  193.     {
  194.       if (access_list_apply (ri->list[RIP_FILTER_IN], 
  195.      (struct prefix *) p) == FILTER_DENY)
  196. {
  197.   if (IS_RIP_DEBUG_PACKET)
  198.     zlog_info ("%s/%d filtered by distribute in",
  199.        inet_ntoa (p->prefix), p->prefixlen);
  200.   return -1;
  201. }
  202.     }
  203.   if (ri->prefix[RIP_FILTER_IN])
  204.     {
  205.       if (prefix_list_apply (ri->prefix[RIP_FILTER_IN], 
  206.      (struct prefix *) p) == PREFIX_DENY)
  207. {
  208.   if (IS_RIP_DEBUG_PACKET)
  209.     zlog_info ("%s/%d filtered by prefix-list in",
  210.        inet_ntoa (p->prefix), p->prefixlen);
  211.   return -1;
  212. }
  213.     }
  214.   /* All interface filter check. */
  215.   dist = distribute_lookup (NULL);
  216.   if (dist)
  217.     {
  218.       if (dist->list[DISTRIBUTE_IN])
  219. {
  220.   alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_IN]);
  221.     
  222.   if (alist)
  223.     {
  224.       if (access_list_apply (alist,
  225.      (struct prefix *) p) == FILTER_DENY)
  226. {
  227.   if (IS_RIP_DEBUG_PACKET)
  228.     zlog_info ("%s/%d filtered by distribute in",
  229.        inet_ntoa (p->prefix), p->prefixlen);
  230.   return -1;
  231. }
  232.     }
  233. }
  234.       if (dist->prefix[DISTRIBUTE_IN])
  235. {
  236.   plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_IN]);
  237.   
  238.   if (plist)
  239.     {
  240.       if (prefix_list_apply (plist,
  241.      (struct prefix *) p) == PREFIX_DENY)
  242. {
  243.   if (IS_RIP_DEBUG_PACKET)
  244.     zlog_info ("%s/%d filtered by prefix-list in",
  245.        inet_ntoa (p->prefix), p->prefixlen);
  246.   return -1;
  247. }
  248.     }
  249. }
  250.     }
  251.   return 0;
  252. }
  253. int
  254. rip_outgoing_filter (struct prefix_ipv4 *p, struct rip_interface *ri)
  255. {
  256.   struct distribute *dist;
  257.   struct access_list *alist;
  258.   struct prefix_list *plist;
  259.   if (ri->list[RIP_FILTER_OUT])
  260.     {
  261.       if (access_list_apply (ri->list[RIP_FILTER_OUT],
  262.      (struct prefix *) p) == FILTER_DENY)
  263. {
  264.   if (IS_RIP_DEBUG_PACKET)
  265.     zlog_info ("%s/%d is filtered by distribute out",
  266.        inet_ntoa (p->prefix), p->prefixlen);
  267.   return -1;
  268. }
  269.     }
  270.   if (ri->prefix[RIP_FILTER_OUT])
  271.     {
  272.       if (prefix_list_apply (ri->prefix[RIP_FILTER_OUT],
  273.      (struct prefix *) p) == PREFIX_DENY)
  274. {
  275.   if (IS_RIP_DEBUG_PACKET)
  276.     zlog_info ("%s/%d is filtered by prefix-list out",
  277.        inet_ntoa (p->prefix), p->prefixlen);
  278.   return -1;
  279. }
  280.     }
  281.   /* All interface filter check. */
  282.   dist = distribute_lookup (NULL);
  283.   if (dist)
  284.     {
  285.       if (dist->list[DISTRIBUTE_OUT])
  286. {
  287.   alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_OUT]);
  288.     
  289.   if (alist)
  290.     {
  291.       if (access_list_apply (alist,
  292.      (struct prefix *) p) == FILTER_DENY)
  293. {
  294.   if (IS_RIP_DEBUG_PACKET)
  295.     zlog_info ("%s/%d filtered by distribute out",
  296.        inet_ntoa (p->prefix), p->prefixlen);
  297.   return -1;
  298. }
  299.     }
  300. }
  301.       if (dist->prefix[DISTRIBUTE_OUT])
  302. {
  303.   plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_OUT]);
  304.   
  305.   if (plist)
  306.     {
  307.       if (prefix_list_apply (plist,
  308.      (struct prefix *) p) == PREFIX_DENY)
  309. {
  310.   if (IS_RIP_DEBUG_PACKET)
  311.     zlog_info ("%s/%d filtered by prefix-list out",
  312.        inet_ntoa (p->prefix), p->prefixlen);
  313.   return -1;
  314. }
  315.     }
  316. }
  317.     }
  318.   return 0;
  319. }
  320. /* Check nexthop address validity. */
  321. static int
  322. rip_nexthop_check (struct in_addr *addr)
  323. {
  324.   listnode node;
  325.   listnode cnode;
  326.   struct interface *ifp;
  327.   struct connected *ifc;
  328.   struct prefix *p;
  329.   /* If nexthop address matches local configured address then it is
  330.      invalid nexthop. */
  331.   for (node = listhead (iflist); node; nextnode (node))
  332.     {
  333.       ifp = getdata (node);
  334.       for (cnode = listhead (ifp->connected); cnode; nextnode (cnode))
  335. {     
  336.   ifc = getdata (cnode);
  337.   p = ifc->address;
  338.   if (p->family == AF_INET
  339.       && IPV4_ADDR_SAME (&p->u.prefix4, addr))
  340.     return -1;
  341. }
  342.     }
  343.   return 0;
  344. }
  345. /* RIP add route to routing table. */
  346. void
  347. rip_rte_process (struct rte *rte, struct sockaddr_in *from,
  348.  struct interface *ifp)
  349. {
  350.   int ret;
  351.   struct prefix_ipv4 p;
  352.   struct route_node *rp;
  353.   struct rip_info *rinfo;
  354.   struct rip_interface *ri;
  355.   struct in_addr *nexthop;
  356.   u_char oldmetric;
  357.   int same = 0;
  358.   /* Make prefix structure. */
  359.   memset (&p, 0, sizeof (struct prefix_ipv4));
  360.   p.family = AF_INET;
  361.   p.prefix = rte->prefix;
  362.   p.prefixlen = ip_masklen (rte->mask);
  363.   /* Make sure mask is applied. */
  364.   apply_mask_ipv4 (&p);
  365.   /* Apply input filters. */
  366.   ri = ifp->info;
  367.   ret = rip_incoming_filter (&p, ri);
  368.   if (ret < 0)
  369.     return;
  370.   /* Once the entry has been validated, update the metric by
  371.      adding the cost of the network on wich the message
  372.      arrived. If the result is greater than infinity, use infinity
  373.      (RFC2453 Sec. 3.9.2) */
  374.   /* Zebra ripd can handle offset-list in. */
  375.   ret = rip_offset_list_apply_in (&p, ifp, &rte->metric);
  376.   /* If offset-list does not modify the metric use interface's
  377.      metric. */
  378.   if (! ret)
  379.     rte->metric += ifp->metric;
  380.   if (rte->metric > RIP_METRIC_INFINITY)
  381.     rte->metric = RIP_METRIC_INFINITY;
  382.   /* Set nexthop pointer. */
  383.   if (rte->nexthop.s_addr == 0)
  384.     nexthop = &from->sin_addr;
  385.   else
  386.     nexthop = &rte->nexthop;
  387.   /* Check nexthop address. */
  388.   if (rip_nexthop_check (nexthop) < 0)
  389.     {
  390.       if (IS_RIP_DEBUG_PACKET)
  391. zlog_info ("Nexthop address %s is invalid", inet_ntoa (*nexthop));
  392.       return;
  393.     }
  394.   /* Get index for the prefix. */
  395.   rp = route_node_get (rip->table, (struct prefix *) &p);
  396.   /* Check to see whether there is already RIP route on the table. */
  397.   rinfo = rp->info;
  398.   if (rinfo)
  399.     {
  400.       /* Redistributed route check. */
  401.       if (rinfo->type != ZEBRA_ROUTE_RIP
  402.   && rinfo->metric != RIP_METRIC_INFINITY)
  403. return;
  404.       /* Local static route. */
  405.       if (rinfo->type == ZEBRA_ROUTE_RIP
  406.   && rinfo->sub_type == RIP_ROUTE_STATIC
  407.   && rinfo->metric != RIP_METRIC_INFINITY)
  408. return;
  409.     }
  410.   
  411.   if (! rinfo)
  412.     {
  413.       /* Now, check to see whether there is already an explicit route
  414.  for the destination prefix.  If there is no such route, add
  415.  this route to the routing table, unless the metric is
  416.  infinity (there is no point in adding a route which
  417.  unusable). */
  418.       if (rte->metric != RIP_METRIC_INFINITY)
  419. {
  420.   rinfo = rip_info_new ();
  421.   
  422.   /* - Setting the destination prefix and length to those in
  423.      the RTE. */
  424.   rinfo->rp = rp;
  425.   /* - Setting the metric to the newly calculated metric (as
  426.      described above). */
  427.   rinfo->metric = rte->metric;
  428.   rinfo->tag = ntohs (rte->tag);
  429.   /* - Set the next hop address to be the address of the router
  430.      from which the datagram came or the next hop address
  431.      specified by a next hop RTE. */
  432.   IPV4_ADDR_COPY (&rinfo->nexthop, nexthop);
  433.   IPV4_ADDR_COPY (&rinfo->from, &from->sin_addr);
  434.   rinfo->ifindex = ifp->ifindex;
  435.   /* - Initialize the timeout for the route.  If the
  436.      garbage-collection timer is running for this route, stop it
  437.      (see section 2.3 for a discussion of the timers). */
  438.   rip_timeout_update (rinfo);
  439.   /* - Set the route change flag. */
  440.   rinfo->flags |= RIP_RTF_CHANGED;
  441.   /* - Signal the output process to trigger an update (see section
  442.      2.5). */
  443.   rip_event (RIP_TRIGGERED_UPDATE, 0);
  444.   /* Finally, route goes into the kernel. */
  445.   rinfo->type = ZEBRA_ROUTE_RIP;
  446.   rinfo->sub_type = RIP_ROUTE_RTE;
  447.   /* Set distance value. */
  448.   rinfo->distance = rip_distance_apply (rinfo);
  449.   rp->info = rinfo;
  450.   rip_zebra_ipv4_add (&p, &rinfo->nexthop, rinfo->metric,
  451.       rinfo->distance);
  452.   rinfo->flags |= RIP_RTF_FIB;
  453. }
  454.     }
  455.   else
  456.     {
  457.       /* Route is there but we are not sure the route is RIP or not. */
  458.       rinfo = rp->info;
  459.   
  460.       /* If there is an existing route, compare the next hop address
  461.  to the address of the router from which the datagram came.
  462.  If this datagram is from the same router as the existing
  463.  route, reinitialize the timeout.  */
  464.       same = IPV4_ADDR_SAME (&rinfo->from, &from->sin_addr);
  465.       if (same)
  466. rip_timeout_update (rinfo);
  467.       /* Next, compare the metrics.  If the datagram is from the same
  468.  router as the existing route, and the new metric is different
  469.  than the old one; or, if the new metric is lower than the old
  470.  one; do the following actions: */
  471.       if ((same && (rinfo->metric != rte->metric
  472.     || rinfo->tag != rte->tag
  473.     || !IPV4_ADDR_SAME(&rte->nexthop, &rinfo->nexthop)))
  474.   || rte->metric < rinfo->metric)
  475. {
  476.   /* - Adopt the route from the datagram.  That is, put the
  477.      new metric in, and adjust the next hop address (if
  478.      necessary). */
  479.   oldmetric = rinfo->metric;
  480.   rinfo->metric = rte->metric;
  481.   rinfo->tag = ntohs (rte->tag);
  482.   IPV4_ADDR_COPY (&rinfo->from, &from->sin_addr);
  483.   rinfo->ifindex = ifp->ifindex;
  484.   rinfo->distance = rip_distance_apply (rinfo);
  485.   /* Should a new route to this network be established
  486.      while the garbage-collection timer is running, the
  487.      new route will replace the one that is about to be
  488.      deleted.  In this case the garbage-collection timer
  489.      must be cleared. */
  490.   if (oldmetric == RIP_METRIC_INFINITY &&
  491.       rinfo->metric < RIP_METRIC_INFINITY)
  492.     {
  493.       rinfo->type = ZEBRA_ROUTE_RIP;
  494.       rinfo->sub_type = RIP_ROUTE_RTE;
  495.       RIP_TIMER_OFF (rinfo->t_garbage_collect);
  496.       if (! IPV4_ADDR_SAME (&rinfo->nexthop, nexthop))
  497. IPV4_ADDR_COPY (&rinfo->nexthop, nexthop);
  498.       rip_zebra_ipv4_add (&p, nexthop, rinfo->metric,
  499.   rinfo->distance);
  500.       rinfo->flags |= RIP_RTF_FIB;
  501.     }
  502.   /* Update nexthop and/or metric value.  */
  503.   if (oldmetric != RIP_METRIC_INFINITY)
  504.     {
  505.       rip_zebra_ipv4_delete (&p, &rinfo->nexthop, oldmetric);
  506.       rip_zebra_ipv4_add (&p, nexthop, rinfo->metric,
  507.   rinfo->distance);
  508.       rinfo->flags |= RIP_RTF_FIB;
  509.       if (! IPV4_ADDR_SAME (&rinfo->nexthop, nexthop))
  510. IPV4_ADDR_COPY (&rinfo->nexthop, nexthop);
  511.     }
  512.   /* - Set the route change flag and signal the output process
  513.      to trigger an update. */
  514.   rinfo->flags |= RIP_RTF_CHANGED;
  515.   rip_event (RIP_TRIGGERED_UPDATE, 0);
  516.   /* - If the new metric is infinity, start the deletion
  517.      process (described above); */
  518.   if (rinfo->metric == RIP_METRIC_INFINITY)
  519.     {
  520.       /* If the new metric is infinity, the deletion process
  521.  begins for the route, which is no longer used for
  522.  routing packets.  Note that the deletion process is
  523.  started only when the metric is first set to
  524.  infinity.  If the metric was already infinity, then a
  525.  new deletion process is not started. */
  526.       if (oldmetric != RIP_METRIC_INFINITY)
  527. {
  528.   /* - The garbage-collection timer is set for 120 seconds. */
  529.   RIP_TIMER_ON (rinfo->t_garbage_collect, 
  530. rip_garbage_collect, rip->garbage_time);
  531.   RIP_TIMER_OFF (rinfo->t_timeout);
  532.   /* - The metric for the route is set to 16
  533.      (infinity).  This causes the route to be removed
  534.      from service.*/
  535.   rip_zebra_ipv4_delete (&p, &rinfo->nexthop, oldmetric);
  536.   rinfo->flags &= ~RIP_RTF_FIB;
  537.   /* - The route change flag is to indicate that this
  538.      entry has been changed. */
  539.   /* - The output process is signalled to trigger a
  540.                      response. */
  541.   ;  /* Above processes are already done previously. */
  542. }
  543.     }
  544.   else
  545.     {
  546.       /* otherwise, re-initialize the timeout. */
  547.       rip_timeout_update (rinfo);
  548.     }
  549. }
  550.       /* Unlock tempolary lock of the route. */
  551.       route_unlock_node (rp);
  552.     }
  553. }
  554. /* Dump RIP packet */
  555. void
  556. rip_packet_dump (struct rip_packet *packet, int size, char *sndrcv)
  557. {
  558.   caddr_t lim;
  559.   struct rte *rte;
  560.   char *command_str;
  561.   char pbuf[BUFSIZ], nbuf[BUFSIZ];
  562.   u_char netmask = 0;
  563.   u_char *p;
  564.   /* Set command string. */
  565.   if (packet->command > 0 && packet->command < RIP_COMMAND_MAX)
  566.     command_str = lookup (rip_msg, packet->command);
  567.   else
  568.     command_str = "unknown";
  569.   /* Dump packet header. */
  570.   zlog_info ("%s %s version %d packet size %d",
  571.      sndrcv, command_str, packet->version, size);
  572.   /* Dump each routing table entry. */
  573.   rte = packet->rte;
  574.   
  575.   for (lim = (caddr_t) packet + size; (caddr_t) rte < lim; rte++)
  576.     {
  577.       if (packet->version == RIPv2)
  578. {
  579.   netmask = ip_masklen (rte->mask);
  580.   if (ntohs (rte->family) == 0xffff)
  581.             {
  582.       if (ntohs (rte->tag) == RIP_AUTH_SIMPLE_PASSWORD)
  583. {
  584.   p = (u_char *)&rte->prefix;
  585.   zlog_info ("  family 0x%X type %d auth string: %s",
  586.      ntohs (rte->family), ntohs (rte->tag), p);
  587. }
  588.       else if (ntohs (rte->tag) == RIP_AUTH_MD5)
  589. {
  590.   struct rip_md5_info *md5;
  591.   md5 = (struct rip_md5_info *) &packet->rte;
  592.   zlog_info ("  family 0x%X type %d (MD5 authentication)",
  593.      ntohs (md5->family), ntohs (md5->type));
  594.   zlog_info ("    RIP-2 packet len %d Key ID %d"
  595.      " Auth Data len %d", ntohs (md5->packet_len),
  596.      md5->keyid, md5->auth_len);
  597.   zlog_info ("    Sequence Number %ld", (u_long)ntohl (md5->sequence));
  598. }
  599.       else if (ntohs (rte->tag) == RIP_AUTH_DATA)
  600. {
  601.   p = (u_char *)&rte->prefix;
  602.   zlog_info ("  family 0x%X type %d (MD5 data)",
  603.      ntohs (rte->family), ntohs (rte->tag));
  604.   zlog_info ("    MD5: %02X%02X%02X%02X%02X%02X%02X%02X"
  605.      "%02X%02X%02X%02X%02X%02X%02X",
  606.      p[0],p[1],p[2],p[3],p[4],p[5],p[6],p[7],
  607.      p[9],p[10],p[11],p[12],p[13],p[14],p[15]);
  608. }
  609.       else
  610. {
  611.   zlog_info ("  family 0x%X type %d (Unknown auth type)",
  612.      ntohs (rte->family), ntohs (rte->tag));
  613. }
  614.             }
  615.   else
  616.     zlog_info ("  %s/%d -> %s family %d tag %d metric %ld",
  617.        inet_ntop (AF_INET, &rte->prefix, pbuf, BUFSIZ),netmask,
  618.        inet_ntop (AF_INET, &rte->nexthop, nbuf, BUFSIZ),
  619.        ntohs (rte->family), ntohs (rte->tag), 
  620.        (u_long)ntohl (rte->metric));
  621. }
  622.       else
  623. {
  624.   zlog_info ("  %s family %d tag %d metric %ld", 
  625.      inet_ntop (AF_INET, &rte->prefix, pbuf, BUFSIZ),
  626.      ntohs (rte->family), ntohs (rte->tag),
  627.      (u_long)ntohl (rte->metric));
  628. }
  629.     }
  630. }
  631. /* Check if the destination address is valid (unicast; not net 0
  632.    or 127) (RFC2453 Section 3.9.2 - Page 26).  But we don't
  633.    check net 0 because we accept default route. */
  634. int
  635. rip_destination_check (struct in_addr addr)
  636. {
  637.   u_int32_t destination;
  638.   /* Convert to host byte order. */
  639.   destination = ntohl (addr.s_addr);
  640.   if (IPV4_NET127 (destination))
  641.     return 0;
  642.   /* Net 0 may match to the default route. */
  643.   if (IPV4_NET0 (destination) && destination != 0)
  644.     return 0;
  645.   /* Unicast address must belong to class A, B, C. */
  646.   if (IN_CLASSA (destination))
  647.     return 1;
  648.   if (IN_CLASSB (destination))
  649.     return 1;
  650.   if (IN_CLASSC (destination))
  651.     return 1;
  652.   return 0;
  653. }
  654. /* RIP version 2 authentication. */
  655. int
  656. rip_auth_simple_password (struct rte *rte, struct sockaddr_in *from,
  657.   struct interface *ifp)
  658. {
  659.   struct rip_interface *ri;
  660.   char *auth_str;
  661.   if (IS_RIP_DEBUG_EVENT)
  662.     zlog_info ("RIPv2 simple password authentication from %s",
  663.        inet_ntoa (from->sin_addr));
  664.   ri = ifp->info;
  665.   if (ri->auth_type != RIP_AUTH_SIMPLE_PASSWORD
  666.       || ntohs (rte->tag) != RIP_AUTH_SIMPLE_PASSWORD)
  667.     return 0;
  668.   /* Simple password authentication. */
  669.   if (ri->auth_str)
  670.     {
  671.       auth_str = (char *) &rte->prefix;
  672.   
  673.       if (strncmp (auth_str, ri->auth_str, 16) == 0)
  674. return 1;
  675.     }
  676.   if (ri->key_chain)
  677.     {
  678.       struct keychain *keychain;
  679.       struct key *key;
  680.       keychain = keychain_lookup (ri->key_chain);
  681.       if (keychain == NULL)
  682. return 0;
  683.       key = key_match_for_accept (keychain, (char *) &rte->prefix);
  684.       if (key)
  685. return 1;
  686.     }
  687.   return 0;
  688. }
  689. /* RIP version 2 authentication with MD5. */
  690. int
  691. rip_auth_md5 (struct rip_packet *packet, struct sockaddr_in *from,
  692.       struct interface *ifp)
  693. {
  694.   struct rip_interface *ri;
  695.   struct rip_md5_info *md5;
  696.   struct rip_md5_data *md5data;
  697.   struct keychain *keychain;
  698.   struct key *key;
  699.   struct md5_ctx ctx;
  700.   u_char pdigest[RIP_AUTH_MD5_SIZE];
  701.   u_char digest[RIP_AUTH_MD5_SIZE];
  702.   u_int16_t packet_len;
  703.   char *auth_str = NULL;
  704.   
  705.   if (IS_RIP_DEBUG_EVENT)
  706.     zlog_info ("RIPv2 MD5 authentication from %s", inet_ntoa (from->sin_addr));
  707.   ri = ifp->info;
  708.   md5 = (struct rip_md5_info *) &packet->rte;
  709.   /* Check auth type. */
  710.   if (ri->auth_type != RIP_AUTH_MD5 || ntohs (md5->type) != RIP_AUTH_MD5)
  711.     return 0;
  712.   if (md5->auth_len != RIP_HEADER_SIZE + RIP_AUTH_MD5_SIZE)
  713.     return 0;
  714.   if (ri->key_chain)
  715.     {
  716.       keychain = keychain_lookup (ri->key_chain);
  717.       if (keychain == NULL)
  718. return 0;
  719.       key = key_lookup_for_accept (keychain, md5->keyid);
  720.       if (key == NULL)
  721. return 0;
  722.       auth_str = key->string;
  723.     }
  724.   if (ri->auth_str)
  725.     auth_str = ri->auth_str;
  726.   if (! auth_str)
  727.     return 0;
  728.   /* MD5 digest authentication. */
  729.   packet_len = ntohs (md5->packet_len);
  730.   md5data = (struct rip_md5_data *)(((u_char *) packet) + packet_len);
  731.   /* Save digest to pdigest. */
  732.   memcpy (pdigest, md5data->digest, RIP_AUTH_MD5_SIZE);
  733.   /* Overwrite digest by my secret. */
  734.   memset (md5data->digest, 0, RIP_AUTH_MD5_SIZE);
  735.   strncpy (md5data->digest, auth_str, RIP_AUTH_MD5_SIZE);
  736.   md5_init_ctx (&ctx);
  737.   md5_process_bytes (packet, packet_len + md5->auth_len, &ctx);
  738.   md5_finish_ctx (&ctx, digest);
  739.   if (memcmp (pdigest, digest, RIP_AUTH_MD5_SIZE) == 0)
  740.     return packet_len;
  741.   else
  742.     return 0;
  743. }
  744. void
  745. rip_auth_md5_set (struct stream *s, struct interface *ifp)
  746. {
  747.   struct rip_interface *ri;
  748.   struct keychain *keychain = NULL;
  749.   struct key *key = NULL;
  750.   unsigned long len;
  751.   struct md5_ctx ctx;
  752.   unsigned char secret[RIP_AUTH_MD5_SIZE];
  753.   unsigned char digest[RIP_AUTH_MD5_SIZE];
  754.   char *auth_str = NULL;
  755.   ri = ifp->info;
  756.   /* Make it sure this interface is configured as MD5
  757.      authentication. */
  758.   if (ri->auth_type != RIP_AUTH_MD5)
  759.     return;
  760.   /* Lookup key chain. */
  761.   if (ri->key_chain)
  762.     {
  763.       keychain = keychain_lookup (ri->key_chain);
  764.       if (keychain == NULL)
  765. return;
  766.       /* Lookup key. */
  767.       key = key_lookup_for_send (keychain);
  768.       if (key == NULL)
  769. return;
  770.       auth_str = key->string;
  771.     }
  772.   if (ri->auth_str)
  773.     auth_str = ri->auth_str;
  774.   if (! auth_str)
  775.     return;
  776.   /* Get packet length. */
  777.   len = s->putp;
  778.   /* Check packet length. */
  779.   if (len < (RIP_HEADER_SIZE + RIP_RTE_SIZE))
  780.     {
  781.       zlog_err ("rip_auth_md5_set(): packet length %ld is less than minimum length.", len);
  782.       return;
  783.     }
  784.   /* Move RTE. */
  785.   memmove (s->data + RIP_HEADER_SIZE + RIP_RTE_SIZE,
  786.    s->data + RIP_HEADER_SIZE,
  787.    len - RIP_HEADER_SIZE);
  788.   
  789.   /* Set pointer to authentication header. */
  790.   stream_set_putp (s, RIP_HEADER_SIZE);
  791.   len += RIP_RTE_SIZE;
  792.   /* MD5 authentication. */
  793.   stream_putw (s, 0xffff);
  794.   stream_putw (s, RIP_AUTH_MD5);
  795.   /* RIP-2 Packet length.  Actual value is filled in
  796.      rip_auth_md5_set(). */
  797.   stream_putw (s, len);
  798.   /* Key ID. */
  799.   if (key)
  800.     stream_putc (s, key->index % 256);
  801.   else
  802.     stream_putc (s, 1);
  803.   /* Auth Data Len.  Set 16 for MD5 authentication
  804.      data. */
  805.   stream_putc (s, RIP_AUTH_MD5_SIZE + RIP_HEADER_SIZE);
  806.   /* Sequence Number (non-decreasing). */
  807.   /* RFC2080: The value used in the sequence number is
  808.      arbitrary, but two suggestions are the time of the
  809.      message's creation or a simple message counter. */
  810.   stream_putl (s, time (NULL));
  811.       
  812.   /* Reserved field must be zero. */
  813.   stream_putl (s, 0);
  814.   stream_putl (s, 0);
  815.   /* Set pointer to authentication data. */
  816.   stream_set_putp (s, len);
  817.   /* Set authentication data. */
  818.   stream_putw (s, 0xffff);
  819.   stream_putw (s, 0x01);
  820.   /* Generate a digest for the RIP packet. */
  821.   memset (secret, 0, RIP_AUTH_MD5_SIZE);
  822.   strncpy (secret, auth_str, RIP_AUTH_MD5_SIZE);
  823.   md5_init_ctx (&ctx);
  824.   md5_process_bytes (s->data, s->endp, &ctx);
  825.   md5_process_bytes (secret, RIP_AUTH_MD5_SIZE, &ctx);
  826.   md5_finish_ctx (&ctx, digest);
  827.   /* Copy the digest to the packet. */
  828.   stream_write (s, digest, RIP_AUTH_MD5_SIZE);
  829. }
  830. /* RIP routing information. */
  831. void
  832. rip_response_process (struct rip_packet *packet, int size, 
  833.       struct sockaddr_in *from, struct interface *ifp)
  834. {
  835.   caddr_t lim;
  836.   struct rte *rte;
  837.       
  838.   /* The Response must be ignored if it is not from the RIP
  839.      port. (RFC2453 - Sec. 3.9.2)*/
  840.   if (ntohs (from->sin_port) != RIP_PORT_DEFAULT) 
  841.     {
  842.       zlog_info ("response doesn't come from RIP port: %d",
  843.  from->sin_port);
  844.       rip_peer_bad_packet (from);
  845.       return;
  846.     }
  847.   /* The datagram's IPv4 source address should be checked to see
  848.      whether the datagram is from a valid neighbor; the source of the
  849.      datagram must be on a directly connected network  */
  850.   if (! if_valid_neighbor (from->sin_addr)) 
  851.     {
  852.       zlog_info ("This datagram doesn't came from a valid neighbor: %s",
  853.  inet_ntoa (from->sin_addr));
  854.       rip_peer_bad_packet (from);
  855.       return;
  856.     }
  857.   /* It is also worth checking to see whether the response is from one
  858.      of the router's own addresses. */
  859.   ; /* Alredy done in rip_read () */
  860.   /* Update RIP peer. */
  861.   rip_peer_update (from, packet->version);
  862.   /* Set RTE pointer. */
  863.   rte = packet->rte;
  864.   for (lim = (caddr_t) packet + size; (caddr_t) rte < lim; rte++)
  865.     {
  866.       /* RIPv2 authentication check. */
  867.       /* If the Address Family Identifier of the first (and only the
  868.  first) entry in the message is 0xFFFF, then the remainder of
  869.  the entry contains the authentication. */
  870.       /* If the packet gets here it means authentication enabled */
  871.       /* Check is done in rip_read(). So, just skipping it */
  872.       if (packet->version == RIPv2 &&
  873.   rte == packet->rte &&
  874.   rte->family == 0xffff)
  875. continue;
  876.       if (ntohs (rte->family) != AF_INET)
  877. {
  878.   /* Address family check.  RIP only supports AF_INET. */
  879.   zlog_info ("Unsupported family %d from %s.",
  880.      ntohs (rte->family), inet_ntoa (from->sin_addr));
  881.   continue;
  882. }
  883.       /* - is the destination address valid (e.g., unicast; not net 0
  884.          or 127) */
  885.       if (! rip_destination_check (rte->prefix))
  886.         {
  887.   zlog_info ("Network is net 0 or net 127 or it is not unicast network");
  888.   rip_peer_bad_route (from);
  889.   continue;
  890.       /* Convert metric value to host byte order. */
  891.       rte->metric = ntohl (rte->metric);
  892.       /* - is the metric valid (i.e., between 1 and 16, inclusive) */
  893.       if (! (rte->metric >= 1 && rte->metric <= 16))
  894. {
  895.   zlog_info ("Route's metric is not in the 1-16 range.");
  896.   rip_peer_bad_route (from);
  897.   continue;
  898. }
  899.       /* RIPv1 does not have nexthop value. */
  900.       if (packet->version == RIPv1 && rte->nexthop.s_addr != 0)
  901. {
  902.   zlog_info ("RIPv1 packet with nexthop value %s",
  903.      inet_ntoa (rte->nexthop));
  904.   rip_peer_bad_route (from);
  905.   continue;
  906. }
  907.       /* That is, if the provided information is ignored, a possibly
  908.  sub-optimal, but absolutely valid, route may be taken.  If
  909.  the received Next Hop is not directly reachable, it should be
  910.  treated as 0.0.0.0. */
  911.       if (packet->version == RIPv2 && rte->nexthop.s_addr != 0)
  912. {
  913.   u_int32_t addrval;
  914.   /* Multicast address check. */
  915.   addrval = ntohl (rte->nexthop.s_addr);
  916.   if (IN_CLASSD (addrval))
  917.     {
  918.       zlog_info ("Nexthop %s is multicast address, skip this rte",
  919.  inet_ntoa (rte->nexthop));
  920.       continue;
  921.     }
  922.   if (! if_lookup_address (rte->nexthop))
  923.     {
  924.       struct route_node *rn;
  925.       struct rip_info *rinfo;
  926.       rn = route_node_match_ipv4 (rip->table, &rte->nexthop);
  927.       if (rn)
  928. {
  929.   rinfo = rn->info;
  930.   if (rinfo->type == ZEBRA_ROUTE_RIP
  931.       && rinfo->sub_type == RIP_ROUTE_RTE)
  932.     {
  933.       if (IS_RIP_DEBUG_EVENT)
  934. zlog_info ("Next hop %s is on RIP network.  Set nexthop to the packet's originator", inet_ntoa (rte->nexthop));
  935.       rte->nexthop = rinfo->from;
  936.     }
  937.   else
  938.     {
  939.       if (IS_RIP_DEBUG_EVENT)
  940. zlog_info ("Next hop %s is not directly reachable. Treat it as 0.0.0.0", inet_ntoa (rte->nexthop));
  941.       rte->nexthop.s_addr = 0;
  942.     }
  943.   route_unlock_node (rn);
  944. }
  945.       else
  946. {
  947.   if (IS_RIP_DEBUG_EVENT)
  948.     zlog_info ("Next hop %s is not directly reachable. Treat it as 0.0.0.0", inet_ntoa (rte->nexthop));
  949.   rte->nexthop.s_addr = 0;
  950. }
  951.     }
  952. }
  953.       /* For RIPv1, there won't be a valid netmask.  
  954.       This is a best guess at the masks.  If everyone was using old
  955.       Ciscos before the 'ip subnet zero' option, it would be almost
  956.       right too :-)
  957.       
  958.       Cisco summarize ripv1 advertisments to the classful boundary
  959.       (/16 for class B's) except when the RIP packet does to inside
  960.       the classful network in question.  */
  961.       if ((packet->version == RIPv1 && rte->prefix.s_addr != 0) 
  962.   || (packet->version == RIPv2 
  963.       && (rte->prefix.s_addr != 0 && rte->mask.s_addr == 0)))
  964. {
  965.   u_int32_t destination;
  966.   destination = ntohl (rte->prefix.s_addr);
  967.   if (destination & 0xff) 
  968.     {
  969.       masklen2ip (32, &rte->mask);
  970.     }
  971.   else if ((destination & 0xff00) || IN_CLASSC (destination)) 
  972.     {
  973.       masklen2ip (24, &rte->mask);
  974.     }
  975.   else if ((destination & 0xff0000) || IN_CLASSB (destination)) 
  976.     {
  977.       masklen2ip (16, &rte->mask);
  978.     }
  979.   else 
  980.     {
  981.       masklen2ip (8, &rte->mask);
  982.     }
  983. }
  984.       /* In case of RIPv2, if prefix in RTE is not netmask applied one
  985.          ignore the entry.  */
  986.       if ((packet->version == RIPv2) 
  987.   && (rte->mask.s_addr != 0) 
  988.   && ((rte->prefix.s_addr & rte->mask.s_addr) != rte->prefix.s_addr))
  989. {
  990.   zlog_warn ("RIPv2 address %s is not mask /%d applied one",
  991.      inet_ntoa (rte->prefix), ip_masklen (rte->mask));
  992.   rip_peer_bad_route (from);
  993.   continue;
  994. }
  995.       /* Default route's netmask is ignored. */
  996.       if (packet->version == RIPv2
  997.   && (rte->prefix.s_addr == 0)
  998.   && (rte->mask.s_addr != 0))
  999. {
  1000.   if (IS_RIP_DEBUG_EVENT)
  1001.     zlog_info ("Default route with non-zero netmask.  Set zero to netmask");
  1002.   rte->mask.s_addr = 0;
  1003. }
  1004.   
  1005.       /* Routing table updates. */
  1006.       rip_rte_process (rte, from, ifp);
  1007.     }
  1008. }
  1009. /* RIP packet send to destination address. */
  1010. int
  1011. rip_send_packet (caddr_t buf, int size, struct sockaddr_in *to, 
  1012.  struct interface *ifp)
  1013. {
  1014.   int ret;
  1015.   struct sockaddr_in sin;
  1016.   int sock;
  1017.   /* Make destination address. */
  1018.   memset (&sin, 0, sizeof (struct sockaddr_in));
  1019.   sin.sin_family = AF_INET;
  1020. #ifdef HAVE_SIN_LEN
  1021.   sin.sin_len = sizeof (struct sockaddr_in);
  1022. #endif /* HAVE_SIN_LEN */
  1023.   /* When destination is specified, use it's port and address. */
  1024.   if (to)
  1025.     {
  1026.       sock = rip->sock;
  1027.       sin.sin_port = to->sin_port;
  1028.       sin.sin_addr = to->sin_addr;
  1029.     }
  1030.   else
  1031.     {
  1032.       sock = socket (AF_INET, SOCK_DGRAM, 0);
  1033.       
  1034.       sockopt_broadcast (sock);
  1035.       sockopt_reuseaddr (sock);
  1036.       sockopt_reuseport (sock);
  1037.       sin.sin_port = htons (RIP_PORT_DEFAULT);
  1038.       sin.sin_addr.s_addr = htonl (INADDR_RIP_GROUP);
  1039.       /* Set multicast interface. */
  1040.       rip_interface_multicast_set (sock, ifp);
  1041.     }
  1042.   ret = sendto (sock, buf, size, 0, (struct sockaddr *)&sin,
  1043. sizeof (struct sockaddr_in));
  1044.   if (IS_RIP_DEBUG_EVENT)
  1045.     zlog_info ("SEND to socket %d port %d addr %s",
  1046.        sock, ntohs (sin.sin_port), inet_ntoa(sin.sin_addr));
  1047.   if (ret < 0)
  1048.     zlog_warn ("can't send packet : %s", strerror (errno));
  1049.   if (! to)
  1050.     close (sock);
  1051.   return ret;
  1052. }
  1053. /* Add redistributed route to RIP table. */
  1054. void
  1055. rip_redistribute_add (int type, int sub_type, struct prefix_ipv4 *p, 
  1056.       unsigned int ifindex, struct in_addr *nexthop)
  1057. {
  1058.   int ret;
  1059.   struct route_node *rp;
  1060.   struct rip_info *rinfo;
  1061.   /* Redistribute route  */
  1062.   ret = rip_destination_check (p->prefix);
  1063.   if (! ret)
  1064.     return;
  1065.   rp = route_node_get (rip->table, (struct prefix *) p);
  1066.   rinfo = rp->info;
  1067.   if (rinfo)
  1068.     {
  1069.       if (rinfo->type == ZEBRA_ROUTE_CONNECT 
  1070.   && rinfo->sub_type == RIP_ROUTE_INTERFACE
  1071.   && rinfo->metric != RIP_METRIC_INFINITY)
  1072. {
  1073.   route_unlock_node (rp);
  1074.   return;
  1075. }
  1076.       /* Manually configured RIP route check. */
  1077.       if (rinfo->type == ZEBRA_ROUTE_RIP 
  1078.   && rinfo->sub_type == RIP_ROUTE_STATIC)
  1079. {
  1080.   if (type != ZEBRA_ROUTE_RIP || sub_type != RIP_ROUTE_STATIC)
  1081.     {
  1082.       route_unlock_node (rp);
  1083.       return;
  1084.     }
  1085. }
  1086.       RIP_TIMER_OFF (rinfo->t_timeout);
  1087.       RIP_TIMER_OFF (rinfo->t_garbage_collect);
  1088.       if (rip_route_rte (rinfo))
  1089. rip_zebra_ipv4_delete ((struct prefix_ipv4 *)&rp->p, &rinfo->nexthop,
  1090.        rinfo->metric);
  1091.       rp->info = NULL;
  1092.       rip_info_free (rinfo);
  1093.       
  1094.       route_unlock_node (rp);      
  1095.     }
  1096.   rinfo = rip_info_new ();
  1097.     
  1098.   rinfo->type = type;
  1099.   rinfo->sub_type = sub_type;
  1100.   rinfo->ifindex = ifindex;
  1101.   rinfo->metric = 1;
  1102.   rinfo->rp = rp;
  1103.   if (nexthop)
  1104.     rinfo->nexthop = *nexthop;
  1105.   rinfo->flags |= RIP_RTF_FIB;
  1106.   rp->info = rinfo;
  1107.   rinfo->flags |= RIP_RTF_CHANGED;
  1108.   rip_event (RIP_TRIGGERED_UPDATE, 0);
  1109. }
  1110. /* Delete redistributed route from RIP table. */
  1111. void
  1112. rip_redistribute_delete (int type, int sub_type, struct prefix_ipv4 *p, 
  1113.  unsigned int ifindex)
  1114. {
  1115.   int ret;
  1116.   struct route_node *rp;
  1117.   struct rip_info *rinfo;
  1118.   ret = rip_destination_check (p->prefix);
  1119.   if (! ret)
  1120.     return;
  1121.   rp = route_node_lookup (rip->table, (struct prefix *) p);
  1122.   if (rp)
  1123.     {
  1124.       rinfo = rp->info;
  1125.       if (rinfo != NULL
  1126.   && rinfo->type == type 
  1127.   && rinfo->sub_type == sub_type 
  1128.   && rinfo->ifindex == ifindex)
  1129. {
  1130.   /* Perform poisoned reverse. */
  1131.   rinfo->metric = RIP_METRIC_INFINITY;
  1132.   RIP_TIMER_ON (rinfo->t_garbage_collect, 
  1133. rip_garbage_collect, rip->garbage_time);
  1134.   RIP_TIMER_OFF (rinfo->t_timeout);
  1135.   rinfo->flags |= RIP_RTF_CHANGED;
  1136.   rip_event (RIP_TRIGGERED_UPDATE, 0);
  1137. }
  1138.     }
  1139. }
  1140. /* Response to request called from rip_read ().*/
  1141. void
  1142. rip_request_process (struct rip_packet *packet, int size, 
  1143.      struct sockaddr_in *from, struct interface *ifp)
  1144. {
  1145.   caddr_t lim;
  1146.   struct rte *rte;
  1147.   struct prefix_ipv4 p;
  1148.   struct route_node *rp;
  1149.   struct rip_info *rinfo;
  1150.   struct rip_interface *ri;
  1151.   ri = ifp->info;
  1152.   /* When passive interface is specified, suppress responses */
  1153.   if (ri->passive)
  1154.     return;
  1155.   /* RIP peer update. */
  1156.   rip_peer_update (from, packet->version);
  1157.   lim = ((caddr_t) packet) + size;
  1158.   rte = packet->rte;
  1159.   /* The Request is processed entry by entry.  If there are no
  1160.      entries, no response is given. */
  1161.   if (lim == (caddr_t) rte)
  1162.     return;
  1163.   /* There is one special case.  If there is exactly one entry in the
  1164.      request, and it has an address family identifier of zero and a
  1165.      metric of infinity (i.e., 16), then this is a request to send the
  1166.      entire routing table. */
  1167.   if ((rte->family == 0xFFFF) && (lim == ((caddr_t) (rte + 2)) )) rte++;
  1168.   
  1169.   if (lim == ((caddr_t) (rte + 1)) &&
  1170.       ntohs (rte->family) == 0 &&
  1171.       ntohl (rte->metric) == RIP_METRIC_INFINITY)
  1172.     {
  1173.       /* All route with split horizon */
  1174.       rip_output_process (ifp, from, rip_all_route, packet->version);
  1175.     }
  1176.   else
  1177.     {
  1178.       /* Examine the list of RTEs in the Request one by one.  For each
  1179.  entry, look up the destination in the router's routing
  1180.  database and, if there is a route, put that route's metric in
  1181.  the metric field of the RTE.  If there is no explicit route
  1182.  to the specified destination, put infinity in the metric
  1183.  field.  Once all the entries have been filled in, change the
  1184.  command from Request to Response and send the datagram back
  1185.  to the requestor. */
  1186.       p.family = AF_INET;
  1187.       for (; ((caddr_t) rte) < lim; rte++)
  1188. {
  1189.   p.prefix = rte->prefix;
  1190.   p.prefixlen = ip_masklen (rte->mask);
  1191.   apply_mask_ipv4 (&p);
  1192.   
  1193.   rp = route_node_lookup (rip->table, (struct prefix *) &p);
  1194.   if (rp)
  1195.     {
  1196.       rinfo = rp->info;
  1197.       rte->metric = htonl (rinfo->metric);
  1198.       route_unlock_node (rp);
  1199.     }
  1200.   else
  1201.     rte->metric = htonl (RIP_METRIC_INFINITY);
  1202. }
  1203.       packet->command = RIP_RESPONSE;
  1204.       rip_send_packet ((caddr_t) packet, size, from, ifp);
  1205.     }
  1206.   rip_global_queries++;
  1207. }
  1208. #if RIP_RECVMSG
  1209. /* Set IPv6 packet info to the socket. */
  1210. static int
  1211. setsockopt_pktinfo (int sock)
  1212. {
  1213.   int ret;
  1214.   int val = 1;
  1215.     
  1216.   ret = setsockopt(sock, IPPROTO_IP, IP_PKTINFO, &val, sizeof(val));
  1217.   if (ret < 0)
  1218.     zlog_warn ("Can't setsockopt IP_PKTINFO : %s", strerror (errno));
  1219.   return ret;
  1220. }
  1221. /* Read RIP packet by recvmsg function. */
  1222. int
  1223. rip_recvmsg (int sock, u_char *buf, int size, struct sockaddr_in *from,
  1224.      int *ifindex)
  1225. {
  1226.   int ret;
  1227.   struct msghdr msg;
  1228.   struct iovec iov;
  1229.   struct cmsghdr *ptr;
  1230.   char adata[1024];
  1231.   msg.msg_name = (void *) from;
  1232.   msg.msg_namelen = sizeof (struct sockaddr_in);
  1233.   msg.msg_iov = &iov;
  1234.   msg.msg_iovlen = 1;
  1235.   msg.msg_control = (void *) adata;
  1236.   msg.msg_controllen = sizeof adata;
  1237.   iov.iov_base = buf;
  1238.   iov.iov_len = size;
  1239.   ret = recvmsg (sock, &msg, 0);
  1240.   if (ret < 0)
  1241.     return ret;
  1242.   for (ptr = CMSG_FIRSTHDR(&msg); ptr != NULL; ptr = CMSG_NXTHDR(&msg, ptr))
  1243.     if (ptr->cmsg_level == IPPROTO_IP && ptr->cmsg_type == IP_PKTINFO) 
  1244.       {
  1245. struct in_pktinfo *pktinfo;
  1246. int i;
  1247. pktinfo = (struct in_pktinfo *) CMSG_DATA (ptr);
  1248. i = pktinfo->ipi_ifindex;
  1249.       }
  1250.   return ret;
  1251. }
  1252. /* RIP packet read function. */
  1253. int
  1254. rip_read_new (struct thread *t)
  1255. {
  1256.   int ret;
  1257.   int sock;
  1258.   char buf[RIP_PACKET_MAXSIZ];
  1259.   struct sockaddr_in from;
  1260.   unsigned int ifindex;
  1261.   
  1262.   /* Fetch socket then register myself. */
  1263.   sock = THREAD_FD (t);
  1264.   rip_event (RIP_READ, sock);
  1265.   /* Read RIP packet. */
  1266.   ret = rip_recvmsg (sock, buf, RIP_PACKET_MAXSIZ, &from, (int *)&ifindex);
  1267.   if (ret < 0)
  1268.     {
  1269.       zlog_warn ("Can't read RIP packet: %s", strerror (errno));
  1270.       return ret;
  1271.     }
  1272.   return ret;
  1273. }
  1274. #endif /* RIP_RECVMSG */
  1275. /* First entry point of RIP packet. */
  1276. int
  1277. rip_read (struct thread *t)
  1278. {
  1279.   int sock;
  1280.   int ret;
  1281.   int rtenum;
  1282.   union rip_buf rip_buf;
  1283.   struct rip_packet *packet;
  1284.   struct sockaddr_in from;
  1285.   int fromlen, len;
  1286.   struct interface *ifp;
  1287.   struct rip_interface *ri;
  1288.   /* Fetch socket then register myself. */
  1289.   sock = THREAD_FD (t);
  1290.   rip->t_read = NULL;
  1291.   /* Add myself to tne next event */
  1292.   rip_event (RIP_READ, sock);
  1293.   /* RIPd manages only IPv4. */
  1294.   memset (&from, 0, sizeof (struct sockaddr_in));
  1295.   fromlen = sizeof (struct sockaddr_in);
  1296.   len = recvfrom (sock, (char *)&rip_buf.buf, sizeof (rip_buf.buf), 0, 
  1297.   (struct sockaddr *) &from, &fromlen);
  1298.   if (len < 0) 
  1299.     {
  1300.       zlog_info ("recvfrom failed: %s", strerror (errno));
  1301.       return len;
  1302.     }
  1303.   /* Check is this packet comming from myself? */
  1304.   if (if_check_address (from.sin_addr)) 
  1305.     {
  1306.       if (IS_RIP_DEBUG_PACKET)
  1307. zlog_warn ("ignore packet comes from myself");
  1308.       return -1;
  1309.     }
  1310.   /* Which interface is this packet comes from. */
  1311.   ifp = if_lookup_address (from.sin_addr);
  1312.   /* RIP packet received */
  1313.   if (IS_RIP_DEBUG_EVENT)
  1314.     zlog_info ("RECV packet from %s port %d on %s",
  1315.        inet_ntoa (from.sin_addr), ntohs (from.sin_port),
  1316.        ifp ? ifp->name : "unknown");
  1317.   /* If this packet come from unknown interface, ignore it. */
  1318.   if (ifp == NULL)
  1319.     {
  1320.       zlog_info ("packet comes from unknown interface");
  1321.       return -1;
  1322.     }
  1323.   /* Packet length check. */
  1324.   if (len < RIP_PACKET_MINSIZ)
  1325.     {
  1326.       zlog_warn ("packet size %d is smaller than minimum size %d",
  1327.  len, RIP_PACKET_MINSIZ);
  1328.       rip_peer_bad_packet (&from);
  1329.       return len;
  1330.     }
  1331.   if (len > RIP_PACKET_MAXSIZ)
  1332.     {
  1333.       zlog_warn ("packet size %d is larger than max size %d",
  1334.  len, RIP_PACKET_MAXSIZ);
  1335.       rip_peer_bad_packet (&from);
  1336.       return len;
  1337.     }
  1338.   /* Packet alignment check. */
  1339.   if ((len - RIP_PACKET_MINSIZ) % 20)
  1340.     {
  1341.       zlog_warn ("packet size %d is wrong for RIP packet alignment", len);
  1342.       rip_peer_bad_packet (&from);
  1343.       return len;
  1344.     }
  1345.   /* Set RTE number. */
  1346.   rtenum = ((len - RIP_PACKET_MINSIZ) / 20);
  1347.   /* For easy to handle. */
  1348.   packet = &rip_buf.rip_packet;
  1349.   /* RIP version check. */
  1350.   if (packet->version == 0)
  1351.     {
  1352.       zlog_info ("version 0 with command %d received.", packet->command);
  1353.       rip_peer_bad_packet (&from);
  1354.       return -1;
  1355.     }
  1356.   /* Dump RIP packet. */
  1357.   if (IS_RIP_DEBUG_RECV)
  1358.     rip_packet_dump (packet, len, "RECV");
  1359.   /* RIP version adjust.  This code should rethink now.  RFC1058 says
  1360.      that "Version 1 implementations are to ignore this extra data and
  1361.      process only the fields specified in this document.". So RIPv3
  1362.      packet should be treated as RIPv1 ignoring must be zero field. */
  1363.   if (packet->version > RIPv2)
  1364.     packet->version = RIPv2;
  1365.   /* Is RIP running or is this RIP neighbor ?*/
  1366.   ri = ifp->info;
  1367.   if (! ri->running && ! rip_neighbor_lookup (&from))
  1368.     {
  1369.       if (IS_RIP_DEBUG_EVENT)
  1370. zlog_info ("RIP is not enabled on interface %s.", ifp->name);
  1371.       rip_peer_bad_packet (&from);
  1372.       return -1;
  1373.     }
  1374.   /* RIP Version check. */
  1375.   if (packet->command == RIP_RESPONSE)
  1376.     {
  1377.       if (ri->ri_receive == RI_RIP_UNSPEC)
  1378. {
  1379.   if (packet->version != rip->version) 
  1380.     {
  1381.       if (IS_RIP_DEBUG_PACKET)
  1382. zlog_warn ("  packet's v%d doesn't fit to my version %d", 
  1383.    packet->version, rip->version);
  1384.       rip_peer_bad_packet (&from);
  1385.       return -1;
  1386.     }
  1387. }
  1388.       else
  1389. {
  1390.   if (packet->version == RIPv1)
  1391.     if (! (ri->ri_receive & RIPv1))
  1392.       {
  1393. if (IS_RIP_DEBUG_PACKET)
  1394.   zlog_warn ("  packet's v%d doesn't fit to if version spec", 
  1395.      packet->version);
  1396. rip_peer_bad_packet (&from);
  1397. return -1;
  1398.       }
  1399.   if (packet->version == RIPv2)
  1400.     if (! (ri->ri_receive & RIPv2))
  1401.       {
  1402. if (IS_RIP_DEBUG_PACKET)
  1403.   zlog_warn ("  packet's v%d doesn't fit to if version spec", 
  1404.      packet->version);
  1405. rip_peer_bad_packet (&from);
  1406. return -1;
  1407.       }
  1408. }
  1409.     }
  1410.   /* RFC2453 5.2 If the router is not configured to authenticate RIP-2
  1411.      messages, then RIP-1 and unauthenticated RIP-2 messages will be
  1412.      accepted; authenticated RIP-2 messages shall be discarded.  */
  1413.   if ((ri->auth_type == RIP_NO_AUTH) 
  1414.       && rtenum 
  1415.       && (packet->version == RIPv2) && (packet->rte->family == 0xffff))
  1416.     {
  1417.       if (IS_RIP_DEBUG_EVENT)
  1418. zlog_warn ("packet RIPv%d is dropped because authentication disabled", 
  1419.    packet->version);
  1420.       rip_peer_bad_packet (&from);
  1421.       return -1;
  1422.     }
  1423.   /* If the router is configured to authenticate RIP-2 messages, then
  1424.      RIP-1 messages and RIP-2 messages which pass authentication
  1425.      testing shall be accepted; unauthenticated and failed
  1426.      authentication RIP-2 messages shall be discarded.  For maximum
  1427.      security, RIP-1 messages should be ignored when authentication is
  1428.      in use (see section 4.1); otherwise, the routing information from
  1429.      authenticated messages will be propagated by RIP-1 routers in an
  1430.      unauthenticated manner. */
  1431.   if ((ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD 
  1432.        || ri->auth_type == RIP_AUTH_MD5)
  1433.       && rtenum)
  1434.     {
  1435.       /* We follow maximum security. */
  1436.       if (packet->version == RIPv1 && packet->rte->family == 0xffff)
  1437. {
  1438.   if (IS_RIP_DEBUG_PACKET)
  1439.     zlog_warn ("packet RIPv%d is dropped because authentication enabled", packet->version);
  1440.   rip_peer_bad_packet (&from);
  1441.   return -1;
  1442. }
  1443.       /* Check RIPv2 authentication. */
  1444.       if (packet->version == RIPv2)
  1445. {
  1446.   if (packet->rte->family == 0xffff)
  1447.     {
  1448.       if (ntohs (packet->rte->tag) == RIP_AUTH_SIMPLE_PASSWORD)
  1449.                 {
  1450.   ret = rip_auth_simple_password (packet->rte, &from, ifp);
  1451.   if (! ret)
  1452.     {
  1453.       if (IS_RIP_DEBUG_EVENT)
  1454. zlog_warn ("RIPv2 simple password authentication failed");
  1455.       rip_peer_bad_packet (&from);
  1456.       return -1;
  1457.     }
  1458.   else
  1459.     {
  1460.       if (IS_RIP_DEBUG_EVENT)
  1461. zlog_info ("RIPv2 simple password authentication success");
  1462.     }
  1463.                 }
  1464.       else if (ntohs (packet->rte->tag) == RIP_AUTH_MD5)
  1465.                 {
  1466.   ret = rip_auth_md5 (packet, &from, ifp);
  1467.   if (! ret)
  1468.     {
  1469.       if (IS_RIP_DEBUG_EVENT)
  1470. zlog_warn ("RIPv2 MD5 authentication failed");
  1471.       rip_peer_bad_packet (&from);
  1472.       return -1;
  1473.     }
  1474.   else
  1475.     {
  1476.       if (IS_RIP_DEBUG_EVENT)
  1477. zlog_info ("RIPv2 MD5 authentication success");
  1478.     }
  1479.   /* Reset RIP packet length to trim MD5 data. */
  1480.   len = ret; 
  1481.                 }
  1482.       else
  1483. {
  1484.   if (IS_RIP_DEBUG_EVENT)
  1485.     zlog_warn ("Unknown authentication type %d",
  1486.        ntohs (packet->rte->tag));
  1487.   rip_peer_bad_packet (&from);
  1488.   return -1;
  1489. }
  1490.     }
  1491.   else
  1492.     {
  1493.       /* There is no authentication in the packet. */
  1494.       if (ri->auth_str || ri->key_chain)
  1495. {
  1496.   if (IS_RIP_DEBUG_EVENT)
  1497.     zlog_warn ("RIPv2 authentication failed: no authentication in packet");
  1498.   rip_peer_bad_packet (&from);
  1499.   return -1;
  1500. }
  1501.     }
  1502. }
  1503.     }
  1504.   
  1505.   /* Process each command. */
  1506.   switch (packet->command)
  1507.     {
  1508.     case RIP_RESPONSE:
  1509.       rip_response_process (packet, len, &from, ifp);
  1510.       break;
  1511.     case RIP_REQUEST:
  1512.     case RIP_POLL:
  1513.       rip_request_process (packet, len, &from, ifp);
  1514.       break;
  1515.     case RIP_TRACEON:
  1516.     case RIP_TRACEOFF:
  1517.       zlog_info ("Obsolete command %s received, please sent it to routed", 
  1518.  lookup (rip_msg, packet->command));
  1519.       rip_peer_bad_packet (&from);
  1520.       break;
  1521.     case RIP_POLL_ENTRY:
  1522.       zlog_info ("Obsolete command %s received", 
  1523.  lookup (rip_msg, packet->command));
  1524.       rip_peer_bad_packet (&from);
  1525.       break;
  1526.     default:
  1527.       zlog_info ("Unknown RIP command %d received", packet->command);
  1528.       rip_peer_bad_packet (&from);
  1529.       break;
  1530.     }
  1531.   return len;
  1532. }
  1533. /* Make socket for RIP protocol. */
  1534. int 
  1535. rip_create_socket ()
  1536. {
  1537.   int ret;
  1538.   int sock;
  1539.   struct sockaddr_in addr;
  1540.   struct servent *sp;
  1541.   memset (&addr, 0, sizeof (struct sockaddr_in));
  1542.   /* Set RIP port. */
  1543.   sp = getservbyname ("router", "udp");
  1544.   if (sp) 
  1545.     addr.sin_port = sp->s_port;
  1546.   else 
  1547.     addr.sin_port = htons (RIP_PORT_DEFAULT);
  1548.   /* Address shoud be any address. */
  1549.   addr.sin_family = AF_INET;
  1550.   addr.sin_addr.s_addr = INADDR_ANY;
  1551.   /* Make datagram socket. */
  1552.   sock = socket (AF_INET, SOCK_DGRAM, 0);
  1553.   if (sock < 0) 
  1554.     {
  1555.       perror ("socket");
  1556.       exit (1);
  1557.     }
  1558.   sockopt_broadcast (sock);
  1559.   sockopt_reuseaddr (sock);
  1560.   sockopt_reuseport (sock);
  1561.   sockopt_recvbuf (sock, RIP_UDP_RCV_BUF);
  1562. #ifdef RIP_RECVMSG
  1563.   setsockopt_pktinfo (sock);
  1564. #endif /* RIP_RECVMSG */
  1565.   ret = bind (sock, (struct sockaddr *) & addr, sizeof (addr));
  1566.   if (ret < 0)
  1567.     {
  1568.       perror ("bind");
  1569.       return ret;
  1570.     }
  1571.   
  1572.   return sock;
  1573. }
  1574. /* Write routing table entry to the stream and return next index of
  1575.    the routing table entry in the stream. */
  1576. int
  1577. rip_write_rte (int num, struct stream *s, struct prefix_ipv4 *p,
  1578.        u_char version, struct rip_info *rinfo, struct interface *ifp)
  1579. {
  1580.   struct in_addr mask;
  1581.   struct rip_interface *ri;
  1582.   /* RIP packet header. */
  1583.   if (num == 0)
  1584.     {
  1585.       stream_putc (s, RIP_RESPONSE);
  1586.       stream_putc (s, version);
  1587.       stream_putw (s, 0);
  1588.       /* In case of we need RIPv2 authentication. */
  1589.       if (version == RIPv2 && ifp)
  1590. {
  1591.   ri = ifp->info;
  1592.       
  1593.   if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
  1594.     {
  1595.       if (ri->auth_str)
  1596. {
  1597.   stream_putw (s, 0xffff);
  1598.   stream_putw (s, RIP_AUTH_SIMPLE_PASSWORD);
  1599.   memset ((s->data + s->putp), 0, 16);
  1600.   strncpy ((s->data + s->putp), ri->auth_str, 16);
  1601.   stream_set_putp (s, s->putp + 16);
  1602.   num++;
  1603. }
  1604.       if (ri->key_chain)
  1605. {
  1606.   struct keychain *keychain;
  1607.   struct key *key;
  1608.   keychain = keychain_lookup (ri->key_chain);
  1609.   if (keychain)
  1610.     {
  1611.       key = key_lookup_for_send (keychain);
  1612.       
  1613.       if (key)
  1614. {
  1615.   stream_putw (s, 0xffff);
  1616.   stream_putw (s, RIP_AUTH_SIMPLE_PASSWORD);
  1617.   memset ((s->data + s->putp), 0, 16);
  1618.   strncpy ((s->data + s->putp), key->string, 16);
  1619.   stream_set_putp (s, s->putp + 16);
  1620.   num++;
  1621. }
  1622.     }
  1623. }
  1624.     }
  1625. }
  1626.     }
  1627.   /* Write routing table entry. */
  1628.   if (version == RIPv1)
  1629.     {
  1630.       stream_putw (s, AF_INET);
  1631.       stream_putw (s, 0);
  1632.       stream_put_ipv4 (s, p->prefix.s_addr);
  1633.       stream_put_ipv4 (s, 0);
  1634.       stream_put_ipv4 (s, 0);
  1635.       stream_putl (s, rinfo->metric_out);
  1636.     }
  1637.   else
  1638.     {
  1639.       masklen2ip (p->prefixlen, &mask);
  1640.       stream_putw (s, AF_INET);
  1641.       stream_putw (s, rinfo->tag);
  1642.       stream_put_ipv4 (s, p->prefix.s_addr);
  1643.       stream_put_ipv4 (s, mask.s_addr);
  1644.       stream_put_ipv4 (s, rinfo->nexthop_out.s_addr);
  1645.       stream_putl (s, rinfo->metric_out);
  1646.     }
  1647.   return ++num;
  1648. }
  1649. /* Send update to the ifp or spcified neighbor. */
  1650. void
  1651. rip_output_process (struct interface *ifp, struct sockaddr_in *to,
  1652.     int route_type, u_char version)
  1653. {
  1654.   int ret;
  1655.   struct stream *s;
  1656.   struct route_node *rp;
  1657.   struct rip_info *rinfo;
  1658.   struct rip_interface *ri;
  1659.   struct prefix_ipv4 *p;
  1660.   struct prefix_ipv4 classfull;
  1661.   int num;
  1662.   int rtemax;
  1663.   /* Logging output event. */
  1664.   if (IS_RIP_DEBUG_EVENT)
  1665.     {
  1666.       if (to)
  1667. zlog_info ("update routes to neighbor %s", inet_ntoa (to->sin_addr));
  1668.       else
  1669. zlog_info ("update routes on interface %s ifindex %d",
  1670.    ifp->name, ifp->ifindex);
  1671.     }
  1672.   /* Set output stream. */
  1673.   s = rip->obuf;
  1674.   /* Reset stream and RTE counter. */
  1675.   stream_reset (s);
  1676.   num = 0;
  1677.   rtemax = (RIP_PACKET_MAXSIZ - 4) / 20;
  1678.   /* Get RIP interface. */
  1679.   ri = ifp->info;
  1680.     
  1681.   /* If output interface is in simple password authentication mode, we
  1682.      need space for authentication data.  */
  1683.   if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
  1684.     rtemax -= 1;
  1685.   /* If output interface is in MD5 authentication mode, we need space
  1686.      for authentication header and data. */
  1687.   if (ri->auth_type == RIP_AUTH_MD5)
  1688.     rtemax -= 2;
  1689.   /* If output interface is in simple password authentication mode
  1690.      and string or keychain is specified we need space for auth. data */
  1691.   if (ri->auth_type == RIP_AUTH_SIMPLE_PASSWORD)
  1692.     {
  1693.       if (ri->key_chain)
  1694. {
  1695.   struct keychain *keychain;
  1696.   keychain = keychain_lookup (ri->key_chain);
  1697.   if (keychain)
  1698.     if (key_lookup_for_send (keychain))
  1699.       rtemax -=1;
  1700. }
  1701.       else
  1702. if (ri->auth_str)
  1703.   rtemax -=1;
  1704.     }
  1705.   for (rp = route_top (rip->table); rp; rp = route_next (rp))
  1706.     if ((rinfo = rp->info) != NULL)
  1707.       {
  1708. /* Some inheritance stuff:                                          */
  1709. /* Before we process with ipv4 prefix we should mask it             */
  1710. /* with Classful mask if we send RIPv1 packet.That's because        */
  1711. /* user could set non-classful mask or we could get it by RIPv2     */
  1712. /* or other protocol. checked with Cisco's way of life :)           */
  1713. if (version == RIPv1)
  1714.   {
  1715.     memcpy (&classfull, &rp->p, sizeof (struct prefix_ipv4));
  1716.     if (IS_RIP_DEBUG_PACKET)
  1717.       zlog_info("%s/%d before RIPv1 mask check ",
  1718. inet_ntoa (classfull.prefix), classfull.prefixlen);
  1719.     apply_classful_mask_ipv4 (&classfull);
  1720.     p = &classfull;
  1721.     if (IS_RIP_DEBUG_PACKET)
  1722.       zlog_info("%s/%d after RIPv1 mask check",
  1723. inet_ntoa (p->prefix), p->prefixlen);
  1724.   }
  1725. else 
  1726.   p = (struct prefix_ipv4 *) &rp->p;
  1727. /* Apply output filters. */
  1728. ret = rip_outgoing_filter (p, ri);
  1729. if (ret < 0)
  1730.   continue;
  1731. /* Changed route only output. */
  1732. if (route_type == rip_changed_route &&
  1733.     (! (rinfo->flags & RIP_RTF_CHANGED)))
  1734.   continue;
  1735. /* Split horizon. */
  1736. /* if (split_horizon == rip_split_horizon) */
  1737. if (ri->split_horizon)
  1738.   {
  1739.     /* We perform split horizon for RIP and connected route. */
  1740.     if ((rinfo->type == ZEBRA_ROUTE_RIP ||
  1741.  rinfo->type == ZEBRA_ROUTE_CONNECT) &&
  1742. rinfo->ifindex == ifp->ifindex)
  1743.       continue;
  1744.   }
  1745. /* Preparation for route-map. */
  1746. rinfo->metric_set = 0;
  1747. rinfo->nexthop_out.s_addr = 0;
  1748. rinfo->metric_out = rinfo->metric;
  1749. rinfo->ifindex_out = ifp->ifindex;
  1750. /* In order to avoid some local loops, if the RIP route has a
  1751.    nexthop via this interface, keep the nexthop, otherwise set
  1752.    it to 0. The nexthop should not be propagated beyond the
  1753.    local broadcast/multicast area in order to avoid an IGP
  1754.    multi-level recursive look-up.  For RIP and connected
  1755.    route, we don't set next hop value automatically.  For
  1756.    settting next hop to those routes, please use
  1757.    route-map.  */
  1758. if (rinfo->type != ZEBRA_ROUTE_RIP
  1759.     && rinfo->type != ZEBRA_ROUTE_CONNECT
  1760.     && rinfo->ifindex == ifp->ifindex)
  1761.   rinfo->nexthop_out = rinfo->nexthop;
  1762.            
  1763. /* Apply route map - continue, if deny */
  1764. if (rip->route_map[rinfo->type].name
  1765.     && rinfo->sub_type != RIP_ROUTE_INTERFACE)
  1766.   {
  1767.     ret = route_map_apply (rip->route_map[rinfo->type].map,
  1768.    (struct prefix *)p, RMAP_RIP, rinfo);
  1769.     if (ret == RMAP_DENYMATCH) 
  1770.       {
  1771. if (IS_RIP_DEBUG_PACKET)
  1772.   zlog_info ("%s/%d is filtered by route-map",
  1773.      inet_ntoa (p->prefix), p->prefixlen);
  1774. continue;
  1775.       }
  1776.   }
  1777. /* When route-map does not set metric. */
  1778. if (! rinfo->metric_set)
  1779.   {
  1780.     /* If redistribute metric is set. */
  1781.     if (rip->route_map[rinfo->type].metric_config
  1782. && rinfo->metric != RIP_METRIC_INFINITY)
  1783.       {
  1784. rinfo->metric_out = rip->route_map[rinfo->type].metric;
  1785.       }
  1786.     else
  1787.       {
  1788. /* If the route is not connected or localy generated
  1789.    one, use default-metric value*/
  1790. if (rinfo->type != ZEBRA_ROUTE_RIP 
  1791.     && rinfo->type != ZEBRA_ROUTE_CONNECT
  1792.     && rinfo->metric != RIP_METRIC_INFINITY)
  1793.   rinfo->metric_out = rip->default_metric;
  1794.       }
  1795.   }
  1796. /* Apply offset-list */
  1797. if (rinfo->metric != RIP_METRIC_INFINITY)
  1798.   rip_offset_list_apply_out (p, ifp, &rinfo->metric_out);
  1799. if (rinfo->metric_out > RIP_METRIC_INFINITY)
  1800.   rinfo->metric_out = RIP_METRIC_INFINITY;
  1801.   
  1802. /* Write RTE to the stream. */
  1803. num = rip_write_rte (num, s, p, version, rinfo, to ? NULL : ifp);
  1804. if (num == rtemax)
  1805.   {
  1806.     if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5)
  1807.       rip_auth_md5_set (s, ifp);
  1808.     ret = rip_send_packet (STREAM_DATA (s), stream_get_endp (s),
  1809.    to, ifp);
  1810.     if (ret >= 0 && IS_RIP_DEBUG_SEND)
  1811.       rip_packet_dump ((struct rip_packet *)STREAM_DATA (s),
  1812.        stream_get_endp(s), "SEND");
  1813.     num = 0;
  1814.     stream_reset (s);
  1815.   }
  1816.       }
  1817.   /* Flush unwritten RTE. */
  1818.   if (num != 0)
  1819.     {
  1820.       if (version == RIPv2 && ri->auth_type == RIP_AUTH_MD5)
  1821. rip_auth_md5_set (s, ifp);
  1822.       ret = rip_send_packet (STREAM_DATA (s), stream_get_endp (s), to, ifp);
  1823.       if (ret >= 0 && IS_RIP_DEBUG_SEND)
  1824. rip_packet_dump ((struct rip_packet *)STREAM_DATA (s),
  1825.  stream_get_endp (s), "SEND");
  1826.       num = 0;
  1827.       stream_reset (s);
  1828.     }
  1829.   /* Statistics updates. */
  1830.   ri->sent_updates++;
  1831. }
  1832. /* Send RIP packet to the interface. */
  1833. void
  1834. rip_update_interface (struct interface *ifp, u_char version, int route_type)
  1835. {
  1836.   struct prefix_ipv4 *p;
  1837.   struct connected *connected;
  1838.   listnode node;
  1839.   struct sockaddr_in to;
  1840.   /* When RIP version is 2 and multicast enable interface. */
  1841.   if (version == RIPv2 && if_is_multicast (ifp)) 
  1842.     {
  1843.       if (IS_RIP_DEBUG_EVENT)
  1844. zlog_info ("multicast announce on %s ", ifp->name);
  1845.       rip_output_process (ifp, NULL, route_type, version);
  1846.       return;
  1847.     }
  1848.   /* If we can't send multicast packet, send it with unicast. */
  1849.   if (if_is_broadcast (ifp) || if_is_pointopoint (ifp))
  1850.     {
  1851.       for (node = listhead (ifp->connected); node; nextnode (node))
  1852. {     
  1853.   connected = getdata (node);
  1854.   /* Fetch broadcast address or poin-to-point destination
  1855.              address . */
  1856.   p = (struct prefix_ipv4 *) connected->destination;
  1857.   if (p->family == AF_INET)
  1858.     {
  1859.       /* Destination address and port setting. */
  1860.       memset (&to, 0, sizeof (struct sockaddr_in));
  1861.       to.sin_addr = p->prefix;
  1862.       to.sin_port = htons (RIP_PORT_DEFAULT);
  1863.       if (IS_RIP_DEBUG_EVENT)
  1864. zlog_info ("%s announce to %s on %s",
  1865.    if_is_pointopoint (ifp) ? "unicast" : "broadcast",
  1866.    inet_ntoa (to.sin_addr), ifp->name);
  1867.       rip_output_process (ifp, &to, route_type, version);
  1868.     }
  1869. }
  1870.     }
  1871. }
  1872. /* Update send to all interface and neighbor. */
  1873. void
  1874. rip_update_process (int route_type)
  1875. {
  1876.   listnode node;
  1877.   struct interface *ifp;
  1878.   struct rip_interface *ri;
  1879.   struct route_node *rp;
  1880.   struct sockaddr_in to;
  1881.   struct prefix_ipv4 *p;
  1882.   /* Send RIP update to each interface. */
  1883.   for (node = listhead (iflist); node; nextnode (node))
  1884.     {
  1885.       ifp = getdata (node);
  1886.       if (if_is_loopback (ifp))
  1887. continue;
  1888.       if (! if_is_up (ifp))
  1889. continue;
  1890.       /* Fetch RIP interface information. */
  1891.       ri = ifp->info;
  1892.       /* When passive interface is specified, suppress announce to the
  1893.          interface. */
  1894.       if (ri->passive)
  1895. continue;
  1896.       if (ri->running)
  1897. {
  1898.   if (IS_RIP_DEBUG_EVENT) 
  1899.     {
  1900.       if (ifp->name) 
  1901. zlog_info ("SEND UPDATE to %s ifindex %d",
  1902.    ifp->name, ifp->ifindex);
  1903.       else
  1904. zlog_info ("SEND UPDATE to _unknown_ ifindex %d",
  1905.    ifp->ifindex);
  1906.     }
  1907.   /* If there is no version configuration in the interface,
  1908.              use rip's version setting. */
  1909.   if (ri->ri_send == RI_RIP_UNSPEC)
  1910.     {
  1911.       if (rip->version == RIPv1)
  1912. rip_update_interface (ifp, RIPv1, route_type);
  1913.       else
  1914. rip_update_interface (ifp, RIPv2, route_type);
  1915.     }
  1916.   /* If interface has RIP version configuration use it. */
  1917.   else
  1918.     {
  1919.       if (ri->ri_send & RIPv1)
  1920. rip_update_interface (ifp, RIPv1, route_type);
  1921.       if (ri->ri_send & RIPv2)
  1922. rip_update_interface (ifp, RIPv2, route_type);
  1923.     }
  1924. }
  1925.     }
  1926.   /* RIP send updates to each neighbor. */
  1927.   for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
  1928.     if (rp->info != NULL)
  1929.       {
  1930. p = (struct prefix_ipv4 *) &rp->p;
  1931. ifp = if_lookup_address (p->prefix);
  1932. if (! ifp)
  1933.   {
  1934.     zlog_warn ("Neighbor %s doesn't exist direct connected network",
  1935.        inet_ntoa (p->prefix));
  1936.     continue;
  1937.   }
  1938. /* Set destination address and port */
  1939. memset (&to, 0, sizeof (struct sockaddr_in));
  1940. to.sin_addr = p->prefix;
  1941. to.sin_port = htons (RIP_PORT_DEFAULT);
  1942. /* RIP version is rip's configuration. */
  1943. rip_output_process (ifp, &to, route_type, rip->version);
  1944.       }
  1945. }
  1946. /* RIP's periodical timer. */
  1947. int
  1948. rip_update (struct thread *t)
  1949. {
  1950.   /* Clear timer pointer. */
  1951.   rip->t_update = NULL;
  1952.   if (IS_RIP_DEBUG_EVENT)
  1953.     zlog_info ("update timer fire!");
  1954.   /* Process update output. */
  1955.   rip_update_process (rip_all_route);
  1956.   /* Triggered updates may be suppressed if a regular update is due by
  1957.      the time the triggered update would be sent. */
  1958.   if (rip->t_triggered_interval)
  1959.     {
  1960.       thread_cancel (rip->t_triggered_interval);
  1961.       rip->t_triggered_interval = NULL;
  1962.     }
  1963.   rip->trigger = 0;
  1964.   /* Register myself. */
  1965.   rip_event (RIP_UPDATE_EVENT, 0);
  1966.   return 0;
  1967. }
  1968. /* Walk down the RIP routing table then clear changed flag. */
  1969. void
  1970. rip_clear_changed_flag ()
  1971. {
  1972.   struct route_node *rp;
  1973.   struct rip_info *rinfo;
  1974.   for (rp = route_top (rip->table); rp; rp = route_next (rp))
  1975.     if ((rinfo = rp->info) != NULL)
  1976.       if (rinfo->flags & RIP_RTF_CHANGED)
  1977. rinfo->flags &= ~RIP_RTF_CHANGED;
  1978. }
  1979. /* Triggered update interval timer. */
  1980. int
  1981. rip_triggered_interval (struct thread *t)
  1982. {
  1983.   int rip_triggered_update (struct thread *);
  1984.   rip->t_triggered_interval = NULL;
  1985.   if (rip->trigger)
  1986.     {
  1987.       rip->trigger = 0;
  1988.       rip_triggered_update (t);
  1989.     }
  1990.   return 0;
  1991. }     
  1992. /* Execute triggered update. */
  1993. int
  1994. rip_triggered_update (struct thread *t)
  1995. {
  1996.   int interval;
  1997.   /* Clear thred pointer. */
  1998.   rip->t_triggered_update = NULL;
  1999.   /* Cancel interval timer. */
  2000.   if (rip->t_triggered_interval)
  2001.     {
  2002.       thread_cancel (rip->t_triggered_interval);
  2003.       rip->t_triggered_interval = NULL;
  2004.     }
  2005.   rip->trigger = 0;
  2006.   /* Logging triggered update. */
  2007.   if (IS_RIP_DEBUG_EVENT)
  2008.     zlog_info ("triggered update!");
  2009.   /* Split Horizon processing is done when generating triggered
  2010.      updates as well as normal updates (see section 2.6). */
  2011.   rip_update_process (rip_changed_route);
  2012.   /* Once all of the triggered updates have been generated, the route
  2013.      change flags should be cleared. */
  2014.   rip_clear_changed_flag ();
  2015.   /* After a triggered update is sent, a timer should be set for a
  2016.      random interval between 1 and 5 seconds.  If other changes that
  2017.      would trigger updates occur before the timer expires, a single
  2018.      update is triggered when the timer expires. */
  2019.   interval = (random () % 5) + 1;
  2020.   rip->t_triggered_interval = 
  2021.     thread_add_timer (master, rip_triggered_interval, NULL, interval);
  2022.   return 0;
  2023. }
  2024. /* Withdraw redistributed route. */
  2025. void
  2026. rip_redistribute_withdraw (int type)
  2027. {
  2028.   struct route_node *rp;
  2029.   struct rip_info *rinfo;
  2030.   if (!rip)
  2031.     return;
  2032.   for (rp = route_top (rip->table); rp; rp = route_next (rp))
  2033.     if ((rinfo = rp->info) != NULL)
  2034.       {
  2035. if (rinfo->type == type
  2036.     && rinfo->sub_type != RIP_ROUTE_INTERFACE)
  2037.   {
  2038.     /* Perform poisoned reverse. */
  2039.     rinfo->metric = RIP_METRIC_INFINITY;
  2040.     RIP_TIMER_ON (rinfo->t_garbage_collect, 
  2041.   rip_garbage_collect, rip->garbage_time);
  2042.     RIP_TIMER_OFF (rinfo->t_timeout);
  2043.     rinfo->flags |= RIP_RTF_CHANGED;
  2044.     rip_event (RIP_TRIGGERED_UPDATE, 0);
  2045.   }
  2046.       }
  2047. }
  2048. /* Create new RIP instance and set it to global variable. */
  2049. int
  2050. rip_create ()
  2051. {
  2052.   rip = XMALLOC (MTYPE_RIP, sizeof (struct rip));
  2053.   memset (rip, 0, sizeof (struct rip));
  2054.   /* Set initial value. */
  2055.   rip->version = RIPv2;
  2056.   rip->update_time = RIP_UPDATE_TIMER_DEFAULT;
  2057.   rip->timeout_time = RIP_TIMEOUT_TIMER_DEFAULT;
  2058.   rip->garbage_time = RIP_GARBAGE_TIMER_DEFAULT;
  2059.   rip->default_metric = RIP_DEFAULT_METRIC_DEFAULT;
  2060.   /* Initialize RIP routig table. */
  2061.   rip->table = route_table_init ();
  2062.   rip->route = route_table_init ();
  2063.   rip->neighbor = route_table_init ();
  2064.   /* Make output stream. */
  2065.   rip->obuf = stream_new (1500);
  2066.   /* Make socket. */
  2067.   rip->sock = rip_create_socket ();
  2068.   if (rip->sock < 0)
  2069.     return rip->sock;
  2070.   /* Create read and timer thread. */
  2071.   rip_event (RIP_READ, rip->sock);
  2072.   rip_event (RIP_UPDATE_EVENT, 1);
  2073.   return 0;
  2074. }
  2075. /* Sned RIP request to the destination. */
  2076. int
  2077. rip_request_send (struct sockaddr_in *to, struct interface *ifp,
  2078.   u_char version)
  2079. {
  2080.   struct rte *rte;
  2081.   struct rip_packet rip_packet;
  2082.   memset (&rip_packet, 0, sizeof (rip_packet));
  2083.   rip_packet.command = RIP_REQUEST;
  2084.   rip_packet.version = version;
  2085.   rte = rip_packet.rte;
  2086.   rte->metric = htonl (RIP_METRIC_INFINITY);
  2087.   return rip_send_packet ((caddr_t) &rip_packet, sizeof (rip_packet), to, ifp);
  2088. }
  2089. int
  2090. rip_update_jitter (unsigned long time)
  2091. {
  2092.   return ((rand () % (time + 1)) - (time / 2));
  2093. }
  2094. void
  2095. rip_event (enum rip_event event, int sock)
  2096. {
  2097.   int jitter = 0;
  2098.   switch (event)
  2099.     {
  2100.     case RIP_READ:
  2101.       rip->t_read = thread_add_read (master, rip_read, NULL, sock);
  2102.       break;
  2103.     case RIP_UPDATE_EVENT:
  2104.       if (rip->t_update)
  2105. {
  2106.   thread_cancel (rip->t_update);
  2107.   rip->t_update = NULL;
  2108. }
  2109.       jitter = rip_update_jitter (rip->update_time);
  2110.       rip->t_update = 
  2111. thread_add_timer (master, rip_update, NULL, 
  2112.   sock ? 2 : rip->update_time + jitter);
  2113.       break;
  2114.     case RIP_TRIGGERED_UPDATE:
  2115.       if (rip->t_triggered_interval)
  2116. rip->trigger = 1;
  2117.       else if (! rip->t_triggered_update)
  2118. rip->t_triggered_update = 
  2119.   thread_add_event (master, rip_triggered_update, NULL, 0);
  2120.       break;
  2121.     default:
  2122.       break;
  2123.     }
  2124. }
  2125. DEFUN (router_rip,
  2126.        router_rip_cmd,
  2127.        "router rip",
  2128.        "Enable a routing processn"
  2129.        "Routing Information Protocol (RIP)n")
  2130. {
  2131.   int ret;
  2132.   /* If rip is not enabled before. */
  2133.   if (! rip)
  2134.     {
  2135.       ret = rip_create ();
  2136.       if (ret < 0)
  2137. {
  2138.   zlog_info ("Can't create RIP");
  2139.   return CMD_WARNING;
  2140. }
  2141.     }
  2142.   vty->node = RIP_NODE;
  2143.   vty->index = rip;
  2144.   return CMD_SUCCESS;
  2145. }
  2146. DEFUN (no_router_rip,
  2147.        no_router_rip_cmd,
  2148.        "no router rip",
  2149.        NO_STR
  2150.        "Enable a routing processn"
  2151.        "Routing Information Protocol (RIP)n")
  2152. {
  2153.   if (rip)
  2154.     rip_clean ();
  2155.   return CMD_SUCCESS;
  2156. }
  2157. DEFUN (rip_version,
  2158.        rip_version_cmd,
  2159.        "version <1-2>",
  2160.        "Set routing protocol versionn"
  2161.        "versionn")
  2162. {
  2163.   int version;
  2164.   version = atoi (argv[0]);
  2165.   if (version != RIPv1 && version != RIPv2)
  2166.     {
  2167.       vty_out (vty, "invalid rip version %d%s", version,
  2168.        VTY_NEWLINE);
  2169.       return CMD_WARNING;
  2170.     }
  2171.   rip->version = version;
  2172.   return CMD_SUCCESS;
  2173. DEFUN (no_rip_version,
  2174.        no_rip_version_cmd,
  2175.        "no version",
  2176.        NO_STR
  2177.        "Set routing protocol versionn")
  2178. {
  2179.   /* Set RIP version to the default. */
  2180.   rip->version = RIPv2;
  2181.   return CMD_SUCCESS;
  2182. ALIAS (no_rip_version,
  2183.        no_rip_version_val_cmd,
  2184.        "no version <1-2>",
  2185.        NO_STR
  2186.        "Set routing protocol versionn"
  2187.        "versionn");
  2188. DEFUN (rip_route,
  2189.        rip_route_cmd,
  2190.        "route A.B.C.D/M",
  2191.        "RIP static route configurationn"
  2192.        "IP prefix <network>/<length>n")
  2193. {
  2194.   int ret;
  2195.   struct prefix_ipv4 p;
  2196.   struct route_node *node;
  2197.   ret = str2prefix_ipv4 (argv[0], &p);
  2198.   if (ret < 0)
  2199.     {
  2200.       vty_out (vty, "Malformed address%s", VTY_NEWLINE);
  2201.       return CMD_WARNING;
  2202.     }
  2203.   apply_mask_ipv4 (&p);
  2204.   /* For router rip configuration. */
  2205.   node = route_node_get (rip->route, (struct prefix *) &p);
  2206.   if (node->info)
  2207.     {
  2208.       vty_out (vty, "There is already same static route.%s", VTY_NEWLINE);
  2209.       route_unlock_node (node);
  2210.       return CMD_WARNING;
  2211.     }
  2212.   node->info = "static";
  2213.   rip_redistribute_add (ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0, NULL);
  2214.   return CMD_SUCCESS;
  2215. }
  2216. DEFUN (no_rip_route,
  2217.        no_rip_route_cmd,
  2218.        "no route A.B.C.D/M",
  2219.        NO_STR
  2220.        "RIP static route configurationn"
  2221.        "IP prefix <network>/<length>n")
  2222. {
  2223.   int ret;
  2224.   struct prefix_ipv4 p;
  2225.   struct route_node *node;
  2226.   ret = str2prefix_ipv4 (argv[0], &p);
  2227.   if (ret < 0)
  2228.     {
  2229.       vty_out (vty, "Malformed address%s", VTY_NEWLINE);
  2230.       return CMD_WARNING;
  2231.     }
  2232.   apply_mask_ipv4 (&p);
  2233.   /* For router rip configuration. */
  2234.   node = route_node_lookup (rip->route, (struct prefix *) &p);
  2235.   if (! node)
  2236.     {
  2237.       vty_out (vty, "Can't find route %s.%s", argv[0],
  2238.        VTY_NEWLINE);
  2239.       return CMD_WARNING;
  2240.     }
  2241.   rip_redistribute_delete (ZEBRA_ROUTE_RIP, RIP_ROUTE_STATIC, &p, 0);
  2242.   route_unlock_node (node);
  2243.   node->info = NULL;
  2244.   route_unlock_node (node);
  2245.   return CMD_SUCCESS;
  2246. }
  2247. void
  2248. rip_update_default_metric ()
  2249. {
  2250.   struct route_node *np;
  2251.   struct rip_info *rinfo;
  2252.   for (np = route_top (rip->table); np; np = route_next (np))
  2253.     if ((rinfo = np->info) != NULL)
  2254.       if (rinfo->type != ZEBRA_ROUTE_RIP && rinfo->type != ZEBRA_ROUTE_CONNECT)
  2255.         rinfo->metric = rip->default_metric;
  2256. }
  2257. DEFUN (rip_default_metric,
  2258.        rip_default_metric_cmd,
  2259.        "default-metric <1-16>",
  2260.        "Set a metric of redistribute routesn"
  2261.        "Default metricn")
  2262. {
  2263.   if (rip)
  2264.     {
  2265.       rip->default_metric = atoi (argv[0]);
  2266.       /* rip_update_default_metric (); */
  2267.     }
  2268.   return CMD_SUCCESS;
  2269. }
  2270. DEFUN (no_rip_default_metric,
  2271.        no_rip_default_metric_cmd,
  2272.        "no default-metric",
  2273.        NO_STR
  2274.        "Set a metric of redistribute routesn"
  2275.        "Default metricn")
  2276. {
  2277.   if (rip)
  2278.     {
  2279.       rip->default_metric = RIP_DEFAULT_METRIC_DEFAULT;
  2280.       /* rip_update_default_metric (); */
  2281.     }
  2282.   return CMD_SUCCESS;
  2283. }
  2284. ALIAS (no_rip_default_metric,
  2285.        no_rip_default_metric_val_cmd,
  2286.        "no default-metric <1-16>",
  2287.        NO_STR
  2288.        "Set a metric of redistribute routesn"
  2289.        "Default metricn");
  2290. DEFUN (rip_timers,
  2291.        rip_timers_cmd,
  2292.        "timers basic <5-2147483647> <5-2147483647> <5-2147483647>",
  2293.        "Adjust routing timersn"
  2294.        "Basic routing protocol update timersn"
  2295.        "Routing table update timer value in second. Default is 30.n"
  2296.        "Routing information timeout timer. Default is 180.n"
  2297.        "Garbage collection timer. Default is 120.n")
  2298. {
  2299.   unsigned long update;
  2300.   unsigned long timeout;
  2301.   unsigned long garbage;
  2302.   char *endptr = NULL;
  2303.   unsigned long RIP_TIMER_MAX = 2147483647;
  2304.   unsigned long RIP_TIMER_MIN = 5;
  2305.   update = strtoul (argv[0], &endptr, 10);
  2306.   if (update > RIP_TIMER_MAX || update < RIP_TIMER_MIN || *endptr != '')  
  2307.     {
  2308.       vty_out (vty, "update timer value error%s", VTY_NEWLINE);
  2309.       return CMD_WARNING;
  2310.     }
  2311.   
  2312.   timeout = strtoul (argv[1], &endptr, 10);
  2313.   if (timeout > RIP_TIMER_MAX || timeout < RIP_TIMER_MIN || *endptr != '') 
  2314.     {
  2315.       vty_out (vty, "timeout timer value error%s", VTY_NEWLINE);
  2316.       return CMD_WARNING;
  2317.     }
  2318.   
  2319.   garbage = strtoul (argv[2], &endptr, 10);
  2320.   if (garbage > RIP_TIMER_MAX || garbage < RIP_TIMER_MIN || *endptr != '') 
  2321.     {
  2322.       vty_out (vty, "garbage timer value error%s", VTY_NEWLINE);
  2323.       return CMD_WARNING;
  2324.     }
  2325.   /* Set each timer value. */
  2326.   rip->update_time = update;
  2327.   rip->timeout_time = timeout;
  2328.   rip->garbage_time = garbage;
  2329.   /* Reset update timer thread. */
  2330.   rip_event (RIP_UPDATE_EVENT, 0);
  2331.   return CMD_SUCCESS;
  2332. }
  2333. DEFUN (no_rip_timers,
  2334.        no_rip_timers_cmd,
  2335.        "no timers basic",
  2336.        NO_STR
  2337.        "Adjust routing timersn"
  2338.        "Basic routing protocol update timersn")
  2339. {
  2340.   /* Set each timer value to the default. */
  2341.   rip->update_time = RIP_UPDATE_TIMER_DEFAULT;
  2342.   rip->timeout_time = RIP_TIMEOUT_TIMER_DEFAULT;
  2343.   rip->garbage_time = RIP_GARBAGE_TIMER_DEFAULT;
  2344.   /* Reset update timer thread. */
  2345.   rip_event (RIP_UPDATE_EVENT, 0);
  2346.   return CMD_SUCCESS;
  2347. }
  2348. struct route_table *rip_distance_table;
  2349. struct rip_distance
  2350. {
  2351.   /* Distance value for the IP source prefix. */
  2352.   u_char distance;
  2353.   /* Name of the access-list to be matched. */
  2354.   char *access_list;
  2355. };
  2356. struct rip_distance *
  2357. rip_distance_new ()
  2358. {
  2359.   struct rip_distance *new;
  2360.   new = XMALLOC (MTYPE_RIP_DISTANCE, sizeof (struct rip_distance));
  2361.   memset (new, 0, sizeof (struct rip_distance));
  2362.   return new;
  2363. }
  2364. void
  2365. rip_distance_free (struct rip_distance *rdistance)
  2366. {
  2367.   XFREE (MTYPE_RIP_DISTANCE, rdistance);
  2368. }
  2369. int
  2370. rip_distance_set (struct vty *vty, char *distance_str, char *ip_str,
  2371.   char *access_list_str)
  2372. {
  2373.   int ret;
  2374.   struct prefix_ipv4 p;
  2375.   u_char distance;
  2376.   struct route_node *rn;
  2377.   struct rip_distance *rdistance;
  2378.   ret = str2prefix_ipv4 (ip_str, &p);
  2379.   if (ret == 0)
  2380.     {
  2381.       vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
  2382.       return CMD_WARNING;
  2383.     }
  2384.   distance = atoi (distance_str);
  2385.   /* Get RIP distance node. */
  2386.   rn = route_node_get (rip_distance_table, (struct prefix *) &p);
  2387.   if (rn->info)
  2388.     {
  2389.       rdistance = rn->info;
  2390.       route_unlock_node (rn);
  2391.     }
  2392.   else
  2393.     {
  2394.       rdistance = rip_distance_new ();
  2395.       rn->info = rdistance;
  2396.     }
  2397.   /* Set distance value. */
  2398.   rdistance->distance = distance;
  2399.   /* Reset access-list configuration. */
  2400.   if (rdistance->access_list)
  2401.     {
  2402.       free (rdistance->access_list);
  2403.       rdistance->access_list = NULL;
  2404.     }
  2405.   if (access_list_str)
  2406.     rdistance->access_list = strdup (access_list_str);
  2407.   return CMD_SUCCESS;
  2408. }
  2409. int
  2410. rip_distance_unset (struct vty *vty, char *distance_str, char *ip_str,
  2411.     char *access_list_str)
  2412. {
  2413.   int ret;
  2414.   struct prefix_ipv4 p;
  2415.   u_char distance;
  2416.   struct route_node *rn;
  2417.   struct rip_distance *rdistance;
  2418.   ret = str2prefix_ipv4 (ip_str, &p);
  2419.   if (ret == 0)
  2420.     {
  2421.       vty_out (vty, "Malformed prefix%s", VTY_NEWLINE);
  2422.       return CMD_WARNING;
  2423.     }
  2424.   distance = atoi (distance_str);
  2425.   rn = route_node_lookup (rip_distance_table, (struct prefix *)&p);
  2426.   if (! rn)
  2427.     {
  2428.       vty_out (vty, "Can't find specified prefix%s", VTY_NEWLINE);
  2429.       return CMD_WARNING;
  2430.     }
  2431.   rdistance = rn->info;
  2432.   if (rdistance->access_list)
  2433.     free (rdistance->access_list);
  2434.   rip_distance_free (rdistance);
  2435.   rn->info = NULL;
  2436.   route_unlock_node (rn);
  2437.   route_unlock_node (rn);
  2438.   return CMD_SUCCESS;
  2439. }
  2440. void
  2441. rip_distance_reset ()
  2442. {
  2443.   struct route_node *rn;
  2444.   struct rip_distance *rdistance;
  2445.   for (rn = route_top (rip_distance_table); rn; rn = route_next (rn))
  2446.     if ((rdistance = rn->info) != NULL)
  2447.       {
  2448. if (rdistance->access_list)
  2449.   free (rdistance->access_list);
  2450. rip_distance_free (rdistance);
  2451. rn->info = NULL;
  2452. route_unlock_node (rn);
  2453.       }
  2454. }
  2455. /* Apply RIP information to distance method. */
  2456. u_char
  2457. rip_distance_apply (struct rip_info *rinfo)
  2458. {
  2459.   struct route_node *rn;
  2460.   struct prefix_ipv4 p;
  2461.   struct rip_distance *rdistance;
  2462.   struct access_list *alist;
  2463.   if (! rip)
  2464.     return 0;
  2465.   memset (&p, 0, sizeof (struct prefix_ipv4));
  2466.   p.family = AF_INET;
  2467.   p.prefix = rinfo->from;
  2468.   p.prefixlen = IPV4_MAX_BITLEN;
  2469.   /* Check source address. */
  2470.   rn = route_node_match (rip_distance_table, (struct prefix *) &p);
  2471.   if (rn)
  2472.     {
  2473.       rdistance = rn->info;
  2474.       route_unlock_node (rn);
  2475.       if (rdistance->access_list)
  2476. {
  2477.   alist = access_list_lookup (AFI_IP, rdistance->access_list);
  2478.   if (alist == NULL)
  2479.     return 0;
  2480.   if (access_list_apply (alist, &rinfo->rp->p) == FILTER_DENY)
  2481.     return 0;
  2482.   return rdistance->distance;
  2483. }
  2484.       else
  2485. return rdistance->distance;
  2486.     }
  2487.   if (rip->distance)
  2488.     return rip->distance;
  2489.   return 0;
  2490. }
  2491. void
  2492. rip_distance_show (struct vty *vty)
  2493. {
  2494.   struct route_node *rn;
  2495.   struct rip_distance *rdistance;
  2496.   int header = 1;
  2497.   char buf[BUFSIZ];
  2498.   
  2499.   vty_out (vty, "  Distance: (default is %d)%s",
  2500.    rip->distance ? rip->distance :ZEBRA_RIP_DISTANCE_DEFAULT,
  2501.    VTY_NEWLINE);
  2502.   for (rn = route_top (rip_distance_table); rn; rn = route_next (rn))
  2503.     if ((rdistance = rn->info) != NULL)
  2504.       {
  2505. if (header)
  2506.   {
  2507.     vty_out (vty, "    Address           Distance  List%s",
  2508.      VTY_NEWLINE);
  2509.     header = 0;
  2510.   }
  2511. sprintf (buf, "%s/%d", inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen);
  2512. vty_out (vty, "    %-20s  %4d  %s%s",
  2513.  buf, rdistance->distance,
  2514.  rdistance->access_list ? rdistance->access_list : "",
  2515.  VTY_NEWLINE);
  2516.       }
  2517. }
  2518. DEFUN (rip_distance,
  2519.        rip_distance_cmd,
  2520.        "distance <1-255>",
  2521.        "Administrative distancen"
  2522.        "Distance valuen")
  2523. {
  2524.   rip->distance = atoi (argv[0]);
  2525.   return CMD_SUCCESS;
  2526. }
  2527. DEFUN (no_rip_distance,
  2528.        no_rip_distance_cmd,
  2529.        "no distance <1-255>",
  2530.        NO_STR
  2531.        "Administrative distancen"
  2532.        "Distance valuen")
  2533. {
  2534.   rip->distance = 0;
  2535.   return CMD_SUCCESS;
  2536. }
  2537. DEFUN (rip_distance_source,
  2538.        rip_distance_source_cmd,
  2539.        "distance <1-255> A.B.C.D/M",
  2540.        "Administrative distancen"
  2541.        "Distance valuen"
  2542.        "IP source prefixn")
  2543. {
  2544.   rip_distance_set (vty, argv[0], argv[1], NULL);
  2545.   return CMD_SUCCESS;
  2546. }
  2547. DEFUN (no_rip_distance_source,
  2548.        no_rip_distance_source_cmd,
  2549.        "no distance <1-255> A.B.C.D/M",
  2550.        NO_STR
  2551.        "Administrative distancen"
  2552.        "Distance valuen"
  2553.        "IP source prefixn")
  2554. {
  2555.   rip_distance_unset (vty, argv[0], argv[1], NULL);
  2556.   return CMD_SUCCESS;
  2557. }
  2558. DEFUN (rip_distance_source_access_list,
  2559.        rip_distance_source_access_list_cmd,
  2560.        "distance <1-255> A.B.C.D/M WORD",
  2561.        "Administrative distancen"
  2562.        "Distance valuen"
  2563.        "IP source prefixn"
  2564.        "Access list namen")
  2565. {
  2566.   rip_distance_set (vty, argv[0], argv[1], argv[2]);
  2567.   return CMD_SUCCESS;
  2568. }
  2569. DEFUN (no_rip_distance_source_access_list,
  2570.        no_rip_distance_source_access_list_cmd,
  2571.        "no distance <1-255> A.B.C.D/M WORD",
  2572.        NO_STR
  2573.        "Administrative distancen"
  2574.        "Distance valuen"
  2575.        "IP source prefixn"
  2576.        "Access list namen")
  2577. {
  2578.   rip_distance_unset (vty, argv[0], argv[1], argv[2]);
  2579.   return CMD_SUCCESS;
  2580. }
  2581. /* Print out routes update time. */
  2582. void
  2583. rip_vty_out_uptime (struct vty *vty, struct rip_info *rinfo)
  2584. {
  2585.   struct timeval timer_now;
  2586.   time_t clock;
  2587.   struct tm *tm;
  2588. #define TIME_BUF 25
  2589.   char timebuf [TIME_BUF];
  2590.   struct thread *thread;
  2591.   gettimeofday (&timer_now, NULL);
  2592.   if ((thread = rinfo->t_timeout) != NULL)
  2593.     {
  2594.       clock = thread->u.sands.tv_sec - timer_now.tv_sec;
  2595.       tm = gmtime (&clock);
  2596.       strftime (timebuf, TIME_BUF, "%M:%S", tm);
  2597.       vty_out (vty, "%5s", timebuf);
  2598.     }
  2599.   else if ((thread = rinfo->t_garbage_collect) != NULL)
  2600.     {
  2601.       clock = thread->u.sands.tv_sec - timer_now.tv_sec;
  2602.       tm = gmtime (&clock);
  2603.       strftime (timebuf, TIME_BUF, "%M:%S", tm);
  2604.       vty_out (vty, "%5s", timebuf);
  2605.     }
  2606. }
  2607. char *
  2608. rip_route_type_print (int sub_type)
  2609. {
  2610.   switch (sub_type)
  2611.     {
  2612.     case RIP_ROUTE_RTE:
  2613.       return "n";
  2614.     case RIP_ROUTE_STATIC:
  2615.       return "s";
  2616.     case RIP_ROUTE_DEFAULT:
  2617.       return "d";
  2618.     case RIP_ROUTE_REDISTRIBUTE:
  2619.       return "r";
  2620.     case RIP_ROUTE_INTERFACE:
  2621.       return "i";
  2622.     default:
  2623.       return "?";
  2624.     }
  2625. }
  2626. DEFUN (show_ip_rip,
  2627.        show_ip_rip_cmd,
  2628.        "show ip rip",
  2629.        SHOW_STR
  2630.        IP_STR
  2631.        "Show RIP routesn")
  2632. {
  2633.   struct route_node *np;
  2634.   struct rip_info *rinfo;
  2635.   if (! rip)
  2636.     return CMD_SUCCESS;
  2637.   vty_out (vty, "Codes: R - RIP, C - connected, O - OSPF, B - BGP%s"
  2638.    "      (n) - normal, (s) - static, (d) - default, (r) - redistribute,%s"
  2639.    "      (i) - interface%s%s"
  2640.    "     Network            Next Hop         Metric From            Time%s",
  2641.    VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE, VTY_NEWLINE);
  2642.   
  2643.   for (np = route_top (rip->table); np; np = route_next (np))
  2644.     if ((rinfo = np->info) != NULL)
  2645.       {
  2646. int len;
  2647. len = vty_out (vty, "%s(%s) %s/%d",
  2648.        /* np->lock, For debugging. */
  2649.        route_info[rinfo->type].str,
  2650.        rip_route_type_print (rinfo->sub_type),
  2651.        inet_ntoa (np->p.u.prefix4), np->p.prefixlen);
  2652. len = 24 - len;
  2653. if (len > 0)
  2654.   vty_out (vty, "%*s", len, " ");
  2655.         if (rinfo->nexthop.s_addr) 
  2656.   vty_out (vty, "%-20s %2d ", inet_ntoa (rinfo->nexthop),
  2657.    rinfo->metric);
  2658.         else
  2659.   vty_out (vty, "0.0.0.0              %2d ", rinfo->metric);
  2660. /* Route which exist in kernel routing table. */
  2661. if ((rinfo->type == ZEBRA_ROUTE_RIP) && 
  2662.     (rinfo->sub_type == RIP_ROUTE_RTE))
  2663.   {
  2664.     vty_out (vty, "%-15s ", inet_ntoa (rinfo->from));
  2665.     rip_vty_out_uptime (vty, rinfo);
  2666.   }
  2667. else if (rinfo->metric == RIP_METRIC_INFINITY)
  2668.   {
  2669.     vty_out (vty, "self            ");
  2670.     rip_vty_out_uptime (vty, rinfo);
  2671.   }
  2672. else
  2673.   vty_out (vty, "self");
  2674. vty_out (vty, "%s", VTY_NEWLINE);
  2675.       }
  2676.   return CMD_SUCCESS;
  2677. }
  2678. /* Return next event time. */
  2679. int
  2680. rip_next_thread_timer (struct thread *thread)
  2681. {
  2682.   struct timeval timer_now;
  2683.   gettimeofday (&timer_now, NULL);
  2684.   return thread->u.sands.tv_sec - timer_now.tv_sec;
  2685. }
  2686. DEFUN (show_ip_protocols_rip,
  2687.        show_ip_protocols_rip_cmd,
  2688.        "show ip protocols",
  2689.        SHOW_STR
  2690.        IP_STR
  2691.        "IP routing protocol process parameters and statisticsn")
  2692. {
  2693.   listnode node;
  2694.   struct interface *ifp;
  2695.   struct rip_interface *ri;
  2696.   extern struct message ri_version_msg[];
  2697.   char *send_version;
  2698.   char *receive_version;
  2699.   if (! rip)
  2700.     return CMD_SUCCESS;
  2701.   vty_out (vty, "Routing Protocol is "rip"%s", VTY_NEWLINE);
  2702.   vty_out (vty, "  Sending updates every %ld seconds with +/-50%%,",
  2703.    rip->update_time);
  2704.   vty_out (vty, " next due in %d seconds%s", 
  2705.    rip_next_thread_timer (rip->t_update),
  2706.    VTY_NEWLINE);
  2707.   vty_out (vty, "  Timeout after %ld seconds,", rip->timeout_time);
  2708.   vty_out (vty, " garbage collect after %ld seconds%s", rip->garbage_time,
  2709.    VTY_NEWLINE);
  2710.   /* Filtering status show. */
  2711.   config_show_distribute (vty);
  2712.  
  2713.   /* Default metric information. */
  2714.   vty_out (vty, "  Default redistribution metric is %d%s",
  2715.    rip->default_metric, VTY_NEWLINE);
  2716.   /* Redistribute information. */
  2717.   vty_out (vty, "  Redistributing:");
  2718.   config_write_rip_redistribute (vty, 0);
  2719.   vty_out (vty, "%s", VTY_NEWLINE);
  2720.   vty_out (vty, "  Default version control: send version %d,", rip->version);
  2721.   vty_out (vty, " receive version %d %s", rip->version,
  2722.    VTY_NEWLINE);
  2723.   vty_out (vty, "    Interface        Send  Recv   Key-chain%s", VTY_NEWLINE);
  2724.   for (node = listhead (iflist); node; node = nextnode (node))
  2725.     {
  2726.       ifp = getdata (node);
  2727.       ri = ifp->info;
  2728.       if (ri->enable_network || ri->enable_interface)
  2729. {
  2730.   if (ri->ri_send == RI_RIP_UNSPEC)
  2731.     send_version = lookup (ri_version_msg, rip->version);
  2732.   else
  2733.     send_version = lookup (ri_version_msg, ri->ri_send);
  2734.   if (ri->ri_receive == RI_RIP_UNSPEC)
  2735.     receive_version = lookup (ri_version_msg, rip->version);
  2736.   else
  2737.     receive_version = lookup (ri_version_msg, ri->ri_receive);
  2738.   vty_out (vty, "    %-17s%-3s   %-3s    %s%s", ifp->name,
  2739.    send_version,
  2740.    receive_version,
  2741.    ri->key_chain ? ri->key_chain : "",
  2742.    VTY_NEWLINE);
  2743. }
  2744.     }
  2745.   vty_out (vty, "  Routing for Networks:%s", VTY_NEWLINE);
  2746.   config_write_rip_network (vty, 0);  
  2747.   vty_out (vty, "  Routing Information Sources:%s", VTY_NEWLINE);
  2748.   vty_out (vty, "    Gateway          BadPackets BadRoutes  Distance Last Update%s", VTY_NEWLINE);
  2749.   rip_peer_display (vty);
  2750.   rip_distance_show (vty);
  2751.   return CMD_SUCCESS;
  2752. }
  2753. /* RIP configuration write function. */
  2754. int
  2755. config_write_rip (struct vty *vty)
  2756. {
  2757.   int write = 0;
  2758.   struct route_node *rn;
  2759.   struct rip_distance *rdistance;
  2760.   if (rip)
  2761.     {
  2762.       /* Router RIP statement. */
  2763.       vty_out (vty, "router rip%s", VTY_NEWLINE);
  2764.       write++;
  2765.   
  2766.       /* RIP version statement.  Default is RIP version 2. */
  2767.       if (rip->version != RIPv2)
  2768. vty_out (vty, " version %d%s", rip->version,
  2769.  VTY_NEWLINE);
  2770.  
  2771.       /* RIP timer configuration. */
  2772.       if (rip->update_time != RIP_UPDATE_TIMER_DEFAULT 
  2773.   || rip->timeout_time != RIP_TIMEOUT_TIMER_DEFAULT 
  2774.   || rip->garbage_time != RIP_GARBAGE_TIMER_DEFAULT)
  2775. vty_out (vty, " timers basic %lu %lu %lu%s",
  2776.  rip->update_time,
  2777.  rip->timeout_time,
  2778.  rip->garbage_time,
  2779.  VTY_NEWLINE);
  2780.       /* Default information configuration. */
  2781.       if (rip->default_information)
  2782. {
  2783.   if (rip->default_information_route_map)
  2784.     vty_out (vty, " default-information originate route-map %s%s",
  2785.      rip->default_information_route_map, VTY_NEWLINE);
  2786.   else
  2787.     vty_out (vty, " default-information originate%s",
  2788.      VTY_NEWLINE);
  2789. }
  2790.       /* Redistribute configuration. */
  2791.       config_write_rip_redistribute (vty, 1);
  2792.       /* RIP offset-list configuration. */
  2793.       config_write_rip_offset_list (vty);
  2794.       /* RIP enabled network and interface configuration. */
  2795.       config_write_rip_network (vty, 1);
  2796.       /* RIP default metric configuration */
  2797.       if (rip->default_metric != RIP_DEFAULT_METRIC_DEFAULT)
  2798.         vty_out (vty, " default-metric %d%s",
  2799.  rip->default_metric, VTY_NEWLINE);
  2800.       /* Distribute configuration. */
  2801.       write += config_write_distribute (vty);
  2802.       /* Distance configuration. */
  2803.       if (rip->distance)
  2804. vty_out (vty, " distance %d%s", rip->distance, VTY_NEWLINE);
  2805.       /* RIP source IP prefix distance configuration. */
  2806.       for (rn = route_top (rip_distance_table); rn; rn = route_next (rn))
  2807. if ((rdistance = rn->info) != NULL)
  2808.   vty_out (vty, " distance %d %s/%d %s%s", rdistance->distance,
  2809.    inet_ntoa (rn->p.u.prefix4), rn->p.prefixlen,
  2810.    rdistance->access_list ? rdistance->access_list : "",
  2811.    VTY_NEWLINE);
  2812.       /* RIP static route configuration. */
  2813.       for (rn = route_top (rip->route); rn; rn = route_next (rn))
  2814. if (rn->info)
  2815.   vty_out (vty, " route %s/%d%s", 
  2816.    inet_ntoa (rn->p.u.prefix4),
  2817.    rn->p.prefixlen,
  2818.    VTY_NEWLINE);
  2819.     }
  2820.   return write;
  2821. }
  2822. /* RIP node structure. */
  2823. struct cmd_node rip_node =
  2824.   {
  2825.     RIP_NODE,
  2826.     "%s(config-router)# ",
  2827.     1
  2828.   };
  2829. /* Distribute-list update functions. */
  2830. void
  2831. rip_distribute_update (struct distribute *dist)
  2832. {
  2833.   struct interface *ifp;
  2834.   struct rip_interface *ri;
  2835.   struct access_list *alist;
  2836.   struct prefix_list *plist;
  2837.   if (! dist->ifname)
  2838.     return;
  2839.   ifp = if_lookup_by_name (dist->ifname);
  2840.   if (ifp == NULL)
  2841.     return;
  2842.   ri = ifp->info;
  2843.   if (dist->list[DISTRIBUTE_IN])
  2844.     {
  2845.       alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_IN]);
  2846.       if (alist)
  2847. ri->list[RIP_FILTER_IN] = alist;
  2848.       else
  2849. ri->list[RIP_FILTER_IN] = NULL;
  2850.     }
  2851.   else
  2852.     ri->list[RIP_FILTER_IN] = NULL;
  2853.   if (dist->list[DISTRIBUTE_OUT])
  2854.     {
  2855.       alist = access_list_lookup (AFI_IP, dist->list[DISTRIBUTE_OUT]);
  2856.       if (alist)
  2857. ri->list[RIP_FILTER_OUT] = alist;
  2858.       else
  2859. ri->list[RIP_FILTER_OUT] = NULL;
  2860.     }
  2861.   else
  2862.     ri->list[RIP_FILTER_OUT] = NULL;
  2863.   if (dist->prefix[DISTRIBUTE_IN])
  2864.     {
  2865.       plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_IN]);
  2866.       if (plist)
  2867. ri->prefix[RIP_FILTER_IN] = plist;
  2868.       else
  2869. ri->prefix[RIP_FILTER_IN] = NULL;
  2870.     }
  2871.   else
  2872.     ri->prefix[RIP_FILTER_IN] = NULL;
  2873.   if (dist->prefix[DISTRIBUTE_OUT])
  2874.     {
  2875.       plist = prefix_list_lookup (AFI_IP, dist->prefix[DISTRIBUTE_OUT]);
  2876.       if (plist)
  2877. ri->prefix[RIP_FILTER_OUT] = plist;
  2878.       else
  2879. ri->prefix[RIP_FILTER_OUT] = NULL;
  2880.     }
  2881.   else
  2882.     ri->prefix[RIP_FILTER_OUT] = NULL;
  2883. }
  2884. void
  2885. rip_distribute_update_interface (struct interface *ifp)
  2886. {
  2887.   struct distribute *dist;
  2888.   dist = distribute_lookup (ifp->name);
  2889.   if (dist)
  2890.     rip_distribute_update (dist);
  2891. }
  2892. /* Update all interface's distribute list. */
  2893. void
  2894. rip_distribute_update_all ()
  2895. {
  2896.   struct interface *ifp;
  2897.   listnode node;
  2898.   for (node = listhead (iflist); node; nextnode (node))
  2899.     {
  2900.       ifp = getdata (node);
  2901.       rip_distribute_update_interface (ifp);
  2902.     }
  2903. }
  2904. /* Delete all added rip route. */
  2905. void
  2906. rip_clean ()
  2907. {
  2908.   int i;
  2909.   struct route_node *rp;
  2910.   struct rip_info *rinfo;
  2911.   if (rip)
  2912.     {
  2913.       /* Clear RIP routes */
  2914.       for (rp = route_top (rip->table); rp; rp = route_next (rp))
  2915. if ((rinfo = rp->info) != NULL)
  2916.   {
  2917.     if (rinfo->type == ZEBRA_ROUTE_RIP &&
  2918. rinfo->sub_type == RIP_ROUTE_RTE)
  2919.       rip_zebra_ipv4_delete ((struct prefix_ipv4 *)&rp->p,
  2920.      &rinfo->nexthop, rinfo->metric);
  2921.     RIP_TIMER_OFF (rinfo->t_timeout);
  2922.     RIP_TIMER_OFF (rinfo->t_garbage_collect);
  2923.     rp->info = NULL;
  2924.     route_unlock_node (rp);
  2925.     rip_info_free (rinfo);
  2926.   }
  2927.       /* Cancel RIP related timers. */
  2928.       RIP_TIMER_OFF (rip->t_update);
  2929.       RIP_TIMER_OFF (rip->t_triggered_update);
  2930.       RIP_TIMER_OFF (rip->t_triggered_interval);
  2931.       /* Cancel read thread. */
  2932.       if (rip->t_read)
  2933. {
  2934.   thread_cancel (rip->t_read);
  2935.   rip->t_read = NULL;
  2936. }
  2937.       /* Close RIP socket. */
  2938.       if (rip->sock >= 0)
  2939. {
  2940.   close (rip->sock);
  2941.   rip->sock = -1;
  2942. }
  2943.       /* Static RIP route configuration. */
  2944.       for (rp = route_top (rip->route); rp; rp = route_next (rp))
  2945. if (rp->info)
  2946.   {
  2947.     rp->info = NULL;
  2948.     route_unlock_node (rp);
  2949.   }
  2950.       /* RIP neighbor configuration. */
  2951.       for (rp = route_top (rip->neighbor); rp; rp = route_next (rp))
  2952. if (rp->info)
  2953.   {
  2954.     rp->info = NULL;
  2955.     route_unlock_node (rp);
  2956.   }
  2957.       /* Redistribute related clear. */
  2958.       if (rip->default_information_route_map)
  2959. free (rip->default_information_route_map);
  2960.       for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
  2961. if (rip->route_map[i].name)
  2962.   free (rip->route_map[i].name);
  2963.       XFREE (MTYPE_ROUTE_TABLE, rip->table);
  2964.       XFREE (MTYPE_ROUTE_TABLE, rip->route);
  2965.       XFREE (MTYPE_ROUTE_TABLE, rip->neighbor);
  2966.       
  2967.       XFREE (MTYPE_RIP, rip);
  2968.       rip = NULL;
  2969.     }
  2970.   rip_clean_network ();
  2971.   rip_passive_interface_clean ();
  2972.   rip_offset_clean ();
  2973.   rip_interface_clean ();
  2974.   rip_distance_reset ();
  2975.   rip_redistribute_clean ();
  2976. }
  2977. /* Reset all values to the default settings. */
  2978. void
  2979. rip_reset ()
  2980. {
  2981.   /* Reset global counters. */
  2982.   rip_global_route_changes = 0;
  2983.   rip_global_queries = 0;
  2984.   /* Call ripd related reset functions. */
  2985.   rip_debug_reset ();
  2986.   rip_route_map_reset ();
  2987.   /* Call library reset functions. */
  2988.   vty_reset ();
  2989.   access_list_reset ();
  2990.   prefix_list_reset ();
  2991.   distribute_list_reset ();
  2992.   rip_interface_reset ();
  2993.   rip_distance_reset ();
  2994.   rip_zclient_reset ();
  2995. }
  2996. /* Allocate new rip structure and set default value. */
  2997. void
  2998. rip_init ()
  2999. {
  3000.   /* Randomize for triggered update random(). */
  3001.   srand (time (NULL));
  3002.   /* Install top nodes. */
  3003.   install_node (&rip_node, config_write_rip);
  3004.   /* Install rip commands. */
  3005.   install_element (VIEW_NODE, &show_ip_rip_cmd);
  3006.   install_element (VIEW_NODE, &show_ip_protocols_rip_cmd);
  3007.   install_element (ENABLE_NODE, &show_ip_rip_cmd);
  3008.   install_element (ENABLE_NODE, &show_ip_protocols_rip_cmd);
  3009.   install_element (CONFIG_NODE, &router_rip_cmd);
  3010.   install_element (CONFIG_NODE, &no_router_rip_cmd);
  3011.   install_default (RIP_NODE);
  3012.   install_element (RIP_NODE, &rip_version_cmd);
  3013.   install_element (RIP_NODE, &no_rip_version_cmd);
  3014.   install_element (RIP_NODE, &no_rip_version_val_cmd);
  3015.   install_element (RIP_NODE, &rip_default_metric_cmd);
  3016.   install_element (RIP_NODE, &no_rip_default_metric_cmd);
  3017.   install_element (RIP_NODE, &no_rip_default_metric_val_cmd);
  3018.   install_element (RIP_NODE, &rip_timers_cmd);
  3019.   install_element (RIP_NODE, &no_rip_timers_cmd);
  3020.   install_element (RIP_NODE, &rip_route_cmd);
  3021.   install_element (RIP_NODE, &no_rip_route_cmd);
  3022.   install_element (RIP_NODE, &rip_distance_cmd);
  3023.   install_element (RIP_NODE, &no_rip_distance_cmd);
  3024.   install_element (RIP_NODE, &rip_distance_source_cmd);
  3025.   install_element (RIP_NODE, &no_rip_distance_source_cmd);
  3026.   install_element (RIP_NODE, &rip_distance_source_access_list_cmd);
  3027.   install_element (RIP_NODE, &no_rip_distance_source_access_list_cmd);
  3028.   /* Debug related init. */
  3029.   rip_debug_init ();
  3030.   /* Filter related init. */
  3031.   rip_route_map_init ();
  3032.   rip_offset_init ();
  3033.   /* SNMP init. */
  3034. #ifdef HAVE_SNMP
  3035.   rip_snmp_init ();
  3036. #endif /* HAVE_SNMP */
  3037.   /* Access list install. */
  3038.   access_list_init ();
  3039.   access_list_add_hook (rip_distribute_update_all);
  3040.   access_list_delete_hook (rip_distribute_update_all);
  3041.   /* Prefix list initialize.*/
  3042.   prefix_list_init ();
  3043.   prefix_list_add_hook (rip_distribute_update_all);
  3044.   prefix_list_delete_hook (rip_distribute_update_all);
  3045.   /* Distribute list install. */
  3046.   distribute_list_init (RIP_NODE);
  3047.   distribute_list_add_hook (rip_distribute_update);
  3048.   distribute_list_delete_hook (rip_distribute_update);
  3049.   /* Distance control. */
  3050.   rip_distance_table = route_table_init ();
  3051. }