Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/dsslib/bgp/bgp-ipma.c
1810 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 2002-2011 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 <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
/*
22
* bgp ipma method
23
*
24
* Glenn Fowler
25
* AT&T Research
26
*/
27
28
#include "bgplib.h"
29
30
typedef struct Ipmastate_s
31
{
32
Bgproute_t route;
33
Bgpnum_t paddr;
34
Bgpnum_t pbits;
35
} Ipmastate_t;
36
37
static const char magic1[] = "Internet Performance Measurement and Analysis";
38
static const char magic2[] = "AS Path";
39
40
/*
41
* ipma identf
42
*/
43
44
static int
45
ipmaident(Dssfile_t* file, void* buf, size_t n, Dssdisc_t* disc)
46
{
47
register char* s;
48
register char* e;
49
register char* e1;
50
register char* e2;
51
52
s = (char*)buf;
53
e = s + n;
54
e1 = e - sizeof(magic1) + 1;
55
e2 = e - sizeof(magic2) + 1;
56
e = (e1 > e2) ? e1 : e2;
57
while (s < e)
58
{
59
if (s < e1 && strneq(s, magic1, sizeof(magic1) - 1) || s < e2 && strneq(s, magic2, sizeof(magic2) - 1))
60
return 1;
61
s++;
62
}
63
return 0;
64
}
65
66
/*
67
* ipma openf
68
*/
69
70
static int
71
ipmaopen(Dssfile_t* file, Dssdisc_t* disc)
72
{
73
register char* s;
74
register char* e;
75
register char* e1;
76
register char* e2;
77
register int c;
78
register int q;
79
80
if (!(file->data = (void*)vmnewof(file->dss->vm, 0, Ipmastate_t, 1, 0)))
81
{
82
if (disc->errorf)
83
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
84
return -1;
85
}
86
if (file->flags & DSS_FILE_READ)
87
{
88
while (s = sfgetr(file->io, '\n', 0))
89
{
90
e = s + sfvalue(file->io);
91
e1 = e - sizeof(magic1) + 1;
92
e2 = e - sizeof(magic2) + 1;
93
e = (e1 > e2) ? e1 : e2;
94
while (s < e)
95
{
96
if (s < e1 && strneq(s, magic1, sizeof(magic1) - 1) || s < e2 && strneq(s, magic2, sizeof(magic2) - 1))
97
break;
98
s++;
99
}
100
if (s < e)
101
break;
102
}
103
q = 0;
104
for (;;)
105
{
106
switch (c = sfgetc(file->io))
107
{
108
case EOF:
109
break;
110
case '\n':
111
q = 0;
112
continue;
113
case '0': case '1': case '2': case '3': case '4':
114
case '5': case '6': case '7': case '8': case '9':
115
if (q == 0)
116
{
117
sfungetc(file->io, c);
118
break;
119
}
120
continue;
121
case '<':
122
if (q == 0 || q == '&')
123
q = c;
124
continue;
125
case '>':
126
if (q == '<' || q == '&')
127
q = 0;
128
else if (q == 0)
129
q = '#';
130
continue;
131
case '&':
132
if (q == 0)
133
q = c;
134
continue;
135
default:
136
if (q == 0)
137
{
138
if (!isspace(c))
139
q = '#';
140
}
141
else if (q == '&')
142
{
143
if (!isalnum(c) && c != '#')
144
q = 0;
145
}
146
continue;
147
}
148
break;
149
}
150
((Ipmastate_t*)file->data)->route.attr = BGP_best;
151
((Ipmastate_t*)file->data)->route.type = BGP_TYPE_table_dump;
152
}
153
else if (!(file->flags & DSS_FILE_APPEND))
154
sfprintf(file->io, "%s\n\n", magic1);
155
return 0;
156
}
157
158
/*
159
* skip over html
160
* number==1 skips to next number
161
*/
162
163
static char*
164
skip(register char* s, register char* e, int number)
165
{
166
register char* b;
167
register char* t;
168
169
do
170
{
171
b = s;
172
while (s < e && isspace(*s))
173
s++;
174
if (*s == '<')
175
{
176
while (s < e && *s++ != '>');
177
while (s < e && isspace(*s))
178
s++;
179
}
180
if (*s == '&')
181
{
182
if (*++s == '#' && s < e)
183
s++;
184
while (s < e && isalnum(*s))
185
s++;
186
}
187
if (s < e && number)
188
{
189
if ((isdigit(*s) || (e - s) > 5 && strneq(s, "local", 5)) && (isspace(*(s - 1)) || *(s - 1) == '>' || *(s - 1) == ';' || *(s - 1) == '='))
190
{
191
if (!isdigit(*s))
192
break;
193
for (t = s; t < e && isdigit(*t); t++);
194
if (t >= e || isspace(*t) || *t == '<' || *t == '&')
195
break;
196
s = t;
197
}
198
if (*s == '=' && (e - s) > 1 && isdigit(*(s + 1)))
199
{
200
s++;
201
break;
202
}
203
while (s < e && !isspace(*s) && *s != '<' && *s != '&' && *s != '=')
204
s++;
205
}
206
} while (s != b);
207
return s;
208
}
209
210
/*
211
* ipma readf
212
*/
213
214
static int
215
ipmaread(register Dssfile_t* file, Dssrecord_t* record, Dssdisc_t* disc)
216
{
217
register Ipmastate_t* state = (Ipmastate_t*)file->data;
218
register Bgproute_t* rp;
219
register char* s;
220
register int i;
221
int c;
222
int n;
223
int o;
224
char* e;
225
char* p;
226
Bgpasn_t* ap;
227
228
rp = &state->route;
229
for (;;)
230
{
231
if (!(s = sfgetr(file->io, '\n', 0)))
232
return 0;
233
e = s + sfvalue(file->io);
234
s = skip(s, e, 0);
235
if (s >= e)
236
continue;
237
if (isdigit(*s))
238
{
239
if (strtoip4(s, &p, &rp->addr.v4, &rp->bits))
240
break;
241
s = skip(p, e, 1);
242
if (s >= e || !isalnum(*s))
243
{
244
if ((c = sfgetc(file->io)) == EOF)
245
break;
246
if (!isspace(c))
247
{
248
sfungetc(file->io, c);
249
s = e = "";
250
}
251
else if (!(s = sfgetr(file->io, '\n', 0)))
252
return 0;
253
else
254
{
255
e = s + sfvalue(file->io);
256
s = skip(s, e, 1);
257
}
258
}
259
}
260
else if ((e - s) > 6 && (strneq(s, "Prefix", 6) || strneq(s, "Networ", 6) || strneq(s, "Receiv", 6) || strneq(s, "Advert", 6)))
261
continue;
262
else
263
s = skip(s, e, 1);
264
if (s >= e)
265
break;
266
if (*(s - 1) == '=')
267
{
268
if (strtoip4(s, &p, &rp->hop.v4, NiL))
269
break;
270
s = skip(s, e, 1);
271
}
272
i = 0;
273
n = elementsof(rp->data) / sizeof(Bgpasn_t);
274
ap = (Bgpasn_t*)rp->data;
275
rp->path.offset = i;
276
o = 0;
277
p = s;
278
do
279
{
280
for (s = p; *s == ' ' || *s == '\t' || *s == ','; s++);
281
if (*s == '{')
282
{
283
if (i >= (n - 2))
284
{
285
if (disc->errorf && !(file->dss->flags & DSS_QUIET))
286
(*disc->errorf)(NiL, disc, 1, "%s: AS path too long -- truncated to %d", file->format->name, n);
287
break;
288
}
289
ap[i++] = BGP_SET16;
290
o = i++;
291
p = s + 1;
292
}
293
else if (*s == '}')
294
s++;
295
else if (!isdigit(*s))
296
break;
297
else
298
{
299
if (i >= n)
300
{
301
if (disc->errorf && !(file->dss->flags & DSS_QUIET))
302
(*disc->errorf)(NiL, disc, 1, "%s: AS path too long -- truncated to %d", file->format->name, n);
303
break;
304
}
305
if ((ap[i++] = strtol(s, &p, 10)) == BGP_SET16)
306
{
307
if (i >= (n - 2))
308
{
309
if (disc->errorf && !(file->dss->flags & DSS_QUIET))
310
(*disc->errorf)(NiL, disc, 1, "%s: AS path too long -- truncated to %d", file->format->name, n);
311
break;
312
}
313
ap[i++] = 0;
314
ap[i++] = BGP_SET16;
315
}
316
}
317
} while (p > s);
318
rp->path.size = i;
319
if (o)
320
ap[o] = i - o;
321
if (s[0] == 'E' || s[0] == 'e')
322
rp->origin = BGP_ORIGIN_egp;
323
else if ((s[0] == 'I' || s[0] == 'i') && (s[1] == 'G' || s[1] == 'g'))
324
rp->origin = BGP_ORIGIN_igp;
325
else
326
rp->origin = BGP_ORIGIN_incomplete;
327
record->data = rp;
328
record->size = rp->size = (char*)(rp->data + i) - (char*)rp;
329
return 1;
330
}
331
return 0;
332
}
333
334
/*
335
* ipma writef
336
*/
337
338
static int
339
ipmawrite(Dssfile_t* file, Dssrecord_t* record, Dssdisc_t* disc)
340
{
341
register Ipmastate_t* state = (Ipmastate_t*)file->data;
342
register Bgproute_t* rp = (Bgproute_t*)record->data;
343
register Sfio_t* io = file->io;
344
register int i;
345
register int j;
346
register int k;
347
Bgpasn_t* ap;
348
349
if (rp->addr.v4 != state->paddr || rp->bits != state->pbits)
350
{
351
state->paddr = rp->addr.v4;
352
state->pbits = rp->bits;
353
sfprintf(io, "%s\n", fmtip4(rp->addr.v4, rp->bits));
354
}
355
sfprintf(io, "\tN=%s", fmtip4(rp->hop.v4, -1));
356
if (j = rp->path.size)
357
{
358
ap = BGPPATH(rp);
359
for (i = 0; i < j; i++)
360
if (ap[i] == BGP_SET16)
361
{
362
if (k = ap[++i])
363
{
364
k += i - 1;
365
sfprintf(io, " {%u", ap[++i]);
366
while (i < k)
367
sfprintf(io, ",%u", ap[++i]);
368
sfputc(io, '}');
369
}
370
else
371
sfprintf(io, " %u", ap[++i]);
372
}
373
else
374
sfprintf(io, " %u", ap[i]);
375
}
376
switch (rp->origin)
377
{
378
case BGP_ORIGIN_egp:
379
sfprintf(io, " EGP");
380
break;
381
case BGP_ORIGIN_igp:
382
sfprintf(io, " IGP");
383
break;
384
default:
385
sfprintf(io, " Incomplete");
386
break;
387
}
388
if (sfputc(io, '\n') == EOF)
389
{
390
if (disc->errorf)
391
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "%s: write error", file->format->name);
392
return -1;
393
}
394
return 0;
395
}
396
397
/*
398
* ipma closef
399
*/
400
401
static int
402
ipmaclose(Dssfile_t* file, Dssdisc_t* disc)
403
{
404
if (!file->data)
405
return -1;
406
vmfree(file->dss->vm, file->data);
407
return 0;
408
}
409
410
Dssformat_t bgp_ipma_format =
411
{
412
"ipma",
413
"ipma router dump format (2009-03-15) [http://www.merit.edu/~ipma/routing_table]",
414
CXH,
415
ipmaident,
416
ipmaopen,
417
ipmaread,
418
ipmawrite,
419
0,
420
ipmaclose,
421
0,
422
0,
423
bgp_ipma_next
424
};
425
426