1
0
mirror of https://github.com/bgp/bgpq4.git synced 2024-05-11 05:55:05 +00:00

JSON output for as-paths

This commit is contained in:
Alexandre Snarskii
2014-10-29 19:27:47 +03:00
parent 9c25c7a780
commit 61c23c53b3
6 changed files with 347 additions and 283 deletions

99
CHANGES
View File

@@ -1,11 +1,24 @@
0.1.24 (2014-07-31) 0.1.25 (2014-10-29)
- JSON support extended to handle "as-paths" too. Well, actually, as
there are no defined format for as-path in json, bgpq3 just creates
simple object like following:
snar@fri:~/compile/bgpq3>./bgpq3 -j3f 20597 as-eltel
{"NN": [
112,5495,6857,8377,20597,34102,35357,43951,
52007,56764,197759,197888,198610,201499
]}
Based on suggestion by Henrik Thostrup Jensen.
0.1.24 (2014-07-31)
- empty prefix-lists (Cisco), extended access-lists (Cisco), as-path - empty prefix-lists (Cisco), extended access-lists (Cisco), as-path
filters (Cisco and Juniper) and route-filters (Juniper) handling: filters (Cisco and Juniper) and route-filters (Juniper) handling:
explicit 'deny any' entry now generated instead of implicit 'permit-any'. explicit 'deny any' entry now generated instead of implicit 'permit-any'.
Based on suggestion by Tore Anderson. Based on suggestion by Tore Anderson.
0.1.23 (2014-07-30) 0.1.23 (2014-07-30)
- bugfix: use of -M option caused major slowdown as it turned off - bugfix: use of -M option caused major slowdown as it turned off
request pipelining... Thanks to Tore Anderson. request pipelining... Thanks to Tore Anderson.
0.1.22 (2014-07-27) 0.1.22 (2014-07-27)
@@ -17,11 +30,11 @@
0.1.21 (2014-06-05) 0.1.21 (2014-06-05)
- new flag -b: generate prefix-filters for BIRD (http://bird.network.cz), - new flag -b: generate prefix-filters for BIRD (http://bird.network.cz),
contributed by Job Snijders. contributed by Job Snijders.
0.1.20-todo2 (2014-05-01) 0.1.20-todo2 (2014-05-01)
- new flag -r <len>, allowing bgpq to generate limited set of more-specific - new flag -r <len>, allowing bgpq to generate limited set of more-specific
routes - only routes with prefix-length >= <len> are accepted. routes - only routes with prefix-length >= <len> are accepted.
Thanks to Pavel Gulchouck for suggesion. Thanks to Pavel Gulchouck for suggesion.
0.1.20-todo (2013-10-07) 0.1.20-todo (2013-10-07)
- socket close code fixed. Thanks to Martin J. Levy. - socket close code fixed. Thanks to Martin J. Levy.
@@ -31,7 +44,7 @@
0.1.19 (2013-05-09) 0.1.19 (2013-05-09)
- CLANG compilation issues fixed. - CLANG compilation issues fixed.
- bgpq3.spec added. Thanks to Arnoud Vermeer. - bgpq3.spec added. Thanks to Arnoud Vermeer.
0.1.18 (2013-01-08) 0.1.18 (2013-01-08)
- JSON output format. Thanks to Job Snijders (Atrato Networks). - JSON output format. Thanks to Job Snijders (Atrato Networks).
@@ -41,57 +54,57 @@
- bug in aggregation documentation fixed. Thanks to Nikolay Shopik. - bug in aggregation documentation fixed. Thanks to Nikolay Shopik.
0.1.16 (2012-01-19) 0.1.16 (2012-01-19)
- new option -m <len>: maximum length of accepted prefixes. - new option -m <len>: maximum length of accepted prefixes.
Suggested by Eugene Demidov, used to discard 'too long prefixes' Suggested by Eugene Demidov, used to discard 'too long prefixes'
(like /30-/32) even if they are registered in IRR. By default (like /30-/32) even if they are registered in IRR. By default
limit is not set and all prefixes accepted. limit is not set and all prefixes accepted.
- documentation redesigned into text/markdown and text/html (manpage - documentation redesigned into text/markdown and text/html (manpage
supported still). supported still).
0.1.15 (2011-07-15) 0.1.15 (2011-07-15)
- prefix-set's for Cisco IOS XR now supported too. - prefix-set's for Cisco IOS XR now supported too.
0.1.14 (2011-06-18) 0.1.14 (2011-06-18)
- Fixed bug in sx_maxsockbuf in rare cases of OS maxsockbuf >2M. - Fixed bug in sx_maxsockbuf in rare cases of OS maxsockbuf >2M.
Thanks to Andreas Lundin. Thanks to Andreas Lundin.
0.1.13 (2011-06-14) 0.1.13 (2011-06-14)
- never publically released. - never publically released.
0.1.12 (2010-10-08) 0.1.12 (2010-10-08)
- Fixed bug preventing AS262144 (that's AS4.0 in asdot) to expand. - Fixed bug preventing AS262144 (that's AS4.0 in asdot) to expand.
Thanks to Sergey Matveychuk Thanks to Sergey Matveychuk
0.1.11 (2010-04-19) 0.1.11 (2010-04-19)
- Fixed another bug in aggregation (-A) mode, thanks to Dmitry Tejblum. - Fixed another bug in aggregation (-A) mode, thanks to Dmitry Tejblum.
0.1.10 (2009-06-13) 0.1.10 (2009-06-13)
- Fixed bug in aggregation (-A) mode, thanks to Sergey Gonchar. - Fixed bug in aggregation (-A) mode, thanks to Sergey Gonchar.
0.1.9 (2009-03-27) 0.1.9 (2009-03-27)
- RIPE changed ASN32 notation to asplain. And RADB does not support - RIPE changed ASN32 notation to asplain. And RADB does not support
asplain indexing (yet?).... Fixed. Thanks to Pavel Gluchouk. asplain indexing (yet?).... Fixed. Thanks to Pavel Gluchouk.
0.1.8 (2008-12-25) 0.1.8 (2008-12-25)
- new flag -D for Cisco asdot notation. Cisco behaviour is a bit - new flag -D for Cisco asdot notation. Cisco behaviour is a bit
strange for me, but, well, that's their decision: strange for me, but, well, that's their decision:
When the asdot format is enabled as the default, any regular expressions When the asdot format is enabled as the default, any regular expressions
to match 4-byte autonomous system numbers must be written using the asdot to match 4-byte autonomous system numbers must be written using the asdot
format, or else the regular expression match will fail. format, or else the regular expression match will fail.
(c) http://www.cisco.com/en/US/docs/ios/12_0s/release/ntes/120SNEWF.html (c) http://www.cisco.com/en/US/docs/ios/12_0s/release/ntes/120SNEWF.html
#wp3521658 (note the URL wrap). #wp3521658 (note the URL wrap).
0.1.7 (2008-12-19): 0.1.7 (2008-12-19):
- man page. Finally :) - man page. Finally :)
- option -h now means not help, but now it can be used to point to - option -h now means not help, but now it can be used to point to
alternate IRRD host, like in old bgpq. alternate IRRD host, like in old bgpq.
0.1.6 (2008-08-08): 0.1.6 (2008-08-08):
- maxsockbuf call added, that can help with pipelining of really large - maxsockbuf call added, that can help with pipelining of really large
as-sets. as-sets.
- new key -M <extra match condition> for juniper route-filters, f.e.: - new key -M <extra match condition> for juniper route-filters, f.e.:
bgpq3 -JEM "protocol bgp;\n community no-export" -l PolicyName/TermName bgpq3 -JEM "protocol bgp;\n community no-export" -l PolicyName/TermName
will generate term with additional match conditions, like: will generate term with additional match conditions, like:
policy-options { policy-options {
policy-statement PolicyName { policy-statement PolicyName {
@@ -106,34 +119,34 @@ format, or else the regular expression match will fail.
} }
} }
0.1.5 (2008-06-02): 0.1.5 (2008-06-02):
- route-set's expansion added. Fully functional for IPv4 prefixes, but - route-set's expansion added. Fully functional for IPv4 prefixes, but
not for IPv6 - only those prefixes explicitely marked as 'member-of: RS..' not for IPv6 - only those prefixes explicitely marked as 'member-of: RS..'
will be expanded. This is due to limitation in IRRd. will be expanded. This is due to limitation in IRRd.
- extended access-lists (Cisco) and route-filters (Juniper) generation - extended access-lists (Cisco) and route-filters (Juniper) generation
is supported now with new -E key. For Cisco ipv6 access-lists is not is supported now with new -E key. For Cisco ipv6 access-lists is not
yet supported. yet supported.
0.1.4 (2008-05-30): 0.1.4 (2008-05-30):
- bugfix for juniper as-path group generation. Thanks to Alexander Shikoff. - bugfix for juniper as-path group generation. Thanks to Alexander Shikoff.
0.1.3 (2008-05-20): 0.1.3 (2008-05-20):
- aggregation (-A) now supported for Cisco prefix-lists. - aggregation (-A) now supported for Cisco prefix-lists.
- pipelining now can be enabled for RIPE-style queries too (ipv6). - pipelining now can be enabled for RIPE-style queries too (ipv6).
- more-specific routes (-R len) feature ported from bgpq - more-specific routes (-R len) feature ported from bgpq
- pipelining now set by default. -T flag now disables pipelining. - pipelining now set by default. -T flag now disables pipelining.
- strlcpy.c imported into sources. Not found on Linux :) - strlcpy.c imported into sources. Not found on Linux :)
0.1.2 (2008-05-19): 0.1.2 (2008-05-19):
- final support for asn32, now with correct syntax for Juniper. - final support for asn32, now with correct syntax for Juniper.
- experimental 'pipelining' mode (flag -T), much faster when - experimental 'pipelining' mode (flag -T), much faster when
working with big as-set's. working with big as-set's.
- RIPE-style query (-i origin) now requests only route6 objects. - RIPE-style query (-i origin) now requests only route6 objects.
0.1.1 (2008-05-16): 0.1.1 (2008-05-16):
- initial support for asn32 added (flag -3). By default it's off, - initial support for asn32 added (flag -3). By default it's off,
and when bgpq sees 32-bit asn in resolver queue, it either replaces and when bgpq sees 32-bit asn in resolver queue, it either replaces
it with AS23456 (in as-path generation mode) or queries radb for it with AS23456 (in as-path generation mode) or queries radb for
prefixes with that origin. prefixes with that origin.
Note: for now only JunOS 9.1 can handle asn32, not Cisco IOS.. Note: for now only JunOS 9.1 can handle asn32, not Cisco IOS..

