2
* Copyright (C) 2000 Kunihiro Ishiguro <kunihiro@zebra.org>
4
* This file is part of GNU Zebra.
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
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.
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
22
/* RIPng support added by Vincent Jardin <vincent.jardin@6wind.com>
23
* Copyright (C) 2002 6WIND
35
#include "ripngd/ripngd.h"
36
#include "ripngd/ripng_nexthop.h"
39
/* Linked list of RIPng peer. */
40
struct list *peer_list;
45
struct ripng_peer *new;
47
new = XMALLOC (MTYPE_RIPNG_PEER, sizeof (struct ripng_peer));
48
memset (new, 0, sizeof (struct ripng_peer));
53
ripng_peer_free (struct ripng_peer *peer)
55
XFREE (MTYPE_RIPNG_PEER, peer);
59
ripng_peer_lookup (struct in6_addr *addr)
61
struct ripng_peer *peer;
62
struct listnode *node, *nnode;
64
for (ALL_LIST_ELEMENTS (peer_list, node, nnode, peer))
66
if (IPV6_ADDR_SAME (&peer->addr, addr))
73
ripng_peer_lookup_next (struct in6_addr *addr)
75
struct ripng_peer *peer;
76
struct listnode *node, *nnode;
78
for (ALL_LIST_ELEMENTS (peer_list, node, nnode, peer))
80
if (addr6_cmp(&peer->addr, addr) > 0)
86
/* RIPng peer is timeout.
90
ripng_peer_timeout (struct thread *t)
92
struct ripng_peer *peer;
94
peer = THREAD_ARG (t);
95
listnode_delete (peer_list, peer);
96
ripng_peer_free (peer);
101
/* Get RIPng peer. At the same time update timeout thread. */
103
ripng_peer_get (struct in6_addr *addr)
105
struct ripng_peer *peer;
107
peer = ripng_peer_lookup (addr);
112
thread_cancel (peer->t_timeout);
116
peer = ripng_peer_new ();
117
peer->addr = *addr; /* XXX */
118
listnode_add_sort (peer_list, peer);
121
/* Update timeout thread. */
122
peer->t_timeout = thread_add_timer (master, ripng_peer_timeout, peer,
123
RIPNG_PEER_TIMER_DEFAULT);
125
/* Last update time set. */
126
time (&peer->uptime);
132
ripng_peer_update (struct sockaddr_in6 *from, u_char version)
134
struct ripng_peer *peer;
135
peer = ripng_peer_get (&from->sin6_addr);
136
peer->version = version;
140
ripng_peer_bad_route (struct sockaddr_in6 *from)
142
struct ripng_peer *peer;
143
peer = ripng_peer_get (&from->sin6_addr);
144
peer->recv_badroutes++;
148
ripng_peer_bad_packet (struct sockaddr_in6 *from)
150
struct ripng_peer *peer;
151
peer = ripng_peer_get (&from->sin6_addr);
152
peer->recv_badpackets++;
155
/* Display peer uptime. */
157
ripng_peer_uptime (struct ripng_peer *peer, char *buf, size_t len)
162
/* If there is no connection has been done before print `never'. */
163
if (peer->uptime == 0)
165
snprintf (buf, len, "never ");
169
/* Get current time. */
170
uptime = time (NULL);
171
uptime -= peer->uptime;
172
tm = gmtime (&uptime);
174
/* Making formatted timer strings. */
175
#define ONE_DAY_SECOND 60*60*24
176
#define ONE_WEEK_SECOND 60*60*24*7
178
if (uptime < ONE_DAY_SECOND)
179
snprintf (buf, len, "%02d:%02d:%02d",
180
tm->tm_hour, tm->tm_min, tm->tm_sec);
181
else if (uptime < ONE_WEEK_SECOND)
182
snprintf (buf, len, "%dd%02dh%02dm",
183
tm->tm_yday, tm->tm_hour, tm->tm_min);
185
snprintf (buf, len, "%02dw%dd%02dh",
186
tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
191
ripng_peer_display (struct vty *vty)
193
struct ripng_peer *peer;
194
struct listnode *node, *nnode;
195
#define RIPNG_UPTIME_LEN 25
196
char timebuf[RIPNG_UPTIME_LEN];
198
for (ALL_LIST_ELEMENTS (peer_list, node, nnode, peer))
200
vty_out (vty, " %s %s%14s %10d %10d %10d %s%s", inet6_ntoa (peer->addr),
202
peer->recv_badpackets, peer->recv_badroutes,
203
ZEBRA_RIPNG_DISTANCE_DEFAULT,
204
ripng_peer_uptime (peer, timebuf, RIPNG_UPTIME_LEN),
210
ripng_peer_list_cmp (struct ripng_peer *p1, struct ripng_peer *p2)
212
return addr6_cmp(&p1->addr, &p2->addr) > 0;
218
peer_list = list_new ();
219
peer_list->cmp = (int (*)(void *, void *)) ripng_peer_list_cmp;