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

515 lines
13 KiB
C
Raw Normal View History

2007-03-22 18:12:32 +00:00
#if HAVE_CONFIG_H
#include <config.h>
#endif
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
2008-06-02 11:32:25 +00:00
#include <string.h>
#include <strings.h>
2007-03-22 18:12:32 +00:00
#include "bgpq3.h"
#include "sx_report.h"
int
bgpq3_print_cisco_aspath(FILE* f, struct bgpq_expander* b)
{
2008-12-25 17:17:05 +00:00
int nc=0, i, j, k;
2007-04-04 13:15:20 +00:00
fprintf(f,"no ip as-path access-list %s\n", b->name?b->name:"NN");
2008-12-25 17:17:05 +00:00
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) {
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);
} else {
fprintf(f,"ip as-path access-list %s permit ^%i(_%i)*$\n",
b->name?b->name:"NN",b->asnumber,b->asnumber);
};
2007-03-22 18:12:32 +00:00
};
2008-12-25 17:17:05 +00:00
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(k*65536+i*8+j==b->asnumber) continue;
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",
b->asnumber,k,i*8+j);
} else {
fprintf(f,"ip as-path access-list %s permit"
" ^%i(_[0-9]+)*_(%i", b->name?b->name:"NN",
b->asnumber,k*65536+i*8+j);
};
} else {
if(b->asdot && k>0) {
fprintf(f,"|%i.%i",k,i*8+j);
} else {
fprintf(f,"|%i",k*65536+i*8+j);
};
}
nc++;
if(nc==b->aswidth) {
fprintf(f,")$\n");
nc=0;
};
2007-03-22 18:12:32 +00:00
};
};
};
};
if(nc) fprintf(f,")$\n");
return 0;
};
2007-04-04 13:15:20 +00:00
int
bgpq3_print_cisco_oaspath(FILE* f, struct bgpq_expander* b)
{
2008-12-25 17:17:05 +00:00
int nc=0, i, j, k;
2007-04-04 13:15:20 +00:00
fprintf(f,"no ip as-path access-list %s\n", b->name?b->name:"NN");
2008-12-25 17:17:05 +00:00
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) {
fprintf(f,"ip as-path access-list %s permit ^(_%i.%i)*$\n",
b->name?b->name:"NN",b->asnumber/65536,b->asnumber%65536);
} else {
fprintf(f,"ip as-path access-list %s permit ^(_%i)*$\n",
b->name?b->name:"NN",b->asnumber);
};
2007-04-04 13:15:20 +00:00
};
2008-12-25 17:17:05 +00:00
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(k*65536+i*8+j==b->asnumber) continue;
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",
k,i*8+j);
} else {
fprintf(f,"ip as-path access-list %s permit"
" ^(_[0-9]+)*_(%i", b->name?b->name:"NN",
k*65536+i*8+j);
};
} else {
if(b->asdot && k>0) {
fprintf(f,"|%i.%i",k,i*8+j);
} else {
fprintf(f,"|%i",k*65536+i*8+j);
};
}
nc++;
if(nc==b->aswidth) {
fprintf(f,")$\n");
nc=0;
};
2007-04-04 13:15:20 +00:00
};
};
};
};
if(nc) fprintf(f,")$\n");
return 0;
};
2007-03-22 18:12:32 +00:00
int
bgpq3_print_juniper_aspath(FILE* f, struct bgpq_expander* b)
{
int nc=0, lineNo=0, i, j, k;
2007-03-22 18:12:32 +00:00
fprintf(f,"policy-options {\nreplace:\n as-path-group %s {\n",
2007-04-04 13:15:20 +00:00
b->name?b->name:"NN");
2007-03-22 18:12:32 +00:00
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,
2007-03-22 18:12:32 +00:00
b->asnumber);
lineNo++;
};
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(k*65536+i*8+j==b->asnumber) continue;
if(!nc) {
fprintf(f," as-path a%i \"^%u(.)*(%u",
lineNo,b->asnumber,k*65536+i*8+j);
} else {
fprintf(f,"|%u",k*65536+i*8+j);
};
nc++;
if(nc==b->aswidth) {
fprintf(f,")$\";\n");
nc=0;
lineNo++;
};
2007-03-22 18:12:32 +00:00
};
};
};
};
if(nc) fprintf(f,")$\";\n");
fprintf(f," }\n}\n");
return 0;
};
2007-04-04 13:15:20 +00:00
int
bgpq3_print_juniper_oaspath(FILE* f, struct bgpq_expander* b)
{
int nc=0, lineNo=0, i, j, k;
2007-04-04 13:15:20 +00:00
fprintf(f,"policy-options {\nreplace:\n as-path-group %s {\n",
b->name?b->name:"NN");
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,
2007-04-04 13:15:20 +00:00
b->asnumber);
lineNo++;
};
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(k*65536+i*8+j==b->asnumber) continue;
if(!nc) {
fprintf(f," as-path a%i \"^(.)*(%u",
lineNo,k*65536+i*8+j);
} else {
fprintf(f,"|%u",k*65536+i*8+j);
}
nc++;
if(nc==b->aswidth) {
fprintf(f,")$\";\n");
nc=0;
lineNo++;
};
2007-04-04 13:15:20 +00:00
};
};
};
};
if(nc) fprintf(f,")$\";\n");
fprintf(f," }\n}\n");
return 0;
};
2007-03-22 18:12:32 +00:00
int
bgpq3_print_aspath(FILE* f, struct bgpq_expander* b)
{
if(b->vendor==V_JUNIPER) {
return bgpq3_print_juniper_aspath(f,b);
} else if(b->vendor==V_CISCO) {
return bgpq3_print_cisco_aspath(f,b);
} else {
sx_report(SX_FATAL,"Unknown vendor %i\n", b->vendor);
};
return 0;
};
2007-04-04 13:15:20 +00:00
int
bgpq3_print_oaspath(FILE* f, struct bgpq_expander* b)
{
if(b->vendor==V_JUNIPER) {
return bgpq3_print_juniper_oaspath(f,b);
} else if(b->vendor==V_CISCO) {
return bgpq3_print_cisco_oaspath(f,b);
} else {
sx_report(SX_FATAL,"Unknown vendor %i\n", b->vendor);
};
return 0;
};
2007-03-22 18:12:32 +00:00
void
bgpq3_print_jprefix(struct sx_radix_node* n, void* ff)
{
char prefix[128];
FILE* f=(FILE*)ff;
if(n->isGlue) return;
2007-03-22 18:12:32 +00:00
if(!f) f=stdout;
sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix));
fprintf(f," %s;\n",prefix);
};
2007-03-22 18:12:32 +00:00
2013-01-08 12:21:14 +00:00
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)
goto checkSon;
if(!f)
f=stdout;
sx_prefix_jsnprintf(&n->prefix, prefix, sizeof(prefix));
if (!n->isAggregate) {
fprintf(f, "%s\n { \"prefix\": \"%s\", \"exact\": true }",
needscomma?",":"", prefix);
} else if (n->aggregateLow > n->prefix.masklen) {
fprintf(f, "%s\n { \"prefix\": \"%s\", \"exact\": false,\n "
"\"greater-equal\": %u, \"less-equal\": %u }",
needscomma?",":"", prefix,
n->aggregateLow, n->aggregateHi);
} else {
fprintf(f, "%s\n { \"prefix\": \"%s\", \"exact\": false, "
"\"less-equal\": %u }",
needscomma?",":"", prefix, n->aggregateHi);
};
needscomma=1;
checkSon:
if(n->son)
bgpq3_print_json_prefix(n->son, ff);
};
2008-06-02 11:32:25 +00:00
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) {
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",
prefix,n->aggregateLow,n->aggregateHi);
} else {
fprintf(f," route-filter %s upto /%u;\n", prefix,n->aggregateHi);
};
};
checkSon:
if(n->son)
bgpq3_print_jrfilter(n->son, ff);
};
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;
2008-05-20 13:12:44 +00:00
if(n->isGlue) goto checkSon;
2007-03-22 18:12:32 +00:00
sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix));
2008-05-20 13:12:44 +00:00
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 {
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 {
fprintf(f,"%s prefix-list %s permit %s\n",
(n->prefix.family==AF_INET)?"ip":"ipv6",bname?bname:"NN",prefix);
};
checkSon:
if(n->son)
bgpq3_print_cprefix(n->son,ff);
2007-03-22 18:12:32 +00:00
};
2011-07-15 11:48:34 +00:00
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) {
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,
n->aggregateHi);
};
} else {
fprintf(f,"%s%s", needscomma?",\n ":" ", prefix);
};
needscomma=1;
checkSon:
if(n->son)
bgpq3_print_cprefixxr(n->son,ff);
};
2008-06-02 11:32:25 +00:00
void
bgpq3_print_ceacl(struct sx_radix_node* n, void* ff)
{
char prefix[128];
FILE* f=(FILE*)ff;
char* c;
uint32_t netmask=0xfffffffful;
if(!f) f=stdout;
if(n->isGlue) goto checkSon;
sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix));
c=strchr(prefix,'/');
if(c) *c=0;
if(n->prefix.masklen==32) {
netmask=0;
} else {
netmask<<=(32-n->prefix.masklen);
2008-08-08 09:29:53 +00:00
netmask&=0xfffffffful;
2008-06-02 11:32:25 +00:00
};
netmask=htonl(netmask);
if(n->isAggregate) {
unsigned long mask=0xfffffffful, wildaddr, wild2addr, wildmask;
int masklen=n->aggregateLow;
wildaddr=0xfffffffful>>n->prefix.masklen;
if(n->aggregateHi==32) {
wild2addr=0;
} else {
wild2addr=0xfffffffful>>n->aggregateHi;
};
wildaddr=wildaddr&(~wild2addr);
if(masklen==32) mask=0xfffffffful;
2008-08-08 09:29:53 +00:00
else mask=0xfffffffful & (0xfffffffful<<(32-masklen));
2008-06-02 11:32:25 +00:00
if(n->aggregateHi==32) wild2addr=0;
else wild2addr=0xfffffffful>>n->aggregateHi;
wildmask=(0xfffffffful>>n->aggregateLow)&(~wild2addr);
mask=htonl(mask);
wildaddr=htonl(wildaddr);
wildmask=htonl(wildmask);
if(wildaddr) {
fprintf(f," permit ip %s ", inet_ntoa(n->prefix.addr.addr));
fprintf(f,"%s ", inet_ntoa(*(struct in_addr*)&wildaddr));
} else {
fprintf(f," permit ip host %s ",inet_ntoa(n->prefix.addr.addr));
};
if(wildmask) {
fprintf(f,"%s ", inet_ntoa(*(struct in_addr*)&mask));
fprintf(f,"%s\n", inet_ntoa(*(struct in_addr*)&wildmask));
} else {
fprintf(f,"host %s\n", inet_ntoa(*(struct in_addr*)&mask));
};
} else {
fprintf(f," permit ip host %s host %s\n",prefix,
inet_ntoa(*(struct in_addr*)&netmask));
};
checkSon:
if(n->son)
bgpq3_print_ceacl(n->son,ff);
};
2007-03-22 18:12:32 +00:00
int
bgpq3_print_juniper_prefixlist(FILE* f, struct bgpq_expander* b)
{
fprintf(f,"policy-options {\nreplace:\n prefix-list %s {\n",
2007-04-04 13:15:20 +00:00
b->name?b->name:"NN");
sx_radix_tree_foreach(b->tree,bgpq3_print_jprefix,f);
fprintf(f," }\n}\n");
return 0;
};
2008-06-02 11:32:25 +00:00
int
bgpq3_print_juniper_routefilter(FILE* f, struct bgpq_expander* b)
{
char* c;
if(b->name && (c=strchr(b->name,'/'))) {
*c=0;
fprintf(f,"policy-options {\n policy-statement %s {\n term %s {\n"
2008-08-08 09:29:53 +00:00
"replace:\n from {\n", b->name, c+1);
if(b->match)
fprintf(f," %s;\n",b->match);
2008-06-02 11:32:25 +00:00
} else {
fprintf(f,"policy-options {\n policy-statement %s { \n"
2008-08-08 09:29:53 +00:00
"replace:\n from {\n", b->name?b->name:"NN");
if(b->match)
fprintf(f," %s;\n",b->match);
2008-06-02 11:32:25 +00:00
};
sx_radix_tree_foreach(b->tree,bgpq3_print_jrfilter,f);
if(c) {
fprintf(f, " }\n }\n }\n}\n");
} else {
fprintf(f, " }\n }\n}\n");
};
return 0;
};
int
bgpq3_print_cisco_prefixlist(FILE* f, struct bgpq_expander* b)
{
bname=b->name;
2007-04-04 13:30:58 +00:00
fprintf(f,"no %s prefix-list %s\n",
(b->family==AF_INET)?"ip":"ipv6",bname?bname:"NN");
sx_radix_tree_foreach(b->tree,bgpq3_print_cprefix,f);
2007-03-22 18:12:32 +00:00
return 0;
};
2011-07-15 11:48:34 +00:00
int
bgpq3_print_ciscoxr_prefixlist(FILE* f, struct bgpq_expander* b)
{
bname=b->name;
fprintf(f,"no prefix-set %s\nprefix-set %s\n", bname?bname:"NN",
bname?bname:"NN");
2011-07-15 11:48:34 +00:00
sx_radix_tree_foreach(b->tree,bgpq3_print_cprefixxr,f);
fprintf(f, "\nend-set\n");
return 0;
};
2013-01-08 12:21:14 +00:00
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);
fprintf(f,"\n] }\n");
return 0;
};
2008-06-02 11:32:25 +00:00
int
bgpq3_print_cisco_eacl(FILE* f, struct bgpq_expander* b)
{
bname=b->name;
fprintf(f,"no ip access-list extended %s\n", bname?bname:"NN");
fprintf(f,"ip access-list extended %s\n", bname?bname:"NN");
sx_radix_tree_foreach(b->tree,bgpq3_print_ceacl,f);
return 0;
};
2007-03-22 18:12:32 +00:00
int
bgpq3_print_prefixlist(FILE* f, struct bgpq_expander* b)
{
switch(b->vendor) {
case V_JUNIPER: return bgpq3_print_juniper_prefixlist(f,b);
case V_CISCO: return bgpq3_print_cisco_prefixlist(f,b);
2011-07-15 11:48:34 +00:00
case V_CISCO_XR: return bgpq3_print_ciscoxr_prefixlist(f,b);
2013-01-08 12:21:14 +00:00
case V_JSON: return bgpq3_print_json_prefixlist(f,b);
2007-03-22 18:12:32 +00:00
};
return 0;
};
2008-06-02 11:32:25 +00:00
int
bgpq3_print_eacl(FILE* f, struct bgpq_expander* b)
{
switch(b->vendor) {
case V_JUNIPER: return bgpq3_print_juniper_routefilter(f,b);
case V_CISCO: return bgpq3_print_cisco_eacl(f,b);
2011-07-15 11:48:34 +00:00
case V_CISCO_XR: sx_report(SX_FATAL, "unreachable point\n");
2013-01-08 12:21:14 +00:00
case V_JSON: sx_report(SX_FATAL, "unreachable point\n");
2008-06-02 11:32:25 +00:00
};
return 0;
};