190
bgpq3.c
View File

@@ -22,11 +22,11 @@ extern int pipelining;
int int
usage(int ecode) usage(int ecode)
{ {
printf("\nUsage: bgpq3 [-h host] [-S sources] [-P|E|G <num>|f <num>]" printf("\nUsage: bgpq3 [-h host] [-S sources] [-P|E|G <num>|f <num>]"
" [-346AbDJjXd] [-R len] <OBJECTS>...\n"); " [-346AbDJjXd] [-R len] <OBJECTS>...\n");
printf(" -3 : assume that your device is asn32-safe\n"); printf(" -3 : assume that your device is asn32-safe\n");
printf(" -4 : generate IPv4 prefix-lists (default)\n"); printf(" -4 : generate IPv4 prefix-lists (default)\n");
printf(" -6 : generate IPv6 prefix-lists (IPv4 by default)\n"); printf(" -6 : generate IPv6 prefix-lists (IPv4 by default)\n");
printf(" -A : try to aggregate Cisco prefix-lists or Juniper " printf(" -A : try to aggregate Cisco prefix-lists or Juniper "
"route-filters\n as much as possible\n"); "route-filters\n as much as possible\n");
@@ -61,7 +61,7 @@ usage(int ecode)
void void
exclusive() exclusive()
{ {
fprintf(stderr,"-E, -f <asnum>, -G <asnum> and -P are mutually " fprintf(stderr,"-E, -f <asnum>, -G <asnum> and -P are mutually "
"exclusive\n"); "exclusive\n");
exit(1); exit(1);
@@ -69,7 +69,7 @@ exclusive()
void void
vendor_exclusive() vendor_exclusive()
{ {
fprintf(stderr, "-b (BIRD), -J (JunOS), -j (JSON) and -X (IOS XR) options are " fprintf(stderr, "-b (BIRD), -J (JunOS), -j (JSON) and -X (IOS XR) options are "
"mutually exclusive\n"); "mutually exclusive\n");
exit(1); exit(1);
@@ -77,32 +77,32 @@ vendor_exclusive()
int int
parseasnumber(struct bgpq_expander* expander, char* optarg) parseasnumber(struct bgpq_expander* expander, char* optarg)
{ {
char* eon=NULL; char* eon=NULL;
expander->asnumber=strtoul(optarg,&eon,10); expander->asnumber=strtoul(optarg,&eon,10);
if(expander->asnumber<1 || expander->asnumber>(65535ul*65535)) { if(expander->asnumber<1 || expander->asnumber>(65535ul*65535)) {
sx_report(SX_FATAL,"Invalid AS number: %s\n", optarg); sx_report(SX_FATAL,"Invalid AS number: %s\n", optarg);
exit(1); exit(1);
}; };
if(eon && *eon=='.') { if(eon && *eon=='.') {
/* -f 3.3, for example */ /* -f 3.3, for example */
uint32_t loas=strtoul(eon+1,&eon,10); uint32_t loas=strtoul(eon+1,&eon,10);
if(expander->asnumber>65535) { if(expander->asnumber>65535) {
/* should prevent incorrect numbers like 65537.1 */ /* should prevent incorrect numbers like 65537.1 */
sx_report(SX_FATAL,"Invalid AS number: %s\n", optarg); sx_report(SX_FATAL,"Invalid AS number: %s\n", optarg);
exit(1); exit(1);
}; };
if(loas<1 || loas>65535) { if(loas<1 || loas>65535) {
sx_report(SX_FATAL,"Invalid AS number: %s\n", optarg); sx_report(SX_FATAL,"Invalid AS number: %s\n", optarg);
exit(1); exit(1);
}; };
if(eon && *eon) { if(eon && *eon) {
sx_report(SX_FATAL,"Invalid symbol in AS number: %c (%s)\n", sx_report(SX_FATAL,"Invalid symbol in AS number: %c (%s)\n",
*eon, optarg); *eon, optarg);
exit(1); exit(1);
}; };
expander->asnumber=(expander->asnumber<<16)+loas; expander->asnumber=(expander->asnumber<<16)+loas;
} else if(eon && *eon) { } else if(eon && *eon) {
sx_report(SX_FATAL,"Invalid symbol in AS number: %c (%s)\n", sx_report(SX_FATAL,"Invalid symbol in AS number: %c (%s)\n",
*eon, optarg); *eon, optarg);
exit(1); exit(1);
@@ -112,7 +112,7 @@ parseasnumber(struct bgpq_expander* expander, char* optarg)
int int
main(int argc, char* argv[]) main(int argc, char* argv[])
{ {
int c; int c;
struct bgpq_expander expander; struct bgpq_expander expander;
int af=AF_INET, selectedipv4 = 0; int af=AF_INET, selectedipv4 = 0;
@@ -123,11 +123,11 @@ main(int argc, char* argv[])
expander.sources=getenv("IRRD_SOURCES"); expander.sources=getenv("IRRD_SOURCES");
while((c=getopt(argc,argv,"346AbdDES:jJf:l:m:M:W:Pr:R:G:Th:X"))!=EOF) { while((c=getopt(argc,argv,"346AbdDES:jJf:l:m:M:W:Pr:R:G:Th:X"))!=EOF) {
switch(c) { switch(c) {
case '3': case '3':
expander.asn32=1; expander.asn32=1;
break; break;
case '4': case '4':
/* do nothing, expander already configured for IPv4 */ /* do nothing, expander already configured for IPv4 */
if (expander.family == AF_INET6) { if (expander.family == AF_INET6) {
sx_report(SX_FATAL, "-4 and -6 are mutually exclusive\n"); sx_report(SX_FATAL, "-4 and -6 are mutually exclusive\n");
@@ -135,8 +135,8 @@ main(int argc, char* argv[])
}; };
selectedipv4=1; selectedipv4=1;
break; break;
case '6': case '6':
if (selectedipv4) { if (selectedipv4) {
sx_report(SX_FATAL, "-4 and -6 are mutually exclusive\n"); sx_report(SX_FATAL, "-4 and -6 are mutually exclusive\n");
exit(1); exit(1);
}; };
@@ -144,11 +144,11 @@ main(int argc, char* argv[])
expander.family=AF_INET6; expander.family=AF_INET6;
expander.tree->family=AF_INET6; expander.tree->family=AF_INET6;
break; break;
case 'A': case 'A':
if(aggregate) debug_aggregation++; if(aggregate) debug_aggregation++;
aggregate=1; aggregate=1;
break; break;
case 'b': case 'b':
if(expander.vendor) vendor_exclusive(); if(expander.vendor) vendor_exclusive();
expander.vendor=V_BIRD; expander.vendor=V_BIRD;
break; break;
@@ -167,30 +167,30 @@ main(int argc, char* argv[])
case 'j': if(expander.vendor) vendor_exclusive(); case 'j': if(expander.vendor) vendor_exclusive();
expander.vendor=V_JSON; expander.vendor=V_JSON;
break; break;
case 'f': case 'f':
if(expander.generation) exclusive(); if(expander.generation) exclusive();
expander.generation=T_ASPATH; expander.generation=T_ASPATH;
parseasnumber(&expander,optarg); parseasnumber(&expander,optarg);
break; break;
case 'G': case 'G':
if(expander.generation) exclusive(); if(expander.generation) exclusive();
expander.generation=T_OASPATH; expander.generation=T_OASPATH;
parseasnumber(&expander,optarg); parseasnumber(&expander,optarg);
break; break;
case 'P': case 'P':
if(expander.generation) exclusive(); if(expander.generation) exclusive();
expander.generation=T_PREFIXLIST; expander.generation=T_PREFIXLIST;
break; break;
case 'r': case 'r':
refineLow=strtoul(optarg,NULL,10); refineLow=strtoul(optarg,NULL,10);
if(!refineLow) { if(!refineLow) {
sx_report(SX_FATAL,"Invalid refineLow value: %s\n", optarg); sx_report(SX_FATAL,"Invalid refineLow value: %s\n", optarg);
exit(1); exit(1);
}; };
break; break;
case 'R': case 'R':
refine=strtoul(optarg,NULL,10); refine=strtoul(optarg,NULL,10);
if(!refine) { if(!refine) {
sx_report(SX_FATAL,"Invalid refine length: %s\n", optarg); sx_report(SX_FATAL,"Invalid refine length: %s\n", optarg);
exit(1); exit(1);
}; };
@@ -198,32 +198,32 @@ main(int argc, char* argv[])
case 'l': expander.name=optarg; case 'l': expander.name=optarg;
break; break;
case 'm': maxlen=strtoul(optarg, NULL, 10); case 'm': maxlen=strtoul(optarg, NULL, 10);
if (!maxlen) { if (!maxlen) {
sx_report(SX_FATAL, "Invalid maxlen (-m): %s\n", optarg); sx_report(SX_FATAL, "Invalid maxlen (-m): %s\n", optarg);
exit(1); exit(1);
}; };
break; break;
case 'M': { case 'M': {
char* c, *d; char* c, *d;
expander.match=strdup(optarg); expander.match=strdup(optarg);
c=d=expander.match; c=d=expander.match;
while(*c) { while(*c) {
if(*c=='\\') { if(*c=='\\') {
if(*(c+1)=='n') { if(*(c+1)=='n') {
*d='\n'; *d='\n';
d++; d++;
c+=2; c+=2;
} else if(*(c+1)=='r') { } else if(*(c+1)=='r') {
*d='\r'; *d='\r';
d++; d++;
c+=2; c+=2;
} else if(*(c+1)=='\\') { } else if(*(c+1)=='\\') {
*d='\\'; *d='\\';
d++; d++;
c+=2; c+=2;
}; };
} else { } else {
if(c!=d) { if(c!=d) {
*d=*c; *d=*c;
}; };
d++; d++;
@@ -238,7 +238,7 @@ main(int argc, char* argv[])
case 'S': expander.sources=optarg; case 'S': expander.sources=optarg;
break; break;
case 'W': expander.aswidth=atoi(optarg); case 'W': expander.aswidth=atoi(optarg);
if(expander.aswidth<1) { if(expander.aswidth<1) {
sx_report(SX_FATAL,"Invalid as-width: %s\n", optarg); sx_report(SX_FATAL,"Invalid as-width: %s\n", optarg);
exit(1); exit(1);
}; };
@@ -254,23 +254,23 @@ main(int argc, char* argv[])
argc-=optind; argc-=optind;
argv+=optind; argv+=optind;
if(!widthSet) { if(!widthSet) {
if(expander.generation==T_ASPATH) { if(expander.generation==T_ASPATH) {
if(expander.vendor==V_CISCO) { if(expander.vendor==V_CISCO) {
expander.aswidth=4; expander.aswidth=4;
} else if(expander.vendor==V_JUNIPER) { } else if(expander.vendor==V_JUNIPER) {
expander.aswidth=8; expander.aswidth=8;
}; };
} else if(expander.generation==T_OASPATH) { } else if(expander.generation==T_OASPATH) {
if(expander.vendor==V_CISCO) { if(expander.vendor==V_CISCO) {
expander.aswidth=5; expander.aswidth=5;
} else if(expander.vendor==V_JUNIPER) { } else if(expander.vendor==V_JUNIPER) {
expander.aswidth=8; expander.aswidth=8;
}; };
}; };
}; };
if(!expander.generation) { if(!expander.generation) {
expander.generation=T_PREFIXLIST; expander.generation=T_PREFIXLIST;
}; };
@@ -281,130 +281,132 @@ main(int argc, char* argv[])
sx_report(SX_FATAL, "Sorry, only prefix-lists supported for BIRD " sx_report(SX_FATAL, "Sorry, only prefix-lists supported for BIRD "
"output\n"); "output\n");
}; };
if(expander.vendor==V_JSON && expander.generation!=T_PREFIXLIST) { if(expander.vendor==V_JSON && expander.generation!=T_PREFIXLIST &&
sx_report(SX_FATAL, "Sorry, only prefix-lists supported for JSON " expander.generation!=T_ASPATH) {
"output\n"); sx_report(SX_FATAL, "Sorry, only prefix-lists and as-paths supported "
"for JSON output\n");
}; };
if(expander.asdot && expander.vendor!=V_CISCO) { if(expander.asdot && expander.vendor!=V_CISCO) {
sx_report(SX_FATAL,"asdot notation supported only for Cisco, Juniper" sx_report(SX_FATAL,"asdot notation supported only for Cisco, Juniper"
" uses asplain only\n"); " uses asplain only\n");
}; };
if(!expander.asn32 && expander.asnumber>65535) { if(!expander.asn32 && expander.asnumber>65535) {
expander.asnumber=23456; expander.asnumber=23456;
}; };
if(aggregate && expander.vendor==V_JUNIPER && if(aggregate && expander.vendor==V_JUNIPER &&
expander.generation==T_PREFIXLIST) { expander.generation==T_PREFIXLIST) {
sx_report(SX_FATAL, "Sorry, aggregation (-A) does not work in" sx_report(SX_FATAL, "Sorry, aggregation (-A) does not work in"
" Juniper prefix-lists\nYou can try route-filters (-E) instead" " Juniper prefix-lists\nYou can try route-filters (-E) instead"
" of prefix-lists (-P, default)\n"); " of prefix-lists (-P, default)\n");
exit(1); exit(1);
}; };
if(aggregate && expander.generation<T_PREFIXLIST) { if(aggregate && expander.generation<T_PREFIXLIST) {
sx_report(SX_FATAL, "Sorry, aggregation (-A) used only for prefix-" sx_report(SX_FATAL, "Sorry, aggregation (-A) used only for prefix-"
"lists, extended access-lists and route-filters\n"); "lists, extended access-lists and route-filters\n");
exit(1); exit(1);
}; };
if(refineLow && !refine) { if(refineLow && !refine) {
if(expander.family == AF_INET) if(expander.family == AF_INET)
refine = 32; refine = 32;
else else
refine = 128; refine = 128;
}; };
if (refineLow && refineLow > refine) { if (refineLow && refineLow > refine) {
sx_report(SX_FATAL, "Incompatible values for -r %u and -R %u\n", sx_report(SX_FATAL, "Incompatible values for -r %u and -R %u\n",
refineLow, refine); refineLow, refine);
}; };
if(refine || refineLow) { if(refine || refineLow) {
if(expander.family==AF_INET6 && refine>128) { if(expander.family==AF_INET6 && refine>128) {
sx_report(SX_FATAL, "Invalid value for refine(-R): %u (1-128 for" sx_report(SX_FATAL, "Invalid value for refine(-R): %u (1-128 for"
" IPv6)\n", refine); " IPv6)\n", refine);
} else if(expander.family==AF_INET6 && refineLow>128) { } else if(expander.family==AF_INET6 && refineLow>128) {
sx_report(SX_FATAL, "Invalid value for refineLow(-r): %u (1-128 for" sx_report(SX_FATAL, "Invalid value for refineLow(-r): %u (1-128 for"
" IPv6)\n", refineLow); " IPv6)\n", refineLow);
} else if(expander.family==AF_INET && refine>32) { } else if(expander.family==AF_INET && refine>32) {
sx_report(SX_FATAL, "Invalid value for refine(-R): %u (1-32 for" sx_report(SX_FATAL, "Invalid value for refine(-R): %u (1-32 for"
" IPv4)\n", refine); " IPv4)\n", refine);
} else if(expander.family==AF_INET && refineLow>32) { } else if(expander.family==AF_INET && refineLow>32) {
sx_report(SX_FATAL, "Invalid value for refineLow(-r): %u (1-32 for" sx_report(SX_FATAL, "Invalid value for refineLow(-r): %u (1-32 for"
" IPv4)\n", refineLow); " IPv4)\n", refineLow);
}; };
if(expander.vendor==V_JUNIPER && expander.generation==T_PREFIXLIST) { if(expander.vendor==V_JUNIPER && expander.generation==T_PREFIXLIST) {
if(refine) { if(refine) {
sx_report(SX_FATAL, "Sorry, more-specific filters (-R %u) " sx_report(SX_FATAL, "Sorry, more-specific filters (-R %u) "
"is not supported for Juniper prefix-lists.\n" "is not supported for Juniper prefix-lists.\n"
"Use router-filters (-E) instead\n", refine); "Use router-filters (-E) instead\n", refine);
} else { } else {
sx_report(SX_FATAL, "Sorry, more-specific filters (-r %u) " sx_report(SX_FATAL, "Sorry, more-specific filters (-r %u) "
"is not supported for Juniper prefix-lists.\n" "is not supported for Juniper prefix-lists.\n"
"Use route-filters (-E) instead\n", refineLow); "Use route-filters (-E) instead\n", refineLow);
}; };
}; };
if(expander.generation<T_PREFIXLIST) { if(expander.generation<T_PREFIXLIST) {
if(refine) { if(refine) {
sx_report(SX_FATAL, "Sorry, more-specific filter (-R %u) " sx_report(SX_FATAL, "Sorry, more-specific filter (-R %u) "
"supported only with prefix-list generation\n", refine); "supported only with prefix-list generation\n", refine);
} else { } else {
sx_report(SX_FATAL, "Sorry, more-specific filter (-r %u) " sx_report(SX_FATAL, "Sorry, more-specific filter (-r %u) "
"supported only with prefix-list generation\n", refineLow); "supported only with prefix-list generation\n", refineLow);
}; };
}; };
}; };
if(maxlen) { if(maxlen) {
if((expander.family==AF_INET6 && maxlen>128) || if((expander.family==AF_INET6 && maxlen>128) ||
(expander.family==AF_INET && maxlen>32)) { (expander.family==AF_INET && maxlen>32)) {
sx_report(SX_FATAL, "Invalid value for max-prefixlen: %lu (1-128 " sx_report(SX_FATAL, "Invalid value for max-prefixlen: %lu (1-128 "
"for IPv6, 1-32 for IPv4)\n", maxlen); "for IPv6, 1-32 for IPv4)\n", maxlen);
exit(1); exit(1);
} else if((expander.family==AF_INET6 && maxlen<128) || } else if((expander.family==AF_INET6 && maxlen<128) ||
(expander.family==AF_INET && maxlen<32)) { (expander.family==AF_INET && maxlen<32)) {
/* inet6/128 and inet4/32 does not make sense - all routes will /* inet6/128 and inet4/32 does not make sense - all routes will
* be accepted, so save some CPU cycles :) */ * be accepted, so save some CPU cycles :) */
expander.maxlen = maxlen; expander.maxlen = maxlen;
}; };
}; };
if(expander.generation==T_EACL && expander.vendor==V_CISCO && if(expander.generation==T_EACL && expander.vendor==V_CISCO &&
expander.family==AF_INET6) { expander.family==AF_INET6) {
sx_report(SX_FATAL,"Sorry, ipv6 access-lists not supported for Cisco" sx_report(SX_FATAL,"Sorry, ipv6 access-lists not supported for Cisco"
" yet.\n"); " yet.\n");
}; };
if(expander.match != NULL && (expander.vendor != V_JUNIPER || if(expander.match != NULL && (expander.vendor != V_JUNIPER ||
expander.generation != T_EACL)) { expander.generation != T_EACL)) {
sx_report(SX_FATAL, "Sorry, extra match conditions (-M) can be used only with Juniper route-filters\n"); sx_report(SX_FATAL, "Sorry, extra match conditions (-M) can be used "
"only with Juniper route-filters\n");
}; };
if(!argv[0]) usage(1); if(!argv[0]) usage(1);
while(argv[0]) { while(argv[0]) {
if(!strncasecmp(argv[0],"AS-",3)) { if(!strncasecmp(argv[0],"AS-",3)) {
bgpq_expander_add_asset(&expander,argv[0]); bgpq_expander_add_asset(&expander,argv[0]);
} else if(!strncasecmp(argv[0],"RS-",3)) { } else if(!strncasecmp(argv[0],"RS-",3)) {
bgpq_expander_add_rset(&expander,argv[0]); bgpq_expander_add_rset(&expander,argv[0]);
} else if(!strncasecmp(argv[0],"AS",2)) { } else if(!strncasecmp(argv[0],"AS",2)) {
char* c; char* c;
if((c=strchr(argv[0],':'))) { if((c=strchr(argv[0],':'))) {
if(!strncasecmp(c+1,"AS-",3)) { if(!strncasecmp(c+1,"AS-",3)) {
bgpq_expander_add_asset(&expander,argv[0]); bgpq_expander_add_asset(&expander,argv[0]);
} else if(!strncasecmp(c+1,"RS-",3)) { } else if(!strncasecmp(c+1,"RS-",3)) {
bgpq_expander_add_rset(&expander,argv[0]); bgpq_expander_add_rset(&expander,argv[0]);
} else { } else {
SX_DEBUG(debug_expander,"Unknown sub-as object %s\n", SX_DEBUG(debug_expander,"Unknown sub-as object %s\n",
argv[0]); argv[0]);
}; };
} else { } else {
bgpq_expander_add_as(&expander,argv[0]); bgpq_expander_add_as(&expander,argv[0]);
}; };
} else { } else {
if(!bgpq_expander_add_prefix(&expander,argv[0])) if(!bgpq_expander_add_prefix(&expander,argv[0]))
exit(1); exit(1);
}; };
@@ -412,20 +414,20 @@ main(int argc, char* argv[])
argc--; argc--;
}; };
if(!bgpq_expand(&expander)) { if(!bgpq_expand(&expander)) {
exit(1); exit(1);
}; };
if(refine) if(refine)
sx_radix_tree_refine(expander.tree,refine); sx_radix_tree_refine(expander.tree,refine);
if(refineLow) if(refineLow)
sx_radix_tree_refineLow(expander.tree, refineLow); sx_radix_tree_refineLow(expander.tree, refineLow);
if(aggregate) if(aggregate)
sx_radix_tree_aggregate(expander.tree); sx_radix_tree_aggregate(expander.tree);
switch(expander.generation) { switch(expander.generation) {
default : default :
case T_NONE: sx_report(SX_FATAL,"Unreachable point... call snar\n"); case T_NONE: sx_report(SX_FATAL,"Unreachable point... call snar\n");
exit(1); exit(1);

View File

@@ -1,12 +1,12 @@
Name: bgpq3 Name: bgpq3
Version: 0.1.21 Version: 0.1.25
Release: 0%{?dist} Release: 0%{?dist}
Group: System/Utilities Group: System/Utilities
Summary: Automate BGP filter generation based on routing database information Summary: Automate BGP filter generation based on routing database information
URL: http://snar.spb.ru/prog/bgpq3/ URL: http://snar.spb.ru/prog/bgpq3/
License: BSD License: BSD
Source0: http://snar.spb.ru/prog/bgpq3/bgpq3-0.1.21.tgz Source0: http://snar.spb.ru/prog/bgpq3/bgpq3-0.1.25.tgz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
%description %description
@@ -35,6 +35,9 @@ rm -rf $RPM_BUILD_ROOT
%changelog %changelog
* Wed Oct 29 Alexandre Snarskii <snar@snar.spb.ru> 0.1.25
- Version updated
* Thu Jun 5 2014 Alexandre Snarskii <snar@snar.spb.ru> 0.1.21-0.snar * Thu Jun 5 2014 Alexandre Snarskii <snar@snar.spb.ru> 0.1.21-0.snar
- Version updated - Version updated

View File

@@ -14,55 +14,57 @@
#include "bgpq3.h" #include "bgpq3.h"
#include "sx_report.h" #include "sx_report.h"
int bgpq3_print_json_aspath(FILE* f, struct bgpq_expander* b);
int int
bgpq3_print_cisco_aspath(FILE* f, struct bgpq_expander* b) bgpq3_print_cisco_aspath(FILE* f, struct bgpq_expander* b)
{ {
int nc=0, i, j, k, empty=1; int nc=0, i, j, k, empty=1;
fprintf(f,"no ip as-path access-list %s\n", b->name?b->name:"NN"); fprintf(f,"no ip as-path access-list %s\n", b->name?b->name:"NN");
if(b->asn32s[b->asnumber/65536] && if(b->asn32s[b->asnumber/65536] &&
b->asn32s[b->asnumber/65536][(b->asnumber%65536)/8]& b->asn32s[b->asnumber/65536][(b->asnumber%65536)/8]&
(0x80>>(b->asnumber%8))) { (0x80>>(b->asnumber%8))) {
if(b->asdot && b->asnumber>65535) { if(b->asdot && b->asnumber>65535) {
fprintf(f,"ip as-path access-list %s permit ^%i.%i(_%i.%i)*$\n", fprintf(f,"ip as-path access-list %s permit ^%i.%i(_%i.%i)*$\n",
b->name?b->name:"NN",b->asnumber/65536,b->asnumber%65536, b->name?b->name:"NN",b->asnumber/65536,b->asnumber%65536,
b->asnumber/65536,b->asnumber%65536); b->asnumber/65536,b->asnumber%65536);
empty=0; empty=0;
} else { } else {
fprintf(f,"ip as-path access-list %s permit ^%i(_%i)*$\n", fprintf(f,"ip as-path access-list %s permit ^%i(_%i)*$\n",
b->name?b->name:"NN",b->asnumber,b->asnumber); b->name?b->name:"NN",b->asnumber,b->asnumber);
empty=0; empty=0;
}; };
}; };
for(k=0;k<65536;k++) { for(k=0;k<65536;k++) {
if(!b->asn32s[k]) continue; if(!b->asn32s[k]) continue;
for(i=0;i<8192;i++) { for(i=0;i<8192;i++) {
for(j=0;j<8;j++) { for(j=0;j<8;j++) {
if(b->asn32s[k][i]&(0x80>>j)) { if(b->asn32s[k][i]&(0x80>>j)) {
if(k*65536+i*8+j==b->asnumber) continue; if(k*65536+i*8+j==b->asnumber) continue;
if(!nc) { if(!nc) {
if(b->asdot && k>0) { if(b->asdot && k>0) {
fprintf(f,"ip as-path access-list %s permit" fprintf(f,"ip as-path access-list %s permit"
" ^%i(_[0-9]+)*_(%i.%i", b->name?b->name:"NN", " ^%i(_[0-9]+)*_(%i.%i", b->name?b->name:"NN",
b->asnumber,k,i*8+j); b->asnumber,k,i*8+j);
empty=0; empty=0;
} else { } else {
fprintf(f,"ip as-path access-list %s permit" fprintf(f,"ip as-path access-list %s permit"
" ^%i(_[0-9]+)*_(%i", b->name?b->name:"NN", " ^%i(_[0-9]+)*_(%i", b->name?b->name:"NN",
b->asnumber,k*65536+i*8+j); b->asnumber,k*65536+i*8+j);
empty=0; empty=0;
}; };
} else { } else {
if(b->asdot && k>0) { if(b->asdot && k>0) {
fprintf(f,"|%i.%i",k,i*8+j); fprintf(f,"|%i.%i",k,i*8+j);
empty=0; empty=0;
} else { } else {
fprintf(f,"|%i",k*65536+i*8+j); fprintf(f,"|%i",k*65536+i*8+j);
empty=0; empty=0;
}; };
} }
nc++; nc++;
if(nc==b->aswidth) { if(nc==b->aswidth) {
fprintf(f,")$\n"); fprintf(f,")$\n");
nc=0; nc=0;
}; };
@@ -77,50 +79,50 @@ bgpq3_print_cisco_aspath(FILE* f, struct bgpq_expander* b)
}; };
int int
bgpq3_print_cisco_oaspath(FILE* f, struct bgpq_expander* b) bgpq3_print_cisco_oaspath(FILE* f, struct bgpq_expander* b)
{ {
int nc=0, i, j, k, empty=1; int nc=0, i, j, k, empty=1;
fprintf(f,"no ip as-path access-list %s\n", b->name?b->name:"NN"); fprintf(f,"no ip as-path access-list %s\n", b->name?b->name:"NN");
if(b->asn32s[b->asnumber/65536] && if(b->asn32s[b->asnumber/65536] &&
b->asn32s[b->asnumber/65536][(b->asnumber%65536)/8]& b->asn32s[b->asnumber/65536][(b->asnumber%65536)/8]&
(0x80>>(b->asnumber%8))) { (0x80>>(b->asnumber%8))) {
if(b->asdot && b->asnumber>65535) { if(b->asdot && b->asnumber>65535) {
fprintf(f,"ip as-path access-list %s permit ^(_%i.%i)*$\n", fprintf(f,"ip as-path access-list %s permit ^(_%i.%i)*$\n",
b->name?b->name:"NN",b->asnumber/65536,b->asnumber%65536); b->name?b->name:"NN",b->asnumber/65536,b->asnumber%65536);
} else { } else {
fprintf(f,"ip as-path access-list %s permit ^(_%i)*$\n", fprintf(f,"ip as-path access-list %s permit ^(_%i)*$\n",
b->name?b->name:"NN",b->asnumber); b->name?b->name:"NN",b->asnumber);
}; };
empty=0; empty=0;
}; };
for(k=0;k<65536;k++) { for(k=0;k<65536;k++) {
if(!b->asn32s[k]) continue; if(!b->asn32s[k]) continue;
for(i=0;i<8192;i++) { for(i=0;i<8192;i++) {
for(j=0;j<8;j++) { for(j=0;j<8;j++) {
if(b->asn32s[k][i]&(0x80>>j)) { if(b->asn32s[k][i]&(0x80>>j)) {
if(k*65536+i*8+j==b->asnumber) continue; if(k*65536+i*8+j==b->asnumber) continue;
if(!nc) { if(!nc) {
if(b->asdot && k>0) { if(b->asdot && k>0) {
fprintf(f,"ip as-path access-list %s permit" fprintf(f,"ip as-path access-list %s permit"
" ^(_[0-9]+)*_(%i.%i", b->name?b->name:"NN", " ^(_[0-9]+)*_(%i.%i", b->name?b->name:"NN",
k,i*8+j); k,i*8+j);
empty=0; empty=0;
} else { } else {
fprintf(f,"ip as-path access-list %s permit" fprintf(f,"ip as-path access-list %s permit"
" ^(_[0-9]+)*_(%i", b->name?b->name:"NN", " ^(_[0-9]+)*_(%i", b->name?b->name:"NN",
k*65536+i*8+j); k*65536+i*8+j);
empty=0; empty=0;
}; };
} else { } else {
if(b->asdot && k>0) { if(b->asdot && k>0) {
fprintf(f,"|%i.%i",k,i*8+j); fprintf(f,"|%i.%i",k,i*8+j);
empty=0; empty=0;
} else { } else {
fprintf(f,"|%i",k*65536+i*8+j); fprintf(f,"|%i",k*65536+i*8+j);
empty=0; empty=0;
}; };
} }
nc++; nc++;
if(nc==b->aswidth) { if(nc==b->aswidth) {
fprintf(f,")$\n"); fprintf(f,")$\n");
nc=0; nc=0;
}; };
@@ -129,39 +131,39 @@ bgpq3_print_cisco_oaspath(FILE* f, struct bgpq_expander* b)
}; };
}; };
if(nc) fprintf(f,")$\n"); if(nc) fprintf(f,")$\n");
if(empty) if(empty)
fprintf(f,"ip as-path access-list %s deny .*\n", b->name?b->name:"NN"); fprintf(f,"ip as-path access-list %s deny .*\n", b->name?b->name:"NN");
return 0; return 0;
}; };
int int
bgpq3_print_juniper_aspath(FILE* f, struct bgpq_expander* b) bgpq3_print_juniper_aspath(FILE* f, struct bgpq_expander* b)
{ {
int nc=0, lineNo=0, i, j, k; int nc=0, lineNo=0, i, j, k;
fprintf(f,"policy-options {\nreplace:\n as-path-group %s {\n", fprintf(f,"policy-options {\nreplace:\n as-path-group %s {\n",
b->name?b->name:"NN"); b->name?b->name:"NN");
if(b->asn32s[b->asnumber/65536] && if(b->asn32s[b->asnumber/65536] &&
b->asn32s[b->asnumber/65535][(b->asnumber%65536)/8]& b->asn32s[b->asnumber/65535][(b->asnumber%65536)/8]&
(0x80>>(b->asnumber%8))) { (0x80>>(b->asnumber%8))) {
fprintf(f," as-path a%i \"^%u(%u)*$\";\n", lineNo, b->asnumber, fprintf(f," as-path a%i \"^%u(%u)*$\";\n", lineNo, b->asnumber,
b->asnumber); b->asnumber);
lineNo++; lineNo++;
}; };
for(k=0;k<65536;k++) { for(k=0;k<65536;k++) {
if(!b->asn32s[k]) continue; if(!b->asn32s[k]) continue;
for(i=0;i<8192;i++) { for(i=0;i<8192;i++) {
for(j=0;j<8;j++) { for(j=0;j<8;j++) {
if(b->asn32s[k][i]&(0x80>>j)) { if(b->asn32s[k][i]&(0x80>>j)) {
if(k*65536+i*8+j==b->asnumber) continue; if(k*65536+i*8+j==b->asnumber) continue;
if(!nc) { if(!nc) {
fprintf(f," as-path a%i \"^%u(.)*(%u", fprintf(f," as-path a%i \"^%u(.)*(%u",
lineNo,b->asnumber,k*65536+i*8+j); lineNo,b->asnumber,k*65536+i*8+j);
} else { } else {
fprintf(f,"|%u",k*65536+i*8+j); fprintf(f,"|%u",k*65536+i*8+j);
}; };
nc++; nc++;
if(nc==b->aswidth) { if(nc==b->aswidth) {
fprintf(f,")$\";\n"); fprintf(f,")$\";\n");
nc=0; nc=0;
lineNo++; lineNo++;
@@ -171,7 +173,7 @@ bgpq3_print_juniper_aspath(FILE* f, struct bgpq_expander* b)
}; };
}; };
if(nc) fprintf(f,")$\";\n"); if(nc) fprintf(f,")$\";\n");
else if(lineNo==0) else if(lineNo==0)
fprintf(f," as-path aNone \"!.*\";\n"); fprintf(f," as-path aNone \"!.*\";\n");
fprintf(f," }\n}\n"); fprintf(f," }\n}\n");
return 0; return 0;
@@ -179,33 +181,33 @@ bgpq3_print_juniper_aspath(FILE* f, struct bgpq_expander* b)
int int
bgpq3_print_juniper_oaspath(FILE* f, struct bgpq_expander* b) bgpq3_print_juniper_oaspath(FILE* f, struct bgpq_expander* b)
{ {
int nc=0, lineNo=0, i, j, k; int nc=0, lineNo=0, i, j, k;
fprintf(f,"policy-options {\nreplace:\n as-path-group %s {\n", fprintf(f,"policy-options {\nreplace:\n as-path-group %s {\n",
b->name?b->name:"NN"); b->name?b->name:"NN");
if(b->asn32s[b->asnumber/65536] && if(b->asn32s[b->asnumber/65536] &&
b->asn32s[b->asnumber/65536][(b->asnumber%65536)/8]& b->asn32s[b->asnumber/65536][(b->asnumber%65536)/8]&
(0x80>>(b->asnumber%8))) { (0x80>>(b->asnumber%8))) {
fprintf(f," as-path a%i \"^%u(%u)*$\";\n", lineNo, b->asnumber, fprintf(f," as-path a%i \"^%u(%u)*$\";\n", lineNo, b->asnumber,
b->asnumber); b->asnumber);
lineNo++; lineNo++;
}; };
for(k=0;k<65536;k++) { for(k=0;k<65536;k++) {
if(!b->asn32s[k]) continue; if(!b->asn32s[k]) continue;
for(i=0;i<8192;i++) { for(i=0;i<8192;i++) {
for(j=0;j<8;j++) { for(j=0;j<8;j++) {
if(b->asn32s[k][i]&(0x80>>j)) { if(b->asn32s[k][i]&(0x80>>j)) {
if(k*65536+i*8+j==b->asnumber) continue; if(k*65536+i*8+j==b->asnumber) continue;
if(!nc) { if(!nc) {
fprintf(f," as-path a%i \"^(.)*(%u", fprintf(f," as-path a%i \"^(.)*(%u",
lineNo,k*65536+i*8+j); lineNo,k*65536+i*8+j);
} else { } else {
fprintf(f,"|%u",k*65536+i*8+j); fprintf(f,"|%u",k*65536+i*8+j);
} }
nc++; nc++;
if(nc==b->aswidth) { if(nc==b->aswidth) {
fprintf(f,")$\";\n"); fprintf(f,")$\";\n");
nc=0; nc=0;
lineNo++; lineNo++;
@@ -215,7 +217,7 @@ bgpq3_print_juniper_oaspath(FILE* f, struct bgpq_expander* b)
}; };
}; };
if(nc) fprintf(f,")$\";\n"); if(nc) fprintf(f,")$\";\n");
else if(lineNo==0) else if(lineNo==0)
fprintf(f," as-path aNone \"!.*\";\n"); fprintf(f," as-path aNone \"!.*\";\n");
fprintf(f," }\n}\n"); fprintf(f," }\n}\n");
return 0; return 0;
@@ -223,12 +225,14 @@ bgpq3_print_juniper_oaspath(FILE* f, struct bgpq_expander* b)
int int
bgpq3_print_aspath(FILE* f, struct bgpq_expander* b) bgpq3_print_aspath(FILE* f, struct bgpq_expander* b)
{ {
if(b->vendor==V_JUNIPER) { if(b->vendor==V_JUNIPER) {
return bgpq3_print_juniper_aspath(f,b); return bgpq3_print_juniper_aspath(f,b);
} else if(b->vendor==V_CISCO) { } else if(b->vendor==V_CISCO) {
return bgpq3_print_cisco_aspath(f,b); return bgpq3_print_cisco_aspath(f,b);
} else { } else if(b->vendor==V_JSON) {
return bgpq3_print_json_aspath(f,b);
} else {
sx_report(SX_FATAL,"Unknown vendor %i\n", b->vendor); sx_report(SX_FATAL,"Unknown vendor %i\n", b->vendor);
}; };
return 0; return 0;
@@ -236,12 +240,12 @@ bgpq3_print_aspath(FILE* f, struct bgpq_expander* b)
int int
bgpq3_print_oaspath(FILE* f, struct bgpq_expander* b) bgpq3_print_oaspath(FILE* f, struct bgpq_expander* b)
{ {
if(b->vendor==V_JUNIPER) { if(b->vendor==V_JUNIPER) {
return bgpq3_print_juniper_oaspath(f,b); return bgpq3_print_juniper_oaspath(f,b);
} else if(b->vendor==V_CISCO) { } else if(b->vendor==V_CISCO) {
return bgpq3_print_cisco_oaspath(f,b); return bgpq3_print_cisco_oaspath(f,b);
} else { } else {
sx_report(SX_FATAL,"Unknown vendor %i\n", b->vendor); sx_report(SX_FATAL,"Unknown vendor %i\n", b->vendor);
}; };
return 0; return 0;
@@ -249,7 +253,7 @@ bgpq3_print_oaspath(FILE* f, struct bgpq_expander* b)
void void
bgpq3_print_jprefix(struct sx_radix_node* n, void* ff) bgpq3_print_jprefix(struct sx_radix_node* n, void* ff)
{ {
char prefix[128]; char prefix[128];
FILE* f=(FILE*)ff; FILE* f=(FILE*)ff;
if(n->isGlue) return; if(n->isGlue) return;
@@ -262,33 +266,75 @@ static int needscomma=0;
void void
bgpq3_print_json_prefix(struct sx_radix_node* n, void* ff) bgpq3_print_json_prefix(struct sx_radix_node* n, void* ff)
{ {
char prefix[128]; char prefix[128];
FILE* f=(FILE*)ff; FILE* f=(FILE*)ff;
if(n->isGlue) if(n->isGlue)
goto checkSon; goto checkSon;
if(!f) if(!f)
f=stdout; f=stdout;
sx_prefix_jsnprintf(&n->prefix, prefix, sizeof(prefix)); sx_prefix_jsnprintf(&n->prefix, prefix, sizeof(prefix));
if (!n->isAggregate) { if (!n->isAggregate) {
fprintf(f, "%s\n { \"prefix\": \"%s\", \"exact\": true }", fprintf(f, "%s\n { \"prefix\": \"%s\", \"exact\": true }",
needscomma?",":"", prefix); needscomma?",":"", prefix);
} else if (n->aggregateLow > n->prefix.masklen) { } else if (n->aggregateLow > n->prefix.masklen) {
fprintf(f, "%s\n { \"prefix\": \"%s\", \"exact\": false,\n " fprintf(f, "%s\n { \"prefix\": \"%s\", \"exact\": false,\n "
"\"greater-equal\": %u, \"less-equal\": %u }", "\"greater-equal\": %u, \"less-equal\": %u }",
needscomma?",":"", prefix, needscomma?",":"", prefix,
n->aggregateLow, n->aggregateHi); n->aggregateLow, n->aggregateHi);
} else { } else {
fprintf(f, "%s\n { \"prefix\": \"%s\", \"exact\": false, " fprintf(f, "%s\n { \"prefix\": \"%s\", \"exact\": false, "
"\"less-equal\": %u }", "\"less-equal\": %u }",
needscomma?",":"", prefix, n->aggregateHi); needscomma?",":"", prefix, n->aggregateHi);
}; };
needscomma=1; needscomma=1;
checkSon: checkSon:
if(n->son) if(n->son)
bgpq3_print_json_prefix(n->son, ff); bgpq3_print_json_prefix(n->son, ff);
}; };
int
bgpq3_print_json_aspath(FILE* f, struct bgpq_expander* b)
{
int nc=0, i, j, k;
fprintf(f,"{\"%s\": [", b->name?b->name:"NN");
for(k=0;k<65536;k++) {
if(!b->asn32s[k]) continue;
for(i=0;i<8192;i++) {
for(j=0;j<8;j++) {
if(b->asn32s[k][i]&(0x80>>j)) {
if(!nc) {
if(b->asdot && k>0) {
fprintf(f,"%s\n %i.%i",needscomma?",":"", k,i*8+j);
needscomma=1;
} else {
fprintf(f,"%s\n %i",needscomma?",":"",
k*65536+i*8+j);
needscomma=1;
};
} else {
if(b->asdot && k>0) {
fprintf(f,"%s%i.%i,",needscomma?",":"", k,i*8+j);
needscomma=1;
} else {
fprintf(f,"%s%i",needscomma?",":"", k*65536+i*8+j);
needscomma=1;
};
}
nc++;
if(nc==b->aswidth) {
nc=0;
};
};
};
};
};
fprintf(f,"\n]}\n");
return 0;
};
void void
bgpq3_print_bird_prefix(struct sx_radix_node* n, void* ff) bgpq3_print_bird_prefix(struct sx_radix_node* n, void* ff)
{ {
@@ -317,19 +363,19 @@ checkSon:
void void
bgpq3_print_jrfilter(struct sx_radix_node* n, void* ff) bgpq3_print_jrfilter(struct sx_radix_node* n, void* ff)
{ {
char prefix[128]; char prefix[128];
FILE* f=(FILE*)ff; FILE* f=(FILE*)ff;
if(n->isGlue) goto checkSon; if(n->isGlue) goto checkSon;
if(!f) f=stdout; if(!f) f=stdout;
sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix)); sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix));
if(!n->isAggregate) { if(!n->isAggregate) {
fprintf(f," route-filter %s exact;\n", prefix); fprintf(f," route-filter %s exact;\n", prefix);
} else { } else {
if(n->aggregateLow>n->prefix.masklen) { if(n->aggregateLow>n->prefix.masklen) {
fprintf(f," route-filter %s prefix-length-range /%u-/%u;\n", fprintf(f," route-filter %s prefix-length-range /%u-/%u;\n",
prefix,n->aggregateLow,n->aggregateHi); prefix,n->aggregateLow,n->aggregateHi);
} else { } else {
fprintf(f," route-filter %s upto /%u;\n", prefix,n->aggregateHi); fprintf(f," route-filter %s upto /%u;\n", prefix,n->aggregateHi);
}; };
}; };
@@ -343,59 +389,59 @@ static char* bname=NULL;
void void
bgpq3_print_cprefix(struct sx_radix_node* n, void* ff) bgpq3_print_cprefix(struct sx_radix_node* n, void* ff)
{ {
char prefix[128]; char prefix[128];
FILE* f=(FILE*)ff; FILE* f=(FILE*)ff;
if(!f) f=stdout; if(!f) f=stdout;
if(n->isGlue) goto checkSon; if(n->isGlue) goto checkSon;
sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix)); sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix));
if(n->isAggregate) { if(n->isAggregate) {
if(n->aggregateLow>n->prefix.masklen) { if(n->aggregateLow>n->prefix.masklen) {
fprintf(f,"%s prefix-list %s permit %s ge %u le %u\n", fprintf(f,"%s prefix-list %s permit %s ge %u le %u\n",
n->prefix.family==AF_INET?"ip":"ipv6",bname?bname:"NN",prefix, n->prefix.family==AF_INET?"ip":"ipv6",bname?bname:"NN",prefix,
n->aggregateLow,n->aggregateHi); n->aggregateLow,n->aggregateHi);
} else { } else {
fprintf(f,"%s prefix-list %s permit %s le %u\n", fprintf(f,"%s prefix-list %s permit %s le %u\n",
n->prefix.family==AF_INET?"ip":"ipv6",bname?bname:"NN",prefix, n->prefix.family==AF_INET?"ip":"ipv6",bname?bname:"NN",prefix,
n->aggregateHi); n->aggregateHi);
}; };
} else { } else {
fprintf(f,"%s prefix-list %s permit %s\n", fprintf(f,"%s prefix-list %s permit %s\n",
(n->prefix.family==AF_INET)?"ip":"ipv6",bname?bname:"NN",prefix); (n->prefix.family==AF_INET)?"ip":"ipv6",bname?bname:"NN",prefix);
}; };
checkSon: checkSon:
if(n->son) if(n->son)
bgpq3_print_cprefix(n->son,ff); bgpq3_print_cprefix(n->son,ff);
}; };
void void
bgpq3_print_cprefixxr(struct sx_radix_node* n, void* ff) bgpq3_print_cprefixxr(struct sx_radix_node* n, void* ff)
{ {
char prefix[128]; char prefix[128];
FILE* f=(FILE*)ff; FILE* f=(FILE*)ff;
if(!f) f=stdout; if(!f) f=stdout;
if(n->isGlue) goto checkSon; if(n->isGlue) goto checkSon;
sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix)); sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix));
if(n->isAggregate) { if(n->isAggregate) {
if(n->aggregateLow>n->prefix.masklen) { if(n->aggregateLow>n->prefix.masklen) {
fprintf(f,"%s%s ge %u le %u", fprintf(f,"%s%s ge %u le %u",
needscomma?",\n ":" ", prefix, n->aggregateLow,n->aggregateHi); needscomma?",\n ":" ", prefix, n->aggregateLow,n->aggregateHi);
} else { } else {
fprintf(f,"%s%s le %u", needscomma?",\n ":" ", prefix, fprintf(f,"%s%s le %u", needscomma?",\n ":" ", prefix,
n->aggregateHi); n->aggregateHi);
}; };
} else { } else {
fprintf(f,"%s%s", needscomma?",\n ":" ", prefix); fprintf(f,"%s%s", needscomma?",\n ":" ", prefix);
}; };
needscomma=1; needscomma=1;
checkSon: checkSon:
if(n->son) if(n->son)
bgpq3_print_cprefixxr(n->son,ff); bgpq3_print_cprefixxr(n->son,ff);
}; };
void void
bgpq3_print_ceacl(struct sx_radix_node* n, void* ff) bgpq3_print_ceacl(struct sx_radix_node* n, void* ff)
{ {
char prefix[128]; char prefix[128];
FILE* f=(FILE*)ff; FILE* f=(FILE*)ff;
char* c; char* c;
@@ -406,21 +452,21 @@ bgpq3_print_ceacl(struct sx_radix_node* n, void* ff)
c=strchr(prefix,'/'); c=strchr(prefix,'/');
if(c) *c=0; if(c) *c=0;
if(n->prefix.masklen==32) { if(n->prefix.masklen==32) {
netmask=0; netmask=0;
} else { } else {
netmask<<=(32-n->prefix.masklen); netmask<<=(32-n->prefix.masklen);
netmask&=0xfffffffful; netmask&=0xfffffffful;
}; };
netmask=htonl(netmask); netmask=htonl(netmask);
if(n->isAggregate) { if(n->isAggregate) {
unsigned long mask=0xfffffffful, wildaddr, wild2addr, wildmask; unsigned long mask=0xfffffffful, wildaddr, wild2addr, wildmask;
int masklen=n->aggregateLow; int masklen=n->aggregateLow;
wildaddr=0xfffffffful>>n->prefix.masklen; wildaddr=0xfffffffful>>n->prefix.masklen;
if(n->aggregateHi==32) { if(n->aggregateHi==32) {
wild2addr=0; wild2addr=0;
} else { } else {
wild2addr=0xfffffffful>>n->aggregateHi; wild2addr=0xfffffffful>>n->aggregateHi;
}; };
wildaddr=wildaddr&(~wild2addr); wildaddr=wildaddr&(~wild2addr);
@@ -436,31 +482,31 @@ bgpq3_print_ceacl(struct sx_radix_node* n, void* ff)
wildaddr=htonl(wildaddr); wildaddr=htonl(wildaddr);
wildmask=htonl(wildmask); wildmask=htonl(wildmask);
if(wildaddr) { if(wildaddr) {
fprintf(f," permit ip %s ", inet_ntoa(n->prefix.addr.addr)); fprintf(f," permit ip %s ", inet_ntoa(n->prefix.addr.addr));
fprintf(f,"%s ", inet_ntoa(*(struct in_addr*)&wildaddr)); fprintf(f,"%s ", inet_ntoa(*(struct in_addr*)&wildaddr));
} else { } else {
fprintf(f," permit ip host %s ",inet_ntoa(n->prefix.addr.addr)); fprintf(f," permit ip host %s ",inet_ntoa(n->prefix.addr.addr));
}; };
if(wildmask) { if(wildmask) {
fprintf(f,"%s ", inet_ntoa(*(struct in_addr*)&mask)); fprintf(f,"%s ", inet_ntoa(*(struct in_addr*)&mask));
fprintf(f,"%s\n", inet_ntoa(*(struct in_addr*)&wildmask)); fprintf(f,"%s\n", inet_ntoa(*(struct in_addr*)&wildmask));
} else { } else {
fprintf(f,"host %s\n", inet_ntoa(*(struct in_addr*)&mask)); fprintf(f,"host %s\n", inet_ntoa(*(struct in_addr*)&mask));
}; };
} else { } else {
fprintf(f," permit ip host %s host %s\n",prefix, fprintf(f," permit ip host %s host %s\n",prefix,
inet_ntoa(*(struct in_addr*)&netmask)); inet_ntoa(*(struct in_addr*)&netmask));
}; };
checkSon: checkSon:
if(n->son) if(n->son)
bgpq3_print_ceacl(n->son,ff); bgpq3_print_ceacl(n->son,ff);
}; };
int int
bgpq3_print_juniper_prefixlist(FILE* f, struct bgpq_expander* b) bgpq3_print_juniper_prefixlist(FILE* f, struct bgpq_expander* b)
{ {
fprintf(f,"policy-options {\nreplace:\n prefix-list %s {\n", fprintf(f,"policy-options {\nreplace:\n prefix-list %s {\n",
b->name?b->name:"NN"); b->name?b->name:"NN");
sx_radix_tree_foreach(b->tree,bgpq3_print_jprefix,f); sx_radix_tree_foreach(b->tree,bgpq3_print_jprefix,f);
@@ -470,29 +516,29 @@ bgpq3_print_juniper_prefixlist(FILE* f, struct bgpq_expander* b)
int int
bgpq3_print_juniper_routefilter(FILE* f, struct bgpq_expander* b) bgpq3_print_juniper_routefilter(FILE* f, struct bgpq_expander* b)
{ {
char* c=NULL; char* c=NULL;
if(b->name && (c=strchr(b->name,'/'))) { if(b->name && (c=strchr(b->name,'/'))) {
*c=0; *c=0;
fprintf(f,"policy-options {\n policy-statement %s {\n term %s {\n" fprintf(f,"policy-options {\n policy-statement %s {\n term %s {\n"
"replace:\n from {\n", b->name, c+1); "replace:\n from {\n", b->name, c+1);
if(b->match) if(b->match)
fprintf(f," %s;\n",b->match); fprintf(f," %s;\n",b->match);
} else { } else {
fprintf(f,"policy-options {\n policy-statement %s { \n" fprintf(f,"policy-options {\n policy-statement %s { \n"
"replace:\n from {\n", b->name?b->name:"NN"); "replace:\n from {\n", b->name?b->name:"NN");
if(b->match) if(b->match)
fprintf(f," %s;\n",b->match); fprintf(f," %s;\n",b->match);
}; };
if(!sx_radix_tree_empty(b->tree)) { if(!sx_radix_tree_empty(b->tree)) {
sx_radix_tree_foreach(b->tree,bgpq3_print_jrfilter,f); sx_radix_tree_foreach(b->tree,bgpq3_print_jrfilter,f);
} else { } else {
fprintf(f," route-filter %s/0 orlonger reject;\n", fprintf(f," route-filter %s/0 orlonger reject;\n",
b->tree->family == AF_INET ? "0.0.0.0" : "::"); b->tree->family == AF_INET ? "0.0.0.0" : "::");
}; };
if(c) { if(c) {
fprintf(f, " }\n }\n }\n}\n"); fprintf(f, " }\n }\n }\n}\n");
} else { } else {
fprintf(f, " }\n }\n}\n"); fprintf(f, " }\n }\n}\n");
}; };
return 0; return 0;
@@ -500,15 +546,15 @@ bgpq3_print_juniper_routefilter(FILE* f, struct bgpq_expander* b)
int int
bgpq3_print_cisco_prefixlist(FILE* f, struct bgpq_expander* b) bgpq3_print_cisco_prefixlist(FILE* f, struct bgpq_expander* b)
{ {
bname=b->name ? b->name : "NN"; bname=b->name ? b->name : "NN";
fprintf(f,"no %s prefix-list %s\n", fprintf(f,"no %s prefix-list %s\n",
(b->family==AF_INET)?"ip":"ipv6",bname); (b->family==AF_INET)?"ip":"ipv6",bname);
if (!sx_radix_tree_empty(b->tree)) { if (!sx_radix_tree_empty(b->tree)) {
sx_radix_tree_foreach(b->tree,bgpq3_print_cprefix,f); sx_radix_tree_foreach(b->tree,bgpq3_print_cprefix,f);
} else { } else {
fprintf(f, "! generated prefix-list %s is empty\n", bname); fprintf(f, "! generated prefix-list %s is empty\n", bname);
fprintf(f, "%s prefix-list %s deny 0.0.0.0/0\n", fprintf(f, "%s prefix-list %s deny 0.0.0.0/0\n",
(b->family==AF_INET) ? "ip" : "ipv6", bname); (b->family==AF_INET) ? "ip" : "ipv6", bname);
}; };
return 0; return 0;
@@ -516,7 +562,7 @@ bgpq3_print_cisco_prefixlist(FILE* f, struct bgpq_expander* b)
int int
bgpq3_print_ciscoxr_prefixlist(FILE* f, struct bgpq_expander* b) bgpq3_print_ciscoxr_prefixlist(FILE* f, struct bgpq_expander* b)
{ {
bname=b->name ? b->name : "NN"; bname=b->name ? b->name : "NN";
fprintf(f,"no prefix-set %s\nprefix-set %s\n", bname, bname); fprintf(f,"no prefix-set %s\nprefix-set %s\n", bname, bname);
sx_radix_tree_foreach(b->tree,bgpq3_print_cprefixxr,f); sx_radix_tree_foreach(b->tree,bgpq3_print_cprefixxr,f);
@@ -526,7 +572,7 @@ bgpq3_print_ciscoxr_prefixlist(FILE* f, struct bgpq_expander* b)
int int
bgpq3_print_json_prefixlist(FILE* f, struct bgpq_expander* b) bgpq3_print_json_prefixlist(FILE* f, struct bgpq_expander* b)
{ {
fprintf(f,"{ \"%s\": [", fprintf(f,"{ \"%s\": [",
b->name?b->name:"NN"); b->name?b->name:"NN");
sx_radix_tree_foreach(b->tree,bgpq3_print_json_prefix,f); sx_radix_tree_foreach(b->tree,bgpq3_print_json_prefix,f);
@@ -546,13 +592,13 @@ bgpq3_print_bird_prefixlist(FILE* f, struct bgpq_expander* b)
int int
bgpq3_print_cisco_eacl(FILE* f, struct bgpq_expander* b) bgpq3_print_cisco_eacl(FILE* f, struct bgpq_expander* b)
{ {
bname=b->name ? b->name : "NN"; bname=b->name ? b->name : "NN";
fprintf(f,"no ip access-list extended %s\n", bname); fprintf(f,"no ip access-list extended %s\n", bname);
if (!sx_radix_tree_empty(b->tree)) { if (!sx_radix_tree_empty(b->tree)) {
fprintf(f,"ip access-list extended %s\n", bname); fprintf(f,"ip access-list extended %s\n", bname);
sx_radix_tree_foreach(b->tree,bgpq3_print_ceacl,f); sx_radix_tree_foreach(b->tree,bgpq3_print_ceacl,f);
} else { } else {
fprintf(f,"! generated access-list %s is empty\n", bname); fprintf(f,"! generated access-list %s is empty\n", bname);
fprintf(f,"ip access-list extended %s deny any any\n", bname); fprintf(f,"ip access-list extended %s deny any any\n", bname);
}; };
@@ -561,8 +607,8 @@ bgpq3_print_cisco_eacl(FILE* f, struct bgpq_expander* b)
int int
bgpq3_print_prefixlist(FILE* f, struct bgpq_expander* b) bgpq3_print_prefixlist(FILE* f, struct bgpq_expander* b)
{ {
switch(b->vendor) { switch(b->vendor) {
case V_JUNIPER: return bgpq3_print_juniper_prefixlist(f,b); case V_JUNIPER: return bgpq3_print_juniper_prefixlist(f,b);
case V_CISCO: return bgpq3_print_cisco_prefixlist(f,b); case V_CISCO: return bgpq3_print_cisco_prefixlist(f,b);
case V_CISCO_XR: return bgpq3_print_ciscoxr_prefixlist(f,b); case V_CISCO_XR: return bgpq3_print_ciscoxr_prefixlist(f,b);
@@ -574,8 +620,8 @@ bgpq3_print_prefixlist(FILE* f, struct bgpq_expander* b)
int int
bgpq3_print_eacl(FILE* f, struct bgpq_expander* b) bgpq3_print_eacl(FILE* f, struct bgpq_expander* b)
{ {
switch(b->vendor) { switch(b->vendor) {
case V_JUNIPER: return bgpq3_print_juniper_routefilter(f,b); case V_JUNIPER: return bgpq3_print_juniper_routefilter(f,b);
case V_CISCO: return bgpq3_print_cisco_eacl(f,b); case V_CISCO: return bgpq3_print_cisco_eacl(f,b);
case V_CISCO_XR: sx_report(SX_FATAL, "unreachable point\n"); case V_CISCO_XR: sx_report(SX_FATAL, "unreachable point\n");

18
configure vendored
View File

@@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Guess values for system-dependent variables and create Makefiles. # Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69 for bgpq3 0.1.24. # Generated by GNU Autoconf 2.69 for bgpq3 0.1.25.
# #
# Report bugs to <snar@snar.spb.ru>. # Report bugs to <snar@snar.spb.ru>.
# #
@@ -579,8 +579,8 @@ MAKEFLAGS=
# Identity of this package. # Identity of this package.
PACKAGE_NAME='bgpq3' PACKAGE_NAME='bgpq3'
PACKAGE_TARNAME='bgpq3' PACKAGE_TARNAME='bgpq3'
PACKAGE_VERSION='0.1.24' PACKAGE_VERSION='0.1.25'
PACKAGE_STRING='bgpq3 0.1.24' PACKAGE_STRING='bgpq3 0.1.25'
PACKAGE_BUGREPORT='snar@snar.spb.ru' PACKAGE_BUGREPORT='snar@snar.spb.ru'
PACKAGE_URL='' PACKAGE_URL=''
@@ -1187,7 +1187,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing. # Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh. # This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF cat <<_ACEOF
\`configure' configures bgpq3 0.1.24 to adapt to many kinds of systems. \`configure' configures bgpq3 0.1.25 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]... Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1248,7 +1248,7 @@ fi
if test -n "$ac_init_help"; then if test -n "$ac_init_help"; then
case $ac_init_help in case $ac_init_help in
short | recursive ) echo "Configuration of bgpq3 0.1.24:";; short | recursive ) echo "Configuration of bgpq3 0.1.25:";;
esac esac
cat <<\_ACEOF cat <<\_ACEOF
@@ -1327,7 +1327,7 @@ fi
test -n "$ac_init_help" && exit $ac_status test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then if $ac_init_version; then
cat <<\_ACEOF cat <<\_ACEOF
bgpq3 configure 0.1.24 bgpq3 configure 0.1.25
generated by GNU Autoconf 2.69 generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc. Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1495,7 +1495,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake. running configure, to aid debugging if configure makes a mistake.
It was created by bgpq3 $as_me 0.1.24, which was It was created by bgpq3 $as_me 0.1.25, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@ $ $0 $@
@@ -3413,7 +3413,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their # report actual input values of CONFIG_FILES etc. instead of their
# values after options handling. # values after options handling.
ac_log=" ac_log="
This file was extended by bgpq3 $as_me 0.1.24, which was This file was extended by bgpq3 $as_me 0.1.25, which was
generated by GNU Autoconf 2.69. Invocation command line was generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES CONFIG_FILES = $CONFIG_FILES
@@ -3475,7 +3475,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\ ac_cs_version="\\
bgpq3 config.status 0.1.24 bgpq3 config.status 0.1.25
configured by $0, generated by GNU Autoconf 2.69, configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\" with options \\"\$ac_cs_config\\"

View File

@@ -1,4 +1,4 @@
AC_INIT(bgpq3,0.1.24,snar@snar.spb.ru) AC_INIT(bgpq3,0.1.25,snar@snar.spb.ru)
AC_CONFIG_HEADER(config.h) AC_CONFIG_HEADER(config.h)
AC_PROG_CC AC_PROG_CC
AC_PROG_INSTALL AC_PROG_INSTALL