diff --git a/.hgignore b/.hgignore index b88d92f..ddb72e4 100644 --- a/.hgignore +++ b/.hgignore @@ -1,9 +1,14 @@ \.o$ -config.log -config.status -bgpdump -testbgpdump -libbgpdump.a -libbgpdump.so -Makefile -test_out/.* +\.pbxuser$ +\.mode1v3$ +\.swp$ +^bgpdump-config.h$ +^config.log$ +^config.status$ +^bgpdump$ +^testbgpdump$ +^libbgpdump.a$ +^libbgpdump.so$ +^Makefile$ +^test_out/.* +^build/ diff --git a/ChangeLog b/ChangeLog index d4ebd8f..1afdadb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -8,6 +8,13 @@ PLEASE DO NOT E-MAIL INDIVIDUAL DEVELOPERS ABOUT ISSUES, AS YOUR E-MAIL MAY BE LOST =============================================== +2010-09-03 Devin Bayer + * Fix parsing of IPv6 NEXT_HOP attributes + * Add clearer command-line options + * Add logging to STDERR + * Add dumping to files instead of STDOUT + * Add regression test suite + 2009-11-24 Roman Kalyakin * Fixed incorrect output when running with -m which was introduced by a change in one of the previous versions. (issue IS-439) diff --git a/Makefile.in b/Makefile.in index 7ef1fa9..b6544bf 100644 --- a/Makefile.in +++ b/Makefile.in @@ -11,13 +11,12 @@ RANLIB = @RANLIB@ SYS_LIBS= @LIBS@ -LIB_H = bgpdump.h bgpdump_attr.h bgpdump_formats.h bgpdump_lib.h bgpdump_mstream.h cfile_tools.h -LIB_C = bgpdump_lib.c bgpdump_mstream.c cfile_tools.c -LIB_O = bgpdump_lib.o bgpdump_mstream.o cfile_tools.o +LIB_H = bgpdump.h bgpdump_attr.h bgpdump_formats.h bgpdump_lib.h bgpdump_mstream.h cfile_tools.h util.h +LIB_O = bgpdump_lib.o bgpdump_mstream.o cfile_tools.o util.o -all: libbgpdump.so libbgpdump.a testbgpdump bgpdump +all: libbgpdump.so bgpdump -libbgpdump.a: $(LIB_H) $(LIB_C) $(LIB_O) Makefile +libbgpdump.a: $(LIB_H) $(LIB_O) Makefile $(AR) r libbgpdump.a $(LIB_O) $(RANLIB) libbgpdump.a @@ -37,7 +36,7 @@ test: test-clean bgpdump ./test.sh clean: test-clean - rm -f libbgpdump.so libbgpdump.a testbgpdump bgpdump *.o + rm -f libbgpdump.so libbgpdump.a testbgpdump bgpdump $(LIB_O) distclean: clean rm -rf config.log config.status *.dSYM core *.core autom4te.cache bgpdump-config.h Makefile diff --git a/bgpdump.1 b/bgpdump.1 new file mode 100644 index 0000000..515e3b1 --- /dev/null +++ b/bgpdump.1 @@ -0,0 +1,79 @@ +.\"Modified from man(1) of FreeBSD, the NetBSD mdoc.template, and mdoc.samples. +.\"See Also: +.\"man mdoc.samples for a complete listing of options +.\"man mdoc for the short list of editing options +.\"/usr/share/misc/mdoc.template +.Dd 8/31/10 \" DATE +.Dt bgpdump 1 \" Program name and manual section number +.Os Darwin +.Sh NAME \" Section Header - required - don't modify +.Nm bgpdump, +.\" The following lines are read in generating the apropos(man -k) database. Use only key +.\" words here as the database is built based on the words here and in the .ND line. +.Nm Other_name_for_same_program(), +.Nm Yet another name for the same program. +.\" Use .Nm macro to designate other names for the documented program. +.Nd This line parsed for whatis database. +.Sh SYNOPSIS \" Section Header - required - don't modify +.Nm +.Op Fl abcd \" [-abcd] +.Op Fl a Ar path \" [-a path] +.Op Ar file \" [file] +.Op Ar \" [file ...] +.Ar arg0 \" Underlined argument - use .Ar anywhere to underline +arg2 ... \" Arguments +.Sh DESCRIPTION \" Section Header - required - don't modify +Use the .Nm macro to refer to your program throughout the man page like such: +.Nm +Underlining is accomplished with the .Ar macro like this: +.Ar underlined text . +.Pp \" Inserts a space +A list of items with descriptions: +.Bl -tag -width -indent \" Begins a tagged list +.It item a \" Each item preceded by .It macro +Description of item a +.It item b +Description of item b +.El \" Ends the list +.Pp +A list of flags and their descriptions: +.Bl -tag -width -indent \" Differs from above in tag removed +.It Fl a \"-a flag as a list item +Description of -a flag +.It Fl b +Description of -b flag +.El \" Ends the list +.Pp +.\" .Sh ENVIRONMENT \" May not be needed +.\" .Bl -tag -width "ENV_VAR_1" -indent \" ENV_VAR_1 is width of the string ENV_VAR_1 +.\" .It Ev ENV_VAR_1 +.\" Description of ENV_VAR_1 +.\" .It Ev ENV_VAR_2 +.\" Description of ENV_VAR_2 +.\" .El +.Sh FILES \" File used or created by the topic of the man page +.Bl -tag -width "/Users/joeuser/Library/really_long_file_name" -compact +.It Pa /usr/share/file_name +FILE_1 description +.It Pa /Users/joeuser/Library/really_long_file_name +FILE_2 description +.El \" Ends the list +.\" .Sh DIAGNOSTICS \" May not be needed +.\" .Bl -diag +.\" .It Diagnostic Tag +.\" Diagnostic informtion here. +.\" .It Diagnostic Tag +.\" Diagnostic informtion here. +.\" .El +.Sh SEE ALSO +.\" List links in ascending order by section, alphabetically within a section. +.\" Please do not reference files that do not exist without filing a bug report +.Xr a 1 , +.Xr b 1 , +.Xr c 1 , +.Xr a 2 , +.Xr b 2 , +.Xr a 3 , +.Xr b 3 +.\" .Sh BUGS \" Document known, unremedied bugs +.\" .Sh HISTORY \" Document history if command behaves in a unique manner \ No newline at end of file diff --git a/bgpdump.c b/bgpdump.c index 929b22b..c9a0ef2 100644 --- a/bgpdump.c +++ b/bgpdump.c @@ -1,38 +1,27 @@ /* - -Copyright (c) 2007 RIPE NCC - - -All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, provided -that the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the name of the author not be used in advertising or -publicity pertaining to distribution of the software without specific, -written prior permission. - -THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL -AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY -DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN -AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -*/ - -/* - + Copyright (c) 2007 - 2010 RIPE NCC - All Rights Reserved + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, provided + that the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation, and that the name of the author not be used in advertising or + publicity pertaining to distribution of the software without specific, + written prior permission. + + THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL + AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + Parts of this code have been engineered after analiyzing GNU Zebra's source code and therefore might contain declarations/code from GNU Zebra, Copyright (C) 1999 Kunihiro Ishiguro. Zebra is a free routing software, distributed under the GNU General Public License. A copy of this license is included with libbgpdump. -*/ - -/* Original Author: Shufu Mao(msf98@mails.tsinghua.edu.cn) */ @@ -41,21 +30,26 @@ Original Author: Shufu Mao(msf98@mails.tsinghua.edu.cn) #endif #include "bgpdump_lib.h" -#include +#include "util.h" +#include +#include +#include #include #include #include #include +#include + +void process(BGPDUMP_ENTRY *entry); +void show_attr(attributes_t *attr); +void show_prefixes(int count,struct prefix *prefix); +void table_line_announce_1(int mode,struct mp_nlri *prefix,int count,BGPDUMP_ENTRY *entry,char *time_str); +void table_line_announce(int mode,struct prefix *prefix,int count,BGPDUMP_ENTRY *entry,char *time_str); +void table_line_withdraw(int mode,struct prefix *prefix,int count,BGPDUMP_ENTRY *entry,char *time_str); +void table_line_mrtd_route(int mode,BGPDUMP_MRTD_TABLE_DUMP *route,BGPDUMP_ENTRY *entry, int timetype); +void table_line_dump_v2_prefix(int mode,BGPDUMP_TABLE_DUMP_V2_PREFIX *e,BGPDUMP_ENTRY *entry,int timetype); - void process(BGPDUMP_ENTRY *entry); - void show_attr(struct attr *attr); - void show_prefixes(int count,struct prefix *prefix); - void table_line_announce_1(int mode,struct mp_nlri *prefix,int count,BGPDUMP_ENTRY *entry,char *time_str); - void table_line_announce(int mode,struct prefix *prefix,int count,BGPDUMP_ENTRY *entry,char *time_str); - void table_line_withdraw(int mode,struct prefix *prefix,int count,BGPDUMP_ENTRY *entry,char *time_str); - void table_line_mrtd_route(int mode,BGPDUMP_MRTD_TABLE_DUMP *route,BGPDUMP_ENTRY *entry, int timetype); - void table_line_dump_v2_prefix(int mode,BGPDUMP_TABLE_DUMP_V2_PREFIX *e,BGPDUMP_ENTRY *entry,int timetype); #ifdef BGPDUMP_HAVE_IPV6 void show_prefixes6(int count,struct prefix *prefix); void table_line_withdraw6(int mode,struct prefix *prefix,int count,BGPDUMP_ENTRY *entry,char *time_str); @@ -63,8 +57,26 @@ Original Author: Shufu Mao(msf98@mails.tsinghua.edu.cn) #endif - static int mode=0; - static int timetype=0; +static int mode=0; +static int timetype=0; + +static const char USAGE[] = "\ +Usage: bgpdump [-m|-M] [-t dump|-t change] [-O ] \n\ +bgpdump translates binary MRT files (possibly compressed) into readable output\n\ +Output mode:\n\ + -H multi-line human-readable output (the default)\n\ + -m output in one-line machine readable format 1\n\ + -M output in one-line machine readable format 2\n\ +\n\ +Common Options:\n\ + -O output to instead of STDOUT\n\ + -s log to syslog (the default)\n\ + -v log to STDERR\n\ +\n\ +Options for -m and -M modes:\n\ + -t dump timestamps for RIB dumps reflect the time of the dump (the default)\n\ + -t change timestamps for RIB dumps reflect the last route modification\n\ +\n"; int main(int argc, char *argv[]) { @@ -73,41 +85,74 @@ int main(int argc, char *argv[]) { extern char *optarg; char c; extern int optind; - char *usage = "Usage: bgpdump [-m] [-M] [-t dump|change ] input_binary_file(s)\n\ - -m and -M produce two different kinds of binary formats,\n\ - -t defines whether timestamps in machine-readable format should be the timestamp of\n\ - when the dump was made, or when the dumped route was last change (only effective for RIB dumps)\n"; - - while ((c=getopt(argc,argv,"if:o:t:mM"))!=-1) + int fd; + bool usage_error = false; + bool use_syslog = true; + + log_to_stderr(); + + while ((c=getopt(argc,argv,"if:o:t:mMHO:sv"))!=-1) switch(c) { + case 'H': + mode=0; + break; case 'm': - mode=1; - break; + mode=1; + break; case 'M': - mode=2; - break; + mode=2; + break; case 't': - if(strcmp(optarg,"dump")==0){ - timetype=0; - }else if(strcmp(optarg,"change")==0){ - timetype=1; - } - default: - break; + if(strcmp(optarg,"dump")==0){ + timetype=0; + } else if(strcmp(optarg,"change")==0){ + timetype=1; + } else { + printf("unknown -t option\n"); + exit(1); + } + break; + case 'O': + fprintf(stderr, "redirecting output to '%s'\n", optarg); + fd = open(optarg, O_WRONLY|O_CREAT, 0666); + if(fd < 0 || 0 > dup2(fd, STDOUT_FILENO)) { + perror("can't open output file"); + exit(1); + } + break; + case 's': + use_syslog = true; + break; + case 'v': + use_syslog = false; + break; + case 'i': + case 'f': + case 'o': + warn("ignoring option '-%c'", c); + break; + case '?': + default: + usage_error = true; } - argc -= optind; - argv += optind; + argc -= optind; + argv += optind; - if(argc>=1 && argv[0] != NULL) { - my_dump=bgpdump_open_dump(argv[0]); - } else { - my_dump=bgpdump_open_dump("dumps/updates.20020701.0032"); + if(use_syslog) { + info("logging to syslog"); + log_to_syslog(); } - if(my_dump==NULL) { - printf("%s",usage); - exit(1); + if(usage_error || argc != 1) { + if(argc != 1) + err("you must supply exactly one file to process"); + fprintf(stderr, "%s", USAGE); + exit(1); + } + + if(argc>=1 && argv[0] != NULL) { + my_dump=bgpdump_open_dump(argv[0]); } do { @@ -861,7 +906,7 @@ void process(BGPDUMP_ENTRY *entry) { printf("\n"); } -void show_attr(struct attr *attr) { +void show_attr(attributes_t *attr) { if(attr != NULL) { @@ -1558,109 +1603,98 @@ void table_line_mrtd_route(int mode,BGPDUMP_MRTD_TABLE_DUMP *route,BGPDUMP_ENTRY } +static char *describe_origin(int origin) { + if(origin == 0) return "IGP"; + if(origin == 1) return "EGP"; + return "INCOMPLETE"; +} void table_line_dump_v2_prefix(int mode,BGPDUMP_TABLE_DUMP_V2_PREFIX *e,BGPDUMP_ENTRY *entry,int timetype) { - struct tm *time = NULL; - char tmp1[20]; - char tmp2[20]; - unsigned int npref; - unsigned int nmed; - char time_str[20]; + struct tm *time = NULL; + unsigned int npref; + unsigned int nmed; + char time_str[20]; char peer[BGPDUMP_ADDRSTRLEN], prefix[BGPDUMP_ADDRSTRLEN], nexthop[BGPDUMP_ADDRSTRLEN]; - - int i; - - for(i = 0; i < e->entry_count; i++){ - - switch (e->entries[i].attr->origin) { - - case 0 : - sprintf(tmp1,"IGP"); - break; - case 1: - sprintf(tmp1,"EGP"); - break; - case 2: - default: - sprintf(tmp1,"INCOMPLETE"); - break; - } - if (e->entries[i].attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) - sprintf(tmp2,"AG"); - else - sprintf(tmp2,"NAG"); - - if(e->entries[i].peer->afi == AFI_IP){ - inet_ntop(AF_INET, &e->entries[i].peer->peer_ip, peer, BGPDUMP_ADDRSTRLEN); + + int i; + + for(i = 0; i < e->entry_count; i++) { + attributes_t *attr = e->entries[i].attr; + if(! attr) + continue; + + char *origin = describe_origin(attr->origin); + char *aspath_str = (attr->aspath) ? attr->aspath->str: ""; + char *aggregate = attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE) ? "AG" : "NAG"; + + if(e->entries[i].peer->afi == AFI_IP){ + inet_ntop(AF_INET, &e->entries[i].peer->peer_ip, peer, BGPDUMP_ADDRSTRLEN); #ifdef BGPDUMP_HAVE_IPV6 - } else if(e->entries[i].peer->afi == AFI_IP6){ - inet_ntop(AF_INET6, &e->entries[i].peer->peer_ip, peer, BGPDUMP_ADDRSTRLEN); + } else if(e->entries[i].peer->afi == AFI_IP6){ + inet_ntop(AF_INET6, &e->entries[i].peer->peer_ip, peer, BGPDUMP_ADDRSTRLEN); #endif - } - - char *aspath_str = (e->entries[i].attr->aspath) ? e->entries[i].attr->aspath->str: ""; - - - if(e->afi == AFI_IP) { - inet_ntop(AF_INET, &e->prefix.v4_addr, prefix, BGPDUMP_ADDRSTRLEN); + } + + if(e->afi == AFI_IP) { + inet_ntop(AF_INET, &e->prefix.v4_addr, prefix, BGPDUMP_ADDRSTRLEN); #ifdef BGPDUMP_HAVE_IPV6 - } else if(e->afi == AFI_IP6) { - inet_ntop(AF_INET6, &e->prefix.v6_addr, prefix, BGPDUMP_ADDRSTRLEN); + } else if(e->afi == AFI_IP6) { + inet_ntop(AF_INET6, &e->prefix.v6_addr, prefix, BGPDUMP_ADDRSTRLEN); #endif - } - - if (mode == 1) - { - if(timetype==0){ - printf("TABLE_DUMP2|%ld|B|%s|%s|",entry->time,peer,print_asn(e->entries[i].peer->peer_as)); - }else if(timetype==1){ - printf("TABLE_DUMP2|%u|B|%s|%s|",e->entries[i].originated_time,peer,print_asn(e->entries[i].peer->peer_as)); - } - printf("%s/%d|%s|%s|",prefix,e->prefix_length,aspath_str,tmp1); - - npref=e->entries[i].attr->local_pref; - if( (e->entries[i].attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF) ) ==0) - npref=0; - nmed=e->entries[i].attr->med; - if( (e->entries[i].attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC) ) ==0) - nmed=0; - + } + + if (mode == 1) + { + if(timetype==0){ + printf("TABLE_DUMP2|%ld|B|%s|%s|",entry->time,peer,print_asn(e->entries[i].peer->peer_as)); + }else if(timetype==1){ + printf("TABLE_DUMP2|%u|B|%s|%s|",e->entries[i].originated_time,peer,print_asn(e->entries[i].peer->peer_as)); + } + printf("%s/%d|%s|%s|",prefix,e->prefix_length,aspath_str,origin); + + npref=attr->local_pref; + if( (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF) ) ==0) + npref=0; + nmed=attr->med; + if( (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC) ) ==0) + nmed=0; + #ifdef BGPDUMP_HAVE_IPV6 - if ((e->entries[i].attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI)) && e->entries[i].attr->mp_info->announce[AFI_IP6][SAFI_UNICAST]) - { - inet_ntop(AF_INET6,&e->entries[i].attr->mp_info->announce[AFI_IP6][SAFI_UNICAST]->nexthop,nexthop,sizeof(nexthop)); - } - else + if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI)) && attr->mp_info->announce[AFI_IP6][SAFI_UNICAST]) + { + inet_ntop(AF_INET6,&attr->mp_info->announce[AFI_IP6][SAFI_UNICAST]->nexthop,nexthop,sizeof(nexthop)); + } + else #endif - { - strncpy(nexthop, inet_ntoa(e->entries[i].attr->nexthop), BGPDUMP_ADDRSTRLEN); - } - printf("%s|%u|%u|",nexthop,npref,nmed); - - if( (e->entries[i].attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES) ) !=0) - printf("%s|%s|",e->entries[i].attr->community->str+1,tmp2); - else - printf("|%s|",tmp2); - - if (e->entries[i].attr->aggregator_addr.s_addr != -1) - printf("%s %s|\n",print_asn(e->entries[i].attr->aggregator_as),inet_ntoa(e->entries[i].attr->aggregator_addr)); - else - printf("|\n"); - } - else - { - if(timetype==0){ - time=gmtime(&entry->time); - }else if(timetype==1){ - time_t time_temp = (time_t)((e->entries[i]).originated_time); - time=gmtime(&time_temp); - } - time2str(time,time_str); - printf("TABLE_DUMP_V2|%s|A|%s|%s|",time_str,peer,print_asn(e->entries[i].peer->peer_as)); - printf("%s/%d|%s|%s\n",prefix,e->prefix_length,aspath_str,tmp1); - - } - } - + { + strncpy(nexthop, inet_ntoa(attr->nexthop), BGPDUMP_ADDRSTRLEN); + } + printf("%s|%u|%u|",nexthop,npref,nmed); + + if( (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES) ) !=0) + printf("%s|%s|",attr->community->str+1,aggregate); + else + printf("|%s|",aggregate); + + if (attr->aggregator_addr.s_addr != -1) + printf("%s %s|\n",print_asn(attr->aggregator_as),inet_ntoa(attr->aggregator_addr)); + else + printf("|\n"); + } + else + { + if(timetype==0){ + time=gmtime(&entry->time); + }else if(timetype==1){ + time_t time_temp = (time_t)((e->entries[i]).originated_time); + time=gmtime(&time_temp); + } + time2str(time,time_str); + printf("TABLE_DUMP_V2|%s|A|%s|%s|",time_str,peer,print_asn(e->entries[i].peer->peer_as)); + printf("%s/%d|%s|%s\n",prefix,e->prefix_length,aspath_str,origin); + + } + } + } diff --git a/bgpdump.h b/bgpdump.h index 6a3dc33..6c857dc 100644 --- a/bgpdump.h +++ b/bgpdump.h @@ -1,41 +1,27 @@ -/* $Id$ */ /* - -Copyright (c) 2007 RIPE NCC - - -All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, provided -that the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the name of the author not be used in advertising or -publicity pertaining to distribution of the software without specific, -written prior permission. - -THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL -AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY -DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN -AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -*/ - -/* - + Copyright (c) 2007 - 2010 RIPE NCC - All Rights Reserved + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, provided + that the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation, and that the name of the author not be used in advertising or + publicity pertaining to distribution of the software without specific, + written prior permission. + + THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL + AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + Parts of this code have been engineered after analiyzing GNU Zebra's source code and therefore might contain declarations/code from GNU Zebra, Copyright (C) 1999 Kunihiro Ishiguro. Zebra is a free routing software, distributed under the GNU General Public License. A copy of this license is included with libbgpdump. -*/ - - -/* -------------------------------------------------------------------------------- Original Author: Dan Ardelean (dan@ripe.net) */ diff --git a/bgpdump.xcodeproj/project.pbxproj b/bgpdump.xcodeproj/project.pbxproj new file mode 100644 index 0000000..8c9ac56 --- /dev/null +++ b/bgpdump.xcodeproj/project.pbxproj @@ -0,0 +1,352 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 45; + objects = { + +/* Begin PBXBuildFile section */ + 4DF74766122D4E800092F3E2 /* bgpdump.c in Sources */ = {isa = PBXBuildFile; fileRef = 4DF7475F122D4E800092F3E2 /* bgpdump.c */; }; + 4DF7479F122D52510092F3E2 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DF7477A122D51850092F3E2 /* libz.dylib */; }; + 4DF747A0122D525A0092F3E2 /* libbz2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DF7477C122D51990092F3E2 /* libbz2.dylib */; }; + 4DF747A4122D52900092F3E2 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DF7477A122D51850092F3E2 /* libz.dylib */; }; + 4DF747A5122D529D0092F3E2 /* libbz2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 4DF7477C122D51990092F3E2 /* libbz2.dylib */; }; + 4DF747A6122D52C30092F3E2 /* bgpdump_lib.c in Sources */ = {isa = PBXBuildFile; fileRef = 4DF74759122D4E800092F3E2 /* bgpdump_lib.c */; }; + 4DF747A7122D52C30092F3E2 /* bgpdump_mstream.c in Sources */ = {isa = PBXBuildFile; fileRef = 4DF7475B122D4E800092F3E2 /* bgpdump_mstream.c */; }; + 4DF747A8122D52C50092F3E2 /* cfile_tools.c in Sources */ = {isa = PBXBuildFile; fileRef = 4DF74761122D4E800092F3E2 /* cfile_tools.c */; }; + 4DF74863122E52060092F3E2 /* util.c in Sources */ = {isa = PBXBuildFile; fileRef = 4DF74862122E52060092F3E2 /* util.c */; }; + 4DF74864122E52060092F3E2 /* util.h in Headers */ = {isa = PBXBuildFile; fileRef = 4DF74861122E52060092F3E2 /* util.h */; }; + 4DF74865122E52060092F3E2 /* util.c in Sources */ = {isa = PBXBuildFile; fileRef = 4DF74862122E52060092F3E2 /* util.c */; }; + 8DD76FB00486AB0100D96B5E /* bgpdump.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = C6A0FF2C0290799A04C91782 /* bgpdump.1 */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 8DD76FAF0486AB0100D96B5E /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 8; + dstPath = /usr/share/man/man1/; + dstSubfolderSpec = 0; + files = ( + 8DD76FB00486AB0100D96B5E /* bgpdump.1 in CopyFiles */, + ); + runOnlyForDeploymentPostprocessing = 1; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 4DF74757122D4E800092F3E2 /* bgpdump_attr.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bgpdump_attr.h; sourceTree = ""; }; + 4DF74758122D4E800092F3E2 /* bgpdump_formats.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bgpdump_formats.h; sourceTree = ""; }; + 4DF74759122D4E800092F3E2 /* bgpdump_lib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bgpdump_lib.c; sourceTree = ""; }; + 4DF7475A122D4E800092F3E2 /* bgpdump_lib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bgpdump_lib.h; sourceTree = ""; }; + 4DF7475B122D4E800092F3E2 /* bgpdump_mstream.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bgpdump_mstream.c; sourceTree = ""; }; + 4DF7475C122D4E800092F3E2 /* bgpdump_mstream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bgpdump_mstream.h; sourceTree = ""; }; + 4DF7475D122D4E800092F3E2 /* bgpdump-config.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "bgpdump-config.h"; sourceTree = ""; }; + 4DF7475E122D4E800092F3E2 /* bgpdump-config.h.in */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "bgpdump-config.h.in"; sourceTree = ""; }; + 4DF7475F122D4E800092F3E2 /* bgpdump.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bgpdump.c; sourceTree = ""; }; + 4DF74760122D4E800092F3E2 /* bgpdump.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bgpdump.h; sourceTree = ""; }; + 4DF74761122D4E800092F3E2 /* cfile_tools.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cfile_tools.c; sourceTree = ""; }; + 4DF74762122D4E800092F3E2 /* cfile_tools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cfile_tools.h; sourceTree = ""; }; + 4DF74763122D4E800092F3E2 /* test.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = test.c; sourceTree = ""; }; + 4DF7477A122D51850092F3E2 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; + 4DF7477C122D51990092F3E2 /* libbz2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libbz2.dylib; path = usr/lib/libbz2.dylib; sourceTree = SDKROOT; }; + 4DF7479C122D52440092F3E2 /* liblibbgpdump.dylib */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.dylib"; includeInIndex = 0; path = liblibbgpdump.dylib; sourceTree = BUILT_PRODUCTS_DIR; }; + 4DF747AD122D53000092F3E2 /* README */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README; sourceTree = ""; }; + 4DF747AE122D53000092F3E2 /* README.ipv6 */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = README.ipv6; sourceTree = ""; }; + 4DF747AF122D53130092F3E2 /* ChangeLog */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ChangeLog; sourceTree = ""; }; + 4DF74861122E52060092F3E2 /* util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = util.h; sourceTree = ""; }; + 4DF74862122E52060092F3E2 /* util.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = util.c; sourceTree = ""; }; + 8DD76FB20486AB0100D96B5E /* bgpdump */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = bgpdump; sourceTree = BUILT_PRODUCTS_DIR; }; + C6A0FF2C0290799A04C91782 /* bgpdump.1 */ = {isa = PBXFileReference; lastKnownFileType = text.man; path = bgpdump.1; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 4DF7479A122D52440092F3E2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4DF7479F122D52510092F3E2 /* libz.dylib in Frameworks */, + 4DF747A0122D525A0092F3E2 /* libbz2.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DD76FAD0486AB0100D96B5E /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4DF747A4122D52900092F3E2 /* libz.dylib in Frameworks */, + 4DF747A5122D529D0092F3E2 /* libbz2.dylib in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 08FB7794FE84155DC02AAC07 /* bgpdump */ = { + isa = PBXGroup; + children = ( + 08FB7795FE84155DC02AAC07 /* Source */, + C6A0FF2B0290797F04C91782 /* Documentation */, + 1AB674ADFE9D54B511CA2CBB /* Products */, + 4DF7477A122D51850092F3E2 /* libz.dylib */, + 4DF7477C122D51990092F3E2 /* libbz2.dylib */, + ); + name = bgpdump; + sourceTree = ""; + }; + 08FB7795FE84155DC02AAC07 /* Source */ = { + isa = PBXGroup; + children = ( + 4DF74757122D4E800092F3E2 /* bgpdump_attr.h */, + 4DF74758122D4E800092F3E2 /* bgpdump_formats.h */, + 4DF74759122D4E800092F3E2 /* bgpdump_lib.c */, + 4DF7475A122D4E800092F3E2 /* bgpdump_lib.h */, + 4DF7475B122D4E800092F3E2 /* bgpdump_mstream.c */, + 4DF7475C122D4E800092F3E2 /* bgpdump_mstream.h */, + 4DF7475D122D4E800092F3E2 /* bgpdump-config.h */, + 4DF7475E122D4E800092F3E2 /* bgpdump-config.h.in */, + 4DF7475F122D4E800092F3E2 /* bgpdump.c */, + 4DF74760122D4E800092F3E2 /* bgpdump.h */, + 4DF74761122D4E800092F3E2 /* cfile_tools.c */, + 4DF74762122D4E800092F3E2 /* cfile_tools.h */, + 4DF74763122D4E800092F3E2 /* test.c */, + 4DF74861122E52060092F3E2 /* util.h */, + 4DF74862122E52060092F3E2 /* util.c */, + ); + indentWidth = 4; + name = Source; + sourceTree = ""; + tabWidth = 8; + }; + 1AB674ADFE9D54B511CA2CBB /* Products */ = { + isa = PBXGroup; + children = ( + 8DD76FB20486AB0100D96B5E /* bgpdump */, + 4DF7479C122D52440092F3E2 /* liblibbgpdump.dylib */, + ); + name = Products; + sourceTree = ""; + }; + C6A0FF2B0290797F04C91782 /* Documentation */ = { + isa = PBXGroup; + children = ( + 4DF747AF122D53130092F3E2 /* ChangeLog */, + 4DF747AD122D53000092F3E2 /* README */, + 4DF747AE122D53000092F3E2 /* README.ipv6 */, + C6A0FF2C0290799A04C91782 /* bgpdump.1 */, + ); + name = Documentation; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXHeadersBuildPhase section */ + 4DF74798122D52440092F3E2 /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 4DF74864122E52060092F3E2 /* util.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXHeadersBuildPhase section */ + +/* Begin PBXNativeTarget section */ + 4DF7479B122D52440092F3E2 /* libbgpdump */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4DF747A3122D52850092F3E2 /* Build configuration list for PBXNativeTarget "libbgpdump" */; + buildPhases = ( + 4DF74798122D52440092F3E2 /* Headers */, + 4DF74799122D52440092F3E2 /* Sources */, + 4DF7479A122D52440092F3E2 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = libbgpdump; + productName = libbgpdump; + productReference = 4DF7479C122D52440092F3E2 /* liblibbgpdump.dylib */; + productType = "com.apple.product-type.library.dynamic"; + }; + 8DD76FA90486AB0100D96B5E /* bgpdump */ = { + isa = PBXNativeTarget; + buildConfigurationList = 1DEB928508733DD80010E9CD /* Build configuration list for PBXNativeTarget "bgpdump" */; + buildPhases = ( + 8DD76FAB0486AB0100D96B5E /* Sources */, + 8DD76FAD0486AB0100D96B5E /* Frameworks */, + 8DD76FAF0486AB0100D96B5E /* CopyFiles */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = bgpdump; + productInstallPath = "$(HOME)/bin"; + productName = bgpdump; + productReference = 8DD76FB20486AB0100D96B5E /* bgpdump */; + productType = "com.apple.product-type.tool"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 08FB7793FE84155DC02AAC07 /* Project object */ = { + isa = PBXProject; + buildConfigurationList = 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "bgpdump" */; + compatibilityVersion = "Xcode 3.1"; + hasScannedForEncodings = 1; + mainGroup = 08FB7794FE84155DC02AAC07 /* bgpdump */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 8DD76FA90486AB0100D96B5E /* bgpdump */, + 4DF7479B122D52440092F3E2 /* libbgpdump */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXSourcesBuildPhase section */ + 4DF74799122D52440092F3E2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4DF74865122E52060092F3E2 /* util.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 8DD76FAB0486AB0100D96B5E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 4DF74766122D4E800092F3E2 /* bgpdump.c in Sources */, + 4DF747A6122D52C30092F3E2 /* bgpdump_lib.c in Sources */, + 4DF747A7122D52C30092F3E2 /* bgpdump_mstream.c in Sources */, + 4DF747A8122D52C50092F3E2 /* cfile_tools.c in Sources */, + 4DF74863122E52060092F3E2 /* util.c in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 1DEB928608733DD80010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_VERSION = com.apple.compilers.llvm.clang.1_0; + GCC_WARN_CHECK_SWITCH_STATEMENTS = YES; + INSTALL_PATH = /usr/local/bin; + PRODUCT_NAME = bgpdump; + RUN_CLANG_STATIC_ANALYZER = NO; + VALIDATE_PRODUCT = NO; + }; + name = Debug; + }; + 1DEB928708733DD80010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + GCC_MODEL_TUNING = G5; + INSTALL_PATH = /usr/local/bin; + PRODUCT_NAME = bgpdump; + }; + name = Release; + }; + 1DEB928A08733DD80010E9CD /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + ONLY_ACTIVE_ARCH = YES; + PREBINDING = NO; + SDKROOT = macosx10.6; + }; + name = Debug; + }; + 1DEB928B08733DD80010E9CD /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ARCHS = "$(ARCHS_STANDARD_32_64_BIT)"; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_WARN_ABOUT_RETURN_TYPE = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + PREBINDING = NO; + SDKROOT = macosx10.6; + }; + name = Release; + }; + 4DF7479D122D52440092F3E2 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = NO; + EXECUTABLE_PREFIX = lib; + GCC_DYNAMIC_NO_PIC = NO; + GCC_ENABLE_FIX_AND_CONTINUE = YES; + GCC_MODEL_TUNING = G5; + GCC_OPTIMIZATION_LEVEL = 0; + INSTALL_PATH = /usr/local/lib; + PREBINDING = NO; + PRODUCT_NAME = libbgpdump; + }; + name = Debug; + }; + 4DF7479E122D52440092F3E2 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + COPY_PHASE_STRIP = YES; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + EXECUTABLE_PREFIX = lib; + GCC_ENABLE_FIX_AND_CONTINUE = NO; + GCC_MODEL_TUNING = G5; + INSTALL_PATH = /usr/local/lib; + PREBINDING = NO; + PRODUCT_NAME = libbgpdump; + ZERO_LINK = NO; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 1DEB928508733DD80010E9CD /* Build configuration list for PBXNativeTarget "bgpdump" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB928608733DD80010E9CD /* Debug */, + 1DEB928708733DD80010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 1DEB928908733DD80010E9CD /* Build configuration list for PBXProject "bgpdump" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 1DEB928A08733DD80010E9CD /* Debug */, + 1DEB928B08733DD80010E9CD /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4DF747A3122D52850092F3E2 /* Build configuration list for PBXNativeTarget "libbgpdump" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4DF7479D122D52440092F3E2 /* Debug */, + 4DF7479E122D52440092F3E2 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 08FB7793FE84155DC02AAC07 /* Project object */; +} diff --git a/bgpdump_attr.h b/bgpdump_attr.h index 3ad15e1..c8e012f 100644 --- a/bgpdump_attr.h +++ b/bgpdump_attr.h @@ -1,40 +1,27 @@ -/* $Id$ */ /* - -Copyright (c) 2007 RIPE NCC - - -All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, provided -that the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the name of the author not be used in advertising or -publicity pertaining to distribution of the software without specific, -written prior permission. - -THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL -AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY -DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN -AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -*/ - -/* - + Copyright (c) 2007 - 2010 RIPE NCC - All Rights Reserved + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, provided + that the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation, and that the name of the author not be used in advertising or + publicity pertaining to distribution of the software without specific, + written prior permission. + + THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL + AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + Parts of this code have been engineered after analiyzing GNU Zebra's source code and therefore might contain declarations/code from GNU Zebra, Copyright (C) 1999 Kunihiro Ishiguro. Zebra is a free routing software, distributed under the GNU General Public License. A copy of this license is included with libbgpdump. -*/ - - -/* Original Author: Dan Ardelean (dan@ripe.net) */ @@ -119,6 +106,7 @@ struct unknown_attr u_char * raw; }; +typedef struct attr attributes_t; struct attr { /* Flag of attribute is set or not. */ diff --git a/bgpdump_formats.h b/bgpdump_formats.h index bb40084..fee14c1 100644 --- a/bgpdump_formats.h +++ b/bgpdump_formats.h @@ -1,29 +1,20 @@ -/* $Id$ */ /* - -Copyright (c) 2007 RIPE NCC - - -All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, provided -that the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the name of the author not be used in advertising or -publicity pertaining to distribution of the software without specific, -written prior permission. - -THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL -AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY -DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN -AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -*/ - -/* + Copyright (c) 2007 - 2010 RIPE NCC - All Rights Reserved + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, provided + that the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation, and that the name of the author not be used in advertising or + publicity pertaining to distribution of the software without specific, + written prior permission. + + THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL + AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. Parts of this code have been engineered after analiyzing GNU Zebra's source code and therefore might contain declarations/code from GNU @@ -31,10 +22,6 @@ Zebra, Copyright (C) 1999 Kunihiro Ishiguro. Zebra is a free routing software, distributed under the GNU General Public License. A copy of this license is included with libbgpdump. -*/ - - -/* Original Author: Dan Ardelean (dan@ripe.net) */ @@ -148,9 +135,8 @@ typedef struct struct_BGPDUMP_TABLE_DUMP_V2_PEER_INDEX_TABLE { typedef struct struct_BGPDUMP_TABLE_DUMP_V2_ROUTE_ENTRY { uint16_t peer_index; uint32_t originated_time; - uint16_t attribute_length; BGPDUMP_TABLE_DUMP_V2_PEER_INDEX_TABLE_ENTRY *peer; - struct attr *attr; + attributes_t *attr; } BGPDUMP_TABLE_DUMP_V2_ROUTE_ENTRY; typedef struct struct_BGPDUMP_TABLE_DUMP_V2_PREFIX { @@ -233,7 +219,6 @@ typedef struct struct_BGPDUMP_ZEBRA_ENTRY { u_char next_hop_len; u_char prefix_length; u_char *address_prefix; - u_int16_t attribute_length; u_int16_t empty; u_char *bgp_atribute; } BGPDUMP_ZEBRA_ENTRY; @@ -261,7 +246,7 @@ typedef struct struct_BGPDUMP_ENTRY { u_int16_t type; u_int16_t subtype; u_int32_t length; - struct attr *attr; + attributes_t *attr; BGPDUMP_BODY body; } BGPDUMP_ENTRY; diff --git a/bgpdump_lib.c b/bgpdump_lib.c index d7b7dce..a0fb54e 100644 --- a/bgpdump_lib.c +++ b/bgpdump_lib.c @@ -1,61 +1,46 @@ -static const char RCSID[] = "$Id$"; /* - -Copyright (c) 2007 RIPE NCC - - -All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, provided -that the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the name of the author not be used in advertising or -publicity pertaining to distribution of the software without specific, -written prior permission. - -THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL -AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY -DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN -AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -*/ - -/* - + Copyright (c) 2007 - 2010 RIPE NCC - All Rights Reserved + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, provided + that the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation, and that the name of the author not be used in advertising or + publicity pertaining to distribution of the software without specific, + written prior permission. + + THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL + AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + Parts of this code have been engineered after analiyzing GNU Zebra's source code and therefore might contain declarations/code from GNU Zebra, Copyright (C) 1999 Kunihiro Ishiguro. Zebra is a free routing software, distributed under the GNU General Public License. A copy of this license is included with libbgpdump. - -*/ - - -/* -Original Author: Dan Ardelean (dan@ripe.net) */ #include "bgpdump_lib.h" #include "bgpdump_mstream.h" #include "cfile_tools.h" +#include "util.h" #include #include #include +#include #include #include #include -#include - #include #include -void bgpdump_free_attr(struct attr *attr); +void bgpdump_free_attr(attributes_t *attr); static int process_mrtd_table_dump(struct mstream *s,BGPDUMP_ENTRY *entry); static int process_mrtd_table_dump_v2(struct mstream *s,BGPDUMP_ENTRY *entry); static int process_mrtd_table_dump_v2_peer_index_table(struct mstream *s,BGPDUMP_ENTRY *entry); @@ -72,22 +57,20 @@ static int process_zebra_bgp_message_notify(struct mstream *s,BGPDUMP_ENTRY * static int process_zebra_bgp_entry(struct mstream *s,BGPDUMP_ENTRY *entry); static int process_zebra_bgp_snapshot(struct mstream *s,BGPDUMP_ENTRY *entry); -static void process_attr_init(BGPDUMP_ENTRY *entry); -static void process_attr_read(struct mstream *s, struct attr *attr, u_int8_t asn_len, struct zebra_incomplete *incomplete, char mp_only_nexthop); +static attributes_t *process_attributes(struct mstream *s, u_int8_t asn_len, struct zebra_incomplete *incomplete); static void process_attr_aspath_string(struct aspath *as); static char aspath_delimiter_char (u_char type, u_char which); static void process_attr_community_string(struct community *com); -static void process_mp_announce(struct mstream *s, struct mp_info *info, int len, struct zebra_incomplete *incomplete); -static void process_mp_announce_only_nexthop(struct mstream *s, struct mp_info *info, int len, struct zebra_incomplete *incomplete); -static void process_mp_withdraw(struct mstream *s, struct mp_info *info, int len, struct zebra_incomplete *incomplete); -static u_int16_t read_prefix_list(struct mstream *s, int len, u_int16_t af, struct prefix **prefixarray, struct zebra_incomplete *incomplete); +static void process_mp_announce(struct mstream *s, struct mp_info *info, struct zebra_incomplete *incomplete); +static void process_mp_withdraw(struct mstream *s, struct mp_info *info, struct zebra_incomplete *incomplete); +static int read_prefix_list(struct mstream *s, u_int16_t af, struct prefix **prefixarray, struct zebra_incomplete *incomplete); static as_t read_asn(struct mstream *s, as_t *asn, u_int8_t len); static struct aspath *create_aspath(u_int16_t len, u_int8_t asn_len); static void aspath_error(struct aspath *as); static int check_new_aspath(struct aspath *aspath); -static void process_asn32_trans(struct attr *attr, u_int8_t asn_len); +static void process_asn32_trans(attributes_t *attr, u_int8_t asn_len); static struct aspath *asn32_merge_paths(struct aspath *path, struct aspath *newpath); static void asn32_expand_16_to_32(char *dst, char *src, int len); @@ -157,8 +140,7 @@ BGPDUMP_ENTRY* bgpdump_read_next(BGPDUMP *dump) { if(bytes_read > 0) { /* Malformed record */ dump->parsed++; - syslog(LOG_ERR, - "bgpdump_read_next: incomplete MRT header (%d bytes read, expecting 12)", + err("bgpdump_read_next: incomplete MRT header (%d bytes read, expecting 12)", bytes_read); } /* Nothing more to read, quit */ @@ -180,8 +162,7 @@ BGPDUMP_ENTRY* bgpdump_read_next(BGPDUMP *dump) { buffer = malloc(this_entry->length); bytes_read = cfr_read_n(dump->f, buffer, this_entry->length); if(bytes_read != this_entry->length) { - syslog(LOG_ERR, - "bgpdump_read_next: incomplete dump record (%d bytes read, expecting %d)", + err("bgpdump_read_next: incomplete dump record (%d bytes read, expecting %d)", bytes_read, this_entry->length); free(this_entry); free(buffer); @@ -289,7 +270,7 @@ void bgpdump_free_mem(BGPDUMP_ENTRY *entry) { } } -void bgpdump_free_attr(struct attr *attr){ +void bgpdump_free_attr(attributes_t *attr){ if(attr != NULL) { u_int16_t i; struct aspath *path, *pathstofree[3] = { attr->aspath, attr->old_aspath, attr->new_aspath }; @@ -353,7 +334,7 @@ int process_mrtd_table_dump(struct mstream *s,BGPDUMP_ENTRY *entry) { break; #endif default: - syslog(LOG_WARNING, "process_mrtd_table_dump: unknown AFI %d", afi); + warn("process_mrtd_table_dump: unknown AFI %d", afi); mstream_get(s, NULL, mstream_can_read(s)); return 0; } @@ -385,15 +366,12 @@ int process_mrtd_table_dump(struct mstream *s,BGPDUMP_ENTRY *entry) { asn_len = ASN32_LEN; break; default: - /* Not reached. Keep compiler happy */ - asn_len = 0; - break; + assert(0); // unreachable } read_asn(s,&entry->body.mrtd_table_dump.peer_as, asn_len); - process_attr_init(entry); - process_attr_read(s, entry->attr, asn_len, NULL, 0); + entry->attr = process_attributes(s, asn_len, NULL); return 1; } @@ -442,7 +420,7 @@ int process_mrtd_table_dump_v2_peer_index_table(struct mstream *s,BGPDUMP_ENTRY // view_name_len is without trailing \0 if(view_name_len+1 > BGPDUMP_TYPE_TABLE_DUMP_V2_MAX_VIEWNAME_LEN) { - syslog(LOG_WARNING, "process_mrtd_table_dump_v2_peer_index_table: view name length more than maximum length (%d), ignoring view name", BGPDUMP_TYPE_TABLE_DUMP_V2_MAX_VIEWNAME_LEN); + warn("process_mrtd_table_dump_v2_peer_index_table: view name length more than maximum length (%d), ignoring view name", BGPDUMP_TYPE_TABLE_DUMP_V2_MAX_VIEWNAME_LEN); } else { mstream_get(s, t->view_name, view_name_len); t->view_name[view_name_len] = 0; @@ -452,7 +430,7 @@ int process_mrtd_table_dump_v2_peer_index_table(struct mstream *s,BGPDUMP_ENTRY t->entries = malloc(sizeof(BGPDUMP_TABLE_DUMP_V2_PEER_INDEX_TABLE_ENTRY) * t->peer_count); if(t->entries == NULL){ - syslog(LOG_ERR, "process_mrtd_table_dump_v2_peer_index_table: failed to allocate memory for index table"); + err("process_mrtd_table_dump_v2_peer_index_table: failed to allocate memory for index table"); return 0; } @@ -501,7 +479,7 @@ int process_mrtd_table_dump_v2_ipv4_unicast(struct mstream *s, BGPDUMP_ENTRY *en prefixdata->entries = malloc(sizeof(BGPDUMP_TABLE_DUMP_V2_ROUTE_ENTRY) * prefixdata->entry_count); if(prefixdata->entries == NULL){ - syslog(LOG_ERR, "process_mrtd_table_dump_v2_ipv4_unicast: failed to allocate memory for entry table"); + err("process_mrtd_table_dump_v2_ipv4_unicast: failed to allocate memory for entry table"); return 0; } @@ -512,12 +490,8 @@ int process_mrtd_table_dump_v2_ipv4_unicast(struct mstream *s, BGPDUMP_ENTRY *en mstream_getw(s, &e->peer_index); e->peer = &table_dump_v2_peer_index_table->entries[e->peer_index]; mstream_getl(s, &e->originated_time); - - process_attr_init(entry); - entry->attr->len = e->attribute_length; - process_attr_read(s, entry->attr, 4, NULL, 0); - e->attr = entry->attr; - entry->attr = NULL; + + e->attr = process_attributes(s, 4, NULL); } return 1; @@ -543,7 +517,7 @@ int process_mrtd_table_dump_v2_ipv6_unicast(struct mstream *s, BGPDUMP_ENTRY *en prefixdata->entries = malloc(sizeof(BGPDUMP_TABLE_DUMP_V2_ROUTE_ENTRY) * prefixdata->entry_count); if(prefixdata->entries == NULL){ - syslog(LOG_ERR, "process_mrtd_table_dump_v2_ipv6_unicast: failed to allocate memory for entry table"); + err("process_mrtd_table_dump_v2_ipv6_unicast: failed to allocate memory for entry table"); return 0; } @@ -555,61 +529,12 @@ int process_mrtd_table_dump_v2_ipv6_unicast(struct mstream *s, BGPDUMP_ENTRY *en e->peer = &table_dump_v2_peer_index_table->entries[e->peer_index]; mstream_getl(s, &e->originated_time); - process_attr_init(entry); - entry->attr->len = e->attribute_length; - process_attr_read(s, entry->attr, 4, NULL, 1); - e->attr = entry->attr; - entry->attr = NULL; + e->attr = process_attributes(s, 4, NULL); } #endif return 1; } -/* -int process_mrtd_table_dump_v2_ipv6_unicast(struct mstream *s, BGPDUMP_ENTRY *entry){ - BGPDUMP_TABLE_DUMP_V2_PREFIX *prefixdata; - prefixdata = &entry->body.mrtd_table_dump_v2_prefix; - uint16_t i; - - mstream_getl(s, &prefixdata->seq); - mstream_getw(s, &prefixdata->afi); - mstream_getc(s, &prefixdata->safi); - - if(prefixdata->afi != AFI_IP6 || prefixdata->safi != SAFI_UNICAST){ - syslog(LOG_ERR, "process_mrtd_table_dump_v2_ipv6_unicast: entry has unsupported AFI/SAFI %d/%d", prefixdata->afi, prefixdata->safi); - return 0; - } - - mstream_getc(s, &prefixdata->prefix_length); - bzero(&prefixdata->prefix.v6_addr.s6_addr, 16); - mstream_get(s, &prefixdata->prefix.v6_addr.s6_addr, (prefixdata->prefix_length+7)/8); - - mstream_getw(s, &prefixdata->entry_count); - - prefixdata->entries = malloc(sizeof(BGPDUMP_TABLE_DUMP_V2_ROUTE_ENTRY) * prefixdata->entry_count); - if(prefixdata->entries == NULL){ - syslog(LOG_ERR, "process_mrtd_table_dump_v2_ipv6_unicast: failed to allocate memory for entry table"); - return 0; - } - - for(i=0; i < prefixdata->entry_count; i++){ - BGPDUMP_TABLE_DUMP_V2_ROUTE_ENTRY *e; - e = &prefixdata->entries[i]; - - mstream_getw(s, &e->peer_index); - e->peer = &table_dump_v2_peer_index_table.entries[e->peer_index]; - mstream_getl(s, &e->originated_time); - - process_attr_init(entry); - entry->attr->len = e->attribute_length; - process_attr_read(s, entry->attr, 4, NULL, 1); - e->attr = entry->attr; - entry->attr = NULL; - } - - return 1; -}*/ - int process_zebra_bgp(struct mstream *s,BGPDUMP_ENTRY *entry) { switch(entry->subtype) { @@ -626,22 +551,19 @@ int process_zebra_bgp(struct mstream *s,BGPDUMP_ENTRY *entry) { case BGPDUMP_SUBTYPE_ZEBRA_BGP_SNAPSHOT: return process_zebra_bgp_snapshot(s, entry); default: - syslog(LOG_WARNING, "process_zebra_bgp: unknown subtype %d", entry->subtype); + warn("process_zebra_bgp: unknown subtype %d", entry->subtype); return 0; } } - -int -process_zebra_bgp_state_change(struct mstream *s,BGPDUMP_ENTRY *entry, u_int8_t asn_len) { +int process_zebra_bgp_state_change(struct mstream *s,BGPDUMP_ENTRY *entry, u_int8_t asn_len) { read_asn(s, &entry->body.zebra_state_change.source_as, asn_len); read_asn(s, &entry->body.zebra_state_change.destination_as, asn_len); /* Work around Zebra dump corruption. * N.B. I don't see this in quagga 0.96.4 any more. Is it fixed? */ if (entry->length == 8) { - syslog(LOG_NOTICE, - "process_zebra_bgp_state_change: 8-byte state change (zebra bug?)"); + warn("process_zebra_bgp_state_change: 8-byte state change (zebra bug?)"); mstream_getw(s,&entry->body.zebra_state_change.old_state); mstream_getw(s,&entry->body.zebra_state_change.new_state); @@ -662,7 +584,7 @@ process_zebra_bgp_state_change(struct mstream *s,BGPDUMP_ENTRY *entry, u_int8_t case AFI_IP: // length could be 20 or 24 (asn16 vs asn32) if(entry->length != 20 && entry->length != 24) { - syslog(LOG_WARNING, "process_zebra_bgp_state_change: bad length %d", + warn("process_zebra_bgp_state_change: bad length %d", entry->length); return 0; } @@ -674,7 +596,7 @@ process_zebra_bgp_state_change(struct mstream *s,BGPDUMP_ENTRY *entry, u_int8_t case AFI_IP6: // length could be 44 or 48 (asn16 vs asn32) if(entry->length != 44 && entry->length != 48) { - syslog(LOG_WARNING, "process_zebra_bgp_state_change: bad length %d", + warn("process_zebra_bgp_state_change: bad length %d", entry->length); return 0; } @@ -684,7 +606,7 @@ process_zebra_bgp_state_change(struct mstream *s,BGPDUMP_ENTRY *entry, u_int8_t break; #endif default: - syslog(LOG_WARNING, "process_zebra_bgp_state_change: unknown AFI %d", + warn("process_zebra_bgp_state_change: unknown AFI %d", entry->body.zebra_state_change.address_family); return 0; } @@ -741,45 +663,48 @@ int process_zebra_bgp_message(struct mstream *s,BGPDUMP_ENTRY *entry, u_int8_t a * the address family is unsupported (since FFFF is not a valid address family) */ default: /* unsupported address family */ - syslog(LOG_WARNING, "process_zebra_bgp_message: unsupported AFI %d", + warn("process_zebra_bgp_message: unsupported AFI %d", entry->body.zebra_message.address_family); return 0; } if(memcmp(marker, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377", 16) != 0) { /* bad marker... ignore packet */ - syslog(LOG_WARNING, + warn( "bgp_message: bad marker: %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x", marker[0],marker[1],marker[2],marker[3],marker[4],marker[5],marker[6],marker[7], marker[8],marker[9],marker[10],marker[11],marker[12],marker[13],marker[14],marker[15]); return 0; } - mstream_getw (s,&entry->body.zebra_message.size); - mstream_getc (s,&entry->body.zebra_message.type); - - entry->body.zebra_message.cut_bytes = entry->body.zebra_message.size - 19 - mstream_can_read(s); + mstream_getw(s,&entry->body.zebra_message.size); + + int expected = entry->body.zebra_message.size - sizeof(marker) - sizeof(u_int16_t); + + mstream_t copy = mstream_copy(s, expected); + + entry->body.zebra_message.cut_bytes = expected - mstream_can_read(©); - switch(entry->body.zebra_message.type) { + switch(mstream_getc (©, &entry->body.zebra_message.type)) { case BGP_MSG_OPEN: - return process_zebra_bgp_message_open(s,entry, asn_len); + return process_zebra_bgp_message_open(©, entry, asn_len); case BGP_MSG_UPDATE: - return process_zebra_bgp_message_update(s,entry, asn_len); + return process_zebra_bgp_message_update(©, entry, asn_len); case BGP_MSG_NOTIFY: - return process_zebra_bgp_message_notify(s,entry); + return process_zebra_bgp_message_notify(©, entry); case BGP_MSG_KEEPALIVE: /* Nothing to do */ return 1; case BGP_MSG_ROUTE_REFRESH_01: /* Not implemented yet */ - syslog(LOG_WARNING, "bgp_message: MSG_ROUTE_REFRESH_01 not implemented yet"); + warn("bgp_message: MSG_ROUTE_REFRESH_01 not implemented yet"); return 0; case BGP_MSG_ROUTE_REFRESH: /* Not implemented yet */ - syslog(LOG_WARNING, "bgp_message: MSG_ROUTE_REFRESH not implemented yet"); + warn("bgp_message: MSG_ROUTE_REFRESH not implemented yet"); return 0; default: - syslog(LOG_WARNING, "bgp_message: unknown BGP message type %d", + warn("bgp_message: unknown BGP message type %d", entry->body.zebra_message.type); return 0; } @@ -814,224 +739,207 @@ int process_zebra_bgp_message_open(struct mstream *s, BGPDUMP_ENTRY *entry, u_in } int process_zebra_bgp_message_update(struct mstream *s, BGPDUMP_ENTRY *entry, u_int8_t asn_len) { - int withdraw_len; - int announce_len; - int attr_pos; - entry->body.zebra_message.incomplete.orig_len = 0; - withdraw_len = mstream_getw(s, NULL); - entry->body.zebra_message.withdraw_count = - read_prefix_list(s, withdraw_len, AFI_IP, &entry->body.zebra_message.withdraw, + mstream_t withdraw_stream = mstream_copy(s, mstream_getw(s, NULL)); + entry->body.zebra_message.withdraw_count = read_prefix_list(&withdraw_stream, AFI_IP, + &entry->body.zebra_message.withdraw, &entry->body.zebra_message.incomplete); - /* Where are we? */ - attr_pos = s->position; - - process_attr_init(entry); - process_attr_read(s, entry->attr, asn_len, &entry->body.zebra_message.incomplete, 0); - - /* Get back in sync in case there are malformed attributes */ - s->position = attr_pos + entry->attr->len + 2; - if(s->position > s->len) s->position = s->len; + entry->attr = process_attributes(s, asn_len, &entry->body.zebra_message.incomplete); - announce_len = entry->body.zebra_message.size - 23 - withdraw_len - entry->attr->len; - entry->body.zebra_message.announce_count = - read_prefix_list(s, announce_len, AFI_IP, &entry->body.zebra_message.announce, + entry->body.zebra_message.announce_count = read_prefix_list(s, AFI_IP, + &entry->body.zebra_message.announce, &entry->body.zebra_message.incomplete); return 1; } int process_zebra_bgp_entry(struct mstream *s, BGPDUMP_ENTRY *entry) { - syslog(LOG_WARNING, "process_zebra_bgp_entry: record type not implemented yet"); + warn("process_zebra_bgp_entry: record type not implemented yet"); return 0; } int process_zebra_bgp_snapshot(struct mstream *s, BGPDUMP_ENTRY *entry) { - syslog(LOG_WARNING, "process_zebra_bgp_snapshot: record type not implemented yet"); + warn("process_zebra_bgp_snapshot: record type not implemented yet"); return 0; } -void process_attr_init(BGPDUMP_ENTRY *entry) { - - entry->attr = malloc(sizeof(struct attr)); - - entry->attr->flag = 0; - entry->attr->origin = -1; - entry->attr->nexthop.s_addr = INADDR_NONE; - entry->attr->med = -1; - entry->attr->local_pref = -1; - entry->attr->aggregator_as = -1; - entry->attr->aggregator_addr.s_addr = INADDR_NONE; - entry->attr->weight = -1; - - entry->attr->originator_id.s_addr = -1; - entry->attr->cluster = NULL; - - entry->attr->aspath = NULL; - entry->attr->community = NULL; - entry->attr->transit = NULL; - - entry->attr->mp_info = NULL; - entry->attr->len = 0; - entry->attr->data = NULL; - - entry->attr->unknown_num = 0; - entry->attr->unknown = NULL; - - entry->attr->new_aspath = NULL; - entry->attr->old_aspath = NULL; - entry->attr->new_aggregator_as = -1; - entry->attr->new_aggregator_addr.s_addr = INADDR_NONE; +attributes_t *attr_init(struct mstream *s, int len) { + + attributes_t *attr = malloc(sizeof(struct attr)); + + attr->data=malloc(len); + memcpy(attr->data, &s->start[s->position], len); + + attr->len = len; + attr->flag = 0; + attr->origin = -1; + attr->nexthop.s_addr = INADDR_NONE; + attr->med = -1; + attr->local_pref = -1; + attr->aggregator_as = -1; + attr->aggregator_addr.s_addr = INADDR_NONE; + attr->weight = -1; + + attr->originator_id.s_addr = -1; + attr->cluster = NULL; + + attr->aspath = NULL; + attr->community = NULL; + attr->transit = NULL; + attr->mp_info = NULL; + + attr->unknown_num = 0; + attr->unknown = NULL; + + attr->new_aspath = NULL; + attr->old_aspath = NULL; + attr->new_aggregator_as = -1; + attr->new_aggregator_addr.s_addr = INADDR_NONE; + + return attr; } -void process_attr_read(struct mstream *s, struct attr *attr, u_int8_t asn_len, struct zebra_incomplete *incomplete, char mp_only_nexthop) { - u_char flag; - u_char type; - u_int32_t len, end; - u_int32_t truelen; - struct unknown_attr *unknown; - - mstream_getw(s, &attr->len); - if(attr->len == 0) - return; - - attr->data=malloc(attr->len); - - /* Check the attributes are not truncated */ - if(attr->len > mstream_can_read(s)) { - truelen = mstream_can_read(s); - memset(attr->data + truelen, 0, attr->len - truelen); +static void process_unknown_attr(struct mstream *s, attributes_t *attr, int flag, int type, int len) { + /* Unknown attribute. Save as is */ + attr->unknown_num++; + attr->unknown = realloc(attr->unknown, attr->unknown_num * sizeof(struct unknown_attr)); + + /* Pointer to the unknown attribute we want to fill in */ + struct unknown_attr *unknown = attr->unknown + attr->unknown_num - 1; + + unknown->flag = flag; + unknown->type = type; + unknown->len = len; + + unknown->raw = malloc(unknown->real_len + ((flag & BGP_ATTR_FLAG_EXTLEN) ? 4 : 3)); + + unknown->raw[0] = flag; + unknown->raw[1] = type; + + if(flag & BGP_ATTR_FLAG_EXTLEN) { + unknown->raw[2] = (len & 0xFF00) >> 8; + unknown->raw[3] = len & 0xFF; + mstream_get(s, unknown->raw + 4, unknown->real_len); } else { - truelen = attr->len; + unknown->raw[2] = len; + mstream_get(s, unknown->raw + 3, unknown->real_len); } - memcpy(attr->data, &s->start[s->position], truelen); - - end = s->position + truelen; - - while(s->position < end) { - mstream_getc(s,&flag); - mstream_getc(s,&type); - - if(flag & BGP_ATTR_FLAG_EXTLEN) - len=mstream_getw(s,NULL); - else - len=mstream_getc(s,NULL); - - /* Take note of all attributes, including unknown ones */ - if(type <= sizeof(attr->flag) * 8) - attr->flag = attr->flag | ATTR_FLAG_BIT (type); - - switch(type) { - case BGP_ATTR_ORIGIN: - mstream_getc(s,&attr->origin); - break; - case BGP_ATTR_AS_PATH: - attr->aspath = create_aspath(len, asn_len); - mstream_get(s,attr->aspath->data,len); - process_attr_aspath_string(attr->aspath); - break; - case BGP_ATTR_NEXT_HOP: - mstream_get_ipv4(s,&attr->nexthop.s_addr); - break; - case BGP_ATTR_MULTI_EXIT_DISC: - mstream_getl(s,&attr->med); - break; - case BGP_ATTR_LOCAL_PREF: - mstream_getl(s,&attr->local_pref); - break; - case BGP_ATTR_ATOMIC_AGGREGATE: - break; - case BGP_ATTR_AGGREGATOR: - read_asn(s, &attr->aggregator_as, asn_len); - mstream_get_ipv4(s,&attr->aggregator_addr.s_addr); - break; - case BGP_ATTR_COMMUNITIES: - attr->community = malloc(sizeof(struct community)); - attr->community->size = len / 4; - attr->community->val = malloc(len); - mstream_get(s,attr->community->val,len); - attr->community->str = NULL; - process_attr_community_string(attr->community); - break; - case BGP_ATTR_MP_REACH_NLRI: - if(attr->mp_info == NULL) { - attr->mp_info = malloc(sizeof(struct mp_info)); - memset(attr->mp_info, 0, sizeof(struct mp_info)); - } - if(mp_only_nexthop) - process_mp_announce_only_nexthop(s, attr->mp_info, len, incomplete); - else - process_mp_announce(s, attr->mp_info, len, incomplete); - break; - case BGP_ATTR_MP_UNREACH_NLRI: - if(attr->mp_info == NULL) { - attr->mp_info = malloc(sizeof(struct mp_info)); - memset(attr->mp_info, 0, sizeof(struct mp_info)); - } - process_mp_withdraw(s, attr->mp_info, len, incomplete); - case BGP_ATTR_NEW_AS_PATH: - attr->new_aspath = create_aspath(len, ASN32_LEN); - mstream_get(s,attr->new_aspath->data,len); - process_attr_aspath_string(attr->new_aspath); - /* AS_CONFED_SEQUENCE and AS_CONFED_SET segments invalid in NEW_AS_PATH */ - check_new_aspath(attr->new_aspath); - break; - case BGP_ATTR_NEW_AGGREGATOR: - read_asn(s, &attr->new_aggregator_as, ASN32_LEN); - mstream_get_ipv4(s,&attr->new_aggregator_addr.s_addr); - break; - - case BGP_ATTR_ORIGINATOR_ID: - mstream_get_ipv4(s,&attr->originator_id.s_addr); - break; - case BGP_ATTR_CLUSTER_LIST: - attr->cluster = malloc(sizeof(struct cluster_list)); - attr->cluster->length = len/4; - attr->cluster->list = malloc((attr->cluster->length) * sizeof(struct in_addr)); - - int cluster_index; - for (cluster_index=0;cluster_indexcluster->length;cluster_index++) - mstream_get_ipv4(s,&attr->cluster->list[cluster_index].s_addr); - break; - - default: - /* Unknown attribute. Save as is */ - attr->unknown_num++; - attr->unknown = realloc(attr->unknown, attr->unknown_num * sizeof(struct unknown_attr)); - - /* Pointer to the unknown attribute we want to fill in */ - unknown = attr->unknown + attr->unknown_num - 1; - - /* Work around bogus attribute lengths */ - if(s->position + len > end) - unknown->real_len = end - s->position; - else - unknown->real_len = len; - - unknown->flag = flag; - unknown->type = type; - unknown->len = len; +} - unknown->raw = malloc(unknown->real_len + ((flag & BGP_ATTR_FLAG_EXTLEN) ? 4 : 3)); +static void process_one_attr(struct mstream *outer_stream, attributes_t *attr, u_int8_t asn_len, struct zebra_incomplete *incomplete) { + int flag = mstream_getc(outer_stream, NULL); + int type = mstream_getc(outer_stream, NULL); + int len; + + if(flag & BGP_ATTR_FLAG_EXTLEN) + len = mstream_getw(outer_stream,NULL); + else + len = mstream_getc(outer_stream,NULL); - unknown->raw[0] = flag; - unknown->raw[1] = type; + //info("flag:%-2i type:%-2i length:%i", flag, type, len); - if(flag & BGP_ATTR_FLAG_EXTLEN) { - unknown->raw[2] = (len & 0xFF00) >> 8; - unknown->raw[3] = len & 0xFF; - mstream_get(s, unknown->raw + 4, unknown->real_len); - } else { - unknown->raw[2] = len; - mstream_get(s, unknown->raw + 3, unknown->real_len); - } - break; - } + mstream_t ms = mstream_copy(outer_stream, len), *s = &ms; + if(mstream_can_read(s) != len) { + warn("ERROR attribute is truncated: expected=%u remaining=%u\n", len, mstream_can_read(s)); + return; } - /* Once all attributes have been read, take care of ASN32 transition */ + + /* Take note of all attributes, including unknown ones */ + if(type <= sizeof(attr->flag) * 8) + attr->flag |= ATTR_FLAG_BIT(type); + + switch(type) { + case BGP_ATTR_MP_REACH_NLRI: + if(! attr->mp_info) + attr->mp_info = calloc(1, sizeof(struct mp_info)); + process_mp_announce(s, attr->mp_info, incomplete); + break; + case BGP_ATTR_MP_UNREACH_NLRI: + if(! attr->mp_info) + attr->mp_info = calloc(1, sizeof(struct mp_info)); + process_mp_withdraw(s, attr->mp_info, incomplete); + break; + case BGP_ATTR_ORIGIN: + mstream_getc(s,&attr->origin); + break; + case BGP_ATTR_AS_PATH: + //FIXME assert(! attr->aspath); + attr->aspath = create_aspath(len, asn_len); + mstream_get(s, attr->aspath->data, len); + process_attr_aspath_string(attr->aspath); + break; + case BGP_ATTR_NEXT_HOP: + mstream_get_ipv4(s,&attr->nexthop.s_addr); + break; + case BGP_ATTR_MULTI_EXIT_DISC: + mstream_getl(s,&attr->med); + break; + case BGP_ATTR_LOCAL_PREF: + mstream_getl(s,&attr->local_pref); + break; + case BGP_ATTR_ATOMIC_AGGREGATE: + break; + case BGP_ATTR_AGGREGATOR: + read_asn(s, &attr->aggregator_as, asn_len); + mstream_get_ipv4(s,&attr->aggregator_addr.s_addr); + break; + case BGP_ATTR_COMMUNITIES: + //FIXME assert(! attr->community); + attr->community = malloc(sizeof(struct community)); + attr->community->size = len / 4; + attr->community->val = malloc(len); + mstream_get(s,attr->community->val,len); + attr->community->str = NULL; + process_attr_community_string(attr->community); + break; + case BGP_ATTR_NEW_AS_PATH: + //FIXME assert(! attr->new_aspath); + attr->new_aspath = create_aspath(len, ASN32_LEN); + mstream_get(s,attr->new_aspath->data, len); + process_attr_aspath_string(attr->new_aspath); + /* AS_CONFED_SEQUENCE and AS_CONFED_SET segments invalid in NEW_AS_PATH */ + check_new_aspath(attr->new_aspath); + break; + case BGP_ATTR_NEW_AGGREGATOR: + read_asn(s, &attr->new_aggregator_as, ASN32_LEN); + mstream_get_ipv4(s,&attr->new_aggregator_addr.s_addr); + break; + case BGP_ATTR_ORIGINATOR_ID: + mstream_get_ipv4(s,&attr->originator_id.s_addr); + break; + case BGP_ATTR_CLUSTER_LIST: + //FIXME assert(! attr->cluster); + attr->cluster = malloc(sizeof(struct cluster_list)); + attr->cluster->length = len/4; + attr->cluster->list = malloc((attr->cluster->length) * sizeof(struct in_addr)); + + int i; // cluster index + for (i = 0; i < attr->cluster->length; i++) + mstream_get_ipv4(s,&attr->cluster->list[i].s_addr); + break; + default: + process_unknown_attr(s, attr, flag, type, len); + } +} + +attributes_t *process_attributes(struct mstream *s, u_int8_t asn_len, struct zebra_incomplete *incomplete) { + int total = mstream_getw(s, NULL); + + attributes_t *attr = attr_init(s, total); + mstream_t copy = mstream_copy(s, total); + + if(mstream_can_read(©) != total) + warn("entry is truncated: expected=%u remaining=%u", total, mstream_can_read(©)); + + while(mstream_can_read(©)) + process_one_attr(©, attr, asn_len, incomplete); + + // Once all attributes have been read, take care of ASN32 transition process_asn32_trans(attr, asn_len); + + return attr; } struct aspath *create_aspath(u_int16_t len, u_int8_t asn_len) { @@ -1058,10 +966,7 @@ void aspath_error(struct aspath *as) { } as->str = malloc(strlen(ASPATH_STR_ERROR) + 1); - if(as->str) - strcpy(as->str, ASPATH_STR_ERROR); - else - syslog(LOG_CRIT, "aspath_error: malloc failed"); + strcpy(as->str, ASPATH_STR_ERROR); } void process_attr_aspath_string(struct aspath *as) { @@ -1284,158 +1189,88 @@ void process_attr_community_string(struct community *com) { strcpy(com->str, buf); } -void process_mp_announce(struct mstream *s, struct mp_info *info, int len, struct zebra_incomplete *incomplete) { - u_int16_t afi; - u_int8_t safi; - u_int8_t num_snpa; - u_int8_t snpa_len; - struct mp_nlri *mp_nlri; - - mstream_getw(s, &afi); - mstream_getc(s, &safi); - len -= 3; - - /* Do we know about this address family? */ - if(afi > BGPDUMP_MAX_AFI || safi > BGPDUMP_MAX_SAFI) { - syslog(LOG_WARNING, "process_mp_announce: unknown AFI,SAFI %d,%d!", - afi, safi); - mstream_get(s, NULL, len); - return; - } - - /* If there are 2 NLRI's for the same protocol, fail but don't burn and die */ - if(info->announce[afi][safi] != NULL) { - syslog(LOG_WARNING, - "process_mp_announce: update contains more than one MP_NLRI with AFI,SAFI %d,%d!", - afi, safi); - mstream_get(s, NULL, len); - return; - } - - /* Allocate structure */ - mp_nlri = malloc(sizeof(struct mp_nlri)); - memset(mp_nlri, 0, sizeof(struct mp_nlri)); - info->announce[afi][safi] = mp_nlri; - - /* Get next hop */ - mstream_getc(s, &mp_nlri->nexthop_len); - len--; +static struct mp_nlri *get_nexthop(struct mstream *s, u_int16_t afi) { + struct mp_nlri *nlri = calloc(1, sizeof(struct mp_nlri)); + + nlri->nexthop_len = mstream_getc(s, NULL); + + // sometimes nexthop_len is 0 - not sure what this means (see IS-626) + // if(mp_nlri->nexthop_len == 0) + // return len; + + if(afi == AFI_IP) { + assert(nlri->nexthop_len == 4); + nlri->nexthop.v4_addr.s_addr = mstream_get_ipv4(s, NULL); + return nlri; + } - switch(afi) { - case AFI_IP: - mstream_get_ipv4(s, &mp_nlri->nexthop.v4_addr.s_addr); - mstream_get(s, NULL, mp_nlri->nexthop_len - 4); - break; #ifdef BGPDUMP_HAVE_IPV6 - case AFI_IP6: - if(mp_nlri->nexthop_len != 32 && mp_nlri->nexthop_len != 16) { - syslog(LOG_WARNING, "process_mp_announce: unknown MP nexthop length %d", - mp_nlri->nexthop_len); - mstream_get(s, NULL, len); - return; - } - /* Get global nexthop */ - mstream_get(s, &mp_nlri->nexthop.v6_addr, 16); - /* Is there also a link-local address? */ - if(mp_nlri->nexthop_len == 32) - mstream_get(s, &mp_nlri->nexthop_local.v6_addr.s6_addr, 16); - break; + assert(afi == AFI_IP6); + mstream_get(s, &nlri->nexthop.v6_addr, 16); + if(nlri->nexthop_len == 32) { + /* Is there also a link-local address? */ + mstream_get(s, &nlri->nexthop_local.v6_addr.s6_addr, 16); + } else if(nlri->nexthop_len != 16) { + warn("process_mp_announce: unknown MP nexthop length %d", nlri->nexthop_len); + } #endif - } - len -= mp_nlri->nexthop_len; - - /* Skip over SNPAs */ - mstream_getc(s, &num_snpa); - len--; - - if(num_snpa) { - syslog(LOG_WARNING, "process_mp_announce: MP_NLRI contains SNPAs, skipped"); - - while(num_snpa > 0) { - snpa_len = mstream_getc(s, NULL); - mstream_get(s, NULL, snpa_len); - len -= snpa_len; - num_snpa--; - } - } - - /* Read prefixes */ - mp_nlri->prefix_count = read_prefix_list(s, len, afi, &mp_nlri->nlri, incomplete); + return nlri; } -void process_mp_announce_only_nexthop(struct mstream *s, struct mp_info *info, int len, struct zebra_incomplete *incomplete) { - u_int16_t afi; - u_int8_t safi; - struct mp_nlri *mp_nlri; +void process_mp_announce(struct mstream *s, struct mp_info *info, struct zebra_incomplete *incomplete) { + u_int16_t afi; + u_int8_t safi; - afi = AFI_IP6; - safi = SAFI_UNICAST; + // look for MRT abbreviated MP_NLRI packets + if(s->start[s->position] != 0) { + assert(info->announce[AFI_IP6][SAFI_UNICAST] == NULL); + info->announce[AFI_IP6][SAFI_UNICAST] = get_nexthop(s, AFI_IP6); + return; + } + + mstream_getw(s, &afi); + mstream_getc(s, &safi); + + if(afi > BGPDUMP_MAX_AFI || safi > BGPDUMP_MAX_SAFI) { + warn("process_mp_announce: unknown protocol(AFI=%d, SAFI=%d)!", afi, safi); + return; + } - /* If there are 2 NLRI's for the same protocol, fail but don't burn and die */ - if(info->announce[afi][safi] != NULL) { - syslog(LOG_WARNING, - "process_mp_announce: update contains more than one MP_NLRI with AFI,SAFI %d,%d!", - afi, safi); - mstream_get(s, NULL, len); - return; - } + if(info->announce[afi][safi] != NULL) { + warn("process_mp_announce: two MP_NLRI for the same protocol(%d, %d)!", afi, safi); + return; + } - /* Allocate structure */ - mp_nlri = malloc(sizeof(struct mp_nlri)); - memset(mp_nlri, 0, sizeof(struct mp_nlri)); - info->announce[afi][safi] = mp_nlri; + info->announce[afi][safi] = get_nexthop(s, afi); - /* Get next hop */ - mstream_getc(s, &mp_nlri->nexthop_len); - len--; + // SNPA is defunct and num_snpa should always be 0 + u_int8_t num_snpa; + if(mstream_getc(s, &num_snpa)) + warn("process_mp_announce: MP_NLRI contains SNPAs, skipping"); + for(; num_snpa > 0; --num_snpa) { + mstream_get(s, NULL, mstream_getc(s, NULL)); + } - switch(afi) { - case AFI_IP: - mstream_get_ipv4(s, &mp_nlri->nexthop.v4_addr.s_addr); - mstream_get(s, NULL, mp_nlri->nexthop_len - 4); - break; -#ifdef BGPDUMP_HAVE_IPV6 - case AFI_IP6: - if(mp_nlri->nexthop_len != 32 && mp_nlri->nexthop_len != 16) { - syslog(LOG_WARNING, "process_mp_announce: unknown MP nexthop length %d", - mp_nlri->nexthop_len); - mstream_get(s, NULL, len); - return; - } - /* Get global nexthop */ - mstream_get(s, &mp_nlri->nexthop.v6_addr, 16); - /* Is there also a link-local address? */ - if(mp_nlri->nexthop_len == 32) - mstream_get(s, &mp_nlri->nexthop_local.v6_addr.s6_addr, 16); - break; -#endif - } - len -= mp_nlri->nexthop_len; + info->announce[afi][safi]->prefix_count = read_prefix_list(s, afi, &info->announce[afi][safi]->nlri, incomplete); } -void process_mp_withdraw(struct mstream *s, struct mp_info *info, int len, struct zebra_incomplete *incomplete) { +void process_mp_withdraw(struct mstream *s, struct mp_info *info, struct zebra_incomplete *incomplete) { u_int16_t afi; u_int8_t safi; struct mp_nlri *mp_nlri; mstream_getw(s, &afi); mstream_getc(s, &safi); - len -= 3; /* Do we know about this address family? */ if(afi > BGPDUMP_MAX_AFI || safi > BGPDUMP_MAX_SAFI) { - syslog(LOG_WARNING, "process_mp_withdraw: unknown AFI,SAFI %d,%d!", - afi, safi); - mstream_get(s, NULL, len); + warn("process_mp_withdraw: unknown AFI,SAFI %d,%d!", afi, safi); return; } /* If there are 2 NLRI's for the same protocol, fail but don't burn and die */ if(info->withdraw[afi][safi] != NULL) { - syslog(LOG_WARNING, - "process_mp_withdraw: update contains more than one MP_NLRI with AFI,SAFI %d,%d!", - afi, safi); - mstream_get(s, NULL, len); + warn("process_mp_withdraw: update contains more than one MP_NLRI with AFI,SAFI %d,%d!", afi, safi); return; } @@ -1444,61 +1279,47 @@ void process_mp_withdraw(struct mstream *s, struct mp_info *info, int len, struc memset(mp_nlri, 0, sizeof(struct mp_nlri)); info->withdraw[afi][safi] = mp_nlri; - mp_nlri->prefix_count = read_prefix_list(s, len, afi, &mp_nlri->nlri, incomplete); + mp_nlri->prefix_count = read_prefix_list(s, afi, &mp_nlri->nlri, incomplete); } -u_int16_t read_prefix_list(struct mstream *s, int len, u_int16_t afi, - struct prefix **prefixarray, struct zebra_incomplete *incomplete) { - u_int8_t p_len; - u_int8_t p_bytes; - u_int16_t count = 0; - struct prefix *prefixes = *prefixarray; - - if(afi > BGPDUMP_MAX_AFI) { - syslog(LOG_WARNING, "read_prefix_list: unknown AFI %d", afi); - mstream_get(s, NULL, len); - *prefixarray = NULL; - return 0; - } - - while(len > 0 && mstream_can_read(s) > 0) { - /* Prefix length in bits */ - p_len = mstream_getc(s,NULL); len--; - /* In bytes */ - p_bytes = p_len / 8; if(p_len % 8 !=0) p_bytes++; - - /* Truncated prefix list? */ - if(mstream_can_read(s) < p_bytes) { - if(incomplete) { - /* Put prefix in incomplete structure */ - memset(&incomplete->prefix, 0, sizeof(struct prefix)); - incomplete->afi = afi; - incomplete->orig_len = p_len; - incomplete->prefix.len = mstream_can_read(s) * 8; - mstream_get(s, &incomplete->prefix.address, mstream_can_read(s)); - } else { - /* Just skip over it */ - mstream_get(s, NULL, mstream_can_read(s)); - } - /* In either case, don't put it in the prefix array */ - break; - } - - /* Reallocate prefix array to add room for one more prefix*/ - prefixes = realloc(prefixes, (count+1) * sizeof(struct prefix)); - - /* Fill new prefix with zeros, set prefix length */ - memset(&prefixes[count],0,sizeof(struct prefix)); - prefixes[count].len = p_len; - - /* Copy prefix */ - mstream_get(s, &prefixes[count].address, p_bytes); - - len = len - p_bytes; - count++; - } - *prefixarray = prefixes; - return count; +static int read_prefix_list(struct mstream *s, u_int16_t afi, struct prefix **nlri, struct zebra_incomplete *incomplete) { + u_int16_t count = 0; + struct prefix *prefixes = NULL; + + while(mstream_can_read(s)) { + u_int8_t p_len = mstream_getc(s,NULL); // length in bits + u_int8_t p_bytes = (p_len + 7) / 8; + + /* Truncated prefix list? */ + if(mstream_can_read(s) < p_bytes) { + if(incomplete) { + /* Put prefix in incomplete structure */ + memset(&incomplete->prefix, 0, sizeof(struct prefix)); + incomplete->afi = afi; + incomplete->orig_len = p_len; + incomplete->prefix.len = mstream_can_read(s) * 8; + mstream_get(s, &incomplete->prefix.address, mstream_can_read(s)); + } else { + /* Just skip over it */ + mstream_get(s, NULL, mstream_can_read(s)); + } + /* In either case, don't put it in the prefix array */ + break; + } + + /* Reallocate prefix array to add room for one more prefix*/ + prefixes = realloc(prefixes, (count+1) * sizeof(struct prefix)); + + /* Fill new prefix with zeros, set prefix length */ + memset(&prefixes[count],0,sizeof(struct prefix)); + prefixes[count].len = p_len; + + /* Copy prefix */ + mstream_get(s, &prefixes[count].address, p_bytes); + count++; + } + *nlri = prefixes; + return count; } static as_t read_asn(struct mstream *s, as_t *asn, u_int8_t len) { @@ -1534,7 +1355,7 @@ int check_new_aspath(struct aspath *aspath) { segment < (struct assegment *) (aspath->data + aspath->length); segment = (struct assegment *) ((char *) segment + sizeof(*segment) + segment->length * ASN32_LEN)) { if(segment->type == AS_CONFED_SEQUENCE || segment->type == AS_CONFED_SET) { - syslog(LOG_WARNING, "check_new_aspath: invalid segment of type AS_CONFED_%s in NEW_AS_PATH", + warn("check_new_aspath: invalid segment of type AS_CONFED_%s in NEW_AS_PATH", segment->type == AS_CONFED_SET ? "SET" : "SEQUENCE"); return 0; } @@ -1542,14 +1363,14 @@ int check_new_aspath(struct aspath *aspath) { return 1; } -void process_asn32_trans(struct attr *attr, u_int8_t asn_len) { +void process_asn32_trans(attributes_t *attr, u_int8_t asn_len) { if(asn_len == ASN32_LEN) { /* These attributes "SHOULD NOT" be used with ASN32. */ if(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEW_AS_PATH)) - syslog(LOG_WARNING, "process_asn32_trans: ASN32 message contains NEW_AS_PATH attribute"); + warn("process_asn32_trans: ASN32 message contains NEW_AS_PATH attribute"); if(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEW_AGGREGATOR)) - syslog(LOG_WARNING, "process_asn32_trans: ASN32 message contains NEW_AGGREGATOR attribute"); + warn("process_asn32_trans: ASN32 message contains NEW_AGGREGATOR attribute"); /* Don't compute anything, just leave AS_PATH and AGGREGATOR as they are */ return; @@ -1599,10 +1420,6 @@ struct aspath *asn32_merge_paths(struct aspath *path, struct aspath *newpath) { /* Make room */ newlen = mergedpath->length + sizeof(struct assegment) + segment->length * ASN32_LEN; mergedpath->data = realloc(mergedpath->data, newlen); - if(mergedpath->data == NULL) { - syslog(LOG_CRIT, "asn32_merge_paths: malloc failed"); - return NULL; - } /* Create a new AS-path segment */ mergedsegment = (struct assegment *) (mergedpath->data + mergedpath->length); @@ -1628,10 +1445,6 @@ struct aspath *asn32_merge_paths(struct aspath *path, struct aspath *newpath) { /* Append NEW_AS_PATH to merged path */ mergedpath->data = realloc(mergedpath->data, mergedpath->length + newpath->length); - if(mergedpath->data == NULL) { - syslog(LOG_CRIT, "asn32_merge_paths: malloc failed"); - return NULL; - } memcpy(mergedpath->data + mergedpath->length, newpath->data, newpath->length); mergedpath->length += newpath->length; diff --git a/bgpdump_lib.h b/bgpdump_lib.h index c041c94..5b63d58 100644 --- a/bgpdump_lib.h +++ b/bgpdump_lib.h @@ -1,45 +1,30 @@ -/* $Id$ */ /* - -Copyright (c) 2007 RIPE NCC - - -All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, provided -that the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the name of the author not be used in advertising or -publicity pertaining to distribution of the software without specific, -written prior permission. - -THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL -AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY -DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN -AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -*/ - -/* - + Copyright (c) 2007 - 2010 RIPE NCC - All Rights Reserved + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, provided + that the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation, and that the name of the author not be used in advertising or + publicity pertaining to distribution of the software without specific, + written prior permission. + + THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL + AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + Parts of this code have been engineered after analiyzing GNU Zebra's source code and therefore might contain declarations/code from GNU Zebra, Copyright (C) 1999 Kunihiro Ishiguro. Zebra is a free routing software, distributed under the GNU General Public License. A copy of this license is included with libbgpdump. -*/ - - -/* Original Author: Dan Ardelean (dan@ripe.net) */ - - #ifndef _BGPDUMP_LIB_H #define _BGPDUMP_LIB_H diff --git a/bgpdump_mstream.c b/bgpdump_mstream.c index 9aa81b8..1f59021 100644 --- a/bgpdump_mstream.c +++ b/bgpdump_mstream.c @@ -1,40 +1,27 @@ -static const char RCSID[] = "$Id$"; /* - -Copyright (c) 2007 RIPE NCC - - -All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, provided -that the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the name of the author not be used in advertising or -publicity pertaining to distribution of the software without specific, -written prior permission. - -THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL -AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY -DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN -AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -*/ - -/* - + Copyright (c) 2007 - 2010 RIPE NCC - All Rights Reserved + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, provided + that the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation, and that the name of the author not be used in advertising or + publicity pertaining to distribution of the software without specific, + written prior permission. + + THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL + AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + Parts of this code have been engineered after analiyzing GNU Zebra's source code and therefore might contain declarations/code from GNU Zebra, Copyright (C) 1999 Kunihiro Ishiguro. Zebra is a free routing software, distributed under the GNU General Public License. A copy of this license is included with libbgpdump. -*/ - - -/* Original Author: Dan Ardelean (dan@ripe.net) */ @@ -89,6 +76,14 @@ u_int32_t mstream_can_read(struct mstream *s) { return s->len - s->position; } +// construct a partial mstream +mstream_t mstream_copy(mstream_t *s, int len) { + mstream_t copy = {0}; + copy.start = s->start + s->position; + copy.len = mstream_get(s, NULL, len); + return copy; +} + u_int32_t mstream_get (struct mstream *s, void *d, u_int32_t len) { int room = mstream_can_read(s); diff --git a/bgpdump_mstream.h b/bgpdump_mstream.h index 45c4076..085c25f 100644 --- a/bgpdump_mstream.h +++ b/bgpdump_mstream.h @@ -1,40 +1,27 @@ -/* $Id$ */ /* - -Copyright (c) 2007 RIPE NCC - - -All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, provided -that the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the name of the author not be used in advertising or -publicity pertaining to distribution of the software without specific, -written prior permission. - -THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL -AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY -DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN -AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -*/ - -/* - + Copyright (c) 2007 - 2010 RIPE NCC - All Rights Reserved + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, provided + that the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation, and that the name of the author not be used in advertising or + publicity pertaining to distribution of the software without specific, + written prior permission. + + THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL + AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + Parts of this code have been engineered after analiyzing GNU Zebra's source code and therefore might contain declarations/code from GNU Zebra, Copyright (C) 1999 Kunihiro Ishiguro. Zebra is a free routing software, distributed under the GNU General Public License. A copy of this license is included with libbgpdump. -*/ - - -/* Original Author: Dan Ardelean (dan@ripe.net) */ @@ -44,18 +31,19 @@ Original Author: Dan Ardelean (dan@ripe.net) #include #include -struct mstream { +typedef struct mstream { u_char *start; u_int16_t position; u_int32_t len; -}; - - void mstream_init(struct mstream *s, u_char *buffer,u_int32_t len); - u_char mstream_getc(struct mstream *s, u_char *d); - u_int16_t mstream_getw(struct mstream *s, u_int16_t *d); - u_int32_t mstream_getl(struct mstream *s, u_int32_t *d); - u_int32_t mstream_get_ipv4(struct mstream *s, u_int32_t *d); - u_int32_t mstream_can_read(struct mstream *s); - u_int32_t mstream_get (struct mstream *s, void *d, u_int32_t len); +} mstream_t; + +void mstream_init(struct mstream *s, u_char *buffer,u_int32_t len); +u_char mstream_getc(struct mstream *s, u_char *d); +u_int16_t mstream_getw(struct mstream *s, u_int16_t *d); +u_int32_t mstream_getl(struct mstream *s, u_int32_t *d); +u_int32_t mstream_get_ipv4(struct mstream *s, u_int32_t *d); +u_int32_t mstream_can_read(struct mstream *s); +u_int32_t mstream_get (struct mstream *s, void *d, u_int32_t len); +mstream_t mstream_copy(mstream_t *s, int len); #endif diff --git a/cfile_tools.c b/cfile_tools.c index 9c7a24e..8a8ac16 100644 --- a/cfile_tools.c +++ b/cfile_tools.c @@ -1,4 +1,3 @@ - /** cfile_tools.c @@ -9,10 +8,7 @@ Distributed under the Gnu Public License version 2 or the modified BSD license (see file COPYING) - Support for gzip added by Bernhard Tellenbach - - $Revision$ $Date$ - + Support for gzip added by Bernhard Tellenbach */ #define _GNU_SOURCE @@ -379,12 +375,11 @@ ssize_t cfr_getline(char **lineptr, size_t *n, CFRFILE *stream) { #ifndef DONT_HAVE_BZ2 case 2: // bzip2 { - BZFILE * bzin; size_t count; char c; size_t ret; - bzin = (BZFILE *) (stream->data2); + //bzin = (BZFILE *) (stream->data2); // allocate initial buffer if none was passed or size was zero if (*lineptr == NULL) { @@ -508,7 +503,7 @@ char * cfr_strerror(CFRFILE *stream) { free(msg); msg = msg2; } - snprintf(res, 120, msg); + snprintf(res, 120, "%s", msg); res[119] = 0; free(msg); return(res); diff --git a/cfile_tools.h b/cfile_tools.h index 5fcbb03..eea9acb 100644 --- a/cfile_tools.h +++ b/cfile_tools.h @@ -23,8 +23,6 @@ - no compression - bzip2 - gzip - - $Revision$ $Date$ */ #ifndef _CFILE_TOOLS_DEFINES diff --git a/test.c b/test.c index 4c442d3..0db7766 100644 --- a/test.c +++ b/test.c @@ -1,51 +1,28 @@ -static const char RCSID[] = "$Id$"; /* - -Copyright (c) 2002 RIPE NCC - - -All Rights Reserved - -Permission to use, copy, modify, and distribute this software and its -documentation for any purpose and without fee is hereby granted, provided -that the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation, and that the name of the author not be used in advertising or -publicity pertaining to distribution of the software without specific, -written prior permission. - -THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING -ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL -AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY -DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN -AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -*/ - -/* - + Copyright (c) 2007 - 2010 RIPE NCC - All Rights Reserved + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, provided + that the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation, and that the name of the author not be used in advertising or + publicity pertaining to distribution of the software without specific, + written prior permission. + + THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL + AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + Parts of this code have been engineered after analiyzing GNU Zebra's source code and therefore might contain declarations/code from GNU Zebra, Copyright (C) 1999 Kunihiro Ishiguro. Zebra is a free routing software, distributed under the GNU General Public License. A copy of this license is included with libbgpdump. -*/ - -/* -------------------------------------------------------------------------------- -Module Header -Filename : test.c -Author : Dan Ardelean (dan@ripe.net) -Date : 02-SEP-2002 -Revision : -Revised : -Description : Example of libbgpdump usage -Language Version : C -OSs Tested : Linux 2.2.19 -To Do : -------------------------------------------------------------------------------- +Author: Dan Ardelean (dan@ripe.net) */ #include "bgpdump_lib.h" @@ -57,7 +34,7 @@ To Do : #include void process(BGPDUMP_ENTRY *entry); - void show_attr(struct attr *attr); + void show_attr(attributes_t *attr); void show_prefixes(int count,struct prefix *prefix); #ifdef BGPDUMP_HAVE_IPV6 void show_v6_prefixes(int count, struct prefix *prefix); @@ -67,15 +44,14 @@ int main(int argc, char **argv) { BGPDUMP *my_dump; BGPDUMP_ENTRY *my_entry=NULL; - if(argc != 2) { - fprintf(stderr, "no dump file supplied\n"); - exit(1); + if(argc>1) { + my_dump=bgpdump_open_dump(argv[1]); + } else { + my_dump=bgpdump_open_dump("dumps/updates.20020701.0032"); } - my_dump=bgpdump_open_dump(argv[1]); - if(my_dump==NULL) { - printf("Error opening dump file\n"); + printf("Error opening dump file ...\n"); exit(1); } @@ -376,7 +352,7 @@ if(entry->type == BGPDUMP_TYPE_ZEBRA_BGP && entry->subtype == BGPDUMP_SUBTYPE_ZE printf("\n"); } -void show_attr(struct attr *attr) { +void show_attr(attributes_t *attr) { int have_nexthop = 0; printf("ATTRIBUTES :\n"); diff --git a/test.sh b/test.sh index 558928e..89fd260 100755 --- a/test.sh +++ b/test.sh @@ -7,11 +7,10 @@ for mrt in `ls test_data`; do echo -n " testing $mrt..." OUT=$mrt.bgp.gz ./bgpdump -vm test_data/$mrt | gzip > test_out/$OUT - cmp -si 6 test_out/$OUT test_expect/$OUT + cmp -i 10 test_out/$OUT test_expect/$OUT if [ $? == 0 ]; then echo "success" else - echo "FAILURE" FAILURES=$(( $FAILURES + 1 )) fi done diff --git a/test_data/bview.20100101.0759.gz b/test_data/bview.20100101.0759.gz new file mode 100644 index 0000000..ceaa5c2 Binary files /dev/null and b/test_data/bview.20100101.0759.gz differ diff --git a/test_data/rrc07-bview.20100101.0759.gz b/test_data/rrc07-bview.20100101.0759.gz new file mode 100644 index 0000000..969d53d Binary files /dev/null and b/test_data/rrc07-bview.20100101.0759.gz differ diff --git a/test_expect/bview.20100101.0759.gz.bgp.gz b/test_expect/bview.20100101.0759.gz.bgp.gz new file mode 100644 index 0000000..9537067 Binary files /dev/null and b/test_expect/bview.20100101.0759.gz.bgp.gz differ diff --git a/test_expect/rrc07-bview.20100101.0759.gz.bgp.gz b/test_expect/rrc07-bview.20100101.0759.gz.bgp.gz new file mode 100644 index 0000000..111b2a7 Binary files /dev/null and b/test_expect/rrc07-bview.20100101.0759.gz.bgp.gz differ diff --git a/util.c b/util.c new file mode 100644 index 0000000..a355624 --- /dev/null +++ b/util.c @@ -0,0 +1,67 @@ +/* + Copyright (c) 2007 - 2010 RIPE NCC - All Rights Reserved + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, provided + that the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation, and that the name of the author not be used in advertising or + publicity pertaining to distribution of the software without specific, + written prior permission. + + THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL + AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Created by Devin Bayer on 9/1/10. +*/ + +#include "util.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +static bool use_syslog = true; + +void log_to_syslog() { + use_syslog = true; +} + +void log_to_stderr() { + use_syslog = false; +} + +#define log(lvl, lvl_str) \ + va_list args; \ + va_start(args, fmt); \ + _log(LOG_##lvl, #lvl_str, fmt, args) + +static char *now_str() { + static char buffer[1000]; + time_t now = time(0); + strftime(buffer, sizeof buffer, "%Y-%m-%d %H:%M:%S", localtime(&now)); + return buffer; +} + +static void _log(int lvl, char *lvl_str, char *fmt, va_list args) { + if(use_syslog) { + syslog(lvl, fmt, args); + } else { + char prefix[strlen(fmt) + 1000]; + sprintf(prefix, "%s [%s] %s\n", now_str(), lvl_str, fmt); + vfprintf(stderr, prefix, args); + } +} + +void err(char *fmt, ...) { log(ERR, error); } +void warn(char *fmt, ...) { log(WARNING, warn); } +void info(char *fmt, ...) { log(INFO, info); } diff --git a/util.h b/util.h new file mode 100644 index 0000000..8b27afb --- /dev/null +++ b/util.h @@ -0,0 +1,32 @@ +/* + Copyright (c) 2007 - 2010 RIPE NCC - All Rights Reserved + + Permission to use, copy, modify, and distribute this software and its + documentation for any purpose and without fee is hereby granted, provided + that the above copyright notice appear in all copies and that both that + copyright notice and this permission notice appear in supporting + documentation, and that the name of the author not be used in advertising or + publicity pertaining to distribution of the software without specific, + written prior permission. + + THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING + ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL + AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY + DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN + AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + + Created by Devin Bayer on 9/1/10. +*/ + +#ifndef _UTIL_H +#define _UTIL_H + +void log_to_stderr(); +void log_to_syslog(); + +void err(char *fmt, ...) __attribute__((format(printf, 1, 2))); +void warn(char *fmt, ...) __attribute__((format(printf, 1, 2))); +void info(char *fmt, ...) __attribute__((format(printf, 1, 2))); + +#endif \ No newline at end of file