~ubuntu-branches/ubuntu/breezy/quagga/breezy-security

« back to all changes in this revision

Viewing changes to ripngd/ripng_peer.c

  • Committer: Bazaar Package Importer
  • Author(s): Andreas Mueller
  • Date: 2005-05-20 13:16:12 UTC
  • Revision ID: james.westby@ubuntu.com-20050520131612-pr6paalox60o3x3n
Tags: upstream-0.99.1
ImportĀ upstreamĀ versionĀ 0.99.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* RIPng 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
 
 
22
/* RIPng support added by Vincent Jardin <vincent.jardin@6wind.com>
 
23
 * Copyright (C) 2002 6WIND
 
24
 */
 
25
 
 
26
#include <zebra.h>
 
27
 
 
28
#include "if.h"
 
29
#include "prefix.h"
 
30
#include "command.h"
 
31
#include "linklist.h"
 
32
#include "thread.h"
 
33
#include "memory.h"
 
34
 
 
35
#include "ripngd/ripngd.h"
 
36
#include "ripngd/ripng_nexthop.h"
 
37
 
 
38
 
 
39
/* Linked list of RIPng peer. */
 
40
struct list *peer_list;
 
41
 
 
42
struct ripng_peer *
 
43
ripng_peer_new ()
 
44
{
 
45
  struct ripng_peer *new;
 
46
 
 
47
  new = XMALLOC (MTYPE_RIPNG_PEER, sizeof (struct ripng_peer));
 
48
  memset (new, 0, sizeof (struct ripng_peer));
 
49
  return new;
 
50
}
 
51
 
 
52
void
 
53
ripng_peer_free (struct ripng_peer *peer)
 
54
{
 
55
  XFREE (MTYPE_RIPNG_PEER, peer);
 
56
}
 
57
 
 
58
struct ripng_peer *
 
59
ripng_peer_lookup (struct in6_addr *addr)
 
60
{
 
61
  struct ripng_peer *peer;
 
62
  struct listnode *node, *nnode;
 
63
 
 
64
  for (ALL_LIST_ELEMENTS (peer_list, node, nnode, peer))
 
65
    {
 
66
      if (IPV6_ADDR_SAME (&peer->addr, addr))
 
67
        return peer;
 
68
    }
 
69
  return NULL;
 
70
}
 
71
 
 
72
struct ripng_peer *
 
73
ripng_peer_lookup_next (struct in6_addr *addr)
 
74
{
 
75
  struct ripng_peer *peer;
 
76
  struct listnode *node, *nnode;
 
77
 
 
78
  for (ALL_LIST_ELEMENTS (peer_list, node, nnode, peer))
 
79
    {
 
80
      if (addr6_cmp(&peer->addr, addr) > 0) 
 
81
        return peer;
 
82
    }
 
83
  return NULL;
 
84
}
 
85
 
 
86
/* RIPng peer is timeout.
 
87
 * Garbage collector.
 
88
 **/
 
89
int
 
90
ripng_peer_timeout (struct thread *t)
 
91
{
 
92
  struct ripng_peer *peer;
 
93
 
 
94
  peer = THREAD_ARG (t);
 
95
  listnode_delete (peer_list, peer);
 
96
  ripng_peer_free (peer);
 
97
 
 
98
  return 0;
 
99
}
 
100
 
 
101
/* Get RIPng peer.  At the same time update timeout thread. */
 
102
struct ripng_peer *
 
103
ripng_peer_get (struct in6_addr *addr)
 
104
{
 
105
  struct ripng_peer *peer;
 
106
 
 
107
  peer = ripng_peer_lookup (addr);
 
108
 
 
109
  if (peer)
 
110
    {
 
111
      if (peer->t_timeout)
 
112
        thread_cancel (peer->t_timeout);
 
113
    }
 
114
  else
 
115
    {
 
116
      peer = ripng_peer_new ();
 
117
      peer->addr = *addr; /* XXX */
 
118
      listnode_add_sort (peer_list, peer);
 
119
    }
 
120
 
 
121
  /* Update timeout thread. */
 
122
  peer->t_timeout = thread_add_timer (master, ripng_peer_timeout, peer,
 
123
                                      RIPNG_PEER_TIMER_DEFAULT);
 
124
 
 
125
  /* Last update time set. */
 
126
  time (&peer->uptime);
 
127
  
 
128
  return peer;
 
129
}
 
