File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / quagga / ripd / rip_peer.c
Revision 1.1.1.2 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Nov 2 10:09:10 2016 UTC (7 years, 8 months ago) by misho
Branches: quagga, MAIN
CVS tags: v1_0_20160315, HEAD
quagga 1.0.20160315

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>