diff --git a/CHANGES b/CHANGES index e554ef3..527f2c3 100644 --- a/CHANGES +++ b/CHANGES @@ -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 - filters (Cisco and Juniper) and route-filters (Juniper) handling: - explicit 'deny any' entry now generated instead of implicit 'permit-any'. + filters (Cisco and Juniper) and route-filters (Juniper) handling: + explicit 'deny any' entry now generated instead of implicit 'permit-any'. Based on suggestion by Tore Anderson. 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. 0.1.22 (2014-07-27) @@ -17,11 +30,11 @@ 0.1.21 (2014-06-05) - new flag -b: generate prefix-filters for BIRD (http://bird.network.cz), contributed by Job Snijders. - + 0.1.20-todo2 (2014-05-01) - new flag -r , allowing bgpq to generate limited set of more-specific - routes - only routes with prefix-length >= are accepted. - Thanks to Pavel Gulchouck for suggesion. + routes - only routes with prefix-length >= are accepted. + Thanks to Pavel Gulchouck for suggesion. 0.1.20-todo (2013-10-07) - socket close code fixed. Thanks to Martin J. Levy. @@ -31,7 +44,7 @@ 0.1.19 (2013-05-09) - CLANG compilation issues fixed. - bgpq3.spec added. Thanks to Arnoud Vermeer. - + 0.1.18 (2013-01-08) - JSON output format. Thanks to Job Snijders (Atrato Networks). @@ -41,57 +54,57 @@ - bug in aggregation documentation fixed. Thanks to Nikolay Shopik. 0.1.16 (2012-01-19) - - new option -m : maximum length of accepted prefixes. + - new option -m : maximum length of accepted 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. - - documentation redesigned into text/markdown and text/html (manpage + - documentation redesigned into text/markdown and text/html (manpage supported still). 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) - - 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. 0.1.13 (2011-06-14) - never publically released. 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 0.1.11 (2010-04-19) - Fixed another bug in aggregation (-A) mode, thanks to Dmitry Tejblum. 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) - 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) - new flag -D for Cisco asdot notation. Cisco behaviour is a bit - strange for me, but, well, that's their decision: -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 -format, or else the regular expression match will fail. + strange for me, but, well, that's their decision: +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 +format, or else the regular expression match will fail. (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): - - man page. Finally :) - - option -h now means not help, but now it can be used to point to +0.1.7 (2008-12-19): + - man page. Finally :) + - option -h now means not help, but now it can be used to point to 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 as-sets. - - new key -M for juniper route-filters, f.e.: - bgpq3 -JEM "protocol bgp;\n community no-export" -l PolicyName/TermName - will generate term with additional match conditions, like: + - new key -M for juniper route-filters, f.e.: + bgpq3 -JEM "protocol bgp;\n community no-export" -l PolicyName/TermName + will generate term with additional match conditions, like: policy-options { 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 not for IPv6 - only those prefixes explicitely marked as 'member-of: RS..' will be expanded. This is due to limitation in IRRd. - extended access-lists (Cisco) and route-filters (Juniper) generation 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. -0.1.3 (2008-05-20): - - aggregation (-A) now supported for Cisco prefix-lists. - - pipelining now can be enabled for RIPE-style queries too (ipv6). +0.1.3 (2008-05-20): + - aggregation (-A) now supported for Cisco prefix-lists. + - pipelining now can be enabled for RIPE-style queries too (ipv6). - more-specific routes (-R len) feature ported from bgpq - 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): - - final support for asn32, now with correct syntax for Juniper. - - experimental 'pipelining' mode (flag -T), much faster when - working with big as-set's. - - RIPE-style query (-i origin) now requests only route6 objects. +0.1.2 (2008-05-19): + - final support for asn32, now with correct syntax for Juniper. + - experimental 'pipelining' mode (flag -T), much faster when + working with big as-set's. + - RIPE-style query (-i origin) now requests only route6 objects. -0.1.1 (2008-05-16): - - initial support for asn32 added (flag -3). By default it's off, +0.1.1 (2008-05-16): + - 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 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.. diff --git a/bgpq3.c b/bgpq3.c index 88182e0..10d64f3 100644 --- a/bgpq3.c +++ b/bgpq3.c @@ -22,11 +22,11 @@ extern int pipelining; int usage(int ecode) -{ +{ printf("\nUsage: bgpq3 [-h host] [-S sources] [-P|E|G |f ]" " [-346AbDJjXd] [-R len] ...\n"); - printf(" -3 : assume that your device is asn32-safe\n"); - printf(" -4 : generate IPv4 prefix-lists (default)\n"); + printf(" -3 : assume that your device is asn32-safe\n"); + printf(" -4 : generate IPv4 prefix-lists (default)\n"); printf(" -6 : generate IPv6 prefix-lists (IPv4 by default)\n"); printf(" -A : try to aggregate Cisco prefix-lists or Juniper " "route-filters\n as much as possible\n"); @@ -61,7 +61,7 @@ usage(int ecode) void exclusive() -{ +{ fprintf(stderr,"-E, -f , -G and -P are mutually " "exclusive\n"); exit(1); @@ -69,7 +69,7 @@ exclusive() void vendor_exclusive() -{ +{ fprintf(stderr, "-b (BIRD), -J (JunOS), -j (JSON) and -X (IOS XR) options are " "mutually exclusive\n"); exit(1); @@ -77,32 +77,32 @@ vendor_exclusive() int parseasnumber(struct bgpq_expander* expander, char* optarg) -{ +{ char* eon=NULL; 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); exit(1); }; - if(eon && *eon=='.') { + if(eon && *eon=='.') { /* -f 3.3, for example */ uint32_t loas=strtoul(eon+1,&eon,10); - if(expander->asnumber>65535) { + if(expander->asnumber>65535) { /* should prevent incorrect numbers like 65537.1 */ sx_report(SX_FATAL,"Invalid AS number: %s\n", optarg); exit(1); }; - if(loas<1 || loas>65535) { + if(loas<1 || loas>65535) { sx_report(SX_FATAL,"Invalid AS number: %s\n", optarg); exit(1); }; - if(eon && *eon) { + if(eon && *eon) { sx_report(SX_FATAL,"Invalid symbol in AS number: %c (%s)\n", *eon, optarg); exit(1); }; 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", *eon, optarg); exit(1); @@ -112,7 +112,7 @@ parseasnumber(struct bgpq_expander* expander, char* optarg) int main(int argc, char* argv[]) -{ +{ int c; struct bgpq_expander expander; int af=AF_INET, selectedipv4 = 0; @@ -123,11 +123,11 @@ main(int argc, char* argv[]) expander.sources=getenv("IRRD_SOURCES"); while((c=getopt(argc,argv,"346AbdDES:jJf:l:m:M:W:Pr:R:G:Th:X"))!=EOF) { - switch(c) { - case '3': + switch(c) { + case '3': expander.asn32=1; break; - case '4': + case '4': /* do nothing, expander already configured for IPv4 */ if (expander.family == AF_INET6) { sx_report(SX_FATAL, "-4 and -6 are mutually exclusive\n"); @@ -135,8 +135,8 @@ main(int argc, char* argv[]) }; selectedipv4=1; break; - case '6': - if (selectedipv4) { + case '6': + if (selectedipv4) { sx_report(SX_FATAL, "-4 and -6 are mutually exclusive\n"); exit(1); }; @@ -144,11 +144,11 @@ main(int argc, char* argv[]) expander.family=AF_INET6; expander.tree->family=AF_INET6; break; - case 'A': + case 'A': if(aggregate) debug_aggregation++; aggregate=1; break; - case 'b': + case 'b': if(expander.vendor) vendor_exclusive(); expander.vendor=V_BIRD; break; @@ -167,30 +167,30 @@ main(int argc, char* argv[]) case 'j': if(expander.vendor) vendor_exclusive(); expander.vendor=V_JSON; break; - case 'f': + case 'f': if(expander.generation) exclusive(); expander.generation=T_ASPATH; parseasnumber(&expander,optarg); break; - case 'G': + case 'G': if(expander.generation) exclusive(); expander.generation=T_OASPATH; parseasnumber(&expander,optarg); break; - case 'P': + case 'P': if(expander.generation) exclusive(); expander.generation=T_PREFIXLIST; break; - case 'r': + case 'r': refineLow=strtoul(optarg,NULL,10); - if(!refineLow) { + if(!refineLow) { sx_report(SX_FATAL,"Invalid refineLow value: %s\n", optarg); exit(1); }; - break; - case 'R': + break; + case 'R': refine=strtoul(optarg,NULL,10); - if(!refine) { + if(!refine) { sx_report(SX_FATAL,"Invalid refine length: %s\n", optarg); exit(1); }; @@ -198,32 +198,32 @@ main(int argc, char* argv[]) case 'l': expander.name=optarg; break; case 'm': maxlen=strtoul(optarg, NULL, 10); - if (!maxlen) { + if (!maxlen) { sx_report(SX_FATAL, "Invalid maxlen (-m): %s\n", optarg); exit(1); }; break; - case 'M': { + case 'M': { char* c, *d; expander.match=strdup(optarg); - c=d=expander.match; - while(*c) { - if(*c=='\\') { - if(*(c+1)=='n') { + c=d=expander.match; + while(*c) { + if(*c=='\\') { + if(*(c+1)=='n') { *d='\n'; d++; c+=2; - } else if(*(c+1)=='r') { + } else if(*(c+1)=='r') { *d='\r'; d++; c+=2; - } else if(*(c+1)=='\\') { + } else if(*(c+1)=='\\') { *d='\\'; d++; c+=2; }; - } else { - if(c!=d) { + } else { + if(c!=d) { *d=*c; }; d++; @@ -238,7 +238,7 @@ main(int argc, char* argv[]) case 'S': expander.sources=optarg; break; case 'W': expander.aswidth=atoi(optarg); - if(expander.aswidth<1) { + if(expander.aswidth<1) { sx_report(SX_FATAL,"Invalid as-width: %s\n", optarg); exit(1); }; @@ -254,23 +254,23 @@ main(int argc, char* argv[]) argc-=optind; argv+=optind; - if(!widthSet) { - if(expander.generation==T_ASPATH) { - if(expander.vendor==V_CISCO) { + if(!widthSet) { + if(expander.generation==T_ASPATH) { + if(expander.vendor==V_CISCO) { expander.aswidth=4; - } else if(expander.vendor==V_JUNIPER) { + } else if(expander.vendor==V_JUNIPER) { expander.aswidth=8; }; - } else if(expander.generation==T_OASPATH) { - if(expander.vendor==V_CISCO) { + } else if(expander.generation==T_OASPATH) { + if(expander.vendor==V_CISCO) { expander.aswidth=5; - } else if(expander.vendor==V_JUNIPER) { + } else if(expander.vendor==V_JUNIPER) { expander.aswidth=8; }; }; }; - if(!expander.generation) { + if(!expander.generation) { expander.generation=T_PREFIXLIST; }; @@ -281,130 +281,132 @@ main(int argc, char* argv[]) sx_report(SX_FATAL, "Sorry, only prefix-lists supported for BIRD " "output\n"); }; - if(expander.vendor==V_JSON && expander.generation!=T_PREFIXLIST) { - sx_report(SX_FATAL, "Sorry, only prefix-lists supported for JSON " - "output\n"); + if(expander.vendor==V_JSON && expander.generation!=T_PREFIXLIST && + expander.generation!=T_ASPATH) { + 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" " uses asplain only\n"); }; - if(!expander.asn32 && expander.asnumber>65535) { + if(!expander.asn32 && expander.asnumber>65535) { expander.asnumber=23456; }; - if(aggregate && expander.vendor==V_JUNIPER && - expander.generation==T_PREFIXLIST) { + if(aggregate && expander.vendor==V_JUNIPER && + expander.generation==T_PREFIXLIST) { sx_report(SX_FATAL, "Sorry, aggregation (-A) does not work in" " Juniper prefix-lists\nYou can try route-filters (-E) instead" " of prefix-lists (-P, default)\n"); exit(1); }; - if(aggregate && expander.generation refine) { - sx_report(SX_FATAL, "Incompatible values for -r %u and -R %u\n", + if (refineLow && refineLow > refine) { + sx_report(SX_FATAL, "Incompatible values for -r %u and -R %u\n", refineLow, refine); }; - if(refine || refineLow) { - if(expander.family==AF_INET6 && refine>128) { + if(refine || refineLow) { + if(expander.family==AF_INET6 && refine>128) { sx_report(SX_FATAL, "Invalid value for refine(-R): %u (1-128 for" " 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" " 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" " 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" " IPv4)\n", refineLow); }; - if(expander.vendor==V_JUNIPER && expander.generation==T_PREFIXLIST) { - if(refine) { + if(expander.vendor==V_JUNIPER && expander.generation==T_PREFIXLIST) { + if(refine) { sx_report(SX_FATAL, "Sorry, more-specific filters (-R %u) " "is not supported for Juniper prefix-lists.\n" "Use router-filters (-E) instead\n", refine); - } else { + } else { sx_report(SX_FATAL, "Sorry, more-specific filters (-r %u) " "is not supported for Juniper prefix-lists.\n" "Use route-filters (-E) instead\n", refineLow); }; }; - if(expander.generation128) || - (expander.family==AF_INET && maxlen>32)) { + if(maxlen) { + if((expander.family==AF_INET6 && maxlen>128) || + (expander.family==AF_INET && maxlen>32)) { sx_report(SX_FATAL, "Invalid value for max-prefixlen: %lu (1-128 " "for IPv6, 1-32 for IPv4)\n", maxlen); exit(1); - } else if((expander.family==AF_INET6 && maxlen<128) || - (expander.family==AF_INET && maxlen<32)) { + } else if((expander.family==AF_INET6 && maxlen<128) || + (expander.family==AF_INET && maxlen<32)) { /* inet6/128 and inet4/32 does not make sense - all routes will * be accepted, so save some CPU cycles :) */ expander.maxlen = maxlen; }; }; - if(expander.generation==T_EACL && expander.vendor==V_CISCO && - expander.family==AF_INET6) { + if(expander.generation==T_EACL && expander.vendor==V_CISCO && + expander.family==AF_INET6) { sx_report(SX_FATAL,"Sorry, ipv6 access-lists not supported for Cisco" " yet.\n"); }; if(expander.match != NULL && (expander.vendor != V_JUNIPER || - expander.generation != T_EACL)) { - sx_report(SX_FATAL, "Sorry, extra match conditions (-M) can be used only with Juniper route-filters\n"); + expander.generation != T_EACL)) { + sx_report(SX_FATAL, "Sorry, extra match conditions (-M) can be used " + "only with Juniper route-filters\n"); }; if(!argv[0]) usage(1); - while(argv[0]) { - if(!strncasecmp(argv[0],"AS-",3)) { + while(argv[0]) { + if(!strncasecmp(argv[0],"AS-",3)) { 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]); - } else if(!strncasecmp(argv[0],"AS",2)) { + } else if(!strncasecmp(argv[0],"AS",2)) { char* c; - if((c=strchr(argv[0],':'))) { - if(!strncasecmp(c+1,"AS-",3)) { + if((c=strchr(argv[0],':'))) { + if(!strncasecmp(c+1,"AS-",3)) { 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]); - } else { + } else { SX_DEBUG(debug_expander,"Unknown sub-as object %s\n", argv[0]); }; - } else { + } else { bgpq_expander_add_as(&expander,argv[0]); }; - } else { + } else { if(!bgpq_expander_add_prefix(&expander,argv[0])) exit(1); }; @@ -412,20 +414,20 @@ main(int argc, char* argv[]) argc--; }; - if(!bgpq_expand(&expander)) { + if(!bgpq_expand(&expander)) { exit(1); }; - if(refine) + if(refine) sx_radix_tree_refine(expander.tree,refine); - if(refineLow) + if(refineLow) sx_radix_tree_refineLow(expander.tree, refineLow); - if(aggregate) + if(aggregate) sx_radix_tree_aggregate(expander.tree); - switch(expander.generation) { + switch(expander.generation) { default : case T_NONE: sx_report(SX_FATAL,"Unreachable point... call snar\n"); exit(1); diff --git a/bgpq3.spec b/bgpq3.spec index cb260e5..254da6f 100644 --- a/bgpq3.spec +++ b/bgpq3.spec @@ -1,12 +1,12 @@ Name: bgpq3 -Version: 0.1.21 +Version: 0.1.25 Release: 0%{?dist} Group: System/Utilities Summary: Automate BGP filter generation based on routing database information URL: http://snar.spb.ru/prog/bgpq3/ 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) %description @@ -35,6 +35,9 @@ rm -rf $RPM_BUILD_ROOT %changelog +* Wed Oct 29 Alexandre Snarskii 0.1.25 +- Version updated + * Thu Jun 5 2014 Alexandre Snarskii 0.1.21-0.snar - Version updated diff --git a/bgpq3_printer.c b/bgpq3_printer.c index 4a22913..7442575 100644 --- a/bgpq3_printer.c +++ b/bgpq3_printer.c @@ -14,55 +14,57 @@ #include "bgpq3.h" #include "sx_report.h" +int bgpq3_print_json_aspath(FILE* f, struct bgpq_expander* b); + int bgpq3_print_cisco_aspath(FILE* f, struct bgpq_expander* b) -{ +{ int nc=0, i, j, k, empty=1; 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]& - (0x80>>(b->asnumber%8))) { - if(b->asdot && b->asnumber>65535) { + (0x80>>(b->asnumber%8))) { + if(b->asdot && b->asnumber>65535) { 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->asnumber/65536,b->asnumber%65536); empty=0; - } else { + } else { fprintf(f,"ip as-path access-list %s permit ^%i(_%i)*$\n", b->name?b->name:"NN",b->asnumber,b->asnumber); empty=0; }; }; - for(k=0;k<65536;k++) { + 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)) { + for(i=0;i<8192;i++) { + for(j=0;j<8;j++) { + if(b->asn32s[k][i]&(0x80>>j)) { if(k*65536+i*8+j==b->asnumber) continue; - if(!nc) { - if(b->asdot && k>0) { + if(!nc) { + if(b->asdot && k>0) { 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); empty=0; - } else { + } else { 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); empty=0; }; - } else { - if(b->asdot && k>0) { + } else { + if(b->asdot && k>0) { fprintf(f,"|%i.%i",k,i*8+j); empty=0; - } else { + } else { fprintf(f,"|%i",k*65536+i*8+j); empty=0; }; } nc++; - if(nc==b->aswidth) { + if(nc==b->aswidth) { fprintf(f,")$\n"); nc=0; }; @@ -77,50 +79,50 @@ bgpq3_print_cisco_aspath(FILE* f, struct bgpq_expander* b) }; int bgpq3_print_cisco_oaspath(FILE* f, struct bgpq_expander* b) -{ +{ int nc=0, i, j, k, empty=1; 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]& - (0x80>>(b->asnumber%8))) { - if(b->asdot && b->asnumber>65535) { + (0x80>>(b->asnumber%8))) { + if(b->asdot && b->asnumber>65535) { fprintf(f,"ip as-path access-list %s permit ^(_%i.%i)*$\n", b->name?b->name:"NN",b->asnumber/65536,b->asnumber%65536); - } else { + } else { fprintf(f,"ip as-path access-list %s permit ^(_%i)*$\n", b->name?b->name:"NN",b->asnumber); }; empty=0; }; - for(k=0;k<65536;k++) { + 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)) { + for(i=0;i<8192;i++) { + for(j=0;j<8;j++) { + if(b->asn32s[k][i]&(0x80>>j)) { if(k*65536+i*8+j==b->asnumber) continue; - if(!nc) { - if(b->asdot && k>0) { + if(!nc) { + if(b->asdot && k>0) { 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); empty=0; - } else { + } else { 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); empty=0; }; - } else { - if(b->asdot && k>0) { + } else { + if(b->asdot && k>0) { fprintf(f,"|%i.%i",k,i*8+j); empty=0; - } else { + } else { fprintf(f,"|%i",k*65536+i*8+j); empty=0; }; } nc++; - if(nc==b->aswidth) { + if(nc==b->aswidth) { fprintf(f,")$\n"); nc=0; }; @@ -129,39 +131,39 @@ bgpq3_print_cisco_oaspath(FILE* f, struct bgpq_expander* b) }; }; if(nc) fprintf(f,")$\n"); - if(empty) + if(empty) fprintf(f,"ip as-path access-list %s deny .*\n", b->name?b->name:"NN"); return 0; }; int bgpq3_print_juniper_aspath(FILE* f, struct bgpq_expander* b) -{ +{ 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"); - if(b->asn32s[b->asnumber/65536] && + if(b->asn32s[b->asnumber/65536] && 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, b->asnumber); lineNo++; }; - for(k=0;k<65536;k++) { + 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)) { + for(i=0;i<8192;i++) { + for(j=0;j<8;j++) { + if(b->asn32s[k][i]&(0x80>>j)) { if(k*65536+i*8+j==b->asnumber) continue; - if(!nc) { + if(!nc) { fprintf(f," as-path a%i \"^%u(.)*(%u", lineNo,b->asnumber,k*65536+i*8+j); - } else { + } else { fprintf(f,"|%u",k*65536+i*8+j); }; nc++; - if(nc==b->aswidth) { + if(nc==b->aswidth) { fprintf(f,")$\";\n"); nc=0; lineNo++; @@ -171,7 +173,7 @@ bgpq3_print_juniper_aspath(FILE* f, struct bgpq_expander* b) }; }; if(nc) fprintf(f,")$\";\n"); - else if(lineNo==0) + else if(lineNo==0) fprintf(f," as-path aNone \"!.*\";\n"); fprintf(f," }\n}\n"); return 0; @@ -179,33 +181,33 @@ bgpq3_print_juniper_aspath(FILE* f, struct bgpq_expander* b) int bgpq3_print_juniper_oaspath(FILE* f, struct bgpq_expander* b) -{ +{ 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"); - if(b->asn32s[b->asnumber/65536] && + if(b->asn32s[b->asnumber/65536] && 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, b->asnumber); lineNo++; }; - for(k=0;k<65536;k++) { + 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)) { + for(i=0;i<8192;i++) { + for(j=0;j<8;j++) { + if(b->asn32s[k][i]&(0x80>>j)) { if(k*65536+i*8+j==b->asnumber) continue; - if(!nc) { + if(!nc) { fprintf(f," as-path a%i \"^(.)*(%u", lineNo,k*65536+i*8+j); - } else { + } else { fprintf(f,"|%u",k*65536+i*8+j); } nc++; - if(nc==b->aswidth) { + if(nc==b->aswidth) { fprintf(f,")$\";\n"); nc=0; lineNo++; @@ -215,7 +217,7 @@ bgpq3_print_juniper_oaspath(FILE* f, struct bgpq_expander* b) }; }; if(nc) fprintf(f,")$\";\n"); - else if(lineNo==0) + else if(lineNo==0) fprintf(f," as-path aNone \"!.*\";\n"); fprintf(f," }\n}\n"); return 0; @@ -223,12 +225,14 @@ bgpq3_print_juniper_oaspath(FILE* f, struct bgpq_expander* b) int 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); - } else if(b->vendor==V_CISCO) { + } else if(b->vendor==V_CISCO) { 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); }; return 0; @@ -236,12 +240,12 @@ bgpq3_print_aspath(FILE* f, struct bgpq_expander* b) int 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); - } else if(b->vendor==V_CISCO) { + } else if(b->vendor==V_CISCO) { return bgpq3_print_cisco_oaspath(f,b); - } else { + } else { sx_report(SX_FATAL,"Unknown vendor %i\n", b->vendor); }; return 0; @@ -249,7 +253,7 @@ bgpq3_print_oaspath(FILE* f, struct bgpq_expander* b) void bgpq3_print_jprefix(struct sx_radix_node* n, void* ff) -{ +{ char prefix[128]; FILE* f=(FILE*)ff; if(n->isGlue) return; @@ -262,33 +266,75 @@ static int needscomma=0; void bgpq3_print_json_prefix(struct sx_radix_node* n, void* ff) -{ +{ char prefix[128]; FILE* f=(FILE*)ff; - if(n->isGlue) + if(n->isGlue) goto checkSon; - if(!f) + if(!f) f=stdout; sx_prefix_jsnprintf(&n->prefix, prefix, sizeof(prefix)); - if (!n->isAggregate) { - fprintf(f, "%s\n { \"prefix\": \"%s\", \"exact\": true }", + if (!n->isAggregate) { + fprintf(f, "%s\n { \"prefix\": \"%s\", \"exact\": true }", 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 " - "\"greater-equal\": %u, \"less-equal\": %u }", + "\"greater-equal\": %u, \"less-equal\": %u }", needscomma?",":"", prefix, n->aggregateLow, n->aggregateHi); - } else { + } else { fprintf(f, "%s\n { \"prefix\": \"%s\", \"exact\": false, " - "\"less-equal\": %u }", + "\"less-equal\": %u }", needscomma?",":"", prefix, n->aggregateHi); }; needscomma=1; -checkSon: - if(n->son) +checkSon: + if(n->son) 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 bgpq3_print_bird_prefix(struct sx_radix_node* n, void* ff) { @@ -317,19 +363,19 @@ checkSon: void bgpq3_print_jrfilter(struct sx_radix_node* n, void* ff) -{ +{ char prefix[128]; FILE* f=(FILE*)ff; if(n->isGlue) goto checkSon; if(!f) f=stdout; sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix)); - if(!n->isAggregate) { + if(!n->isAggregate) { fprintf(f," route-filter %s exact;\n", prefix); - } else { - if(n->aggregateLow>n->prefix.masklen) { - fprintf(f," route-filter %s prefix-length-range /%u-/%u;\n", + } else { + if(n->aggregateLow>n->prefix.masklen) { + fprintf(f," route-filter %s prefix-length-range /%u-/%u;\n", prefix,n->aggregateLow,n->aggregateHi); - } else { + } else { fprintf(f," route-filter %s upto /%u;\n", prefix,n->aggregateHi); }; }; @@ -343,59 +389,59 @@ static char* bname=NULL; void bgpq3_print_cprefix(struct sx_radix_node* n, void* ff) -{ +{ char prefix[128]; FILE* f=(FILE*)ff; if(!f) f=stdout; if(n->isGlue) goto checkSon; sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix)); - if(n->isAggregate) { - if(n->aggregateLow>n->prefix.masklen) { + if(n->isAggregate) { + if(n->aggregateLow>n->prefix.masklen) { 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->aggregateLow,n->aggregateHi); - } else { + } else { fprintf(f,"%s prefix-list %s permit %s le %u\n", n->prefix.family==AF_INET?"ip":"ipv6",bname?bname:"NN",prefix, n->aggregateHi); }; - } else { + } else { fprintf(f,"%s prefix-list %s permit %s\n", (n->prefix.family==AF_INET)?"ip":"ipv6",bname?bname:"NN",prefix); }; checkSon: - if(n->son) + if(n->son) bgpq3_print_cprefix(n->son,ff); }; void bgpq3_print_cprefixxr(struct sx_radix_node* n, void* ff) -{ +{ char prefix[128]; FILE* f=(FILE*)ff; if(!f) f=stdout; if(n->isGlue) goto checkSon; sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix)); - if(n->isAggregate) { - if(n->aggregateLow>n->prefix.masklen) { + if(n->isAggregate) { + if(n->aggregateLow>n->prefix.masklen) { fprintf(f,"%s%s ge %u le %u", needscomma?",\n ":" ", prefix, n->aggregateLow,n->aggregateHi); - } else { - fprintf(f,"%s%s le %u", needscomma?",\n ":" ", prefix, + } else { + fprintf(f,"%s%s le %u", needscomma?",\n ":" ", prefix, n->aggregateHi); }; - } else { + } else { fprintf(f,"%s%s", needscomma?",\n ":" ", prefix); }; needscomma=1; checkSon: - if(n->son) + if(n->son) bgpq3_print_cprefixxr(n->son,ff); }; void bgpq3_print_ceacl(struct sx_radix_node* n, void* ff) -{ +{ char prefix[128]; FILE* f=(FILE*)ff; char* c; @@ -406,21 +452,21 @@ bgpq3_print_ceacl(struct sx_radix_node* n, void* ff) c=strchr(prefix,'/'); if(c) *c=0; - if(n->prefix.masklen==32) { + if(n->prefix.masklen==32) { netmask=0; - } else { + } else { netmask<<=(32-n->prefix.masklen); netmask&=0xfffffffful; }; netmask=htonl(netmask); - if(n->isAggregate) { + if(n->isAggregate) { unsigned long mask=0xfffffffful, wildaddr, wild2addr, wildmask; int masklen=n->aggregateLow; wildaddr=0xfffffffful>>n->prefix.masklen; - if(n->aggregateHi==32) { + if(n->aggregateHi==32) { wild2addr=0; - } else { + } else { wild2addr=0xfffffffful>>n->aggregateHi; }; wildaddr=wildaddr&(~wild2addr); @@ -436,31 +482,31 @@ bgpq3_print_ceacl(struct sx_radix_node* n, void* ff) wildaddr=htonl(wildaddr); wildmask=htonl(wildmask); - if(wildaddr) { + if(wildaddr) { fprintf(f," permit ip %s ", inet_ntoa(n->prefix.addr.addr)); fprintf(f,"%s ", inet_ntoa(*(struct in_addr*)&wildaddr)); - } else { + } else { 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\n", inet_ntoa(*(struct in_addr*)&wildmask)); - } else { + } else { fprintf(f,"host %s\n", inet_ntoa(*(struct in_addr*)&mask)); }; - } else { + } else { fprintf(f," permit ip host %s host %s\n",prefix, inet_ntoa(*(struct in_addr*)&netmask)); }; checkSon: - if(n->son) + if(n->son) bgpq3_print_ceacl(n->son,ff); }; int bgpq3_print_juniper_prefixlist(FILE* f, struct bgpq_expander* b) -{ +{ fprintf(f,"policy-options {\nreplace:\n prefix-list %s {\n", b->name?b->name:"NN"); 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 bgpq3_print_juniper_routefilter(FILE* f, struct bgpq_expander* b) -{ +{ char* c=NULL; - if(b->name && (c=strchr(b->name,'/'))) { + if(b->name && (c=strchr(b->name,'/'))) { *c=0; fprintf(f,"policy-options {\n policy-statement %s {\n term %s {\n" "replace:\n from {\n", b->name, c+1); - if(b->match) + if(b->match) fprintf(f," %s;\n",b->match); - } else { + } else { fprintf(f,"policy-options {\n policy-statement %s { \n" "replace:\n from {\n", b->name?b->name:"NN"); - if(b->match) + if(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); - } else { - fprintf(f," route-filter %s/0 orlonger reject;\n", + } else { + fprintf(f," route-filter %s/0 orlonger reject;\n", b->tree->family == AF_INET ? "0.0.0.0" : "::"); }; - if(c) { + if(c) { fprintf(f, " }\n }\n }\n}\n"); - } else { + } else { fprintf(f, " }\n }\n}\n"); }; return 0; @@ -500,15 +546,15 @@ bgpq3_print_juniper_routefilter(FILE* f, struct bgpq_expander* b) int bgpq3_print_cisco_prefixlist(FILE* f, struct bgpq_expander* b) -{ +{ bname=b->name ? b->name : "NN"; fprintf(f,"no %s prefix-list %s\n", (b->family==AF_INET)?"ip":"ipv6",bname); if (!sx_radix_tree_empty(b->tree)) { sx_radix_tree_foreach(b->tree,bgpq3_print_cprefix,f); - } else { + } else { 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); }; return 0; @@ -516,7 +562,7 @@ bgpq3_print_cisco_prefixlist(FILE* f, struct bgpq_expander* b) int bgpq3_print_ciscoxr_prefixlist(FILE* f, struct bgpq_expander* b) -{ +{ bname=b->name ? b->name : "NN"; fprintf(f,"no prefix-set %s\nprefix-set %s\n", bname, bname); 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 bgpq3_print_json_prefixlist(FILE* f, struct bgpq_expander* b) -{ +{ fprintf(f,"{ \"%s\": [", b->name?b->name:"NN"); 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 bgpq3_print_cisco_eacl(FILE* f, struct bgpq_expander* b) -{ +{ bname=b->name ? b->name : "NN"; fprintf(f,"no ip access-list extended %s\n", bname); if (!sx_radix_tree_empty(b->tree)) { fprintf(f,"ip access-list extended %s\n", bname); sx_radix_tree_foreach(b->tree,bgpq3_print_ceacl,f); - } else { + } else { fprintf(f,"! generated access-list %s is empty\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 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_CISCO: return bgpq3_print_cisco_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 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_CISCO: return bgpq3_print_cisco_eacl(f,b); case V_CISCO_XR: sx_report(SX_FATAL, "unreachable point\n"); diff --git a/configure b/configure index 06fc32a..a8aa192 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # 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 . # @@ -579,8 +579,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='bgpq3' PACKAGE_TARNAME='bgpq3' -PACKAGE_VERSION='0.1.24' -PACKAGE_STRING='bgpq3 0.1.24' +PACKAGE_VERSION='0.1.25' +PACKAGE_STRING='bgpq3 0.1.25' PACKAGE_BUGREPORT='snar@snar.spb.ru' 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. # This message is too long to be a string in the A/UX 3.1 sh. 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]... @@ -1248,7 +1248,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of bgpq3 0.1.24:";; + short | recursive ) echo "Configuration of bgpq3 0.1.25:";; esac cat <<\_ACEOF @@ -1327,7 +1327,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -bgpq3 configure 0.1.24 +bgpq3 configure 0.1.25 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1495,7 +1495,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while 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 $ $0 $@ @@ -3413,7 +3413,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. 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 CONFIG_FILES = $CONFIG_FILES @@ -3475,7 +3475,7 @@ _ACEOF cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -bgpq3 config.status 0.1.24 +bgpq3 config.status 0.1.25 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.in b/configure.in index 082d195..ee57921 100644 --- a/configure.in +++ b/configure.in @@ -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_PROG_CC AC_PROG_INSTALL