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
31 #include "ripd/ripd.h"
33 /* Linked list of RIP peer. */
34 struct list
*peer_list
;
36 static struct rip_peer
*
39 return XCALLOC (MTYPE_RIP_PEER
, sizeof (struct rip_peer
));
43 rip_peer_free (struct rip_peer
*peer
)
45 XFREE (MTYPE_RIP_PEER
, peer
);
49 rip_peer_lookup (struct in_addr
*addr
)
51 struct rip_peer
*peer
;
52 struct listnode
*node
, *nnode
;
54 for (ALL_LIST_ELEMENTS (peer_list
, node
, nnode
, peer
))
56 if (IPV4_ADDR_SAME (&peer
->addr
, addr
))
63 rip_peer_lookup_next (struct in_addr
*addr
)
65 struct rip_peer
*peer
;
66 struct listnode
*node
, *nnode
;
68 for (ALL_LIST_ELEMENTS (peer_list
, node
, nnode
, peer
))
70 if (htonl (peer
->addr
.s_addr
) > htonl (addr
->s_addr
))
76 /* RIP peer is timeout. */
78 rip_peer_timeout (struct thread
*t
)
80 struct rip_peer
*peer
;
82 peer
= THREAD_ARG (t
);
83 listnode_delete (peer_list
, peer
);
89 /* Get RIP peer. At the same time update timeout thread. */
90 static struct rip_peer
*
91 rip_peer_get (struct in_addr
*addr
)
93 struct rip_peer
*peer
;
95 peer
= rip_peer_lookup (addr
);
100 thread_cancel (peer
->t_timeout
);
104 peer
= rip_peer_new ();
106 listnode_add_sort (peer_list
, peer
);
109 /* Update timeout thread. */
110 peer
->t_timeout
= thread_add_timer (master
, rip_peer_timeout
, peer
,
111 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%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
),
197 rip_peer_list_cmp (struct rip_peer
*p1
, struct rip_peer
*p2
)
199 return htonl (p1
->addr
.s_addr
) > htonl (p2
->addr
.s_addr
);
205 peer_list
= list_new ();
206 peer_list
->cmp
= (int (*)(void *, void *)) rip_peer_list_cmp
;