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

    1: /* RIPng 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: /* RIPng support added by Vincent Jardin <vincent.jardin@6wind.com>
   23:  * Copyright (C) 2002 6WIND
   24:  */
   25: 
   26: #include <zebra.h>
   27: 
   28: #include "if.h"
   29: #include "prefix.h"
   30: #include "command.h"
   31: #include "linklist.h"
   32: #include "thread.h"
   33: #include "memory.h"
   34: 
   35: #include "ripngd/ripngd.h"
   36: #include "ripngd/ripng_nexthop.h"
   37: 
   38: 
   39: /* Linked list of RIPng peer. */
   40: struct list *peer_list;
   41: 
   42: static struct ripng_peer *
   43: ripng_peer_new (void)
   44: {
   45:   return XCALLOC (MTYPE_RIPNG_PEER, sizeof (struct ripng_peer));
   46: }
   47: 
   48: static void
   49: ripng_peer_free (struct ripng_peer *peer)
   50: {
   51:   XFREE (MTYPE_RIPNG_PEER, peer);
   52: }
   53: 
   54: struct ripng_peer *
   55: ripng_peer_lookup (struct in6_addr *addr)
   56: {
   57:   struct ripng_peer *peer;
   58:   struct listnode *node, *nnode;
   59: 
   60:   for (ALL_LIST_ELEMENTS (peer_list, node, nnode, peer))
   61:     {
   62:       if (IPV6_ADDR_SAME (&peer->addr, addr))
   63: 	return peer;
   64:     }
   65:   return NULL;
   66: }
   67: 
   68: struct ripng_peer *
   69: ripng_peer_lookup_next (struct in6_addr *addr)
   70: {
   71:   struct ripng_peer *peer;
   72:   struct listnode *node, *nnode;
   73: 
   74:   for (ALL_LIST_ELEMENTS (peer_list, node, nnode, peer))
   75:     {
   76:       if (addr6_cmp(&peer->addr, addr) > 0) 
   77: 	return peer;
   78:     }
   79:   return NULL;
   80: }
   81: 
   82: /* RIPng peer is timeout.
   83:  * Garbage collector.
   84:  **/
   85: static int
   86: ripng_peer_timeout (struct thread *t)
   87: {
   88:   struct ripng_peer *peer;
   89: 
   90:   peer = THREAD_ARG (t);
   91:   listnode_delete (peer_list, peer);
   92:   ripng_peer_free (peer);
   93: 
   94:   return 0;
   95: }
   96: 
   97: /* Get RIPng peer.  At the same time update timeout thread. */
   98: static struct ripng_peer *
   99: ripng_peer_get (struct in6_addr *addr)
  100: {
  101:   struct ripng_peer *peer;
  102: 
  103:   peer = ripng_peer_lookup (addr);
  104: 
  105:   if (peer)
  106:     {
  107:       if (peer->t_timeout)
  108: 	thread_cancel (peer->t_timeout);
  109:     }
  110:   else
  111:     {
  112:       peer = ripng_peer_new ();
  113:       peer->addr = *addr; /* XXX */
  114:       listnode_add_sort (peer_list, peer);
  115:     }
  116: 
  117:   /* Update timeout thread. */
  118:   peer->t_timeout = thread_add_timer (master, ripng_peer_timeout, peer,
  119: 				      RIPNG_PEER_TIMER_DEFAULT);
  120: 
  121:   /* Last update time set. */
  122:   time (&peer->uptime);
  123:   
  124:   return peer;
  125: }
  126: 
  127: void
  128: ripng_peer_update (struct sockaddr_in6 *from, u_char version)
  129: {
  130:   struct ripng_peer *peer;
  131:   peer = ripng_peer_get (&from->sin6_addr);
  132:   peer->version = version;
  133: }
  134: 
  135: void
  136: ripng_peer_bad_route (struct sockaddr_in6 *from)
  137: {
  138:   struct ripng_peer *peer;
  139:   peer = ripng_peer_get (&from->sin6_addr);
  140:   peer->recv_badroutes++;
  141: }
  142: 
  143: void
  144: ripng_peer_bad_packet (struct sockaddr_in6 *from)
  145: {
  146:   struct ripng_peer *peer;
  147:   peer = ripng_peer_get (&from->sin6_addr);
  148:   peer->recv_badpackets++;
  149: }
  150: 
  151: /* Display peer uptime. */
  152: static char *
  153: ripng_peer_uptime (struct ripng_peer *peer, char *buf, size_t len)
  154: {
  155:   time_t uptime;
  156:   struct tm *tm;
  157: 
  158:   /* If there is no connection has been done before print `never'. */
  159:   if (peer->uptime == 0)
  160:     {
  161:       snprintf (buf, len, "never   ");
  162:       return buf;
  163:     }
  164: 
  165:   /* Get current time. */
  166:   uptime = time (NULL);
  167:   uptime -= peer->uptime;
  168:   tm = gmtime (&uptime);
  169: 
  170:   /* Making formatted timer strings. */
  171: #define ONE_DAY_SECOND 60*60*24
  172: #define ONE_WEEK_SECOND 60*60*24*7
  173: 
  174:   if (uptime < ONE_DAY_SECOND)
  175:     snprintf (buf, len, "%02d:%02d:%02d", 
  176: 	      tm->tm_hour, tm->tm_min, tm->tm_sec);
  177:   else if (uptime < ONE_WEEK_SECOND)
  178:     snprintf (buf, len, "%dd%02dh%02dm", 
  179: 	      tm->tm_yday, tm->tm_hour, tm->tm_min);
  180:   else
  181:     snprintf (buf, len, "%02dw%dd%02dh", 
  182: 	      tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
  183:   return buf;
  184: }
  185: 
  186: void
  187: ripng_peer_display (struct vty *vty)
  188: {
  189:   struct ripng_peer *peer;
  190:   struct listnode *node, *nnode;
  191: #define RIPNG_UPTIME_LEN 25
  192:   char timebuf[RIPNG_UPTIME_LEN];
  193: 
  194:   for (ALL_LIST_ELEMENTS (peer_list, node, nnode, peer))
  195:     {
  196:       vty_out (vty, "    %s %s%14s %10d %10d %10d      %s%s", inet6_ntoa (peer->addr),
  197:                VTY_NEWLINE, " ",
  198: 	       peer->recv_badpackets, peer->recv_badroutes,
  199: 	       ZEBRA_RIPNG_DISTANCE_DEFAULT,
  200: 	       ripng_peer_uptime (peer, timebuf, RIPNG_UPTIME_LEN),
  201: 	       VTY_NEWLINE);
  202:     }
  203: }
  204: 
  205: static int
  206: ripng_peer_list_cmp (struct ripng_peer *p1, struct ripng_peer *p2)
  207: {
  208:   return addr6_cmp(&p1->addr, &p2->addr) > 0;
  209: }
  210: 
  211: void
  212: ripng_peer_init ()
  213: {
  214:   peer_list = list_new ();
  215:   peer_list->cmp = (int (*)(void *, void *)) ripng_peer_list_cmp;
  216: }

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