mirror of
https://github.com/bgp/bgpq4
synced 2025-02-28 08:53:11 +00:00
bgpq3 - complete rewrite of bgpq
This commit is contained in:
18
Makefile.in
Normal file
18
Makefile.in
Normal file
@@ -0,0 +1,18 @@
|
||||
CC=@CC@
|
||||
CFLAGS=@CFLAGS@ @DEFS@ -g -Wall -I. -O0
|
||||
LDADD=@LDFLAGS@ @LIBS@
|
||||
|
||||
OBJECTS=bgpq3.o sx_report.o bgpq_expander.o sx_slentry.o bgpq3_printer.o
|
||||
|
||||
|
||||
all: bgpq3
|
||||
|
||||
bgpq3: ${OBJECTS}
|
||||
${CC} ${CFLAGS} -o bgpq3 ${OBJECTS} ${LDADD}
|
||||
|
||||
.c.o:
|
||||
${CC} ${CFLAGS} -c $<
|
||||
|
||||
clean:
|
||||
rm -rf Makefile autom4te.cache bgpq3 config.h config.log config.status
|
||||
rm -rf *.o *.core core.* core
|
||||
122
bgpq3.c
Normal file
122
bgpq3.c
Normal file
@@ -0,0 +1,122 @@
|
||||
#if HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "bgpq3.h"
|
||||
#include "sx_report.h"
|
||||
|
||||
int
|
||||
usage(int ecode)
|
||||
{
|
||||
printf("Usage: bgpq3 [-h] [-S sources] <OBJECTS>...\n");
|
||||
printf(" -h : this help\n");
|
||||
printf(" -J : use Juniper replace formatted output\n");
|
||||
printf(" -l : use specified name for generated access/prefix/.. list\n");
|
||||
printf(" -S sources: use only specified sources (default:"
|
||||
" RADB,RIPE,APNIC)\n");
|
||||
exit(ecode);
|
||||
};
|
||||
|
||||
int
|
||||
main(int argc, char* argv[])
|
||||
{
|
||||
int c;
|
||||
struct bgpq_expander expander;
|
||||
int af=AF_INET;
|
||||
int widthSet=0;
|
||||
|
||||
bgpq_expander_init(&expander,af);
|
||||
expander.sources=getenv("IRRD_SOURCES");
|
||||
|
||||
while((c=getopt(argc,argv,"6hS:Jf:l:W:P"))!=EOF) {
|
||||
switch(c) {
|
||||
case '6': af=AF_INET6;
|
||||
expander.family=AF_INET6;
|
||||
break;
|
||||
case 'J': expander.vendor=V_JUNIPER;
|
||||
break;
|
||||
case 'f': expander.asnumber=atoi(optarg);
|
||||
if(expander.asnumber<0 || expander.asnumber>65535) {
|
||||
sx_report(SX_FATAL,"Invalid AS number: %s\n", optarg);
|
||||
exit(1);
|
||||
};
|
||||
expander.generation=T_ASPATH;
|
||||
break;
|
||||
case 'P': expander.generation=T_PREFIXLIST;
|
||||
break;
|
||||
case 'l': expander.name=optarg;
|
||||
break;
|
||||
case 'S': expander.sources=optarg;
|
||||
break;
|
||||
case 'W': expander.aswidth=atoi(optarg);
|
||||
if(expander.aswidth<1) {
|
||||
sx_report(SX_FATAL,"Invalid as-width: %s\n", optarg);
|
||||
exit(1);
|
||||
};
|
||||
widthSet=1;
|
||||
break;
|
||||
case 'h': usage(0);
|
||||
default : usage(1);
|
||||
};
|
||||
};
|
||||
|
||||
argc-=optind;
|
||||
argv+=optind;
|
||||
|
||||
if(!widthSet) {
|
||||
if(expander.generation==T_ASPATH) {
|
||||
if(expander.vendor==V_CISCO) {
|
||||
expander.aswidth=4;
|
||||
} else if(expander.vendor==V_JUNIPER) {
|
||||
expander.aswidth=8;
|
||||
};
|
||||
} else if(expander.generation==T_OASPATH) {
|
||||
if(expander.vendor==V_CISCO) {
|
||||
expander.aswidth=5;
|
||||
} else if(expander.vendor==V_JUNIPER) {
|
||||
expander.aswidth=8;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
if(!argv[0]) usage(1);
|
||||
|
||||
while(argv[0]) {
|
||||
if(!strncasecmp(argv[0],"AS-",3)) {
|
||||
bgpq_expander_add_asset(&expander,argv[0]);
|
||||
} else if(!strncasecmp(argv[0],"AS",2)) {
|
||||
bgpq_expander_add_as(&expander,argv[0]);
|
||||
} else {
|
||||
if(!bgpq_expander_add_prefix(&expander,argv[0]))
|
||||
exit(1);
|
||||
};
|
||||
argv++;
|
||||
argc--;
|
||||
};
|
||||
|
||||
if(!bgpq_expand(&expander)) {
|
||||
exit(1);
|
||||
};
|
||||
|
||||
switch(expander.generation) {
|
||||
case T_ASPATH: bgpq3_print_aspath(stdout,&expander);
|
||||
break;
|
||||
case T_PREFIXLIST: bgpq3_print_prefixlist(stdout,&expander);
|
||||
default :
|
||||
break;
|
||||
};
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
37
bgpq3.h
Normal file
37
bgpq3.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#ifndef BGPQ3_H_
|
||||
#define BGPQ3_H_
|
||||
|
||||
#include "sx_prefix.h"
|
||||
#include "sx_slentry.h"
|
||||
|
||||
typedef enum {
|
||||
V_CISCO = 0,
|
||||
V_JUNIPER
|
||||
} bgpq_vendor_t;
|
||||
|
||||
typedef enum {
|
||||
T_NONE = 0,
|
||||
T_ASPATH,
|
||||
T_OASPATH,
|
||||
T_PREFIXLIST
|
||||
} bgpq_gen_t;
|
||||
|
||||
struct bgpq_expander {
|
||||
struct sx_radix_tree* tree;
|
||||
unsigned char asnumbers[8192];
|
||||
struct sx_slentry* macroses;
|
||||
int family;
|
||||
char* sources;
|
||||
int asnumber, aswidth;
|
||||
char* name;
|
||||
bgpq_vendor_t vendor;
|
||||
bgpq_gen_t generation;
|
||||
};
|
||||
|
||||
int bgpq_expander_init(struct bgpq_expander* b, int af);
|
||||
int bgpq_expander_add_asset(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);
|
||||
|
||||
#endif
|
||||
|
||||
123
bgpq3_printer.c
Normal file
123
bgpq3_printer.c
Normal file
@@ -0,0 +1,123 @@
|
||||
#if HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "bgpq3.h"
|
||||
#include "sx_report.h"
|
||||
|
||||
int
|
||||
bgpq3_print_cisco_aspath(FILE* f, struct bgpq_expander* b)
|
||||
{
|
||||
int nc=0, i, j;
|
||||
fprintf(f,"no ip as-path access-list %s\n", b->name?b->name:"UNKNOWN");
|
||||
if(b->asnumbers[b->asnumber/8]&(0x80>>(b->asnumber%8))) {
|
||||
fprintf(f,"ip as-path access-list %s permit ^%i(_%i)*$\n",
|
||||
b->name?b->name:"UNKNOWN",b->asnumber,b->asnumber);
|
||||
};
|
||||
for(i=0;i<sizeof(b->asnumbers);i++) {
|
||||
for(j=0;j<8;j++) {
|
||||
if(b->asnumbers[i]&(0x80>>j)) {
|
||||
if(i*8+j==b->asnumber) continue;
|
||||
if(!nc) {
|
||||
fprintf(f,"ip as-path access-list %s permit"
|
||||
" ^%i(_[0-9]+)*_(%i", b->name?b->name:"UNKNOWN",
|
||||
b->asnumber,i*8+j);
|
||||
} else {
|
||||
fprintf(f,"|%i",i*8+j);
|
||||
}
|
||||
nc++;
|
||||
if(nc==b->aswidth) {
|
||||
fprintf(f,")$\n");
|
||||
nc=0;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
if(nc) fprintf(f,")$\n");
|
||||
return 0;
|
||||
};
|
||||
|
||||
int
|
||||
bgpq3_print_juniper_aspath(FILE* f, struct bgpq_expander* b)
|
||||
{
|
||||
int nc=0, lineNo=0, i, j;
|
||||
fprintf(f,"policy-options {\nreplace:\n as-path-group %s {\n",
|
||||
b->name?b->name:"UNKNOWN");
|
||||
|
||||
if(b->asnumbers[b->asnumber/8]&(0x80>>(b->asnumber%8))) {
|
||||
fprintf(f," as-path a%i \"^%i(%i)*$\";\n", lineNo, b->asnumber,
|
||||
b->asnumber);
|
||||
lineNo++;
|
||||
};
|
||||
for(i=0;i<sizeof(b->asnumbers);i++) {
|
||||
for(j=0;j<8;j++) {
|
||||
if(b->asnumbers[i]&(0x80>>j)) {
|
||||
if(i*8+j==b->asnumber) continue;
|
||||
if(!nc) {
|
||||
fprintf(f," as-path a%i \"^%i(.)*(%i",
|
||||
lineNo,b->asnumber,i*8+j);
|
||||
} else {
|
||||
fprintf(f,"|%i",i*8+j);
|
||||
}
|
||||
nc++;
|
||||
if(nc==b->aswidth) {
|
||||
fprintf(f,")$\";\n");
|
||||
nc=0;
|
||||
lineNo++;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
if(nc) fprintf(f,")$\";\n");
|
||||
fprintf(f," }\n}\n");
|
||||
return 0;
|
||||
};
|
||||
|
||||
int
|
||||
bgpq3_print_aspath(FILE* f, struct bgpq_expander* b)
|
||||
{
|
||||
if(b->vendor==V_JUNIPER) {
|
||||
return bgpq3_print_juniper_aspath(f,b);
|
||||
} else if(b->vendor==V_CISCO) {
|
||||
return bgpq3_print_cisco_aspath(f,b);
|
||||
} else {
|
||||
sx_report(SX_FATAL,"Unknown vendor %i\n", b->vendor);
|
||||
};
|
||||
return 0;
|
||||
};
|
||||
|
||||
void
|
||||
bgpq3_print_jprefix(struct sx_radix_node* n, void* ff)
|
||||
{
|
||||
char prefix[128];
|
||||
FILE* f=(FILE*)ff;
|
||||
if(!f) f=stdout;
|
||||
|
||||
sx_prefix_snprintf(&n->prefix,prefix,sizeof(prefix));
|
||||
fprintf(f," %s; (%i)\n",prefix,n->isGlue);
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
bgpq3_print_juniper_prefixlist(FILE* f, struct bgpq_expander* b)
|
||||
{
|
||||
printf("prefix-printer called\n");
|
||||
sx_radix_tree_foreach(b->tree,bgpq3_print_jprefix,stdout);
|
||||
return 0;
|
||||
};
|
||||
|
||||
int
|
||||
bgpq3_print_prefixlist(FILE* f, struct bgpq_expander* b)
|
||||
{
|
||||
switch(b->vendor) {
|
||||
case V_JUNIPER: return bgpq3_print_juniper_prefixlist(f,b);
|
||||
};
|
||||
return 0;
|
||||
};
|
||||
300
bgpq_expander.c
Normal file
300
bgpq_expander.c
Normal file
@@ -0,0 +1,300 @@
|
||||
#if HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "bgpq3.h"
|
||||
#include "sx_report.h"
|
||||
|
||||
int
|
||||
bgpq_expander_init(struct bgpq_expander* b, int af)
|
||||
{
|
||||
if(!af) af=AF_INET;
|
||||
if(!b) return 0;
|
||||
|
||||
memset(b,0,sizeof(struct bgpq_expander));
|
||||
|
||||
b->tree=sx_radix_tree_new(af);
|
||||
if(!b->tree) goto fixups;
|
||||
|
||||
b->family=af;
|
||||
b->sources="ripe,radb,apnic";
|
||||
b->aswidth=8;
|
||||
|
||||
return 1;
|
||||
fixups:
|
||||
/* if(b->tree) XXXXXXXXXXXXX sx_radix_tree_destroy(b->tree); */
|
||||
b->tree=NULL;
|
||||
free(b);
|
||||
return 0;
|
||||
};
|
||||
|
||||
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) {
|
||||
b->macroses=le;
|
||||
} else {
|
||||
struct sx_slentry* ln=b->macroses;
|
||||
while(ln->next) ln=ln->next;
|
||||
ln->next=le;
|
||||
};
|
||||
return 1;
|
||||
};
|
||||
|
||||
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",
|
||||
*eoa, as);
|
||||
return 0;
|
||||
};
|
||||
|
||||
if(*eoa=='.') {
|
||||
sx_report(SX_ERROR,"32-bit as numbers is not supported yet (%s)\n",as);
|
||||
return 0;
|
||||
};
|
||||
|
||||
if(asno<1 || asno>65535) {
|
||||
sx_report(SX_ERROR,"Invalid AS number in %s\n", as);
|
||||
return 0;
|
||||
};
|
||||
|
||||
b->asnumbers[asno/8]|=(0x80>>(asno%8));
|
||||
|
||||
return 1;
|
||||
};
|
||||
|
||||
int
|
||||
bgpq_expander_add_prefix(struct bgpq_expander* b, char* prefix)
|
||||
{
|
||||
struct sx_prefix p;
|
||||
if(!sx_prefix_parse(&p,b->family,prefix)) {
|
||||
sx_report(SX_ERROR,"Unable to parse prefix %s\n", prefix);
|
||||
return 0;
|
||||
};
|
||||
sx_radix_tree_insert(b->tree,&p);
|
||||
return 0;
|
||||
};
|
||||
|
||||
int
|
||||
bgpq_expanded_macro(char* as, void* udata)
|
||||
{
|
||||
struct bgpq_expander* ex=(struct bgp_expander*)udata;
|
||||
if(!ex) return 0;
|
||||
bgpq_expander_add_as(ex,as);
|
||||
return 1;
|
||||
};
|
||||
|
||||
int
|
||||
bgpq_expanded_prefix(char* as, void* udata)
|
||||
{
|
||||
struct bgpq_expander* ex=(struct bgp_expander*)udata;
|
||||
if(!ex) return 0;
|
||||
printf("expanded prefix %s\n", as);
|
||||
bgpq_expander_add_prefix(ex,as);
|
||||
return 1;
|
||||
};
|
||||
|
||||
int
|
||||
bgpq_expand_radb(int fd, int (*callback)(char*, void*), void* udata,
|
||||
char* fmt, ...)
|
||||
{
|
||||
char request[128];
|
||||
va_list ap;
|
||||
int ret;
|
||||
|
||||
va_start(ap,fmt);
|
||||
vsnprintf(request,sizeof(request),fmt,ap);
|
||||
va_end(ap);
|
||||
|
||||
write(fd,request,strlen(request));
|
||||
memset(request,0,sizeof(request));
|
||||
ret=read(fd,request,sizeof(request)-1);
|
||||
if(ret<0) {
|
||||
sx_report(SX_ERROR,"Error reading data from radb: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
};
|
||||
if(ret==0) {
|
||||
sx_report(SX_ERROR,"Connection with radb closed inexpeced\n");
|
||||
exit(1);
|
||||
};
|
||||
if(request[0]=='A') {
|
||||
char* eon, *c;
|
||||
long togot=strtol(request+1,&eon,10);
|
||||
char recvbuffer[togot+128];
|
||||
char* recvto;
|
||||
if(eon && *eon!='\n') {
|
||||
sx_report(SX_ERROR,"Number ends at wrong character: '%c'(%s)\n"
|
||||
,*eon,request);
|
||||
exit(1);
|
||||
};
|
||||
eon++;
|
||||
memset(recvbuffer,0,togot+128);
|
||||
memcpy(recvbuffer,eon,ret-(eon-request));
|
||||
recvto=recvbuffer+ret-(eon-request);
|
||||
togot-=ret-(eon-request);
|
||||
while(togot>0) {
|
||||
ret=read(fd,recvto,togot);
|
||||
if(ret<0) {
|
||||
sx_report(SX_ERROR,"Error reading data: %s\n",
|
||||
strerror(errno));
|
||||
exit(1);
|
||||
};
|
||||
if(ret==0) {
|
||||
sx_report(SX_ERROR,"Server unexpectedly closed the"
|
||||
" connection\n");
|
||||
exit(1);
|
||||
};
|
||||
togot-=ret;
|
||||
recvto+=ret;
|
||||
};
|
||||
if(togot==0) {
|
||||
memset(request,0,sizeof(request));
|
||||
ret=read(fd,request,sizeof(request)-1);
|
||||
if(ret>0) {
|
||||
if(request[0]!='C') {
|
||||
sx_report(SX_ERROR,"Wrong character after reply: %s\n",
|
||||
request);
|
||||
exit(0);
|
||||
};
|
||||
} else {
|
||||
if(ret==0) {
|
||||
sx_report(SX_ERROR,"Server inexpectedly closed"
|
||||
" connection\n");
|
||||
exit(0);
|
||||
} else {
|
||||
sx_report(SX_ERROR,"Error reading data from server:"
|
||||
" %s\n",
|
||||
strerror(errno));
|
||||
};
|
||||
};
|
||||
} else {
|
||||
/* togot < 0, initially. */
|
||||
if(recvto[togot]=='C') {
|
||||
/* ok, finised */
|
||||
} else if(recvto[togot]=='D') {
|
||||
/* nodata */
|
||||
} else if(recvto[togot]=='E') {
|
||||
} else if(recvto[togot]=='F') {
|
||||
sx_report(SX_FATAL,"Error from server: %s", recvto+togot);
|
||||
exit(1);
|
||||
};
|
||||
recvto[togot]=0;
|
||||
};
|
||||
for(c=recvbuffer; c<recvto;) {
|
||||
size_t spn=strcspn(c," \n");
|
||||
if(spn) c[spn]=0;
|
||||
if(c[0]==0) break;
|
||||
if(callback) callback(c,udata);
|
||||
c+=spn+1;
|
||||
};
|
||||
} else if(request[0]=='C') {
|
||||
/* no data */
|
||||
} else if(request[0]=='D') {
|
||||
/* ... */
|
||||
} else if(request[0]=='E') {
|
||||
/* XXXXXX */
|
||||
} else if(request[0]=='F') {
|
||||
/* XXXXXX */
|
||||
} else {
|
||||
sx_report(SX_ERROR,"Wrong reply: %s\n", request);
|
||||
exit(0);
|
||||
};
|
||||
return 0;
|
||||
};
|
||||
|
||||
int
|
||||
bgpq_expand(struct bgpq_expander* b)
|
||||
{
|
||||
int fd=-1, err;
|
||||
struct sx_slentry* mc;
|
||||
struct addrinfo hints, *res=NULL, *rp;
|
||||
memset(&hints,0,sizeof(struct addrinfo));
|
||||
|
||||
hints.ai_socktype=SOCK_STREAM;
|
||||
|
||||
err=getaddrinfo("whois.radb.net","43",&hints,&res);
|
||||
if(err) {
|
||||
sx_report(SX_ERROR,"Unable to resolve whois.radb.net: %s\n",
|
||||
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) continue;
|
||||
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) {
|
||||
shutdown(fd,SHUT_RDWR);
|
||||
close(fd);
|
||||
fd=-1;
|
||||
continue;
|
||||
};
|
||||
break;
|
||||
};
|
||||
freeaddrinfo(res);
|
||||
|
||||
if(fd==-1) {
|
||||
/* all our attempts to connect failed */
|
||||
sx_report(SX_ERROR,"All attempts to connect failed\n");
|
||||
exit(1);
|
||||
};
|
||||
|
||||
write(fd,"!!\n",3);
|
||||
|
||||
if(b->sources && b->sources[0]!=0) {
|
||||
char sources[128];
|
||||
snprintf(sources,sizeof(sources),"!s%s\n", b->sources);
|
||||
write(fd,sources,strlen(sources));
|
||||
};
|
||||
|
||||
for(mc=b->macroses;mc;mc=mc->next) {
|
||||
bgpq_expand_radb(fd,bgpq_expanded_macro,b,"!i%s,1\n",mc->text);
|
||||
};
|
||||
if(b->generation>=T_PREFIXLIST) {
|
||||
int i, j;
|
||||
for(i=0;i<sizeof(b->asnumbers);i++) {
|
||||
for(j=0;j<8;j++) {
|
||||
if(b->asnumbers[i]&(0x80>>j)) {
|
||||
bgpq_expand_radb(fd,bgpq_expanded_prefix,b,"!gas%i\n",
|
||||
i*8+j);
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
write(fd,"!q\n",3);
|
||||
shutdown(fd,SHUT_RDWR);
|
||||
close(fd);
|
||||
return 1;
|
||||
};
|
||||
|
||||
16
config.h.in
Normal file
16
config.h.in
Normal file
@@ -0,0 +1,16 @@
|
||||
/* config.h.in. Generated from configure.in by autoheader. */
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
24
configure.in
Normal file
24
configure.in
Normal file
@@ -0,0 +1,24 @@
|
||||
AC_INIT(bgpq3.c)
|
||||
AC_CONFIG_HEADER(config.h)
|
||||
AC_PROG_CC
|
||||
|
||||
if test -d "../libsxreport" ; then
|
||||
CFLAGS="$CFLAGS -I../libsxreport"
|
||||
CPPFLAGS="$CPPFLAGS -I../libsxreport"
|
||||
LDFLAGS="$LDFLAGS -L../libsxreport"
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADERS(sx_report.h,,[AC_MSG_ERROR([no sx_report.h])])
|
||||
AC_CHECK_LIB(sxreport,sx_report,,[AC_MSG_ERROR([no -lsxreport])])
|
||||
|
||||
if test -d "../libptree" ; then
|
||||
CFLAGS="$CFLAGS -I../libptree"
|
||||
CPPFLAGS="$CPPFLAGS -I../libptree"
|
||||
LDFLAGS="$LDFLAGS -L../libptree"
|
||||
fi
|
||||
|
||||
AC_CHECK_HEADERS(sx_prefix.h,,[AC_MSG_ERROR([no sx_prefix.h])])
|
||||
AC_CHECK_LIB(sxprefix,sx_prefix_new,,[AC_MSG_ERROR([no -lsxprefix])])
|
||||
|
||||
AC_OUTPUT(Makefile)
|
||||
|
||||
97
sx_report.c
Normal file
97
sx_report.c
Normal file
@@ -0,0 +1,97 @@
|
||||
#if HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "sx_report.h"
|
||||
|
||||
static int reportStderr=1;
|
||||
|
||||
static char const* 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:";
|
||||
};
|
||||
return "...... HMMMMM.... ERROR... \n";
|
||||
};
|
||||
|
||||
int
|
||||
sx_report(sx_report_t t, char* fmt, ...)
|
||||
{
|
||||
char buffer[1024];
|
||||
va_list ap;
|
||||
va_start(ap,fmt);
|
||||
|
||||
vsnprintf(buffer,sizeof(buffer),fmt,ap);
|
||||
va_end(ap);
|
||||
|
||||
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,"Warning: %s", buffer);
|
||||
break;
|
||||
case SX_DEBUG:
|
||||
syslog(LOG_DEBUG,"Debug: %s", buffer);
|
||||
break;
|
||||
};
|
||||
};
|
||||
|
||||
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 buffer[1024];
|
||||
char bline[1024];
|
||||
|
||||
va_list ap;
|
||||
va_start(ap,fmt);
|
||||
|
||||
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);
|
||||
} else {
|
||||
syslog(LOG_DEBUG,"%s %s", bline, buffer);
|
||||
};
|
||||
|
||||
return 0;
|
||||
};
|
||||
|
||||
void
|
||||
sx_openlog(char* progname)
|
||||
{
|
||||
openlog(progname?progname:"<unknown>",LOG_PID,LOG_DAEMON);
|
||||
reportStderr=0;
|
||||
};
|
||||
|
||||
24
sx_report.h
Normal file
24
sx_report.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#ifndef SX_REPORT_H_
|
||||
#define SX_REPORT_H_
|
||||
|
||||
typedef enum {
|
||||
SX_DEBUG = 0,
|
||||
SX_NOTICE,
|
||||
SX_ERROR,
|
||||
SX_MISFEATURE,
|
||||
SX_FATAL
|
||||
} sx_report_t;
|
||||
|
||||
/* opens syslog and disables logging to stderr */
|
||||
void sx_openlog(char* progname);
|
||||
|
||||
int sx_report(sx_report_t, char* fmt, ...)
|
||||
__attribute__ ((format (printf, 2, 3)));
|
||||
|
||||
int sx_debug(char const* const, char const* const, int const, char* fmt, ...)
|
||||
__attribute__ ((format (printf, 4, 5)));
|
||||
|
||||
#define SX_DEBUG(a,b,c...) if(a) sx_debug(__FILE__,__FUNCTION__,__LINE__,\
|
||||
b, ## c);
|
||||
|
||||
#endif
|
||||
16
sx_slentry.c
Normal file
16
sx_slentry.c
Normal file
@@ -0,0 +1,16 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include "sx_slentry.h"
|
||||
|
||||
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);
|
||||
return e;
|
||||
};
|
||||
11
sx_slentry.h
Normal file
11
sx_slentry.h
Normal file
@@ -0,0 +1,11 @@
|
||||
#ifndef SX_SLENTRY_H_
|
||||
#define SX_SLENTRY_H_
|
||||
|
||||
struct sx_slentry {
|
||||
struct sx_slentry* next;
|
||||
char* text;
|
||||
};
|
||||
|
||||
struct sx_slentry* sx_slentry_new(char* text);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user