From e3974c5469047348b0c3189d3fe8d38262ff2614 Mon Sep 17 00:00:00 2001 From: Job Snijders Date: Mon, 30 Dec 2019 12:45:49 +0000 Subject: [PATCH 1/2] Remove P command line option --- README.md | 25 ++++++++++--------------- bgpq4.c | 28 ++++++++++------------------ 2 files changed, 20 insertions(+), 33 deletions(-) diff --git a/README.md b/README.md index fc96112..11260b4 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ SYNOPSIS -------- ``` - bgpq4 [-h host[:port]] [-S sources] [-EPz] [-f asn | -F fmt | -G asn | -t] [-2346ABbDdJjNnpsUX] [-a asn] [-r len] [-R len] [-m max] [-W len] OBJECTS [...] EXCEPT OBJECTS + bgpq4 [-h host[:port]] [-S sources] [-Ez] [-f asn | -F fmt | -G asn | -t] [-2346ABbDdJjNnpsUX] [-a asn] [-r len] [-R len] [-m max] [-W len] OBJECTS [...] EXCEPT OBJECTS ``` DESCRIPTION @@ -46,11 +46,11 @@ Specify ASN that shall be denied in case of empty prefix-list (OpenBGPD). #### -B -Generate output in OpenBGPD format (default: Cisco). +Generate output in OpenBGPD format. #### -b -Generate output in BIRD format (default: Cisco). +Generate output in BIRD format. #### -d @@ -80,15 +80,15 @@ Host running IRRD database (default: `rr.ntt.net`). #### -J -Generate config for Juniper (default: Cisco). +Generate config for Juniper. #### -j -Generate output in JSON format (default: Cisco). +Generate output in JSON format. #### -K -Generate config for MikroTik (default: Cisco). +Generate config for MikroTik. #### -m `length` @@ -100,11 +100,11 @@ Extra match conditions for Juniper route-filters. See the examples section. #### -n -Generate config for Nokia SR OS (former Alcatel-Lucent) MD-CLI (default: Cisco) +Generate config for Nokia SR OS (former Alcatel-Lucent) MD-CLI. #### -N -Generate config for Nokia SR OS (former Alcatel-Lucent) classic CLI (default: Cisco) +Generate config for Nokia SR OS (former Alcatel-Lucent) classic CLI. #### -l `name` @@ -120,11 +120,6 @@ is a useful feature to prevent generated filters from growing too big. 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 -only). - #### -r `length` Allow more-specific routes with masklen starting with specified length. @@ -152,7 +147,7 @@ Disable pipelining. (not recommended) #### -U -Generate output in Huawei format (default: Cisco). +Generate output in Huawei format. #### -W `length` @@ -160,7 +155,7 @@ Generate as-path strings of a given length maximum (0 for infinity). #### -X -Generate config for Cisco IOS XR devices (plain IOS by default). +Generate output in Cisco IOS XR format. #### -z diff --git a/bgpq4.c b/bgpq4.c index 42cf00e..10cd785 100644 --- a/bgpq4.c +++ b/bgpq4.c @@ -27,13 +27,13 @@ extern int expand_special_asn; int usage(int ecode) { - printf("\nUsage: bgpq4 [-h host[:port]] [-S sources] [-P|E|G |f |t]" - " [-2346ABbdJjKNnwXz] [-R len] ...\n"); + printf("\nUsage: bgpq4 [-h host[:port]] [-S sources] [-E|G " + "|f |t] [-2346ABbdJjKNnwXz] [-R len] ...\n"); printf(" -2 : allow routes belonging to as23456 (transition-as) " "(default: false)\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(" -6 : generate IPv6 prefix-lists\n"); printf(" -A : try to aggregate prefix-lists/route-filters\n"); printf(" -B : generate OpenBGPD output (Cisco IOS by default)\n"); printf(" -b : generate BIRD output (Cisco IOS by default)\n"); @@ -57,12 +57,8 @@ usage(int ecode) printf(" -L depth : limit recursion depth (default: unlimited)\n"), printf(" -l name : use specified name for generated access/prefix/.." " list\n"); - printf(" -N : generate config for Nokia SR OS classic CLI " - "(Cisco IOS by default)\n"); - printf(" -n : generate config for Nokia SR OS MD-CLI (Cisco IOS " - "by default)\n"); - printf(" -P : generate prefix-list (default, just for backward" - " compatibility)\n"); + printf(" -N : generate config for Nokia SR OS classic CLI\n"); + printf(" -n : generate config for Nokia SR OS MD-CLI\n"); printf(" -R len : allow more specific routes up to specified masklen\n"); printf(" -r len : allow more specific routes from masklen specified\n"); printf(" -S sources: use only specified sources (recommended:" @@ -71,12 +67,12 @@ usage(int ecode) printf(" -T : disable pipelining (experimental, faster mode)\n"); printf(" -t : generate as-sets for OpenBGPD (OpenBSD 6.4+), BIRD " "and JSON formats\n"); - printf(" -U : generate config for Huawei (Cisco IOS by default)\n"); + printf(" -U : generate config for Huawei\n"); printf(" -W len : specify max-entries on as-path line (use 0 for " "infinity)\n"); printf(" -w : 'validate' AS numbers: accept only ones with " "registered routes\n"); - printf(" -X : generate config for IOS XR (Cisco IOS by default)\n"); + printf(" -X : generate Cisco IOS XR output\n"); printf("\n" PACKAGE_NAME " version: " PACKAGE_VERSION "\n"); exit(ecode); }; @@ -84,8 +80,8 @@ usage(int ecode) void exclusive() { - fprintf(stderr,"-E, -f , -G , -P and -t are mutually " - "exclusive\n"); + fprintf(stderr,"-E, -f , -G , and -t are mutually " + "exclusive\n"); exit(1); }; @@ -146,7 +142,7 @@ main(int argc, char* argv[]) if (getenv("IRRD_SOURCES")) expander.sources=getenv("IRRD_SOURCES"); - while((c=getopt(argc,argv,"2346a:AbBdDEF:S:jJKf:l:L:m:M:NnW:Ppr:R:G:tTh:UwXsz")) + while((c=getopt(argc,argv,"2346a:AbBdDEF:S:jJKf:l:L:m:M:NnW:pr:R:G:tTh:UwXsz")) !=EOF) { switch(c) { case '2': @@ -228,10 +224,6 @@ main(int argc, char* argv[]) case 'p': expand_special_asn=1; break; - case 'P': - if(expander.generation) exclusive(); - expander.generation=T_PREFIXLIST; - break; case 'r': refineLow=strtoul(optarg,NULL,10); if(!refineLow) { From 7d6c4421de9f4b6b585da0350ac25d9a412af088 Mon Sep 17 00:00:00 2001 From: Job Snijders Date: Mon, 30 Dec 2019 05:12:11 +0000 Subject: [PATCH 2/2] Apply OpenBSD's style(9) code formatting --- bgpq4.c | 620 ++++++++------- bgpq4_printer.c | 1826 +++++++++++++++++++++++++++----------------- bgpq_expander.c | 748 ++++++++++-------- expander_freeall.c | 129 ++-- strlcpy.c | 4 +- sx_maxsockbuf.c | 90 ++- sx_prefix.c | 1327 ++++++++++++++++++-------------- sx_report.c | 75 +- sx_slentry.c | 17 +- 9 files changed, 2828 insertions(+), 2008 deletions(-) diff --git a/bgpq4.c b/bgpq4.c index 10cd785..66071ee 100644 --- a/bgpq4.c +++ b/bgpq4.c @@ -27,7 +27,7 @@ extern int expand_special_asn; int usage(int ecode) { - printf("\nUsage: bgpq4 [-h host[:port]] [-S sources] [-E|G " + printf("\nUsage: bgpq4 [-h host[:port]] [-S sources] [-P|E|G " "|f |t] [-2346ABbdJjKNnwXz] [-R len] ...\n"); printf(" -2 : allow routes belonging to as23456 (transition-as) " "(default: false)\n"); @@ -35,22 +35,22 @@ usage(int ecode) printf(" -4 : generate IPv4 prefix-lists (default)\n"); printf(" -6 : generate IPv6 prefix-lists\n"); printf(" -A : try to aggregate prefix-lists/route-filters\n"); - printf(" -B : generate OpenBGPD output (Cisco IOS by default)\n"); - printf(" -b : generate BIRD output (Cisco IOS by default)\n"); + printf(" -B : generate OpenBGPD output\n"); + printf(" -b : generate BIRD output\n"); printf(" -d : generate some debugging output\n"); printf(" -E : generate extended access-list(Cisco), " - "route-filter(Juniper)\n" - " [ip|ipv6]-prefix-list (Nokia) or prefix-set (OpenBGPD)" - "\n"); + "route-filter(Juniper)\n" + " [ip|ipv6]-prefix-list (Nokia) or prefix-set " + "(OpenBGPD)\n"); printf(" -F fmt : generate output in user-defined format\n"); printf(" -f number : generate input as-path access-list\n"); printf(" -G number : generate output as-path access-list\n"); printf(" -h host : host running IRRD software (rr.ntt.net by " "default)\n" " (use host:port to specify alternate port)\n"); - printf(" -J : generate config for JunOS (Cisco IOS by default)\n"); - printf(" -j : generate JSON output (Cisco IOS by default)\n"); - printf(" -K : generate config for MikroTik RouterOS (Cisco IOS by default)\n"); + printf(" -J : generate config for JunOS\n"); + printf(" -j : generate JSON output\n"); + printf(" -K : generate config for MikroTik RouterOS\n"); printf(" -M match : extra match conditions for JunOS route-filters\n"); printf(" -m len : maximum prefix length (default: 32 for IPv4, " "128 for IPv6)\n"); @@ -88,9 +88,9 @@ exclusive() void vendor_exclusive() { - fprintf(stderr, "-b (BIRD), -B (OpenBGPD), -F (formatted), -J (JunOS), " - "-j (JSON), -N (Nokia SR OS classic), -n (Nokia SR OS MD-CLI), " - "-U (Huawei) and -X (IOS XR) options are mutually exclusive\n"); + fprintf(stderr, "-b (BIRD), -B (OpenBGPD), -F (formatted), -J (Junos)," + " -j (JSON), -N (Nokia SR OS Classic), -n (Nokia SR OS MD-CLI)," + " -U (Huawei) and -X (IOS XR) options are mutually exclusive\n"); exit(1); }; @@ -98,30 +98,30 @@ 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)) { + expander->asnumber=strtoul(optarg,&eon, 10); + 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) { + uint32_t loas = strtoul(eon+1, &eon, 10); + 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) { - sx_report(SX_FATAL,"Invalid symbol in AS number: %c (%s)\n", - *eon, optarg); + 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) { + expander->asnumber=(expander->asnumber << 16) + loas; + } else if (eon && *eon) { sx_report(SX_FATAL,"Invalid symbol in AS number: %c (%s)\n", *eon, optarg); exit(1); @@ -134,286 +134,333 @@ main(int argc, char* argv[]) { int c; struct bgpq_expander expander; - int af=AF_INET, selectedipv4 = 0, exceptmode = 0; - int widthSet=0, aggregate=0, refine=0, refineLow=0; - unsigned long maxlen=0; + int af = AF_INET, selectedipv4 = 0, exceptmode = 0; + int widthSet = 0, aggregate = 0, refine = 0, refineLow = 0; + unsigned long maxlen = 0; - bgpq_expander_init(&expander,af); + bgpq_expander_init(&expander, af); if (getenv("IRRD_SOURCES")) expander.sources=getenv("IRRD_SOURCES"); - while((c=getopt(argc,argv,"2346a:AbBdDEF:S:jJKf:l:L:m:M:NnW:pr:R:G:tTh:UwXsz")) - !=EOF) { - switch(c) { + while ((c = getopt(argc,argv,"2346a:AbBdDEF:S:jJKf:l:L:m:M:NnW:pr:R:G:tTh:UwXsz")) + !=EOF) { + switch (c) { case '2': - expand_as23456=1; + expand_as23456 = 1; break; case '3': - expander.asn32=1; + expander.asn32 = 1; break; 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"); + sx_report(SX_FATAL, "-4 and -6 are mutually " + "exclusive\n"); exit(1); }; selectedipv4=1; break; case '6': 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); }; - af=AF_INET6; - expander.family=AF_INET6; - expander.tree->family=AF_INET6; + af = AF_INET6; + expander.family = AF_INET6; + expander.tree->family = AF_INET6; break; case 'a': - parseasnumber(&expander,optarg); + parseasnumber(&expander, optarg); break; case 'A': - if(aggregate) debug_aggregation++; - aggregate=1; + if (aggregate) + debug_aggregation++; + aggregate = 1; break; case 'b': - if(expander.vendor) vendor_exclusive(); - expander.vendor=V_BIRD; + if (expander.vendor) + vendor_exclusive(); + expander.vendor = V_BIRD; break; case 'B': - if(expander.vendor) vendor_exclusive(); - expander.vendor=V_OPENBGPD; - expander.asn32=1; + if (expander.vendor) + vendor_exclusive(); + expander.vendor = V_OPENBGPD; + expander.asn32 = 1; break; - case 'd': debug_expander++; + case 'd': + debug_expander++; break; - case 'E': if(expander.generation) exclusive(); - expander.generation=T_EACL; + case 'E': + if (expander.generation) + exclusive(); + expander.generation = T_EACL; break; - case 'F': if(expander.vendor) exclusive(); - expander.vendor=V_FORMAT; - expander.format=optarg; + case 'F': + if (expander.vendor) + exclusive(); + expander.vendor = V_FORMAT; + expander.format = optarg; break; case 'f': - if(expander.generation) exclusive(); - expander.generation=T_ASPATH; - parseasnumber(&expander,optarg); + if (expander.generation) + exclusive(); + expander.generation = T_ASPATH; + parseasnumber(&expander, optarg); break; case 'G': - if(expander.generation) exclusive(); - expander.generation=T_OASPATH; - parseasnumber(&expander,optarg); + if (expander.generation) + exclusive(); + expander.generation = T_OASPATH; + parseasnumber(&expander, optarg); break; - case 'h': { - char* d=strchr(optarg, ':'); - expander.server=optarg; - if(d) { - *d=0; - expander.port=d+1; + case 'h': + { + char* d = strchr(optarg, ':'); + expander.server = optarg; + if (d) { + *d = 0; + expander.port = d + 1; + }; }; break; - }; - case 'J': if(expander.vendor) vendor_exclusive(); - expander.vendor=V_JUNIPER; + case 'J': + if (expander.vendor) + vendor_exclusive(); + expander.vendor = V_JUNIPER; break; - case 'j': if(expander.vendor) vendor_exclusive(); - expander.vendor=V_JSON; + case 'j': + if (expander.vendor) + vendor_exclusive(); + expander.vendor = V_JSON; break; - case 'K': if(expander.vendor) vendor_exclusive(); - expander.vendor=V_MIKROTIK; + case 'K': + if (expander.vendor) + vendor_exclusive(); + expander.vendor = V_MIKROTIK; break; case 'p': - expand_special_asn=1; + expand_special_asn = 1; break; case 'r': - refineLow=strtoul(optarg,NULL,10); - if(!refineLow) { - sx_report(SX_FATAL,"Invalid refineLow value: %s\n", optarg); + refineLow = strtoul(optarg, NULL, 10); + if (!refineLow) { + sx_report(SX_FATAL, "Invalid refineLow value:" + " %s\n", optarg); exit(1); }; break; case 'R': - refine=strtoul(optarg,NULL,10); - if(!refine) { - sx_report(SX_FATAL,"Invalid refine length: %s\n", optarg); + refine = strtoul(optarg, NULL, 10); + if (!refine) { + sx_report(SX_FATAL,"Invalid refine length:" + " %s\n", optarg); exit(1); }; break; - case 'l': expander.name=optarg; + case 'l': + expander.name = optarg; break; - case 'L': expander.maxdepth=strtol(optarg, NULL, 10); + case 'L': + expander.maxdepth = strtol(optarg, NULL, 10); if (expander.maxdepth < 1) { - sx_report(SX_FATAL, "Invalid maximum recursion (-L): %s\n", - optarg); + sx_report(SX_FATAL, "Invalid maximum recursion" + " (-L): %s\n", optarg); exit(1); }; break; - case 'm': maxlen=strtoul(optarg, NULL, 10); + case 'm': + maxlen=strtoul(optarg, NULL, 10); if (!maxlen) { - sx_report(SX_FATAL, "Invalid maxlen (-m): %s\n", optarg); + 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') { - *d='\n'; + expander.match = strdup(optarg); + c = d = expander.match; + while (*c) { + if (*c == '\\') { + if (*(c+1) == '\n') { + *d = '\n'; d++; - c+=2; - } else if(*(c+1)=='r') { - *d='\r'; + c += 2; + } else if (*(c + 1) == 'r') { + *d = '\r'; d++; - c+=2; - } else if(*(c+1)=='t') { - *d='\t'; + c += 2; + } else if (*(c + 1) == 't') { + *d = '\t'; d++; - c+=2; - } else if(*(c+1)=='\\') { - *d='\\'; + c += 2; + } else if (*(c + 1) == '\\') { + *d = '\\'; d++; - c+=2; + c += 2; } else { - sx_report(SX_FATAL, "Unsupported escape \%c (0x%2.2x) " - "in '%s'\n", isprint(*c)?*c:20, *c, optarg); + sx_report(SX_FATAL, "Unsupported" + " escape \%c (0x%2.2x) in " + "'%s'\n", + isprint(*c) ? *c : 20, + *c, optarg); exit(1); }; } else { - if(c!=d) { - *d=*c; + if (c != d) { + *d = *c; }; d++; c++; }; }; - *d=0; + *d = 0; }; break; - case 'N': if(expander.vendor) vendor_exclusive(); - expander.vendor=V_NOKIA; + case 'N': + if (expander.vendor) + vendor_exclusive(); + expander.vendor = V_NOKIA; break; - case 'n': if(expander.vendor) vendor_exclusive(); - expander.vendor=V_NOKIA_MD; + case 'n': + if (expander.vendor) + vendor_exclusive(); + expander.vendor = V_NOKIA_MD; break; case 't': - if(expander.generation) exclusive(); - expander.generation=T_ASSET; + if (expander.generation) + exclusive(); + expander.generation = T_ASSET; break; - case 'T': pipelining=0; + case 'T': + pipelining = 0; break; - case 's': expander.sequence=1; + case 's': + expander.sequence = 1; break; - case 'S': expander.sources=optarg; + case 'S': + expander.sources = optarg; break; case 'U': - if(expander.vendor) exclusive(); - expander.vendor=V_HUAWEI; + if (expander.vendor) + exclusive(); + expander.vendor = V_HUAWEI; break; - case 'W': expander.aswidth=atoi(optarg); - if(expander.aswidth<0) { - sx_report(SX_FATAL,"Invalid as-width: %s\n", optarg); + case 'W': + expander.aswidth = atoi(optarg); + if (expander.aswidth < 0) { + sx_report(SX_FATAL,"Invalid as-width: %s\n", + optarg); exit(1); }; - widthSet=1; + widthSet = 1; break; - case 'w': expander.validate_asns=1; + case 'w': + expander.validate_asns = 1; break; - case 'X': if(expander.vendor) vendor_exclusive(); - expander.vendor=V_CISCO_XR; + case 'X': + if (expander.vendor) + vendor_exclusive(); + expander.vendor = V_CISCO_XR; break; case 'z': - if(expander.generation) exclusive(); - expander.generation=T_ROUTE_FILTER_LIST; + if (expander.generation) + exclusive(); + expander.generation = T_ROUTE_FILTER_LIST; break; - default : usage(1); + default: + usage(1); }; }; - argc-=optind; - argv+=optind; + argc -= optind; + argv += optind; - if(!widthSet) { - if(expander.generation==T_ASPATH) { - if(expander.vendor==V_CISCO) { - expander.aswidth=4; - } else if(expander.vendor==V_CISCO_XR) { - expander.aswidth=6; - } else if(expander.vendor==V_JUNIPER) { - expander.aswidth=8; - } else if(expander.vendor==V_MIKROTIK) { - expander.aswidth=4; - } else if(expander.vendor==V_BIRD) { - expander.aswidth=10; - } else if(expander.vendor==V_NOKIA || expander.vendor==V_NOKIA_MD) { - expander.aswidth=8; + if (!widthSet) { + if (expander.generation==T_ASPATH) { + if (expander.vendor == V_CISCO) { + expander.aswidth = 4; + } else if (expander.vendor == V_CISCO_XR) { + expander.aswidth = 6; + } else if (expander.vendor == V_JUNIPER) { + expander.aswidth = 8; + } else if (expander.vendor == V_MIKROTIK) { + expander.aswidth = 4; + } else if (expander.vendor == V_BIRD) { + expander.aswidth = 10; + } else if (expander.vendor == V_NOKIA || + expander.vendor == V_NOKIA_MD) { + expander.aswidth = 8; }; - } else if(expander.generation==T_OASPATH) { - if(expander.vendor==V_CISCO) { - expander.aswidth=5; - } else if(expander.vendor==V_CISCO_XR) { - expander.aswidth=7; - } else if(expander.vendor==V_JUNIPER) { - expander.aswidth=8; - } else if(expander.vendor==V_NOKIA || expander.vendor==V_NOKIA_MD) { - expander.aswidth=8; + } else if (expander.generation == T_OASPATH) { + if (expander.vendor == V_CISCO) { + expander.aswidth = 5; + } else if (expander.vendor == V_CISCO_XR) { + expander.aswidth = 7; + } else if (expander.vendor==V_JUNIPER) { + expander.aswidth = 8; + } else if (expander.vendor == V_NOKIA || + expander.vendor == V_NOKIA_MD) { + expander.aswidth = 8; }; }; }; - if(!expander.generation) { - expander.generation=T_PREFIXLIST; + if (!expander.generation) { + expander.generation = T_PREFIXLIST; }; - if(expander.vendor==V_CISCO_XR && expander.generation!=T_PREFIXLIST && - expander.generation!=T_ASPATH && expander.generation!=T_OASPATH) { + if (expander.generation != (T_PREFIXLIST & T_ASPATH & T_OASPATH) && + expander.vendor == V_CISCO_XR) { sx_report(SX_FATAL, "Sorry, only prefix-sets and as-paths " "supported for IOS XR\n"); }; - if(expander.vendor==V_BIRD && expander.generation!=T_PREFIXLIST && - expander.generation!=T_ASPATH && expander.generation!=T_ASSET) { + if (expander.vendor == V_BIRD && expander.generation != T_PREFIXLIST && + expander.generation != T_ASPATH && expander.generation != T_ASSET) { sx_report(SX_FATAL, "Sorry, only prefix-lists and as-paths/as-sets " - "supported for BIRD output\n"); + "supported for BIRD output\n"); }; - if(expander.vendor==V_JSON && expander.generation!=T_PREFIXLIST && - expander.generation!=T_ASPATH && expander.generation!=T_ASSET) { + if (expander.vendor == V_JSON && expander.generation != T_PREFIXLIST && + expander.generation != T_ASPATH && expander.generation != T_ASSET) { sx_report(SX_FATAL, "Sorry, only prefix-lists and as-paths/as-sets " - "supported for JSON output\n"); + "supported for JSON output\n"); }; - if(expander.vendor==V_FORMAT && expander.generation!=T_PREFIXLIST) + + if (expander.vendor == V_FORMAT && expander.generation != T_PREFIXLIST) sx_report(SX_FATAL, "Sorry, only prefix-lists supported in formatted " - "output\n"); - if(expander.vendor==V_FORMAT && (refine || refineLow)) { + "output\n"); + + if (expander.vendor == V_FORMAT && (refine || refineLow)) { sx_report(SX_FATAL, "Sorry, formatted output (-F ) in not " - "compatible with -R/-r options\n"); + "compatible with -R/-r options\n"); exit(1); }; - if(expander.vendor==V_HUAWEI && expander.generation!=T_ASPATH && - expander.generation!=T_OASPATH && expander.generation != T_PREFIXLIST) + + if (expander.vendor == V_HUAWEI && expander.generation != T_ASPATH && + expander.generation != T_OASPATH && expander.generation != T_PREFIXLIST) sx_report(SX_FATAL, "Sorry, only as-paths and prefix-lists supported " - "for Huawei output\n"); + "for Huawei output\n"); - if(expander.generation==T_ROUTE_FILTER_LIST && expander.vendor!=V_JUNIPER) { + if (expander.generation == T_ROUTE_FILTER_LIST && expander.vendor != V_JUNIPER) sx_report(SX_FATAL, "Route-filter-lists (-z) supported for Juniper (-J)" - " output only\n"); - }; - if(expander.generation==T_ASSET && expander.vendor!=V_JSON && - expander.vendor!=V_OPENBGPD && expander.vendor!=V_BIRD) { + " output only\n"); + + if (expander.generation == T_ASSET && expander.vendor != V_JSON && + expander.vendor != V_OPENBGPD && expander.vendor != V_BIRD) sx_report(SX_FATAL, "As-Sets (-t) supported for JSON (-j), OpenBGPD " - "(-B) and BIRD (-b) output only\n"); - }; + "(-B) and BIRD (-b) output only\n"); - if(!expander.asn32 && expander.asnumber>65535) { - expander.asnumber=23456; - }; + 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) " - "or route-filter-lists (-z) instead of prefix-lists " - "(-P, default)\n"); + " Juniper prefix-lists\nYou can try route-filters (-E) " + "or route-filter-lists (-z) instead of prefix-lists " + "(-P, default)\n"); exit(1); }; @@ -423,48 +470,50 @@ main(int argc, char* argv[]) exit(1); }; - if(aggregate && (expander.vendor==V_NOKIA_MD || expander.vendor==V_NOKIA) && - expander.generation!=T_PREFIXLIST) { + if (aggregate && (expander.vendor == V_NOKIA_MD || expander.vendor == V_NOKIA) && + expander.generation != T_PREFIXLIST) { sx_report(SX_FATAL, "Sorry, aggregation (-A) is not supported with " - "ip-prefix-lists (-E) on Nokia. You can try prefix-lists (-P) " - "instead\n"); + "ip-prefix-lists (-E) on Nokia. You can try prefix-lists (-P) " + "instead\n"); exit(1); }; - if(refine && (expander.vendor==V_NOKIA_MD || expander.vendor==V_NOKIA) && - expander.generation!=T_PREFIXLIST) { + + if (refine && (expander.vendor == V_NOKIA_MD || expander.vendor == V_NOKIA) && + expander.generation != T_PREFIXLIST) { sx_report(SX_FATAL, "Sorry, more-specifics (-R) is not supported with " - "ip-prefix-lists (-E) on Nokia. You can try prefix-lists (-P) " - "instead\n"); + "ip-prefix-lists (-E) on Nokia. You can try prefix-lists (-P) " + "instead\n"); exit(1); }; - if(refineLow && (expander.vendor==V_NOKIA_MD || expander.vendor==V_NOKIA) && - expander.generation!=T_PREFIXLIST) { + + if (refineLow && (expander.vendor == V_NOKIA_MD || expander.vendor == V_NOKIA) && + expander.generation != T_PREFIXLIST) { sx_report(SX_FATAL, "Sorry, more-specifics (-r) is not supported with " - "ip-prefix-lists (-E) on Nokia. You can try prefix-lists (-P) " - "instead\n"); + "ip-prefix-lists (-E) on Nokia. You can try prefix-lists (-P) " + "instead\n"); exit(1); }; - if(aggregate && expander.generation refine) { sx_report(SX_FATAL, "Incompatible values for -r %u and -R %u\n", - refineLow, refine); + 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) { + " IPv6)\n", refine); + } 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) { + " IPv6)\n", refineLow); + } 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) { + " IPv4)\n", refine); + } else if (expander.family == AF_INET && refineLow > 32) { 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(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) or route-filter-lists (-z) " - "instead\n", refine); + "is not supported for Juniper prefix-lists.\n" + "Use router-filters (-E) or route-filter-lists (-z) " + "instead\n", refine); } else { sx_report(SX_FATAL, "Sorry, more-specific filters (-r %u) " - "is not supported for Juniper prefix-lists.\n" - "Use route-filters (-E) or route-filter-lists (-z) " - "instead\n", refineLow); + "is not supported for Juniper prefix-lists.\n" + "Use route-filters (-E) or route-filter-lists (-z) " + "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); + "for IPv6, 1-32 for IPv4)\n", maxlen); exit(1); - } 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 :) */ + } 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; }; - } else if (expander.family==AF_INET) { + } else if (expander.family == AF_INET) { expander.maxlen = 32; - } else if (expander.family==AF_INET6) { + } else if (expander.family == AF_INET6) { expander.maxlen = 128; }; - 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.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)) { + 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"); + "only with Juniper route-filters\n"); }; - if((expander.generation==T_ASPATH || expander.generation==T_OASPATH) && - af != AF_INET && !expander.validate_asns) { + if ((expander.generation == T_ASPATH || expander.generation == T_OASPATH) + && af != AF_INET && !expander.validate_asns) { sx_report(SX_FATAL, "Sorry, -6 makes no sense with as-path (-f/-G) " - "generation\n"); + "generation\n"); }; - if (expander.validate_asns && expander.generation != T_ASPATH && - expander.generation != T_OASPATH) { - sx_report(SX_FATAL, "Sorry, -w makes sense only for as-path (-f/-G) " - "generation\n"); + if (expander.validate_asns && expander.generation != T_ASPATH + && expander.generation != T_OASPATH) { + sx_report(SX_FATAL, "Sorry, -w makes sense only for as-path " + "(-f/-G) generation\n"); }; - if(!argv[0]) + if (!argv[0]) usage(1); - while(argv[0]) { - if(!strcmp(argv[0], "EXCEPT")) { + while (argv[0]) { + if (!strcmp(argv[0], "EXCEPT")) { exceptmode = 1; } else if (exceptmode) { bgpq_expander_add_stop(&expander,argv[0]); - } else if(!strncasecmp(argv[0],"AS-",3)) { + } else 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)) { - bgpq_expander_add_asset(&expander,argv[0]); - } else if(!strncasecmp(c+1,"RS-",3)) { - bgpq_expander_add_rset(&expander,argv[0]); + 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)) { + bgpq_expander_add_rset(&expander, argv[0]); } else { - SX_DEBUG(debug_expander,"Unknown sub-as object %s\n", - argv[0]); + SX_DEBUG(debug_expander,"Unknown sub-as" + " object %s\n", argv[0]); }; } else { bgpq_expander_add_as(&expander,argv[0]); }; } else { char* c = strchr(argv[0], '^'); - if (!c && !bgpq_expander_add_prefix(&expander,argv[0])) { - sx_report(SX_ERROR, "Unable to add prefix %s (bad prefix or " - "address-family)\n", argv[0]); + if (!c && !bgpq_expander_add_prefix(&expander, argv[0])) { + sx_report(SX_ERROR, "Unable to add prefix %s " + "(bad prefix or address-family)\n", argv[0]); exit(1); - } else if (c && !bgpq_expander_add_prefix_range(&expander,argv[0])){ - sx_report(SX_ERROR, "Unable to add prefix-range %s (bad range " - "or address-family)\n", argv[0]); + } else if (c && !bgpq_expander_add_prefix_range(&expander, argv[0])){ + sx_report(SX_ERROR, "Unable to add prefix-range " + "%s (bad range or address-family)\n", + argv[0]); exit(1); }; }; @@ -599,31 +651,36 @@ main(int argc, char* argv[]) argc--; }; - if(!bgpq_expand(&expander)) { + if (!bgpq_expand(&expander)) exit(1); - }; - if(refine) - sx_radix_tree_refine(expander.tree,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) { - case T_NONE: sx_report(SX_FATAL,"Unreachable point... call snar\n"); + switch (expander.generation) { + case T_NONE: + sx_report(SX_FATAL,"Unreachable point... call snar\n"); exit(1); - case T_ASPATH: bgpq4_print_aspath(stdout,&expander); + case T_ASPATH: + bgpq4_print_aspath(stdout,&expander); break; - case T_OASPATH: bgpq4_print_oaspath(stdout,&expander); + case T_OASPATH: + bgpq4_print_oaspath(stdout,&expander); break; - case T_ASSET: bgpq4_print_asset(stdout,&expander); + case T_ASSET: + bgpq4_print_asset(stdout,&expander); break; - case T_PREFIXLIST: bgpq4_print_prefixlist(stdout,&expander); + case T_PREFIXLIST: + bgpq4_print_prefixlist(stdout,&expander); break; - case T_EACL: bgpq4_print_eacl(stdout,&expander); + case T_EACL: + bgpq4_print_eacl(stdout,&expander); break; case T_ROUTE_FILTER_LIST: bgpq4_print_route_filter_list(stdout, &expander); @@ -634,4 +691,3 @@ main(int argc, char* argv[]) return 0; }; - diff --git a/bgpq4_printer.c b/bgpq4_printer.c index 79f5b3e..455cc47 100644 --- a/bgpq4_printer.c +++ b/bgpq4_printer.c @@ -24,152 +24,218 @@ int bgpq4_print_openbgpd_asset(FILE* f, struct bgpq_expander* b); int bgpq4_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] && - b->asn32s[b->asnumber/65536][(b->asnumber%65536)/8]& - (0x80>>(b->asnumber%8))) { - fprintf(f,"ip as-path access-list %s permit ^%u(_%u)*$\n", - b->name?b->name:"NN",b->asnumber,b->asnumber); - empty=0; - }; - for(k=0;k<65536;k++) { - if(!b->asn32s[k]) continue; + int nc = 0, i, j, k, empty = 1; - 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,"ip as-path access-list %s permit" - " ^%u(_[0-9]+)*_(%u", b->name?b->name:"NN", - b->asnumber,k*65536+i*8+j); - empty=0; - }; - } else { - fprintf(f,"|%u",k*65536+i*8+j); - empty=0; - }; - } - nc++; - if(nc==b->aswidth) { - fprintf(f,")$\n"); - nc=0; + fprintf(f, "no ip as-path access-list %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,"ip as-path access-list %s permit " + "^%u(_%u)*$\n", b->name ? b->name : "NN", + b->asnumber, b->asnumber); + empty = 0; + }; + + 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,"ip as-path access-list %s permit" + " ^%u(_[0-9]+)*_(%u", + b->name ? b->name : "NN", + b->asnumber, + k * 65536 + i * 8 + j); + empty = 0; }; + } else { + fprintf(f, "|%u", k * 65536 + i * 8 + j); + empty = 0; }; + } + + nc++; + + if (nc == b->aswidth) { + fprintf(f, ")$\n"); + nc = 0; }; - if(nc) fprintf(f,")$\n"); - if(empty) - fprintf(f,"ip as-path access-list %s deny .*\n", b->name?b->name:"NN"); + }; + }; + + if (nc) + fprintf(f, ")$\n"); + + if (empty) + fprintf(f, "ip as-path access-list %s deny .*\n", + b->name ? b->name : "NN"); + return 0; }; int bgpq4_print_cisco_xr_aspath(FILE* f, struct bgpq_expander* b) { - int nc=0, i, j, k, comma=0; - fprintf(f, "as-path-set %s", 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,"\n ios-regex '^%u(_%u)*$'", b->asnumber,b->asnumber); - comma=1; - }; - for(k=0;k<65536;k++) { - if(!b->asn32s[k]) continue; + int nc = 0, i, j, k, comma = 0; - 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,"%s\n ios-regex '^%u(_[0-9]+)*_(%u", - comma?",":"", b->asnumber,k*65536+i*8+j); + fprintf(f, "as-path-set %s", 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,"\n ios-regex '^%u(_%u)*$'", b->asnumber, + b->asnumber); + comma = 1; + }; + + 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, "%s\n ios-regex '^%u(_[0-9]+)*_(%u", + comma ? "," : "", + b->asnumber, + k * 65536 + i * 8 + j); comma=1; } else { - fprintf(f,"|%u",k*65536+i*8+j); + fprintf(f, "|%u", + k * 65536 + i * 8 + j); } + nc++; - if(nc==b->aswidth) { - fprintf(f,")$'"); - nc=0; + + if (nc == b->aswidth) { + fprintf(f, ")$'"); + nc = 0; }; }; }; }; }; - if(nc) fprintf(f,")$'"); - fprintf(f,"\nend-set\n"); + + if (nc) + fprintf(f, ")$'"); + + fprintf(f, "\nend-set\n"); return 0; }; + int bgpq4_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] && - b->asn32s[b->asnumber/65536][(b->asnumber%65536)/8]& - (0x80>>(b->asnumber%8))) { - fprintf(f,"ip as-path access-list %s permit ^(_%u)*$\n", - b->name?b->name:"NN",b->asnumber); - }; - empty=0; - 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,"ip as-path access-list %s permit" - " ^(_[0-9]+)*_(%u", b->name?b->name:"NN", - k*65536+i*8+j); - empty=0; - }; - } else { - fprintf(f,"|%u",k*65536+i*8+j); - empty=0; - }; - } - nc++; - if(nc==b->aswidth) { - fprintf(f,")$\n"); - nc=0; + 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] && + b->asn32s[b->asnumber / 65536][(b->asnumber % 65536) / 8] & + (0x80 >> (b->asnumber % 8))) { + fprintf(f,"ip as-path access-list %s permit ^(_%u)*$\n", + b->name ? b->name : "NN", + b->asnumber); + }; + + empty = 0; + + 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,"ip as-path access-list %s permit" + " ^(_[0-9]+)*_(%u", + b->name ? b->name : "NN", + k * 65536 + i * 8 + j); + empty = 0; }; + } else { + fprintf(f,"|%u",k*65536+i*8+j); + empty=0; }; + } + + nc++; + + if (nc==b->aswidth) { + fprintf(f,")$\n"); + nc=0; }; - if(nc) fprintf(f,")$\n"); - if(empty) - fprintf(f,"ip as-path access-list %s deny .*\n", b->name?b->name:"NN"); + }; + }; + + if (nc) + fprintf(f,")$\n"); + + if (empty) + fprintf(f,"ip as-path access-list %s deny .*\n", + b->name ? b->name : "NN"); + return 0; }; int bgpq4_print_cisco_xr_oaspath(FILE* f, struct bgpq_expander* b) { - int nc=0, i, j, k, comma=0; - fprintf(f, "as-path-set %s", 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,"\n ios-regex '^(_%u)*$'",b->asnumber); - comma=1; + int nc = 0, i, j, k, comma = 0; + + fprintf(f, "as-path-set %s", 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,"\n ios-regex '^(_%u)*$'", b->asnumber); + comma = 1; }; - 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) { + + 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,"%s\n ios-regex '^(_[0-9]+)*_(%u", - comma?",":"", k*65536+i*8+j); - comma=1; + comma ? "," : "", + k * 65536 + i * 8 + j); + comma = 1; } else { fprintf(f,"|%u",k*65536+i*8+j); } + nc++; - if(nc==b->aswidth) { + if (nc == b->aswidth) { fprintf(f,")$'"); nc=0; }; @@ -177,203 +243,277 @@ bgpq4_print_cisco_xr_oaspath(FILE* f, struct bgpq_expander* b) }; }; }; - if(nc) fprintf(f,")$'"); + + if (nc) + fprintf(f,")$'"); + fprintf(f,"\nend-set\n"); + return 0; }; - + int bgpq4_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", - b->name?b->name:"NN"); + int nc = 0, lineNo = 0, i, j, k; - if(b->asn32s[b->asnumber/65536] && - b->asn32s[b->asnumber/65535][(b->asnumber%65536)/8]& - (0x80>>(b->asnumber%8))) { - fprintf(f," as-path a%u \"^%u(%u)*$\";\n", lineNo, b->asnumber, - b->asnumber); + 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 / 65535][(b->asnumber % 65536) / 8] + & (0x80 >> (b->asnumber % 8))) { + fprintf(f," as-path a%u \"^%u(%u)*$\";\n", lineNo, + b->asnumber, 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%u \"^%u(.)*(%u", - lineNo,b->asnumber,k*65536+i*8+j); + + 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%u \"^%u(.)*(%u", + lineNo, b->asnumber, + k * 65536 + i * 8 + j); } else { - fprintf(f,"|%u",k*65536+i*8+j); + fprintf(f,"|%u", + k * 65536 + i * 8 + j); }; + nc++; - if(nc==b->aswidth) { - fprintf(f,")$\";\n"); - nc=0; + + if (nc == b->aswidth) { + fprintf(f, ")$\";\n"); + nc = 0; lineNo++; }; }; }; }; }; - if(nc) fprintf(f,")$\";\n"); - else if(lineNo==0) - fprintf(f," as-path aNone \"!.*\";\n"); - fprintf(f," }\n}\n"); + + if (nc) + fprintf(f, ")$\";\n"); + else if (lineNo == 0) + fprintf(f, " as-path aNone \"!.*\";\n"); + + fprintf(f, " }\n}\n"); + return 0; }; int bgpq4_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", - b->name?b->name:"NN"); + int nc = 0, lineNo = 0, i, j, k; - if(b->asn32s[b->asnumber/65536] && - b->asn32s[b->asnumber/65536][(b->asnumber%65536)/8]& - (0x80>>(b->asnumber%8))) { - fprintf(f," as-path a%u \"^%u(%u)*$\";\n", lineNo, b->asnumber, - b->asnumber); + 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%u \"^%u(%u)*$\";\n", lineNo, + b->asnumber, 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) { + 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%u \"^(.)*(%u", - lineNo,k*65536+i*8+j); + lineNo, + k * 65536 + i * 8 + j); } else { - fprintf(f,"|%u",k*65536+i*8+j); + fprintf(f, "|%u", + k * 65536 + i* 8 + j); } + nc++; - if(nc==b->aswidth) { - fprintf(f,")$\";\n"); - nc=0; + + if (nc == b->aswidth) { + fprintf(f, ")$\";\n"); + nc = 0; lineNo++; }; }; }; }; }; - if(nc) fprintf(f,")$\";\n"); - else if(lineNo==0) - fprintf(f," as-path aNone \"!.*\";\n"); - fprintf(f," }\n}\n"); + + if (nc) + fprintf(f, ")$\";\n"); + else if (lineNo == 0) + fprintf(f, " as-path aNone \"!.*\";\n"); + + fprintf(f, " }\n}\n"); + return 0; }; int bgpq4_print_openbgpd_oaspath(FILE* f, struct bgpq_expander* b) { - int i, j, k, lineNo=0; + int i, j, k, lineNo = 0; - for(k=0;k<65536;k++) { - if(!b->asn32s[k]) continue; + for (k=0; k<65536; k++) { - for(i=0;i<8192;i++) { - for(j=0;j<8;j++) { - if(b->asn32s[k][i]&(0x80>>j)) { - fprintf(f, "allow to AS %u AS %u\n", b->asnumber, - k*65536+i*8+j); + if (!b->asn32s[k]) + continue; + + for (i = 0 ; i < 8192; i++) { + for (j = 0; j < 8; j++) { + if (b->asn32s[k][i] & (0x80 >> j)) { + fprintf(f, "allow to AS %u AS %u\n", + b->asnumber, + k * 65536 + i * 8 + j); lineNo++; }; }; }; }; - if(!lineNo) + + if (!lineNo) fprintf(f, "deny to AS %u\n", b->asnumber); + return 0; }; int bgpq4_print_nokia_aspath(FILE* f, struct bgpq_expander* b) { - int nc=0, lineNo=1, i, j, k; + int nc = 0, lineNo=1, i, j, k; - fprintf(f,"configure router policy-options\nbegin\nno as-path-group \"%s\"\n", - b->name ? b->name : "NN"); - fprintf(f,"as-path-group \"%s\"\n", b->name ? b->name : "NN"); + fprintf(f, "configure router policy-options\n" + "begin\nno as-path-group \"%s\"\n", + b->name ? b->name : "NN"); - if(b->asn32s[b->asnumber/65536] && - b->asn32s[b->asnumber/65535][(b->asnumber%65536)/8]& - (0x80>>(b->asnumber%8))) { - fprintf(f," entry %u expression \"%u+\"\n", lineNo, b->asnumber); + fprintf(f, "as-path-group \"%s\"\n", b->name ? b->name : "NN"); + + if (b->asn32s[b->asnumber / 65536] && + b->asn32s[b->asnumber / 65535][(b->asnumber % 65536) / 8] & + (0x80 >> (b->asnumber % 8))) { + fprintf(f, " entry %u expression \"%u+\"\n", lineNo, + 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) { + + 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," entry %u expression \"%u.*[%u", - lineNo,b->asnumber,k*65536+i*8+j); + lineNo, b->asnumber, + k * 65536 + i * 8 + j); } else { - fprintf(f," %u",k*65536+i*8+j); + fprintf(f, " %u", + k * 65536 + i * 8 + j); }; + nc++; - if(nc==b->aswidth) { - fprintf(f,"]\"\n"); - nc=0; + + if (nc == b->aswidth) { + fprintf(f, "]\"\n"); + nc = 0; lineNo++; }; }; }; }; }; - if(nc) fprintf(f,"]\"\n"); + + if (nc) + fprintf(f, "]\"\n"); + fprintf(f,"exit\ncommit\n"); + return 0; }; int bgpq4_print_nokia_md_aspath(FILE* f, struct bgpq_expander* b) { - int nc=0, lineNo=1, i, j, k; + int nc = 0, lineNo = 1, i, j, k; fprintf(f,"/configure policy-options\ndelete as-path-group \"%s\"\n", - b->name ? b->name : "NN"); + b->name ? b->name : "NN"); fprintf(f,"as-path-group \"%s\" {\n", b->name ? b->name : "NN"); - if(b->asn32s[b->asnumber/65536] && - b->asn32s[b->asnumber/65535][(b->asnumber%65536)/8]& - (0x80>>(b->asnumber%8))) { - fprintf(f," entry %u {\n expression \"%u+\"\n }\n", lineNo, - b->asnumber); + if (b->asn32s[b->asnumber / 65536] && + b->asn32s[b->asnumber / 65535][(b->asnumber % 65536) / 8] & + (0x80 >> (b->asnumber % 8))) { + fprintf(f," entry %u {\n expression \"%u+\"\n }\n", + lineNo, 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) { + + 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," entry %u {\n expression \"%u.*[%u", - lineNo,b->asnumber,k*65536+i*8+j); + lineNo, b->asnumber, + k * 65536 + i * 8 + j); } else { - fprintf(f," %u",k*65536+i*8+j); + fprintf(f, " %u", + k * 65536 + i * 8 + j); }; + nc++; - if(nc==b->aswidth) { + + if (nc == b->aswidth) { fprintf(f,"]\"\n }\n"); - nc=0; + nc = 0; lineNo++; }; }; }; }; }; - if(nc) fprintf(f,"]\"\n }\n"); + + if (nc) + fprintf(f,"]\"\n }\n"); + fprintf(f, "}\n"); + return 0; }; @@ -381,231 +521,292 @@ bgpq4_print_nokia_md_aspath(FILE* f, struct bgpq_expander* b) int bgpq4_print_huawei_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,"undo ip as-path-filter %s\n", + fprintf(f, "undo ip as-path-filter %s\n", b->name ? b->name : "NN"); - if(b->asn32s[b->asnumber/65536] && - b->asn32s[b->asnumber/65535][(b->asnumber%65536)/8]& - (0x80>>(b->asnumber%8))) { - fprintf(f,"ip as-path-filter %s permit ^%u(%u)*$\n", - b->name?b->name:"NN",b->asnumber,b->asnumber); + if (b->asn32s[b->asnumber / 65536] && + b->asn32s[b->asnumber / 65535][(b->asnumber % 65536) / 8] & + (0x80 >> (b->asnumber % 8))) { + fprintf(f, "ip as-path-filter %s permit ^%u(%u)*$\n", + b->name ? b->name : "NN", b->asnumber, b->asnumber); empty=0; }; - 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,"ip as-path-filter %s permit ^%u([0-9]+)*" - "_(%u", - b->name?b->name:"NN",b->asnumber,k*65536+i*8+j); - empty=0; + + 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, "ip as-path-filter %s permit ^%u([0-9]+)*" + "_(%u", + b->name ? b->name : "NN", + b->asnumber, + k * 65536 + i * 8 + j); + empty = 0; } else { - fprintf(f,"|%u",k*65536+i*8+j); + fprintf(f, "|%u", + k * 65536 + i * 8 + j); }; + nc++; - if(nc==b->aswidth) { - fprintf(f,")$\n"); - nc=0; + + if (nc == b->aswidth) { + fprintf(f, ")$\n"); + nc = 0; }; }; }; }; }; - if(nc) fprintf(f,")$\n"); - if(empty) - fprintf(f,"ip as-path-filter %s deny .*\n", b->name?b->name:"NN"); + + if (nc) + fprintf(f, ")$\n"); + + if (empty) + fprintf(f,"ip as-path-filter %s deny .*\n", + b->name ? b->name : "NN"); + return 0; }; int bgpq4_print_huawei_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,"undo ip as-path-filter %s\n", - b->name ? b->name : "NN"); + 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,"ip as-path-filter %s permit (_%u)*$\n", b->name?b->name:"NN", - b->asnumber); - empty=0; + if (b->asn32s[b->asnumber / 65536] && + b->asn32s[b->asnumber / 65536][(b->asnumber % 65536) / 8] & + (0x80 >> (b->asnumber % 8))) { + fprintf(f,"ip as-path-filter %s permit (_%u)*$\n", + b->name ? b->name : "NN", b->asnumber); + empty = 0; }; - 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,"ip as-path-filter %s permit ^(_[0-9]+)*_(%u", + 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, "ip as-path-filter %s permit ^(_[0-9]+)*_(%u", b->name?b->name:"NN",k*65536+i*8+j); } else { - fprintf(f,"|%u",k*65536+i*8+j); + fprintf(f, "|%u",k*65536+i*8+j); } + nc++; - empty=0; - if(nc==b->aswidth) { - fprintf(f,")$\n"); - nc=0; + empty = 0; + + if (nc == b->aswidth) { + fprintf(f, ")$\n"); + nc = 0; }; }; }; }; }; - if(nc) fprintf(f,")$\n"); - if(empty) - fprintf(f, "ip as-path-filter %s deny .*\n", b->name?b->name:"NN"); + + if (nc) + fprintf(f, ")$\n"); + + if (empty) + fprintf(f, "ip as-path-filter %s deny .*\n", + b->name ? b->name : "NN"); + return 0; }; int bgpq4_print_nokia_oaspath(FILE* f, struct bgpq_expander* b) { - int nc=0, lineNo=1, i, j, k; + int nc = 0, lineNo = 1, i, j, k; - fprintf(f,"configure router policy-options\nbegin\nno as-path-group \"%s\"\n", - b->name ? b->name : "NN"); + fprintf(f, "configure router policy-options\nbegin\nno as-path-group" + "\"%s\"\n", b->name ? b->name : "NN"); fprintf(f,"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," entry %u expression \"%u+\"\n", lineNo, b->asnumber); + if (b->asn32s[b->asnumber / 65536] && + b->asn32s[b->asnumber/65536][(b->asnumber%65536)/8] & + (0x80 >> (b->asnumber % 8))) { + fprintf(f, " entry %u expression \"%u+\"\n", lineNo, + 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) { + 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," entry %u expression \".*[%u", - lineNo,k*65536+i*8+j); + lineNo, + k * 65536 + i * 8 + j); } else { fprintf(f," %u",k*65536+i*8+j); } + nc++; - if(nc==b->aswidth) { + + if (nc == b->aswidth) { fprintf(f,"]\"\n"); - nc=0; + nc = 0; lineNo++; }; }; }; }; }; - if(nc) fprintf(f,"]\"\n"); + + if (nc) + fprintf(f, "]\"\n"); + return 0; }; int bgpq4_print_nokia_md_oaspath(FILE* f, struct bgpq_expander* b) { - int nc=0, lineNo=1, i, j, k; + int nc = 0, lineNo = 1, i, j, k; - fprintf(f,"/configure policy-options\ndelete as-path-group \"%s\"\n", + fprintf(f, "/configure policy-options\ndelete as-path-group \"%s\"\n", b->name ? b->name : "NN"); - fprintf(f,"as-path-group \"%s\" {\n", b->name ? b->name : "NN"); + fprintf(f, "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," entry %u {\n expression \"%u+\"\n }\n", lineNo, - b->asnumber); + if (b->asn32s[b->asnumber / 65536] && + b->asn32s[b->asnumber / 65536][(b->asnumber % 65536) / 8] & + (0x80>>(b->asnumber%8))) { + fprintf(f, " entry %u {\n expression \"%u+\"\n }\n", + lineNo, 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) { + 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," entry %u {\n expression \".*[%u", - lineNo,k*65536+i*8+j); + lineNo, + k * 65536 + i * 8 + j); } else { - fprintf(f," %u",k*65536+i*8+j); + fprintf(f, " %u", + k * 65536 + i * 8 + j); } + nc++; - if(nc==b->aswidth) { - fprintf(f,"]\"\n }\n"); - nc=0; + + if (nc == b->aswidth) { + fprintf(f, "]\"\n }\n"); + nc = 0; lineNo++; }; }; }; }; }; - if(nc) fprintf(f,"]\"\n }\n"); + + if (nc) + fprintf(f,"]\"\n }\n"); + fprintf(f, "}\n"); + return 0; }; int bgpq4_print_aspath(FILE* f, struct bgpq_expander* b) { - if(b->vendor==V_JUNIPER) { - return bgpq4_print_juniper_aspath(f,b); - } else if(b->vendor==V_CISCO) { - return bgpq4_print_cisco_aspath(f,b); - } else if(b->vendor==V_CISCO_XR) { - return bgpq4_print_cisco_xr_aspath(f,b); - } else if(b->vendor==V_JSON) { - return bgpq4_print_json_aspath(f,b); - } else if(b->vendor==V_BIRD) { - return bgpq4_print_bird_aspath(f,b); - } else if(b->vendor==V_OPENBGPD) { - return bgpq4_print_openbgpd_aspath(f,b); - } else if(b->vendor==V_NOKIA) { - return bgpq4_print_nokia_aspath(f,b); - } else if(b->vendor==V_NOKIA_MD) { - return bgpq4_print_nokia_md_aspath(f,b); - } else if(b->vendor==V_HUAWEI) { - return bgpq4_print_huawei_aspath(f,b); + if (b->vendor == V_JUNIPER) { + return bgpq4_print_juniper_aspath(f, b); + } else if (b->vendor == V_CISCO) { + return bgpq4_print_cisco_aspath(f, b); + } else if (b->vendor == V_CISCO_XR) { + return bgpq4_print_cisco_xr_aspath(f, b); + } else if (b->vendor == V_JSON) { + return bgpq4_print_json_aspath(f, b); + } else if (b->vendor == V_BIRD) { + return bgpq4_print_bird_aspath(f, b); + } else if (b->vendor == V_OPENBGPD) { + return bgpq4_print_openbgpd_aspath(f, b); + } else if (b->vendor == V_NOKIA) { + return bgpq4_print_nokia_aspath(f, b); + } else if (b->vendor == V_NOKIA_MD) { + return bgpq4_print_nokia_md_aspath(f, b); + } else if (b->vendor == V_HUAWEI) { + return bgpq4_print_huawei_aspath(f, b); } else { sx_report(SX_FATAL,"Unknown vendor %i\n", b->vendor); }; + return 0; }; int bgpq4_print_oaspath(FILE* f, struct bgpq_expander* b) { - if(b->vendor==V_JUNIPER) { - return bgpq4_print_juniper_oaspath(f,b); - } else if(b->vendor==V_CISCO) { - return bgpq4_print_cisco_oaspath(f,b); - } else if(b->vendor==V_CISCO_XR) { - return bgpq4_print_cisco_xr_oaspath(f,b); - } else if(b->vendor==V_OPENBGPD) { - return bgpq4_print_openbgpd_oaspath(f,b); - } else if(b->vendor==V_NOKIA) { - return bgpq4_print_nokia_oaspath(f,b); - } else if(b->vendor==V_NOKIA_MD) { - return bgpq4_print_nokia_md_oaspath(f,b); - } else if(b->vendor==V_HUAWEI) { - return bgpq4_print_huawei_oaspath(f,b); + if (b->vendor == V_JUNIPER) { + return bgpq4_print_juniper_oaspath(f, b); + } else if (b->vendor == V_CISCO) { + return bgpq4_print_cisco_oaspath(f, b); + } else if (b->vendor == V_CISCO_XR) { + return bgpq4_print_cisco_xr_oaspath(f, b); + } else if (b->vendor == V_OPENBGPD) { + return bgpq4_print_openbgpd_oaspath(f, b); + } else if (b->vendor == V_NOKIA) { + return bgpq4_print_nokia_oaspath(f, b); + } else if (b->vendor == V_NOKIA_MD) { + return bgpq4_print_nokia_md_oaspath(f, b); + } else if (b->vendor == V_HUAWEI) { + return bgpq4_print_huawei_oaspath(f, b); } else { sx_report(SX_FATAL,"Unknown vendor %i\n", b->vendor); }; + return 0; }; int bgpq4_print_asset(FILE* f, struct bgpq_expander* b) { - switch(b->vendor) { + switch (b->vendor) { case V_JSON: return bgpq4_print_json_aspath(f,b); case V_OPENBGPD: @@ -613,8 +814,8 @@ bgpq4_print_asset(FILE* f, struct bgpq_expander* b) case V_BIRD: return bgpq4_print_bird_aspath(f,b); default: - sx_report(SX_FATAL, "as-sets (-t) supported for JSON, OpenBGPD " - "and BIRD only\n"); + sx_report(SX_FATAL, "as-sets (-t) supported for JSON, " + "OpenBGPD, and BIRD only\n"); return -1; }; }; @@ -623,11 +824,16 @@ void bgpq4_print_jprefix(struct sx_radix_node* n, void* ff) { char prefix[128]; - FILE* f=(FILE*)ff; - if(n->isGlue) return; - if(!f) f=stdout; - sx_prefix_snprintf(n->prefix,prefix,sizeof(prefix)); - fprintf(f," %s;\n",prefix); + FILE* f = (FILE*)ff; + + if (n->isGlue) + return; + + if (!f) + f = stdout; + + sx_prefix_snprintf(n->prefix, prefix, sizeof(prefix)); + fprintf(f," %s;\n", prefix); }; static int needscomma=0; @@ -636,59 +842,77 @@ void bgpq4_print_json_prefix(struct sx_radix_node* n, void* ff) { char prefix[128]; - FILE* f=(FILE*)ff; - if(n->isGlue) + FILE* f = (FILE*)ff; + + if (n->isGlue) goto checkSon; - if(!f) - f=stdout; + + 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); + 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); + 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); + "\"less-equal\": %u }", needscomma ? "," : "", prefix, + n->aggregateHi); }; - needscomma=1; + + needscomma = 1; + checkSon: - if(n->son) + if (n->son) bgpq4_print_json_prefix(n->son, ff); }; int bgpq4_print_json_aspath(FILE* f, struct bgpq_expander* b) { - int nc=0, i, j, k; - fprintf(f,"{\"%s\": [", b->name?b->name:"NN"); + int nc = 0, i, j, k; - for(k=0;k<65536;k++) { - if(!b->asn32s[k]) continue; + fprintf(f, "{\"%s\": [", b->name ? b->name : "NN"); - for(i=0;i<8192;i++) { - for(j=0;j<8;j++) { - if(b->asn32s[k][i]&(0x80>>j)) { - if(!nc) { - fprintf(f,"%s\n %u",needscomma?",":"", k*65536+i*8+j); - needscomma=1; + 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\n %u", + needscomma ? "," : "", + k * 65536 + i * 8 + j); + needscomma = 1; } else { - fprintf(f,"%s%u",needscomma?",":"", k*65536+i*8+j); - needscomma=1; + fprintf(f, "%s%u", + needscomma ? "," : "", + k * 65536 + i * 8 + j); + needscomma = 1; } + nc++; - if(nc==b->aswidth) { - nc=0; - }; + + if (nc == b->aswidth) + nc = 0; }; }; }; }; + fprintf(f,"\n]}\n"); + return 0; }; @@ -696,25 +920,30 @@ void bgpq4_print_bird_prefix(struct sx_radix_node* n, void* ff) { char prefix[128]; - FILE* f=(FILE*)ff; - if(n->isGlue) + FILE* f = (FILE*)ff; + + if (n->isGlue) goto checkSon; - if(!f) + + if (!f) f=stdout; + sx_prefix_snprintf(n->prefix, prefix, sizeof(prefix)); + if (!n->isAggregate) { - fprintf(f, "%s\n %s", - needscomma?",":"", prefix); + fprintf(f, "%s\n %s", needscomma ? "," : "", prefix); } else if (n->aggregateLow > n->prefix->masklen) { - fprintf(f, "%s\n %s{%u,%u}", - needscomma?",":"", prefix, n->aggregateLow, n->aggregateHi); + fprintf(f, "%s\n %s{%u,%u}", needscomma ? "," : "", prefix, + n->aggregateLow, n->aggregateHi); } else { - fprintf(f, "%s\n %s{%u,%u}", - needscomma?",":"", prefix, n->prefix->masklen, n->aggregateHi); + fprintf(f, "%s\n %s{%u,%u}", needscomma ? "," : "", prefix, + n->prefix->masklen, n->aggregateHi); }; - needscomma=1; + + needscomma = 1; + checkSon: - if(n->son) + if (n->son) bgpq4_print_bird_prefix(n->son, ff); }; @@ -723,33 +952,45 @@ bgpq4_print_bird_aspath(FILE* f, struct bgpq_expander* b) { int nc=0, i, j, k, empty=1; char buffer[2048]; - snprintf(buffer, sizeof(buffer), "%s = [", b->name?b->name:"NN"); + snprintf(buffer, sizeof(buffer), "%s = [", b->name ? b->name : "NN"); - for(k=0;k<65536;k++) { - if(!b->asn32s[k]) continue; + for (k = 0; k < 65536; k++) { - for(i=0;i<8192;i++) { - for(j=0;j<8;j++) { - if(b->asn32s[k][i]&(0x80>>j)) { - if(buffer[0]) + 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 (buffer[0]) fprintf(f, "%s", buffer); - buffer[0]=0; - if(!nc) { - fprintf(f, "%s%u", empty?"":",\n ", k*65536+i*8+j); + + buffer[0] = 0; + + if (!nc) { + fprintf(f, "%s%u", + empty ? "" : ",\n ", + k * 65536 + i * 8 + j); empty = 0; } else { - fprintf(f, ", %u", k*65536+i*8+j); + fprintf(f, ", %u", + k * 65536 + i * 8 + j); }; + nc++; - if(nc==b->aswidth) { - nc=0; - }; + + if (nc == b->aswidth) + nc = 0; }; }; }; }; - if(!empty) - fprintf(f,"];\n"); + + if (!empty) + fprintf(f, "];\n"); + return 0; }; @@ -757,136 +998,169 @@ void bgpq4_print_openbgpd_prefix(struct sx_radix_node* n, void* ff) { char prefix[128]; - FILE* f=(FILE*)ff; - if(n->isGlue) + FILE* f = (FILE*)ff; + + if (n->isGlue) goto checkSon; - if(!f) - f=stdout; + + if (!f) + f = stdout; + sx_prefix_snprintf(n->prefix, prefix, sizeof(prefix)); + if (!n->isAggregate) { fprintf(f, "\n\t%s", prefix); } else if (n->aggregateLow == n->aggregateHi) { fprintf(f, "\n\t%s prefixlen = %u", prefix, n->aggregateHi); } else if (n->aggregateLow > n->prefix->masklen) { fprintf(f, "\n\t%s prefixlen %u - %u", - prefix, n->aggregateLow, n->aggregateHi); + prefix, n->aggregateLow, n->aggregateHi); } else { fprintf(f, "\n\t%s prefixlen %u - %u", - prefix, n->prefix->masklen, n->aggregateHi); + prefix, n->prefix->masklen, n->aggregateHi); }; + checkSon: - if(n->son) + if (n->son) bgpq4_print_openbgpd_prefix(n->son, ff); }; int bgpq4_print_openbgpd_asset(FILE* f, struct bgpq_expander* b) { - int i, j, k, nc=0; + int i, j, k, nc = 0; - fprintf(f, "as-set %s {", b->name?b->name:"NN"); + fprintf(f, "as-set %s {", b->name ? b->name : "NN"); - for(k=0;k<65536;k++) { - if(!b->asn32s[k]) continue; + 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)) { + fprintf(f, "%s%u", + nc == 0 ? "\n\t" : " ", + k * 65536 + i * 8 + j); - for(i=0;i<8192;i++) { - for(j=0;j<8;j++) { - if(b->asn32s[k][i]&(0x80>>j)) { - fprintf(f, "%s%u", nc==0 ? "\n\t" : " ", k*65536+i*8+j); nc++; - if(nc==b->aswidth) - nc=0; + + if (nc == b->aswidth) + nc = 0; }; }; }; }; + fprintf(f, "\n}\n"); + return 0; }; int bgpq4_print_openbgpd_aspath(FILE* f, struct bgpq_expander* b) { - int i, j, k, lineNo=0; + int i, j, k, lineNo = 0; - for(k=0;k<65536;k++) { - if(!b->asn32s[k]) continue; + for (k = 0; k < 65536; k++) { - for(i=0;i<8192;i++) { - for(j=0;j<8;j++) { - if(b->asn32s[k][i]&(0x80>>j)) { - fprintf(f, "allow from AS %u AS %u\n", b->asnumber, - k*65536+i*8+j); + if (!b->asn32s[k]) + continue; + + for (i = 0; i < 8192; i++) { + for(j = 0; j < 8; j++) { + if (b->asn32s[k][i] & (0x80 >> j)) { + fprintf(f, "allow from AS %u AS %u\n", + b->asnumber, k * 65536 + i * 8 + j); lineNo++; }; }; }; }; - if(!lineNo) + + if (!lineNo) fprintf(f, "deny from AS %u\n", b->asnumber); + return 0; }; -static int jrfilter_prefixed=1; +static int jrfilter_prefixed = 1; void bgpq4_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; + 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," %s%s exact;\n", - jrfilter_prefixed ? "route-filter " : "", prefix); + + if (!n->isAggregate) { + fprintf(f, " %s%s exact;\n", + jrfilter_prefixed ? "route-filter " : "", prefix); } else { - if(n->aggregateLow>n->prefix->masklen) { + if (n->aggregateLow>n->prefix->masklen) { fprintf(f," %s%s prefix-length-range /%u-/%u;\n", - jrfilter_prefixed ? "route-filter " : "", - prefix,n->aggregateLow,n->aggregateHi); + jrfilter_prefixed ? "route-filter " : "", + prefix, n->aggregateLow, n->aggregateHi); } else { fprintf(f," %s%s upto /%u;\n", - jrfilter_prefixed ? "route-filter " : "", - prefix,n->aggregateHi); + jrfilter_prefixed ? "route-filter " : "", + prefix, n->aggregateHi); }; }; + checkSon: - if(n->son) + if (n->son) bgpq4_print_jrfilter(n->son, ff); }; - -static char* bname=NULL; -static int seq=0; +static char* bname = NULL; +static int seq = 0; void bgpq4_print_cprefix(struct sx_radix_node* n, void* ff) { - char prefix[128], seqno[16]=""; - FILE* f=(FILE*)ff; - if(!f) f=stdout; - if(n->isGlue) goto checkSon; + char prefix[128], seqno[16] = ""; + FILE* f = (FILE*)ff; + + if (!f) + f = stdout; + + if (n->isGlue) + goto checkSon; + sx_prefix_snprintf(n->prefix,prefix,sizeof(prefix)); - if(seq) + + if (seq) snprintf(seqno, sizeof(seqno), " seq %i", seq++); - if(n->isAggregate) { - if(n->aggregateLow>n->prefix->masklen) { + + if (n->isAggregate) { + if (n->aggregateLow>n->prefix->masklen) { fprintf(f,"%s prefix-list %s%s permit %s ge %u le %u\n", - n->prefix->family==AF_INET?"ip":"ipv6",bname?bname:"NN",seqno, - prefix,n->aggregateLow,n->aggregateHi); + n->prefix->family == AF_INET ? "ip" : "ipv6", + bname ? bname : "NN", seqno, prefix, + n->aggregateLow, n->aggregateHi); } else { fprintf(f,"%s prefix-list %s%s permit %s le %u\n", - n->prefix->family==AF_INET?"ip":"ipv6",bname?bname:"NN",seqno, - prefix,n->aggregateHi); + n->prefix->family == AF_INET ? "ip" : "ipv6", + bname?bname:"NN", seqno, prefix, + n->aggregateHi); }; } else { fprintf(f,"%s prefix-list %s%s permit %s\n", - (n->prefix->family==AF_INET)?"ip":"ipv6",bname?bname:"NN",seqno, - prefix); + n->prefix->family==AF_INET ? "ip" : "ipv6", + bname ? bname : "NN", seqno, prefix); }; + checkSon: - if(n->son) + if (n->son) bgpq4_print_cprefix(n->son,ff); }; @@ -894,54 +1168,76 @@ void bgpq4_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; + 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); + needscomma ? ",\n " : " ", + prefix, n->aggregateLow, n->aggregateHi); } else { - fprintf(f,"%s%s le %u", needscomma?",\n ":" ", prefix, - n->aggregateHi); + fprintf(f,"%s%s le %u", + needscomma ? ",\n " : " ", + prefix, n->aggregateHi); }; } else { - fprintf(f,"%s%s", needscomma?",\n ":" ", prefix); + fprintf(f, "%s%s", + needscomma ? ",\n " : " ", + prefix); }; - needscomma=1; + + needscomma = 1; + checkSon: - if(n->son) - bgpq4_print_cprefixxr(n->son,ff); + if (n->son) + bgpq4_print_cprefixxr(n->son, ff); }; void bgpq4_print_hprefix(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_sep(n->prefix,prefix,sizeof(prefix)," "); - if(n->isAggregate) { - if(n->aggregateLow>n->prefix->masklen) { + FILE* f = (FILE*)ff; + + if (!f) + f = stdout; + + if (n->isGlue) + goto checkSon; + + sx_prefix_snprintf_sep(n->prefix, prefix, sizeof(prefix), " "); + + if (n->isAggregate) { + if (n->aggregateLow>n->prefix->masklen) { fprintf(f,"ip %s-prefix %s permit %s greater-equal %u " - "less-equal %u\n", - n->prefix->family==AF_INET?"ip":"ipv6",bname?bname:"NN", - prefix,n->aggregateLow,n->aggregateHi); + "less-equal %u\n", + n->prefix->family == AF_INET ? "ip" : "ipv6", + bname ? bname : "NN", + prefix, n->aggregateLow, n->aggregateHi); } else { fprintf(f,"ip %s-prefix %s permit %s less-equal %u\n", - n->prefix->family==AF_INET?"ip":"ipv6",bname?bname:"NN", - prefix,n->aggregateHi); + n->prefix->family == AF_INET ? "ip" : "ipv6", + bname ? bname : "NN", + prefix, n->aggregateHi); }; } else { fprintf(f,"ip %s-prefix %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: - if(n->son) - bgpq4_print_hprefix(n->son,ff); + if (n->son) + bgpq4_print_hprefix(n->son, ff); }; @@ -949,78 +1245,107 @@ void bgpq4_print_ceacl(struct sx_radix_node* n, void* ff) { char prefix[128]; - FILE* f=(FILE*)ff; + 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; + uint32_t netmask = 0xfffffffful; - if(n->prefix->masklen==32) { - netmask=0; + 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); - netmask&=0xfffffffful; + netmask <<= (32 - n->prefix->masklen); + netmask &= 0xfffffffful; }; - netmask=htonl(netmask); + 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) { + 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; + + else + mask = 0xfffffffful & (0xfffffffful << (32 - masklen)); + + 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 { - wild2addr=0xfffffffful>>n->aggregateHi; - }; - wildaddr=wildaddr&(~wild2addr); - - if(masklen==32) mask=0xfffffffful; - else mask=0xfffffffful & (0xfffffffful<<(32-masklen)); - - 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)); + 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)); + 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)); + 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)); + fprintf(f, " permit ip host %s host %s\n", prefix, + inet_ntoa(*(struct in_addr*) & netmask)); }; + checkSon: - if(n->son) - bgpq4_print_ceacl(n->son,ff); + if (n->son) + bgpq4_print_ceacl(n->son, ff); }; void bgpq4_print_nokia_ipfilter(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)); - fprintf(f," prefix %s\n", prefix); + FILE* f = (FILE*)ff; + + if (n->isGlue) + goto checkSon; + + if (!f) + f = stdout; + + sx_prefix_snprintf(n->prefix, prefix, sizeof(prefix)); + + fprintf(f, " prefix %s\n", prefix); + checkSon: - if(n->son) + if (n->son) bgpq4_print_nokia_ipfilter(n->son, ff); }; @@ -1028,13 +1353,20 @@ void bgpq4_print_nokia_md_ipfilter(struct sx_radix_node* n, void* ff) { char prefix[128]; - FILE* f=(FILE*)ff; - if(n->isGlue) goto checkSon; - if(!f) f=stdout; + FILE* f = (FILE*)ff; + + if (n->isGlue) + goto checkSon; + + if (!f) + f = stdout; + sx_prefix_snprintf(n->prefix,prefix,sizeof(prefix)); - fprintf(f," prefix %s { }\n", prefix); + + fprintf(f, " prefix %s { }\n", prefix); + checkSon: - if(n->son) + if (n->son) bgpq4_print_nokia_md_ipfilter(n->son, ff); }; @@ -1042,23 +1374,30 @@ void bgpq4_print_nokia_prefix(struct sx_radix_node* n, void* ff) { char prefix[128]; - FILE* f=(FILE*)ff; - if(n->isGlue) goto checkSon; - if(!f) f=stdout; + 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," prefix %s exact\n", prefix); + + if (!n->isAggregate) { + fprintf(f, " prefix %s exact\n", prefix); } else { - if(n->aggregateLow>n->prefix->masklen) { + if (n->aggregateLow>n->prefix->masklen) { fprintf(f," prefix %s prefix-length-range %u-%u\n", - prefix,n->aggregateLow,n->aggregateHi); + prefix, n->aggregateLow, n->aggregateHi); } else { fprintf(f," prefix %s prefix-length-range %u-%u\n", - prefix, n->prefix->masklen, n->aggregateHi); + prefix, n->prefix->masklen, n->aggregateHi); }; }; + checkSon: - if(n->son) + if (n->son) bgpq4_print_nokia_prefix(n->son, ff); }; @@ -1067,25 +1406,33 @@ void bgpq4_print_nokia_md_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_snprintf(n->prefix,prefix,sizeof(prefix)); - if(!n->isAggregate) { - fprintf(f," prefix %s type exact {\n }\n", prefix); + 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, " prefix %s type exact {\n }\n", prefix); } else { - if(n->aggregateLow>n->prefix->masklen) { - fprintf(f," prefix %s type range {\n start-length %u\n" - " end-length %u\n }\n", - prefix,n->aggregateLow,n->aggregateHi); + if (n->aggregateLow>n->prefix->masklen) { + fprintf(f," prefix %s type range {\n" + " start-length %u\n" + " end-length %u\n }\n", + prefix, n->aggregateLow, n->aggregateHi); } else { fprintf(f," prefix %s type through {\n " - "through-length %u\n }\n", - prefix, n->aggregateHi); + "through-length %u\n }\n", prefix, + n->aggregateHi); }; }; + checkSon: - if(n->son) + if (n->son) bgpq4_print_nokia_md_prefix(n->son, ff); }; @@ -1093,66 +1440,77 @@ checkSon: int bgpq4_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,bgpq4_print_jprefix,f); - fprintf(f," }\n}\n"); + fprintf(f, "policy-options {\nreplace:\n prefix-list %s {\n", + b->name ? b->name : "NN"); + + sx_radix_tree_foreach(b->tree, bgpq4_print_jprefix, f); + + fprintf(f, " }\n}\n"); + return 0; }; int bgpq4_print_juniper_routefilter(FILE* f, struct bgpq_expander* b) { - char* c=NULL; - 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) - fprintf(f," %s;\n",b->match); + char* c = NULL; + + 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) + fprintf(f, " %s;\n", b->match); } else { - fprintf(f,"policy-options {\n policy-statement %s { \n" - "replace:\n from {\n", b->name?b->name:"NN"); - if(b->match) - fprintf(f," %s;\n",b->match); + fprintf(f, "policy-options {\n policy-statement %s { \n" + "replace:\n from {\n", b->name ? b->name : "NN"); + if (b->match) + fprintf(f, " %s;\n", b->match); }; - if(!sx_radix_tree_empty(b->tree)) { - jrfilter_prefixed=1; - sx_radix_tree_foreach(b->tree,bgpq4_print_jrfilter,f); + + if (!sx_radix_tree_empty(b->tree)) { + jrfilter_prefixed = 1; + sx_radix_tree_foreach(b->tree, bgpq4_print_jrfilter, f); } 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" : "::"); }; - if(c) { + + if (c) { fprintf(f, " }\n }\n }\n}\n"); } else { fprintf(f, " }\n }\n}\n"); }; + return 0; }; int bgpq4_print_openbgpd_prefixlist(FILE* f, struct bgpq_expander* b) { - bname=b->name ? b->name : "NN"; + bname = b->name ? b->name : "NN"; + if (sx_radix_tree_empty(b->tree)) { - fprintf(f, "# generated prefix-list %s (AS %u) is empty\n", bname, - b->asnumber); + fprintf(f, "# generated prefix-list %s (AS %u) is empty\n", + bname, b->asnumber); if (!b->asnumber) - fprintf(f, "# use -a to generate \"deny from ASN \" " - "instead of this list\n"); + fprintf(f, "# use -a to generate \"deny from " + "ASN \" instead of this list\n"); }; + if (!sx_radix_tree_empty(b->tree) || !b->asnumber) { - if(b->name){ - if(strcmp(b->name, "NN") != 0) { + if (b->name) { + if (strcmp(b->name, "NN") != 0) { fprintf(f, "%s=\"", b->name); } } - fprintf(f,"prefix { "); - sx_radix_tree_foreach(b->tree,bgpq4_print_openbgpd_prefix,f); + fprintf(f, "prefix { "); + sx_radix_tree_foreach(b->tree, bgpq4_print_openbgpd_prefix, f); fprintf(f, "\n\t}"); - if(b->name){ - if(strcmp(b->name, "NN") != 0) { + if (b->name) { + if (strcmp(b->name, "NN") != 0) { fprintf(f, "\""); } } @@ -1160,55 +1518,72 @@ bgpq4_print_openbgpd_prefixlist(FILE* f, struct bgpq_expander* b) } else { fprintf(f, "deny from AS %u\n", b->asnumber); }; + return 0; }; int bgpq4_print_openbgpd_prefixset(FILE* f, struct bgpq_expander* b) { - bname=b->name ? b->name : "NN"; - fprintf(f,"prefix-set %s {", b->name); + bname = b->name ? b->name : "NN"; + + fprintf(f, "prefix-set %s {", bname); + if (!sx_radix_tree_empty(b->tree)) - sx_radix_tree_foreach(b->tree,bgpq4_print_openbgpd_prefix,f); + sx_radix_tree_foreach(b->tree, bgpq4_print_openbgpd_prefix, f); + fprintf(f, "\n}\n"); + return 0; }; int bgpq4_print_cisco_prefixlist(FILE* f, struct bgpq_expander* b) { - bname=b->name ? b->name : "NN"; - seq=b->sequence; - fprintf(f,"no %s prefix-list %s\n", - (b->family==AF_INET)?"ip":"ipv6",bname); + bname = b->name ? b->name : "NN"; + seq = b->sequence; + + 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,bgpq4_print_cprefix,f); + sx_radix_tree_foreach(b->tree, bgpq4_print_cprefix, f); } else { fprintf(f, "! generated prefix-list %s is empty\n", bname); fprintf(f, "%s prefix-list %s deny %s\n", - (b->family==AF_INET) ? "ip" : "ipv6", bname, - (b->family==AF_INET) ? "0.0.0.0/0" : "::/0"); + b->family==AF_INET ? "ip" : "ipv6", + bname, + b->family==AF_INET ? "0.0.0.0/0" : "::/0"); }; + return 0; }; int bgpq4_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,bgpq4_print_cprefixxr,f); + bname = b->name ? b->name : "NN"; + + fprintf(f, "no prefix-set %s\nprefix-set %s\n", bname, bname); + + sx_radix_tree_foreach(b->tree, bgpq4_print_cprefixxr, f); + fprintf(f, "\nend-set\n"); + return 0; }; int bgpq4_print_json_prefixlist(FILE* f, struct bgpq_expander* b) { - fprintf(f,"{ \"%s\": [", - b->name?b->name:"NN"); - sx_radix_tree_foreach(b->tree,bgpq4_print_json_prefix,f); + fprintf(f, "{ \"%s\": [", + b->name ? b->name : "NN"); + + sx_radix_tree_foreach(b->tree, bgpq4_print_json_prefix, f); + fprintf(f,"\n] }\n"); + return 0; }; @@ -1217,29 +1592,34 @@ bgpq4_print_bird_prefixlist(FILE* f, struct bgpq_expander* b) { if (!sx_radix_tree_empty(b->tree)) { fprintf(f,"%s = [", - b->name?b->name:"NN"); - sx_radix_tree_foreach(b->tree,bgpq4_print_bird_prefix,f); - fprintf(f,"\n];\n"); + b->name ? b->name : "NN"); + sx_radix_tree_foreach(b->tree, bgpq4_print_bird_prefix, f); + fprintf(f, "\n];\n"); } else { SX_DEBUG(debug_expander, "skip empty prefix-list in BIRD format\n"); }; + return 0; }; int bgpq4_print_huawei_prefixlist(FILE* f, struct bgpq_expander* b) { - bname=b->name ? b->name : "NN"; - seq=b->sequence; + bname = b->name ? b->name : "NN"; + seq = b->sequence; + fprintf(f,"undo ip %s-prefix %s\n", - (b->family==AF_INET)?"ip":"ipv6",bname); + b->family==AF_INET ? "ip" : "ipv6", bname); + if (!sx_radix_tree_empty(b->tree)) { - sx_radix_tree_foreach(b->tree,bgpq4_print_hprefix,f); + sx_radix_tree_foreach(b->tree, bgpq4_print_hprefix, f); } else { fprintf(f, "ip %s-prefix %s deny %s\n", - (b->family==AF_INET) ? "ip" : "ipv6", bname, - (b->family==AF_INET) ? "0.0.0.0/0" : "::/0"); + b->family==AF_INET ? "ip" : "ipv6", + bname, + b->family==AF_INET ? "0.0.0.0/0" : "::/0"); }; + return 0; }; @@ -1253,16 +1633,22 @@ void bgpq4_print_format_prefix(struct sx_radix_node* n, void* ff) { char prefix[128]; - struct fpcbdata* fpc=(struct fpcbdata*)ff; - FILE* f=fpc->f; - struct bgpq_expander* b=fpc->b; - if(n->isGlue) + struct fpcbdata* fpc = (struct fpcbdata*)ff; + FILE* f = fpc->f; + struct bgpq_expander* b = fpc->b; + + if (n->isGlue) return; - if(!f) - f=stdout; + + if (!f) + f = stdout; + memset(prefix, 0, sizeof(prefix)); + sx_prefix_snprintf_fmt(n->prefix, prefix, sizeof(prefix), - b->name?b->name:"NN", b->format); + b->name ? b->name : "NN", + b->format); + fprintf(f, "%s", prefix); }; @@ -1271,9 +1657,12 @@ int bgpq4_print_format_prefixlist(FILE* f, struct bgpq_expander* b) { struct fpcbdata ff = {.f=f, .b=b}; - sx_radix_tree_foreach(b->tree,bgpq4_print_format_prefix,&ff); - if (strcmp(b->format+strlen(b->format-2), "\n")) + + sx_radix_tree_foreach(b->tree, bgpq4_print_format_prefix, &ff); + + if (strcmp(b->format + strlen(b->format - 2), "\n")) fprintf(f, "\n"); + return 0; }; @@ -1292,62 +1681,82 @@ bgpq4_print_nokia_prefixlist(FILE* f, struct bgpq_expander* b) int bgpq4_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); + if (!sx_radix_tree_empty(b->tree)) { - fprintf(f,"ip access-list extended %s\n", bname); - sx_radix_tree_foreach(b->tree,bgpq4_print_ceacl,f); + fprintf(f, "ip access-list extended %s\n", bname); + sx_radix_tree_foreach(b->tree, bgpq4_print_ceacl, f); } else { - fprintf(f,"! generated access-list %s is empty\n", bname); - fprintf(f,"ip access-list extended %s deny any any\n", bname); + fprintf(f, "! generated access-list %s is empty\n", bname); + fprintf(f, "ip access-list extended %s deny any any\n", bname); }; + return 0; }; int bgpq4_print_nokia_ipprefixlist(FILE* f, struct bgpq_expander* b) { - bname=b->name ? b->name : "NN"; - fprintf(f,"configure filter match-list\nno %s-prefix-list \"%s\"\n", - b->tree->family==AF_INET?"ip":"ipv6", bname); - fprintf(f,"%s-prefix-list \"%s\" create\n", b->tree->family==AF_INET?"ip":"ipv6", bname); + bname = b->name ? b->name : "NN"; + + fprintf(f, "configure filter match-list\nno %s-prefix-list \"%s\"\n", + b->tree->family==AF_INET ? "ip" : "ipv6", bname); + + fprintf(f, "%s-prefix-list \"%s\" create\n", + b->tree->family == AF_INET ? "ip":"ipv6", bname); + if (!sx_radix_tree_empty(b->tree)) { - sx_radix_tree_foreach(b->tree,bgpq4_print_nokia_ipfilter,f); + sx_radix_tree_foreach(b->tree, bgpq4_print_nokia_ipfilter, f); } else { - fprintf(f,"# generated ip-prefix-list %s is empty\n", bname); + fprintf(f, "# generated ip-prefix-list %s is empty\n", bname); }; + fprintf(f,"exit\n"); + return 0; }; int bgpq4_print_nokia_md_prefixlist(FILE* f, struct bgpq_expander* b) { - bname=b->name ? b->name : "NN"; + bname = b->name ? b->name : "NN"; + fprintf(f,"/configure filter match-list\ndelete %s-prefix-list \"%s\"\n", - b->tree->family==AF_INET?"ip":"ipv6", bname); - fprintf(f,"%s-prefix-list \"%s\" {\n", b->tree->family==AF_INET?"ip":"ipv6", - bname); + b->tree->family == AF_INET ? "ip" : "ipv6", bname); + + fprintf(f,"%s-prefix-list \"%s\" {\n", + b->tree->family == AF_INET ? "ip" : "ipv6", bname); + if (!sx_radix_tree_empty(b->tree)) { - sx_radix_tree_foreach(b->tree,bgpq4_print_nokia_md_ipfilter,f); + sx_radix_tree_foreach(b->tree, bgpq4_print_nokia_md_ipfilter, f); } else { fprintf(f,"# generated %s-prefix-list %s is empty\n", - b->tree->family==AF_INET?"ip":"ipv6", bname); + b->tree->family == AF_INET ? "ip" : "ipv6", bname); }; + fprintf(f,"}\n"); + return 0; }; int bgpq4_print_nokia_md_ipprefixlist(FILE* f, struct bgpq_expander* b) { - bname=b->name ? b->name : "NN"; - fprintf(f,"/configure policy-options\ndelete prefix-list \"%s\"\n", bname); - fprintf(f,"prefix-list \"%s\" {\n", bname); + bname = b->name ? b->name : "NN"; + + fprintf(f, "/configure policy-options\ndelete prefix-list \"%s\"\n", + bname); + + fprintf(f, "prefix-list \"%s\" {\n", bname); + if (!sx_radix_tree_empty(b->tree)) { - sx_radix_tree_foreach(b->tree,bgpq4_print_nokia_md_prefix,f); + sx_radix_tree_foreach(b->tree, bgpq4_print_nokia_md_prefix, f); }; + fprintf(f,"}\n"); + return 0; }; @@ -1355,83 +1764,116 @@ void bgpq4_print_kprefix(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_sep(n->prefix,prefix,sizeof(prefix),"/"); - if(n->isAggregate) { - if(n->aggregateLow>n->prefix->masklen) { - fprintf(f,"/routing filter add action=accept chain=\"%s-%s\" prefix=%s prefix-length=%d-%d\n", - bname?bname:"NN", - n->prefix->family==AF_INET?"V4":"V6", - prefix, - n->aggregateLow, - n->aggregateHi); + FILE* f = (FILE*)ff; + + if (!f) + f = stdout; + + if (n->isGlue) + goto checkSon; + + sx_prefix_snprintf_sep(n->prefix, prefix, sizeof(prefix), "/"); + + if (n->isAggregate) { + if (n->aggregateLow>n->prefix->masklen) { + fprintf(f,"/routing filter add action=accept chain=\"" + "%s-%s\" prefix=%s prefix-length=%d-%d\n", + bname ? bname : "NN", + n->prefix->family == AF_INET ? "V4" : "V6", + prefix, n->aggregateLow, n->aggregateHi); } else { - fprintf(f,"/routing filter add action=accept chain=\"%s-%s\" prefix=%s prefix-length=%d\n", - bname?bname:"NN", - n->prefix->family==AF_INET?"V4":"V6", - prefix, - n->aggregateHi); + fprintf(f,"/routing filter add action=accept chain=\"" + "%s-%s\" prefix=%s prefix-length=%d\n", + bname ? bname : "NN", + n->prefix->family == AF_INET ? "V4" : "V6", + prefix, n->aggregateHi); }; } else { - fprintf(f,"/routing filter add action=accept chain=\"%s-%s\" prefix=%s\n", - bname?bname:"NN", - n->prefix->family==AF_INET?"V4":"V6", - prefix); + fprintf(f,"/routing filter add action=accept chain=\"" + "%s-%s\" prefix=%s\n", + bname ? bname : "NN", + n->prefix->family == AF_INET ? "V4" : "V6", + prefix); }; + checkSon: - if(n->son) + if (n->son) bgpq4_print_kprefix(n->son,ff); }; int bgpq4_print_mikrotik_prefixlist(FILE* f, struct bgpq_expander* b) { - bname=b->name ? b->name : "NN"; + bname = b->name ? b->name : "NN"; + if (!sx_radix_tree_empty(b->tree)) { - sx_radix_tree_foreach(b->tree,bgpq4_print_kprefix,f); + sx_radix_tree_foreach(b->tree, bgpq4_print_kprefix, f); } else { fprintf(f, "# generated prefix-list %s is empty\n", bname); }; + return 0; }; int bgpq4_print_prefixlist(FILE* f, struct bgpq_expander* b) { - switch(b->vendor) { - case V_JUNIPER: return bgpq4_print_juniper_prefixlist(f,b); - case V_CISCO: return bgpq4_print_cisco_prefixlist(f,b); - case V_CISCO_XR: return bgpq4_print_ciscoxr_prefixlist(f,b); - case V_JSON: return bgpq4_print_json_prefixlist(f,b); - case V_BIRD: return bgpq4_print_bird_prefixlist(f,b); - case V_OPENBGPD: return bgpq4_print_openbgpd_prefixlist(f,b); - case V_FORMAT: return bgpq4_print_format_prefixlist(f,b); - case V_NOKIA: return bgpq4_print_nokia_prefixlist(f,b); - case V_NOKIA_MD: return bgpq4_print_nokia_md_ipprefixlist(f,b); - case V_HUAWEI: return bgpq4_print_huawei_prefixlist(f,b); - case V_MIKROTIK: return bgpq4_print_mikrotik_prefixlist(f,b); + switch (b->vendor) { + case V_JUNIPER: + return bgpq4_print_juniper_prefixlist(f, b); + case V_CISCO: + return bgpq4_print_cisco_prefixlist(f, b); + case V_CISCO_XR: + return bgpq4_print_ciscoxr_prefixlist(f, b); + case V_JSON: + return bgpq4_print_json_prefixlist(f, b); + case V_BIRD: + return bgpq4_print_bird_prefixlist(f, b); + case V_OPENBGPD: + return bgpq4_print_openbgpd_prefixlist(f, b); + case V_FORMAT: + return bgpq4_print_format_prefixlist(f, b); + case V_NOKIA: + return bgpq4_print_nokia_prefixlist(f, b); + case V_NOKIA_MD: + return bgpq4_print_nokia_md_ipprefixlist(f, b); + case V_HUAWEI: + return bgpq4_print_huawei_prefixlist(f, b); + case V_MIKROTIK: + return bgpq4_print_mikrotik_prefixlist(f, b); }; + return 0; }; int bgpq4_print_eacl(FILE* f, struct bgpq_expander* b) { - switch(b->vendor) { - case V_JUNIPER: return bgpq4_print_juniper_routefilter(f,b); - case V_CISCO: return bgpq4_print_cisco_eacl(f,b); - case V_CISCO_XR: sx_report(SX_FATAL, "unreachable point\n"); - case V_JSON: sx_report(SX_FATAL, "unreachable point\n"); - case V_BIRD: sx_report(SX_FATAL, "unreachable point\n"); - case V_OPENBGPD: return bgpq4_print_openbgpd_prefixset(f,b); - case V_FORMAT: sx_report(SX_FATAL, "unreachable point\n"); - case V_NOKIA: return bgpq4_print_nokia_ipprefixlist(f,b); - case V_NOKIA_MD: return bgpq4_print_nokia_md_prefixlist(f,b); - case V_MIKROTIK: return sx_report(SX_FATAL, "unreachable point\n"); - case V_HUAWEI: return sx_report(SX_FATAL, "unreachable point\n"); + switch (b->vendor) { + case V_JUNIPER: + return bgpq4_print_juniper_routefilter(f, b); + case V_CISCO: + return bgpq4_print_cisco_eacl(f, b); + case V_CISCO_XR: + sx_report(SX_FATAL, "unreachable point\n"); + case V_JSON: + sx_report(SX_FATAL, "unreachable point\n"); + case V_BIRD: + sx_report(SX_FATAL, "unreachable point\n"); + case V_OPENBGPD: + return bgpq4_print_openbgpd_prefixset(f, b); + case V_FORMAT: + sx_report(SX_FATAL, "unreachable point\n"); + case V_NOKIA: + return bgpq4_print_nokia_ipprefixlist(f, b); + case V_NOKIA_MD: + return bgpq4_print_nokia_md_prefixlist(f, b); + case V_MIKROTIK: + return sx_report(SX_FATAL, "unreachable point\n"); + case V_HUAWEI: + return sx_report(SX_FATAL, "unreachable point\n"); }; + return 0; }; @@ -1439,15 +1881,18 @@ int bgpq4_print_juniper_route_filter_list(FILE* f, struct bgpq_expander* b) { fprintf(f, "policy-options {\nreplace:\n route-filter-list %s {\n", - b->name?b->name:"NN"); + b->name ? b->name : "NN"); + if (sx_radix_tree_empty(b->tree)) { 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" : "::"); } else { - jrfilter_prefixed=0; + jrfilter_prefixed = 0; sx_radix_tree_foreach(b->tree,bgpq4_print_jrfilter,f); }; + fprintf(f, " }\n}\n"); + return 0; }; @@ -1455,8 +1900,11 @@ int bgpq4_print_route_filter_list(FILE* f, struct bgpq_expander* b) { switch(b->vendor) { - case V_JUNIPER: return bgpq4_print_juniper_route_filter_list(f,b); - default: sx_report(SX_FATAL, "unreachable point\n"); + case V_JUNIPER: + return bgpq4_print_juniper_route_filter_list(f, b); + default: + sx_report(SX_FATAL, "unreachable point\n"); }; + return 0; }; diff --git a/bgpq_expander.c b/bgpq_expander.c index c60c1eb..ce71d9b 100644 --- a/bgpq_expander.c +++ b/bgpq_expander.c @@ -27,10 +27,10 @@ #include "sx_maxsockbuf.h" #include "expander_freeall.h" -int debug_expander=0; -int pipelining=1; -int expand_as23456=0; -int expand_special_asn=0; +int debug_expander = 0; +int pipelining = 1; +int expand_as23456 = 0; +int expand_special_asn = 0; static inline int tentry_cmp(struct sx_tentry* a, struct sx_tentry* b) @@ -43,28 +43,33 @@ RB_GENERATE(tentree, sx_tentry, entry, tentry_cmp); int bgpq_expander_init(struct bgpq_expander* b, int af) { - if(!af) af=AF_INET; - if(!b) return 0; + if (!af) + af = AF_INET; - memset(b,0,sizeof(struct bgpq_expander)); + if (!b) + return 0; - b->tree=sx_radix_tree_new(af); - if(!b->tree) goto fixups; + memset(b, 0, sizeof(struct bgpq_expander)); - b->family=af; - b->sources=""; - b->name="NN"; - b->aswidth=8; - b->asn32s[0]=malloc(8192); - if(!b->asn32s[0]) { + b->tree = sx_radix_tree_new(af); + + if (!b->tree) + goto fixups; + + b->family = af; + b->sources = ""; + b->name = "NN"; + b->aswidth = 8; + b->asn32s[0] = malloc(8192); + if (!b->asn32s[0]) { sx_report(SX_FATAL,"Unable to allocate 8192 bytes: %s\n", - strerror(errno)); + strerror(errno)); exit(1); }; - memset(b->asn32s[0],0,8192); - b->identify=1; - b->server="rr.ntt.net"; - b->port="43"; + memset(b->asn32s[0], 0, 8192); + b->identify = 1; + b->server = "rr.ntt.net"; + b->port = "43"; // b->wq = STAILQ_HEAD_INITIALZIER(b->wq); // b->rq = STAILQ_HEAD_INITIALZIER(b->rq); @@ -77,10 +82,14 @@ bgpq_expander_init(struct bgpq_expander* b, int af) STAILQ_INIT(&b->macroses); return 1; + fixups: - if(b->tree) sx_radix_tree_freeall(b->tree); - b->tree=NULL; + if (b->tree) + sx_radix_tree_freeall(b->tree); + + b->tree = NULL; free(b); + return 0; }; @@ -88,9 +97,14 @@ int bgpq_expander_add_asset(struct bgpq_expander* b, char* as) { struct sx_slentry* le; - if(!b || !as) return 0; - le=sx_slentry_new(as); + + if (!b || !as) + return 0; + + le = sx_slentry_new(as); + STAILQ_INSERT_TAIL(&b->macroses, le, next); + return 1; }; @@ -98,10 +112,17 @@ int bgpq_expander_add_rset(struct bgpq_expander* b, char* rs) { struct sx_slentry* le; - if(!b || !rs) return 0; - le=sx_slentry_new(rs); - if(!le) return 0; + + if (!b || !rs) + return 0; + + le = sx_slentry_new(rs); + + if (!le) + return 0; + STAILQ_INSERT_TAIL(&b->rsets, le, next); + return 1; }; @@ -110,10 +131,14 @@ bgpq_expander_add_already(struct bgpq_expander* b, char* rs) { struct sx_tentry* le, lkey; lkey.text = rs; + if (RB_FIND(tentree, &b->already, &lkey)) return 1; + le = sx_tentry_new(rs); + RB_INSERT(tentree, &b->already, le); + return 1; }; @@ -122,10 +147,14 @@ bgpq_expander_add_stop(struct bgpq_expander* b, char* rs) { struct sx_tentry* le, lkey; lkey.text = rs; + if (RB_FIND(tentree, &b->stoplist, &lkey)) return 1; + le = sx_tentry_new(rs); + RB_INSERT(tentree, &b->stoplist, le); + return 1; }; @@ -135,70 +164,75 @@ bgpq_expander_add_as(struct bgpq_expander* b, char* as) char* eoa; uint32_t asno; - if(!b || !as) return 0; + if (!b || !as) + return 0; - asno=strtoul(as+2,&eoa,10); - if(eoa && (*eoa!='.' && *eoa!=0)) { + asno = strtoul(as+2,&eoa,10); + if (eoa && (*eoa!='.' && *eoa!=0)) { sx_report(SX_ERROR,"Invalid symbol in AS number: '%c' in %s\n", - *eoa, as); + *eoa, as); return 0; }; - if(*eoa=='.' || asno>65535) { - if(b->asn32 || b->generation>=T_PREFIXLIST) { + if (*eoa == '.' || asno > 65535) { + if (b->asn32 || b->generation >= T_PREFIXLIST) { uint32_t asn1; - if(asno>65535) { - asn1=asno%65536; - asno/=65536; - } else if(eoa && *(eoa+1)) { - asn1=strtoul(eoa+1,&eoa,10); + if (asno > 65535) { + asn1 = asno % 65536; + asno /= 65536; + } 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", - *eoa, as); + if (eoa && *eoa!=0) + sx_report(SX_ERROR,"Invalid symbol in AS number: '%c' in %s\n", + *eoa, as); + return 0; + + if (asn1 > 65535) { + sx_report(SX_ERROR, "Invalid AS number in %s\n", as); return 0; }; - if(asn1>65535) { - sx_report(SX_ERROR,"Invalid AS number in %s\n", as); + + if (!expand_special_asn && (((asno * 65536 + asn1) >= 4200000000ul) || + ((asno * 65536 + asn1) >= 64496 && (asno * 65536 + asn1) <= 65551))) return 0; - }; - if(!expand_special_asn && (((asno*65536+asn1)>=4200000000ul) || - ((asno*65536+asn1)>=64496 && (asno*65536+asn1) <= 65551))) { - return 0; - }; - if(!b->asn32s[asno]) { - b->asn32s[asno]=malloc(8192); - if(!b->asn32s[asno]) { + + if (!b->asn32s[asno]) { + b->asn32s[asno] = malloc(8192); + if (!b->asn32s[asno]) { sx_report(SX_FATAL, "Unable to allocate 8192 bytes: %s." - " Unable to add asn32 %s to future expansion\n", - strerror(errno), as); + " Unable to add asn32 %s to future expansion\n", + strerror(errno), as); return 0; }; - memset(b->asn32s[asno],0,8192); + memset(b->asn32s[asno], 0, 8192); }; - b->asn32s[asno][asn1/8]|=(0x80>>(asn1%8)); - } else if(!b->asn32) { - b->asn32s[0][23456/8]|=(0x80>>(23456%8)); + + b->asn32s[asno][asn1/8] |= (0x80 >> (asn1 % 8)); + + } else if (!b->asn32) { + b->asn32s[0][23456/8] |= (0x80 >> (23456 % 8)); }; + return 1; }; - if(asno<1 || asno>65535) { + if (asno < 1 || asno > 65535) { sx_report(SX_ERROR,"Invalid AS number in %s\n", as); return 0; }; - if(asno==23456 && !expand_as23456) + if (asno == 23456 && !expand_as23456) return 0; - if(!expand_special_asn && (asno>=64496 && asno <= 65536)) + if (!expand_special_asn && (asno >= 64496 && asno <= 65536)) return 0; - b->asn32s[0][asno/8]|=(0x80>>(asno%8)); + b->asn32s[0][asno / 8] |= (0x80 >> (asno % 8)); return 1; }; @@ -207,21 +241,24 @@ int bgpq_expander_add_prefix(struct bgpq_expander* b, char* prefix) { struct sx_prefix *p = sx_prefix_alloc(NULL); - if(!sx_prefix_parse(p,0,prefix)) { - sx_report(SX_ERROR,"Unable to parse prefix %s\n", prefix); + if (!sx_prefix_parse(p, 0, prefix)) { + sx_report(SX_ERROR, "Unable to parse prefix %s\n", prefix); return 0; - } else if(p->family!=b->family) { - SX_DEBUG(debug_expander,"Ignoring prefix %s with wrong address family\n" - ,prefix); + } else if (p->family != b->family) { + SX_DEBUG(debug_expander, "Ignoring prefix %s with wrong " + "address family\n", prefix); return 0; }; - if(b->maxlen && p->masklen>b->maxlen) { - SX_DEBUG(debug_expander, "Ignoring prefix %s: masklen %i > max " - "masklen %u\n", prefix, p->masklen, b->maxlen); + if (b->maxlen && p->masklen>b->maxlen) { + SX_DEBUG(debug_expander, "Ignoring prefix %s: masklen %i > max" + " masklen %u\n", prefix, p->masklen, b->maxlen); return 0; }; sx_radix_tree_insert(b->tree,p); - if (p) sx_prefix_destroy(p); + + if (p) + sx_prefix_destroy(p); + return 1; }; @@ -233,9 +270,10 @@ bgpq_expander_add_prefix_range(struct bgpq_expander* b, char* prefix) int bgpq_expanded_macro(char* as, struct bgpq_expander* ex, - struct bgpq_request* req) + struct bgpq_request* req) { - bgpq_expander_add_as(ex,as); + bgpq_expander_add_as(ex, as); + return 1; }; @@ -243,82 +281,99 @@ struct bgpq_request* bgpq_pipeline(struct bgpq_expander* b, int (*callback)(char*, struct bgpq_expander* b, struct bgpq_request* req), void* udata, char* fmt, ...); int bgpq_expand_irrd(struct bgpq_expander* b, - int (*callback)(char*, struct bgpq_expander* b, struct bgpq_request* req), - void* udata, char* fmt, ...); + int (*callback)(char*, struct bgpq_expander* b, struct bgpq_request* req), + void* udata, char* fmt, ...); int bgpq_expanded_macro_limit(char* as, struct bgpq_expander* b, - struct bgpq_request* req) + struct bgpq_request* req) { if (!strncasecmp(as, "AS-", 3) || strchr(as, '-') || strchr(as, ':')) { struct sx_tentry tkey = { .text = as }; + if (RB_FIND(tentree, &b->already, &tkey)) { - SX_DEBUG(debug_expander>2,"%s is already expanding, ignore\n", as); + SX_DEBUG(debug_expander>2, "%s is already expanding, " + "ignore\n", as); return 0; }; + if (RB_FIND(tentree, &b->stoplist, &tkey)) { - SX_DEBUG(debug_expander>2,"%s is in the stoplist, ignore\n", as); + SX_DEBUG(debug_expander>2, "%s is in the stoplist, " + "ignore\n", as); return 0; }; - if(!b->maxdepth || - (b->cdepth + 1 < b->maxdepth && req->depth + 1 < b->maxdepth)) { - bgpq_expander_add_already(b,as); + + if (!b->maxdepth || + (b->cdepth + 1 < b->maxdepth && + req->depth + 1 < b->maxdepth)) { + bgpq_expander_add_already(b, as); if (pipelining) { struct bgpq_request* req1 = bgpq_pipeline(b, - bgpq_expanded_macro_limit, NULL, "!i%s\n", as); + bgpq_expanded_macro_limit, NULL, "!i%s\n", + as); req1->depth = req->depth+1; } else { b->cdepth++; - bgpq_expand_irrd(b, bgpq_expanded_macro_limit, NULL, "!i%s\n", - as); + bgpq_expand_irrd(b, bgpq_expanded_macro_limit, + NULL, "!i%s\n", as); b->cdepth--; }; } else { - SX_DEBUG(debug_expander>2, "ignoring %s at depth %i\n", as, - b->cdepth?(b->cdepth+1):(req->depth+1)); + SX_DEBUG(debug_expander>2, "ignoring %s at depth %i\n", + as, + b->cdepth ? (b->cdepth + 1) : (req->depth + 1)); }; - } else if(!strncasecmp(as, "AS", 2)) { + } else if (!strncasecmp(as, "AS", 2)) { struct sx_tentry tkey = { .text = as }; + if (RB_FIND(tentree, &b->stoplist, &tkey)) { - SX_DEBUG(debug_expander>2,"%s is in the stoplist, ignore\n", as); + SX_DEBUG(debug_expander > 2, + "%s is in the stoplist, ignore\n", as); return 0; }; - if(bgpq_expander_add_as(b, as)) { - SX_DEBUG(debug_expander>2, ".. added asn %s\n", as); + + if (bgpq_expander_add_as(b, as)) { + SX_DEBUG(debug_expander > 2, ".. added asn %s\n", as); } else { - SX_DEBUG(debug_expander, ".. some error adding as %s (in " - "response to %s)\n", as, req->request); - }; - } else if (!strcasecmp(as, "ANY")) { + SX_DEBUG(debug_expander, ".. some error adding as %s " + "(in response to %s)\n", as, req->request); + } + + } else if (!strcasecmp(as, "ANY")) return 0; - } else { - sx_report(SX_ERROR, "unexpected object '%s' in expanded_macro_limit " - "(in response to %s)\n", as, req->request); - }; + else + sx_report(SX_ERROR, "unexpected object '%s' in " + "expanded_macro_limit (in response to %s)\n", as, + req->request); + return 1; }; int bgpq_expanded_prefix(char* as, struct bgpq_expander* ex, - struct bgpq_request* req __attribute__((unused))) + struct bgpq_request* req __attribute__((unused))) { char* d = strchr(as, '^'); + if (!d) bgpq_expander_add_prefix(ex, as); else bgpq_expander_add_prefix_range(ex, as); + return 1; }; int bgpq_expanded_v6prefix(char* prefix, struct bgpq_expander* ex, - struct bgpq_request* req) + struct bgpq_request* req) { char* d = strchr(prefix, '^'); + if (!d) - bgpq_expander_add_prefix(ex,prefix); + bgpq_expander_add_prefix(ex, prefix); else - bgpq_expander_add_prefix_range(ex,prefix); + bgpq_expander_add_prefix_range(ex, prefix); + return 1; }; @@ -326,56 +381,66 @@ int bgpq_pipeline_dequeue(int fd, struct bgpq_expander* b); static struct bgpq_request* bgpq_request_alloc(char* request, int (*callback)(char*, struct bgpq_expander*, - struct bgpq_request*), void* udata) + struct bgpq_request*), void* udata) { struct bgpq_request* bp = malloc(sizeof(struct bgpq_request)); + if (!bp) return NULL; + memset(bp, 0, sizeof(struct bgpq_request)); bp->request = strdup(request); bp->offset = 0; bp->size = strlen(bp->request); bp->callback = callback; bp->udata = udata; + return bp; }; static void bgpq_request_free(struct bgpq_request* req) { - if (req->request) free(req->request); + if (req->request) + free(req->request); + free(req); }; struct bgpq_request* bgpq_pipeline(struct bgpq_expander* b, - int (*callback)(char*, struct bgpq_expander*, struct bgpq_request*), - void* udata, char* fmt, ...) + int (*callback)(char*, struct bgpq_expander*, struct bgpq_request*), + void* udata, char* fmt, ...) { char request[128]; int ret; - struct bgpq_request* bp=NULL; + struct bgpq_request* bp = NULL; va_list ap; - va_start(ap,fmt); - vsnprintf(request,sizeof(request),fmt,ap); + + va_start(ap, fmt); + vsnprintf(request, sizeof(request), fmt, ap); va_end(ap); SX_DEBUG(debug_expander,"expander: sending %s", request); bp = bgpq_request_alloc(request, callback, udata); - if(!bp) { + + if (!bp) { sx_report(SX_FATAL,"Unable to allocate %lu bytes: %s\n", - (unsigned long)sizeof(struct bgpq_request),strerror(errno)); + (unsigned long)sizeof(struct bgpq_request), + strerror(errno)); exit(1); }; + if (STAILQ_EMPTY(&b->wq)) { - ret=write(b->fd, request, bp->size); + ret = write(b->fd, request, bp->size); if (ret < 0) { if (errno == EAGAIN) { STAILQ_INSERT_TAIL(&b->wq, bp, next); return bp; }; - sx_report(SX_FATAL, "Error writing request: %s\n", strerror(errno)); + sx_report(SX_FATAL, "Error writing request: %s\n", + strerror(errno)); }; bp->offset=ret; if (ret == bp->size) { @@ -395,19 +460,20 @@ bgpq_expander_invalidate_asn(struct bgpq_expander* b, const char* q) if (!strncmp(q, "!gas", 4) || !strncmp(q, "!6as", 4)) { char* eptr; unsigned long asn = strtoul(q+4, &eptr, 10), asn0, asn1 = 0; - if (!asn || asn == ULONG_MAX || asn >= 4294967295 || - (eptr && *eptr != '\n')) { - sx_report(SX_ERROR, "some problem invalidating asn %s\n", q); + if (!asn || asn == ULONG_MAX || asn >= 4294967295 + || (eptr && *eptr != '\n')) { + sx_report(SX_ERROR, "some problem invalidating asn" + " %s\n", q); return; }; asn1 = asn % 65536; asn0 = asn / 65536; if (!b->asn32s[asn0] || !(b->asn32s[asn0][asn1/8] & (0x80 >> (asn1 % 8)))) { - sx_report(SX_NOTICE, "strange, invalidating inactive asn %lu(%s)\n", - asn, q); + sx_report(SX_NOTICE, "strange, invalidating inactive " + "asn %lu(%s)\n", asn, q); } else { - b->asn32s[asn0][asn1/8] &= ~(0x80 >> (asn1 % 8)); + b->asn32s[asn0][asn1 / 8] &= ~(0x80 >> (asn1 % 8)); }; }; }; @@ -417,11 +483,15 @@ bgpq_write(struct bgpq_expander* b) { while(!STAILQ_EMPTY(&b->wq)) { struct bgpq_request* req = STAILQ_FIRST(&b->wq); - int ret = write(b->fd, req->request+req->offset, req->size-req->offset); + + int ret = write(b->fd, req->request+req->offset, + req->size-req->offset); + if (ret < 0) { if (errno == EAGAIN) return; - sx_report(SX_FATAL, "error writing data: %s\n", strerror(errno)); + sx_report(SX_FATAL, "error writing data: %s\n", + strerror(errno)); }; if (ret == req->size - req->offset) { @@ -446,22 +516,26 @@ repeat: FD_ZERO(&rfd); FD_SET(b->fd, &rfd); FD_ZERO(&wfd); + if (!STAILQ_EMPTY(&b->wq)) FD_SET(b->fd, &wfd); - ret = select(b->fd+1, &rfd, &wfd, NULL, &timeout); + ret = select(b->fd + 1, &rfd, &wfd, NULL, &timeout); + if (ret == 0) sx_report(SX_FATAL, "select timeout\n"); else if (ret == -1 && errno == EINTR) goto repeat; else if (ret == -1) - sx_report(SX_FATAL, "select error %i: %s\n", errno, strerror(errno)); + sx_report(SX_FATAL, "select error %i: %s\n", errno, + strerror(errno)); if (!STAILQ_EMPTY(&b->wq) && FD_ISSET(b->fd, &wfd)) bgpq_write(b); if (FD_ISSET(b->fd, &rfd)) return read(b->fd, buffer, size); + goto repeat; }; @@ -476,157 +550,186 @@ bgpq_read(struct bgpq_expander* b) while(!STAILQ_EMPTY(&b->rq)) { struct bgpq_request* req = STAILQ_FIRST(&b->rq); - SX_DEBUG(debug_expander>2, "waiting for answer to %s, init %i '%.*s'\n", - req->request, off, off, response); + SX_DEBUG(debug_expander > 2, "waiting for answer to %s," + "init %i '%.*s'\n", req->request, off, off, response); int ret = 0; char* cres; - if ((cres=strchr(response, '\n'))!=NULL) + if ((cres=strchr(response, '\n')) != NULL) goto have; + repeat: - ret = bgpq_selread(b, response+off, sizeof(response)-off); + ret = bgpq_selread(b, response + off, sizeof(response) - off); if (ret < 0) { if (errno == EAGAIN) goto repeat; - sx_report(SX_FATAL,"Error reading data from IRRd: %s (dequeue)\n", - strerror(errno)); + sx_report(SX_FATAL,"Error reading data from IRRd: " + "%s (dequeue)\n", strerror(errno)); } else if (ret == 0) { sx_report(SX_FATAL,"EOF from IRRd (dequeue)\n"); }; off += ret; - if (!(cres=strchr(response, '\n'))) + if (!(cres = strchr(response, '\n'))) goto repeat; + have: - SX_DEBUG(debug_expander>5, "got response of %.*s\n", off, response); - if(response[0]=='A') { + SX_DEBUG(debug_expander > 5, "got response of %.*s\n", off, + response); + + if (response[0] == 'A') { char* eon, *c; - unsigned long togot=strtoul(response+1,&eon,10); - char* recvbuffer=malloc(togot+2); + unsigned long togot = strtoul(response+1,&eon,10); + char* recvbuffer = malloc(togot+2); int offset = 0; + if (!recvbuffer) { - sx_report(SX_FATAL, "error allocating %lu bytes: %s\n", - togot+2, strerror(errno)); + sx_report(SX_FATAL, "error allocating %lu " + "bytes: %s\n", togot + 2, strerror(errno)); }; + memset(recvbuffer,0,togot+2); - if(!eon || *eon!='\n') { - sx_report(SX_ERROR,"A-code finished with wrong char '%c'(%s)\n", - eon?*eon:'0',response); + if (!eon || *eon != '\n') { + sx_report(SX_ERROR,"A-code finished with wrong" + " char '%c'(%s)\n", eon ? *eon : '0', + response); exit(1); }; - if (off - ((eon+1) - response) > togot) { - /* full response and more data is already in buffer */ - memcpy(recvbuffer, eon+1, togot); + if (off - ((eon + 1) - response) > togot) { + // full response and more data is already in buffer + memcpy(recvbuffer, eon + 1, togot); offset = togot; - memmove(response, eon+1+togot, off-((eon+1)-response)-togot); - off -= togot + ((eon+1)-response); - memset(response+off, 0, sizeof(response)-off); + memmove(response, eon + 1 + togot, + off - ((eon + 1) - response) - togot); + off -= togot + ((eon + 1) - response); + memset(response + off, 0, + sizeof(response) - off); } else { /* response is not yet fully buffered */ - memcpy(recvbuffer, eon+1, off - ((eon+1)-response)); + memcpy(recvbuffer, eon + 1, + off - ((eon + 1) - response)); offset = off - ((eon+1) - response); memset(response, 0, sizeof(response)); off = 0; }; SX_DEBUG(debug_expander>5, - "starting read with ready '%.*s', waiting for %lu\n", - offset, recvbuffer, togot-offset); + "starting read with ready '%.*s', waiting for " + "%lu\n", offset, recvbuffer, togot-offset); if (off > 0) goto have3; if (offset == togot) goto reread2; + reread: - ret = bgpq_selread(b, recvbuffer+offset, togot-offset); + ret = bgpq_selread(b, recvbuffer + offset, togot-offset); if (ret < 0) { if (errno == EAGAIN) goto reread; - sx_report(SX_FATAL,"Error reading IRRd: %s (dequeue, result)\n", - strerror(errno)); + sx_report(SX_FATAL,"Error reading IRRd: %s " + "(dequeue, result)\n", strerror(errno)); } else if (ret == 0) { - sx_report(SX_FATAL,"EOF from IRRd (dequeue, result)\n"); + sx_report(SX_FATAL,"EOF from IRRd (dequeue, " + "result)\n"); }; - SX_DEBUG(debug_expander>5, - "Read1: got '%.*s'\n", ret, recvbuffer+offset); - offset+=ret; - if(offset < togot) { - SX_DEBUG(debug_expander>5, "expected %lu, got %lu expanding %s", - togot, strlen(recvbuffer), req->request); + SX_DEBUG(debug_expander > 5, + "Read1: got '%.*s'\n", ret, + recvbuffer + offset); + offset += ret; + if (offset < togot) { + SX_DEBUG(debug_expander>5, "expected %lu, got " + "%lu expanding %s", togot, + strlen(recvbuffer), req->request); goto reread; }; + reread2: - ret = bgpq_selread(b, response+off, sizeof(response) - off); + ret = bgpq_selread(b, response + off, + sizeof(response) - off); + if (ret < 0) { if (errno == EAGAIN) goto reread2; - sx_report(SX_FATAL,"Error reading IRRd: %s (dequeue,final)\n", - strerror(errno)); + sx_report(SX_FATAL,"Error reading IRRd: %s " + "(dequeue,final)\n", strerror(errno)); } else if (ret == 0) { - sx_report(SX_FATAL,"EOF from IRRd (dequeue,final)\n"); + sx_report(SX_FATAL,"EOF from IRRd (dequeue," + "final)\n"); }; - SX_DEBUG(debug_expander>5, - "Read2: got '%.*s'\n", ret, response+off); - off+=ret; + + SX_DEBUG(debug_expander > 5, + "Read2: got '%.*s'\n", ret, response + off); + + off += ret; have3: if (!(cres = strchr(response, '\n'))) goto reread2; - SX_DEBUG(debug_expander>=3,"Got %s (%lu bytes of %lu) in response " - "to %sfinal code: %.*s",recvbuffer,strlen(recvbuffer),togot, - req->request,off,response); + SX_DEBUG(debug_expander>=3,"Got %s (%lu bytes of %lu) " + "in response to %sfinal code: %.*s", recvbuffer, + strlen(recvbuffer), togot, req->request, + off, response); - for(c=recvbuffer; ccallback(c, b, req); - c+=spn+1; + c += spn+1; }; - assert(c == recvbuffer+togot); - memset(recvbuffer,0,togot+2); + assert(c == recvbuffer + togot); + memset(recvbuffer, 0, togot + 2); free(recvbuffer); - } else if(response[0]=='C') { + } else if (response[0] == 'C') { /* No data */ - SX_DEBUG(debug_expander,"No data expanding %s\n", req->request); - if (b->validate_asns) bgpq_expander_invalidate_asn(b, req->request); - } else if(response[0]=='D') { + SX_DEBUG(debug_expander,"No data expanding %s\n", + req->request); + if (b->validate_asns) + bgpq_expander_invalidate_asn(b, req->request); + } else if (response[0] == 'D') { /* .... */ SX_DEBUG(debug_expander,"Key not found expanding %s\n", - req->request); - if (b->validate_asns) bgpq_expander_invalidate_asn(b, req->request); - } else if(response[0]=='E') { + req->request); + if (b->validate_asns) + bgpq_expander_invalidate_asn(b, req->request); + } else if (response[0] == 'E') { sx_report(SX_ERROR, "Multiple keys expanding %s: %s\n", - req->request, response); - } else if(response[0]=='F') { + req->request, response); + } else if ( response[0] == 'F') { sx_report(SX_ERROR, "Error expanding %s: %s\n", - req->request, response); + req->request, response); } else { sx_report(SX_ERROR,"Wrong reply: %s to %s\n", response, - req->request); + req->request); exit(1); }; - memmove(response, cres+1, off-((cres+1)-response)); - off -= (cres+1)-response; - memset(response+off, 0, sizeof(response) - off); - SX_DEBUG(debug_expander>5, - "fixed response of %i, %.*s\n", off, off, response); + + memmove(response, cres + 1, off - ((cres + 1) - response)); + off -= (cres+1) - response; + memset(response + off, 0, sizeof(response) - off); + SX_DEBUG(debug_expander > 5, + "fixed response of %i, %.*s\n", off, off, response); STAILQ_REMOVE_HEAD(&b->rq, next); b->piped--; + bgpq_request_free(req); }; + return 0; }; int bgpq_expand_irrd(struct bgpq_expander* b, - int (*callback)(char*, struct bgpq_expander*, struct bgpq_request* ), - void* udata, char* fmt, ...) + int (*callback)(char*, struct bgpq_expander*, struct bgpq_request* ), + void* udata, char* fmt, ...) { char request[128], response[128]; va_list ap; @@ -634,62 +737,68 @@ bgpq_expand_irrd(struct bgpq_expander* b, struct bgpq_request *req; va_start(ap,fmt); - vsnprintf(request,sizeof(request),fmt,ap); + vsnprintf(request, sizeof(request), fmt, ap); va_end(ap); req = bgpq_request_alloc(request, callback, udata); - SX_DEBUG(debug_expander,"expander: sending '%s'\n", request); + SX_DEBUG(debug_expander, "expander: sending '%s'\n", request); ret=write(b->fd, request, strlen(request)); - if(ret!=strlen(request)) { - sx_report(SX_FATAL,"Partial write to IRRd, only %i bytes written: %s\n", - ret, strerror(errno)); + if (ret != strlen(request)) { + sx_report(SX_FATAL,"Partial write to IRRd, only %i bytes " + "written: %s\n", ret, strerror(errno)); exit(1); }; - memset(response,0,sizeof(response)); + memset(response, 0, sizeof(response)); repeat: ret = bgpq_selread(b, response+off, sizeof(response)-off); if (ret < 0) { - sx_report(SX_ERROR, "Error reading IRRd: %s\n", strerror(errno)); + sx_report(SX_ERROR, "Error reading IRRd: %s\n", + strerror(errno)); exit(1); } else if (ret == 0) { sx_report(SX_FATAL, "EOF reading IRRd\n"); exit(1); }; + off += ret; if (strchr(response, '\n') == NULL) goto repeat; - SX_DEBUG(debug_expander>2,"expander: initially got %lu bytes, '%s'\n", - (unsigned long)strlen(response),response); - if(response[0]=='A') { + SX_DEBUG(debug_expander > 2, "expander: initially got %lu bytes, " + "'%s'\n", (unsigned long)strlen(response), response); + + if (response[0] == 'A') { char* eon, *c; - long togot=strtoul(response+1,&eon,10); - char *recvbuffer = malloc(togot+2); - int offset = 0; + long togot = strtoul(response+1, &eon, 10); + char *recvbuffer = malloc(togot + 2); + int offset = 0; + if (!recvbuffer) { sx_report(SX_FATAL, "Error allocating %lu bytes: %s\n", - togot+2, strerror(errno)); + togot + 2, strerror(errno)); }; - if(eon && *eon!='\n') { - sx_report(SX_ERROR,"A-code finised with wrong char '%c' (%s)\n", - *eon,response); + if (eon && *eon != '\n') { + sx_report(SX_ERROR,"A-code finised with wrong char " + "'%c' (%s)\n", *eon,response); exit(1); }; - if (off - ((eon+1)-response) > togot) { + if (off - ((eon + 1)-response) > togot) { memcpy(recvbuffer, eon+1, togot); offset = togot; - memmove(response, eon+1+togot, off - ((eon+1)-response) - togot); - off -= togot + ((eon+1)-response); - memset(response+off, 0, sizeof(response)-off); + memmove(response, eon + 1 + togot, + off - ((eon + 1) - response) - togot); + off -= togot + ((eon + 1) - response); + memset(response+off, 0, sizeof(response) - off); } else { - memcpy(recvbuffer, eon+1, off - ((eon+1)-response)); - offset = off - ((eon+1) - response); + memcpy(recvbuffer, eon + 1, + off - ((eon + 1) - response)); + offset = off - ((eon + 1) - response); memset(response, 0, sizeof(response)); off = 0; }; @@ -700,170 +809,183 @@ repeat: goto reread2; reread: - ret = bgpq_selread(b, recvbuffer+offset, togot-offset); + ret = bgpq_selread(b, recvbuffer + offset, togot - offset); if (ret == 0) { sx_report(SX_FATAL,"EOF from IRRd (expand,result)\n"); } else if (ret < 0) { - sx_report(SX_FATAL,"Error reading IRRd: %s (expand,result)\n", - strerror(errno)); + sx_report(SX_FATAL,"Error reading IRRd: %s " + "(expand,result)\n", strerror(errno)); }; offset += ret; if (offset < togot) goto reread; reread2: - ret = bgpq_selread(b, response+off, sizeof(response)-off); + ret = bgpq_selread(b, response+off, sizeof(response) - off); if (ret < 0) { - sx_report(SX_FATAL, "error reading IRRd: %s\n", strerror(errno)); + sx_report(SX_FATAL, "error reading IRRd: %s\n", + strerror(errno)); exit(1); } else if (ret == 0) { sx_report(SX_FATAL, "eof reading IRRd\n"); exit(1); }; off += ret; + have3: if (!strchr(response, '\n')) goto reread2; - SX_DEBUG(debug_expander>2,"expander: final reply of %lu bytes, " - "%.*sreturn code %.*s", - (unsigned long)strlen(recvbuffer), offset, recvbuffer, off, - response); + SX_DEBUG(debug_expander>2,"expander: final reply of %lu bytes," + " %.*sreturn code %.*s", + (unsigned long)strlen(recvbuffer), offset, recvbuffer, off, + response); - for(c=recvbuffer; cvalidate_asns) bgpq_expander_invalidate_asn(b, request); - } else if(response[0]=='D') { + if (b->validate_asns) + bgpq_expander_invalidate_asn(b, request); + } else if (response[0] == 'D') { /* ... */ - if (b->validate_asns) bgpq_expander_invalidate_asn(b, request); - } else if(response[0]=='E') { + if (b->validate_asns) + bgpq_expander_invalidate_asn(b, request); + } else if (response[0] == 'E') { /* XXXXXX */ - } else if(response[0]=='F') { + } else if (response[0] == 'F') { /* XXXXXX */ } else { sx_report(SX_ERROR,"Wrong reply: %s\n", response); exit(0); }; bgpq_request_free(req); + return 0; }; int bgpq_expand(struct bgpq_expander* b) { - int fd=-1, err, ret, aquery=0; + int fd = -1, err, ret, aquery = 0; struct sx_slentry* mc; struct addrinfo hints, *res=NULL, *rp; struct linger sl; sl.l_onoff = 1; sl.l_linger = 5; - memset(&hints,0,sizeof(struct addrinfo)); - hints.ai_socktype=SOCK_STREAM; + memset(&hints, 0, sizeof(struct addrinfo)); - err=getaddrinfo(b->server,b->port,&hints,&res); - if(err) { - sx_report(SX_ERROR,"Unable to resolve %s: %s\n", - b->server, gai_strerror(err)); + hints.ai_socktype = SOCK_STREAM; + + err=getaddrinfo(b->server, b->port, &hints, &res); + + if (err) { + sx_report(SX_ERROR,"Unable to resolve %s: %s\n", b->server, + gai_strerror(err)); exit(1); }; - for(rp=res; rp; rp=rp->ai_next) { - fd=socket(rp->ai_family,rp->ai_socktype,0); - if(fd==-1) { - if(errno==EPROTONOSUPPORT || errno==EAFNOSUPPORT) continue; + for (rp=res; rp; rp = rp->ai_next) { + fd = socket(rp->ai_family, rp->ai_socktype, 0); + if (fd == -1) { + if (errno==EPROTONOSUPPORT || errno==EAFNOSUPPORT) + continue; sx_report(SX_ERROR,"Unable to create socket: %s\n", - strerror(errno)); + strerror(errno)); exit(1); }; - if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &sl, sizeof(struct linger))) { - sx_report(SX_ERROR,"Unable to set linger on socket: %s\n", - strerror(errno)); + if (setsockopt(fd, SOL_SOCKET, SO_LINGER, &sl, + sizeof(struct linger))) { + sx_report(SX_ERROR,"Unable to set linger on socket: " + "%s\n", strerror(errno)); shutdown(fd, SHUT_RDWR); close(fd); exit(1); }; - err=connect(fd,rp->ai_addr,rp->ai_addrlen); - if(err) { - shutdown(fd,SHUT_RDWR); + err = connect(fd, rp->ai_addr, rp->ai_addrlen); + if (err) { + shutdown(fd, SHUT_RDWR); close(fd); - fd=-1; + fd = -1; continue; }; - err=sx_maxsockbuf(fd,SO_SNDBUF); - if(err>0) { - SX_DEBUG(debug_expander, "Acquired sendbuf of %i bytes\n", err); + err = sx_maxsockbuf(fd, SO_SNDBUF); + if (err > 0) { + SX_DEBUG(debug_expander, "Acquired sendbuf of %i " + "bytes\n", err); } else { shutdown(fd, SHUT_RDWR); close(fd); - fd=-1; + fd = -1; continue; }; break; }; + freeaddrinfo(res); - if(fd == -1) { + if (fd == -1) { /* all our attempts to connect failed */ sx_report(SX_ERROR,"All attempts to connect %s failed, last" - " error: %s\n", b->server, strerror(errno)); + " error: %s\n", b->server, strerror(errno)); exit(1); }; b->fd = fd; - if((ret=write(fd, "!!\n", 3))!=3) { + if ((ret = write(fd, "!!\n", 3)) != 3) { sx_report(SX_ERROR,"Partial write to IRRd: %i bytes, %s\n", - ret, strerror(errno)); + ret, strerror(errno)); exit(1); }; - if(b->identify) { + if (b->identify) { char ident[128]; - snprintf(ident,sizeof(ident),"!n" PACKAGE_STRING "\n"); + snprintf(ident, sizeof(ident), "!n" PACKAGE_STRING "\n"); write(fd, ident, strlen(ident)); read(fd, ident, sizeof(ident)); }; /* Test whether the server has support for the A query */ - if(b->generation>=T_PREFIXLIST) { + if (b->generation >= T_PREFIXLIST) { char aret[128]; char aresp[] = "F Missing required set name for A query"; SX_DEBUG(debug_expander, "Testing support for A queries\n"); write(fd, "!a\n", 3); memset(aret, 0, sizeof(aret)); read(fd, aret, sizeof(aret)); - if(strncmp(aret, aresp, strlen(aresp)) == 0) { - SX_DEBUG(debug_expander, "OK: found support for A queries\n"); - aquery=1; - } else { + if (strncmp(aret, aresp, strlen(aresp)) == 0) { + SX_DEBUG(debug_expander, "Server supports A query\n"); + aquery = 1; + } else SX_DEBUG(debug_expander, "No support for A queries\n"); - } } - if(b->sources && b->sources[0]!=0) { - int slen = strlen(b->sources)+4; + if (b->sources && b->sources[0] != 0) { + int slen = strlen(b->sources) + 4; if (slen < 128) slen = 128; char sources[slen]; - snprintf(sources,sizeof(sources),"!s%s\n", b->sources); - SX_DEBUG(debug_expander,"Requesting sources %s", sources); + snprintf(sources, sizeof(sources), "!s%s\n", b->sources); + SX_DEBUG(debug_expander, "Requesting sources %s", sources); write(fd, sources, strlen(sources)); memset(sources, 0, slen); read(fd, sources, slen); SX_DEBUG(debug_expander,"Got answer %s", sources); - if(sources[0]!='C') { - sx_report(SX_ERROR, "Invalid source(s) '%s': %s\n", b->sources, - sources); + if (sources[0] != 'C') { + sx_report(SX_ERROR, "Invalid source(s) '%s': %s\n", + b->sources, sources); exit(1); }; }; @@ -873,70 +995,71 @@ bgpq_expand(struct bgpq_expander* b) STAILQ_FOREACH(mc, &b->macroses, next) { if (!b->maxdepth && RB_EMPTY(&b->stoplist)) { - if(aquery) + if (aquery) bgpq_expand_irrd(b, bgpq_expanded_prefix, b, - (b->family == AF_INET) ? "!a4%s\n" : "!a6%s\n", + "!a%s%s\n", + b->family == AF_INET ? "4" : "6", mc->text); else - bgpq_expand_irrd(b, bgpq_expanded_macro, b, "!i%s,1\n", mc->text); + bgpq_expand_irrd(b, bgpq_expanded_macro, b, + "!i%s,1\n", mc->text); } else { bgpq_expander_add_already(b,mc->text); - if (pipelining) { - bgpq_pipeline(b, bgpq_expanded_macro_limit, NULL, "!i%s\n", - mc->text); - } else { - bgpq_expand_irrd(b, bgpq_expanded_macro_limit, NULL, "!i%s\n", - mc->text); - }; + if (pipelining) + bgpq_pipeline(b, bgpq_expanded_macro_limit, + NULL, "!i%s\n", mc->text); + else + bgpq_expand_irrd(b, bgpq_expanded_macro_limit, + NULL, "!i%s\n", mc->text); }; }; - if(pipelining) { - if(!STAILQ_EMPTY(&b->wq)) + if (pipelining) { + if (!STAILQ_EMPTY(&b->wq)) bgpq_write(b); if (!STAILQ_EMPTY(&b->rq)) bgpq_read(b); }; - if(b->generation>=T_PREFIXLIST || b->validate_asns) { + if (b->generation >= T_PREFIXLIST || b->validate_asns) { uint32_t i, j, k; STAILQ_FOREACH(mc, &b->rsets, next) { - if(b->family==AF_INET) { - bgpq_expand_irrd(b, bgpq_expanded_prefix, NULL, "!i%s,1\n", - mc->text); - } else { - bgpq_expand_irrd(b, bgpq_expanded_v6prefix, NULL, "!i%s,1\n", - mc->text); - }; + if (b->family == AF_INET) + bgpq_expand_irrd(b, bgpq_expanded_prefix, + NULL, "!i%s,1\n", mc->text); + else + bgpq_expand_irrd(b, bgpq_expanded_v6prefix, + NULL, "!i%s,1\n", mc->text); }; - for(k=0;kasn32s)/sizeof(unsigned char*);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(b->family==AF_INET6) { - if(!pipelining) { + for (k=0; k < sizeof(b->asn32s) / sizeof(unsigned char*); 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 (b->family == AF_INET6) { + if (!pipelining) { bgpq_expand_irrd(b, bgpq_expanded_v6prefix, - NULL, "!6as%" PRIu32 "\n", (k<<16)+i*8+j); + NULL, "!6as%" PRIu32 "\n", ( k << 16) + i * 8 + j); } else { bgpq_pipeline(b, bgpq_expanded_v6prefix, - NULL, "!6as%" PRIu32 "\n", (k<<16)+i*8+j); + NULL, "!6as%" PRIu32 "\n", (k << 16) + i * 8 + j); }; } else { - if(!pipelining) { + if (!pipelining) { bgpq_expand_irrd(b, bgpq_expanded_prefix, - NULL, "!gas%" PRIu32 "\n", (k<<16)+i*8+j); + NULL, "!gas%" PRIu32 "\n", (k << 16) + i * 8 + j); } else { bgpq_pipeline(b, bgpq_expanded_prefix, - NULL, "!gas%" PRIu32 "\n", (k<<16)+i*8+j); + NULL, "!gas%" PRIu32 "\n", ( k<< 16) + i* 8 + j); }; }; }; }; }; }; - if(pipelining) { - if(!STAILQ_EMPTY(&b->wq)) + if (pipelining) { + if (!STAILQ_EMPTY(&b->wq)) bgpq_write(b); if (!STAILQ_EMPTY(&b->rq)) bgpq_read(b); @@ -951,6 +1074,7 @@ bgpq_expand(struct bgpq_expander* b) }; shutdown(fd, SHUT_RDWR); close(fd); + return 1; }; diff --git a/expander_freeall.c b/expander_freeall.c index 1a8e0d2..3cdd363 100644 --- a/expander_freeall.c +++ b/expander_freeall.c @@ -1,78 +1,83 @@ #include #include - #include -void sx_radix_node_freeall(struct sx_radix_node *n) { - if (n->l != NULL) { - sx_radix_node_freeall(n->l); - } - if (n->r != NULL) { - sx_radix_node_freeall(n->r); - } - if (n->son != NULL) { - sx_radix_node_freeall(n->son); - } +void +sx_radix_node_freeall(struct sx_radix_node *n) { - if (n->payload) { - free(n->payload); - } - sx_prefix_destroy(n->prefix); - free(n); + if (n->l != NULL) + sx_radix_node_freeall(n->l); + + if (n->r != NULL) + sx_radix_node_freeall(n->r); + + if (n->son != NULL) + sx_radix_node_freeall(n->son); + + if (n->payload) + free(n->payload); + + sx_prefix_destroy(n->prefix); + + free(n); } -void sx_radix_tree_freeall(struct sx_radix_tree *t) { - if (t->head != NULL) { - sx_radix_node_freeall(t->head); - } - free(t); +void +sx_radix_tree_freeall(struct sx_radix_tree *t) { + + if (t->head != NULL) + sx_radix_node_freeall(t->head); + + free(t); } -void bgpq_prequest_freeall(struct bgpq_prequest *bpr) { - +void +bgpq_prequest_freeall(struct bgpq_prequest *bpr) { } -void expander_freeall(struct bgpq_expander *expander) { +void +expander_freeall(struct bgpq_expander *expander) { - // printf("starting to free all\n"); - // seg fault here - // if (expander->sources != NULL) { - // printf("freeing soruces\n"); - // free(expander->sources); - //} - // if (expander->name != NULL) { - // printf("freeing name\n"); - // free(expander->name); - //} - // printf("freeing asn32s\n"); - for (int i = 0; i < 65536; i++) { - if (expander->asn32s[i] != NULL) { - free(expander->asn32s[i]); - } - } - // if (expander->match != NULL) { - // printf("freeing match\n"); - // free(expander->match); - //} - //if (expander->server != NULL) { - // printf("freeing server\n"); - // free(expander->server); - //} - //if (expander->port != NULL) { - // printf("freeing port\n"); - // free(expander->port); - //} - //if (expander->format != NULL) { - // printf("freeing format\n"); - // free(expander->format); - //} + // printf("starting to free all\n"); + // seg fault here + // if (expander->sources != NULL) { + // printf("freeing soruces\n"); + // free(expander->sources); + //} + // if (expander->name != NULL) { + // printf("freeing name\n"); + // free(expander->name); + //} + // printf("freeing asn32s\n"); - sx_radix_tree_freeall(expander->tree); + for (int i = 0; i < 65536; i++) { + if (expander->asn32s[i] != NULL) { + free(expander->asn32s[i]); + } + } - bgpq_prequest_freeall(expander->firstpipe); - bgpq_prequest_freeall(expander->lastpipe); - // printf("finished freeing all\n"); - + // if (expander->match != NULL) { + // printf("freeing match\n"); + // free(expander->match); + //} + //if (expander->server != NULL) { + // printf("freeing server\n"); + // free(expander->server); + //} + //if (expander->port != NULL) { + // printf("freeing port\n"); + // free(expander->port); + //} + //if (expander->format != NULL) { + // printf("freeing format\n"); + // free(expander->format); + //} + + sx_radix_tree_freeall(expander->tree); + + bgpq_prequest_freeall(expander->firstpipe); + bgpq_prequest_freeall(expander->lastpipe); + + // printf("finished freeing all\n"); } - diff --git a/strlcpy.c b/strlcpy.c index f66dc42..a41cfe2 100644 --- a/strlcpy.c +++ b/strlcpy.c @@ -62,11 +62,11 @@ strlcpy(dst, src, siz) /* Not enough room in dst, add NUL and traverse rest of src */ if (n == 0) { if (siz != 0) - *d = '\0'; /* NUL-terminate dst */ + *d = '\0'; /* NUL-terminate dst */ while (*s++) ; } - return(s - src - 1); /* count does not include NUL */ + return(s - src - 1); /* count does not include NUL */ } #endif diff --git a/sx_maxsockbuf.c b/sx_maxsockbuf.c index d9f4f75..f9e6d78 100644 --- a/sx_maxsockbuf.c +++ b/sx_maxsockbuf.c @@ -18,66 +18,85 @@ int sx_maxsockbuf(int s, int dir) { - int optval=0, voptval; - int hiconf=-1, loconf=-1; + int optval = 0, voptval; + int hiconf = -1, loconf = -1; unsigned int voptlen; - int phase=0, iterations=0; + int phase = 0, iterations = 0; - if(s<0) { - sx_report(SX_FATAL,"Unable to maximize sockbuf on invalid socket %i\n", - s); + if (s<0) { + sx_report(SX_FATAL,"Unable to maximize sockbuf on invalid " + "socket %i\n", s); exit(1); }; + voptlen = sizeof(optval); - voptlen=sizeof(optval); - if(getsockopt(s,SOL_SOCKET,dir,(void*)&optval,&voptlen)==-1) { - sx_report(SX_ERROR,"initial getsockopt failed: %s\n", strerror(errno)); + if (getsockopt(s, SOL_SOCKET, dir, (void*)&optval, &voptlen) == -1) { + sx_report(SX_ERROR,"initial getsockopt failed: %s\n", + strerror(errno)); return -1; }; - for(;;) { + for (;;) { iterations++; - if(phase==0) optval<<=1; + + if (phase == 0) + optval<<=1; else { - if(optval==(hiconf+loconf)/2) break; - optval=(hiconf+loconf)/2; + if (optval == (hiconf + loconf) / 2) + break; + optval = (hiconf + loconf) / 2; }; - if(optval>SX_MAXSOCKBUF_MAX && phase==0) + + if (optval > SX_MAXSOCKBUF_MAX && phase == 0) break; - if(setsockopt(s,SOL_SOCKET,dir,(void*)&optval,sizeof(optval))==-1) - { - if(phase==0) phase=1; - hiconf=optval; + if (setsockopt(s, SOL_SOCKET, dir, (void*)&optval, + sizeof(optval)) == -1) { + + if (phase == 0) + phase = 1; + + hiconf = optval; + continue; } else { - loconf=optval; + loconf = optval; }; - voptlen=sizeof(voptval); + voptlen = sizeof(voptval); - if(getsockopt(s,SOL_SOCKET,dir,(void*)&voptval,&voptlen)==-1) { - sx_report(SX_ERROR,"getsockopt failed: %s\n", strerror(errno)); + if (getsockopt(s, SOL_SOCKET, dir, (void*)&voptval, + &voptlen) == -1) { + sx_report(SX_ERROR,"getsockopt failed: %s\n", + strerror(errno)); return -1; - } else if(voptval>=1; continue; - } else if(phase==1) { - phase=2; optval-=2048; continue; - } else break; - } else if(voptval>=SX_MAXSOCKBUF_MAX) { - /* ... and getsockopt not failed and voptval>=optval. Do not allow - * to increase sockbuf too much even in case OS permits it */ + } else if (voptval < optval) { + if (phase == 0) { + phase = 1; + optval >>= 1; + continue; + } else if (phase == 1) { + phase = 2; + optval -= 2048; + continue; + } else + break; + } else if (voptval >= SX_MAXSOCKBUF_MAX) { + /* + * ... and getsockopt not failed and voptval>=optval. + * Do not allow to increase sockbuf too much even in + * case OS permits it + */ break; }; }; - - voptlen=sizeof(voptval); - if(getsockopt(s,SOL_SOCKET,dir,(void*)&voptval,&voptlen)==-1) { + voptlen = sizeof(voptval); + if (getsockopt(s, SOL_SOCKET, dir, (void*)&voptval, + &voptlen) == -1) { sx_report(SX_ERROR,"getsockopt(final stage) failed: %s\n", - strerror(errno)); + strerror(errno)); return -1; } else { /* @@ -85,5 +104,6 @@ sx_maxsockbuf(int s, int dir) voptval, iterations); */ }; + return voptval; }; diff --git a/sx_prefix.c b/sx_prefix.c index c56587d..85a8fa3 100644 --- a/sx_prefix.c +++ b/sx_prefix.c @@ -18,42 +18,55 @@ extern int debug_expander; struct sx_prefix* sx_prefix_alloc(struct sx_prefix* p) { - struct sx_prefix* sp=malloc(sizeof(struct sx_prefix)); - if(!sp) return NULL; - if(p) { - memcpy(sp, p, sizeof(struct sx_prefix)); - } else { - memset(sp,0,sizeof(struct sx_prefix)); - }; + struct sx_prefix* sp = malloc(sizeof(struct sx_prefix)); + + if (!sp) + return NULL; + + if (p) + memcpy(sp, p, sizeof(struct sx_prefix)); + else + memset(sp, 0, sizeof(struct sx_prefix)); + return sp; }; + void sx_prefix_destroy(struct sx_prefix* p) { - if(p) free(p); + if (p) + free(p); }; void sx_radix_node_destroy(struct sx_radix_node *n) { - if (n) { - if (n->payload) free(n->payload); - if (n->prefix) free(n->prefix); - free(n); - } + if (n) { + if (n->payload) + free(n->payload); + + if (n->prefix) + free(n->prefix); + + free(n); + } }; void sx_prefix_adjust_masklen(struct sx_prefix* p) { - int nbytes=(p->family==AF_INET?4:16); + int nbytes = (p->family == AF_INET ? 4 : 16); int i; - if(p->masklen==nbytes*8) return ; /* mask is all ones */ - for(i=nbytes-1;i>p->masklen/8;i--) { + + if (p->masklen == nbytes * 8) + return; /* mask is all ones */ + + for (i = nbytes -1; i > p->masklen / 8; i--) { p->addr.addrs[i]=0; }; - for(i=1;i<=8-p->masklen%8;i++) { - p->addr.addrs[p->masklen/8]&=(0xff<masklen % 8; i++) { + p->addr.addrs[p->masklen / 8] &= (0xff << i); }; }; @@ -61,106 +74,130 @@ void sx_prefix_mask(struct sx_prefix* p, struct sx_prefix* q) { int i; + memset(q->addr.addrs, 0, sizeof(q->addr.addrs)); - q->family=p->family; - q->masklen=p->masklen; - for(i=0;imasklen/8;i++) - q->addr.addrs[i]=0xff; - for(i=1;i<=p->masklen%8;i++) - q->addr.addrs[p->masklen/8]|=(1<<(8-i)); + + q->family = p->family; + q->masklen = p->masklen; + + for (i = 0; i < p->masklen / 8; i++) + q->addr.addrs[i] = 0xff; + + for (i = 1; i <= p->masklen % 8; i++) + q->addr.addrs[p->masklen / 8] |= (1 << (8 - i)); }; void sx_prefix_imask(struct sx_prefix* p, struct sx_prefix* q) { int i; + memset(q->addr.addrs, 0xff, sizeof(q->addr.addrs)); - q->family=p->family; - q->masklen=p->masklen; - for(i=0;imasklen/8;i++) - q->addr.addrs[i]=0; - for(i=1;i<=p->masklen%8;i++) - q->addr.addrs[p->masklen/8]&=~(1<<(8-i)); + + q->family = p->family; + q->masklen = p->masklen; + + for (i = 0; i < p->masklen / 8; i++) + q->addr.addrs[i] = 0; + + for (i = 1;i <= p->masklen % 8; i++) + q->addr.addrs[p->masklen / 8] &= ~(1 <<(8 - i)); }; int sx_prefix_parse(struct sx_prefix* p, int af, char* text) { - char* c=NULL; + char* c = NULL; int masklen, ret; char mtext[INET6_ADDRSTRLEN+5]; + strlcpy(mtext, text, sizeof(mtext)); - c=strchr(mtext,'/'); - if(c) { + c = strchr(mtext,'/'); + + if (c) { char* eod; - *c=0; - masklen=strtol(c+1,&eod,10); - if(eod && eod[0] && !isspace(eod[0])) { - *c='/'; - sx_report(SX_ERROR,"Invalid masklen in prefix %s\n", text); + *c = 0; + masklen = strtol(c+1, &eod, 10); + if (eod && eod[0] && !isspace(eod[0])) { + *c = '/'; + sx_report(SX_ERROR, "Invalid masklen in prefix %s\n", + text); goto fixups; }; } else { - masklen=-1; + masklen = -1; }; - if(!af) { - if(strchr(mtext,':')) af=AF_INET6; + if (!af) { + if (strchr(mtext, ':')) + af = AF_INET6; else - af=AF_INET; + af = AF_INET; }; ret = inet_pton(af, mtext, &p->addr); - if(ret != 1) { + + if (ret != 1) { int aparts[4]; - /* contrary to documentation (man inet_ntop on FreeBSD), - addresses with leading zeros are not parsed correctly. Try to - workaround this issue manually */ - if (af==AF_INET && sscanf(mtext, "%i.%i.%i.%i", aparts, - aparts+1, aparts+2, aparts+3) == 4 && aparts[0]>=0 && - aparts[0]<256 && aparts[1]>=0 && aparts[1]<256 && - aparts[2]>=0 && aparts[2]<256 && aparts[3]>=0 && - aparts[3]<256) { - p->addr.addr.s_addr = htonl((aparts[0]<<24) + - (aparts[1]<<16) + (aparts[2]<<8) + aparts[3]); + /* + * contrary to documentation (man inet_ntop on FreeBSD), + * addresses with leading zeros are not parsed correctly. Try + * to workaround this issue manually. + */ + if (af == AF_INET && sscanf(mtext, "%i.%i.%i.%i", aparts, + aparts + 1, aparts + 2, aparts + 3) == 4 + && aparts[0] >= 0 && aparts[0] < 256 + && aparts[1] >= 0 && aparts[1] < 256 + && aparts[2] >= 0 && aparts[2] < 256 + && aparts[3] >= 0 && aparts[3] < 256) { + p->addr.addr.s_addr = htonl((aparts[0] << 24) + + (aparts[1] << 16) + (aparts[2] << 8) + aparts[3]); } else { - if(c) *c='/'; - sx_report(SX_ERROR,"Unable to parse prefix '%s', af=%i (%s), " - "ret=%i\n", mtext, af, af==AF_INET ? "inet" : "inet6", ret); + if (c) + *c = '/'; + + sx_report(SX_ERROR,"Unable to parse prefix '%s', af=%i" + " (%s), ret=%i\n", mtext, af, + af == AF_INET ? "inet" : "inet6", ret); goto fixups; }; }; - if(af==AF_INET) { - if(masklen==-1) p->masklen=32; + if (af == AF_INET) { + if (masklen == -1) + p->masklen = 32; else { - if(masklen<0 || masklen>32) { - p->masklen=32; + if(masklen < 0 || masklen > 32) { + p->masklen = 32; } else { - p->masklen=masklen; + p->masklen = masklen; }; }; - } else if(af==AF_INET6) { - if(masklen==-1) p->masklen=128; + } else if (af == AF_INET6) { + if (masklen == -1) + p->masklen = 128; else { - if(masklen<0 || masklen>128) { - p->masklen=128; + if (masklen < 0 || masklen > 128) { + p->masklen = 128; } else { - p->masklen=masklen; + p->masklen = masklen; }; }; } else { - sx_report(SX_ERROR,"Invalid address family %i\n", af); + sx_report(SX_ERROR, "Invalid address family %i\n", af); goto fixups; }; - p->family=af; + p->family = af; sx_prefix_adjust_masklen(p); - if(c) *c='/'; + + if (c) + *c = '/'; return 1; + fixups: return 0; }; @@ -169,131 +206,158 @@ int sx_prefix_isbitset(struct sx_prefix* p, int n) { unsigned char s; + /* bits outside the prefix considered unset */ - if(p->family==AF_INET && (n<0 || n>32)) return 0; - else if(p->family==AF_INET6 && (n<0 || n>128)) return 0; - s=p->addr.addrs[(n-1)/8]; - return (s&(0x80>>((n-1)%8)))?1:0; + if (p->family == AF_INET && (n < 0 || n > 32)) + return 0; + else if (p->family == AF_INET6 && (n < 0 || n > 128)) + return 0; + s = p->addr.addrs[(n - 1) / 8]; + + return (s & (0x80 >> ((n - 1) % 8))) ? 1 : 0; }; void sx_prefix_setbit(struct sx_prefix* p, int n) { unsigned char* s; - if (p->family == AF_INET && (n<0 || n>32)) return; - else if (p->family == AF_INET6 && (n<0 || n>128)) return; - s=p->addr.addrs+(n-1)/8; - (*s)|=0x80>>((n-1)%8); + + if (p->family == AF_INET && (n < 0 || n > 32)) + return; + else if (p->family == AF_INET6 && (n < 0 || n > 128)) + return; + + s = p->addr.addrs + (n - 1) / 8; + + (*s) |= 0x80 >> ((n - 1) % 8); }; int sx_radix_tree_insert_specifics(struct sx_radix_tree* t, struct sx_prefix *p, - unsigned min, unsigned max) + unsigned min, unsigned max) { - struct sx_prefix *np; - np = sx_prefix_alloc(p); + struct sx_prefix *np; + np = sx_prefix_alloc(p); - if (np->masklen >= min) { - struct sx_radix_node *nn = sx_radix_tree_insert(t, np); - sx_prefix_destroy(np); - np = nn->prefix; - } - if (np->masklen+1 > max) - return 1; - np->masklen+=1; - sx_radix_tree_insert_specifics(t, np, min, max); - sx_prefix_setbit(np, np->masklen); - sx_radix_tree_insert_specifics(t, np, min, max); - return 1; + if (np->masklen >= min) { + struct sx_radix_node *nn = sx_radix_tree_insert(t, np); + sx_prefix_destroy(np); + np = nn->prefix; + } + + if (np->masklen + 1 > max) + return 1; + + np->masklen += 1; + sx_radix_tree_insert_specifics(t, np, min, max); + sx_prefix_setbit(np, np->masklen); + sx_radix_tree_insert_specifics(t, np, min, max); + + return 1; }; int sx_prefix_range_parse(struct sx_radix_tree* tree, int af, int maxlen, - char* text) + char* text) { - char* d=strchr(text, '^'); + char* d = strchr(text, '^'); struct sx_prefix *p; unsigned long min, max; p = sx_prefix_alloc(NULL); - if (!d || !d[1]) return 0; + if (!d || !d[1]) + return 0; + *d = 0; if (!sx_prefix_parse(p, 0, text)) { - sx_report(SX_ERROR, "Unable to parse prefix %s^%s\n", text, d+1); + sx_report(SX_ERROR, "Unable to parse prefix %s^%s\n", text, + d+1); return 0; }; + *d = '^'; if (af && p->family != af) { sx_report(SX_ERROR, "Ignoring prefix %s, wrong af %i\n", text, - p->family); + p->family); return 0; }; if (maxlen && p->masklen > maxlen) { - SX_DEBUG(debug_expander, "Ignoring prefix %s, masklen %i > max " - "masklen %u\n", text, p->masklen, maxlen); + SX_DEBUG(debug_expander, "Ignoring prefix %s, masklen %i > max" + " masklen %u\n", text, p->masklen, maxlen); return 0; }; if (d[1] == '-') { - min=p->masklen+1; - max=maxlen; + min = p->masklen + 1; + max = maxlen; } else if (d[1] == '+') { - min=p->masklen; - max=maxlen; + min = p->masklen; + max = maxlen; } else if (isdigit(d[1])) { char* dm = NULL; min = strtoul(d+1, &dm, 10); if (dm && *dm == '-' && isdigit(dm[1])) { - max = strtoul(dm+1, NULL, 10); + max = strtoul(dm + 1, NULL, 10); } else if (dm && *dm) { - sx_report(SX_ERROR, "Unable to parse prefix-range %s\n", text); + sx_report(SX_ERROR, "Unable to parse prefix-range " + "%s\n", text); return 0; }; } else { sx_report(SX_ERROR, "Invalid prefix-range %s\n", text); return 0; }; + if (min < p->masklen) { - sx_report(SX_ERROR, "Invalid prefix-range %s: min %lu < masklen %u\n", - text, min, p->masklen); + sx_report(SX_ERROR, "Invalid prefix-range %s: min %lu < " + "masklen %u\n", text, min, p->masklen); return 0; }; + if (af == AF_INET && max > 32) { - sx_report(SX_ERROR, "Invalid prefix-range %s: max %lu > 32\n", - text, max); + sx_report(SX_ERROR, "Invalid prefix-range %s: max %lu > " + "32\n", text, max); return 0; } else if (af == AF_INET6 && max > 128) { - sx_report(SX_ERROR, "Invalid ipv6 prefix-range %s: max %lu > 128\n", - text, max); + sx_report(SX_ERROR, "Invalid ipv6 prefix-range %s: max %lu > " + "128\n", text, max); return 0; }; + if (max > maxlen) max = maxlen; - SX_DEBUG(debug_expander, "parsed prefix-range %s as %lu-%lu (maxlen: %u)\n", - text, min, max, maxlen); + + SX_DEBUG(debug_expander, "parsed prefix-range %s as %lu-%lu (maxlen: " + "%u)\n", text, min, max, maxlen); + sx_radix_tree_insert_specifics(tree, p, min, max); + return 1; }; struct sx_prefix* sx_prefix_new(int af, char* text) { - struct sx_prefix* p=NULL; + struct sx_prefix* p = NULL; - if(!text) return NULL; + if (!text) + return NULL; - p=sx_prefix_alloc(NULL); + p = sx_prefix_alloc(NULL); - if(!p) return NULL; - if(!sx_prefix_parse(p,af,text)) { + if (!p) + return NULL; + + if (!sx_prefix_parse(p, af, text)) { sx_prefix_destroy(p); return NULL; }; + return p; }; @@ -301,25 +365,32 @@ int sx_prefix_fprint(FILE* f, struct sx_prefix* p) { char buffer[128]; - if(!p) { + + if (!p) { fprintf(f?f:stdout,"(null)"); return 0; }; - inet_ntop(p->family,&p->addr,buffer,sizeof(buffer)); - return fprintf(f?f:stdout,"%s/%i",buffer,p->masklen); + + inet_ntop(p->family, &p->addr, buffer, sizeof(buffer)); + return fprintf( f ? f : stdout, "%s/%i", buffer, p->masklen); }; int sx_prefix_snprintf_sep(struct sx_prefix* p, char* rbuffer, int srb, char* sep) { char buffer[128]; - if(!sep) sep="/"; - if(!p) { - snprintf(rbuffer,srb,"(null)"); + + if (!sep) + sep="/"; + + if (!p) { + snprintf(rbuffer, srb, "(null)"); return 0; }; - inet_ntop(p->family,&p->addr,buffer,sizeof(buffer)); - return snprintf(rbuffer,srb,"%s%s%i",buffer,sep,p->masklen); + + inet_ntop(p->family, &p->addr, buffer, sizeof(buffer)); + + return snprintf(rbuffer, srb, "%s%s%i", buffer, sep, p->masklen); }; int @@ -330,61 +401,71 @@ sx_prefix_snprintf(struct sx_prefix* p, char* rbuffer, int srb) int sx_prefix_snprintf_fmt(struct sx_prefix* p, char* buffer, int size, - const char* name, const char* format) + const char* name, const char* format) { - unsigned off=0; - const char* c=format; + unsigned off = 0; + const char* c = format; struct sx_prefix *q = sx_prefix_alloc(NULL); - while(*c) { - if(*c=='%') { - switch(*(c+1)) { - case 'r': - case 'n': - inet_ntop(p->family,&p->addr,buffer+off,size-off); - off=strlen(buffer); - break; - case 'l': - off+=snprintf(buffer+off,size-off,"%i",p->masklen); - break; - case '%': - buffer[off++]='%'; - break; - case 'N': - off+=snprintf(buffer+off,size-off,"%s",name); - break; - case 'm': - sx_prefix_mask(p, q); - inet_ntop(p->family,&q->addr,buffer+off,size-off); - off=strlen(buffer); - break; - case 'i': - sx_prefix_imask(p, q); - inet_ntop(p->family,&q->addr,buffer+off,size-off); - off=strlen(buffer); - break; - default : - sx_report(SX_ERROR, "Unknown format char '%c'\n", *(c+1)); - return 0; + + while (*c) { + if(*c == '%') { + switch (*(c + 1)) { + case 'r': + case 'n': + inet_ntop(p->family, &p->addr, buffer+off, size-off); + off = strlen(buffer); + break; + case 'l': + off += snprintf(buffer + off, size - off, + "%i", p->masklen); + break; + case '%': + buffer[off++] = '%'; + break; + case 'N': + off += snprintf(buffer + off, size - off, + "%s", name); + break; + case 'm': + sx_prefix_mask(p, q); + inet_ntop(p->family, &q->addr, buffer + off, + size - off); + off = strlen(buffer); + break; + case 'i': + sx_prefix_imask(p, q); + inet_ntop(p->family, &q->addr, buffer + off, + size - off); + off = strlen(buffer); + break; + default : + sx_report(SX_ERROR, "Unknown format char " + "'%c'\n", *(c + 1)); + return 0; }; - c+=2; - } else if (*c=='\\') { + c += 2; + } else if (*c == '\\') { switch(*(c+1)) { - case 'n': - buffer[off++]='\n'; break; - case 't': - buffer[off++]='\t'; break; - case '\\': - buffer[off++]='\\'; break; - default: - buffer[off++]=*(c+1); - break; + case 'n': + buffer[off++] = '\n'; + break; + case 't': + buffer[off++] = '\t'; + break; + case '\\': + buffer[off++] = '\\'; + break; + default: + buffer[off++] = *(c + 1); + break; }; - c+=2; + c += 2; } else { - buffer[off++]=*c; + buffer[off++] = *c; c++; }; }; + return strlen(buffer); }; @@ -392,23 +473,27 @@ int sx_prefix_jsnprintf(struct sx_prefix* p, char* rbuffer, int srb) { char buffer[128]; - if(!p) { - snprintf(rbuffer,srb,"(null)"); + + if (!p) { + snprintf(rbuffer, srb, "(null)"); return 0; }; - inet_ntop(p->family,&p->addr,buffer,sizeof(buffer)); - return snprintf(rbuffer,srb,"%s\\/%i",buffer,p->masklen); + inet_ntop(p->family, &p->addr, buffer, sizeof(buffer)); + + return snprintf(rbuffer, srb, "%s\\/%i", buffer, p->masklen); }; struct sx_radix_tree* sx_radix_tree_new(int af) { - struct sx_radix_tree* rt=malloc(sizeof(struct sx_radix_tree)); - if(!rt) { + struct sx_radix_tree* rt = malloc(sizeof(struct sx_radix_tree)); + + if (!rt) return NULL; - }; - memset(rt,0,sizeof(struct sx_radix_tree)); - rt->family=af; + + memset(rt, 0, sizeof(struct sx_radix_tree)); + rt->family = af; + return rt; }; @@ -421,12 +506,16 @@ sx_radix_tree_empty(struct sx_radix_tree* t) struct sx_radix_node* sx_radix_node_new(struct sx_prefix* prefix) { - struct sx_radix_node* rn=malloc(sizeof(struct sx_radix_node)); - if(!rn) return NULL; - memset(rn,0,sizeof(struct sx_radix_node)); - if(prefix) { - rn->prefix = sx_prefix_alloc(prefix); - }; + struct sx_radix_node* rn = malloc(sizeof(struct sx_radix_node)); + + if (!rn) + return NULL; + + memset(rn, 0, sizeof(struct sx_radix_node)); + + if (prefix) + rn->prefix = sx_prefix_alloc(prefix); + return rn; }; @@ -434,27 +523,36 @@ int sx_prefix_eqbits(struct sx_prefix* a, struct sx_prefix* b) { int i; - int nbytes=(a->family==AF_INET?4:16); - for(i=0;iaddr.addrs[i]==b->addr.addrs[i]) continue; + int nbytes = (a->family == AF_INET ? 4 : 16); + + for (i = 0; i < nbytes; i++) { + + if (a->addr.addrs[i] == b->addr.addrs[i]) + continue; else { int j; - for(j=0;j<8 && i*8+j<=a->masklen && i*8+j<=b->masklen;j++) { - if((a->addr.addrs[i]&(0x80>>j))!=(b->addr.addrs[i]&(0x80>>j))) - return i*8+j; + for (j = 0; j < 8 && i * 8 + j <= a->masklen + && i * 8 + j<= b->masklen; j++) { + if ((a->addr.addrs[i] & (0x80 >> j)) + != (b->addr.addrs[i] & (0x80 >> j))) + return i * 8 + j; }; }; }; - if(a->masklenmasklen) return a->masklen; + + if (a->masklen < b->masklen) + return a->masklen; + return b->masklen; }; struct sx_prefix* sx_prefix_overlay(struct sx_prefix* p, int n) { - struct sx_prefix* sp=sx_prefix_alloc(p); - sp->masklen=n; + struct sx_prefix* sp = sx_prefix_alloc(p); + sp->masklen = n; sx_prefix_adjust_masklen(sp); + return sp; }; @@ -462,34 +560,35 @@ void sx_radix_tree_unlink(struct sx_radix_tree* tree, struct sx_radix_node* node) { next: - if(node->r && node->l) { - node->isGlue=1; - } else if(node->r) { - if(node->parent) { - if(node->parent->r==node) { - node->parent->r=node->r; - node->r->parent=node->parent; - } else if(node->parent->l==node) { - node->parent->l=node->r; - node->r->parent=node->parent; + if (node->r && node->l) + node->isGlue = 1; + else if (node->r) { + if (node->parent) { + if (node->parent->r == node) { + node->parent->r = node->r; + node->r->parent = node->parent; + } else if (node->parent->l == node) { + node->parent->l = node->r; + node->r->parent = node->parent; } else { - sx_report(SX_ERROR,"Unlinking node which is not descendant " - "of its parent\n"); + sx_report(SX_ERROR,"Unlinking node which is " + "not descendant of its parent\n"); }; - } else if(tree->head==node) { + } else if (tree->head == node) { /* only one case, really */ - tree->head=node->r; - node->r->parent=NULL; + tree->head = node->r; + node->r->parent = NULL; } else { - sx_report(SX_ERROR,"Unlinking node with no parent and not root\n"); + sx_report(SX_ERROR,"Unlinking node with no parent and" + " not root\n"); }; sx_radix_node_destroy(node); return; - } else if(node->l) { - if(node->parent) { - if(node->parent->r==node) { - node->parent->r=node->l; - node->l->parent=node->parent; + } else if (node->l) { + if (node->parent) { + if (node->parent->r == node) { + node->parent->r = node->l; + node->l->parent = node->parent; } else if(node->parent->l==node) { node->parent->l=node->l; node->l->parent=node->parent; @@ -507,21 +606,25 @@ next: return; } else { /* the only case - node does not have descendants */ - if(node->parent) { - if(node->parent->l==node) node->parent->l=NULL; - else if(node->parent->r==node) node->parent->r=NULL; + if (node->parent) { + if(node->parent->l == node) + node->parent->l = NULL; + else if (node->parent->r == node) + node->parent->r=NULL; else { - sx_report(SX_ERROR,"Unlinking node which is not descendant " - "of its parent\n"); + sx_report(SX_ERROR,"Unlinking node which is " + "not descendant of its parent\n"); }; - if(node->parent->isGlue) { - node=node->parent; + + if (node->parent->isGlue) { + node = node->parent; goto next; }; - } else if(tree->head==node) { - tree->head=NULL; + } else if (tree->head==node) { + tree->head = NULL; } else { - sx_report(SX_ERROR,"Unlinking node with no parent and not root\n"); + sx_report(SX_ERROR, "Unlinking node with no parent and" + " not root\n"); }; sx_radix_node_destroy(node); return; @@ -533,53 +636,61 @@ struct sx_radix_node* sx_radix_tree_lookup(struct sx_radix_tree* tree, struct sx_prefix* prefix) { int eb; - struct sx_radix_node* candidate=NULL, *chead; + struct sx_radix_node* candidate = NULL, *chead; - if(!tree || !prefix) return NULL; - if(tree->family!=prefix->family) return NULL; - if(!tree->head) return NULL; + if (!tree || !prefix) + return NULL; - chead=tree->head; + if (tree->family!=prefix->family) + return NULL; + + if (!tree->head) + return NULL; + + chead = tree->head; next: - eb=sx_prefix_eqbits(chead->prefix,prefix); - if(eb==chead->prefix->masklen && eb==prefix->masklen) { + eb = sx_prefix_eqbits(chead->prefix, prefix); + if (eb == chead->prefix->masklen && eb == prefix->masklen) { /* they are equal */ - if(chead->isGlue) return candidate; + if (chead->isGlue) + return candidate; return chead; - } else if(ebprefix->masklen) { + } else if (eb < chead->prefix->masklen) { return candidate; - } else if(ebmasklen) { + } else if (eb < prefix->masklen) { /* it equals chead->masklen */ - if(sx_prefix_isbitset(prefix,eb+1)) { - if(chead->r) { - if(!chead->isGlue) { - candidate=chead; + if (sx_prefix_isbitset(prefix, eb + 1)) { + if (chead->r) { + if (!chead->isGlue) { + candidate = chead; }; - chead=chead->r; + chead = chead->r; goto next; } else { - if(chead->isGlue) return candidate; + if (chead->isGlue) + return candidate; return chead; }; } else { - if(chead->l) { - if(!chead->isGlue) { - candidate=chead; + if (chead->l) { + if (!chead->isGlue) { + candidate = chead; }; - chead=chead->l; + chead = chead->l; goto next; } else { - if(chead->isGlue) return candidate; + if (chead->isGlue) + return candidate; return chead; }; }; } else { char pbuffer[128], cbuffer[128]; - sx_prefix_snprintf(prefix,pbuffer,sizeof(pbuffer)); - sx_prefix_snprintf(chead->prefix,cbuffer,sizeof(cbuffer)); - printf("Unreachible point... eb=%i, prefix=%s, chead=%s\n", eb, - pbuffer, cbuffer); + sx_prefix_snprintf(prefix, pbuffer, sizeof(pbuffer)); + sx_prefix_snprintf(chead->prefix, cbuffer, sizeof(cbuffer)); + printf("Unreachible point... eb=%i, prefix=%s, chead=%s\n", + eb, pbuffer, cbuffer); abort(); }; }; @@ -591,90 +702,96 @@ sx_radix_tree_insert(struct sx_radix_tree* tree, struct sx_prefix* prefix) int eb; struct sx_radix_node** candidate=NULL, *chead; - if(!tree || !prefix) return NULL; - if(tree->family!=prefix->family) { + if (!tree || !prefix) return NULL; - }; - if(!tree->head) { + + if (tree->family!=prefix->family) + return NULL; + + if (!tree->head) { tree->head=sx_radix_node_new(prefix); return tree->head; }; - candidate=&tree->head; - chead=tree->head; + + candidate = &tree->head; + chead = tree->head; next: - eb=sx_prefix_eqbits(prefix,chead->prefix); - if(ebmasklen && ebprefix->masklen) { + eb = sx_prefix_eqbits(prefix, chead->prefix); + if (eb < prefix->masklen && eb < chead->prefix->masklen) { struct sx_prefix *neoRoot = sx_prefix_alloc(prefix); struct sx_radix_node* rn, *ret=sx_radix_node_new(prefix); - neoRoot->masklen=eb; + neoRoot->masklen = eb; sx_prefix_adjust_masklen(neoRoot); rn=sx_radix_node_new(neoRoot); sx_prefix_destroy(neoRoot); neoRoot = rn->prefix; - if(!rn) { - sx_report(SX_ERROR,"Unable to create node: %s\n", strerror(errno)); + if (!rn) { + sx_report(SX_ERROR,"Unable to create node: %s\n", + strerror(errno)); return NULL; }; - if(sx_prefix_isbitset(prefix,eb+1)) { - rn->l=chead; - rn->r=ret; + + if (sx_prefix_isbitset(prefix, eb + 1)) { + rn->l = chead; + rn->r = ret; } else { - rn->l=ret; - rn->r=chead; + rn->l = ret; + rn->r = chead; }; - rn->parent=chead->parent; - chead->parent=rn; - ret->parent=rn; - rn->isGlue=1; - *candidate=rn; + + rn->parent = chead->parent; + chead->parent = rn; + ret->parent = rn; + rn->isGlue = 1; + *candidate = rn; return ret; - } else if(eb==prefix->masklen && ebprefix->masklen) { - struct sx_radix_node* ret=sx_radix_node_new(prefix); - if(sx_prefix_isbitset(chead->prefix,eb+1)) { - ret->r=chead; + } else if (eb == prefix->masklen && eb < chead->prefix->masklen) { + struct sx_radix_node* ret = sx_radix_node_new(prefix); + if (sx_prefix_isbitset(chead->prefix, eb + 1)) { + ret->r = chead; } else { - ret->l=chead; + ret->l = chead; }; - ret->parent=chead->parent; - chead->parent=ret; - *candidate=ret; + ret->parent = chead->parent; + chead->parent = ret; + *candidate = ret; return ret; - } else if(eb==chead->prefix->masklen && ebmasklen) { - if(sx_prefix_isbitset(prefix,eb+1)) { - if(chead->r) { - candidate=&chead->r; - chead=chead->r; + } else if (eb == chead->prefix->masklen && eb < prefix->masklen) { + if (sx_prefix_isbitset(prefix, eb + 1)) { + if (chead->r) { + candidate = &chead->r; + chead = chead->r; goto next; } else { - chead->r=sx_radix_node_new(prefix); - chead->r->parent=chead; + chead->r = sx_radix_node_new(prefix); + chead->r->parent = chead; return chead->r; }; } else { - if(chead->l) { - candidate=&chead->l; - chead=chead->l; + if (chead->l) { + candidate = &chead->l; + chead = chead->l; goto next; } else { - chead->l=sx_radix_node_new(prefix); - chead->l->parent=chead; + chead->l = sx_radix_node_new(prefix); + chead->l->parent = chead; return chead->l; }; }; - } else if(eb==chead->prefix->masklen && eb==prefix->masklen) { + } else if (eb == chead->prefix->masklen && eb == prefix->masklen) { /* equal routes... */ - if(chead->isGlue) { - chead->isGlue=0; + if (chead->isGlue) { + chead->isGlue = 0; }; return chead; } else { char pbuffer[128], cbuffer[128]; - sx_prefix_snprintf(prefix,pbuffer,sizeof(pbuffer)); - sx_prefix_snprintf(chead->prefix,cbuffer,sizeof(cbuffer)); + sx_prefix_snprintf(prefix, pbuffer, sizeof(pbuffer)); + sx_prefix_snprintf(chead->prefix, cbuffer, sizeof(cbuffer)); printf("Unreachible point... eb=%i, prefix=%s, chead=%s\n", eb, - pbuffer, cbuffer); + pbuffer, cbuffer); abort(); }; } @@ -682,23 +799,28 @@ next: void sx_radix_node_fprintf(struct sx_radix_node* node, void* udata) { - FILE* out=(udata?udata:stdout); + FILE* out = (udata?udata:stdout); char buffer[128]; - if(!node) { - fprintf(out,"(null)\n"); + if (!node) { + fprintf(out, "(null)\n"); } else { - sx_prefix_snprintf(node->prefix,buffer,sizeof(buffer)); - fprintf(out,"%s %s\n", buffer, node->isGlue?"(glue)":""); + sx_prefix_snprintf(node->prefix, buffer, sizeof(buffer)); + fprintf(out, "%s %s\n", buffer, node->isGlue ? "(glue)" : ""); }; }; int sx_radix_node_foreach(struct sx_radix_node* node, - void (*func)(struct sx_radix_node*, void*), void* udata) + void (*func)(struct sx_radix_node*, void*), void* udata) { func(node,udata); - if(node->l) sx_radix_node_foreach(node->l,func,udata); - if(node->r) sx_radix_node_foreach(node->r,func,udata); + + if (node->l) + sx_radix_node_foreach(node->l, func, udata); + + if (node->r) + sx_radix_node_foreach(node->r, func, udata); + return 0; }; @@ -725,203 +847,218 @@ sx_radix_node_aggregate(struct sx_radix_node* node) printf(" %s%s%u,%u\n", node->isGlue?"Glue ":"", node->isAggregate?"Aggregate ":"",node->aggregateLow, node->aggregateHi); - if(node->r) { + if (node->r) { printf("R-Tree: "); - sx_prefix_fprint(stdout,node->r->prefix); - printf(" %s%s%u,%u\n", (node->r->isGlue)?"Glue ":"", - (node->r->isAggregate)?"Aggregate ":"", - node->r->aggregateLow,node->r->aggregateHi); - if(node->r->son) { - printf("R-Son: "); - sx_prefix_fprint(stdout,node->r->son->prefix); - printf(" %s%s%u,%u\n",node->r->son->isGlue?"Glue ":"", - node->r->son->isAggregate?"Aggregate ":"", - node->r->son->aggregateLow,node->r->son->aggregateHi); + sx_prefix_fprint(stdout, node->r->prefix); + printf(" %s%s%u,%u\n", + (node->r->isGlue) ? "Glue " : "", + (node->r->isAggregate) ? " Aggregate ": "", + node->r->aggregateLow, node->r->aggregateHi); + if (node->r->son) { + printf("R-Son: "); + sx_prefix_fprint(stdout, node->r->son->prefix); + printf(" %s%s%u,%u\n", + node->r->son->isGlue ? "Glue " : "", + node->r->son->isAggregate ? "Aggregate " : "", + node->r->son->aggregateLow, + node->r->son->aggregateHi); }; }; - if(node->l) { + if (node->l) { printf("L-Tree: "); - sx_prefix_fprint(stdout,node->l->prefix); - printf(" %s%s%u,%u\n",node->l->isGlue?"Glue ":"", - node->l->isAggregate?"Aggregate ":"", - node->l->aggregateLow,node->l->aggregateHi); - if(node->l->son) { - printf("L-Son: "); - sx_prefix_fprint(stdout,node->l->son->prefix); - printf(" %s%s%u,%u\n",node->l->son->isGlue?"Glue ":"", - node->l->son->isAggregate?"Aggregate ":"", - node->l->son->aggregateLow,node->l->son->aggregateHi); + sx_prefix_fprint(stdout, node->l->prefix); + printf(" %s%s%u,%u\n", node->l->isGlue ? "Glue ": "", + node->l->isAggregate ? "Aggregate ": "", + node->l->aggregateLow, node->l->aggregateHi); + if (node->l->son) { + printf("L-Son: "); + sx_prefix_fprint(stdout, node->l->son->prefix); + printf(" %s%s%u,%u\n", + node->l->son->isGlue ? "Glue " : "", + node->l->son->isAggregate ? "Aggregate " : "", + node->l->son->aggregateLow, + node->l->son->aggregateHi); }; }; }; - if(node->r && node->l) { - if(!node->r->isAggregate && !node->l->isAggregate && - !node->r->isGlue && !node->l->isGlue && - node->r->prefix->masklen==node->l->prefix->masklen) { - if(node->r->prefix->masklen==node->prefix->masklen+1) { - node->isAggregate=1; - node->r->isGlue=1; - node->l->isGlue=1; - node->aggregateHi=node->r->prefix->masklen; - if(node->isGlue) { - node->isGlue=0; - node->aggregateLow=node->r->prefix->masklen; + if (node->r && node->l) { + if (!node->r->isAggregate && !node->l->isAggregate + && !node->r->isGlue && !node->l->isGlue + && node->r->prefix->masklen == node->l->prefix->masklen) { + if (node->r->prefix->masklen == node->prefix->masklen+1) { + node->isAggregate = 1; + node->r->isGlue = 1; + node->l->isGlue = 1; + node->aggregateHi = node->r->prefix->masklen; + if (node->isGlue) { + node->isGlue = 0; + node->aggregateLow = node->r->prefix->masklen; } else { - node->aggregateLow=node->prefix->masklen; + node->aggregateLow = node->prefix->masklen; }; }; - if(node->r->son && node->l->son && - node->r->son->isAggregate && node->l->son->isAggregate && - node->r->son->aggregateHi==node->l->son->aggregateHi && - node->r->son->aggregateLow==node->l->son->aggregateLow && - node->r->prefix->masklen==node->prefix->masklen+1 && - node->l->prefix->masklen==node->prefix->masklen+1) - { - node->son=sx_radix_node_new(node->prefix); - node->son->isGlue=0; - node->son->isAggregate=1; - node->son->aggregateHi=node->r->son->aggregateHi; - node->son->aggregateLow=node->r->son->aggregateLow; - node->r->son->isGlue=1; - node->l->son->isGlue=1; + if (node->r->son && node->l->son + && node->r->son->isAggregate + && node->l->son->isAggregate + && node->r->son->aggregateHi == node->l->son->aggregateHi + && node->r->son->aggregateLow == node->l->son->aggregateLow + && node->r->prefix->masklen == node->prefix->masklen + 1 + && node->l->prefix->masklen == node->prefix->masklen + 1) { + node->son = sx_radix_node_new(node->prefix); + node->son->isGlue = 0; + node->son->isAggregate = 1; + node->son->aggregateHi = node->r->son->aggregateHi; + node->son->aggregateLow = node->r->son->aggregateLow; + node->r->son->isGlue = 1; + node->l->son->isGlue = 1; }; - } else if(node->r->isAggregate && node->l->isAggregate && - node->r->aggregateHi==node->l->aggregateHi && - node->r->aggregateLow==node->l->aggregateLow) { - if(node->r->prefix->masklen==node->prefix->masklen+1 && - node->l->prefix->masklen==node->prefix->masklen+1) { - if(node->isGlue) { - node->r->isGlue=1; - node->l->isGlue=1; - node->isAggregate=1; - node->isGlue=0; - node->aggregateHi=node->r->aggregateHi; - node->aggregateLow=node->r->aggregateLow; - } else if(node->r->prefix->masklen==node->r->aggregateLow) { - node->r->isGlue=1; - node->l->isGlue=1; - node->isAggregate=1; - node->aggregateHi=node->r->aggregateHi; - node->aggregateLow=node->prefix->masklen; + } else if (node->r->isAggregate && node->l->isAggregate + && node->r->aggregateHi == node->l->aggregateHi + && node->r->aggregateLow==node->l->aggregateLow) { + if (node->r->prefix->masklen == node->prefix->masklen + 1 + && node->l->prefix->masklen == node->prefix->masklen + 1) { + if (node->isGlue) { + node->r->isGlue = 1; + node->l->isGlue = 1; + node->isAggregate = 1; + node->isGlue = 0; + node->aggregateHi = node->r->aggregateHi; + node->aggregateLow = node->r->aggregateLow; + } else if (node->r->prefix->masklen == node->r->aggregateLow) { + node->r->isGlue = 1; + node->l->isGlue = 1; + node->isAggregate = 1; + node->aggregateHi = node->r->aggregateHi; + node->aggregateLow = node->prefix->masklen; } else { - node->son=sx_radix_node_new(node->prefix); - node->son->isGlue=0; - node->son->isAggregate=1; - node->son->aggregateHi=node->r->aggregateHi; - node->son->aggregateLow=node->r->aggregateLow; - node->r->isGlue=1; - node->l->isGlue=1; - if(node->r->son && node->l->son && - node->r->son->aggregateHi==node->l->son->aggregateHi && - node->r->son->aggregateLow==node->l->son->aggregateLow) - { - node->son->son=sx_radix_node_new(node->prefix); - node->son->son->isGlue=0; - node->son->son->isAggregate=1; - node->son->son->aggregateHi=node->r->son->aggregateHi; - node->son->son->aggregateLow=node->r->son->aggregateLow; - node->r->son->isGlue=1; - node->l->son->isGlue=1; + node->son = sx_radix_node_new(node->prefix); + node->son->isGlue = 0; + node->son->isAggregate = 1; + node->son->aggregateHi = node->r->aggregateHi; + node->son->aggregateLow = node->r->aggregateLow; + node->r->isGlue = 1; + node->l->isGlue = 1; + if (node->r->son && node->l->son + && node->r->son->aggregateHi == node->l->son->aggregateHi + && node->r->son->aggregateLow == node->l->son->aggregateLow) { + node->son->son = sx_radix_node_new(node->prefix); + node->son->son->isGlue = 0; + node->son->son->isAggregate = 1; + node->son->son->aggregateHi = node->r->son->aggregateHi; + node->son->son->aggregateLow = node->r->son->aggregateLow; + node->r->son->isGlue = 1; + node->l->son->isGlue = 1; }; }; }; - } else if(node->l->son && - node->r->isAggregate && node->l->son->isAggregate && - node->r->aggregateHi==node->l->son->aggregateHi && - node->r->aggregateLow==node->l->son->aggregateLow) { - if(node->r->prefix->masklen==node->prefix->masklen+1 && - node->l->prefix->masklen==node->prefix->masklen+1) { - if(node->isGlue) { - node->r->isGlue=1; - node->l->son->isGlue=1; - node->isAggregate=1; - node->isGlue=0; - node->aggregateHi=node->r->aggregateHi; - node->aggregateLow=node->r->aggregateLow; + } else if (node->l->son && node->r->isAggregate + && node->l->son->isAggregate + && node->r->aggregateHi == node->l->son->aggregateHi + && node->r->aggregateLow == node->l->son->aggregateLow) { + if (node->r->prefix->masklen == node->prefix->masklen + 1 + && node->l->prefix->masklen == node->prefix->masklen + 1) { + if (node->isGlue) { + node->r->isGlue = 1; + node->l->son->isGlue = 1; + node->isAggregate = 1; + node->isGlue = 0; + node->aggregateHi = node->r->aggregateHi; + node->aggregateLow = node->r->aggregateLow; } else { - node->son=sx_radix_node_new(node->prefix); - node->son->isGlue=0; - node->son->isAggregate=1; - node->son->aggregateHi=node->r->aggregateHi; - node->son->aggregateLow=node->r->aggregateLow; - node->r->isGlue=1; - node->l->son->isGlue=1; + node->son = sx_radix_node_new(node->prefix); + node->son->isGlue = 0; + node->son->isAggregate = 1; + node->son->aggregateHi = node->r->aggregateHi; + node->son->aggregateLow = node->r->aggregateLow; + node->r->isGlue = 1; + node->l->son->isGlue = 1; }; }; - } else if(node->r->son && - node->l->isAggregate && node->r->son->isAggregate && - node->l->aggregateHi==node->r->son->aggregateHi && - node->l->aggregateLow==node->r->son->aggregateLow) { - if(node->l->prefix->masklen==node->prefix->masklen+1 && - node->r->prefix->masklen==node->prefix->masklen+1) { - if(node->isGlue) { - node->l->isGlue=1; - node->r->son->isGlue=1; - node->isAggregate=1; - node->isGlue=0; - node->aggregateHi=node->l->aggregateHi; - node->aggregateLow=node->l->aggregateLow; + } else if (node->r->son && node->l->isAggregate + && node->r->son->isAggregate + && node->l->aggregateHi == node->r->son->aggregateHi + && node->l->aggregateLow == node->r->son->aggregateLow) { + if (node->l->prefix->masklen == node->prefix->masklen + 1 + && node->r->prefix->masklen == node->prefix->masklen+1) { + if (node->isGlue) { + node->l->isGlue = 1; + node->r->son->isGlue = 1; + node->isAggregate = 1; + node->isGlue = 0; + node->aggregateHi = node->l->aggregateHi; + node->aggregateLow = node->l->aggregateLow; } else { - node->son=sx_radix_node_new(node->prefix); - node->son->isGlue=0; - node->son->isAggregate=1; - node->son->aggregateHi=node->l->aggregateHi; - node->son->aggregateLow=node->l->aggregateLow; - node->l->isGlue=1; - node->r->son->isGlue=1; + node->son = sx_radix_node_new(node->prefix); + node->son->isGlue = 0; + node->son->isAggregate = 1; + node->son->aggregateHi = node->l->aggregateHi; + node->son->aggregateLow = node->l->aggregateLow; + node->l->isGlue = 1; + node->r->son->isGlue = 1; }; }; }; }; + return 0; }; int sx_radix_tree_aggregate(struct sx_radix_tree* tree) { - if(tree && tree->head) return sx_radix_node_aggregate(tree->head); + if (tree && tree->head) + return sx_radix_node_aggregate(tree->head); + return 0; }; static void setGlueUpTo(struct sx_radix_node* node, void* udata) { - unsigned refine=*(unsigned*)udata; - if(node && node->prefix->masklen <= refine) { - node->isGlue=1; - }; + unsigned refine = *(unsigned*)udata; + + if (node && node->prefix->masklen <= refine) + node->isGlue = 1; }; int sx_radix_node_refine(struct sx_radix_node* node, unsigned refine) { - if(!node->isGlue && node->prefix->masklenisAggregate=1; - node->aggregateLow=node->prefix->masklen; - node->aggregateHi=refine; - if(node->l) { + if (!node->isGlue && node->prefix->masklenisAggregate = 1; + node->aggregateLow = node->prefix->masklen; + node->aggregateHi = refine; + if (node->l) { sx_radix_node_foreach(node->l, setGlueUpTo, &refine); sx_radix_node_refine(node->l, refine); }; - if(node->r) { + if (node->r) { sx_radix_node_foreach(node->r, setGlueUpTo, &refine); sx_radix_node_refine(node->r, refine); }; - } else if(!node->isGlue && node->prefix->masklen==refine) { + } else if (!node->isGlue && node->prefix->masklen == refine) { /* not setting aggregate in this case */ - if(node->l) sx_radix_node_refine(node->l, refine); - if(node->r) sx_radix_node_refine(node->r, refine); - } else if(node->isGlue) { - if(node->r) sx_radix_node_refine(node->r, refine); - if(node->l) sx_radix_node_refine(node->l, refine); + if (node->l) + sx_radix_node_refine(node->l, refine); + if (node->r) + sx_radix_node_refine(node->r, refine); + } else if (node->isGlue) { + if (node->r) + sx_radix_node_refine(node->r, refine); + if (node->l) + sx_radix_node_refine(node->l, refine); } else { /* node->prefix.masklen > refine */ - /* do nothing, should pass specifics 'as is'. Also, do not - process any embedded routes, their masklen is bigger, too... - node->isGlue=1; - if(node->l) sx_radix_node_foreach(node->l, setGlue, NULL); - if(node->r) sx_radix_node_foreach(node->r, setGlue, NULL); + /* + * do nothing, should pass specifics 'as is'. Also, do not + * process any embedded routes, their masklen is bigger, too... + node->isGlue = 1; + if (node->l) + sx_radix_node_foreach(node->l, setGlue, NULL); + + if (node->r) + sx_radix_node_foreach(node->r, setGlue, NULL); */ }; return 0; @@ -930,71 +1067,81 @@ sx_radix_node_refine(struct sx_radix_node* node, unsigned refine) int sx_radix_tree_refine(struct sx_radix_tree* tree, unsigned refine) { - if(tree && tree->head) return sx_radix_node_refine(tree->head, refine); + if (tree && tree->head) + return sx_radix_node_refine(tree->head, refine); + return 0; }; static void setGlueFrom(struct sx_radix_node* node, void* udata) { - unsigned refine=*(unsigned*)udata; - if(node && node->prefix->masklen <= refine) { + unsigned refine = *(unsigned*)udata; + + if (node && node->prefix->masklen <= refine) node->isGlue=1; - }; }; static int sx_radix_node_refineLow(struct sx_radix_node* node, unsigned refineLow) { - if(!node->isGlue && node->prefix->masklen<=refineLow) { - if(!node->isAggregate) { - node->isAggregate=1; + if (!node->isGlue && node->prefix->masklen<=refineLow) { + + if (!node->isAggregate) { + node->isAggregate = 1; + node->aggregateLow = refineLow; + if (node->prefix->family == AF_INET) + node->aggregateHi = 32; + else + node->aggregateHi = 128; + } else node->aggregateLow=refineLow; - if(node->prefix->family == AF_INET) { - node->aggregateHi=32; - } else { - node->aggregateHi=128; - } - } else { - node->aggregateLow=refineLow; - }; - if(node->l) { + + if (node->l) { sx_radix_node_foreach(node->l, setGlueFrom, &refineLow); sx_radix_node_refineLow(node->l, refineLow); }; - if(node->r) { + + if (node->r) { sx_radix_node_foreach(node->r, setGlueFrom, &refineLow); sx_radix_node_refineLow(node->r, refineLow); }; - } else if(!node->isGlue && node->prefix->masklen==refineLow) { + + } else if (!node->isGlue && node->prefix->masklen == refineLow) { /* not setting aggregate in this case */ - if(node->l) sx_radix_node_refineLow(node->l, refineLow); - if(node->r) sx_radix_node_refineLow(node->r, refineLow); - } else if(node->isGlue) { - if(node->r) sx_radix_node_refineLow(node->r, refineLow); - if(node->l) sx_radix_node_refineLow(node->l, refineLow); + if (node->l) + sx_radix_node_refineLow(node->l, refineLow); + if (node->r) + sx_radix_node_refineLow(node->r, refineLow); + } else if (node->isGlue) { + if (node->r) + sx_radix_node_refineLow(node->r, refineLow); + if (node->l) + sx_radix_node_refineLow(node->l, refineLow); } else { /* node->prefix.masklen > refine */ /* do nothing, should pass specifics 'as is'. Also, do not process any embedded routes, their masklen is bigger, too... - node->isGlue=1; - if(node->l) sx_radix_node_foreach(node->l, setGlue, NULL); - if(node->r) sx_radix_node_foreach(node->r, setGlue, NULL); + node->isGlue = 1; + if (node->l) + sx_radix_node_foreach(node->l, setGlue, NULL); + if (node->r) + sx_radix_node_foreach(node->r, setGlue, NULL); */ }; + return 0; }; - int sx_radix_tree_refineLow(struct sx_radix_tree* tree, unsigned refineLow) { - if(tree && tree->head) + if (tree && tree->head) return sx_radix_node_refineLow(tree->head, refineLow); + return 0; }; - #if SX_PTREE_TEST int main() { @@ -1003,160 +1150,164 @@ main() { struct sx_radix_tree* tree; struct sx_radix_node* node; - p=sx_prefix_new(0,"10.11.12.13/24"); - sx_prefix_fprint(stdout,p); + p = sx_prefix_new(0, "10.11.12.13/24"); + sx_prefix_fprint(stdout, p); printf("\n"); - p=sx_prefix_new(0,"10.11.12.13/33"); - sx_prefix_fprint(stdout,p); + p = sx_prefix_new(0, "10.11.12.13/33"); + sx_prefix_fprint(stdout, p); printf("\n"); - p=sx_prefix_new(0,"10.11.12.13/-133"); - sx_prefix_fprint(stdout,p); + p = sx_prefix_new(0, "10.11.12.13/-133"); + sx_prefix_fprint(stdout, p); printf("\n"); - p=sx_prefix_new(AF_INET,"10.11.12.14/24"); - sx_prefix_fprint(stdout,p); + p = sx_prefix_new(AF_INET, "10.11.12.14/24"); + sx_prefix_fprint(stdout, p); printf("\n"); - p=sx_prefix_new(AF_INET,"10.11.12.14/33"); - sx_prefix_fprint(stdout,p); + p = sx_prefix_new(AF_INET, "10.11.12.14/33"); + sx_prefix_fprint(stdout, p); printf("\n"); - p=sx_prefix_new(AF_INET,"10.11.12.14/-133"); - sx_prefix_fprint(stdout,p); + p = sx_prefix_new(AF_INET, "10.11.12.14/-133"); + sx_prefix_fprint(stdout, p); printf("\n"); - p=sx_prefix_new(AF_INET6,"10.11.12.15/24"); - sx_prefix_fprint(stdout,p); + p = sx_prefix_new(AF_INET6, "10.11.12.15/24"); + sx_prefix_fprint(stdout, p); printf("\n"); - p=sx_prefix_new(AF_INET6,"10.11.12.15/33"); - sx_prefix_fprint(stdout,p); + p = sx_prefix_new(AF_INET6, "10.11.12.15/33"); + sx_prefix_fprint(stdout, p); printf("\n"); - p=sx_prefix_new(AF_INET6,"10.11.12.15/-133"); - sx_prefix_fprint(stdout,p); + p = sx_prefix_new(AF_INET6, "10.11.12.15/-133"); + sx_prefix_fprint(stdout, p); printf("\n"); - p=sx_prefix_new(0,"2001:1b00::/24"); - sx_prefix_fprint(stdout,p); + p = sx_prefix_new(0, "2001:1b00::/24"); + sx_prefix_fprint(stdout, p); printf("\n"); - p=sx_prefix_new(0,"2001:1b00::/33"); - sx_prefix_fprint(stdout,p); + p = sx_prefix_new(0, "2001:1b00::/33"); + sx_prefix_fprint(stdout, p); printf("\n"); - p=sx_prefix_new(0,"2001:1b00::/-133"); - sx_prefix_fprint(stdout,p); + p = sx_prefix_new(0, "2001:1b00::/-133"); + sx_prefix_fprint(stdout, p); printf("\n"); - p=sx_prefix_new(AF_INET6,"2001:1b01::/24"); - sx_prefix_fprint(stdout,p); + p = sx_prefix_new(AF_INET6, "2001:1b01::/24"); + sx_prefix_fprint(stdout, p); printf("\n"); - p=sx_prefix_new(AF_INET6,"2001:1b01::/33"); - sx_prefix_fprint(stdout,p); + p = sx_prefix_new(AF_INET6, "2001:1b01::/33"); + sx_prefix_fprint(stdout, p); printf("\n"); - p=sx_prefix_new(AF_INET6,"2001:1b01::/-133"); - sx_prefix_fprint(stdout,p); + p = sx_prefix_new(AF_INET6, "2001:1b01::/-133"); + sx_prefix_fprint(stdout, p); printf("\n"); -#define SX_TEST_EBITS(a,b,susp) n=sx_prefix_eqbits(sx_prefix_new(0,a)),\ +#define SX_TEST_EBITS(a,b,susp) n = sx_prefix_eqbits(sx_prefix_new(0,a)),\ sx_prefix_new(0,b))); \ - if(n!=susp) printf("FAILED: %s eqbits %s=%i, not %i\n", a, b, n, susp);\ - else printf("OK, %s eqbits %s=%i, as suspected\n", a, b, n); - SX_TEST_EBITS("192.168.0.0/24","192.168.1.0/24",23); - SX_TEST_EBITS("192.168.0.0/32","192.168.0.1/32",31); + if (n != susp) \ + printf("FAILED: %s eqbits %s=%i, not %i\n", a, b, n, + susp);\ + else + printf("OK, %s eqbits %s = %i, as suspected\n", a, b, + n); + SX_TEST_EBITS("192.168.0.0/24", "192.168.1.0/24", 23); + SX_TEST_EBITS("192.168.0.0/32", "192.168.0.1/32", 31); #if SX_LIBPTREE_IPV6 - SX_TEST_EBITS("2001:1b00::/32","2001:1b01::/32",31); + SX_TEST_EBITS("2001:1b00::/32", "2001:1b01::/32", 31); #endif - p=sx_prefix_new(0,"10.11.12.255/32"); - sx_prefix_fprint(stdout,p); - printf("\n31'th bit is %i\n",sx_prefix_isbitset(p,31)); - printf("32'th bit is %i\n",sx_prefix_isbitset(p,32)); - printf("33'th bit is %i\n",sx_prefix_isbitset(p,33)); - p=sx_prefix_new(0,"10.11.12.255/31"); - sx_prefix_fprint(stdout,p); - printf("\n31'th bit is %i\n",sx_prefix_isbitset(p,31)); - printf("32'th bit is %i\n",sx_prefix_isbitset(p,32)); - printf("33'th bit is %i\n",sx_prefix_isbitset(p,33)); - p=sx_prefix_new(0,"10.11.12.255/30"); - sx_prefix_fprint(stdout,p); - printf("\n31'th bit is %i\n",sx_prefix_isbitset(p,31)); - p=sx_prefix_new(0,"10.11.12.255/29"); - sx_prefix_fprint(stdout,p); + p = sx_prefix_new(0, "10.11.12.255/32"); + sx_prefix_fprint(stdout, p); + printf("\n31'th bit is %i\n",sx_prefix_isbitset(p, 31)); + printf("32'th bit is %i\n",sx_prefix_isbitset(p, 32)); + printf("33'th bit is %i\n",sx_prefix_isbitset(p, 33)); + p = sx_prefix_new(0, "10.11.12.255/31"); + sx_prefix_fprint(stdout, p); + printf("\n31'th bit is %i\n", sx_prefix_isbitset(p, 31)); + printf("32'th bit is %i\n", sx_prefix_isbitset(p, 32)); + printf("33'th bit is %i\n", sx_prefix_isbitset(p, 33)); + p = sx_prefix_new(0, "10.11.12.255/30"); + sx_prefix_fprint(stdout, p); + printf("\n31'th bit is %i\n", sx_prefix_isbitset(p, 31)); + p = sx_prefix_new(0, "10.11.12.255/29"); + sx_prefix_fprint(stdout, p); printf("\n"); - p=sx_prefix_new(0,"10.11.12.255/28"); - sx_prefix_fprint(stdout,p); + p = sx_prefix_new(0, "10.11.12.255/28"); + sx_prefix_fprint(stdout, p); printf("\n"); - p=sx_prefix_new(0,"10.11.12.255/27"); - sx_prefix_fprint(stdout,p); + p = sx_prefix_new(0, "10.11.12.255/27"); + sx_prefix_fprint(stdout, p); printf("\n"); - p=sx_prefix_new(0,"10.11.12.255/26"); - sx_prefix_fprint(stdout,p); + p = sx_prefix_new(0, "10.11.12.255/26"); + sx_prefix_fprint(stdout, p); printf("\n"); - p=sx_prefix_new(0,"10.11.12.255/25"); - sx_prefix_fprint(stdout,p); - printf("\n25'th bit is %i\n",sx_prefix_isbitset(p,25)); - p=sx_prefix_new(0,"10.11.12.255/24"); - sx_prefix_fprint(stdout,p); - printf("\n25'th bit is %i\n",sx_prefix_isbitset(p,25)); + p = sx_prefix_new(0, "10.11.12.255/25"); + sx_prefix_fprint(stdout, p); + printf("\n25'th bit is %i\n", sx_prefix_isbitset(p, 25)); + p = sx_prefix_new(0, "10.11.12.255/24"); + sx_prefix_fprint(stdout, p); + printf("\n25'th bit is %i\n", sx_prefix_isbitset(p, 25)); - tree=sx_radix_tree_new(AF_INET); - sx_radix_tree_insert(tree,sx_prefix_new(0,"81.9.100.10/32")); - sx_radix_tree_insert(tree,sx_prefix_new(0,"217.170.80.83/32")); + tree = sx_radix_tree_new(AF_INET); + sx_radix_tree_insert(tree, sx_prefix_new(0, "81.9.100.10/32")); + sx_radix_tree_insert(tree, sx_prefix_new(0, "217.170.80.83/32")); - sx_radix_tree_foreach(tree,sx_radix_node_fprintf,NULL); + sx_radix_tree_foreach(tree, sx_radix_node_fprintf, NULL); - tree=sx_radix_tree_new(AF_INET); - sx_radix_tree_insert(tree,sx_prefix_new(0,"81.9.100.10/32")); - sx_radix_tree_insert(tree,sx_prefix_new(0,"217.170.80.83/32")); - sx_radix_tree_insert(tree,sx_prefix_new(0,"217.170.80.84/32")); - sx_radix_tree_insert(tree,sx_prefix_new(0,"217.170.80.85/32")); - sx_radix_tree_insert(tree,sx_prefix_new(0,"217.170.80.86/32")); - sx_radix_tree_insert(tree,sx_prefix_new(0,"217.170.80.87/32")); - sx_radix_tree_insert(tree,sx_prefix_new(0,"217.170.80.90/32")); - sx_radix_tree_insert(tree,sx_prefix_new(0,"217.170.80.90/32")); - sx_radix_tree_insert(tree,sx_prefix_new(0,"127.0.0.1/32")); - sx_radix_tree_insert(tree,sx_prefix_new(0,"127.0.0.1/24")); - sx_radix_tree_insert(tree,sx_prefix_new(0,"127.0.0.0/24")); - sx_radix_tree_insert(tree,sx_prefix_new(0,"128.0.0.0/1")); + tree = sx_radix_tree_new(AF_INET); + sx_radix_tree_insert(tree, sx_prefix_new(0, "81.9.100.10/32")); + sx_radix_tree_insert(tree, sx_prefix_new(0, "217.170.80.83/32")); + sx_radix_tree_insert(tree, sx_prefix_new(0, "217.170.80.84/32")); + sx_radix_tree_insert(tree, sx_prefix_new(0, "217.170.80.85/32")); + sx_radix_tree_insert(tree, sx_prefix_new(0, "217.170.80.86/32")); + sx_radix_tree_insert(tree, sx_prefix_new(0, "217.170.80.87/32")); + sx_radix_tree_insert(tree, sx_prefix_new(0, "217.170.80.90/32")); + sx_radix_tree_insert(tree, sx_prefix_new(0, "217.170.80.90/32")); + sx_radix_tree_insert(tree, sx_prefix_new(0, "127.0.0.1/32")); + sx_radix_tree_insert(tree, sx_prefix_new(0, "127.0.0.1/24")); + sx_radix_tree_insert(tree, sx_prefix_new(0, "127.0.0.0/24")); + sx_radix_tree_insert(tree, sx_prefix_new(0, "128.0.0.0/1")); - sx_radix_tree_foreach(tree,sx_radix_node_fprintf,NULL); + sx_radix_tree_foreach(tree, sx_radix_node_fprintf, NULL); printf("lookup 1.1.1.1: "); - node=sx_radix_tree_lookup(tree,sx_prefix_new(0,"1.1.1.1")); - sx_radix_node_fprintf(node,NULL); + node = sx_radix_tree_lookup(tree, sx_prefix_new(0, "1.1.1.1")); + sx_radix_node_fprintf(node, NULL); printf("lookup 217.170.80.90: "); - node=sx_radix_tree_lookup(tree,sx_prefix_new(0,"217.170.80.90")); - sx_radix_node_fprintf(node,NULL); + node = sx_radix_tree_lookup(tree, sx_prefix_new(0, "217.170.80.90")); + sx_radix_node_fprintf(node, NULL); - sx_radix_tree_unlink(tree,node); + sx_radix_tree_unlink(tree, node); printf("lookup 217.170.80.90 after delete: "); - node=sx_radix_tree_lookup(tree,sx_prefix_new(0,"217.170.80.90")); - sx_radix_node_fprintf(node,NULL); + node = sx_radix_tree_lookup(tree, sx_prefix_new(0, "217.170.80.90")); + sx_radix_node_fprintf(node, NULL); - sx_radix_tree_insert(tree,sx_prefix_new(0,"217.170.80.90/32")); + sx_radix_tree_insert(tree, sx_prefix_new(0, "217.170.80.90/32")); printf("lookup 217.170.80.90 after reinsert: "); - node=sx_radix_tree_lookup(tree,sx_prefix_new(0,"217.170.80.90")); - sx_radix_node_fprintf(node,NULL); + node = sx_radix_tree_lookup(tree, sx_prefix_new(0, "217.170.80.90")); + sx_radix_node_fprintf(node, NULL); printf("lookup 217.170.80.81: "); - node=sx_radix_tree_lookup(tree,sx_prefix_new(0,"217.170.80.81")); - sx_radix_node_fprintf(node,NULL); + node = sx_radix_tree_lookup(tree, sx_prefix_new(0, "217.170.80.81")); + sx_radix_node_fprintf(node, NULL); printf("lookup 127.0.0.1/24: "); - node=sx_radix_tree_lookup(tree,sx_prefix_new(0,"127.0.0.1/24")); - sx_radix_node_fprintf(node,NULL); + node = sx_radix_tree_lookup(tree, sx_prefix_new(0, "127.0.0.1/24")); + sx_radix_node_fprintf(node, NULL); printf("lookup 127.0.0.1/26: "); - node=sx_radix_tree_lookup(tree,sx_prefix_new(0,"127.0.0.1/26")); - sx_radix_node_fprintf(node,NULL); + node = sx_radix_tree_lookup(tree, sx_prefix_new(0, "127.0.0.1/26")); + sx_radix_node_fprintf(node, NULL); printf("lookup 127.0.0.1/23: "); - node=sx_radix_tree_lookup(tree,sx_prefix_new(0,"127.0.0.1/23")); - sx_radix_node_fprintf(node,NULL); + node = sx_radix_tree_lookup(tree, sx_prefix_new(0, "127.0.0.1/23")); + sx_radix_node_fprintf(node, NULL); - tree=sx_radix_tree_new(AF_INET6); - sx_radix_tree_insert(tree,sx_prefix_new(0,"2100:1b00::/32")); - sx_radix_tree_insert(tree,sx_prefix_new(0,"2100:1b01::/32")); - sx_radix_tree_insert(tree,sx_prefix_new(0,"2100:1b00::/33")); - sx_radix_tree_insert(tree,sx_prefix_new(0,"2100:1b00::1/128")); - sx_radix_tree_foreach(tree,sx_radix_node_fprintf,NULL); + tree = sx_radix_tree_new(AF_INET6); + sx_radix_tree_insert(tree, sx_prefix_new(0, "2100:1b00::/32")); + sx_radix_tree_insert(tree, sx_prefix_new(0, "2100:1b01::/32")); + sx_radix_tree_insert(tree, sx_prefix_new(0, "2100:1b00::/33")); + sx_radix_tree_insert(tree, sx_prefix_new(0, "2100:1b00::1/128")); + sx_radix_tree_foreach(tree, sx_radix_node_fprintf, NULL); return 0; }; diff --git a/sx_report.c b/sx_report.c index eccc67e..68ecbcb 100644 --- a/sx_report.c +++ b/sx_report.c @@ -18,13 +18,19 @@ static int reportStderr=1; static char const* sx_report_name(sx_report_t t) { - switch(t) { - case SX_MISFEATURE: return "MISSING FEATURE:"; - case SX_FATAL: return "FATAL ERROR:"; - case SX_ERROR: return "ERROR:"; - case SX_NOTICE: return "Notice:"; - case SX_DEBUG: return "Debug:"; + switch (t) { + case SX_MISFEATURE: + return "MISSING FEATURE:"; + case SX_FATAL: + return "FATAL ERROR:"; + case SX_ERROR: + return "ERROR:"; + case SX_NOTICE: + return "Notice:"; + case SX_DEBUG: + return "Debug:"; }; + return "...... HMMMMM.... ERROR... \n"; }; @@ -33,54 +39,55 @@ sx_report(sx_report_t t, char* fmt, ...) { char buffer[65536]; va_list ap; - va_start(ap,fmt); + va_start(ap, fmt); - vsnprintf(buffer,sizeof(buffer),fmt,ap); + vsnprintf(buffer, sizeof(buffer), fmt, ap); va_end(ap); - if(reportStderr) { - fputs(sx_report_name(t),stderr); - fputs(buffer,stderr); + if (reportStderr) { + fputs(sx_report_name(t), stderr); + fputs(buffer, stderr); } else { switch(t) { - case SX_FATAL: - syslog(LOG_ERR,"FATAL ERROR: %s", buffer); - break; - case SX_MISFEATURE: - case SX_ERROR: - syslog(LOG_ERR,"ERROR: %s", buffer); - break; - case SX_NOTICE: - syslog(LOG_WARNING,"Notice: %s", buffer); - break; - case SX_DEBUG: - syslog(LOG_DEBUG,"Debug: %s", buffer); - break; + case SX_FATAL: + syslog(LOG_ERR,"FATAL ERROR: %s", buffer); + break; + case SX_MISFEATURE: + case SX_ERROR: + syslog(LOG_ERR,"ERROR: %s", buffer); + break; + case SX_NOTICE: + syslog(LOG_WARNING,"Notice: %s", buffer); + break; + case SX_DEBUG: + syslog(LOG_DEBUG,"Debug: %s", buffer); + break; }; }; - if(t==SX_FATAL) exit(-1); + if (t == SX_FATAL) + exit(-1); return 0; }; int sx_debug(char const* const file, char const* const func, int const line, - char* fmt, ...) + char* fmt, ...) { char buffer[65536]; char bline[65536]; va_list ap; - va_start(ap,fmt); + va_start(ap, fmt); - vsnprintf(buffer,sizeof(buffer),fmt,ap); + vsnprintf(buffer, sizeof(buffer), fmt, ap); va_end(ap); - snprintf(bline,sizeof(bline),"DEBUG: %s:%i %s ", file, line, func); - if(reportStderr) { - fputs(bline,stderr); - fputs(buffer,stderr); + snprintf(bline, sizeof(bline), "DEBUG: %s:%i %s ", file, line, func); + if (reportStderr) { + fputs(bline, stderr); + fputs(buffer, stderr); } else { syslog(LOG_DEBUG,"%s %s", bline, buffer); }; @@ -91,7 +98,7 @@ sx_debug(char const* const file, char const* const func, int const line, void sx_openlog(char* progname) { - openlog(progname?progname:"",LOG_PID,LOG_DAEMON); - reportStderr=0; + openlog(progname ? progname : "", LOG_PID, LOG_DAEMON); + reportStderr = 0; }; diff --git a/sx_slentry.c b/sx_slentry.c index 1c10aeb..4ae7946 100644 --- a/sx_slentry.c +++ b/sx_slentry.c @@ -8,10 +8,16 @@ struct sx_slentry* sx_slentry_new(char* t) { - struct sx_slentry* e=malloc(sizeof(struct sx_slentry)); - if(!e) return NULL; - memset(e,0,sizeof(struct sx_slentry)); - if(t) e->text=strdup(t); + struct sx_slentry* e = malloc(sizeof(struct sx_slentry)); + + if (!e) + return NULL; + + memset(e, 0, sizeof(struct sx_slentry)); + + if (t) + e->text = strdup(t); + return e; }; @@ -19,9 +25,12 @@ struct sx_tentry* sx_tentry_new(char* t) { struct sx_tentry* te = malloc(sizeof(struct sx_tentry)); + if (!te) return NULL; + memset(te, 0, sizeof(struct sx_tentry)); te->text = strdup(t); + return te; };