mirror of
https://github.com/bgp/bgpq4
synced 2025-02-28 08:53:11 +00:00
RPSL <address-prefix-range> routes now supported too. Can be found in
rs-esnetcustomers.
This commit is contained in:
4
CHANGES
4
CHANGES
@@ -1,3 +1,7 @@
|
||||
0.1.26 (2015-02-19)
|
||||
- RPSL <address-prefix-range> support, can be found in rs-esnetcustomers.
|
||||
Thanks to Kris O'Connell for reporting.
|
||||
|
||||
0.1.25 (2014-10-29)
|
||||
- JSON support extended to handle "as-paths" too. Well, actually, as
|
||||
there are no defined format for as-path in json, bgpq3 just creates
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*-
|
||||
* Copyright (c) 2007-2014 Alexandre Snarskii <snar@snar.spb.ru>
|
||||
* Copyright (c) 2007-2015 Alexandre Snarskii <snar@snar.spb.ru>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
2
bgpq3.8
2
bgpq3.8
@@ -1,4 +1,4 @@
|
||||
.\" Copyright (c) 2007-2014 Alexandre Snarskii
|
||||
.\" Copyright (c) 2007-2015 Alexandre Snarskii
|
||||
.\" All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
|
||||
11
bgpq3.c
11
bgpq3.c
@@ -351,7 +351,7 @@ main(int argc, char* argv[])
|
||||
};
|
||||
};
|
||||
if(expander.generation<T_PREFIXLIST) {
|
||||
if(refine) {
|
||||
if(refine) {
|
||||
sx_report(SX_FATAL, "Sorry, more-specific filter (-R %u) "
|
||||
"supported only with prefix-list generation\n", refine);
|
||||
} else {
|
||||
@@ -373,6 +373,10 @@ main(int argc, char* argv[])
|
||||
* be accepted, so save some CPU cycles :) */
|
||||
expander.maxlen = maxlen;
|
||||
};
|
||||
} else if (expander.family==AF_INET) {
|
||||
expander.maxlen = 32;
|
||||
} else if (expander.family==AF_INET6) {
|
||||
expander.maxlen = 128;
|
||||
};
|
||||
|
||||
if(expander.generation==T_EACL && expander.vendor==V_CISCO &&
|
||||
@@ -409,7 +413,10 @@ main(int argc, char* argv[])
|
||||
bgpq_expander_add_as(&expander,argv[0]);
|
||||
};
|
||||
} else {
|
||||
if(!bgpq_expander_add_prefix(&expander,argv[0]))
|
||||
char* c = strchr(argv[0], '^');
|
||||
if (!c && !bgpq_expander_add_prefix(&expander,argv[0]))
|
||||
exit(1);
|
||||
else if (!bgpq_expander_add_prefix_range(&expander,argv[0]))
|
||||
exit(1);
|
||||
};
|
||||
argv++;
|
||||
|
||||
1
bgpq3.h
1
bgpq3.h
@@ -54,6 +54,7 @@ int bgpq_expander_add_asset(struct bgpq_expander* b, char* set);
|
||||
int bgpq_expander_add_rset(struct bgpq_expander* b, char* set);
|
||||
int bgpq_expander_add_as(struct bgpq_expander* b, char* as);
|
||||
int bgpq_expander_add_prefix(struct bgpq_expander* b, char* prefix);
|
||||
int bgpq_expander_add_prefix_range(struct bgpq_expander* b, char* prefix);
|
||||
|
||||
int bgpq_expand(struct bgpq_expander* b);
|
||||
|
||||
|
||||
302
bgpq_expander.c
302
bgpq_expander.c
@@ -24,7 +24,7 @@ int pipelining=1;
|
||||
|
||||
int
|
||||
bgpq_expander_init(struct bgpq_expander* b, int af)
|
||||
{
|
||||
{
|
||||
if(!af) af=AF_INET;
|
||||
if(!b) return 0;
|
||||
|
||||
@@ -38,8 +38,8 @@ bgpq_expander_init(struct bgpq_expander* b, int af)
|
||||
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",
|
||||
if(!b->asn32s[0]) {
|
||||
sx_report(SX_FATAL,"Unable to allocate 8192 bytes: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
};
|
||||
@@ -57,14 +57,14 @@ fixups:
|
||||
|
||||
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(!le) return 0;
|
||||
if(!b->macroses) {
|
||||
if(!b->macroses) {
|
||||
b->macroses=le;
|
||||
} else {
|
||||
} else {
|
||||
struct sx_slentry* ln=b->macroses;
|
||||
while(ln->next) ln=ln->next;
|
||||
ln->next=le;
|
||||
@@ -72,16 +72,16 @@ bgpq_expander_add_asset(struct bgpq_expander* b, char* as)
|
||||
return 1;
|
||||
};
|
||||
|
||||
int
|
||||
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->rsets) {
|
||||
if(!b->rsets) {
|
||||
b->rsets=le;
|
||||
} else {
|
||||
} else {
|
||||
struct sx_slentry* ln=b->rsets;
|
||||
while(ln->next) ln=ln->next;
|
||||
ln->next=le;
|
||||
@@ -91,55 +91,55 @@ bgpq_expander_add_rset(struct bgpq_expander* b, char* rs)
|
||||
|
||||
int
|
||||
bgpq_expander_add_as(struct bgpq_expander* b, char* as)
|
||||
{
|
||||
{
|
||||
char* eoa;
|
||||
uint32_t asno;
|
||||
|
||||
if(!b || !as) return 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",
|
||||
if(eoa && (*eoa!='.' && *eoa!=0)) {
|
||||
sx_report(SX_ERROR,"Invalid symbol in AS number: '%c' in %s\n",
|
||||
*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) {
|
||||
if(asno>65535) {
|
||||
asn1=asno%65536;
|
||||
asno/=65536;
|
||||
} else
|
||||
} else
|
||||
asn1=strtoul(eoa+1,&eoa,10);
|
||||
|
||||
if(eoa && *eoa!=0) {
|
||||
if(eoa && *eoa!=0) {
|
||||
sx_report(SX_ERROR,"Invalid symbol in AS number: '%c' in %s\n",
|
||||
*eoa, as);
|
||||
return 0;
|
||||
};
|
||||
if(asn1>65535) {
|
||||
if(asn1>65535) {
|
||||
sx_report(SX_ERROR,"Invalid AS number in %s\n", as);
|
||||
return 0;
|
||||
};
|
||||
if(!b->asn32s[asno]) {
|
||||
if(!b->asn32s[asno]) {
|
||||
b->asn32s[asno]=malloc(8192);
|
||||
if(!b->asn32s[asno]) {
|
||||
if(!b->asn32s[asno]) {
|
||||
sx_report(SX_FATAL, "Unable to allocate 8192 bytes: %s."
|
||||
" Unable to add asn32 %s to future expansion\n",
|
||||
" Unable to add asn32 %s to future expansion\n",
|
||||
strerror(errno), as);
|
||||
return 0;
|
||||
};
|
||||
memset(b->asn32s[asno],0,8192);
|
||||
};
|
||||
b->asn32s[asno][asn1/8]|=(0x80>>(asn1%8));
|
||||
} else if(!b->asn32) {
|
||||
} else if(!b->asn32) {
|
||||
b->asn32s[0][23456/8]|=(0x80>>(23456%8));
|
||||
};
|
||||
return 0;
|
||||
};
|
||||
|
||||
if(asno<1 || asno>65535) {
|
||||
if(asno<1 || asno>65535) {
|
||||
sx_report(SX_ERROR,"Invalid AS number in %s\n", as);
|
||||
return 0;
|
||||
};
|
||||
@@ -151,17 +151,17 @@ bgpq_expander_add_as(struct bgpq_expander* b, char* as)
|
||||
|
||||
int
|
||||
bgpq_expander_add_prefix(struct bgpq_expander* b, char* prefix)
|
||||
{
|
||||
{
|
||||
struct sx_prefix p;
|
||||
if(!sx_prefix_parse(&p,0,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) {
|
||||
} 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) {
|
||||
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;
|
||||
@@ -170,9 +170,15 @@ bgpq_expander_add_prefix(struct bgpq_expander* b, char* prefix)
|
||||
return 1;
|
||||
};
|
||||
|
||||
int
|
||||
bgpq_expander_add_prefix_range(struct bgpq_expander* b, char* prefix)
|
||||
{
|
||||
return sx_prefix_range_parse(b->tree, b->family, b->maxlen, prefix);
|
||||
};
|
||||
|
||||
int
|
||||
bgpq_expanded_macro(char* as, void* udata)
|
||||
{
|
||||
{
|
||||
struct bgpq_expander* ex=(struct bgpq_expander*)udata;
|
||||
if(!ex) return 0;
|
||||
bgpq_expander_add_as(ex,as);
|
||||
@@ -181,68 +187,72 @@ bgpq_expanded_macro(char* as, void* udata)
|
||||
|
||||
int
|
||||
bgpq_expanded_prefix(char* as, void* udata)
|
||||
{
|
||||
{
|
||||
struct bgpq_expander* ex=(struct bgpq_expander*)udata;
|
||||
char* d = strchr(as, '^');
|
||||
if(!ex) return 0;
|
||||
bgpq_expander_add_prefix(ex,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, void* udata)
|
||||
{
|
||||
{
|
||||
struct bgpq_expander* ex=(struct bgpq_expander*)udata;
|
||||
if(!ex) return 0;
|
||||
bgpq_expander_add_prefix(ex,prefix);
|
||||
return 1;
|
||||
};
|
||||
|
||||
int
|
||||
int
|
||||
bgpq_pipeline_dequeue_ripe(FILE* f, struct bgpq_expander* b)
|
||||
{
|
||||
{
|
||||
int sawNL=0;
|
||||
char buffer[128];
|
||||
char* otype=NULL, *object=NULL;
|
||||
|
||||
if(!f || !b) {
|
||||
if(!f || !b) {
|
||||
sx_report(SX_FATAL, "Invalid arguments\n");
|
||||
exit(1);
|
||||
};
|
||||
if(!b->firstpipe) {
|
||||
if(!b->firstpipe) {
|
||||
sx_report(SX_FATAL, "No piped requests\n");
|
||||
exit(1);
|
||||
};
|
||||
while(fgets(buffer,sizeof(buffer),f)) {
|
||||
if(buffer[0]=='\n') {
|
||||
while(fgets(buffer,sizeof(buffer),f)) {
|
||||
if(buffer[0]=='\n') {
|
||||
if(b->family==AF_INET && otype && !strcmp(otype,"route")) {
|
||||
SX_DEBUG(debug_expander,"dequeuer(ripe): got route %s\n",
|
||||
object);
|
||||
if(b->firstpipe->callback)
|
||||
if(b->firstpipe->callback)
|
||||
b->firstpipe->callback(object,b->firstpipe->udata);
|
||||
} else if(b->family==AF_INET6 && otype && !strcmp(otype,"route6")){
|
||||
SX_DEBUG(debug_expander,"dequeuer(ripe): got route6 %s\n",
|
||||
object);
|
||||
if(b->firstpipe->callback)
|
||||
if(b->firstpipe->callback)
|
||||
b->firstpipe->callback(object,b->firstpipe->udata);
|
||||
};
|
||||
if(otype) free(otype); otype=NULL;
|
||||
if(object) free(object); object=NULL;
|
||||
sawNL++;
|
||||
if(sawNL==2) {
|
||||
if(sawNL==2) {
|
||||
/* end of object */
|
||||
struct bgpq_prequest* p=b->firstpipe;
|
||||
b->firstpipe=b->firstpipe->next;
|
||||
free(p);
|
||||
b->piped--;
|
||||
if(!b->piped) {
|
||||
if(!b->piped) {
|
||||
return 0;
|
||||
};
|
||||
};
|
||||
} else {
|
||||
} else {
|
||||
sawNL=0;
|
||||
if(!otype) {
|
||||
if(!otype) {
|
||||
char* c=strchr(buffer,':');
|
||||
if(c) {
|
||||
if(c) {
|
||||
*c=0;
|
||||
otype=strdup(buffer);
|
||||
c++;
|
||||
@@ -254,10 +264,10 @@ bgpq_pipeline_dequeue_ripe(FILE* f, struct bgpq_expander* b)
|
||||
};
|
||||
};
|
||||
};
|
||||
if(feof(f)) {
|
||||
if(feof(f)) {
|
||||
sx_report(SX_FATAL,"EOF from RADB (dequeue, ripe)\n");
|
||||
} else {
|
||||
sx_report(SX_FATAL,"Error from RADB: %s (dequeue, ripe)\n",
|
||||
} else {
|
||||
sx_report(SX_FATAL,"Error from RADB: %s (dequeue, ripe)\n",
|
||||
strerror(errno));
|
||||
};
|
||||
return 0;
|
||||
@@ -273,7 +283,7 @@ bgpq_expand_ripe(FILE* f, int (*callback)(char*, void*), void* udata,
|
||||
va_list ap;
|
||||
struct bgpq_expander* b=(struct bgpq_expander*)udata;
|
||||
|
||||
if(!f) {
|
||||
if(!f) {
|
||||
sx_report(SX_FATAL,"Invalid argments\n");
|
||||
exit(1);
|
||||
};
|
||||
@@ -287,13 +297,13 @@ bgpq_expand_ripe(FILE* f, int (*callback)(char*, void*), void* udata,
|
||||
fflush(f);
|
||||
|
||||
sawNL=0;
|
||||
while(fgets(request,sizeof(request),f)) {
|
||||
if(request[0]=='\n') {
|
||||
if(b->family==AF_INET && otype && !strcmp(otype,"route")) {
|
||||
while(fgets(request,sizeof(request),f)) {
|
||||
if(request[0]=='\n') {
|
||||
if(b->family==AF_INET && otype && !strcmp(otype,"route")) {
|
||||
SX_DEBUG(debug_expander,"expander(ripe): got route: %s\n",
|
||||
object);
|
||||
callback(object,udata);
|
||||
} else if(b->family==AF_INET6 && otype&&!strcmp(otype,"route6")) {
|
||||
} else if(b->family==AF_INET6 && otype&&!strcmp(otype,"route6")) {
|
||||
SX_DEBUG(debug_expander,"expander(ripe): got route6: %s\n",
|
||||
object);
|
||||
callback(object,udata);
|
||||
@@ -303,16 +313,16 @@ bgpq_expand_ripe(FILE* f, int (*callback)(char*, void*), void* udata,
|
||||
if(origin) free(origin); origin=NULL;
|
||||
nObjects++;
|
||||
sawNL++;
|
||||
if(sawNL==2) {
|
||||
if(sawNL==2) {
|
||||
/* ok, that's end of input */
|
||||
return nObjects;
|
||||
};
|
||||
} else {
|
||||
} else {
|
||||
sawNL=0;
|
||||
if(!otype) {
|
||||
if(!otype) {
|
||||
/* that's the first line of object */
|
||||
char* c=strchr(request,':');
|
||||
if(c) {
|
||||
if(c) {
|
||||
*c=0;
|
||||
otype=strdup(request);
|
||||
c++;
|
||||
@@ -321,16 +331,16 @@ bgpq_expand_ripe(FILE* f, int (*callback)(char*, void*), void* udata,
|
||||
c=strchr(object,'\n');
|
||||
if(c) *c=0;
|
||||
};
|
||||
} else if(!strncmp(request,"origin",6)) {
|
||||
} else if(!strncmp(request,"origin",6)) {
|
||||
if(origin) free(origin);
|
||||
origin=strdup(request);
|
||||
};
|
||||
};
|
||||
};
|
||||
if(feof(f)) {
|
||||
if(feof(f)) {
|
||||
sx_report(SX_FATAL,"EOF from server (expand, ripe)\n");
|
||||
} else {
|
||||
sx_report(SX_FATAL,"Error reading server: %s (expand, ripe)\n",
|
||||
} else {
|
||||
sx_report(SX_FATAL,"Error reading server: %s (expand, ripe)\n",
|
||||
strerror(errno));
|
||||
};
|
||||
return 0;
|
||||
@@ -339,7 +349,7 @@ bgpq_expand_ripe(FILE* f, int (*callback)(char*, void*), void* udata,
|
||||
int
|
||||
bgpq_pipeline(FILE* f, int (*callback)(char*, void*), void* udata,
|
||||
char* fmt, ...)
|
||||
{
|
||||
{
|
||||
char request[128];
|
||||
int ret;
|
||||
struct bgpq_prequest* bp=NULL;
|
||||
@@ -352,8 +362,8 @@ bgpq_pipeline(FILE* f, int (*callback)(char*, void*), void* udata,
|
||||
SX_DEBUG(debug_expander,"expander: sending '%s'\n", request);
|
||||
|
||||
bp=malloc(sizeof(struct bgpq_prequest));
|
||||
if(!bp) {
|
||||
sx_report(SX_FATAL,"Unable to allocate %lu bytes: %s\n",
|
||||
if(!bp) {
|
||||
sx_report(SX_FATAL,"Unable to allocate %lu bytes: %s\n",
|
||||
(unsigned long)sizeof(struct bgpq_prequest),strerror(errno));
|
||||
exit(1);
|
||||
};
|
||||
@@ -361,7 +371,7 @@ bgpq_pipeline(FILE* f, int (*callback)(char*, void*), void* udata,
|
||||
|
||||
ret=fwrite(request,1,strlen(request),f);
|
||||
|
||||
if(ret!=strlen(request)) {
|
||||
if(ret!=strlen(request)) {
|
||||
sx_report(SX_FATAL,"Partial write to radb, only %i bytes written: %s\n",
|
||||
ret,strerror(errno));
|
||||
exit(1);
|
||||
@@ -371,10 +381,10 @@ bgpq_pipeline(FILE* f, int (*callback)(char*, void*), void* udata,
|
||||
bp->callback=callback;
|
||||
bp->udata=udata;
|
||||
|
||||
if(d->lastpipe) {
|
||||
if(d->lastpipe) {
|
||||
d->lastpipe->next=bp;
|
||||
d->lastpipe=bp;
|
||||
} else {
|
||||
} else {
|
||||
d->firstpipe=d->lastpipe=bp;
|
||||
};
|
||||
d->piped++;
|
||||
@@ -384,37 +394,37 @@ bgpq_pipeline(FILE* f, int (*callback)(char*, void*), void* udata,
|
||||
|
||||
int
|
||||
bgpq_pipeline_dequeue(FILE* f, struct bgpq_expander* b)
|
||||
{
|
||||
while(b->piped>0) {
|
||||
{
|
||||
while(b->piped>0) {
|
||||
char request[128];
|
||||
struct bgpq_prequest* pipe;
|
||||
memset(request,0,sizeof(request));
|
||||
if(!fgets(request,sizeof(request),f)) {
|
||||
if(ferror(f)) {
|
||||
if(!fgets(request,sizeof(request),f)) {
|
||||
if(ferror(f)) {
|
||||
sx_report(SX_FATAL,"Error reading data from RADB: %s (dequeue)"
|
||||
"\n", strerror(errno));
|
||||
} else {
|
||||
} else {
|
||||
sx_report(SX_FATAL,"EOF from RADB (dequeue)\n");
|
||||
};
|
||||
exit(1);
|
||||
};
|
||||
|
||||
if(request[0]=='A') {
|
||||
if(request[0]=='A') {
|
||||
char* eon, *c;
|
||||
unsigned long togot=strtoul(request+1,&eon,10);
|
||||
char recvbuffer[togot+2];
|
||||
memset(recvbuffer,0,togot+2);
|
||||
|
||||
if(eon && *eon!='\n') {
|
||||
if(eon && *eon!='\n') {
|
||||
sx_report(SX_ERROR,"A-code finished with wrong char '%c'(%s)\n",
|
||||
*eon,request);
|
||||
exit(1);
|
||||
};
|
||||
if(fgets(recvbuffer,togot+1,f)==NULL) {
|
||||
if(ferror(f)) {
|
||||
if(fgets(recvbuffer,togot+1,f)==NULL) {
|
||||
if(ferror(f)) {
|
||||
sx_report(SX_FATAL,"Error reading RADB: %s (dequeue, "
|
||||
"result)\n", strerror(errno));
|
||||
} else {
|
||||
} else {
|
||||
sx_report(SX_FATAL,"EOF from RADB (dequeue, result)\n");
|
||||
};
|
||||
exit(1);
|
||||
@@ -422,36 +432,36 @@ bgpq_pipeline_dequeue(FILE* f, struct bgpq_expander* b)
|
||||
SX_DEBUG(debug_expander>=3,"Got %s in response to %s",recvbuffer,
|
||||
b->firstpipe->request);
|
||||
|
||||
for(c=recvbuffer; c<recvbuffer+togot;) {
|
||||
for(c=recvbuffer; c<recvbuffer+togot;) {
|
||||
size_t spn=strcspn(c," \n");
|
||||
if(spn) c[spn]=0;
|
||||
if(c[0]==0) break;
|
||||
if(b->firstpipe->callback) {
|
||||
if(b->firstpipe->callback) {
|
||||
b->firstpipe->callback(c,b->firstpipe->udata);
|
||||
};
|
||||
c+=spn+1;
|
||||
};
|
||||
|
||||
/* Final code */
|
||||
if(fgets(recvbuffer,togot,f)==NULL) {
|
||||
if(ferror(f)) {
|
||||
if(fgets(recvbuffer,togot,f)==NULL) {
|
||||
if(ferror(f)) {
|
||||
sx_report(SX_FATAL,"Error reading RADB: %s (dequeue,final)"
|
||||
")\n", strerror(errno));
|
||||
} else {
|
||||
} else {
|
||||
sx_report(SX_FATAL,"EOF from RADB (dequeue,final)\n");
|
||||
};
|
||||
exit(1);
|
||||
};
|
||||
} else if(request[0]=='C') {
|
||||
} else if(request[0]=='C') {
|
||||
/* No data */
|
||||
} else if(request[0]=='D') {
|
||||
} else if(request[0]=='D') {
|
||||
/* .... */
|
||||
} else if(request[0]=='E') {
|
||||
} else if(request[0]=='E') {
|
||||
/* XXXXX */
|
||||
} else if(request[0]=='F') {
|
||||
} else if(request[0]=='F') {
|
||||
/* XXXXX */
|
||||
} else {
|
||||
sx_report(SX_ERROR,"Wrong reply: %s to %s\n", request,
|
||||
} else {
|
||||
sx_report(SX_ERROR,"Wrong reply: %s to %s\n", request,
|
||||
b->firstpipe->request);
|
||||
};
|
||||
|
||||
@@ -467,7 +477,7 @@ bgpq_pipeline_dequeue(FILE* f, struct bgpq_expander* b)
|
||||
int
|
||||
bgpq_expand_radb(FILE* f, int (*callback)(char*, void*), void* udata,
|
||||
char* fmt, ...)
|
||||
{
|
||||
{
|
||||
char request[128];
|
||||
va_list ap;
|
||||
int ret;
|
||||
@@ -479,14 +489,14 @@ bgpq_expand_radb(FILE* f, int (*callback)(char*, void*), void* udata,
|
||||
SX_DEBUG(debug_expander,"expander: sending '%s'\n", request);
|
||||
|
||||
ret=fwrite(request,1,strlen(request),f);
|
||||
if(ret!=strlen(request)) {
|
||||
if(ret!=strlen(request)) {
|
||||
sx_report(SX_FATAL,"Partial write to radb, only %i bytes written: %s\n",
|
||||
ret,strerror(errno));
|
||||
exit(1);
|
||||
};
|
||||
memset(request,0,sizeof(request));
|
||||
if(!fgets(request,sizeof(request),f)) {
|
||||
if(ferror(f)) {
|
||||
if(!fgets(request,sizeof(request),f)) {
|
||||
if(ferror(f)) {
|
||||
sx_report(SX_FATAL,"Error reading data from radb: %s (expand,radb)"
|
||||
"\n", strerror(errno));
|
||||
exit(1);
|
||||
@@ -496,21 +506,21 @@ bgpq_expand_radb(FILE* f, int (*callback)(char*, void*), void* udata,
|
||||
};
|
||||
SX_DEBUG(debug_expander>2,"expander: initially got %lu bytes, '%s'\n",
|
||||
(unsigned long)strlen(request),request);
|
||||
if(request[0]=='A') {
|
||||
if(request[0]=='A') {
|
||||
char* eon, *c;
|
||||
long togot=strtoul(request+1,&eon,10);
|
||||
char recvbuffer[togot+1];
|
||||
|
||||
if(eon && *eon!='\n') {
|
||||
if(eon && *eon!='\n') {
|
||||
sx_report(SX_ERROR,"A-code finised with wrong char '%c' (%s)\n",
|
||||
*eon,request);
|
||||
exit(1);
|
||||
};
|
||||
|
||||
if(fgets(recvbuffer,togot+1,f)==NULL) {
|
||||
if(feof(f)) {
|
||||
if(fgets(recvbuffer,togot+1,f)==NULL) {
|
||||
if(feof(f)) {
|
||||
sx_report(SX_FATAL,"EOF from radb (expand,radb,result)\n");
|
||||
} else {
|
||||
} else {
|
||||
sx_report(SX_FATAL,"Error reading radb: %s (expand,radb,"
|
||||
"result)\n", strerror(errno));
|
||||
};
|
||||
@@ -519,7 +529,7 @@ bgpq_expand_radb(FILE* f, int (*callback)(char*, void*), void* udata,
|
||||
SX_DEBUG(debug_expander>2,"expander: final reply of %lu bytes, '%s'\n",
|
||||
(unsigned long)strlen(recvbuffer),recvbuffer);
|
||||
|
||||
for(c=recvbuffer; c<recvbuffer+togot;) {
|
||||
for(c=recvbuffer; c<recvbuffer+togot;) {
|
||||
size_t spn=strcspn(c," \n");
|
||||
if(spn) c[spn]=0;
|
||||
if(c[0]==0) break;
|
||||
@@ -527,23 +537,23 @@ bgpq_expand_radb(FILE* f, int (*callback)(char*, void*), void* udata,
|
||||
c+=spn+1;
|
||||
};
|
||||
|
||||
if(fgets(recvbuffer,togot,f)==NULL) {
|
||||
if(feof(f)) {
|
||||
if(fgets(recvbuffer,togot,f)==NULL) {
|
||||
if(feof(f)) {
|
||||
sx_report(SX_FATAL,"EOF from radb (expand,radb,final)\n");
|
||||
} else {
|
||||
} else {
|
||||
sx_report(SX_FATAL,"ERROR from radb: %s\n", strerror(errno));
|
||||
};
|
||||
exit(1);
|
||||
};
|
||||
} else if(request[0]=='C') {
|
||||
} else if(request[0]=='C') {
|
||||
/* no data */
|
||||
} else if(request[0]=='D') {
|
||||
} else if(request[0]=='D') {
|
||||
/* ... */
|
||||
} else if(request[0]=='E') {
|
||||
} else if(request[0]=='E') {
|
||||
/* XXXXXX */
|
||||
} else if(request[0]=='F') {
|
||||
} else if(request[0]=='F') {
|
||||
/* XXXXXX */
|
||||
} else {
|
||||
} else {
|
||||
sx_report(SX_ERROR,"Wrong reply: %s\n", request);
|
||||
exit(0);
|
||||
};
|
||||
@@ -552,7 +562,7 @@ bgpq_expand_radb(FILE* f, int (*callback)(char*, void*), void* udata,
|
||||
|
||||
int
|
||||
bgpq_expand(struct bgpq_expander* b)
|
||||
{
|
||||
{
|
||||
int fd=-1, err, ret;
|
||||
struct sx_slentry* mc;
|
||||
struct addrinfo hints, *res=NULL, *rp;
|
||||
@@ -562,22 +572,22 @@ bgpq_expand(struct bgpq_expander* b)
|
||||
hints.ai_socktype=SOCK_STREAM;
|
||||
|
||||
err=getaddrinfo(b->server,"43",&hints,&res);
|
||||
if(err) {
|
||||
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) {
|
||||
for(rp=res; rp; rp=rp->ai_next) {
|
||||
fd=socket(rp->ai_family,rp->ai_socktype,0);
|
||||
if(fd==-1) {
|
||||
if(fd==-1) {
|
||||
if(errno==EPROTONOSUPPORT) continue;
|
||||
sx_report(SX_ERROR,"Unable to create socket: %s\n",
|
||||
sx_report(SX_ERROR,"Unable to create socket: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
};
|
||||
err=connect(fd,rp->ai_addr,rp->ai_addrlen);
|
||||
if(err) {
|
||||
if(err) {
|
||||
shutdown(fd,SHUT_RDWR);
|
||||
close(fd);
|
||||
fd=-1;
|
||||
@@ -585,7 +595,7 @@ bgpq_expand(struct bgpq_expander* b)
|
||||
};
|
||||
sx_maxsockbuf(fd,SO_SNDBUF);
|
||||
f=fdopen(fd,"a+");
|
||||
if(!f) {
|
||||
if(!f) {
|
||||
shutdown(fd,SHUT_RDWR);
|
||||
close(fd);
|
||||
fd=-1;
|
||||
@@ -596,87 +606,87 @@ bgpq_expand(struct bgpq_expander* b)
|
||||
};
|
||||
freeaddrinfo(res);
|
||||
|
||||
if(!f) {
|
||||
if(!f) {
|
||||
/* all our attempts to connect failed */
|
||||
sx_report(SX_ERROR,"All attempts to connect %s failed, last"
|
||||
" error: %s\n", b->server, strerror(errno));
|
||||
exit(1);
|
||||
};
|
||||
|
||||
if((ret=fwrite("!!\n",1,3,f))!=3) {
|
||||
sx_report(SX_ERROR,"Partial fwrite to radb: %i bytes, %s\n",
|
||||
if((ret=fwrite("!!\n",1,3,f))!=3) {
|
||||
sx_report(SX_ERROR,"Partial fwrite to radb: %i bytes, %s\n",
|
||||
ret, strerror(errno));
|
||||
exit(1);
|
||||
};
|
||||
|
||||
if(b->sources && b->sources[0]!=0) {
|
||||
if(b->sources && b->sources[0]!=0) {
|
||||
char sources[128];
|
||||
snprintf(sources,sizeof(sources),"!s%s\n", b->sources);
|
||||
fwrite(sources,strlen(sources),1,f);
|
||||
fgets(sources,sizeof(sources),f);
|
||||
};
|
||||
|
||||
if(b->identify) {
|
||||
if(b->identify) {
|
||||
char ident[128];
|
||||
snprintf(ident,sizeof(ident),"!n" PACKAGE_STRING "\n");
|
||||
fwrite(ident,strlen(ident),1,f);
|
||||
fgets(ident,sizeof(ident),f);
|
||||
};
|
||||
|
||||
for(mc=b->macroses;mc;mc=mc->next) {
|
||||
for(mc=b->macroses;mc;mc=mc->next) {
|
||||
bgpq_expand_radb(f,bgpq_expanded_macro,b,"!i%s,1\n",mc->text);
|
||||
};
|
||||
if(b->generation>=T_PREFIXLIST) {
|
||||
if(b->generation>=T_PREFIXLIST) {
|
||||
unsigned i, j, k;
|
||||
for(mc=b->rsets;mc;mc=mc->next) {
|
||||
if(b->family==AF_INET) {
|
||||
for(mc=b->rsets;mc;mc=mc->next) {
|
||||
if(b->family==AF_INET) {
|
||||
bgpq_expand_radb(f,bgpq_expanded_prefix,b,"!i%s,1\n",mc->text);
|
||||
} else {
|
||||
if(!pipelining) {
|
||||
} else {
|
||||
if(!pipelining) {
|
||||
bgpq_expand_ripe(f,bgpq_expanded_v6prefix,b,
|
||||
"-T route6 -i member-of %s\n",mc->text);
|
||||
} else {
|
||||
} else {
|
||||
bgpq_pipeline(f,bgpq_expanded_v6prefix,b,
|
||||
"-T route6 -i member-of %s\n", mc->text);
|
||||
};
|
||||
};
|
||||
};
|
||||
for(k=0;k<sizeof(b->asn32s)/sizeof(unsigned char*);k++) {
|
||||
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) {
|
||||
if(k>0)
|
||||
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) {
|
||||
if(k>0)
|
||||
bgpq_expand_ripe(f,bgpq_expanded_v6prefix,b,
|
||||
"-T route6 -i origin as%u.%u\r\n", k,
|
||||
i*8+j);
|
||||
else
|
||||
else
|
||||
bgpq_expand_ripe(f,bgpq_expanded_v6prefix,b,
|
||||
"-T route6 -i origin as%u\r\n", i*8+j);
|
||||
} else {
|
||||
if(k>0)
|
||||
} else {
|
||||
if(k>0)
|
||||
bgpq_pipeline(f,bgpq_expanded_v6prefix,b,
|
||||
"-T route6 -i origin as%u.%u\r\n", k,
|
||||
i*8+j);
|
||||
else
|
||||
else
|
||||
bgpq_pipeline(f,bgpq_expanded_v6prefix,b,
|
||||
"-T route6 -i origin as%u\r\n", i*8+j);
|
||||
};
|
||||
} else {
|
||||
if(!pipelining) {
|
||||
if(k>0)
|
||||
} else {
|
||||
if(!pipelining) {
|
||||
if(k>0)
|
||||
bgpq_expand_radb(f,bgpq_expanded_prefix,b,
|
||||
"!gas%u.%u\n", k, i*8+j);
|
||||
else
|
||||
else
|
||||
bgpq_expand_radb(f,bgpq_expanded_prefix,b,
|
||||
"!gas%u\n", i*8+j);
|
||||
} else {
|
||||
if(k>0)
|
||||
} else {
|
||||
if(k>0)
|
||||
bgpq_pipeline(f,bgpq_expanded_prefix,b,
|
||||
"!gas%u.%u\n", k, i*8+j);
|
||||
else
|
||||
else
|
||||
bgpq_pipeline(f,bgpq_expanded_prefix,b,
|
||||
"!gas%u\n", i*8+j);
|
||||
};
|
||||
@@ -685,10 +695,10 @@ bgpq_expand(struct bgpq_expander* b)
|
||||
};
|
||||
};
|
||||
};
|
||||
if(pipelining && b->firstpipe) {
|
||||
if(b->family==AF_INET6) {
|
||||
if(pipelining && b->firstpipe) {
|
||||
if(b->family==AF_INET6) {
|
||||
bgpq_pipeline_dequeue_ripe(f,b);
|
||||
} else {
|
||||
} else {
|
||||
bgpq_pipeline_dequeue(f,b);
|
||||
};
|
||||
};
|
||||
|
||||
18
configure
vendored
18
configure
vendored
@@ -1,6 +1,6 @@
|
||||
#! /bin/sh
|
||||
# Guess values for system-dependent variables and create Makefiles.
|
||||
# Generated by GNU Autoconf 2.69 for bgpq3 0.1.25.
|
||||
# Generated by GNU Autoconf 2.69 for bgpq3 0.1.26.
|
||||
#
|
||||
# Report bugs to <snar@snar.spb.ru>.
|
||||
#
|
||||
@@ -579,8 +579,8 @@ MAKEFLAGS=
|
||||
# Identity of this package.
|
||||
PACKAGE_NAME='bgpq3'
|
||||
PACKAGE_TARNAME='bgpq3'
|
||||
PACKAGE_VERSION='0.1.25'
|
||||
PACKAGE_STRING='bgpq3 0.1.25'
|
||||
PACKAGE_VERSION='0.1.26'
|
||||
PACKAGE_STRING='bgpq3 0.1.26'
|
||||
PACKAGE_BUGREPORT='snar@snar.spb.ru'
|
||||
PACKAGE_URL=''
|
||||
|
||||
@@ -1187,7 +1187,7 @@ if test "$ac_init_help" = "long"; then
|
||||
# Omit some internal or obsolete options to make the list less imposing.
|
||||
# This message is too long to be a string in the A/UX 3.1 sh.
|
||||
cat <<_ACEOF
|
||||
\`configure' configures bgpq3 0.1.25 to adapt to many kinds of systems.
|
||||
\`configure' configures bgpq3 0.1.26 to adapt to many kinds of systems.
|
||||
|
||||
Usage: $0 [OPTION]... [VAR=VALUE]...
|
||||
|
||||
@@ -1248,7 +1248,7 @@ fi
|
||||
|
||||
if test -n "$ac_init_help"; then
|
||||
case $ac_init_help in
|
||||
short | recursive ) echo "Configuration of bgpq3 0.1.25:";;
|
||||
short | recursive ) echo "Configuration of bgpq3 0.1.26:";;
|
||||
esac
|
||||
cat <<\_ACEOF
|
||||
|
||||
@@ -1327,7 +1327,7 @@ fi
|
||||
test -n "$ac_init_help" && exit $ac_status
|
||||
if $ac_init_version; then
|
||||
cat <<\_ACEOF
|
||||
bgpq3 configure 0.1.25
|
||||
bgpq3 configure 0.1.26
|
||||
generated by GNU Autoconf 2.69
|
||||
|
||||
Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
@@ -1495,7 +1495,7 @@ cat >config.log <<_ACEOF
|
||||
This file contains any messages produced by compilers while
|
||||
running configure, to aid debugging if configure makes a mistake.
|
||||
|
||||
It was created by bgpq3 $as_me 0.1.25, which was
|
||||
It was created by bgpq3 $as_me 0.1.26, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
$ $0 $@
|
||||
@@ -3413,7 +3413,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
|
||||
# report actual input values of CONFIG_FILES etc. instead of their
|
||||
# values after options handling.
|
||||
ac_log="
|
||||
This file was extended by bgpq3 $as_me 0.1.25, which was
|
||||
This file was extended by bgpq3 $as_me 0.1.26, which was
|
||||
generated by GNU Autoconf 2.69. Invocation command line was
|
||||
|
||||
CONFIG_FILES = $CONFIG_FILES
|
||||
@@ -3475,7 +3475,7 @@ _ACEOF
|
||||
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
|
||||
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
|
||||
ac_cs_version="\\
|
||||
bgpq3 config.status 0.1.25
|
||||
bgpq3 config.status 0.1.26
|
||||
configured by $0, generated by GNU Autoconf 2.69,
|
||||
with options \\"\$ac_cs_config\\"
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
AC_INIT(bgpq3,0.1.25,snar@snar.spb.ru)
|
||||
AC_INIT(bgpq3,0.1.26,snar@snar.spb.ru)
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_PROG_CC
|
||||
AC_PROG_INSTALL
|
||||
|
||||
566
sx_prefix.c
566
sx_prefix.c
File diff suppressed because it is too large
Load Diff
@@ -46,6 +46,7 @@ void sx_prefix_destroy(struct sx_prefix* p);
|
||||
void sx_prefix_adjust_masklen(struct sx_prefix* p);
|
||||
struct sx_prefix* sx_prefix_new(int af, char* text);
|
||||
int sx_prefix_parse(struct sx_prefix* p, int af, char* text);
|
||||
int sx_prefix_range_parse(struct sx_radix_tree* t, int af, int ml, char* text);
|
||||
int sx_prefix_fprint(FILE* f, struct sx_prefix* p);
|
||||
int sx_prefix_snprintf(struct sx_prefix* p, char* rbuffer, int srb);
|
||||
int sx_prefix_jsnprintf(struct sx_prefix* p, char* rbuffer, int srb);
|
||||
|
||||
Reference in New Issue
Block a user