Annotation of embedaddon/quagga/ripd/rip_peer.c, revision 1.1

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