130
 
 
131
void
 
132
ripng_peer_update (struct sockaddr_in6 *from, u_char version)
 
133
{
 
134
  struct ripng_peer *peer;
 
135
  peer = ripng_peer_get (&from->sin6_addr);
 
136
  peer->version = version;
 
137
}
 
138
 
 
139
void
 
140
ripng_peer_bad_route (struct sockaddr_in6 *from)
 
141
{
 
142
  struct ripng_peer *peer;
 
143
  peer = ripng_peer_get (&from->sin6_addr);
 
144
  peer->recv_badroutes++;
 
145
}
 
146
 
 
147
void
 
148
ripng_peer_bad_packet (struct sockaddr_in6 *from)
 
149
{
 
150
  struct ripng_peer *peer;
 
151
  peer = ripng_peer_get (&from->sin6_addr);
 
152
  peer->recv_badpackets++;
 
153
}
 
154
 
 
155
/* Display peer uptime. */
 
156
char *
 
157
ripng_peer_uptime (struct ripng_peer *peer, char *buf, size_t len)
 
158
{
 
159
  time_t uptime;
 
160
  struct tm *tm;
 
161
 
 
162
  /* If there is no connection has been done before print `never'. */
 
163
  if (peer->uptime == 0)
 
164
    {
 
165
      snprintf (buf, len, "never   ");
 
166
      return buf;
 
167
    }
 
168
 
 
169
  /* Get current time. */
 
170
  uptime = time (NULL);
 
171
  uptime -= peer->uptime;
 
172
  tm = gmtime (&uptime);
 
173
 
 
174
  /* Making formatted timer strings. */
 
175
#define ONE_DAY_SECOND 60*60*24
 
176
#define ONE_WEEK_SECOND 60*60*24*7
 
177
 
 
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);
 
184
  else
 
185
    snprintf (buf, len, "%02dw%dd%02dh", 
 
186
              tm->tm_yday/7, tm->tm_yday - ((tm->tm_yday/7) * 7), tm->tm_hour);
 
187
  return buf;
 
188
}
 
189
 
 
190
void
 
191
ripng_peer_display (struct vty *vty)
 
192
{
 
193
  struct ripng_peer *peer;
 
194
  struct listnode *node, *nnode;
 
195
#define RIPNG_UPTIME_LEN 25
 
196
  char timebuf[RIPNG_UPTIME_LEN];
 
197
 
 
198
  for (ALL_LIST_ELEMENTS (peer_list, node, nnode, peer))
 
199
    {
 
200
      vty_out (vty, "    %s %s%14s %10d %10d %10d      %s%s", inet6_ntoa (peer->addr),
 
201
               VTY_NEWLINE, " ",
 
202
               peer->recv_badpackets, peer->recv_badroutes,
 
203
               ZEBRA_RIPNG_DISTANCE_DEFAULT,
 
204
               ripng_peer_uptime (peer, timebuf, RIPNG_UPTIME_LEN),
 
205
               VTY_NEWLINE);
 
206
    }
 
207
}
 
208
 
 
209
int
 
210
ripng_peer_list_cmp (struct ripng_peer *p1, struct ripng_peer *p2)
 
211
{
 
212
  return addr6_cmp(&p1->addr, &p2->addr) > 0;
 
213
}
 
214
 
 
215
void
 
216
ripng_peer_init ()
 
217
{
 
218
  peer_list = list_new ();
 
219
  peer_list->cmp = (int (*)(void *, void *)) ripng_peer_list_cmp;
 
220
}