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