Annotation of embedaddon/quagga/ripngd/ripng_peer.c, revision 1.1

1.1     ! misho       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>