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

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;
1.1.1.2 ! misho      41: 
1.1       misho      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>