1 /***********************************************************************
2 * *
3 * This software is part of the ast package *
4 * Copyright (c) 2002-2012 AT&T Intellectual Property *
5 * and is licensed under the *
6 * Eclipse Public License, Version 1.0 *
7 * by AT&T Intellectual Property *
8 * *
9 * A copy of the License is available at *
10 * http://www.eclipse.org/org/documents/epl-v10.html *
11 * (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12 * *
13 * Information and Software Systems Research *
14 * AT&T Research *
15 * Florham Park NJ *
16 * *
17 * Glenn Fowler <gsf@research.att.com> *
18 * *
19 ***********************************************************************/
20 #pragma prototyped
21 /*
22 * bgp cisco ipv6 method
23 *
24 * Glenn Fowler
25 * AT&T Research
26 */
27
28 #include "bgplib.h"
29
30 typedef struct Ciscov6state_s
31 {
32 Bgproute_t route;
33 char* line;
34 unsigned char prefix[IP6PREFIX];
35 } Ciscov6state_t;
36
37 /*
38 * ciscov6 identf
39 */
40
41 static int
ciscov6ident(Dssfile_t * file,void * buf,size_t n,Dssdisc_t * disc)42 ciscov6ident(Dssfile_t* file, void* buf, size_t n, Dssdisc_t* disc)
43 {
44 register char* s;
45 register char* e;
46 register char* f;
47 register int c;
48 char* v;
49 int m;
50
51 static const char* magic[] = { "IPv6 Routing Table - ", "Codes: " };
52
53 m = 0;
54 v = 0;
55 s = (char*)buf;
56 e = s + n;
57 for (;;)
58 {
59 for (;;)
60 {
61 if (s >= e)
62 return 0;
63 c = *s++;
64 if (!isspace(c))
65 break;
66 }
67 f = s - 1;
68 for (;;)
69 {
70 if (s >= e)
71 return 0;
72 if (*s++ == '\n')
73 break;
74 }
75 if (!isascii(*f) && (s - f) > 256)
76 return 0;
77 v++;
78 if (strneq(f, magic[m], strlen(magic[m])) && ++m >= elementsof(magic))
79 {
80 file->caller = v;
81 break;
82 }
83 }
84 return 1;
85 }
86
87 /*
88 * ciscov6 openf
89 */
90
91 static int
ciscov6open(Dssfile_t * file,Dssdisc_t * disc)92 ciscov6open(Dssfile_t* file, Dssdisc_t* disc)
93 {
94 register char* v = file->caller;
95 register Ciscov6state_t* state;
96
97 if (!(state = vmnewof(file->dss->vm, 0, Ciscov6state_t, 1, 0)))
98 {
99 if (disc->errorf)
100 (*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
101 return -1;
102 }
103 file->data = state;
104 if ((file->flags & (DSS_FILE_WRITE|DSS_FILE_APPEND)) == DSS_FILE_WRITE)
105 {
106 sfprintf(file->io, "Codes: C - Connected, L - Local, S - Static, R - RIP, B - BGP\n\
107 U - Per-user Static route\n\
108 I1 - ISIS L1, I2 - ISIS L2, IA - ISIS interarea\n\
109 O - OSPF intra, OI - OSPF inter, OE1 - OSPF ext 1, OE2 - OSPF ext 2\n");
110 }
111 while (v-- && sfgetr(file->io, '\n', 0));
112 while ((state->line = sfgetr(file->io, '\n', 0)) && !isupper(*state->line));
113 return 0;
114 }
115
116 /*
117 * ciscov6 readf
118 */
119
120 static int
ciscov6read(register Dssfile_t * file,Dssrecord_t * record,Dssdisc_t * disc)121 ciscov6read(register Dssfile_t* file, Dssrecord_t* record, Dssdisc_t* disc)
122 {
123 register Ciscov6state_t* state = (Ciscov6state_t*)file->data;
124 register Bgproute_t* rp;
125 register char* s;
126 int o;
127 int p;
128 char* t;
129
130 rp = &state->route;
131 while (s = state->line)
132 {
133 t = s;
134 while (*s && *s != '\n' && *s != ' ' && *s != '\t')
135 s++;
136 switch (*t)
137 {
138 case 'B':
139 rp->set = 0;
140 rp->attr = BGP_valid;
141 rp->type = BGP_TYPE_table_dump;
142 rp->origin = BGP_ORIGIN_incomplete;
143 o = 0;
144 p = 0;
145 for (;;)
146 {
147 while (*s == ' ' || *s == '\t')
148 s++;
149 if (*s && *s != '\n')
150 {
151 t = s;
152 while (*s && *s != '\n' && *s != ' ' && *s != '\t')
153 s++;
154 while (*s == ' ' || *s == '\t')
155 s++;
156 switch (p)
157 {
158 case 0:
159 if (!strtoip6(t, NiL, rp->prefixv6, rp->prefixv6 + IP6BITS))
160 p = 1;
161 break;
162 case 1:
163 if ((s - t) > 3 && t[0] == 'v' && t[1] == 'i' && t[2] == 'a')
164 p = 2;
165 break;
166 case 2:
167 if (!strtoip6(t, NiL, rp->hop.v6, NiL))
168 p = 3;
169 break;
170 }
171 }
172 if ((!*s || *s == '\n') && (!(s = state->line = sfgetr(file->io, '\n', 0)) || *s != ' ' && *s != '\t' && *s != '\r' && *s != '\n'))
173 break;
174 }
175 if (p != 3)
176 return 0;
177 rp->set |= BGP_SET_prefixv6|BGP_SET_hopv6;
178 break;
179 default:
180 while ((state->line = sfgetr(file->io, '\n', 0)) && !isupper(*state->line));
181 continue;
182 }
183 memset(rp->data + o, 0, elementsof(rp->data) - o);
184 record->data = rp;
185 record->size = rp->size = (char*)(rp->data + o) - (char*)rp;
186 return 1;
187 }
188 return 0;
189 }
190
191 /*
192 * ciscov6 writef
193 */
194
195 static int
ciscov6write(Dssfile_t * file,Dssrecord_t * record,Dssdisc_t * disc)196 ciscov6write(Dssfile_t* file, Dssrecord_t* record, Dssdisc_t* disc)
197 {
198 #if 0
199 register Ciscov6state_t* state = (Ciscov6state_t*)file->data;
200 register Bgproute_t* rp = (Bgproute_t*)record->data;
201 register Sfio_t* io = file->io;
202 register int i;
203 register int j;
204 register int k;
205 Bgpasn_t* ap;
206 Bgpnum_t* np;
207
208 if (rp->type == BGP_TYPE_announce)
209 sfputc(io, '+');
210 else if (rp->type == BGP_TYPE_withdraw)
211 sfputc(io, '-');
212 else if (rp->attr & BGP_valid)
213 sfputc(io, '*');
214 else if (rp->attr & BGP_rib_failure)
215 sfputc(io, 'r');
216 else
217 sfputc(io, ' ');
218 if (rp->attr & BGP_best)
219 sfputc(io, '>');
220 else if (rp->attr & BGP_history)
221 sfputc(io, 'h');
222 else
223 sfputc(io, ' ');
224 if (rp->attr & BGP_atomic)
225 sfputc(io, 'a');
226 else if (rp->attr & BGP_damped)
227 sfputc(io, 'd');
228 else if (rp->attr & BGP_internal)
229 sfputc(io, 'i');
230 else if (rp->attr & BGP_suppressed)
231 sfputc(io, 's');
232 else if (rp->attr & BGP_stale)
233 sfputc(io, 'S');
234 else
235 sfputc(io, ' ');
236 if (rp->addr == state->paddr && rp->bits == state->pbits)
237 sfprintf(io, " ");
238 else
239 {
240 state->paddr = rp->addr;
241 state->pbits = rp->bits;
242 if (sfprintf(io, "%-16s", fmtip4(rp->addr, rp->bits)) > 16)
243 sfprintf(io, "\n ");
244 else
245 sfputc(io, ' ');
246 }
247 sfprintf(io, "%-19s ", fmtip4(rp->hop, -1));
248 if (rp->med)
249 sfprintf(io, "%6u ", rp->med);
250 else
251 sfprintf(io, " ");
252 if (rp->local)
253 sfprintf(io, "%6u ", rp->local);
254 else
255 sfprintf(io, " ");
256 sfprintf(io, "%6u", rp->weight);
257 if (j = rp->path.size)
258 {
259 ap = BGPPATH(rp);
260 for (i = 0; i < j; i++)
261 if (ap[i] == BGP_SET16)
262 {
263 if (k = ap[++i])
264 {
265 k += i - 1;
266 sfprintf(io, " {%u", ap[++i]);
267 while (i < k)
268 sfprintf(io, ",%u", ap[++i]);
269 sfputc(io, '}');
270 }
271 else
272 sfprintf(io, " %u", ap[++i]);
273 }
274 else
275 sfprintf(io, " %u", ap[i]);
276 }
277 if (rp->community.size)
278 {
279 sfputc(io, ' ');
280 sfputc(io, 'C');
281 ap = BGPCOMMUNITY(rp);
282 for (i = 0, j = rp->community.size; i < j; i += 2)
283 sfprintf(io, " %u:%u", ap[i], ap[i+1]);
284 }
285 if (rp->cluster.size)
286 {
287 sfputc(io, ' ');
288 sfputc(io, 'I');
289 np = BGPCLUSTER(rp);
290 for (i = 0, j = rp->cluster.size; i < j; i++)
291 sfprintf(io, " %lu", np[i]);
292 }
293 if (rp->time)
294 sfprintf(io, " T %s", fmttime("%K", rp->time));
295 if (rp->origin)
296 {
297 sfputc(io, ' ');
298 sfputc(io, rp->origin);
299 }
300 if (sfputc(io, '\n') == EOF)
301 {
302 if (disc->errorf)
303 (*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "%s: write error", file->format->name);
304 return -1;
305 }
306 #endif
307 return 0;
308 }
309
310 /*
311 * ciscov6 closef
312 */
313
314 static int
ciscov6close(Dssfile_t * file,Dssdisc_t * disc)315 ciscov6close(Dssfile_t* file, Dssdisc_t* disc)
316 {
317 if (!file->data)
318 return -1;
319 vmfree(file->dss->vm, file->data);
320 return 0;
321 }
322
323 Dssformat_t bgp_ciscov6_format =
324 {
325 "ciscov6",
326 "cisco ipv6 router dump format (2009-03-15)",
327 CXH,
328 ciscov6ident,
329 ciscov6open,
330 ciscov6read,
331 ciscov6write,
332 0,
333 ciscov6close,
334 0,
335 0,
336 bgp_ciscov6_next
337 };
338