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

网络

开发平台:

Unix_Linux

  1. /* RIP peer support
  2.  * Copyright (C) 2000 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 "prefix.h"
  24. #include "command.h"
  25. #include "linklist.h"
  26. #include "thread.h"
  27. #include "memory.h"
  28. #include "ripd/ripd.h"
  29. /* Linked list of RIP peer. */
  30. struct list *peer_list;
  31. struct rip_peer *
  32. rip_peer_new ()
  33. {
  34.   struct rip_peer *new;
  35.   new = XMALLOC (MTYPE_RIP_PEER, sizeof (struct rip_peer));
  36.   memset (new, 0, sizeof (struct rip_peer));
  37.   return new;
  38. }
  39. void
  40. rip_peer_free (struct rip_peer *peer)
  41. {
  42.   XFREE (MTYPE_RIP_PEER, peer);
  43. }
  44. struct rip_peer *
  45. rip_peer_lookup (struct in_addr *addr)
  46. {
  47.   struct rip_peer *peer;
  48.   struct listnode *nn;
  49.   LIST_LOOP (peer_list, peer, nn)
  50.     {
  51.       if (IPV4_ADDR_SAME (&peer->addr, addr))
  52. return peer;
  53.     }
  54.   return NULL;
  55. }
  56. struct rip_peer *
  57. rip_peer_lookup_next (struct in_addr *addr)
  58. {
  59.   struct rip_peer *peer;
  60.   struct listnode *nn;
  61.   LIST_LOOP (peer_list, peer, nn)
  62.     {
  63.       if (htonl (peer->addr.s_addr) > htonl (addr->s_addr))
  64. return peer;
  65.     }
  66.   return NULL;
  67. }
  68. /* RIP peer is timeout. */
  69. int
  70. rip_peer_timeout (struct thread *t)
  71. {
  72.   struct rip_peer *peer;
  73.   peer = THREAD_ARG (t);
  74.   listnode_delete (peer_list, peer);
  75.   rip_peer_free (peer);
  76.   return 0;
  77. }
  78. /* Get RIP peer.  At the same time update timeout thread. */
  79. struct rip_peer *
  80. rip_peer_get (struct in_addr *addr)
  81. {
  82.   struct rip_peer *peer;
  83.   peer = rip_peer_lookup (addr);
  84.   if (peer)
  85.     {
  86.       if (peer->t_timeout)
  87. thread_cancel (peer->t_timeout);
  88.     }
  89.   else
  90.     {
  91.       peer = rip_peer_new ();
  92.       peer->addr = *addr;
  93.       listnode_add_sort (peer_list, peer);
  94.     }
  95.   /* Update timeout thread. */
  96.   peer->t_timeout = thread_add_timer (master, rip_peer_timeout, peer,
  97.       RIP_PEER_TIMER_DEFAULT);
  98.   /* Last update time set. */
  99.   time (&peer->uptime);
  100.   
  101.   return peer;
  102. }
  103. void
  104. rip_peer_update (struct sockaddr_in *from, u_char version)
  105. {
  106.   struct rip_peer *peer;
  107.   peer = rip_peer_get (&from->sin_addr);
  108.   peer->version = version;
  109. }
  110. void
  111. rip_peer_bad_route (struct sockaddr_in *from)
  112. {
  113.   struct rip_peer *peer;
  114.   peer = rip_peer_get (&from->sin_addr);
  115.   peer->recv_badroutes++;
  116. }
  117. void
  118. rip_peer_bad_packet (struct sockaddr_in *from)
  119. {
  120.   struct rip_peer *peer;
  121.   peer = rip_peer_get (&from->sin_addr);
  122.   peer->recv_badpackets++;
  123. }
  124. /* Display peer uptime. */
  125. char *
  126. rip_peer_uptime (struct rip_peer *peer, char *buf, size_t len)
  127. {
  128.   time_t uptime;
  129.   struct tm *tm;
  130.   /* If there is no connection has been done before print `never'. */
  131.   if (peer->uptime == 0)
  132.     {
  133.       snprintf (buf, len, "never   ");
  134.       return buf;
  135.     }
  136.   /* Get current time. */
  137.   uptime = time (NULL);
  138.   uptime -= peer->uptime;
  139.   tm = gmtime (&uptime);
  140.   /* Making formatted timer strings. */
  141. #define ONE_DAY_SECOND 60*60*24
  142. #define ONE_WEEK_SECOND 60*60*24*7
  143.   if (uptime < ONE_DAY_SECOND)
  144.     snprintf (buf, len, "%02d:%02d:%02d", 
  145.       tm->tm_hour, tm->tm_min, tm->tm_sec);
  146.   else if (uptime < ONE_WEEK_SECOND)
  147.     snprintf (buf, len, "%dd%02dh%02dm", 
  148.       tm->tm_yday, tm->tm_hour, tm->tm_min);
  149.   else
  150.     snprintf (buf, len, "%02dw%dd%02dh", 
  151.       tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
  152.   return buf;
  153. }
  154. void
  155. rip_peer_display (struct vty *vty)
  156. {
  157.   struct rip_peer *peer;
  158.   struct listnode *nn;
  159. #define RIP_UPTIME_LEN 25
  160.   char timebuf[RIP_UPTIME_LEN];
  161.   LIST_LOOP (peer_list, peer, nn)
  162.     {
  163.       vty_out (vty, "    %-16s %9d %9d %9d   %s%s", inet_ntoa (peer->addr),
  164.        peer->recv_badpackets, peer->recv_badroutes,
  165.        ZEBRA_RIP_DISTANCE_DEFAULT,
  166.        rip_peer_uptime (peer, timebuf, RIP_UPTIME_LEN),
  167.        VTY_NEWLINE);
  168.     }
  169. }
  170. int
  171. rip_peer_list_cmp (struct rip_peer *p1, struct rip_peer *p2)
  172. {
  173.   return htonl (p1->addr.s_addr) > htonl (p2->addr.s_addr);
  174. }
  175. void
  176. rip_peer_init ()
  177. {
  178.   peer_list = list_new ();
  179.   peer_list->cmp = (int (*)(void *, void *)) rip_peer_list_cmp;
  180. }