diff --git a/CHANGES b/CHANGES index 25d5f14..6de9b9e 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,20 @@ +0.1.30 (2015-06-16) + - bugfix: private asns with number > 2^31 were printed as negative integers. + Thanks to Henrik Thostrup Jensen. + - do not use ASNs reserved for documentation purposes and private use: + 64496-64511 For documentation and sample code; reserved by [RFC5398] + 64512-65534 For private use; reserved by [RFC6996] + 65535 Reserved by [RFC7300] + 65536-65551 For documentation and sample code; reserved by [RFC5398] + 4200000000-4294967294 For private use; reserved by [RFC6996] + 4294967295 Reserved by [RFC7300] + Please, use new -p flag to include these asn's. + Suggested by Henrik Thostrup Jensen and Job Snijders. + - allow as-path generation with BIRD output. Suggested by Jiri Mikulas. + - merge README.md changes by Job Snijders. + - bugfix: incorrect asdot representation (as101. without symbols after dot) + is not allowed anymore. + 0.1.29 (2015-05-04) - do not include routes registered for AS23456 (transition-as) by default. Use new option -2 to restore old behaviour. @@ -47,7 +64,7 @@ 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. @@ -61,7 +78,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). diff --git a/README.md b/README.md index 3551ac8..388bb79 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ SYNOPSIS -------- ``` - bgpq3 [-h host] [-S sources] [-EP] [-f asn | -G asn] [-346AbDdJjX] [-r len] [-R len] [-m max] [-W len] OBJECTS [...] + bgpq3 [-h host] [-S sources] [-EP] [-f asn | -G asn] [-2346AbDdJjpX] [-r len] [-R len] [-m max] [-W len] OBJECTS [...] ``` DESCRIPTION @@ -85,6 +85,11 @@ Extra match conditions for Juniper route-filters. See the examples section. `Name` of generated configuration stanza. +#### -p + +Enable use of private ASNs and ASNs used for documentation purpose only +(default: disabled). + #### -P Generate prefix-list (default behaviour, flag added for backward compatibility diff --git a/bgpq3.c b/bgpq3.c index cb589dc..b665ef0 100644 --- a/bgpq3.c +++ b/bgpq3.c @@ -20,6 +20,7 @@ extern int debug_expander; extern int debug_aggregation; extern int pipelining; extern int expand_as23456; +extern int expand_special_asn; int usage(int ecode) @@ -127,7 +128,7 @@ main(int argc, char* argv[]) bgpq_expander_init(&expander,af); expander.sources=getenv("IRRD_SOURCES"); - while((c=getopt(argc,argv,"2346AbdDES:jJf:l:m:M:W:Pr:R:G:Th:X"))!=EOF) { + while((c=getopt(argc,argv,"2346AbdDES:jJf:l:m:M:W:Ppr:R:G:Th:X"))!=EOF) { switch(c) { case '2': expand_as23456=1; @@ -185,6 +186,9 @@ main(int argc, char* argv[]) expander.generation=T_OASPATH; parseasnumber(&expander,optarg); break; + case 'p': + expand_special_asn=1; + break; case 'P': if(expander.generation) exclusive(); expander.generation=T_PREFIXLIST; @@ -268,6 +272,8 @@ main(int argc, char* argv[]) expander.aswidth=4; } else if(expander.vendor==V_JUNIPER) { expander.aswidth=8; + } else if(expander.vendor==V_BIRD) { + expander.aswidth=10; }; } else if(expander.generation==T_OASPATH) { if(expander.vendor==V_CISCO) { @@ -285,9 +291,10 @@ main(int argc, char* argv[]) if(expander.vendor==V_CISCO_XR && expander.generation!=T_PREFIXLIST) { sx_report(SX_FATAL, "Sorry, only prefix-sets supported for IOS XR\n"); }; - if(expander.vendor==V_BIRD && expander.generation!=T_PREFIXLIST) { - sx_report(SX_FATAL, "Sorry, only prefix-lists supported for BIRD " - "output\n"); + if(expander.vendor==V_BIRD && expander.generation!=T_PREFIXLIST && + expander.generation!=T_ASPATH) { + sx_report(SX_FATAL, "Sorry, only prefix-lists and as-paths supported " + "for BIRD output\n"); }; if(expander.vendor==V_JSON && expander.generation!=T_PREFIXLIST && expander.generation!=T_ASPATH) { diff --git a/bgpq3_printer.c b/bgpq3_printer.c index a4b7621..fc46503 100644 --- a/bgpq3_printer.c +++ b/bgpq3_printer.c @@ -15,6 +15,7 @@ #include "sx_report.h" int bgpq3_print_json_aspath(FILE* f, struct bgpq_expander* b); +int bgpq3_print_bird_aspath(FILE* f, struct bgpq_expander* b); int bgpq3_print_cisco_aspath(FILE* f, struct bgpq_expander* b) @@ -25,12 +26,12 @@ bgpq3_print_cisco_aspath(FILE* f, struct bgpq_expander* b) b->asn32s[b->asnumber/65536][(b->asnumber%65536)/8]& (0x80>>(b->asnumber%8))) { 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 ^%u.%u(_%u.%u)*$\n", b->name?b->name:"NN",b->asnumber/65536,b->asnumber%65536, b->asnumber/65536,b->asnumber%65536); empty=0; } else { - fprintf(f,"ip as-path access-list %s permit ^%i(_%i)*$\n", + fprintf(f,"ip as-path access-list %s permit ^%u(_%u)*$\n", b->name?b->name:"NN",b->asnumber,b->asnumber); empty=0; }; @@ -45,21 +46,21 @@ bgpq3_print_cisco_aspath(FILE* f, struct bgpq_expander* b) 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", + " ^%u(_[0-9]+)*_(%u.%u", b->name?b->name:"NN", b->asnumber,k,i*8+j); empty=0; } else { fprintf(f,"ip as-path access-list %s permit" - " ^%i(_[0-9]+)*_(%i", b->name?b->name:"NN", + " ^%u(_[0-9]+)*_(%u", b->name?b->name:"NN", b->asnumber,k*65536+i*8+j); empty=0; }; } else { if(b->asdot && k>0) { - fprintf(f,"|%i.%i",k,i*8+j); + fprintf(f,"|%u.%u",k,i*8+j); empty=0; } else { - fprintf(f,"|%i",k*65536+i*8+j); + fprintf(f,"|%u",k*65536+i*8+j); empty=0; }; } @@ -86,10 +87,10 @@ bgpq3_print_cisco_oaspath(FILE* f, struct bgpq_expander* b) b->asn32s[b->asnumber/65536][(b->asnumber%65536)/8]& (0x80>>(b->asnumber%8))) { 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 ^(_%u.%u)*$\n", b->name?b->name:"NN",b->asnumber/65536,b->asnumber%65536); } else { - fprintf(f,"ip as-path access-list %s permit ^(_%i)*$\n", + fprintf(f,"ip as-path access-list %s permit ^(_%u)*$\n", b->name?b->name:"NN",b->asnumber); }; empty=0; @@ -103,21 +104,21 @@ bgpq3_print_cisco_oaspath(FILE* f, struct bgpq_expander* b) 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]+)*_(%u.%u", b->name?b->name:"NN", k,i*8+j); empty=0; } else { fprintf(f,"ip as-path access-list %s permit" - " ^(_[0-9]+)*_(%i", b->name?b->name:"NN", + " ^(_[0-9]+)*_(%u", b->name?b->name:"NN", k*65536+i*8+j); empty=0; }; } else { if(b->asdot && k>0) { - fprintf(f,"|%i.%i",k,i*8+j); + fprintf(f,"|%u.%u",k,i*8+j); empty=0; } else { - fprintf(f,"|%i",k*65536+i*8+j); + fprintf(f,"|%u",k*65536+i*8+j); empty=0; }; } @@ -146,7 +147,7 @@ bgpq3_print_juniper_aspath(FILE* f, struct bgpq_expander* b) if(b->asn32s[b->asnumber/65536] && b->asn32s[b->asnumber/65535][(b->asnumber%65536)/8]& (0x80>>(b->asnumber%8))) { - fprintf(f," as-path a%i \"^%u(%u)*$\";\n", lineNo, b->asnumber, + fprintf(f," as-path a%u \"^%u(%u)*$\";\n", lineNo, b->asnumber, b->asnumber); lineNo++; }; @@ -157,7 +158,7 @@ bgpq3_print_juniper_aspath(FILE* f, struct bgpq_expander* b) if(b->asn32s[k][i]&(0x80>>j)) { if(k*65536+i*8+j==b->asnumber) continue; if(!nc) { - fprintf(f," as-path a%i \"^%u(.)*(%u", + fprintf(f," as-path a%u \"^%u(.)*(%u", lineNo,b->asnumber,k*65536+i*8+j); } else { fprintf(f,"|%u",k*65536+i*8+j); @@ -189,7 +190,7 @@ bgpq3_print_juniper_oaspath(FILE* f, struct bgpq_expander* b) if(b->asn32s[b->asnumber/65536] && b->asn32s[b->asnumber/65536][(b->asnumber%65536)/8]& (0x80>>(b->asnumber%8))) { - fprintf(f," as-path a%i \"^%u(%u)*$\";\n", lineNo, b->asnumber, + fprintf(f," as-path a%u \"^%u(%u)*$\";\n", lineNo, b->asnumber, b->asnumber); lineNo++; }; @@ -201,7 +202,7 @@ bgpq3_print_juniper_oaspath(FILE* f, struct bgpq_expander* b) if(b->asn32s[k][i]&(0x80>>j)) { if(k*65536+i*8+j==b->asnumber) continue; if(!nc) { - fprintf(f," as-path a%i \"^(.)*(%u", + fprintf(f," as-path a%u \"^(.)*(%u", lineNo,k*65536+i*8+j); } else { fprintf(f,"|%u",k*65536+i*8+j); @@ -232,6 +233,8 @@ bgpq3_print_aspath(FILE* f, struct bgpq_expander* b) return bgpq3_print_cisco_aspath(f,b); } else if(b->vendor==V_JSON) { return bgpq3_print_json_aspath(f,b); + } else if(b->vendor==V_BIRD) { + return bgpq3_print_bird_aspath(f,b); } else { sx_report(SX_FATAL,"Unknown vendor %i\n", b->vendor); }; @@ -306,10 +309,10 @@ bgpq3_print_json_aspath(FILE* f, struct bgpq_expander* b) for(j=0;j<8;j++) { if(b->asn32s[k][i]&(0x80>>j)) { if(!nc) { - fprintf(f,"%s\n %i",needscomma?",":"", k*65536+i*8+j); + fprintf(f,"%s\n %u",needscomma?",":"", k*65536+i*8+j); needscomma=1; } else { - fprintf(f,"%s%i",needscomma?",":"", k*65536+i*8+j); + fprintf(f,"%s%u",needscomma?",":"", k*65536+i*8+j); needscomma=1; } nc++; @@ -350,6 +353,36 @@ checkSon: bgpq3_print_bird_prefix(n->son, ff); }; +int +bgpq3_print_bird_aspath(FILE* f, struct bgpq_expander* b) +{ + int nc=0, i, j, k, empty=1; + 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) { + fprintf(f, "%s%u", empty?"":",\n ", k*65536+i*8+j); + empty = 0; + } else { + fprintf(f, ", %u", k*65536+i*8+j); + }; + nc++; + if(nc==b->aswidth) { + nc=0; + }; + }; + }; + }; + }; + fprintf(f,"];\n"); + return 0; +}; + void bgpq3_print_jrfilter(struct sx_radix_node* n, void* ff) { diff --git a/bgpq_expander.c b/bgpq_expander.c index b88f76a..28e0984 100644 --- a/bgpq_expander.c +++ b/bgpq_expander.c @@ -22,6 +22,7 @@ int debug_expander=0; int pipelining=1; int expand_as23456=0; +int expand_special_asn=0; int bgpq_expander_init(struct bgpq_expander* b, int af) @@ -111,8 +112,12 @@ bgpq_expander_add_as(struct bgpq_expander* b, char* as) if(asno>65535) { asn1=asno%65536; asno/=65536; - } else + } else if(eoa && *(eoa+1)) { asn1=strtoul(eoa+1,&eoa,10); + } else { + sx_report(SX_ERROR, "Invalid AS number: '%s'\n", as); + return 0; + }; if(eoa && *eoa!=0) { sx_report(SX_ERROR,"Invalid symbol in AS number: '%c' in %s\n", @@ -123,6 +128,10 @@ bgpq_expander_add_as(struct bgpq_expander* b, char* as) sx_report(SX_ERROR,"Invalid AS number in %s\n", as); return 0; }; + if(!expand_special_asn && (((asno*65536+asn1)>=4200000000) || + ((asno*65536+asn1)>=64496 && (asno*65536+asn1) <= 65551))) { + return 0; + }; if(!b->asn32s[asno]) { b->asn32s[asno]=malloc(8192); if(!b->asn32s[asno]) { @@ -148,6 +157,9 @@ bgpq_expander_add_as(struct bgpq_expander* b, char* as) if(asno==23456 && !expand_as23456) return 0; + if(!expand_special_asn && (asno>=64496 && asno <= 65536)) + return 0; + b->asn32s[0][asno/8]|=(0x80>>(asno%8)); return 1; diff --git a/configure b/configure index 1deab50..b2fae1f 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.29. +# Generated by GNU Autoconf 2.69 for bgpq3 0.1.30. # # Report bugs to . # @@ -579,8 +579,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='bgpq3' PACKAGE_TARNAME='bgpq3' -PACKAGE_VERSION='0.1.29' -PACKAGE_STRING='bgpq3 0.1.29' +PACKAGE_VERSION='0.1.30' +PACKAGE_STRING='bgpq3 0.1.30' 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.29 to adapt to many kinds of systems. +\`configure' configures bgpq3 0.1.30 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.29:";; + short | recursive ) echo "Configuration of bgpq3 0.1.30:";; 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.29 +bgpq3 configure 0.1.30 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.29, which was +It was created by bgpq3 $as_me 0.1.30, 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.29, which was +This file was extended by bgpq3 $as_me 0.1.30, 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.29 +bgpq3 config.status 0.1.30 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.in b/configure.in index be890d2..ea6e7cb 100644 --- a/configure.in +++ b/configure.in @@ -1,4 +1,4 @@ -AC_INIT(bgpq3,0.1.29,snar@snar.spb.ru) +AC_INIT(bgpq3,0.1.30,snar@snar.spb.ru) AC_CONFIG_HEADER(config.h) AC_PROG_CC AC_PROG_INSTALL