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
*
41 new = XMALLOC (MTYPE_RIP_PEER
, sizeof (struct rip_peer
));
42 memset (new, 0, sizeof (struct rip_peer
));
47 rip_peer_free (struct rip_peer
*peer
)
49 XFREE (MTYPE_RIP_PEER
, peer
);
53 rip_peer_lookup (struct in_addr
*addr
)
55 struct rip_peer
*peer
;
56 struct listnode
*node
, *nnode
;
58 for (ALL_LIST_ELEMENTS (peer_list
, node
, nnode
, peer
))
60 if (IPV4_ADDR_SAME (&peer
->addr
, addr
))
67 rip_peer_lookup_next (struct in_addr
*addr
)
69 struct rip_peer
*peer
;
70 struct listnode
*node
, *nnode
;
72 for (ALL_LIST_ELEMENTS (peer_list
, node
, nnode
, peer
))
74 if (htonl (peer
->addr
.s_addr
) > htonl (addr
->s_addr
))
80 /* RIP peer is timeout. */
82 rip_peer_timeout (struct thread
*t
)
84 struct rip_peer
*peer
;
86 peer
= THREAD_ARG (t
);
87 listnode_delete (peer_list
, peer
);
93 /* Get RIP peer. At the same time update timeout thread. */
94 static struct rip_peer
*
95 rip_peer_get (struct in_addr
*addr
)
97 struct rip_peer
*peer
;
99 peer
= rip_peer_lookup (addr
);
104 thread_cancel (peer
->t_timeout
);
108 peer
= rip_peer_new ();
110 listnode_add_sort (peer_list
, peer
);
113 /* Update timeout thread. */
114 peer
->t_timeout
= thread_add_timer (master
, rip_peer_timeout
, peer
,
115 RIP_PEER_TIMER_DEFAULT
);
117 /* Last update time set. */
118 time (&peer
->uptime
);
124 rip_peer_update (struct sockaddr_in
*from
, u_char version
)
126 struct rip_peer
*peer
;
127 peer
= rip_peer_get (&from
->sin_addr
);
128 peer
->version
= version
;
132 rip_peer_bad_route (struct sockaddr_in
*from
)
134 struct rip_peer
*peer
;
135 peer
= rip_peer_get (&from
->sin_addr
);
136 peer
->recv_badroutes
++;
140 rip_peer_bad_packet (struct sockaddr_in
*from
)
142 struct rip_peer
*peer
;
143 peer
= rip_peer_get (&from
->sin_addr
);
144 peer
->recv_badpackets
++;
147 /* Display peer uptime. */
149 rip_peer_uptime (struct rip_peer
*peer
, char *buf
, size_t len
)
154 /* If there is no connection has been done before print `never'. */
155 if (peer
->uptime
== 0)
157 snprintf (buf
, len
, "never ");
161 /* Get current time. */
162 uptime
= time (NULL
);
163 uptime
-= peer
->uptime
;
164 tm
= gmtime (&uptime
);
166 /* Making formatted timer strings. */
167 #define ONE_DAY_SECOND 60*60*24
168 #define ONE_WEEK_SECOND 60*60*24*7
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
);
177 snprintf (buf
, len
, "%02dw%dd%02dh",
178 tm
->tm_yday
/7, tm
->tm_yday
- ((tm
->tm_yday
/7) * 7), tm
->tm_hour
);
183 rip_peer_display (struct vty
*vty
)
185 struct rip_peer
*peer
;
186 struct listnode
*node
, *nnode
;
187 #define RIP_UPTIME_LEN 25
188 char timebuf
[RIP_UPTIME_LEN
];
190 for (ALL_LIST_ELEMENTS (peer_list
, node
, nnode
, peer
))
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
),
201 rip_peer_list_cmp (struct rip_peer
*p1
, struct rip_peer
*p2
)
203 return htonl (p1
->addr
.s_addr
) > htonl (p2
->addr
.s_addr
);
209 peer_list
= list_new ();
210 peer_list
->cmp
= (int (*)(void *, void *)) rip_peer_list_cmp
;