Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/dsslib/bgp/bgp.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 method
23
*
24
* Glenn Fowler
25
* AT&T Research
26
*/
27
28
static const char usage[] =
29
"[a:anonymize?Anonymize output data for \bbgp-*-anonymize\b formats.]"
30
;
31
32
#include "bgplib.h"
33
#include "mrt.h"
34
35
#define BGP_path_len (((BGP_LAST+1)<<1)|1)
36
#define BGP_path16_len (((BGP_LAST+2)<<1)|1)
37
#define BGP_path32_len (((BGP_LAST+3)<<1)|1)
38
#define BGP_cluster_len (((BGP_LAST+4)<<1)|1)
39
#define BGP_community_len (((BGP_LAST+5)<<1)|1)
40
#define BGP_extended_len (((BGP_LAST+6)<<1)|1)
41
#define BGP_labels_len (((BGP_LAST+7)<<1)|1)
42
43
#define CXD(name,type,index,description) \
44
{name,description,{{0},CX_DEPRECATED},0,(Cxtype_t*)type,0,index},
45
46
Dssformat_t* bgp_formats = bgp_first_format;
47
48
static Cxvariable_t fields[] =
49
{
50
CXV("afi", "number", BGP_afi, "Announce address family identifier: 1:ipv4, 2:ipv6.")
51
CXV("agg_addr", "ipaddr_t", BGP_agg_addr, "Aggregator AS address.")
52
CXV("agg_addrv4", "ipv4addr_t", BGP_agg_addrv4, "Aggregator AS ipv4 address.")
53
CXV("agg_addrv6", "ipv6addr_t", BGP_agg_addrv6, "Aggregator AS ipv6 address.")
54
CXV("agg_addr32", "ipaddr_t", BGP_agg_addr32, "Aggregator AS32 address.")
55
CXV("agg_addr32v4", "ipv4addr_t", BGP_agg_addr32v4, "Aggregator AS32 ipv4 address.")
56
CXV("agg_addr32v6", "ipv6addr_t", BGP_agg_addr32v6, "Aggregator AS32 ipv6 address.")
57
CXV("agg_as", "as_t", BGP_agg_as, "Aggregator AS number.")
58
CXV("agg_as16", "as16_t", BGP_agg_as16, "Aggregator AS16 number.")
59
CXV("agg_as32", "as32_t", BGP_agg_as32, "Aggregator AS32 number.")
60
CXV("atomic", "number", BGP_atomic, "Atomic.")
61
CXV("best", "number", BGP_best, "Best route.")
62
CXV("bits", "number", BGP_bits, "Number of prefix mask bits.")
63
CXV("bitsv4", "number", BGP_bitsv4, "Number of ipv4 prefix mask bits.")
64
CXV("bitsv6", "number", BGP_bitsv6, "Number of ipv6 prefix mask bits.")
65
CXV("cluster", "cluster_t", BGP_cluster, "Cluster id list.")
66
CXV("community", "community_t", BGP_community, "Community of interest id list.")
67
CXV("damped", "number", BGP_damped, "Damped prefix.")
68
CXV("dpa_addr", "ipaddr_t", BGP_dpa_addr, "DPA address.")
69
CXV("dpa_addrv4", "ipv4addr_t", BGP_dpa_addrv4, "DPA ipv4 address.")
70
CXV("dpa_addrv6", "ipv6addr_t", BGP_dpa_addrv6, "DPA ipv6 address.")
71
CXV("dpa_as", "as_t", BGP_dpa_as, "DPA AS number.")
72
CXV("dpa_as16", "as16_t", BGP_dpa_as16, "DPA AS16 number.")
73
CXV("dpa_as32", "as32_t", BGP_dpa_as32, "DPA AS32 number.")
74
CXV("dst_addr", "ipaddr_t", BGP_dst_addr, "Destination address.")
75
CXV("dst_addrv4", "ipv4addr_t", BGP_dst_addrv4, "Destination ipv4 address.")
76
CXV("dst_addrv6", "ipv6addr_t", BGP_dst_addrv6, "Destination ipv6 address.")
77
CXV("dst_as", "as_t", BGP_dst_as, "Destination AS number.")
78
CXV("dst_as16", "as16_t", BGP_dst_as16, "Destination AS16 number.")
79
CXV("dst_as32", "as32_t", BGP_dst_as32, "Destination AS32 number.")
80
CXV("extended", "extended_t", BGP_extended, "Extended community list.")
81
CXV("flags", "number", BGP_flags, "Auxiliary flags.")
82
CXV("history", "number", BGP_history, "History prefix.")
83
CXV("hop", "ipaddr_t", BGP_hop, "Next hop address.")
84
CXV("hopv4", "ipv4addr_t", BGP_hopv4, "Next hop ipv4 address.")
85
CXV("hopv6", "ipv6addr_t", BGP_hopv6, "Next hop ipv6 address.")
86
CXV("id", "number", BGP_id, "Auxiliary id.")
87
CXV("internal", "number", BGP_internal, "Internal prefix.")
88
CXV("key", "bgp_t", BGP_key, "Route key NLRI.")
89
CXV("label", "number", BGP_label, "NLRI label.")
90
CXV("labels", "labels_t", BGP_labels, "NLRI label list; LHS is label, RHS is COS and end of stack bit.")
91
CXV("local", "number", BGP_local, "Local preference.")
92
CXV("med", "number", BGP_med, "Multi exit discriminator.")
93
CXV("message", "number", BGP_message, "Message group index.")
94
CXV("mvpn", "bgp_t", BGP_mvpn, "[Mcast vpn data using members of the main schema; access as \bmvpn\b.\amember\a:]{[+agg_addr?VPN_S_PMSI_A_D multicast address.][+key?Route key NLRI.][+originator?Originator ipv4 address.][+rd_addr?Route distinguisher address.][+rd_as?Route distinguisher AS number.][+rd_number?Route distinguisher assigned number.][+rd_type?Route distinguisher type.][+src_addr?Source address.][+src_as?Originator AS number.][+type?The route type index.]}")
95
CXV("new_state", "number", BGP_new_state, "STATE_CHANGE record new state.")
96
CXV("old_state", "number", BGP_old_state, "STATE_CHANGE record old state.")
97
CXV("origin", "number", BGP_origin, "Origin: 'i':igp, 'e':egp, '?':incomplete.")
98
CXV("originator", "ipv4addr_t", BGP_originator, "Originator ipv4 address.")
99
CXV("path", "aspath_t", BGP_path, "AS path.")
100
CXV("path16", "as16path_t", BGP_path16, "AS16 path.")
101
CXV("path32", "as32path_t", BGP_path32, "AS32 path.")
102
CXV("prefix", "ipprefix_t", BGP_prefix, "Routing ddress prefix and length.")
103
CXV("prefixv4", "ipv4prefix_t", BGP_prefixv4, "ipv4 routing prefix and length.")
104
CXV("prefixv6", "ipv6prefix_t", BGP_prefixv6, "ipv6 routing prefix and length.")
105
CXV("rd_addr", "ipaddr_t", BGP_rd_addr, "NLRI route distinguisher address.")
106
CXV("rd_as", "as_t", BGP_rd_as, "NLRI route distinguisher AS number.")
107
CXV("rd_number", "number", BGP_rd_number, "NLRI route distinguisher assigned number.")
108
CXV("rd_type", "number", BGP_rd_type, "NLRI route distinguisher type.")
109
CXV("rib_failure", "number", BGP_rib_failure, "RIB failure.")
110
CXV("safi", "number", BGP_safi, "Announce subsequent address family identifier bits: 1:unicast, 2:multicast, 4:MLPS-label, 5:MCAST-VPN, 128:MLPS-labeled-VPN.")
111
CXV("slot", "number", BGP_slot, "Slot.")
112
CXV("src_addr", "ipaddr_t", BGP_src_addr, "Source address.")
113
CXV("src_addrv4", "ipv4addr_t", BGP_src_addrv4, "Source ipv4 address.")
114
CXV("src_addrv6", "ipv6addr_t", BGP_src_addrv6, "Source ipv6 address.")
115
CXV("src_as", "as_t", BGP_src_as, "Source AS number.")
116
CXV("src_as16", "as16_t", BGP_src_as16, "Source AS16 number.")
117
CXV("src_as32", "as32_t", BGP_src_as32, "Source AS32 number.")
118
CXV("stale", "number", BGP_stale, "Stale.")
119
CXV("stamp", "time_t", BGP_stamp, "Data time stamp.")
120
CXV("suppressed", "number", BGP_suppressed, "Suppressed prefix.")
121
CXV("time", "time_t", BGP_time, "Packet event time stamp.")
122
CXV("type", "number", BGP_type, "Record type:: 'A':announce, 'K':keepalive, 'N':notification, 'O':open, 'S':state, 'T':table, 'W':withdraw.")
123
CXV("unknown", "string", BGP_unknown, "Unknown attributes in the form: \"<flag-i>:<type-i>:<size-i>:<hex-data-i>;...\".")
124
CXV("usec", "number", BGP_usec, "Packet event time stamp usec.")
125
CXV("valid", "number", BGP_valid, "Valid prefix.")
126
CXV("weight", "number", BGP_weight, "Router proprietary weight.")
127
CXV("MESSAGE", "number", BGP_MESSAGE, "Message group bit, toggled for each message.")
128
CXV("PART", "number", BGP_PART, "Message part bit, 0 for first part, 1 for remainder.")
129
CXD("cluster_len", "number", BGP_cluster_len, "DEPRECATED -- use sizeof(cluster). Cluster id list length.")
130
CXD("community_len", "number", BGP_community_len, "DEPRECATED -- use sizeof(community). Community of interest id list length.")
131
CXD("extended_len", "number", BGP_extended_len, "DEPRECATED -- use sizeof(extended). Extended community list length.")
132
CXD("labels_len", "number", BGP_labels_len, "DEPRECATED -- use sizeof(labels). NLRI label list length.")
133
CXD("path_len", "number", BGP_path_len, "DEPRECATED -- use sizeof(path). AS path length.")
134
CXD("path16_len", "number", BGP_path16_len, "DEPRECATED -- use sizeof(path16). AS16 path length.")
135
CXD("path32_len", "number", BGP_path32_len, "DEPRECATED -- use sizeof(path32). AS32 path length.")
136
{0}
137
};
138
139
static int
140
op_get(Cx_t* cx, Cxinstruction_t* pc, Cxoperand_t* r, Cxoperand_t* a, Cxoperand_t* b, void* data, Cxdisc_t* disc)
141
{
142
Bgp_t* bgp = BGPDATA(data);
143
Bgproute_t* rp = (Bgproute_t*)DSSDATA(data);
144
Cxvariable_t* vp = (Cxvariable_t*)pc->data.variable;
145
146
static unsigned char noipv6[MRT_BITS_IPV6 + 1];
147
148
switch (vp->index)
149
{
150
case BGP_afi:
151
r->value.number = rp->afi ? rp->afi : MRT_AFI_IPV4;
152
break;
153
case BGP_agg_addr:
154
if (rp->set & BGP_SET_agg_addrv6)
155
{
156
r->value.buffer.data = rp->agg_addr.v6;
157
r->value.buffer.size = sizeof(rp->agg_addr.v6);
158
r->value.buffer.elements = 0;
159
r->type = bgp->type_ipv6addr;
160
}
161
else
162
{
163
r->value.number = rp->agg_addr.v4;
164
r->type = bgp->type_ipv4addr;
165
}
166
break;
167
case BGP_agg_addrv4:
168
r->value.number = (rp->set & BGP_SET_agg_addrv6) ? 0 : rp->agg_addr.v4;
169
break;
170
case BGP_agg_addrv6:
171
r->value.buffer.data = (rp->set & BGP_SET_agg_addrv6) ? rp->agg_addr.v6 : noipv6;
172
r->value.buffer.size = sizeof(rp->agg_addr.v6);
173
r->value.buffer.elements = 0;
174
break;
175
case BGP_agg_addr32:
176
if (rp->set & BGP_SET_agg_addr32v6)
177
{
178
r->value.buffer.data = rp->agg_addr32.v6;
179
r->value.buffer.size = sizeof(rp->agg_addr32.v6);
180
r->value.buffer.elements = 0;
181
r->type = bgp->type_ipv6addr;
182
}
183
else
184
{
185
r->value.number = rp->agg_addr32.v4;
186
r->type = bgp->type_ipv4addr;
187
}
188
break;
189
case BGP_agg_addr32v4:
190
r->value.number = (rp->set & BGP_SET_agg_addr32v6) ? 0 : rp->agg_addr32.v4;
191
break;
192
case BGP_agg_addr32v6:
193
r->value.buffer.data = (rp->set & BGP_SET_agg_addr32v6) ? rp->agg_addr32.v6 : noipv6;
194
r->value.buffer.size = sizeof(rp->agg_addr32.v6);
195
r->value.buffer.elements = 0;
196
break;
197
case BGP_agg_as:
198
r->value.number = rp->agg_as ? rp->agg_as : rp->agg_as32;
199
break;
200
case BGP_agg_as16:
201
r->value.number = rp->agg_as;
202
break;
203
case BGP_agg_as32:
204
r->value.number = rp->agg_as32;
205
break;
206
case BGP_bits:
207
r->value.number = (rp->set & BGP_SET_prefixv6) ? rp->prefixv6[IP6BITS] : rp->bits;
208
break;
209
case BGP_bitsv4:
210
r->value.number = rp->bits;
211
break;
212
case BGP_bitsv6:
213
r->value.number = rp->prefixv6[IP6BITS];
214
break;
215
case BGP_cluster:
216
r->value.buffer.data = rp->data + rp->cluster.offset;
217
r->value.buffer.size = rp->cluster.size * sizeof(Bgpnum_t);
218
r->value.buffer.elements = 0;
219
break;
220
case BGP_community:
221
r->value.buffer.data = rp->data + rp->community.offset;
222
r->value.buffer.size = rp->community.size * sizeof(Bgpasn_t);
223
r->value.buffer.elements = 0;
224
break;
225
case BGP_dpa_addr:
226
if (rp->set & BGP_SET_dpa_addrv6)
227
{
228
r->value.buffer.data = rp->dpa_addr.v6;
229
r->value.buffer.size = sizeof(rp->dpa_addr.v6);
230
r->value.buffer.elements = 0;
231
r->type = bgp->type_ipv6addr;
232
}
233
else
234
{
235
r->value.number = rp->dpa_addr.v4;
236
r->type = bgp->type_ipv4addr;
237
}
238
break;
239
case BGP_dpa_addrv4:
240
r->value.number = (rp->set & BGP_SET_dpa_addrv6) ? 0 : rp->dpa_addr.v4;
241
break;
242
case BGP_dpa_addrv6:
243
r->value.buffer.data = (rp->set & BGP_SET_dpa_addrv6) ? rp->dpa_addr.v6 : noipv6;
244
r->value.buffer.size = sizeof(rp->dpa_addr.v6);
245
r->value.buffer.elements = 0;
246
break;
247
case BGP_dpa_as:
248
r->value.number = rp->dpa_as ? rp->dpa_as : rp->dpa_as32;
249
break;
250
case BGP_dpa_as16:
251
r->value.number = rp->dpa_as;
252
break;
253
case BGP_dpa_as32:
254
r->value.number = rp->dpa_as32;
255
break;
256
case BGP_dst_addr:
257
if (rp->set & BGP_SET_dst_addrv6)
258
{
259
r->value.buffer.data = rp->dst_addr.v6;
260
r->value.buffer.size = sizeof(rp->dst_addr.v6);
261
r->value.buffer.elements = 0;
262
r->type = bgp->type_ipv6addr;
263
}
264
else
265
{
266
r->value.number = rp->dst_addr.v4;
267
r->type = bgp->type_ipv4addr;
268
}
269
break;
270
case BGP_dst_addrv4:
271
r->value.number = (rp->set & BGP_SET_dst_addrv6) ? 0 : rp->dst_addr.v4;
272
break;
273
case BGP_dst_addrv6:
274
r->value.buffer.data = (rp->set & BGP_SET_dst_addrv6) ? rp->dst_addr.v6 : noipv6;
275
r->value.buffer.size = sizeof(rp->dst_addr.v6);
276
r->value.buffer.elements = 0;
277
break;
278
case BGP_dst_as:
279
r->value.number = rp->dst_as ? rp->dst_as : rp->dst_as32;
280
break;
281
case BGP_dst_as16:
282
r->value.number = rp->dst_as;
283
break;
284
case BGP_dst_as32:
285
r->value.number = rp->dst_as32;
286
break;
287
case BGP_extended:
288
r->value.buffer.data = rp->data + rp->extended.offset;
289
r->value.buffer.size = rp->extended.size;
290
r->value.buffer.elements = 0;
291
break;
292
case BGP_flags:
293
r->value.number = rp->flags;
294
break;
295
case BGP_hop:
296
if (rp->set & BGP_SET_hopv6)
297
{
298
r->value.buffer.data = rp->hop.v6;
299
r->value.buffer.size = sizeof(rp->hop.v6);
300
r->value.buffer.elements = 0;
301
r->type = bgp->type_ipv6addr;
302
}
303
else
304
{
305
r->value.number = rp->hop.v4;
306
r->type = bgp->type_ipv4addr;
307
}
308
break;
309
case BGP_hopv4:
310
r->value.number = (rp->set & BGP_SET_hopv6) ? 0 : rp->hop.v4;
311
break;
312
case BGP_hopv6:
313
r->value.buffer.data = (rp->set & BGP_SET_hopv6) ? rp->hop.v6 : noipv6;
314
r->value.buffer.size = sizeof(rp->hop.v6);
315
r->value.buffer.elements = 0;
316
break;
317
case BGP_id:
318
r->value.number = rp->id;
319
break;
320
case BGP_label:
321
r->value.number = rp->label;
322
break;
323
case BGP_labels:
324
r->value.buffer.data = rp->data + rp->labels.offset;
325
r->value.buffer.size = rp->labels.size * sizeof(Bgpnum_t);
326
r->value.buffer.elements = 0;
327
break;
328
case BGP_local:
329
r->value.number = rp->local;
330
break;
331
case BGP_med:
332
r->value.number = rp->med;
333
break;
334
case BGP_message:
335
r->value.number = rp->message;
336
break;
337
case BGP_mvpn:
338
r->value.number = !!(rp->set & BGP_SET_mvpn);
339
break;
340
case BGP_new_state:
341
r->value.number = rp->type == BGP_TYPE_state_change ? rp->new_state : 0;
342
break;
343
case BGP_old_state:
344
r->value.number = rp->type == BGP_TYPE_state_change ? rp->old_state : 0;
345
break;
346
case BGP_origin:
347
r->value.number = rp->origin ? rp->origin : '0';
348
break;
349
case BGP_originator:
350
if (rp->set & BGP_SET_originatorv6)
351
{
352
r->value.buffer.data = rp->originator.v6;
353
r->value.buffer.size = sizeof(rp->originator.v6);
354
r->value.buffer.elements = 0;
355
r->type = bgp->type_ipv6addr;
356
}
357
else
358
{
359
r->value.number = rp->originator.v4;
360
r->type = bgp->type_ipv4addr;
361
}
362
break;
363
case BGP_path:
364
if (rp->path.size)
365
{
366
r->value.buffer.data = rp->data + rp->path.offset;
367
r->value.buffer.size = rp->path.size * sizeof(Bgpasn_t);
368
r->value.buffer.elements = rp->path.elements;
369
r->type = bgp->type_as16path;
370
}
371
else
372
{
373
r->value.buffer.data = rp->data + rp->path32.offset;
374
r->value.buffer.size = rp->path32.size * sizeof(Bgpnum_t);
375
r->value.buffer.elements = rp->path32.elements;
376
r->type = bgp->type_as32path;
377
}
378
break;
379
case BGP_path16:
380
r->value.buffer.data = rp->data + rp->path.offset;
381
r->value.buffer.size = rp->path.size * sizeof(Bgpasn_t);
382
r->value.buffer.elements = rp->path.elements;
383
break;
384
case BGP_path32:
385
r->value.buffer.data = rp->data + rp->path32.offset;
386
r->value.buffer.size = rp->path32.size * sizeof(Bgpnum_t);
387
r->value.buffer.elements = rp->path32.elements;
388
break;
389
case BGP_prefix:
390
if (rp->set & BGP_SET_prefixv6)
391
{
392
r->value.buffer.data = rp->prefixv6;
393
r->value.buffer.size = sizeof(rp->prefixv6);
394
r->value.buffer.elements = 0;
395
r->type = bgp->type_ipv6prefix;
396
}
397
else
398
{
399
r->value.number = (Cxnumber_t)rp->addr.v4 * 64 + rp->bits;
400
r->type = bgp->type_ipv4prefix;
401
}
402
break;
403
case BGP_prefixv4:
404
r->value.number = (rp->set & BGP_SET_prefixv6) ? 0 : ((Cxnumber_t)rp->addr.v4 * 64 + rp->bits);
405
break;
406
case BGP_prefixv6:
407
r->value.buffer.data = (rp->set & BGP_SET_prefixv6) ? rp->prefixv6 : noipv6;
408
r->value.buffer.size = sizeof(rp->prefixv6);
409
r->value.buffer.elements = 0;
410
break;
411
case BGP_rd_addr:
412
if (rp->afi == MRT_AFI_IPV6)
413
{
414
r->value.buffer.data = rp->rd_addr.v6;
415
r->value.buffer.size = sizeof(rp->rd_addr.v6);
416
r->value.buffer.elements = 0;
417
r->type = bgp->type_ipv6addr;
418
}
419
else
420
{
421
r->value.number = rp->rd_addr.v4;
422
r->type = bgp->type_ipv4addr;
423
}
424
break;
425
case BGP_rd_as:
426
r->value.number = rp->rd_as;
427
break;
428
case BGP_rd_number:
429
r->value.number = rp->rd_number;
430
break;
431
case BGP_rd_type:
432
r->value.number = rp->rd_type;
433
break;
434
case BGP_safi:
435
r->value.number = rp->safi ? rp->safi : MRT_SAFI_NLRI_UCAST_FORWARD;
436
break;
437
case BGP_src_addr:
438
if (rp->set & BGP_SET_src_addrv6)
439
{
440
r->value.buffer.data = rp->src_addr.v6;
441
r->value.buffer.size = sizeof(rp->src_addr.v6);
442
r->value.buffer.elements = 0;
443
r->type = bgp->type_ipv6addr;
444
}
445
else
446
{
447
r->value.number = rp->src_addr.v4;
448
r->type = bgp->type_ipv4addr;
449
}
450
break;
451
case BGP_src_addrv4:
452
r->value.number = (rp->set & BGP_SET_src_addrv6) ? 0 : rp->src_addr.v4;
453
break;
454
case BGP_src_addrv6:
455
r->value.buffer.data = (rp->set & BGP_SET_src_addrv6) ? rp->src_addr.v6 : noipv6;
456
r->value.buffer.size = sizeof(rp->src_addr.v6);
457
r->value.buffer.elements = 0;
458
break;
459
case BGP_src_as:
460
r->value.number = rp->src_as ? rp->src_as : rp->src_as32;
461
break;
462
case BGP_src_as16:
463
r->value.number = rp->src_as;
464
break;
465
case BGP_src_as32:
466
r->value.number = rp->src_as32;
467
break;
468
case BGP_stamp:
469
r->value.number = rp->stamp;
470
break;
471
case BGP_time:
472
r->value.number = rp->time ? rp->time : rp->stamp;
473
break;
474
case BGP_type:
475
r->value.number = rp->type;
476
break;
477
case BGP_unknown:
478
r->value.string.data = rp->data + rp->unknown.offset;
479
r->value.string.size = rp->unknown.size;
480
break;
481
case BGP_usec:
482
r->value.number = rp->usec;
483
break;
484
case BGP_weight:
485
r->value.number = rp->weight;
486
break;
487
/*DEPRECATED*/
488
case BGP_cluster_len:
489
r->value.number = rp->cluster.size;
490
break;
491
case BGP_community_len:
492
r->value.number = rp->community.size;
493
break;
494
case BGP_extended_len:
495
r->value.number = rp->extended.size / 8;
496
break;
497
case BGP_labels_len:
498
r->value.number = rp->labels.size / 2;
499
break;
500
case BGP_path_len:
501
r->value.number = rp->path.size ? rp->path.elements : rp->path32.size ? rp->path32.elements : 0;
502
break;
503
case BGP_path16_len:
504
r->value.number = rp->path.size ? rp->path.elements : 0;
505
break;
506
case BGP_path32_len:
507
r->value.number = rp->path32.size ? rp->path32.elements : 0;
508
break;
509
default:
510
r->value.number = (vp->index & 1) ? 0 : (rp->attr & vp->index) != 0;
511
break;
512
}
513
return 0;
514
}
515
516
static Cxcallout_t local_callouts[] =
517
{
518
CXC(CX_GET, "void", "void", op_get, 0)
519
};
520
521
static int
522
bgp_get(Cx_t* cx, Cxinstruction_t* pc, Cxoperand_t* r, Cxoperand_t* a, Cxoperand_t* b, void* data, Cxdisc_t* disc)
523
{
524
Cxvariable_t* vp = (Cxvariable_t*)pc->data.variable;
525
void* save;
526
int i;
527
528
save = DSSRECORD(data)->data;
529
DSSRECORD(data)->data = &BGPDATA(data)->sub + (((Cxvariable_t*)pc->data.variable)->index == BGP_key);
530
i = op_get(cx, pc, r, a, b, data, disc);
531
DSSRECORD(data)->data = save;
532
return i;
533
}
534
535
static Cxmember_t bgp_member =
536
{
537
bgp_get,
538
0,
539
(Dt_t*)&fields[0]
540
};
541
542
static Cxtype_t types[] =
543
{
544
{ "bgp_t", "BGP route data.", { { 0 }, CX_REFERENCED }, (Cxtype_t*)"number", 0, 0, 0, 0, 0, 0, 0, { 0, 0, CX_UNSIGNED|CX_INTEGER, 4 }, 0, &bgp_member },
545
{ 0 }
546
};
547
548
/*
549
* methf
550
*/
551
552
extern Dsslib_t dss_lib_bgp;
553
554
static Dssmeth_t*
555
bgpmeth(const char* name, const char* options, const char* schema, Dssdisc_t* disc, Dssmeth_t* meth)
556
{
557
int i;
558
char* s;
559
Dssformat_t* fp;
560
Dssmeth_t* copy;
561
562
if (!dtsize(meth->formats))
563
{
564
cxaddvariable(meth->cx, NiL, disc);
565
for (i = 0; types[i].name; i++)
566
if (cxaddtype(meth->cx, &types[i], disc))
567
return 0;
568
for (i = 0; i < elementsof(local_callouts); i++)
569
if (cxaddcallout(meth->cx, &local_callouts[i], disc))
570
return 0;
571
for (i = 0; fields[i].name; i++)
572
if (cxaddvariable(meth->cx, &fields[i], disc))
573
return 0;
574
for (fp = bgp_formats; fp; fp = fp->next)
575
dtinsert(meth->formats, fp);
576
}
577
if (options)
578
{
579
if (dssoptlib(meth->cx->buf, &dss_lib_bgp, usage, disc))
580
return 0;
581
s = sfstruse(meth->cx->buf);
582
i = 0;
583
for (;;)
584
{
585
switch (optstr(options, s))
586
{
587
case 'a':
588
i |= BGP_METHOD_ANONYMIZE;
589
continue;
590
case '?':
591
if (disc->errorf)
592
(*disc->errorf)(NiL, disc, ERROR_USAGE|4, "%s", opt_info.arg);
593
return 0;
594
case ':':
595
if (disc->errorf)
596
(*disc->errorf)(NiL, disc, 2, "%s", opt_info.arg);
597
return 0;
598
}
599
break;
600
}
601
if (i)
602
{
603
if (!(copy = newof(0, Dssmeth_t, 1, 0)))
604
{
605
if (disc->errorf)
606
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
607
return 0;
608
}
609
*copy = *meth;
610
meth = copy;
611
meth->flags = i;
612
}
613
}
614
return meth;
615
}
616
617
/*
618
* openf
619
*/
620
621
static int
622
bgpopen(Dss_t* dss, Dssdisc_t* disc)
623
{
624
Bgp_t* bgp;
625
626
if (!(bgp = vmnewof(dss->vm, 0, Bgp_t, 1, 0)) ||
627
!(bgp->type_as16path = cxtype(dss->cx, "as16path_t", disc)) ||
628
!(bgp->type_as32path = cxtype(dss->cx, "as32path_t", disc)) ||
629
!(bgp->type_cluster = cxtype(dss->cx, "cluster_t", disc)) ||
630
!(bgp->type_community = cxtype(dss->cx, "community_t", disc)) ||
631
!(bgp->type_extended = cxtype(dss->cx, "extended_t", disc)) ||
632
!(bgp->type_ipv4addr = cxtype(dss->cx, "ipv4addr_t", disc)) ||
633
!(bgp->type_ipv4prefix = cxtype(dss->cx, "ipv4prefix_t", disc)) ||
634
!(bgp->type_ipv6addr = cxtype(dss->cx, "ipv6addr_t", disc)) ||
635
!(bgp->type_ipv6prefix = cxtype(dss->cx, "ipv6prefix_t", disc)) ||
636
!(bgp->tmp = sfstropen()))
637
{
638
if (bgp)
639
vmfree(dss->vm, bgp);
640
if (disc->errorf)
641
(*disc->errorf)(NiL, disc, ERROR_SYSTEM|2, "out of space");
642
return -1;
643
}
644
dss->data = bgp;
645
return 0;
646
}
647
648
/*
649
* closef
650
*/
651
652
static int
653
bgpclose(Dss_t* dss, Dssdisc_t* disc)
654
{
655
Bgp_t* bgp;
656
657
if (!(bgp = (Bgp_t*)dss->data) || !bgp->tmp)
658
return -1;
659
sfstrclose(bgp->tmp);
660
return 0;
661
}
662
663
static const char* libraries[] = { "time_t", "ip_t", 0 };
664
665
static Dssmeth_t method =
666
{
667
"bgp",
668
"BGP router dump and announce/withdraw messages",
669
CXH,
670
bgpmeth,
671
bgpopen,
672
bgpclose,
673
0
674
};
675
676
Dsslib_t dss_lib_bgp =
677
{
678
"bgp",
679
"bgp method"
680
"[-1ls5Pp0?\n@(#)$Id: dss bgp method (AT&T Research) 2012-06-14 $\n]"
681
USAGE_LICENSE,
682
CXH,
683
&libraries[0],
684
&method,
685
};
686
687