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 along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
30 #include "ripd/ripd.h"
32 /* Linked list of RIP peer. */
33 struct list
*peer_list
;
35 static struct rip_peer
*
38 return XCALLOC (MTYPE_RIP_PEER
, sizeof (struct rip_peer
));
42 rip_peer_free (struct rip_peer
*peer
)
44 XFREE (MTYPE_RIP_PEER
, peer
);
48 rip_peer_lookup (struct in_addr
*addr
)
50 struct rip_peer
*peer
;
51 struct listnode
*node
, *nnode
;
53 for (ALL_LIST_ELEMENTS (peer_list
, node
, nnode
, peer
))
55 if (IPV4_ADDR_SAME (&peer
->addr
, addr
))
62 rip_peer_lookup_next (struct in_addr
*addr
)
64 struct rip_peer
*peer
;
65 struct listnode
*node
, *nnode
;
67 for (ALL_LIST_ELEMENTS (peer_list
, node
, nnode
, peer
))
69 if (htonl (peer
->addr
.s_addr
) > htonl (addr
->s_addr
))
75 /* RIP peer is timeout. */
77 rip_peer_timeout (struct thread
*t
)
79 struct rip_peer
*peer
;
81 peer
= THREAD_ARG (t
);
82 listnode_delete (peer_list
, peer
);
88 /* Get RIP peer. At the same time update timeout thread. */
89 static struct rip_peer
*
90 rip_peer_get (struct in_addr
*addr
)
92 struct rip_peer
*peer
;
94 peer
= rip_peer_lookup (addr
);
99 thread_cancel (peer
->t_timeout
);
103 peer
= rip_peer_new ();
105 listnode_add_sort (peer_list
, peer
);
108 /* Update timeout thread. */
109 peer
->t_timeout
= NULL
;
110 thread_add_timer(master
, rip_peer_timeout
, peer
, RIP_PEER_TIMER_DEFAULT
,
113 /* Last update time set. */
114 time (&peer
->uptime
);
120 rip_peer_update (struct sockaddr_in
*from
, u_char version
)
122 struct rip_peer
*peer
;
123 peer
= rip_peer_get (&from
->sin_addr
);
124 peer
->version
= version
;
128 rip_peer_bad_route (struct sockaddr_in
*from
)
130 struct rip_peer
*peer
;
131 peer
= rip_peer_get (&from
->sin_addr
);
132 peer
->recv_badroutes
++;
136 rip_peer_bad_packet (struct sockaddr_in
*from
)
138 struct rip_peer
*peer
;
139 peer
= rip_peer_get (&from
->sin_addr
);
140 peer
->recv_badpackets
++;
143 /* Display peer uptime. */
145 rip_peer_uptime (struct rip_peer
*peer
, char *buf
, size_t len
)
150 /* If there is no connection has been done before print `never'. */
151 if (peer
->uptime
== 0)
153 snprintf (buf
, len
, "never ");
157 /* Get current time. */
158 uptime
= time (NULL
);
159 uptime
-= peer
->uptime
;
160 tm
= gmtime (&uptime
);
162 /* Making formatted timer strings. */
163 #define ONE_DAY_SECOND 60*60*24
164 #define ONE_WEEK_SECOND 60*60*24*7
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
);
173 snprintf (buf
, len
, "%02dw%dd%02dh",
174 tm
->tm_yday
/7, tm
->tm_yday
- ((tm
->tm_yday
/7) * 7), tm
->tm_hour
);
179 rip_peer_display (struct vty
*vty
)
181 struct rip_peer
*peer
;
182 struct listnode
*node
, *nnode
;
183 #define RIP_UPTIME_LEN 25
184 char timebuf
[RIP_UPTIME_LEN
];
186 for (ALL_LIST_ELEMENTS (peer_list
, node
, nnode
, peer
))
188 vty_out (vty
, " %-16s %9d %9d %9d %s\n", 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
));
196 rip_peer_list_cmp (struct rip_peer
*p1
, struct rip_peer
*p2
)
198 return htonl (p1
->addr
.s_addr
) > htonl (p2
->addr
.s_addr
);
204 peer_list
= list_new ();
205 peer_list
->cmp
= (int (*)(void *, void *)) rip_peer_list_cmp
;