Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/dsslib/bgp/bgp-table.c
1810 views
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 <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
/*
22
* bgp table method
23
*
24
* Glenn Fowler
25
* AT&T Research
26
*/
27
28
#include "bgplib.h"
29
30
typedef struct Tablestate_s
31
{
32
Bgproute_t route[2];
33
int index;
34
int v6;
35
} Tablestate_t;
36
37
/*
38
* table identf
39
*/
40
41
static int
42
tableident(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
unsigned char prefix[IP6PREFIX];
49
Bgpnum_t addr;
50
unsigned char bits;
51
52
s = (char*)buf;
53
e = s + n;
54
for (;;)
55
{
56
for (;;)
57
{
58
if (s >= e)
59
return 0;
60
c = *s++;
61
if (!isascii(c))
62
return 0;
63
if (!isspace(c))
64
break;
65
}
66
f = s - 1;
67
for (;;)
68
{
69
if (s >= e)
70
return 0;
71
c = *s++;
72
if (!isascii(c))
73
return 0;
74
if (c == '\n')
75
break;
76
}
77
if (isdigit(*f) && !strtoip4(f, NiL, &addr, &bits) || !strtoip6(f, NiL, prefix, prefix + IP6BITS) && (file->caller = file))
78
break;
79
}
80
return 1;
81
}
82
83
/*
84
* table openf
85
*/
86
87
static int
88
tableopen(Dssfile_t* file, Dssdisc_t* disc)
89
{
90
Tablestate_t* state;
91
92
if (!(state = vmnewof(file->dss->vm, 0, Tablestate_t, 1, 0)))
93
{
94
if (disc->errorf)
95
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
96
return -1;
97
}
98
state->route[0].bits = -1;
99
state->v6 = file->caller == file;
100
file->data = (void*)state;
101
return 0;
102
}
103
104
/*
105
* table readf
106
*/
107
108
static int
109
tableread(Dssfile_t* file, Dssrecord_t* record, Dssdisc_t* disc)
110
{
111
register Tablestate_t* state = (Tablestate_t*)file->data;
112
register Bgproute_t* rp;
113
register char* s;
114
char* p;
115
char* e;
116
Bgproute_t* op;
117
118
for (;;)
119
{
120
op = &state->route[state->index];
121
rp = &state->route[state->index = !state->index];
122
if (!(s = sfgetr(file->io, '\n', 1)))
123
return 0;
124
while (*s == ' ' || *s == '\t' || *s == '\r')
125
s++;
126
if (*s == 0 || *s == '#' || *s == '\n')
127
continue;
128
rp->set = 0;
129
rp->type = BGP_TYPE_withdraw;
130
rp->attr = BGP_valid;
131
rp->origin = BGP_ORIGIN_incomplete;
132
if (state->v6)
133
{
134
rp->addr.v4 = 0;
135
rp->bits = 0;
136
if (strtoip6(s, &p, rp->prefixv6, rp->prefixv6 + IP6BITS))
137
break;
138
rp->set |= BGP_SET_prefixv6;
139
for (s = p; *s == ' ' || *s == '\t'; s++);
140
rp->hop.v4 = strtoul(s, &p, 0);
141
switch (*p)
142
{
143
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
144
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
145
case ':':
146
rp->hop.v4 = 0;
147
if (!strtoip6(s, &e, rp->hop.v6, NiL) && e > p)
148
{
149
rp->type = BGP_TYPE_announce;
150
rp->attr |= BGP_slot;
151
rp->set |= BGP_SET_hopv6;
152
}
153
break;
154
case '.':
155
if (strtoip4(s, &e, &rp->hop.v4, NiL) || e <= p)
156
break;
157
/*FALLTHROUGH*/
158
default:
159
if (rp->hop.v4)
160
{
161
rp->type = BGP_TYPE_announce;
162
rp->attr |= BGP_slot;
163
}
164
break;
165
}
166
if ((rp->set & BGP_SET_prefixv6) && memcmp(rp->prefixv6, op->prefixv6, sizeof(rp->prefixv6)))
167
rp->attr |= BGP_best;
168
else if ((rp->set & BGP_SET_hopv6) && !memcmp(rp->hop.v6, op->hop.v6, sizeof(rp->hop.v6)))
169
continue;
170
else if (rp->hop.v4 && op->hop.v4 && rp->hop.v4 == op->hop.v4)
171
continue;
172
}
173
else
174
{
175
if (strtoip4(s, &p, &rp->addr.v4, &rp->bits))
176
break;
177
for (s = p; *s == ' ' || *s == '\t'; s++);
178
rp->hop.v4 = strtoul(s, &p, 0);
179
if (p > s && (*p != '.' || !strtoip4(s, NiL, &rp->hop.v4, NiL)) && rp->hop.v4)
180
{
181
rp->type = BGP_TYPE_announce;
182
rp->attr |= BGP_slot;
183
}
184
if (rp->addr.v4 != op->addr.v4 || rp->bits != op->bits)
185
rp->attr |= BGP_best;
186
else if (rp->hop.v4 == op->hop.v4)
187
continue;
188
}
189
record->data = rp;
190
record->size = BGP_FIXED;
191
return 1;
192
}
193
return 0;
194
}
195
196
/*
197
* table writef
198
*/
199
200
static int
201
tablewrite(Dssfile_t* file, Dssrecord_t* record, Dssdisc_t* disc)
202
{
203
register Bgproute_t* rp = (Bgproute_t*)record->data;
204
205
switch (rp->attr & (BGP_best|BGP_damped|BGP_internal|BGP_suppressed|BGP_valid))
206
{
207
case BGP_best|BGP_valid:
208
case BGP_internal|BGP_valid:
209
break;
210
default:
211
return 0;
212
}
213
sfprintf(file->io, "%-16s ", fmtip4(rp->addr.v4, rp->bits));
214
if (rp->hop.v4 < 256)
215
sfprintf(file->io, "%-19u", rp->hop.v4);
216
else
217
sfprintf(file->io, "%-19s", fmtip4(rp->hop.v4, -1));
218
if (sfputc(file->io, '\n') == EOF)
219
{
220
if (disc->errorf)
221
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "write error");
222
return -1;
223
}
224
return 0;
225
}
226
227
/*
228
* table closef
229
*/
230
231
static int
232
tableclose(Dssfile_t* file, Dssdisc_t* disc)
233
{
234
if (!file->data)
235
return -1;
236
vmfree(file->dss->vm, file->data);
237
return 0;
238
}
239
240
Dssformat_t bgp_table_format =
241
{
242
"table",
243
"simple table format (2008-06-20) with prefix mask and optional next hop",
244
CXH,
245
tableident,
246
tableopen,
247
tableread,
248
tablewrite,
249
0,
250
tableclose,
251
0,
252
0,
253
bgp_table_next
254
};
255
256