Only in libbgpdump-1.4/: CVS diff -r -U 3 libbgpdump-1.4/ChangeLog libbgpdump-new/ChangeLog --- libbgpdump-1.4/ChangeLog 2005-06-09 11:56:00.000000000 +0200 +++ libbgpdump-new/ChangeLog 2005-01-14 22:30:10.000000000 +0100 @@ -1,37 +1,3 @@ -2004-05-17 Lorenzo Colitti - * Output times properly in withdrawals with -m/-M - * Properly support ipv6 with table dumps and -M - -2004-02-04 Hong-wei Kong - * Add a new option (-t dump|change) to bgpdump. If '-t dump' is - specified, then the decoding result with '-m' / '-M' option will - show the timestamp when these routes are dumped. If '-t change' is - specified, then the decoding result with '-m' / '-M' option will - show the timestamp when the routes were last time changed. This - option only works with routing table dumps. - -2004-01-16 Lorenzo Colitti - * Fix compile errors under cygwin (only IPv4 works though) - -2003-12-18 Hong-Wei Kong - * Added support for dumping BGP routing table entries in - machine-readable format (-m). Previously -m was only supported - for BGP messages - -2003-12-16 Shufu Mao - * Revised the decoding of BGP routing table dump to make the result - identical to route_btoa - -2003-12-15 Lorenzo Colitti - * Proper autoconf support: check for features instead of target - systems, remove extra .h files and only use configure.in, use - Makefile.in instead of Make.include, link both static and - shared library, check for ar and ranlib, etc. - * Changed INET6 to BGPDUMP_HAVE_IPV6 - (N.B. Docs are not updated yet) - * Fixed possible endianness issues on Sparc. - * Fixed a crash while decoding NOTIFICATION messages - 2004-02-10 Lorenzo Colitti * Fix a stupid crash when reading truncated prefixes. diff -r -U 3 libbgpdump-1.4/Makefile.in libbgpdump-new/Makefile.in --- libbgpdump-1.4/Makefile.in 2004-07-29 15:48:19.000000000 +0200 +++ libbgpdump-new/Makefile.in 2005-01-14 22:30:09.000000000 +0100 @@ -1,4 +1,4 @@ -# $Id: Makefile.in,v 1.1.1.1 2004/07/29 13:48:19 james Exp $ +# $Id: Makefile.in,v 1.1.1.1 2005/01/14 21:30:09 ljb Exp $ CC = @CC@ CFLAGS = @CFLAGS@ diff -r -U 3 libbgpdump-1.4/VERSION libbgpdump-new/VERSION --- libbgpdump-1.4/VERSION 2005-01-17 11:38:22.000000000 +0100 +++ libbgpdump-new/VERSION 2005-01-14 22:30:09.000000000 +0100 @@ -1 +1 @@ -libbgpdump-1.4.1 +libbgpdump-1.4 Only in libbgpdump-new/: bgpdump-config.h.in diff -r -U 3 libbgpdump-1.4/bgpdump.c libbgpdump-new/bgpdump.c --- libbgpdump-1.4/bgpdump.c 2005-01-17 11:18:51.000000000 +0100 +++ libbgpdump-new/bgpdump.c 2005-06-09 14:03:28.000000000 +0200 @@ -1,51 +1,46 @@ /* + * + * 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) 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. - -*/ - -/* - -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. - -*/ +/* + * + * 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 : bgpdump.c -Author : Shufu Mao(msf98@mails.tsinghua.edu.cn) -Date : 2003-11-02 -Revision : -Revised : -Description : bgpdump program, the input and output format is the same as route_btoa -Language Version : C -OSs Tested : Linux 2.4.22 -To Do : -------------------------------------------------------------------------------- -*/ + * ---------------------------------------------------------------------------- + * Module Header Filename : bgpdump.c Author : Shufu + * Mao(msf98@mails.tsinghua.edu.cn) Date : 2003-11-02 Revision : Revised : + * Description : bgpdump program, the input and output format is the same as + * route_btoa Language Version : C OSs Tested : Linux 2.4.22 To Do : + * ---------------------------------------------------------------------------- + */ #if HAVE_CONFIG_H #include @@ -59,1406 +54,2160 @@ #include #include - void process(BGPDUMP_ENTRY *entry); + 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); -#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); - void table_line_announce6(int mode,struct mp_nlri *prefix,int count,BGPDUMP_ENTRY *entry,char *time_str); + 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); +#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); + void table_line_announce6(int mode, struct mp_nlri *prefix, int count, BGPDUMP_ENTRY * entry, char *time_str); #endif + static int mode = 0; + static int timetype = 0; - static int mode=0; - static int timetype=0; - -int main(int argc, char *argv[]) { - - BGPDUMP *my_dump; - BGPDUMP_ENTRY *my_entry=NULL; - extern char *optarg; - char c; - extern int optind; - char *usage = "Usage: bgpdump [-m] [-M] [-i] [-t dump|change ] input_binary_file(s) \n"; +int main(int argc, char *argv[]) +{ - while ((c=getopt(argc,argv,"if:o:t:mM"))!=-1) - switch(c) - { + BGPDUMP *my_dump; + BGPDUMP_ENTRY *my_entry = NULL; + extern char *optarg; + char c; + extern int optind; + char *usage = + "Usage: bgpdump [-m] [-M] [-i] [-t dump|change ] input_binary_file(s) \n"; + + while ((c = getopt(argc, argv, "if:o:t:mM")) != -1) + switch (c) { 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; - } + if (strcmp(optarg, "dump") == 0) { + timetype = 0; + } else if (strcmp(optarg, "change") == 0) { + timetype = 1; + } default: - break; + break; } - - if(argc>1) { - my_dump=bgpdump_open_dump(argv[optind]); + + if (argc > 1) { + my_dump = bgpdump_open_dump(argv[optind]); } else { - my_dump=bgpdump_open_dump("dumps/updates.20020701.0032"); + my_dump = bgpdump_open_dump("dumps/updates.20020701.0032"); } - - if(my_dump==NULL) { - printf("%s",usage); + + if (my_dump == NULL) { + printf("%s", usage); exit(1); } - + do { - my_entry=bgpdump_read_next(my_dump); - if(my_entry!=NULL) { + my_entry = bgpdump_read_next(my_dump); + if (my_entry != NULL) { process(my_entry); bgpdump_free_mem(my_entry); } - } while(my_dump->eof==0); + } + while (my_dump->eof == 0); bgpdump_close_dump(my_dump); - - return 0; + + return 0; } -char *bgp_state_name[] = { - "Unknown", - "Idle", - "Connect", - "Active", - "Opensent", - "Openconfirm", - "Established", - NULL +char *bgp_state_name[] = { + "Unknown", + "Idle", + "Connect", + "Active", + "Opensent", + "Openconfirm", + "Established", + NULL }; -void time2str(struct tm* time,char *time_str) + +void +time2str(struct tm *time, char *time_str) { - char tmp_str[10]; + char tmp_str[10]; - if (time->tm_mon+1<10) - sprintf(tmp_str,"0%d/",time->tm_mon+1); - else - sprintf(tmp_str,"%d/",time->tm_mon+1); - strcpy(time_str,tmp_str); - - if (time->tm_mday<10) - sprintf(tmp_str,"0%d/",time->tm_mday); - else - sprintf(tmp_str,"%d/",time->tm_mday); - strcat(time_str,tmp_str); - - if (time->tm_year%100 <10) - sprintf(tmp_str,"0%d ",time->tm_year%100); - else - sprintf(tmp_str,"%d ",time->tm_year%100); - strcat(time_str,tmp_str); - - if (time->tm_hour<10) - sprintf(tmp_str,"0%d:",time->tm_hour); - else - sprintf(tmp_str,"%d:",time->tm_hour); - strcat(time_str,tmp_str); - - if (time->tm_min<10) - sprintf(tmp_str,"0%d:",time->tm_min); - else - sprintf(tmp_str,"%d:",time->tm_min); - strcat(time_str,tmp_str); - - if (time->tm_sec <10) - sprintf(tmp_str,"0%d",time->tm_sec); - else - sprintf(tmp_str,"%d",time->tm_sec); - strcat(time_str,tmp_str); + if (time->tm_mon + 1 < 10) + sprintf(tmp_str, "0%d/", time->tm_mon + 1); + else + sprintf(tmp_str, "%d/", time->tm_mon + 1); + strcpy(time_str, tmp_str); + + if (time->tm_mday < 10) + sprintf(tmp_str, "0%d/", time->tm_mday); + else + sprintf(tmp_str, "%d/", time->tm_mday); + strcat(time_str, tmp_str); + + if (time->tm_year % 100 < 10) + sprintf(tmp_str, "0%d ", time->tm_year % 100); + else + sprintf(tmp_str, "%d ", time->tm_year % 100); + strcat(time_str, tmp_str); + + if (time->tm_hour < 10) + sprintf(tmp_str, "0%d:", time->tm_hour); + else + sprintf(tmp_str, "%d:", time->tm_hour); + strcat(time_str, tmp_str); + + if (time->tm_min < 10) + sprintf(tmp_str, "0%d:", time->tm_min); + else + sprintf(tmp_str, "%d:", time->tm_min); + strcat(time_str, tmp_str); + + if (time->tm_sec < 10) + sprintf(tmp_str, "0%d", time->tm_sec); + else + sprintf(tmp_str, "%d", time->tm_sec); + strcat(time_str, tmp_str); } -void process(BGPDUMP_ENTRY *entry) { - struct tm *time; - char time_str[128]; - char time_str2[128]; - char tmp_str[10]; - char prefix[BGPDUMP_ADDRSTRLEN]; - - time=gmtime(&entry->time); - time2str(time,time_str); - if (mode==0) - { - printf("TIME: %s\n",time_str); - } - //printf("TIME: %s",asctime(gmtime(&entry->time))); - //printf("LENGTH : %u\n", entry->length); - switch(entry->type) { - case BGPDUMP_TYPE_MRTD_TABLE_DUMP: - if(mode==0){ -#ifdef BGPDUMP_HAVE_IPV6 - if (entry->subtype == AFI_IP6) - printf("TYPE: TABLE_DUMP/INET6\n"); - else -#endif - printf("TYPE: TABLE_DUMP/INET\n"); - printf("VIEW: %d\n",entry->body.mrtd_table_dump.view); - printf("SEQUENCE: %d\n",entry->body.mrtd_table_dump.sequence); - printf("PREFIX: %s/%d\n",inet_ntoa(entry->body.mrtd_table_dump.prefix.v4_addr),entry->body.mrtd_table_dump.mask); - printf("FROM:"); - switch(entry->subtype) - { -#ifdef BGPDUMP_HAVE_IPV6 - case AFI_IP6: +void print_notify_message(u_char error_code, u_char sub_error_code) { - inet_ntop(AF_INET6,&entry->body.mrtd_table_dump.peer_ip.v6_addr,prefix,sizeof(prefix)); - printf(" %s ",prefix); - break; -#endif - case AFI_IP: - default: - if (entry->body.mrtd_table_dump.peer_ip.v4_addr.s_addr != 0x00000000L) - printf(" %s ",inet_ntoa(entry->body.mrtd_table_dump.peer_ip.v4_addr)); - else - printf(" N/A "); - } - printf("AS%d\n",entry->body.mrtd_table_dump.peer_as); + switch (error_code) { + case 1: + printf(" ERROR CODE : 1 (Message Header Error)\n"); + switch (sub_error_code) { + case 1: + printf + (" SUB ERROR : 1 (Connection Not Synchronized)\n"); + break; - //printf("FROM: %s AS%d\n",inet_ntoa(entry->body.mrtd_table_dump.peer_ip.v4_addr),entry->body.mrtd_table_dump.peer_as); - //time2str(localtime(&entry->body.mrtd_table_dump.uptime),time_str2); - time2str(gmtime(&entry->body.mrtd_table_dump.uptime),time_str2); - printf("ORIGINATED: %s\n",time_str2); - if (entry->attr && entry->attr->len) - show_attr(entry->attr); + case 2: + printf + (" SUB ERROR : 2 (Bad Message Length)\n"); + break; - printf("STATUS: 0x%x\n",entry->body.mrtd_table_dump.status); - - - //printf(" UPTIME : %s",asctime(gmtime(&entry->body.mrtd_table_dump.uptime))); - //printf(" PEER IP : %s\n",inet_ntoa(entry->body.mrtd_table_dump.peer_ip)); - //printf(" PEER IP : %s\n",inet_ntoa(entry->body.mrtd_table_dump.peer_ip.v4_addr)); - //printf(" PEER AS : %d\n",entry->body.mrtd_table_dump.peer_as); - } - else if (mode ==1 || mode ==2) // -m -M - { - table_line_mrtd_route(mode,&entry->body.mrtd_table_dump,entry,timetype); - } + case 3: + printf(" SUB ERROR : 3 (Bad Message Type)\n"); + break; + + default: + printf(" SUB ERROR : %d\n", sub_error_code); + break; + } break; - - case BGPDUMP_TYPE_ZEBRA_BGP: - - switch(entry->subtype) - { - case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE: + case 2: + printf(" ERROR CODE : 2 (OPEN Message Error)\n"); + switch (sub_error_code) { + case 1: + printf + (" SUB ERROR : 1 (Unsupported Version Number)\n"); + break; - switch(entry->body.zebra_message.type) - { - case BGP_MSG_UPDATE: - if (mode ==0) - { - printf("TYPE: BGP4MP/MESSAGE/Update\n"); - if (entry->body.zebra_message.source_as) - { - printf("FROM:"); - switch(entry->body.zebra_message.address_family) - { -#ifdef BGPDUMP_HAVE_IPV6 - case AFI_IP6: - - inet_ntop(AF_INET6,&entry->body.zebra_message.source_ip.v6_addr,prefix,sizeof(prefix)); - printf(" %s ",prefix); - break; -#endif - case AFI_IP: - default: - if (entry->body.zebra_message.source_ip.v4_addr.s_addr != 0x00000000L) - printf(" %s ",inet_ntoa(entry->body.zebra_message.source_ip.v4_addr)); - else - printf(" N/A "); - } - printf("AS%d\n",entry->body.zebra_message.source_as); - } - if (entry->body.zebra_message.destination_as) - { - printf("TO:"); - switch(entry->body.zebra_message.address_family) - { -#ifdef BGPDUMP_HAVE_IPV6 - case AFI_IP6: - - inet_ntop(AF_INET6,&entry->body.zebra_message.destination_ip.v6_addr,prefix,sizeof(prefix)); - printf(" %s ",prefix); - break; -#endif - case AFI_IP: - default: - if (entry->body.zebra_message.destination_ip.v4_addr.s_addr != 0x00000000L) - printf(" %s ",inet_ntoa(entry->body.zebra_message.destination_ip.v4_addr)); - else - printf(" N/A "); - } - printf("AS%d\n",entry->body.zebra_message.destination_as); - } - if (entry->attr && entry->attr->len) - show_attr(entry->attr); - if (entry->body.zebra_message.cut_bytes) - { - u_int16_t cutted,index; - u_int8_t buf[128]; - - printf(" INCOMPLETE PACKET: %d bytes cutted\n",entry->body.zebra_message.cut_bytes); - printf(" INCOMPLETE PART: "); - if (entry->body.zebra_message.incomplete.orig_len) - { - cutted=entry->body.zebra_message.incomplete.prefix.len/8+1; - buf[0]=entry->body.zebra_message.incomplete.orig_len; - memcpy(buf+1,&entry->body.zebra_message.incomplete.prefix.address,cutted-1); - - for (index=0;indexbody.zebra_message.withdraw_count) || (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MP_UNREACH_NLRI))) - { -#ifdef BGPDUMP_HAVE_IPV6 - if ((entry->body.zebra_message.withdraw_count)||(entry->attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST] && entry->attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST]->prefix_count) || (entry->attr->mp_info->withdraw[AFI_IP][SAFI_MULTICAST] && entry->attr->mp_info->withdraw[AFI_IP][SAFI_MULTICAST]->prefix_count) || (entry->attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST_MULTICAST] && entry->attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST_MULTICAST]->prefix_count) ||(entry->attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST] && entry->attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST]->prefix_count) || (entry->attr->mp_info->withdraw[AFI_IP6][SAFI_MULTICAST] && entry->attr->mp_info->withdraw[AFI_IP6][SAFI_MULTICAST]->prefix_count) || (entry->attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST_MULTICAST] && entry->attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST_MULTICAST]->prefix_count) ) + case 2: + printf(" SUB ERROR : 2 (Bad Peer AS)\n"); + break; -#else - if ((entry->body.zebra_message.withdraw_count)||(entry->attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST] && entry->attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST]->prefix_count) || (entry->attr->mp_info->withdraw[AFI_IP][SAFI_MULTICAST] && entry->attr->mp_info->withdraw[AFI_IP][SAFI_MULTICAST]->prefix_count) || (entry->attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST_MULTICAST] && entry->attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST_MULTICAST]->prefix_count)) + case 3: + printf + (" SUB ERROR : 3 (Bad BGP Identifier)\n"); + break; -#endif - printf("WITHDRAW\n"); - if (entry->body.zebra_message.withdraw_count) - show_prefixes(entry->body.zebra_message.withdraw_count,entry->body.zebra_message.withdraw); - if (entry->attr->mp_info) - { - if (entry->attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST] && entry->attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST]->prefix_count) - show_prefixes(entry->attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST]->prefix_count,entry->attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST]->nlri); - - if (entry->attr->mp_info->withdraw[AFI_IP][SAFI_MULTICAST] && entry->attr->mp_info->withdraw[AFI_IP][SAFI_MULTICAST]->prefix_count) - show_prefixes(entry->attr->mp_info->withdraw[AFI_IP][SAFI_MULTICAST]->prefix_count,entry->attr->mp_info->withdraw[AFI_IP][SAFI_MULTICAST]->nlri); - - if (entry->attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST_MULTICAST] && entry->attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST_MULTICAST]->prefix_count) - show_prefixes(entry->attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST_MULTICAST]->prefix_count,entry->attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST_MULTICAST]->nlri); - -#ifdef BGPDUMP_HAVE_IPV6 - if (entry->attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST] && entry->attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST]->prefix_count) - show_prefixes6(entry->attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST]->prefix_count,entry->attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST]->nlri); - - if (entry->attr->mp_info->withdraw[AFI_IP6][SAFI_MULTICAST] && entry->attr->mp_info->withdraw[AFI_IP6][SAFI_MULTICAST]->prefix_count) - show_prefixes6(entry->attr->mp_info->withdraw[AFI_IP6][SAFI_MULTICAST]->prefix_count,entry->attr->mp_info->withdraw[AFI_IP6][SAFI_MULTICAST]->nlri); - - if (entry->attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST_MULTICAST] && entry->attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST_MULTICAST]->prefix_count) - show_prefixes6(entry->attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST_MULTICAST]->prefix_count,entry->attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST_MULTICAST]->nlri); -#endif - } - } - if ( (entry->body.zebra_message.announce_count) || (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI))) - { - printf("ANNOUNCE\n"); - if (entry->body.zebra_message.announce_count) - show_prefixes(entry->body.zebra_message.announce_count,entry->body.zebra_message.announce); - if (entry->attr->mp_info) - { - if (entry->attr->mp_info->announce[AFI_IP][SAFI_UNICAST] && entry->attr->mp_info->announce[AFI_IP][SAFI_UNICAST]->prefix_count) - show_prefixes(entry->attr->mp_info->announce[AFI_IP][SAFI_UNICAST]->prefix_count,entry->attr->mp_info->announce[AFI_IP][SAFI_UNICAST]->nlri); - - if (entry->attr->mp_info->announce[AFI_IP][SAFI_MULTICAST] && entry->attr->mp_info->announce[AFI_IP][SAFI_MULTICAST]->prefix_count) - show_prefixes(entry->attr->mp_info->announce[AFI_IP][SAFI_MULTICAST]->prefix_count,entry->attr->mp_info->announce[AFI_IP][SAFI_MULTICAST]->nlri); - - if (entry->attr->mp_info->announce[AFI_IP][SAFI_UNICAST_MULTICAST] && entry->attr->mp_info->announce[AFI_IP][SAFI_UNICAST_MULTICAST]->prefix_count) - show_prefixes(entry->attr->mp_info->announce[AFI_IP][SAFI_UNICAST_MULTICAST]->prefix_count,entry->attr->mp_info->announce[AFI_IP][SAFI_UNICAST_MULTICAST]->nlri); - -#ifdef BGPDUMP_HAVE_IPV6 - if (entry->attr->mp_info->announce[AFI_IP6][SAFI_UNICAST] && entry->attr->mp_info->announce[AFI_IP6][SAFI_UNICAST]->prefix_count) - show_prefixes6(entry->attr->mp_info->announce[AFI_IP6][SAFI_UNICAST]->prefix_count,entry->attr->mp_info->announce[AFI_IP6][SAFI_UNICAST]->nlri); - - if (entry->attr->mp_info->announce[AFI_IP6][SAFI_MULTICAST] && entry->attr->mp_info->announce[AFI_IP6][SAFI_MULTICAST]->prefix_count) - show_prefixes6(entry->attr->mp_info->announce[AFI_IP6][SAFI_MULTICAST]->prefix_count,entry->attr->mp_info->announce[AFI_IP6][SAFI_MULTICAST]->nlri); - - if (entry->attr->mp_info->announce[AFI_IP6][SAFI_UNICAST_MULTICAST] && entry->attr->mp_info->announce[AFI_IP6][SAFI_UNICAST_MULTICAST]->prefix_count) - show_prefixes6(entry->attr->mp_info->announce[AFI_IP6][SAFI_UNICAST_MULTICAST]->prefix_count,entry->attr->mp_info->announce[AFI_IP6][SAFI_UNICAST_MULTICAST]->nlri); -#endif - } - } - } - else if (mode == 1 || mode == 2) //-m -M - { - if ((entry->body.zebra_message.withdraw_count) || (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MP_UNREACH_NLRI))) - { - - table_line_withdraw(mode,entry->body.zebra_message.withdraw,entry->body.zebra_message.withdraw_count,entry,time_str); - if (entry->attr->mp_info) - { - if (entry->attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST] && entry->attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST]->prefix_count) - table_line_withdraw(mode,entry->attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST]->nlri,entry->attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST]->prefix_count,entry,time_str); - if (entry->attr->mp_info->withdraw[AFI_IP][SAFI_MULTICAST] && entry->attr->mp_info->withdraw[AFI_IP][SAFI_MULTICAST]->prefix_count) - table_line_withdraw(mode,entry->attr->mp_info->withdraw[AFI_IP][SAFI_MULTICAST]->nlri,entry->attr->mp_info->withdraw[AFI_IP][SAFI_MULTICAST]->prefix_count,entry,time_str); - if (entry->attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST_MULTICAST] && entry->attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST_MULTICAST]->prefix_count) - table_line_withdraw(mode,entry->attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST_MULTICAST]->nlri,entry->attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST_MULTICAST]->prefix_count,entry,time_str); - -#ifdef BGPDUMP_HAVE_IPV6 - if (entry->attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST] && entry->attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST]->prefix_count) - table_line_withdraw6(mode,entry->attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST]->nlri,entry->attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST]->prefix_count,entry,time_str); - if (entry->attr->mp_info->withdraw[AFI_IP6][SAFI_MULTICAST] && entry->attr->mp_info->withdraw[AFI_IP6][SAFI_MULTICAST]->prefix_count) - table_line_withdraw6(mode,entry->attr->mp_info->withdraw[AFI_IP6][SAFI_MULTICAST]->nlri,entry->attr->mp_info->withdraw[AFI_IP6][SAFI_MULTICAST]->prefix_count,entry,time_str); - if (entry->attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST_MULTICAST] && entry->attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST_MULTICAST]->prefix_count) - table_line_withdraw6(mode,entry->attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST_MULTICAST]->nlri,entry->attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST_MULTICAST]->prefix_count,entry,time_str); -#endif - - } - - - } - if ( (entry->body.zebra_message.announce_count) || (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI))) - { - table_line_announce(mode,entry->body.zebra_message.announce,entry->body.zebra_message.announce_count,entry,time_str); - if (entry->attr->mp_info) - { - if (entry->attr->mp_info->announce[AFI_IP][SAFI_UNICAST] && entry->attr->mp_info->announce[AFI_IP][SAFI_UNICAST]->prefix_count) - table_line_announce_1(mode,entry->attr->mp_info->announce[AFI_IP][SAFI_UNICAST],entry->attr->mp_info->announce[AFI_IP][SAFI_UNICAST]->prefix_count,entry,time_str); - if (entry->attr->mp_info->announce[AFI_IP][SAFI_MULTICAST] && entry->attr->mp_info->announce[AFI_IP][SAFI_MULTICAST]->prefix_count) - table_line_announce_1(mode,entry->attr->mp_info->announce[AFI_IP][SAFI_MULTICAST],entry->attr->mp_info->announce[AFI_IP][SAFI_MULTICAST]->prefix_count,entry,time_str); - if (entry->attr->mp_info->announce[AFI_IP][SAFI_UNICAST_MULTICAST] && entry->attr->mp_info->announce[AFI_IP][SAFI_UNICAST_MULTICAST]->prefix_count) - table_line_announce_1(mode,entry->attr->mp_info->announce[AFI_IP][SAFI_UNICAST_MULTICAST],entry->attr->mp_info->announce[AFI_IP][SAFI_UNICAST_MULTICAST]->prefix_count,entry,time_str); -#ifdef BGPDUMP_HAVE_IPV6 - if (entry->attr->mp_info->announce[AFI_IP6][SAFI_UNICAST] && entry->attr->mp_info->announce[AFI_IP6][SAFI_UNICAST]->prefix_count) - table_line_announce6(mode,entry->attr->mp_info->announce[AFI_IP6][SAFI_UNICAST],entry->attr->mp_info->announce[AFI_IP6][SAFI_UNICAST]->prefix_count,entry,time_str); - if (entry->attr->mp_info->announce[AFI_IP6][SAFI_MULTICAST] && entry->attr->mp_info->announce[AFI_IP6][SAFI_MULTICAST]->prefix_count) - table_line_announce6(mode,entry->attr->mp_info->announce[AFI_IP6][SAFI_MULTICAST],entry->attr->mp_info->announce[AFI_IP6][SAFI_MULTICAST]->prefix_count,entry,time_str); - if (entry->attr->mp_info->announce[AFI_IP6][SAFI_UNICAST_MULTICAST] && entry->attr->mp_info->announce[AFI_IP6][SAFI_UNICAST_MULTICAST]->prefix_count) - table_line_announce6(mode,entry->attr->mp_info->announce[AFI_IP6][SAFI_UNICAST_MULTICAST],entry->attr->mp_info->announce[AFI_IP6][SAFI_UNICAST_MULTICAST]->prefix_count,entry,time_str); -#endif - - } - - } - } - break; - - case BGP_MSG_OPEN: - if (mode != 0) - break; - printf("TYPE: BGP4MP/MESSAGE/Open\n"); - if (entry->body.zebra_message.source_as) - { - printf("FROM:"); - switch(entry->body.zebra_message.address_family) - { -#ifdef BGPDUMP_HAVE_IPV6 - case AFI_IP6: - - inet_ntop(AF_INET6,&entry->body.zebra_message.source_ip.v6_addr,prefix,sizeof(prefix)); - printf(" %s ",prefix); - break; -#endif - case AFI_IP: - default: - if (entry->body.zebra_message.source_ip.v4_addr.s_addr != 0x00000000L) - printf(" %s ",inet_ntoa(entry->body.zebra_message.source_ip.v4_addr)); - else - printf(" N/A "); - } - printf("AS%d\n",entry->body.zebra_message.source_as); - } - if (entry->body.zebra_message.destination_as) - { - printf("TO:"); - switch(entry->body.zebra_message.address_family) - { -#ifdef BGPDUMP_HAVE_IPV6 - case AFI_IP6: - - inet_ntop(AF_INET6,&entry->body.zebra_message.destination_ip.v6_addr,prefix,sizeof(prefix)); - printf(" %s ",prefix); - break; -#endif - case AFI_IP: - default: - if (entry->body.zebra_message.destination_ip.v4_addr.s_addr != 0x00000000L) - printf(" %s ",inet_ntoa(entry->body.zebra_message.destination_ip.v4_addr)); - else - printf(" N/A "); - } - printf("AS%d\n",entry->body.zebra_message.destination_as); - } - - printf("VERSION: %d\n",entry->body.zebra_message.version); - printf("AS: %d\n",entry->body.zebra_message.my_as); - printf("HOLD_TIME: %d\n",entry->body.zebra_message.hold_time); - printf("ID: %s\n",inet_ntoa(entry->body.zebra_message.bgp_id)); - printf("OPT_PARM_LEN: %d\n",entry->body.zebra_message.opt_len); - break; - - case BGP_MSG_NOTIFY: - if (mode != 0) - break; - printf("TYPE: BGP4MP/MESSAGE/Notify\n"); - if (entry->body.zebra_message.source_as) - { - printf("FROM:"); - switch(entry->body.zebra_message.address_family) - { -#ifdef BGPDUMP_HAVE_IPV6 - case AFI_IP6: - - inet_ntop(AF_INET6,&entry->body.zebra_message.source_ip.v6_addr,prefix,sizeof(prefix)); - printf(" %s ",prefix); - break; -#endif - case AFI_IP: - default: - if (entry->body.zebra_message.source_ip.v4_addr.s_addr != 0x00000000L) - printf(" %s ",inet_ntoa(entry->body.zebra_message.source_ip.v4_addr)); - else - printf(" N/A "); - } - printf("AS%d\n",entry->body.zebra_message.source_as); - } - if (entry->body.zebra_message.destination_as) - { - printf("TO:"); - switch(entry->body.zebra_message.address_family) - { -#ifdef BGPDUMP_HAVE_IPV6 - case AFI_IP6: - - inet_ntop(AF_INET6,&entry->body.zebra_message.destination_ip.v6_addr,prefix,sizeof(prefix)); - printf(" %s ",prefix); - break; -#endif - case AFI_IP: - default: - if (entry->body.zebra_message.destination_ip.v4_addr.s_addr != 0x00000000L) - printf(" %s ",inet_ntoa(entry->body.zebra_message.destination_ip.v4_addr)); - else - printf(" N/A "); - } - printf("AS%d\n",entry->body.zebra_message.destination_as); - } - - switch (entry->body.zebra_message.error_code) - { - case 1: - printf(" ERROR CODE : 1 (Message Header Error)\n"); - switch(entry->body.zebra_message.sub_error_code) - { - case 1: - printf(" SUB ERROR : 1 (Connection Not Synchronized)\n"); - break; - - case 2: - printf(" SUB ERROR : 2 (Bad Message Length)\n"); - break; - - case 3: - printf(" SUB ERROR : 3 (Bad Message Type)\n"); - break; - - default: - printf(" SUB ERROR : %d\n",entry->body.zebra_message.sub_error_code); - break; - } - break; - case 2: - printf(" ERROR CODE : 2 (OPEN Message Error)\n"); - switch(entry->body.zebra_message.sub_error_code) - { - case 1: - printf(" SUB ERROR : 1 (Unsupported Version Number)\n"); - break; - - case 2: - printf(" SUB ERROR : 2 (Bad Peer AS)\n"); - break; - - case 3: - printf(" SUB ERROR : 3 (Bad BGP Identifier)\n"); - break; - - case 4: - printf(" SUB ERROR : 4 (Unsupported Optional Parameter)\n"); - break; - - case 5: - printf(" SUB ERROR : 5 (Authentication Failure)\n"); - break; - - case 6: - printf(" SUB ERROR : 6 (Unacceptable Hold Time)\n"); - break; - - default: - printf(" SUB ERROR : %d\n",entry->body.zebra_message.sub_error_code); - break; - } - break; - case 3: - printf(" ERROR CODE : 3 (UPDATE Message Error)\n"); - switch(entry->body.zebra_message.sub_error_code) - { - case 1: - printf(" SUB ERROR : 1 (Malformed Attribute List)\n"); - break; - - case 2: - printf(" SUB ERROR : 2 (Unrecognized Well-known Attribute)\n"); - break; - - case 3: - printf(" SUB ERROR : 3 (Missing Well-known Attribute)\n"); - break; - - case 4: - printf(" SUB ERROR : 4 (Attribute Flags Error)\n"); - break; - - case 5: - printf(" SUB ERROR : 5 (Attribute Length Error)\n"); - break; - - case 6: - printf(" SUB ERROR : 6 (Invalid ORIGIN Attribute)\n"); - break; - - case 7: - printf(" SUB ERROR : 7 (AS Routing Loop)\n"); - break; - - case 8: - printf(" SUB ERROR : 8 (Invalid NEXT-HOP Attribute)\n"); - break; - - case 9: - printf(" SUB ERROR : 9 (Optional Attribute Error)\n"); - break; - - case 10: - printf(" SUB ERROR : 10 (Invalid Network Field)\n"); - break; - - case 11: - printf(" SUB ERROR : 11 (Malformed AS-PATH)\n"); - break; - - default: - printf(" SUB ERROR : %d\n",entry->body.zebra_message.sub_error_code); - break; - } - break; - case 4: - printf(" ERROR CODE : 4 (Hold Timer Expired)\n"); - break; - case 5: - printf(" ERROR CODE : 5 (Finite State Machine Error)\n"); - break; - case 6: - printf(" ERROR CODE : 6 (Cease)\n"); - break; - default: - printf(" ERROR CODE : %d\n",entry->body.zebra_message.error_code); - break; - - } - break; - - case BGP_MSG_KEEPALIVE: - if ( mode != 0) - break; - - printf("TYPE: BGP4MP/MESSAGE/Keepalive\n"); - if (entry->body.zebra_message.source_as) - { - printf("FROM:"); - switch(entry->body.zebra_message.address_family) - { -#ifdef BGPDUMP_HAVE_IPV6 - case AFI_IP6: - - inet_ntop(AF_INET6,&entry->body.zebra_message.source_ip.v6_addr,prefix,sizeof(prefix)); - printf(" %s ",prefix); - break; -#endif - case AFI_IP: - default: - if (entry->body.zebra_message.source_ip.v4_addr.s_addr != 0x00000000L) - printf(" %s ",inet_ntoa(entry->body.zebra_message.source_ip.v4_addr)); - else - printf(" N/A "); - } - printf("AS%d\n",entry->body.zebra_message.source_as); - } - if (entry->body.zebra_message.destination_as) - { - printf("TO:"); - switch(entry->body.zebra_message.address_family) - { -#ifdef BGPDUMP_HAVE_IPV6 - case AFI_IP6: - - inet_ntop(AF_INET6,&entry->body.zebra_message.destination_ip.v6_addr,prefix,sizeof(prefix)); - printf(" %s ",prefix); - break; -#endif - case AFI_IP: - default: - if (entry->body.zebra_message.destination_ip.v4_addr.s_addr != 0x00000000L) - printf(" %s ",inet_ntoa(entry->body.zebra_message.destination_ip.v4_addr)); - else - printf(" N/A "); - } - printf("AS%d\n",entry->body.zebra_message.destination_as); - } + case 4: + printf + (" SUB ERROR : 4 (Unsupported Optional Parameter)\n"); + break; + case 5: + printf + (" SUB ERROR : 5 (Authentication Failure)\n"); + break; - break; - } - break; + case 6: + printf + (" SUB ERROR : 6 (Unacceptable Hold Time)\n"); + break; - case BGPDUMP_SUBTYPE_ZEBRA_BGP_STATE_CHANGE: - if (mode==0) - { - printf("TYPE: BGP4MP/STATE_CHANGE\n"); + default: + printf(" SUB ERROR : %d\n", sub_error_code); + break; + } + break; + case 3: + printf(" ERROR CODE : 3 (UPDATE Message Error)\n"); + switch (sub_error_code) { + case 1: + printf + (" SUB ERROR : 1 (Malformed Attribute List)\n"); + break; - printf("PEER:"); - switch(entry->body.zebra_state_change.address_family) - { -#ifdef BGPDUMP_HAVE_IPV6 - case AFI_IP6: + case 2: + printf + (" SUB ERROR : 2 (Unrecognized Well-known Attribute)\n"); + break; - inet_ntop(AF_INET6,&entry->body.zebra_state_change.source_ip.v6_addr,prefix,sizeof(prefix)); - printf(" %s ",prefix); - break; -#endif - case AFI_IP: - default: - if (entry->body.zebra_state_change.source_ip.v4_addr.s_addr != 0x00000000L) - printf(" %s ",inet_ntoa(entry->body.zebra_message.source_ip.v4_addr)); - else - printf(" N/A "); - } - //if (entry->body.zebra_message.source_ip.s_addr != 0x00000000L) - // printf(" %s ",inet_ntoa(entry->body.zebra_message.source_ip)); - //else - // printf(" N/A "); - printf("AS%d\n",entry->body.zebra_state_change.source_as); + case 3: + printf + (" SUB ERROR : 3 (Missing Well-known Attribute)\n"); + break; - printf("STATE: %s/%s\n",bgp_state_name[entry->body.zebra_state_change.old_state],bgp_state_name[entry->body.zebra_state_change.new_state]); - } - else if (mode==1 || mode==2 ) //-m -M - { - switch(entry->body.zebra_state_change.address_family) - { -#ifdef BGPDUMP_HAVE_IPV6 - case AFI_IP6: + case 4: + printf + (" SUB ERROR : 4 (Attribute Flags Error)\n"); + break; - inet_ntop(AF_INET6,&entry->body.zebra_state_change.source_ip.v6_addr,prefix,sizeof(prefix)); - if (mode == 1) - printf("BGP4MP|%ld|STATE|%s|%d|%d|%d\n",entry->time,prefix,entry->body.zebra_state_change.source_as,entry->body.zebra_state_change.old_state,entry->body.zebra_state_change.new_state); - else - printf("BGP4MP|%s|STATE|%s|%d|%d|%d\n",time_str,prefix,entry->body.zebra_state_change.source_as,entry->body.zebra_state_change.old_state,entry->body.zebra_state_change.new_state); - break; -#endif - case AFI_IP: - default: - if (mode == 1) - printf("BGP4MP|%ld|STATE|%s|%d|%d|%d\n",entry->time,inet_ntoa(entry->body.zebra_state_change.source_ip.v4_addr),entry->body.zebra_state_change.source_as,entry->body.zebra_state_change.old_state,entry->body.zebra_state_change.new_state); - else - printf("BGP4MP|%s|STATE|%s|%d|%d|%d\n",time_str,inet_ntoa(entry->body.zebra_state_change.source_ip.v4_addr),entry->body.zebra_state_change.source_as,entry->body.zebra_state_change.old_state,entry->body.zebra_state_change.new_state); - break; + case 5: + printf + (" SUB ERROR : 5 (Attribute Length Error)\n"); + break; - } - } - break; - - } - break; - } - if (mode==0) - printf("\n"); -} + case 6: + printf + (" SUB ERROR : 6 (Invalid ORIGIN Attribute)\n"); + break; -void show_attr(struct attr *attr) { - - if(attr != NULL) { + case 7: + printf(" SUB ERROR : 7 (AS Routing Loop)\n"); + break; - if( (attr->flag & ATTR_FLAG_BIT (BGP_ATTR_ORIGIN) ) !=0 ) - { - switch (attr->origin) - { - case 0: - printf("ORIGIN: IGP\n"); - break; - case 1: - printf("ORIGIN: EGP\n"); - break; - case 2: - printf("ORIGIN: INCOMPLETE\n"); - - } - - } + case 8: + printf + (" SUB ERROR : 8 (Invalid NEXT-HOP Attribute)\n"); + break; - if( (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AS_PATH) ) !=0) - printf("ASPATH: %s\n",attr->aspath->str); + case 9: + printf + (" SUB ERROR : 9 (Optional Attribute Error)\n"); + break; - if( (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP) ) !=0) - printf("NEXT_HOP: %s\n",inet_ntoa(attr->nexthop)); + case 10: + printf + (" SUB ERROR : 10 (Invalid Network Field)\n"); + break; - if( (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC) ) !=0) - printf("MULTI_EXIT_DISC: %d\n",attr->med); + case 11: + printf + (" SUB ERROR : 11 (Malformed AS-PATH)\n"); + break; - if( (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF) ) !=0) - printf("LOCAL_PREF: %d\n",attr->local_pref); + default: + printf(" SUB ERROR : %d\n", sub_error_code); + break; + } + break; + case 4: + printf(" ERROR CODE : 4 (Hold Timer Expired)\n"); + break; + case 5: + printf + (" ERROR CODE : 5 (Finite State Machine Error)\n"); + break; + case 6: + printf(" ERROR CODE : 6 (Cease)\n"); + break; + default: + printf(" ERROR CODE : %d\n", error_code); + break; - if( (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE) ) !=0) - printf("ATOMIC_AGGREGATE\n"); + } +} - if( (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR) ) !=0) - printf("AGGREGATOR: AS%d %s\n",attr->aggregator_as,inet_ntoa(attr->aggregator_addr)); +void +process(BGPDUMP_ENTRY * entry) +{ + struct tm *time; + char time_str[128]; + char time_str2[128]; + char prefix[BGPDUMP_ADDRSTRLEN]; + + time = gmtime(&entry->time); + time2str(time, time_str); + if (mode == 0) + printf("TIME: %s\n", time_str); + + // printf("TIME: %s",asctime(gmtime(&entry->time))); + // printf("LENGTH : %u\n", entry->length); + switch (entry->type) { + case BGPDUMP_TYPE_MRTD_TABLE_DUMP: + if (mode == 0) { +#ifdef BGPDUMP_HAVE_IPV6 + if (entry->subtype == AFI_IP6) + printf("TYPE: TABLE_DUMP/INET6\n"); + else +#endif + printf("TYPE: TABLE_DUMP/INET\n"); + printf("VIEW: %d\n", entry->body.mrtd_table_dump.view); + printf("SEQUENCE: %d\n", entry->body.mrtd_table_dump.sequence); +#ifdef BGPDUMP_HAVE_IPV6 + if (entry->subtype == AFI_IP6) + printf("PREFIX: %s/%d\n", + inet_ntop(AF_INET6, + &entry->body.mrtd_table_dump.prefix. + v6_addr, prefix, sizeof(prefix)), + entry->body.mrtd_table_dump.mask); + else +#endif + printf("PREFIX: %s/%d\n", + inet_ntoa(entry->body.mrtd_table_dump.prefix. + v4_addr), + entry->body.mrtd_table_dump.mask); + printf("FROM:"); + switch (entry->subtype) { +#ifdef BGPDUMP_HAVE_IPV6 + case AFI_IP6: + + inet_ntop(AF_INET6, + &entry->body.mrtd_table_dump.peer_ip.v6_addr, + prefix, sizeof(prefix)); + printf(" %s ", prefix); + break; +#endif + case AFI_IP: + default: + if (entry->body.mrtd_table_dump.peer_ip.v4_addr.s_addr != + 0x00000000L) + printf(" %s ", + inet_ntoa(entry->body.mrtd_table_dump.peer_ip. + v4_addr)); + else + printf(" N/A "); + } + printf("AS%d\n", entry->body.mrtd_table_dump.peer_as); - if (attr->unknown_num) + // printf("FROM: %s + // AS%d\n",inet_ntoa(entry->body.mrtd_table_dump.peer_ip.v4_addr),entry->body.mrtd_table_dump.peer_as); + // time2str(localtime(&entry->body.mrtd_table_dump.uptime),time_str2); + time2str(gmtime(&entry->body.mrtd_table_dump.uptime), + time_str2); + printf("ORIGINATED: %s\n", time_str2); + if (entry->attr && entry->attr->len) + show_attr(entry->attr); + + printf("STATUS: 0x%x\n", entry->body.mrtd_table_dump.status); + + // printf(" UPTIME : + // %s",asctime(gmtime(&entry->body.mrtd_table_dump.uptime))); + // printf(" PEER IP : + // %s\n",inet_ntoa(entry->body.mrtd_table_dump.peer_ip)); + // printf(" PEER IP : + // %s\n",inet_ntoa(entry->body.mrtd_table_dump.peer_ip.v4_addr)); + // printf(" PEER AS : + // %d\n",entry->body.mrtd_table_dump.peer_as); + } else if (mode == 1 || mode == 2) // -m -M + { + table_line_mrtd_route(mode, &entry->body.mrtd_table_dump, + entry, timetype); + } + break; + case BGPDUMP_TYPE_MRTD_BGP: + switch (entry->subtype) { + case BGPDUMP_SUBTYPE_MRTD_BGP_UPDATE: + if (mode == 0) { + printf("TYPE: BGP4MP/MESSAGE/Update\n"); + if (entry->body.mrtd_message.source_as) { + printf("FROM:"); + if (entry->body.mrtd_message.source_ip.s_addr != + 0x00000000L) + printf(" %s ", + inet_ntoa(entry->body.mrtd_message. + source_ip)); + else + printf(" N/A "); + printf("AS%d\n", entry->body.mrtd_message.source_as); + } + if (entry->body.mrtd_message.destination_as) { + printf("TO:"); + if (entry->body.mrtd_message.destination_ip.s_addr != + 0x00000000L) + printf(" %s ", + inet_ntoa(entry->body.mrtd_message. + destination_ip)); + else + printf(" N/A "); + printf("AS%d\n", + entry->body.mrtd_message.destination_as); + } + if (entry->attr && entry->attr->len) + show_attr(entry->attr); + if (entry->body.mrtd_message.withdraw_count) { + printf("WITHDRAW\n"); + show_prefixes(entry->body.mrtd_message.withdraw_count, + entry->body.mrtd_message.withdraw); + } + if (entry->body.mrtd_message.announce_count) { + printf("ANNOUNCE\n"); + show_prefixes(entry->body.mrtd_message.announce_count, + entry->body.mrtd_message.announce); + } + } else if (mode == 1 || mode == 2) // -m -M { - u_int32_t index,len; - u_char *p; - - for (index=0;indexunknown_num;index++) - { - printf(" UNKNOWN_ATTR :"); - p = attr->unknown[index].raw; - if(p[0] & BGP_ATTR_FLAG_EXTLEN) { - len = attr->unknown[index].real_len + 4; - } else { - len = attr->unknown[index].real_len + 3; - } - - while (len) { - printf(" %02x", *p); - p++; - len--; - } - printf("\n"); - } + if (entry->body.mrtd_message.withdraw_count) + table_line_withdraw(mode, + entry->body.mrtd_message.withdraw, + entry->body.mrtd_message. + withdraw_count, entry, time_str); + if (entry->body.mrtd_message.announce_count) + table_line_announce(mode, + entry->body.mrtd_message.announce, + entry->body.mrtd_message. + announce_count, entry, time_str); + } + break; + case BGPDUMP_SUBTYPE_MRTD_BGP_NOTIFY: + if (mode != 0) + break; + printf("TYPE: BGP4MP/MESSAGE/Notify\n"); + if (entry->body.mrtd_message.source_as) { + printf("FROM:"); + if (entry->body.mrtd_message.source_ip.s_addr != 0x00000000L) + printf(" %s ",inet_ntoa(entry->body.mrtd_message.source_ip)); + else + printf(" N/A "); + printf("AS%d\n", entry->body.mrtd_message.source_as); + } + if (entry->body.mrtd_message.destination_as) { + printf("TO:"); + if (entry->body.mrtd_message.destination_ip.s_addr != 0x00000000L) + printf(" %s ",inet_ntoa(entry->body.mrtd_message.destination_ip)); + else + printf(" N/A "); + printf("AS%d\n", entry->body.mrtd_message.destination_as); + } + print_notify_message(entry->body.mrtd_message.error_code, entry->body.mrtd_message.sub_error_code); + break; + case BGPDUMP_SUBTYPE_MRTD_BGP_OPEN: + if (mode != 0) + break; + printf("TYPE: BGP4MP/MESSAGE/Open\n"); + if (entry->body.mrtd_message.source_as) { + printf("FROM:"); + if (entry->body.mrtd_message.source_ip.s_addr != 0x00000000L) + printf(" %s ",inet_ntoa(entry->body.mrtd_message.source_ip)); + else + printf(" N/A "); + printf("AS%d\n", entry->body.mrtd_message.source_as); + } + if (entry->body.mrtd_message.destination_as) { + printf("TO:"); + if (entry->body.mrtd_message.destination_ip.s_addr != 0x00000000L) + printf(" %s ",inet_ntoa(entry->body.mrtd_message.destination_ip)); + else + printf(" N/A "); + printf("AS%d\n", entry->body.mrtd_message.destination_as); + } + printf("VERSION: %d\n", entry->body.mrtd_message.version); + printf("AS: %d\n", entry->body.mrtd_message.my_as); + printf("HOLD_TIME: %d\n", + entry->body.mrtd_message.hold_time); + printf("ID: %s\n", + inet_ntoa(entry->body.mrtd_message.bgp_id)); + printf("OPT_PARM_LEN: %d\n", + entry->body.mrtd_message.opt_len); + break; + case BGPDUMP_SUBTYPE_MRTD_BGP_KEEPALIVE: + if (mode != 0) + break; + printf("TYPE: BGP4MP/MESSAGE/Keepalive\n"); + if (entry->body.mrtd_message.source_as) { + printf("FROM:"); + if (entry->body.mrtd_message.source_ip.s_addr != 0x00000000L) + printf(" %s ",inet_ntoa(entry->body.mrtd_message.source_ip)); + else + printf(" N/A "); + printf("AS%d\n", entry->body.mrtd_message.source_as); + } + if (entry->body.mrtd_message.destination_as) { + printf("TO:"); + if (entry->body.mrtd_message.destination_ip.s_addr != 0x00000000L) + printf(" %s ",inet_ntoa(entry->body.mrtd_message.destination_ip)); + else + printf(" N/A "); + printf("AS%d\n", entry->body.mrtd_message.destination_as); } - if( (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI) )!=0) + break; + case BGPDUMP_SUBTYPE_MRTD_BGP_STATE_CHANGE: + if (mode == 0) { + printf("TYPE: BGP4MP/STATE_CHANGE\n"); + printf("PEER:"); + if (entry->body.mrtd_message.source_ip.s_addr != 0x00000000L) + printf(" %s ",inet_ntoa(entry->body.mrtd_message.source_ip)); + else + printf(" N/A "); + printf("AS%d\n", entry->body.mrtd_state_change.source_as); + printf("STATE: %s/%s\n", + bgp_state_name[entry->body.mrtd_state_change. + old_state], + bgp_state_name[entry->body.mrtd_state_change. + new_state]); + } else if (mode == 1 || mode == 2) // -m -M { - printf("MP_REACH_NLRI"); + if (mode == 1) + printf("BGP4MP|%ld|STATE|%s|%d|%d|%d\n", + entry->time, + inet_ntoa(entry->body.mrtd_state_change. + source_ip), + entry->body.mrtd_state_change.source_as, + entry->body.mrtd_state_change.old_state, + entry->body.mrtd_state_change.new_state); + else + printf("BGP4MP|%s|STATE|%s|%d|%d|%d\n", time_str, + inet_ntoa(entry->body.mrtd_state_change. + source_ip), + entry->body.mrtd_state_change.source_as, + entry->body.mrtd_state_change.old_state, + entry->body.mrtd_state_change.new_state); + } + break; + } + break; + case BGPDUMP_TYPE_ZEBRA_BGP: + switch (entry->subtype) { + case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE: + switch (entry->body.zebra_message.type) { + case BGP_MSG_UPDATE: + if (mode == 0) { + printf("TYPE: BGP4MP/MESSAGE/Update\n"); + if (entry->body.zebra_message.source_as) { + printf("FROM:"); + switch (entry->body.zebra_message.address_family) { #ifdef BGPDUMP_HAVE_IPV6 - if (attr->mp_info->announce[AFI_IP6][SAFI_UNICAST] || attr->mp_info->announce[AFI_IP6][SAFI_MULTICAST] || attr->mp_info->announce[AFI_IP6][SAFI_UNICAST_MULTICAST]) - - { - char buf[128]; - - if (attr->mp_info->announce[AFI_IP6][SAFI_UNICAST]) - { - printf("(IPv6 Unicast)\n"); - printf("NEXT_HOP: %s\n",inet_ntop(AF_INET6,&attr->mp_info->announce[AFI_IP6][SAFI_UNICAST]->nexthop.v6_addr,buf,128)); - if (attr->mp_info->announce[AFI_IP6][SAFI_UNICAST]->nexthop_len==32) - printf("NEXT_HOP: %s\n",inet_ntop(AF_INET6,&attr->mp_info->announce[AFI_IP6][SAFI_UNICAST]->nexthop_local.v6_addr,buf,128)); - } - else if (attr->mp_info->announce[AFI_IP6][SAFI_MULTICAST]) - { - printf("(IPv6 Multicast)\n"); - printf("NEXT_HOP: %s\n",inet_ntop(AF_INET6,&attr->mp_info->announce[AFI_IP6][SAFI_MULTICAST]->nexthop.v6_addr,buf,128)); - if (attr->mp_info->announce[AFI_IP6][SAFI_MULTICAST]->nexthop_len==32) - printf("NEXT_HOP: %s\n",inet_ntop(AF_INET6,&attr->mp_info->announce[AFI_IP6][SAFI_MULTICAST]->nexthop_local.v6_addr,buf,128)); - - } - else - { - printf("(IPv6 Both unicast and multicast)\n"); - printf("NEXT_HOP: %s\n",inet_ntop(AF_INET6,&attr->mp_info->announce[AFI_IP6][SAFI_UNICAST_MULTICAST]->nexthop.v6_addr,buf,128)); - if (attr->mp_info->announce[AFI_IP6][SAFI_UNICAST_MULTICAST]->nexthop_len==32) - printf("NEXT_HOP: %s\n",inet_ntop(AF_INET6,&attr->mp_info->announce[AFI_IP6][SAFI_UNICAST_MULTICAST]->nexthop_local.v6_addr,buf,128)); + case AFI_IP6: + inet_ntop(AF_INET6, + &entry->body.zebra_message.source_ip. + v6_addr, prefix, sizeof(prefix)); + printf(" %s ", prefix); + break; +#endif + case AFI_IP: + default: + if (entry->body.zebra_message.source_ip. + v4_addr.s_addr != 0x00000000L) + printf(" %s ", + inet_ntoa(entry->body.zebra_message. + source_ip.v4_addr)); + else + printf(" N/A "); + } + printf("AS%d\n", + entry->body.zebra_message.source_as); + } + if (entry->body.zebra_message.destination_as) { + printf("TO:"); + switch (entry->body.zebra_message.address_family) { +#ifdef BGPDUMP_HAVE_IPV6 + case AFI_IP6: - } + inet_ntop(AF_INET6, + &entry->body.zebra_message. + destination_ip.v6_addr, prefix, + sizeof(prefix)); + printf(" %s ", prefix); + break; +#endif + case AFI_IP: + default: + if (entry->body.zebra_message.destination_ip. + v4_addr.s_addr != 0x00000000L) + printf(" %s ", + inet_ntoa(entry->body.zebra_message. + destination_ip.v4_addr)); + else + printf(" N/A "); + } + printf("AS%d\n", + entry->body.zebra_message.destination_as); } - else + if (entry->attr && entry->attr->len) + show_attr(entry->attr); + if (entry->body.zebra_message.cut_bytes) { + u_int16_t cutted, + index; + u_int8_t buf[128]; + + printf(" INCOMPLETE PACKET: %d bytes cutted\n", + entry->body.zebra_message.cut_bytes); + printf(" INCOMPLETE PART: "); + if (entry->body.zebra_message.incomplete.orig_len) { + cutted = + entry->body.zebra_message.incomplete. + prefix.len / 8 + 1; + buf[0] = + entry->body.zebra_message.incomplete. + orig_len; + memcpy(buf + 1, + &entry->body.zebra_message.incomplete. + prefix.address, cutted - 1); + + for (index = 0; index < cutted; index++) { + if (buf[index] < 0x10) + printf("0%x ", buf[index]); + else + printf("%x ", buf[index]); + } + } + printf("\n"); + } + if ((entry->body.zebra_message.withdraw_count) + || (entry->attr-> + flag & + ATTR_FLAG_BIT(BGP_ATTR_MP_UNREACH_NLRI))) { +#ifdef BGPDUMP_HAVE_IPV6 + if ((entry->body.zebra_message.withdraw_count) + || (entry->attr->mp_info-> + withdraw[AFI_IP][SAFI_UNICAST] + && entry->attr->mp_info-> + withdraw[AFI_IP][SAFI_UNICAST]-> + prefix_count) + || (entry->attr->mp_info-> + withdraw[AFI_IP][SAFI_MULTICAST] + && entry->attr->mp_info-> + withdraw[AFI_IP][SAFI_MULTICAST]-> + prefix_count) + || (entry->attr->mp_info-> + withdraw[AFI_IP][SAFI_UNICAST_MULTICAST] + && entry->attr->mp_info-> + withdraw[AFI_IP][SAFI_UNICAST_MULTICAST]-> + prefix_count) + || (entry->attr->mp_info-> + withdraw[AFI_IP6][SAFI_UNICAST] + && entry->attr->mp_info-> + withdraw[AFI_IP6][SAFI_UNICAST]-> + prefix_count) + || (entry->attr->mp_info-> + withdraw[AFI_IP6][SAFI_MULTICAST] + && entry->attr->mp_info-> + withdraw[AFI_IP6][SAFI_MULTICAST]-> + prefix_count) + || (entry->attr->mp_info-> + withdraw[AFI_IP6][SAFI_UNICAST_MULTICAST] + && entry->attr->mp_info-> + withdraw[AFI_IP6][SAFI_UNICAST_MULTICAST]-> + prefix_count)) +#else + if ((entry->body.zebra_message.withdraw_count) + || (entry->attr->mp_info-> + withdraw[AFI_IP][SAFI_UNICAST] + && entry->attr->mp_info-> + withdraw[AFI_IP][SAFI_UNICAST]-> + prefix_count) + || (entry->attr->mp_info-> + withdraw[AFI_IP][SAFI_MULTICAST] + && entry->attr->mp_info-> + withdraw[AFI_IP][SAFI_MULTICAST]-> + prefix_count) + || (entry->attr->mp_info-> + withdraw[AFI_IP][SAFI_UNICAST_MULTICAST] + && entry->attr->mp_info-> + withdraw[AFI_IP][SAFI_UNICAST_MULTICAST]-> + prefix_count)) +#endif + printf("WITHDRAW\n"); + if (entry->body.zebra_message.withdraw_count) + show_prefixes(entry->body.zebra_message. + withdraw_count, + entry->body.zebra_message. + withdraw); + if (entry->attr->mp_info) { + if (entry->attr->mp_info-> + withdraw[AFI_IP][SAFI_UNICAST] + && entry->attr->mp_info-> + withdraw[AFI_IP][SAFI_UNICAST]-> + prefix_count) + show_prefixes(entry->attr->mp_info-> + withdraw[AFI_IP] + [SAFI_UNICAST]->prefix_count, + entry->attr->mp_info-> + withdraw[AFI_IP] + [SAFI_UNICAST]->nlri); + + if (entry->attr->mp_info-> + withdraw[AFI_IP][SAFI_MULTICAST] + && entry->attr->mp_info-> + withdraw[AFI_IP][SAFI_MULTICAST]-> + prefix_count) + show_prefixes(entry->attr->mp_info-> + withdraw[AFI_IP] + [SAFI_MULTICAST]-> + prefix_count, + entry->attr->mp_info-> + withdraw[AFI_IP] + [SAFI_MULTICAST]->nlri); + + if (entry->attr->mp_info-> + withdraw[AFI_IP][SAFI_UNICAST_MULTICAST] + && entry->attr->mp_info-> + withdraw[AFI_IP][SAFI_UNICAST_MULTICAST]-> + prefix_count) + show_prefixes(entry->attr->mp_info-> + withdraw[AFI_IP] + [SAFI_UNICAST_MULTICAST]-> + prefix_count, + entry->attr->mp_info-> + withdraw[AFI_IP] + [SAFI_UNICAST_MULTICAST]-> + nlri); + +#ifdef BGPDUMP_HAVE_IPV6 + if (entry->attr->mp_info-> + withdraw[AFI_IP6][SAFI_UNICAST] + && entry->attr->mp_info-> + withdraw[AFI_IP6][SAFI_UNICAST]-> + prefix_count) + show_prefixes6(entry->attr->mp_info-> + withdraw[AFI_IP6] + [SAFI_UNICAST]-> + prefix_count, + entry->attr->mp_info-> + withdraw[AFI_IP6] + [SAFI_UNICAST]->nlri); + + if (entry->attr->mp_info-> + withdraw[AFI_IP6][SAFI_MULTICAST] + && entry->attr->mp_info-> + withdraw[AFI_IP6][SAFI_MULTICAST]-> + prefix_count) + show_prefixes6(entry->attr->mp_info-> + withdraw[AFI_IP6] + [SAFI_MULTICAST]-> + prefix_count, + entry->attr->mp_info-> + withdraw[AFI_IP6] + [SAFI_MULTICAST]->nlri); + + if (entry->attr->mp_info-> + withdraw[AFI_IP6][SAFI_UNICAST_MULTICAST] + && entry->attr->mp_info-> + withdraw[AFI_IP6][SAFI_UNICAST_MULTICAST]-> + prefix_count) + show_prefixes6(entry->attr->mp_info-> + withdraw[AFI_IP6] + [SAFI_UNICAST_MULTICAST]-> + prefix_count, + entry->attr->mp_info-> + withdraw[AFI_IP6] + [SAFI_UNICAST_MULTICAST]-> + nlri); #endif + } + } + if ((entry->body.zebra_message.announce_count) + || (entry->attr-> + flag & ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI))) { - - if (attr->mp_info->announce[AFI_IP][SAFI_UNICAST]) - { - printf("(IPv4 Unicast)\n"); - printf("NEXT_HOP: %s\n",inet_ntoa(attr->mp_info->announce[AFI_IP][SAFI_UNICAST]->nexthop.v4_addr)); - if (attr->mp_info->announce[AFI_IP][SAFI_UNICAST]->nexthop_len==32) - printf("NEXT_HOP: %s\n",inet_ntoa(attr->mp_info->announce[AFI_IP][SAFI_UNICAST]->nexthop_local.v4_addr)); - - } - else if (attr->mp_info->announce[AFI_IP][SAFI_MULTICAST]) - { - printf("(IPv4 Multicast)\n"); - printf("NEXT_HOP: %s\n",inet_ntoa(attr->mp_info->announce[AFI_IP][SAFI_MULTICAST]->nexthop.v4_addr)); - if (attr->mp_info->announce[AFI_IP][SAFI_MULTICAST]->nexthop_len==32) - printf("NEXT_HOP: %s\n",inet_ntoa(attr->mp_info->announce[AFI_IP][SAFI_MULTICAST]->nexthop_local.v4_addr)); - - - } - else if (attr->mp_info->announce[AFI_IP][SAFI_UNICAST_MULTICAST]) - { - printf("(IPv4 Both unicast and multicast)\n"); - printf("NEXT_HOP: %s\n",inet_ntoa(attr->mp_info->announce[AFI_IP][SAFI_UNICAST_MULTICAST]->nexthop.v4_addr)); - if (attr->mp_info->announce[AFI_IP][SAFI_UNICAST_MULTICAST]->nexthop_len==32) - printf("NEXT_HOP: %s\n",inet_ntoa(attr->mp_info->announce[AFI_IP][SAFI_UNICAST_MULTICAST]->nexthop_local.v4_addr)); - - - } - + printf("ANNOUNCE\n"); + if (entry->body.zebra_message.announce_count) + show_prefixes(entry->body.zebra_message. + announce_count, + entry->body.zebra_message. + announce); + if (entry->attr->mp_info) { + if (entry->attr->mp_info-> + announce[AFI_IP][SAFI_UNICAST] + && entry->attr->mp_info-> + announce[AFI_IP][SAFI_UNICAST]-> + prefix_count) + show_prefixes(entry->attr->mp_info-> + announce[AFI_IP] + [SAFI_UNICAST]->prefix_count, + entry->attr->mp_info-> + announce[AFI_IP] + [SAFI_UNICAST]->nlri); + + if (entry->attr->mp_info-> + announce[AFI_IP][SAFI_MULTICAST] + && entry->attr->mp_info-> + announce[AFI_IP][SAFI_MULTICAST]-> + prefix_count) + show_prefixes(entry->attr->mp_info-> + announce[AFI_IP] + [SAFI_MULTICAST]-> + prefix_count, + entry->attr->mp_info-> + announce[AFI_IP] + [SAFI_MULTICAST]->nlri); + + if (entry->attr->mp_info-> + announce[AFI_IP][SAFI_UNICAST_MULTICAST] + && entry->attr->mp_info-> + announce[AFI_IP][SAFI_UNICAST_MULTICAST]-> + prefix_count) + show_prefixes(entry->attr->mp_info-> + announce[AFI_IP] + [SAFI_UNICAST_MULTICAST]-> + prefix_count, + entry->attr->mp_info-> + announce[AFI_IP] + [SAFI_UNICAST_MULTICAST]-> + nlri); + +#ifdef BGPDUMP_HAVE_IPV6 + if (entry->attr->mp_info-> + announce[AFI_IP6][SAFI_UNICAST] + && entry->attr->mp_info-> + announce[AFI_IP6][SAFI_UNICAST]-> + prefix_count) + show_prefixes6(entry->attr->mp_info-> + announce[AFI_IP6] + [SAFI_UNICAST]-> + prefix_count, + entry->attr->mp_info-> + announce[AFI_IP6] + [SAFI_UNICAST]->nlri); + + if (entry->attr->mp_info-> + announce[AFI_IP6][SAFI_MULTICAST] + && entry->attr->mp_info-> + announce[AFI_IP6][SAFI_MULTICAST]-> + prefix_count) + show_prefixes6(entry->attr->mp_info-> + announce[AFI_IP6] + [SAFI_MULTICAST]-> + prefix_count, + entry->attr->mp_info-> + announce[AFI_IP6] + [SAFI_MULTICAST]->nlri); + + if (entry->attr->mp_info-> + announce[AFI_IP6][SAFI_UNICAST_MULTICAST] + && entry->attr->mp_info-> + announce[AFI_IP6][SAFI_UNICAST_MULTICAST]-> + prefix_count) + show_prefixes6(entry->attr->mp_info-> + announce[AFI_IP6] + [SAFI_UNICAST_MULTICAST]-> + prefix_count, + entry->attr->mp_info-> + announce[AFI_IP6] + [SAFI_UNICAST_MULTICAST]-> + nlri); +#endif + } } - } - - if( (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MP_UNREACH_NLRI) )!=0) - { - printf("MP_UNREACH_NLRI"); -#ifdef BGPDUMP_HAVE_IPV6 - if (attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST] || attr->mp_info->withdraw[AFI_IP6][SAFI_MULTICAST] || attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST_MULTICAST]) + } else if (mode == 1 || mode == 2) // -m -M + { + if ((entry->body.zebra_message.withdraw_count) + || (entry->attr-> + flag & + ATTR_FLAG_BIT(BGP_ATTR_MP_UNREACH_NLRI))) { + table_line_withdraw(mode, + entry->body.zebra_message. + withdraw, + entry->body.zebra_message. + withdraw_count, entry, + time_str); + if (entry->attr->mp_info) { + if (entry->attr->mp_info-> + withdraw[AFI_IP][SAFI_UNICAST] + && entry->attr->mp_info-> + withdraw[AFI_IP][SAFI_UNICAST]-> + prefix_count) + table_line_withdraw(mode, + entry->attr->mp_info-> + withdraw[AFI_IP] + [SAFI_UNICAST]->nlri, + entry->attr->mp_info-> + withdraw[AFI_IP] + [SAFI_UNICAST]-> + prefix_count, entry, + time_str); + if (entry->attr->mp_info-> + withdraw[AFI_IP][SAFI_MULTICAST] + && entry->attr->mp_info-> + withdraw[AFI_IP][SAFI_MULTICAST]-> + prefix_count) + table_line_withdraw(mode, + entry->attr->mp_info-> + withdraw[AFI_IP] + [SAFI_MULTICAST]->nlri, + entry->attr->mp_info-> + withdraw[AFI_IP] + [SAFI_MULTICAST]-> + prefix_count, entry, + time_str); + if (entry->attr->mp_info-> + withdraw[AFI_IP][SAFI_UNICAST_MULTICAST] + && entry->attr->mp_info-> + withdraw[AFI_IP][SAFI_UNICAST_MULTICAST]-> + prefix_count) + table_line_withdraw(mode, + entry->attr->mp_info-> + withdraw[AFI_IP] + [SAFI_UNICAST_MULTICAST]-> + nlri, + entry->attr->mp_info-> + withdraw[AFI_IP] + [SAFI_UNICAST_MULTICAST]-> + prefix_count, entry, + time_str); + +#ifdef BGPDUMP_HAVE_IPV6 + if (entry->attr->mp_info-> + withdraw[AFI_IP6][SAFI_UNICAST] + && entry->attr->mp_info-> + withdraw[AFI_IP6][SAFI_UNICAST]-> + prefix_count) + table_line_withdraw6(mode, + entry->attr->mp_info-> + withdraw[AFI_IP6] + [SAFI_UNICAST]->nlri, + entry->attr->mp_info-> + withdraw[AFI_IP6] + [SAFI_UNICAST]-> + prefix_count, entry, + time_str); + if (entry->attr->mp_info-> + withdraw[AFI_IP6][SAFI_MULTICAST] + && entry->attr->mp_info-> + withdraw[AFI_IP6][SAFI_MULTICAST]-> + prefix_count) + table_line_withdraw6(mode, + entry->attr->mp_info-> + withdraw[AFI_IP6] + [SAFI_MULTICAST]-> + nlri, + entry->attr->mp_info-> + withdraw[AFI_IP6] + [SAFI_MULTICAST]-> + prefix_count, entry, + time_str); + if (entry->attr->mp_info-> + withdraw[AFI_IP6][SAFI_UNICAST_MULTICAST] + && entry->attr->mp_info-> + withdraw[AFI_IP6][SAFI_UNICAST_MULTICAST]-> + prefix_count) + table_line_withdraw6(mode, + entry->attr->mp_info-> + withdraw[AFI_IP6] + [SAFI_UNICAST_MULTICAST]-> + nlri, + entry->attr->mp_info-> + withdraw[AFI_IP6] + [SAFI_UNICAST_MULTICAST]-> + prefix_count, entry, + time_str); +#endif - { - - if (attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST]) - { - printf("(IPv6 Unicast)\n"); - } - else if (attr->mp_info->withdraw[AFI_IP6][SAFI_MULTICAST]) - { - printf("(IPv6 Multicast)\n"); - - } - else - { - printf("(IPv6 Both unicast and multicast)\n"); + } - } } - else -#endif + if ((entry->body.zebra_message.announce_count) + || (entry->attr-> + flag & ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI))) { - - if (attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST]) - { - printf("(IPv4 Unicast)\n"); - - } - else if (attr->mp_info->withdraw[AFI_IP][SAFI_MULTICAST]) - { - printf("(IPv4 Multicast)\n"); - - - } - else if (attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST_MULTICAST]) - { - printf("(IPv4 Both unicast and multicast)\n"); - + table_line_announce(mode, + entry->body.zebra_message. + announce, + entry->body.zebra_message. + announce_count, entry, + time_str); + if (entry->attr->mp_info) { + if (entry->attr->mp_info-> + announce[AFI_IP][SAFI_UNICAST] + && entry->attr->mp_info-> + announce[AFI_IP][SAFI_UNICAST]-> + prefix_count) + table_line_announce_1(mode, + entry->attr-> + mp_info-> + announce[AFI_IP] + [SAFI_UNICAST], + entry->attr-> + mp_info-> + announce[AFI_IP] + [SAFI_UNICAST]-> + prefix_count, entry, + time_str); + if (entry->attr->mp_info-> + announce[AFI_IP][SAFI_MULTICAST] + && entry->attr->mp_info-> + announce[AFI_IP][SAFI_MULTICAST]-> + prefix_count) + table_line_announce_1(mode, + entry->attr-> + mp_info-> + announce[AFI_IP] + [SAFI_MULTICAST], + entry->attr-> + mp_info-> + announce[AFI_IP] + [SAFI_MULTICAST]-> + prefix_count, entry, + time_str); + if (entry->attr->mp_info-> + announce[AFI_IP][SAFI_UNICAST_MULTICAST] + && entry->attr->mp_info-> + announce[AFI_IP][SAFI_UNICAST_MULTICAST]-> + prefix_count) + table_line_announce_1(mode, + entry->attr-> + mp_info-> + announce[AFI_IP] + [SAFI_UNICAST_MULTICAST], + entry->attr-> + mp_info-> + announce[AFI_IP] + [SAFI_UNICAST_MULTICAST]-> + prefix_count, entry, + time_str); +#ifdef BGPDUMP_HAVE_IPV6 + if (entry->attr->mp_info-> + announce[AFI_IP6][SAFI_UNICAST] + && entry->attr->mp_info-> + announce[AFI_IP6][SAFI_UNICAST]-> + prefix_count) + table_line_announce6(mode, + entry->attr->mp_info-> + announce[AFI_IP6] + [SAFI_UNICAST], + entry->attr->mp_info-> + announce[AFI_IP6] + [SAFI_UNICAST]-> + prefix_count, entry, + time_str); + if (entry->attr->mp_info-> + announce[AFI_IP6][SAFI_MULTICAST] + && entry->attr->mp_info-> + announce[AFI_IP6][SAFI_MULTICAST]-> + prefix_count) + table_line_announce6(mode, + entry->attr->mp_info-> + announce[AFI_IP6] + [SAFI_MULTICAST], + entry->attr->mp_info-> + announce[AFI_IP6] + [SAFI_MULTICAST]-> + prefix_count, entry, + time_str); + if (entry->attr->mp_info-> + announce[AFI_IP6][SAFI_UNICAST_MULTICAST] + && entry->attr->mp_info-> + announce[AFI_IP6][SAFI_UNICAST_MULTICAST]-> + prefix_count) + table_line_announce6(mode, + entry->attr->mp_info-> + announce[AFI_IP6] + [SAFI_UNICAST_MULTICAST], + entry->attr->mp_info-> + announce[AFI_IP6] + [SAFI_UNICAST_MULTICAST]-> + prefix_count, entry, + time_str); +#endif + + } - } - } - } - if( (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES) ) !=0) - printf("COMMUNITY:%s\n",attr->community->str); - } - -} + } + break; -void show_prefixes(int count,struct prefix *prefix) { - int i; - for(i=0;ibody.zebra_message.source_as) { + printf("FROM:"); + switch (entry->body.zebra_message.address_family) { +#ifdef BGPDUMP_HAVE_IPV6 + case AFI_IP6: + + inet_ntop(AF_INET6, + &entry->body.zebra_message.source_ip. + v6_addr, prefix, sizeof(prefix)); + printf(" %s ", prefix); + break; +#endif + case AFI_IP: + default: + if (entry->body.zebra_message.source_ip.v4_addr. + s_addr != 0x00000000L) + printf(" %s ", + inet_ntoa(entry->body.zebra_message. + source_ip.v4_addr)); + else + printf(" N/A "); + } + printf("AS%d\n", entry->body.zebra_message.source_as); + } + if (entry->body.zebra_message.destination_as) { + printf("TO:"); + switch (entry->body.zebra_message.address_family) { +#ifdef BGPDUMP_HAVE_IPV6 + case AFI_IP6: + + inet_ntop(AF_INET6, + &entry->body.zebra_message. + destination_ip.v6_addr, prefix, + sizeof(prefix)); + printf(" %s ", prefix); + break; +#endif + case AFI_IP: + default: + if (entry->body.zebra_message.destination_ip. + v4_addr.s_addr != 0x00000000L) + printf(" %s ", + inet_ntoa(entry->body.zebra_message. + destination_ip.v4_addr)); + else + printf(" N/A "); + } + printf("AS%d\n", + entry->body.zebra_message.destination_as); + } - for (i=0;ibody.zebra_message.version); + printf("AS: %d\n", entry->body.zebra_message.my_as); + printf("HOLD_TIME: %d\n", + entry->body.zebra_message.hold_time); + printf("ID: %s\n", + inet_ntoa(entry->body.zebra_message.bgp_id)); + printf("OPT_PARM_LEN: %d\n", + entry->body.zebra_message.opt_len); + break; + + case BGP_MSG_NOTIFY: + if (mode != 0) + break; + printf("TYPE: BGP4MP/MESSAGE/Notify\n"); + if (entry->body.zebra_message.source_as) { + printf("FROM:"); + switch (entry->body.zebra_message.address_family) { +#ifdef BGPDUMP_HAVE_IPV6 + case AFI_IP6: + + inet_ntop(AF_INET6, + &entry->body.zebra_message.source_ip. + v6_addr, prefix, sizeof(prefix)); + printf(" %s ", prefix); + break; +#endif + case AFI_IP: + default: + if (entry->body.zebra_message.source_ip.v4_addr. + s_addr != 0x00000000L) + printf(" %s ", + inet_ntoa(entry->body.zebra_message. + source_ip.v4_addr)); + else + printf(" N/A "); + } + printf("AS%d\n", entry->body.zebra_message.source_as); + } + if (entry->body.zebra_message.destination_as) { + printf("TO:"); + switch (entry->body.zebra_message.address_family) { +#ifdef BGPDUMP_HAVE_IPV6 + case AFI_IP6: + + inet_ntop(AF_INET6, + &entry->body.zebra_message. + destination_ip.v6_addr, prefix, + sizeof(prefix)); + printf(" %s ", prefix); + break; #endif + case AFI_IP: + default: + if (entry->body.zebra_message.destination_ip. + v4_addr.s_addr != 0x00000000L) + printf(" %s ", + inet_ntoa(entry->body.zebra_message. + destination_ip.v4_addr)); + else + printf(" N/A "); + } + printf("AS%d\n", + entry->body.zebra_message.destination_as); + } + print_notify_message(entry->body.zebra_message.error_code, entry->body.zebra_message.sub_error_code); + break; + case BGP_MSG_KEEPALIVE: + if (mode != 0) + break; -void table_line_withdraw(int mode,struct prefix *prefix,int count,BGPDUMP_ENTRY *entry,char *time_str) -{ - int index; - char buf[128]; - - for (index=0;indexbody.zebra_message.address_family) - { -#ifdef BGPDUMP_HAVE_IPV6 - case AFI_IP6: - printf("BGP4MP|%ld|W|%s|%d|",entry->time,inet_ntop(AF_INET6,&entry->body.zebra_message.source_ip.v6_addr,buf,128),entry->body.zebra_message.source_as); - break; + printf("TYPE: BGP4MP/MESSAGE/Keepalive\n"); + if (entry->body.zebra_message.source_as) { + printf("FROM:"); + switch (entry->body.zebra_message.address_family) { +#ifdef BGPDUMP_HAVE_IPV6 + case AFI_IP6: + + inet_ntop(AF_INET6, + &entry->body.zebra_message.source_ip. + v6_addr, prefix, sizeof(prefix)); + printf(" %s ", prefix); + break; #endif - case AFI_IP: - default: - printf("BGP4MP|%ld|W|%s|%d|",entry->time,inet_ntoa(entry->body.zebra_message.source_ip.v4_addr),entry->body.zebra_message.source_as); - break; - } - printf("%s/%d\n",inet_ntoa(prefix[index].address.v4_addr),prefix[index].len); + case AFI_IP: + default: + if (entry->body.zebra_message.source_ip.v4_addr. + s_addr != 0x00000000L) + printf(" %s ", + inet_ntoa(entry->body.zebra_message. + source_ip.v4_addr)); + else + printf(" N/A "); + } + printf("AS%d\n", entry->body.zebra_message.source_as); } - else - { - switch(entry->body.zebra_message.address_family) - { -#ifdef BGPDUMP_HAVE_IPV6 - case AFI_IP6: - printf("BGP4MP|%s|W|%s|%d|",time_str,inet_ntop(AF_INET6,&entry->body.zebra_message.source_ip.v6_addr,buf,128),entry->body.zebra_message.source_as); - break; + if (entry->body.zebra_message.destination_as) { + printf("TO:"); + switch (entry->body.zebra_message.address_family) { +#ifdef BGPDUMP_HAVE_IPV6 + case AFI_IP6: + + inet_ntop(AF_INET6, + &entry->body.zebra_message. + destination_ip.v6_addr, prefix, + sizeof(prefix)); + printf(" %s ", prefix); + break; #endif - case AFI_IP: - default: - printf("BGP4MP|%s|W|%s|%d|",time_str,inet_ntoa(entry->body.zebra_message.source_ip.v4_addr),entry->body.zebra_message.source_as); - break; - } - printf("%s/%d\n",inet_ntoa(prefix[index].address.v4_addr),prefix[index].len); + case AFI_IP: + default: + if (entry->body.zebra_message.destination_ip. + v4_addr.s_addr != 0x00000000L) + printf(" %s ", + inet_ntoa(entry->body.zebra_message. + destination_ip.v4_addr)); + else + printf(" N/A "); + } + printf("AS%d\n", + entry->body.zebra_message.destination_as); } - - } -} + break; + } + break; + case BGPDUMP_SUBTYPE_ZEBRA_BGP_STATE_CHANGE: + if (mode == 0) { + printf("TYPE: BGP4MP/STATE_CHANGE\n"); + printf("PEER:"); + switch (entry->body.zebra_state_change.address_family) { #ifdef BGPDUMP_HAVE_IPV6 + case AFI_IP6: -void table_line_withdraw6(int mode,struct prefix *prefix,int count,BGPDUMP_ENTRY *entry,char *time_str) -{ - int index; - char buf[128]; - char buf1[128]; + inet_ntop(AF_INET6, + &entry->body.zebra_state_change.source_ip. + v6_addr, prefix, sizeof(prefix)); + printf(" %s ", prefix); + break; +#endif + case AFI_IP: + default: + if (entry->body.zebra_state_change.source_ip.v4_addr. + s_addr != 0x00000000L) + printf(" %s ", + inet_ntoa(entry->body.zebra_message. + source_ip.v4_addr)); + else + printf(" N/A "); + } + // if (entry->body.zebra_message.source_ip.s_addr != + // 0x00000000L) + // printf(" %s + // ",inet_ntoa(entry->body.zebra_message.source_ip)); + // else + // printf(" N/A "); + printf("AS%d\n", entry->body.zebra_state_change.source_as); + printf("STATE: %s/%s\n", + bgp_state_name[entry->body.zebra_state_change. + old_state], + bgp_state_name[entry->body.zebra_state_change. + new_state]); + } else if (mode == 1 || mode == 2) // -m -M + { + switch (entry->body.zebra_state_change.address_family) { +#ifdef BGPDUMP_HAVE_IPV6 + case AFI_IP6: + + inet_ntop(AF_INET6, + &entry->body.zebra_state_change.source_ip. + v6_addr, prefix, sizeof(prefix)); + if (mode == 1) + printf("BGP4MP|%ld|STATE|%s|%d|%d|%d\n", + entry->time, prefix, + entry->body.zebra_state_change.source_as, + entry->body.zebra_state_change.old_state, + entry->body.zebra_state_change.new_state); + else + printf("BGP4MP|%s|STATE|%s|%d|%d|%d\n", time_str, + prefix, + entry->body.zebra_state_change.source_as, + entry->body.zebra_state_change.old_state, + entry->body.zebra_state_change.new_state); + break; +#endif + case AFI_IP: + default: + if (mode == 1) + printf("BGP4MP|%ld|STATE|%s|%d|%d|%d\n", + entry->time, + inet_ntoa(entry->body.zebra_state_change. + source_ip.v4_addr), + entry->body.zebra_state_change.source_as, + entry->body.zebra_state_change.old_state, + entry->body.zebra_state_change.new_state); + else + printf("BGP4MP|%s|STATE|%s|%d|%d|%d\n", time_str, + inet_ntoa(entry->body.zebra_state_change. + source_ip.v4_addr), + entry->body.zebra_state_change.source_as, + entry->body.zebra_state_change.old_state, + entry->body.zebra_state_change.new_state); + break; - for (index=0;indexbody.zebra_message.address_family) - { - case AFI_IP6: - printf("BGP4MP|%ld|W|%s|%d|%s/%d\n",entry->time,inet_ntop(AF_INET6,&entry->body.zebra_message.source_ip,buf1,128),entry->body.zebra_message.source_as,inet_ntop(AF_INET6,&prefix[index].address.v6_addr,buf,128),prefix[index].len); - break; - case AFI_IP: - default: - printf("BGP4MP|%ld|W|%s|%d|%s/%d\n",entry->time,inet_ntop(AF_INET,&entry->body.zebra_message.source_ip,buf1,128),entry->body.zebra_message.source_as,inet_ntop(AF_INET6,&prefix[index].address.v6_addr,buf,128),prefix[index].len); - break; - } - } - else - { - switch(entry->body.zebra_message.address_family) - { - case AFI_IP6: - printf("BGP4MP|%s|W|%s|%d|%s/%d\n",time_str,inet_ntop(AF_INET6,&entry->body.zebra_message.source_ip,buf1,128),entry->body.zebra_message.source_as,inet_ntop(AF_INET6,&prefix[index].address.v6_addr,buf,128),prefix[index].len); - break; - case AFI_IP: - default: - printf("BGP4MP|%s|W|%s|%d|%s/%d\n",time_str,inet_ntop(AF_INET,&entry->body.zebra_message.source_ip,buf1,128),entry->body.zebra_message.source_as,inet_ntop(AF_INET6,&prefix[index].address.v6_addr,buf,128),prefix[index].len); - break; - } } + } + break; } + break; + } + if (mode == 0) + printf("\n"); } -#endif -void table_line_announce(int mode,struct prefix *prefix,int count,BGPDUMP_ENTRY *entry,char *time_str) +void +show_attr(struct attr *attr) { - int index ; - char buf[128]; - //char buf1[128]; - //char buf2[128]; - char tmp1[20]; - char tmp2[20]; - int npref; - int nmed; - - switch (entry->attr->origin) - { - case 0 : - sprintf(tmp1,"IGP"); - break; - case 1: - sprintf(tmp1,"EGP"); + if (attr != NULL) { + + if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ORIGIN)) != 0) { + switch (attr->origin) { + case 0: + printf("ORIGIN: IGP\n"); break; - case 2: - default: - sprintf(tmp1,"INCOMPLETE"); + case 1: + printf("ORIGIN: EGP\n"); break; + case 2: + printf("ORIGIN: INCOMPLETE\n"); + + } + } - if (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) - sprintf(tmp2,"AG"); - else - sprintf(tmp2,"NAG"); - for (index=0;indexbody.zebra_message.address_family) - { + if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AS_PATH)) != 0) + printf("ASPATH: %s\n", attr->aspath->str); + + if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) != 0) + printf("NEXT_HOP: %s\n", inet_ntoa(attr->nexthop)); + + if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) != 0) + printf("MULTI_EXIT_DISC: %d\n", attr->med); + + if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) != 0) + printf("LOCAL_PREF: %d\n", attr->local_pref); + + if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) != 0) + printf("ATOMIC_AGGREGATE\n"); + + if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_AGGREGATOR)) != 0) + printf("AGGREGATOR: AS%d %s\n", attr->aggregator_as, + inet_ntoa(attr->aggregator_addr)); + + if (attr->unknown_num) { + u_int32_t index, + len; + u_char *p; + + for (index = 0; index < attr->unknown_num; index++) { + printf(" UNKNOWN_ATTR :"); + p = attr->unknown[index].raw; + if (p[0] & BGP_ATTR_FLAG_EXTLEN) { + len = attr->unknown[index].real_len + 4; + } else { + len = attr->unknown[index].real_len + 3; + } + + while (len) { + printf(" %02x", *p); + p++; + len--; + } + printf("\n"); + } + } + if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI)) != 0) { + printf("MP_REACH_NLRI"); #ifdef BGPDUMP_HAVE_IPV6 - case AFI_IP6: - printf("BGP4MP|%ld|A|%s|%d|",entry->time,inet_ntop(AF_INET6,&entry->body.zebra_message.source_ip,buf,128),entry->body.zebra_message.source_as); - break; + if (attr->mp_info->announce[AFI_IP6][SAFI_UNICAST] + || attr->mp_info->announce[AFI_IP6][SAFI_MULTICAST] + || attr->mp_info-> + announce[AFI_IP6][SAFI_UNICAST_MULTICAST]) { + char buf[128]; + + if (attr->mp_info->announce[AFI_IP6][SAFI_UNICAST]) { + printf("(IPv6 Unicast)\n"); + printf("NEXT_HOP: %s\n", + inet_ntop(AF_INET6, + &attr->mp_info-> + announce[AFI_IP6][SAFI_UNICAST]-> + nexthop.v6_addr, buf, 128)); + if (attr->mp_info->announce[AFI_IP6][SAFI_UNICAST]-> + nexthop_len == 32) + printf("NEXT_HOP: %s\n", + inet_ntop(AF_INET6, + &attr->mp_info-> + announce[AFI_IP6][SAFI_UNICAST]-> + nexthop_local.v6_addr, buf, 128)); + } else if (attr->mp_info-> + announce[AFI_IP6][SAFI_MULTICAST]) { + printf("(IPv6 Multicast)\n"); + printf("NEXT_HOP: %s\n", + inet_ntop(AF_INET6, + &attr->mp_info-> + announce[AFI_IP6][SAFI_MULTICAST]-> + nexthop.v6_addr, buf, 128)); + if (attr->mp_info->announce[AFI_IP6][SAFI_MULTICAST]-> + nexthop_len == 32) + printf("NEXT_HOP: %s\n", + inet_ntop(AF_INET6, + &attr->mp_info->announce[AFI_IP6] + [SAFI_MULTICAST]->nexthop_local. + v6_addr, buf, 128)); + + } else { + printf("(IPv6 Both unicast and multicast)\n"); + printf("NEXT_HOP: %s\n", + inet_ntop(AF_INET6, + &attr->mp_info->announce[AFI_IP6] + [SAFI_UNICAST_MULTICAST]->nexthop. + v6_addr, buf, 128)); + if (attr->mp_info-> + announce[AFI_IP6][SAFI_UNICAST_MULTICAST]-> + nexthop_len == 32) + printf("NEXT_HOP: %s\n", + inet_ntop(AF_INET6, + &attr->mp_info->announce[AFI_IP6] + [SAFI_UNICAST_MULTICAST]-> + nexthop_local.v6_addr, buf, 128)); + + + } + } else #endif - case AFI_IP: - default: - printf("BGP4MP|%ld|A|%s|%d|",entry->time,inet_ntoa(entry->body.zebra_message.source_ip.v4_addr),entry->body.zebra_message.source_as); - break; - } - printf("%s/%d|%s|%s|",inet_ntoa(prefix[index].address.v4_addr),prefix[index].len,entry->attr->aspath->str,tmp1); - npref=entry->attr->local_pref; - if( (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF) ) ==0) - npref=0; - nmed=entry->attr->med; - if( (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC) ) ==0) - nmed=0; - - printf("%s|%d|%d|",inet_ntoa(entry->attr->nexthop),npref,nmed); - if( (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES) ) !=0) - printf("%s|%s|",entry->attr->community->str+1,tmp2); - else - printf("|%s|",tmp2); - - if (entry->attr->aggregator_addr.s_addr != -1) - printf("%s|\n",inet_ntoa(entry->attr->aggregator_addr)); - else - printf("|\n"); + { + + if (attr->mp_info->announce[AFI_IP][SAFI_UNICAST]) { + printf("(IPv4 Unicast)\n"); + printf("NEXT_HOP: %s\n", + inet_ntoa(attr->mp_info-> + announce[AFI_IP][SAFI_UNICAST]-> + nexthop.v4_addr)); + if (attr->mp_info->announce[AFI_IP][SAFI_UNICAST]-> + nexthop_len == 32) + printf("NEXT_HOP: %s\n", + inet_ntoa(attr->mp_info-> + announce[AFI_IP][SAFI_UNICAST]-> + nexthop_local.v4_addr)); + + } else if (attr->mp_info->announce[AFI_IP][SAFI_MULTICAST]) { + printf("(IPv4 Multicast)\n"); + printf("NEXT_HOP: %s\n", + inet_ntoa(attr->mp_info-> + announce[AFI_IP][SAFI_MULTICAST]-> + nexthop.v4_addr)); + if (attr->mp_info->announce[AFI_IP][SAFI_MULTICAST]-> + nexthop_len == 32) + printf("NEXT_HOP: %s\n", + inet_ntoa(attr->mp_info-> + announce[AFI_IP][SAFI_MULTICAST]-> + nexthop_local.v4_addr)); + + + } else if (attr->mp_info-> + announce[AFI_IP][SAFI_UNICAST_MULTICAST]) { + printf("(IPv4 Both unicast and multicast)\n"); + printf("NEXT_HOP: %s\n", + inet_ntoa(attr->mp_info->announce[AFI_IP] + [SAFI_UNICAST_MULTICAST]->nexthop. + v4_addr)); + if (attr->mp_info-> + announce[AFI_IP][SAFI_UNICAST_MULTICAST]-> + nexthop_len == 32) + printf("NEXT_HOP: %s\n", + inet_ntoa(attr->mp_info->announce[AFI_IP] + [SAFI_UNICAST_MULTICAST]-> + nexthop_local.v4_addr)); + + } - else - { - switch(entry->body.zebra_message.address_family) - { + + } + } + + if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MP_UNREACH_NLRI)) != 0) { + printf("MP_UNREACH_NLRI"); #ifdef BGPDUMP_HAVE_IPV6 - case AFI_IP6: - printf("BGP4MP|%s|A|%s|%d|",time_str,inet_ntop(AF_INET6,&entry->body.zebra_message.source_ip,buf,128),entry->body.zebra_message.source_as); - break; + if (attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST] + || attr->mp_info->withdraw[AFI_IP6][SAFI_MULTICAST] + || attr->mp_info-> + withdraw[AFI_IP6][SAFI_UNICAST_MULTICAST]) { + + if (attr->mp_info->withdraw[AFI_IP6][SAFI_UNICAST]) { + printf("(IPv6 Unicast)\n"); + } else if (attr->mp_info-> + withdraw[AFI_IP6][SAFI_MULTICAST]) { + printf("(IPv6 Multicast)\n"); + + } else { + printf("(IPv6 Both unicast and multicast)\n"); + + + } + } else #endif - case AFI_IP: - default: - printf("BGP4MP|%s|A|%s|%d|",time_str,inet_ntoa(entry->body.zebra_message.source_ip.v4_addr),entry->body.zebra_message.source_as); - break; - } - printf("%s/%d|%s|%s\n",inet_ntoa(prefix[index].address.v4_addr),prefix[index].len,entry->attr->aspath->str,tmp1); - + { + + if (attr->mp_info->withdraw[AFI_IP][SAFI_UNICAST]) { + printf("(IPv4 Unicast)\n"); + + } else if (attr->mp_info->withdraw[AFI_IP][SAFI_MULTICAST]) { + printf("(IPv4 Multicast)\n"); + + + } else if (attr->mp_info-> + withdraw[AFI_IP][SAFI_UNICAST_MULTICAST]) { + printf("(IPv4 Both unicast and multicast)\n"); + + } + + } } + if ((attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) != 0) + printf("COMMUNITY:%s\n", attr->community->str); + } } -void table_line_announce_1(int mode,struct mp_nlri *prefix,int count,BGPDUMP_ENTRY *entry,char *time_str) -{ - int index ; - char buf[128]; - //char buf1[128]; - //char buf2[128]; - char tmp1[20]; - char tmp2[20]; - int npref; - int nmed; - - switch (entry->attr->origin) - { - case 0 : - sprintf(tmp1,"IGP"); - break; - case 1: - sprintf(tmp1,"EGP"); - break; - case 2: - default: - sprintf(tmp1,"INCOMPLETE"); - break; - } - if (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) - sprintf(tmp2,"AG"); - else - sprintf(tmp2,"NAG"); +void +show_prefixes(int count, struct prefix *prefix) +{ + int i; + for (i = 0; i < count; i++) + printf(" %s/%d\n", inet_ntoa(prefix[i].address.v4_addr), + prefix[i].len); +} - for (index=0;indexattr->flag & ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI)) - { - switch(entry->body.zebra_message.address_family) - { -#ifdef BGPDUMP_HAVE_IPV6 - case AFI_IP6: - printf("BGP4MP|%ld|A|%s|%d|",entry->time,inet_ntop(AF_INET6,&entry->body.zebra_message.source_ip,buf,128),entry->body.zebra_message.source_as); - break; -#endif - case AFI_IP: - default: - printf("BGP4MP|%ld|A|%s|%d|",entry->time,inet_ntoa(entry->body.zebra_message.source_ip.v4_addr),entry->body.zebra_message.source_as); - break; - } - printf("%s/%d|%s|%s|",inet_ntoa(prefix->nlri[index].address.v4_addr),prefix->nlri[index].len,entry->attr->aspath->str,tmp1); - - npref=entry->attr->local_pref; - if( (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF) ) ==0) - npref=0; - nmed=entry->attr->med; - if( (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC) ) ==0) - nmed=0; - - printf("%s|%d|%d|",inet_ntoa(entry->attr->nexthop),npref,nmed); - //printf("%s|%d|%d|",inet_ntoa(prefix->nexthop.v4_addr),entry->attr->local_pref,entry->attr->med); - if( (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES) ) !=0) - printf("%s|%s|",entry->attr->community->str+1,tmp2); - else - printf("|%s|",tmp2); +#ifdef BGPDUMP_HAVE_IPV6 +void +show_prefixes6(int count, struct prefix *prefix) +{ + int i; + char buf[128]; - } - else - { - switch(entry->body.zebra_message.address_family) - { -#ifdef BGPDUMP_HAVE_IPV6 - case AFI_IP6: - printf("BGP4MP|%ld|A|%s|%d|",entry->time,inet_ntop(AF_INET6,&entry->body.zebra_message.source_ip,buf,128),entry->body.zebra_message.source_as); - break; -#endif - case AFI_IP: - default: - printf("BGP4MP|%ld|A|%s|%d|",entry->time,inet_ntoa(entry->body.zebra_message.source_ip.v4_addr),entry->body.zebra_message.source_as); - break; - } - printf("%s/%d|%s|%s|",inet_ntoa(prefix->nlri[index].address.v4_addr),prefix->nlri[index].len,entry->attr->aspath->str,tmp1); - - npref=entry->attr->local_pref; - if( (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF) ) ==0) - npref=0; - nmed=entry->attr->med; - if( (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC) ) ==0) - nmed=0; - - printf("%s|%d|%d|",inet_ntoa(entry->attr->nexthop),npref,nmed); - //printf("%s|%d|%d|",inet_ntoa(entry->attr->nexthop),entry->attr->local_pref,entry->attr->med); - if( (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES) ) !=0) - printf("%s|%s|",entry->attr->community->str+1,tmp2); - else - printf("|%s|",tmp2); + for (i = 0; i < count; i++) + printf(" %s/%d\n", + inet_ntop(AF_INET6, &prefix[i].address.v6_addr, buf, 128), + prefix[i].len); +} +#endif +void +table_line_withdraw(int mode, struct prefix *prefix, int count, + BGPDUMP_ENTRY * entry, char *time_str) +{ + int index; + char buf[128]; - } - if (entry->attr->aggregator_addr.s_addr != -1) - printf("%s|\n",inet_ntoa(entry->attr->aggregator_addr)); - else - printf("|\n"); + for (index = 0; index < count; index++) { + if (mode == 1) { + if (entry->type == BGPDUMP_TYPE_MRTD_BGP) { + printf("BGP4MP|%ld|W|%s|%d|", entry->time, + inet_ntoa(entry->body.mrtd_message.source_ip), + entry->body.mrtd_message.source_as); + } else { + switch (entry->body.zebra_message.address_family) { +#ifdef BGPDUMP_HAVE_IPV6 + case AFI_IP6: + printf("BGP4MP|%ld|W|%s|%d|", entry->time, + inet_ntop(AF_INET6, + &entry->body.zebra_message.source_ip. + v6_addr, buf, 128), + entry->body.zebra_message.source_as); + break; +#endif + case AFI_IP: + default: + printf("BGP4MP|%ld|W|%s|%d|", entry->time, + inet_ntoa(entry->body.zebra_message.source_ip. + v4_addr), + entry->body.zebra_message.source_as); + break; } - else - { - switch(entry->body.zebra_message.address_family) - { + } + printf("%s/%d\n", inet_ntoa(prefix[index].address.v4_addr), + prefix[index].len); + } else { + if (entry->type == BGPDUMP_TYPE_MRTD_BGP) { + printf("BGP4MP|%s|W|%s|%d|", time_str, + inet_ntoa(entry->body.mrtd_message.source_ip), + entry->body.mrtd_message.source_as); + } else { + switch (entry->body.zebra_message.address_family) { #ifdef BGPDUMP_HAVE_IPV6 - case AFI_IP6: - printf("BGP4MP|%s|A|%s|%d|",time_str,inet_ntop(AF_INET6,&entry->body.zebra_message.source_ip,buf,128),entry->body.zebra_message.source_as); - break; + case AFI_IP6: + printf("BGP4MP|%s|W|%s|%d|", time_str, + inet_ntop(AF_INET6, + &entry->body.zebra_message.source_ip. + v6_addr, buf, 128), + entry->body.zebra_message.source_as); + break; #endif - case AFI_IP: - default: - printf("BGP4MP|%s|A|%s|%d|",time_str,inet_ntoa(entry->body.zebra_message.source_ip.v4_addr),entry->body.zebra_message.source_as); - break; - } - printf("%s/%d|%s|%s\n",inet_ntoa(prefix->nlri[index].address.v4_addr),prefix->nlri[index].len,entry->attr->aspath->str,tmp1); - + case AFI_IP: + default: + printf("BGP4MP|%s|W|%s|%d|", time_str, + inet_ntoa(entry->body.zebra_message.source_ip. + v4_addr), + entry->body.zebra_message.source_as); + break; } + } + printf("%s/%d\n", inet_ntoa(prefix[index].address.v4_addr), + prefix[index].len); } + } } #ifdef BGPDUMP_HAVE_IPV6 -void table_line_announce6(int mode,struct mp_nlri *prefix,int count,BGPDUMP_ENTRY *entry,char *time_str) -{ - int index ; - char buf[128]; - char buf1[128]; - char buf2[128]; - char tmp1[20]; - char tmp2[20]; - int npref; - int nmed; - - switch (entry->attr->origin) - { - case 0 : - sprintf(tmp1,"IGP"); +void +table_line_withdraw6(int mode, struct prefix *prefix, int count, + BGPDUMP_ENTRY * entry, char *time_str) +{ + int index; + char buf[128]; + char buf1[128]; + + for (index = 0; index < count; index++) { + if (mode == 1) { + switch (entry->body.zebra_message.address_family) { + case AFI_IP6: + printf("BGP4MP|%ld|W|%s|%d|%s/%d\n", entry->time, + inet_ntop(AF_INET6, + &entry->body.zebra_message.source_ip, + buf1, 128), + entry->body.zebra_message.source_as, + inet_ntop(AF_INET6, &prefix[index].address.v6_addr, + buf, 128), prefix[index].len); break; - case 1: - sprintf(tmp1,"EGP"); + case AFI_IP: + default: + printf("BGP4MP|%ld|W|%s|%d|%s/%d\n", entry->time, + inet_ntop(AF_INET, + &entry->body.zebra_message.source_ip, + buf1, 128), + entry->body.zebra_message.source_as, + inet_ntop(AF_INET6, &prefix[index].address.v6_addr, + buf, 128), prefix[index].len); break; - case 2: - default: - sprintf(tmp1,"INCOMPLETE"); + } + } else { + switch (entry->body.zebra_message.address_family) { + case AFI_IP6: + printf("BGP4MP|%s|W|%s|%d|%s/%d\n", time_str, + inet_ntop(AF_INET6, + &entry->body.zebra_message.source_ip, + buf1, 128), + entry->body.zebra_message.source_as, + inet_ntop(AF_INET6, &prefix[index].address.v6_addr, + buf, 128), prefix[index].len); break; + case AFI_IP: + default: + printf("BGP4MP|%s|W|%s|%d|%s/%d\n", time_str, + inet_ntop(AF_INET, + &entry->body.zebra_message.source_ip, + buf1, 128), + entry->body.zebra_message.source_as, + inet_ntop(AF_INET6, &prefix[index].address.v6_addr, + buf, 128), prefix[index].len); + break; + } } - if (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) - sprintf(tmp2,"AG"); - else - sprintf(tmp2,"NAG"); - - for (index=0;indexbody.zebra_message.address_family) - { - case AFI_IP6: - - npref=entry->attr->local_pref; - if( (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF) ) ==0) - npref=0; - nmed=entry->attr->med; - if( (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC) ) ==0) - nmed=0; - - printf("BGP4MP|%ld|A|%s|%d|%s/%d|%s|%s|%s|%d|%d|",entry->time,inet_ntop(AF_INET6,&entry->body.zebra_message.source_ip,buf1,128),entry->body.zebra_message.source_as,inet_ntop(AF_INET6,&prefix->nlri[index].address.v6_addr,buf2,128),prefix->nlri[index].len,entry->attr->aspath->str,tmp1,inet_ntop(AF_INET6,&prefix->nexthop,buf,128),npref,nmed); - break; - case AFI_IP: - default: - npref=entry->attr->local_pref; - if( (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF) ) ==0) - npref=0; - nmed=entry->attr->med; - if( (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC) ) ==0) - nmed=0; - - //printf("%s|%d|%d|",inet_ntoa(entry->attr->nexthop),nprof,nmed); - printf("BGP4MP|%ld|A|%s|%d|%s/%d|%s|%s|%s|%d|%d|",entry->time,inet_ntop(AF_INET,&entry->body.zebra_message.source_ip,buf1,128),entry->body.zebra_message.source_as,inet_ntop(AF_INET6,&prefix->nlri[index].address.v6_addr,buf2,128),prefix->nlri[index].len,entry->attr->aspath->str,tmp1,inet_ntop(AF_INET6,&prefix->nexthop,buf,128),npref,nmed); - break; - } - if( (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES) ) !=0) - printf("%s|%s|",entry->attr->community->str+1,tmp2); - else - printf("|%s|",tmp2); + } +} +#endif +void +table_line_announce(int mode, struct prefix *prefix, int count, + BGPDUMP_ENTRY * entry, char *time_str) +{ + int index; + char buf[128]; + // char buf1[128]; + // char buf2[128]; + char tmp1[20]; + char tmp2[20]; + int npref; + int nmed; + + switch (entry->attr->origin) { + + case 0: + sprintf(tmp1, "IGP"); + break; + case 1: + sprintf(tmp1, "EGP"); + break; + case 2: + default: + sprintf(tmp1, "INCOMPLETE"); + break; + } + if (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) + sprintf(tmp2, "AG"); + else + sprintf(tmp2, "NAG"); + + for (index = 0; index < count; index++) { + if (mode == 1) { + if (entry->type == BGPDUMP_TYPE_MRTD_BGP) { + printf("BGP4MP|%ld|A|%s|%d|", entry->time, + inet_ntoa(entry->body.mrtd_message.source_ip), + entry->body.mrtd_message.source_as); + } else { + switch (entry->body.zebra_message.address_family) { +#ifdef BGPDUMP_HAVE_IPV6 + case AFI_IP6: + printf("BGP4MP|%ld|A|%s|%d|", entry->time, + inet_ntop(AF_INET6, + &entry->body.zebra_message.source_ip, + buf, 128), + entry->body.zebra_message.source_as); + break; +#endif + case AFI_IP: + default: + printf("BGP4MP|%ld|A|%s|%d|", entry->time, + inet_ntoa(entry->body.zebra_message.source_ip. + v4_addr), + entry->body.zebra_message.source_as); + break; + } + } + printf("%s/%d|%s|%s|", + inet_ntoa(prefix[index].address.v4_addr), + prefix[index].len, entry->attr->aspath->str, tmp1); + npref = entry->attr->local_pref; + if ((entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) == + 0) + npref = 0; + nmed = entry->attr->med; + if ((entry->attr-> + flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) == 0) + nmed = 0; + + printf("%s|%d|%d|", inet_ntoa(entry->attr->nexthop), npref, + nmed); + if ((entry->attr-> + flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) != 0) + printf("%s|%s|", entry->attr->community->str + 1, tmp2); + else + printf("|%s|", tmp2); + + if (entry->attr->aggregator_addr.s_addr != -1) + printf("%s|\n", inet_ntoa(entry->attr->aggregator_addr)); + else + printf("|\n"); + } else { + if (entry->type == BGPDUMP_TYPE_MRTD_BGP) { + printf("BGP4MP|%s|A|%s|%d|", time_str, + inet_ntoa(entry->body.mrtd_message.source_ip), + entry->body.mrtd_message.source_as); + } else { + switch (entry->body.zebra_message.address_family) { +#ifdef BGPDUMP_HAVE_IPV6 + case AFI_IP6: + printf("BGP4MP|%s|A|%s|%d|", time_str, + inet_ntop(AF_INET6, + &entry->body.zebra_message.source_ip, + buf, 128), + entry->body.zebra_message.source_as); + break; +#endif + case AFI_IP: + default: + printf("BGP4MP|%s|A|%s|%d|", time_str, + inet_ntoa(entry->body.zebra_message.source_ip. + v4_addr), + entry->body.zebra_message.source_as); + break; + } + } + printf("%s/%d|%s|%s\n", + inet_ntoa(prefix[index].address.v4_addr), + prefix[index].len, entry->attr->aspath->str, tmp1); + } + } +} - if (entry->attr->aggregator_addr.s_addr != -1) - printf("%s|\n",inet_ntoa(entry->attr->aggregator_addr)); - else - printf("|\n"); +void +table_line_announce_1(int mode, struct mp_nlri *prefix, int count, + BGPDUMP_ENTRY * entry, char *time_str) +{ + int index; + char buf[128]; + // char buf1[128]; + // char buf2[128]; + char tmp1[20]; + char tmp2[20]; + int npref; + int nmed; + + switch (entry->attr->origin) { + + case 0: + sprintf(tmp1, "IGP"); + break; + case 1: + sprintf(tmp1, "EGP"); + break; + case 2: + default: + sprintf(tmp1, "INCOMPLETE"); + break; + } + if (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) + sprintf(tmp2, "AG"); + else + sprintf(tmp2, "NAG"); + + for (index = 0; index < count; index++) { + if (mode == 1) { + if (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MP_REACH_NLRI)) { + switch (entry->body.zebra_message.address_family) { +#ifdef BGPDUMP_HAVE_IPV6 + case AFI_IP6: + printf("BGP4MP|%ld|A|%s|%d|", entry->time, + inet_ntop(AF_INET6, + &entry->body.zebra_message.source_ip, + buf, 128), + entry->body.zebra_message.source_as); + break; +#endif + case AFI_IP: + default: + printf("BGP4MP|%ld|A|%s|%d|", entry->time, + inet_ntoa(entry->body.zebra_message.source_ip. + v4_addr), + entry->body.zebra_message.source_as); + break; + } + printf("%s/%d|%s|%s|", + inet_ntoa(prefix->nlri[index].address.v4_addr), + prefix->nlri[index].len, entry->attr->aspath->str, + tmp1); + + npref = entry->attr->local_pref; + if ((entry->attr-> + flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) == 0) + npref = 0; + nmed = entry->attr->med; + if ((entry->attr-> + flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) == 0) + nmed = 0; + + printf("%s|%d|%d|", inet_ntoa(entry->attr->nexthop), npref, + nmed); + // printf("%s|%d|%d|",inet_ntoa(prefix->nexthop.v4_addr),entry->attr->local_pref,entry->attr->med); + if ((entry->attr-> + flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) != 0) + printf("%s|%s|", entry->attr->community->str + 1, + tmp2); + else + printf("|%s|", tmp2); + } else { + switch (entry->body.zebra_message.address_family) { +#ifdef BGPDUMP_HAVE_IPV6 + case AFI_IP6: + printf("BGP4MP|%ld|A|%s|%d|", entry->time, + inet_ntop(AF_INET6, + &entry->body.zebra_message.source_ip, + buf, 128), + entry->body.zebra_message.source_as); + break; +#endif + case AFI_IP: + default: + printf("BGP4MP|%ld|A|%s|%d|", entry->time, + inet_ntoa(entry->body.zebra_message.source_ip. + v4_addr), + entry->body.zebra_message.source_as); + break; } + printf("%s/%d|%s|%s|", + inet_ntoa(prefix->nlri[index].address.v4_addr), + prefix->nlri[index].len, entry->attr->aspath->str, + tmp1); + + npref = entry->attr->local_pref; + if ((entry->attr-> + flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) == 0) + npref = 0; + nmed = entry->attr->med; + if ((entry->attr-> + flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) == 0) + nmed = 0; + + printf("%s|%d|%d|", inet_ntoa(entry->attr->nexthop), npref, + nmed); + // printf("%s|%d|%d|",inet_ntoa(entry->attr->nexthop),entry->attr->local_pref,entry->attr->med); + if ((entry->attr-> + flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) != 0) + printf("%s|%s|", entry->attr->community->str + 1, + tmp2); else - { - switch(entry->body.zebra_message.address_family) - { - case AFI_IP6: - printf("BGP4MP|%s|A|%s|%d|%s/%d|%s|%s\n",time_str,inet_ntop(AF_INET6,&entry->body.zebra_message.source_ip,buf1,128),entry->body.zebra_message.source_as,inet_ntop(AF_INET6,&prefix->nlri[index].address.v6_addr,buf,128),prefix->nlri[index].len,entry->attr->aspath->str,tmp1); - break; - case AFI_IP: - default: - printf("BGP4MP|%s|A|%s|%d|%s/%d|%s|%s\n",time_str,inet_ntop(AF_INET,&entry->body.zebra_message.source_ip,buf1,128),entry->body.zebra_message.source_as,inet_ntop(AF_INET6,&prefix->nlri[index].address.v6_addr,buf,128),prefix->nlri[index].len,entry->attr->aspath->str,tmp1); - break; - } - } + printf("|%s|", tmp2); - } -} + } + if (entry->attr->aggregator_addr.s_addr != -1) + printf("%s|\n", inet_ntoa(entry->attr->aggregator_addr)); + else + printf("|\n"); + } else { + switch (entry->body.zebra_message.address_family) { +#ifdef BGPDUMP_HAVE_IPV6 + case AFI_IP6: + printf("BGP4MP|%s|A|%s|%d|", time_str, + inet_ntop(AF_INET6, + &entry->body.zebra_message.source_ip, buf, + 128), + entry->body.zebra_message.source_as); + break; #endif + case AFI_IP: + default: + printf("BGP4MP|%s|A|%s|%d|", time_str, + inet_ntoa(entry->body.zebra_message.source_ip. + v4_addr), + entry->body.zebra_message.source_as); + break; + } + printf("%s/%d|%s|%s\n", + inet_ntoa(prefix->nlri[index].address.v4_addr), + prefix->nlri[index].len, entry->attr->aspath->str, + tmp1); + } + } +} - -void table_line_mrtd_route(int mode,BGPDUMP_MRTD_TABLE_DUMP *route,BGPDUMP_ENTRY *entry,int timetype) +#ifdef BGPDUMP_HAVE_IPV6 +void +table_line_announce6(int mode, struct mp_nlri *prefix, int count, + BGPDUMP_ENTRY * entry, char *time_str) { - - struct tm *time; - char tmp1[20]; - char tmp2[20]; - int npref; - int nmed; - char time_str[10]; - char peer[BGPDUMP_ADDRSTRLEN]; - char prefix[BGPDUMP_ADDRSTRLEN + 4]; - char nexthop[BGPDUMP_ADDRSTRLEN]; - switch (entry->attr->origin) - { - - case 0 : - sprintf(tmp1,"IGP"); + int index; + char buf[128]; + char buf1[128]; + char buf2[128]; + char tmp1[20]; + char tmp2[20]; + int npref; + int nmed; + + switch (entry->attr->origin) { + + case 0: + sprintf(tmp1, "IGP"); + break; + case 1: + sprintf(tmp1, "EGP"); + break; + case 2: + default: + sprintf(tmp1, "INCOMPLETE"); + break; + } + if (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) + sprintf(tmp2, "AG"); + else + sprintf(tmp2, "NAG"); + + for (index = 0; index < count; index++) { + if (mode == 1) { + switch (entry->body.zebra_message.address_family) { + case AFI_IP6: + + npref = entry->attr->local_pref; + if ((entry->attr-> + flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) == 0) + npref = 0; + nmed = entry->attr->med; + if ((entry->attr-> + flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) == 0) + nmed = 0; + + printf("BGP4MP|%ld|A|%s|%d|%s/%d|%s|%s|%s|%d|%d|", + entry->time, inet_ntop(AF_INET6, + &entry->body.zebra_message. + source_ip, buf1, 128), + entry->body.zebra_message.source_as, + inet_ntop(AF_INET6, + &prefix->nlri[index].address.v6_addr, + buf2, 128), prefix->nlri[index].len, + entry->attr->aspath->str, tmp1, inet_ntop(AF_INET6, + &prefix-> + nexthop, + buf, 128), + npref, nmed); break; - case 1: - sprintf(tmp1,"EGP"); + case AFI_IP: + default: + npref = entry->attr->local_pref; + if ((entry->attr-> + flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) == 0) + npref = 0; + nmed = entry->attr->med; + if ((entry->attr-> + flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) == 0) + nmed = 0; + + // printf("%s|%d|%d|",inet_ntoa(entry->attr->nexthop),nprof,nmed); + printf("BGP4MP|%ld|A|%s|%d|%s/%d|%s|%s|%s|%d|%d|", + entry->time, inet_ntop(AF_INET, + &entry->body.zebra_message. + source_ip, buf1, 128), + entry->body.zebra_message.source_as, + inet_ntop(AF_INET6, + &prefix->nlri[index].address.v6_addr, + buf2, 128), prefix->nlri[index].len, + entry->attr->aspath->str, tmp1, inet_ntop(AF_INET6, + &prefix-> + nexthop, + buf, 128), + npref, nmed); break; - case 2: - default: - sprintf(tmp1,"INCOMPLETE"); + } + if ((entry->attr-> + flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) != 0) + printf("%s|%s|", entry->attr->community->str + 1, tmp2); + else + printf("|%s|", tmp2); + + + if (entry->attr->aggregator_addr.s_addr != -1) + printf("%s|\n", inet_ntoa(entry->attr->aggregator_addr)); + else + printf("|\n"); + + } else { + switch (entry->body.zebra_message.address_family) { + case AFI_IP6: + printf("BGP4MP|%s|A|%s|%d|%s/%d|%s|%s\n", time_str, + inet_ntop(AF_INET6, + &entry->body.zebra_message.source_ip, + buf1, 128), + entry->body.zebra_message.source_as, + inet_ntop(AF_INET6, + &prefix->nlri[index].address.v6_addr, buf, + 128), prefix->nlri[index].len, + entry->attr->aspath->str, tmp1); break; + case AFI_IP: + default: + printf("BGP4MP|%s|A|%s|%d|%s/%d|%s|%s\n", time_str, + inet_ntop(AF_INET, + &entry->body.zebra_message.source_ip, + buf1, 128), + entry->body.zebra_message.source_as, + inet_ntop(AF_INET6, + &prefix->nlri[index].address.v6_addr, buf, + 128), prefix->nlri[index].len, + entry->attr->aspath->str, tmp1); + break; + } } - if (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) - sprintf(tmp2,"AG"); - else - sprintf(tmp2,"NAG"); - - switch(entry->subtype){ -#ifdef BGPDUMP_HAVE_IPV6 - case AFI_IP6 : - inet_ntop(AF_INET6, &route->peer_ip.v6_addr, peer, sizeof(peer)); - inet_ntop(AF_INET6, &route->prefix.v6_addr, prefix, sizeof(prefix)); - inet_ntop(AF_INET6, &entry->attr->mp_info->announce[AFI_IP6][SAFI_UNICAST]->nexthop.v6_addr, - nexthop, sizeof(nexthop)); - break; + } +} #endif - case AFI_IP: - sprintf(peer, "%s", inet_ntoa(route->peer_ip.v4_addr)); - sprintf(prefix, "%s", inet_ntoa(route->prefix.v4_addr)); - sprintf(nexthop, "%s", inet_ntoa(entry->attr->nexthop)); - break; - default: - *peer = *prefix = *nexthop = '\0'; + +void +table_line_mrtd_route(int mode, BGPDUMP_MRTD_TABLE_DUMP * route, + BGPDUMP_ENTRY * entry, int timetype) +{ + struct tm *time; + char tmp1[20]; + char tmp2[20]; + int npref; + int nmed; + char time_str[10]; + switch (entry->attr->origin) { + + case 0: + sprintf(tmp1, "IGP"); + break; + case 1: + sprintf(tmp1, "EGP"); + break; + case 2: + default: + sprintf(tmp1, "INCOMPLETE"); + break; + } + if (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE)) + sprintf(tmp2, "AG"); + else + sprintf(tmp2, "NAG"); + + if (mode == 1) { + if (timetype == 0) { + printf("TABLE_DUMP|%ld|B|%s|%d|", entry->time, + inet_ntoa(route->peer_ip.v4_addr), route->peer_as); + } else if (timetype == 1) { + printf("TABLE_DUMP|%ld|B|%s|%d|", route->uptime, + inet_ntoa(route->peer_ip.v4_addr), route->peer_as); } - if (mode == 1) - { - if(timetype==0){ - printf("TABLE_DUMP|%ld|B|%s|%d|",entry->time,peer,route->peer_as); - }else if(timetype==1){ - printf("TABLE_DUMP|%ld|B|%s|%d|",route->uptime,peer,route->peer_as); - } - printf("%s/%d|%s|%s|",prefix,route->mask,entry->attr->aspath->str,tmp1); - - npref=entry->attr->local_pref; - if( (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF) ) ==0) - npref=0; - nmed=entry->attr->med; - if( (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC) ) ==0) - nmed=0; - - printf("%s|%d|%d|",nexthop,npref,nmed); - if( (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES) ) !=0) - printf("%s|%s|",entry->attr->community->str+1,tmp2); - else - printf("|%s|",tmp2); - - if (entry->attr->aggregator_addr.s_addr != -1) - printf("%s|\n",inet_ntoa(entry->attr->aggregator_addr)); - else - printf("|\n"); - } - else - { - if(timetype==0){ - time=gmtime(&entry->time); - }else if(timetype==1){ - time=gmtime(&route->uptime); - } - time2str(time,time_str); - printf("TABLE_DUMP|%s|A|%s|%d|",time_str,peer,route->peer_as); - printf("%s/%d|%s|%s\n",prefix,route->mask,entry->attr->aspath->str,tmp1); - - } + printf("%s/%d|%s|%s|", inet_ntoa(route->prefix.v4_addr), + route->mask, entry->attr->aspath->str, tmp1); + + npref = entry->attr->local_pref; + if ((entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LOCAL_PREF)) == 0) + npref = 0; + nmed = entry->attr->med; + if ((entry->attr-> + flag & ATTR_FLAG_BIT(BGP_ATTR_MULTI_EXIT_DISC)) == 0) + nmed = 0; + + printf("%s|%d|%d|", inet_ntoa(entry->attr->nexthop), npref, nmed); + if ((entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES)) != 0) + printf("%s|%s|", entry->attr->community->str + 1, tmp2); + else + printf("|%s|", tmp2); + if (entry->attr->aggregator_addr.s_addr != -1) + printf("%s|\n", inet_ntoa(entry->attr->aggregator_addr)); + else + printf("|\n"); + } else { + if (timetype == 0) { + time = gmtime(&entry->time); + } else { + time = gmtime(&route->uptime); + } + time2str(time, time_str); + printf("TABLE_DUMP|%s|A|%s|%d|", time_str, + inet_ntoa(route->peer_ip.v4_addr), route->peer_as); + printf("%s/%d|%s|%s\n", inet_ntoa(route->prefix.v4_addr), + route->mask, entry->attr->aspath->str, tmp1); + } } diff -r -U 3 libbgpdump-1.4/bgpdump.h libbgpdump-new/bgpdump.h --- libbgpdump-1.4/bgpdump.h 2004-07-29 15:48:19.000000000 +0200 +++ libbgpdump-new/bgpdump.h 2005-01-14 22:30:09.000000000 +0100 @@ -1,4 +1,4 @@ -/* $Id: bgpdump.h,v 1.1.1.1 2004/07/29 13:48:19 james Exp $ */ +/* $Id: bgpdump.h,v 1.1.1.1 2005/01/14 21:30:09 ljb Exp $ */ /* Copyright (c) 2002 RIPE NCC diff -r -U 3 libbgpdump-1.4/bgpdump_attr.h libbgpdump-new/bgpdump_attr.h --- libbgpdump-1.4/bgpdump_attr.h 2004-07-29 15:48:19.000000000 +0200 +++ libbgpdump-new/bgpdump_attr.h 2005-01-22 07:32:34.000000000 +0100 @@ -1,4 +1,4 @@ -/* $Id: bgpdump_attr.h,v 1.1.1.1 2004/07/29 13:48:19 james Exp $ */ +/* $Id: bgpdump_attr.h,v 1.2 2005/01/22 06:32:34 ljb Exp $ */ /* Copyright (c) 2002 RIPE NCC @@ -159,9 +159,12 @@ u_int16_t len; caddr_t data; + /* flag to indicated truncated attr field */ + u_char trunc; + u_int16_t trunc_len; /* length of truncated attr field */ + u_int16_t unknown_num; struct unknown_attr *unknown; - }; struct community diff -r -U 3 libbgpdump-1.4/bgpdump_formats.h libbgpdump-new/bgpdump_formats.h --- libbgpdump-1.4/bgpdump_formats.h 2004-07-29 15:48:19.000000000 +0200 +++ libbgpdump-new/bgpdump_formats.h 2005-05-24 22:49:14.000000000 +0200 @@ -1,4 +1,4 @@ -/* $Id: bgpdump_formats.h,v 1.1.1.1 2004/07/29 13:48:19 james Exp $ */ +/* $Id: bgpdump_formats.h,v 1.5 2005/05/24 20:49:14 ljb Exp $ */ /* Copyright (c) 2002 RIPE NCC @@ -63,14 +63,13 @@ /* type and subtypes values */ #define BGPDUMP_TYPE_MRTD_BGP 5 #define BGPDUMP_SUBTYPE_MRTD_BGP_NULL 0 -#define BGPDUMP_SUBTYPE_MRTD_BGP_PREFUPDATE 1 -#define BGPDUMP_SUBTYPE_MRTD_BGP_UPDATE 2 +#define BGPDUMP_SUBTYPE_MRTD_BGP_UPDATE 1 +#define BGPDUMP_SUBTYPE_MRTD_BGP_PREF_UPDATE 2 #define BGPDUMP_SUBTYPE_MRTD_BGP_STATE_CHANGE 3 #define BGPDUMP_SUBTYPE_MRTD_BGP_SYNC 4 -#define BGPDUMP_SUBTYPE_MRTD_BGP_OPEN 129 -#define BGPDUMP_SUBTYPE_MRTD_BGP_NOTIFICATION 131 -#define BGPDUMP_SUBTYPE_MRTD_BGP_KEEPALIVE 132 -#define BGPDUMP_SUBTYPE_MRTD_BGP_ROUT_REFRESH 133 +#define BGPDUMP_SUBTYPE_MRTD_BGP_OPEN 5 +#define BGPDUMP_SUBTYPE_MRTD_BGP_NOTIFY 6 +#define BGPDUMP_SUBTYPE_MRTD_BGP_KEEPALIVE 7 #define BGPDUMP_TYPE_MRTD_TABLE_DUMP 12 #define BGPDUMP_SUBTYPE_MRTD_TABLE_DUMP_AFI_IP 1 @@ -109,9 +108,35 @@ struct in_addr source_ip; u_int16_t destination_as; struct in_addr destination_ip; - u_char *bgp_message; + + /* For OPEN packets */ + u_char version; + u_int16_t my_as; + u_int16_t hold_time; + struct in_addr bgp_id; + u_char opt_len; + u_char *opt_data; + + /* For UPDATE packets */ + u_int16_t withdraw_count; + u_int16_t announce_count; + struct prefix *withdraw; + struct prefix *announce; + + /* For NOTIFY packets */ + u_char error_code; + u_char sub_error_code; + u_int16_t notify_len; + u_char *notify_data; } BGPDUMP_MRTD_MESSAGE; +typedef struct struct_BGPDUMP_MRTD_STATE_CHANGE { + u_int16_t source_as; + struct in_addr source_ip; + u_int16_t old_state; + u_int16_t new_state; +} BGPDUMP_MRTD_STATE_CHANGE; + typedef struct struct_BGPDUMP_MRTD_TABLE_DUMP { u_int16_t view; u_int16_t sequence; @@ -170,8 +195,10 @@ struct prefix *withdraw; struct prefix *announce; - /* For corrupt update dumps */ - u_int16_t cut_bytes; + /* For corrupt update dumps -- Zebra truncation issue */ + u_int16_t cut_bytes; + u_char announce_trunc; /* flag -- announcments truncated */ + u_char withdraw_trunc; /* flag -- withdraws truncated */ struct zebra_incomplete incomplete; /* For NOTIFY packets */ @@ -206,6 +233,7 @@ typedef union union_BGPDUMP_BODY { BGPDUMP_MRTD_MESSAGE mrtd_message; BGPDUMP_MRTD_TABLE_DUMP mrtd_table_dump; + BGPDUMP_MRTD_STATE_CHANGE mrtd_state_change; BGPDUMP_ZEBRA_STATE_CHANGE zebra_state_change; BGPDUMP_ZEBRA_MESSAGE zebra_message; BGPDUMP_ZEBRA_ENTRY zebra_entry; diff -r -U 3 libbgpdump-1.4/bgpdump_lib.c libbgpdump-new/bgpdump_lib.c --- libbgpdump-1.4/bgpdump_lib.c 2004-07-29 15:48:19.000000000 +0200 +++ libbgpdump-new/bgpdump_lib.c 2005-05-24 22:49:14.000000000 +0200 @@ -1,4 +1,4 @@ -static char RCSID[] = "$Id: bgpdump_lib.c,v 1.1.1.1 2004/07/29 13:48:19 james Exp $"; +static char RCSID[] = "$Id: bgpdump_lib.c,v 1.8 2005/05/24 20:49:14 ljb Exp $"; /* Copyright (c) 2002 RIPE NCC @@ -33,11 +33,10 @@ */ - /* ------------------------------------------------------------------------------- Module Header -Filename : bgdump_lib.c +Filename : bgpdump_lib.c Author : Dan Ardelean (dan@ripe.net) Date : 02-SEP-2002 Revision : @@ -92,6 +91,10 @@ #endif BGPDUMP *bgpdump_open_dump(char *filename) { + return new_bgpdump_open_dump(filename, BGPDUMP_ALL_FLAGS); +} + +BGPDUMP *new_bgpdump_open_dump(char *filename, int option_flags) { BGPDUMP *this_dump=NULL; gzFile *f; @@ -115,6 +118,7 @@ this_dump->eof=0; this_dump->parsed = 0; this_dump->parsed_ok = 0; + this_dump->option_flags = option_flags; return this_dump; } @@ -124,7 +128,7 @@ gzclose(dump->f); } -BGPDUMP_ENTRY* bgpdump_read_next(BGPDUMP *dump) { +BGPDUMP_ENTRY* bgpdump_read_next(BGPDUMP *dump) { BGPDUMP_ENTRY *this_entry=NULL; struct mstream s; u_char *buffer; @@ -157,6 +161,11 @@ this_entry->time=ntohl(this_entry->time); this_entry->length=ntohl(this_entry->length); + if (this_entry->length > BGPDUMP_MAX_MRT_LEN) { + syslog(LOG_ERR, "bgpdump_read_next: dump record too long (%d bytes), offset %lx, timestamp: %lx", this_entry->length, gztell(dump->f), this_entry->time); free(this_entry); + return(NULL); + } + this_entry->attr=NULL; buffer = malloc(this_entry->length); @@ -170,13 +179,13 @@ dump->eof=1; return(NULL); } - ok=0; - mstream_init(&s,buffer,this_entry->length); + mstream_init(&s,buffer,this_entry->length,dump); switch(this_entry->type) { case BGPDUMP_TYPE_MRTD_BGP: + ok = process_mrtd_bgp(&s,this_entry); break; case BGPDUMP_TYPE_MRTD_TABLE_DUMP: ok = process_mrtd_table_dump(&s,this_entry); @@ -202,14 +211,17 @@ for(afi = 1; afi < BGPDUMP_MAX_AFI; afi++) { for(safi = 1; safi < BGPDUMP_MAX_SAFI; safi++) { - if(info->announce[afi][safi]) + if(info->announce[afi][safi]) { + free(info->announce[afi][safi]->nlri); free(info->announce[afi][safi]); - if(info->withdraw[afi][safi]) + } + if(info->withdraw[afi][safi]) { + free(info->withdraw[afi][safi]->nlri); free(info->withdraw[afi][safi]); + } } } - - free(info); + free(info); } void bgpdump_free_mem(BGPDUMP_ENTRY *entry) { @@ -256,6 +268,24 @@ switch(entry->type) { case BGPDUMP_TYPE_MRTD_TABLE_DUMP: break; + case BGPDUMP_TYPE_MRTD_BGP: + switch(entry->subtype) { + case BGPDUMP_SUBTYPE_MRTD_BGP_UPDATE: + if(entry->body.mrtd_message.withdraw != NULL) + free(entry->body.mrtd_message.withdraw); + if(entry->body.mrtd_message.announce != NULL) + free(entry->body.mrtd_message.announce); + break; + case BGPDUMP_SUBTYPE_MRTD_BGP_OPEN: + if(entry->body.mrtd_message.opt_data) + free(entry->body.mrtd_message.opt_data); + break; + case BGPDUMP_SUBTYPE_MRTD_BGP_NOTIFY: + if(entry->body.mrtd_message.notify_data) + free(entry->body.mrtd_message.notify_data); + break; + } + break; case BGPDUMP_TYPE_ZEBRA_BGP: switch(entry->subtype) { case BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE: @@ -284,19 +314,163 @@ } } +int process_mrtd_header(struct mstream *s, BGPDUMP_ENTRY *entry) { + + if (MSTREAM_CAN_READ(s) < 12 ) { /* check for space for MRTD header */ + syslog(LOG_ERR, "process_mrtd_header: MRTd message length (%d bytes) too short for header", MSTREAM_CAN_READ(s)); + return 0; + } + + /* read in MRT header fields */ + MSTREAM_GETW(s,&entry->body.mrtd_message.source_as); + MSTREAM_GET_IPV4(s,&entry->body.mrtd_message.source_ip); + MSTREAM_GETW(s,&entry->body.mrtd_message.destination_as); + MSTREAM_GET_IPV4(s,&entry->body.mrtd_message.destination_ip); + return 1; +} + +int process_mrtd_bgp_state_change(struct mstream *s, BGPDUMP_ENTRY *entry) { + + if (MSTREAM_CAN_READ(s) < 10 ) { /* check for space for MRTD header */ + syslog(LOG_ERR, "process_mrtd_bgp_state_change: message length (%d bytes) too short", MSTREAM_CAN_READ(s)); + return 0; + } + MSTREAM_GETW(s,&entry->body.mrtd_state_change.source_as); + MSTREAM_GET_IPV4(s,&entry->body.mrtd_state_change.source_ip); + MSTREAM_GETW(s,&entry->body.mrtd_state_change.old_state); + MSTREAM_GETW(s,&entry->body.mrtd_state_change.new_state); + return 1; +} + +int process_mrtd_bgp_open(struct mstream *s, BGPDUMP_ENTRY *entry) { + + if (!process_mrtd_header(s, entry)) + return 0; + MSTREAM_GETC(s, &entry->body.mrtd_message.version); + MSTREAM_GETW(s, &entry->body.mrtd_message.my_as); + MSTREAM_GETW(s, &entry->body.mrtd_message.hold_time); + MSTREAM_GET_IPV4(s, &entry->body.mrtd_message.bgp_id.s_addr); + MSTREAM_GETC(s, &entry->body.mrtd_message.opt_len); + + if(entry->body.mrtd_message.opt_len) { + entry->body.mrtd_message.opt_data = malloc(entry->body.mrtd_message.opt_len); + mstream_get(s, entry->body.mrtd_message.opt_data, entry->body.mrtd_message.opt_len); + } else + entry->body.mrtd_message.opt_data = NULL; + return 1; +} + +int process_mrtd_bgp_notify(struct mstream *s, BGPDUMP_ENTRY *entry) { + + if (!process_mrtd_header(s, entry)) + return 0; + MSTREAM_GETC(s, &entry->body.mrtd_message.error_code); + MSTREAM_GETC(s, &entry->body.mrtd_message.sub_error_code); + /* don't bother with notify data for now */ + entry->body.mrtd_message.notify_len = 0; + entry->body.mrtd_message.notify_data = NULL; + + return 1; +} + +int process_mrtd_bgp_keepalive(struct mstream *s, BGPDUMP_ENTRY *entry) { + + return process_mrtd_header(s, entry); +} + +int process_mrtd_bgp_update(struct mstream *s, BGPDUMP_ENTRY *entry) { + u_int16_t withdraw_len; + int len; + u_char *attr_ptr; + + if (!process_mrtd_header(s, entry)) + return 0; + + /* Initialize announce and withdraw arrays: if there is a + * parse error, they will not be free()d, and we will not segfault. */ + entry->body.mrtd_message.withdraw = NULL; + entry->body.mrtd_message.announce = NULL; + entry->body.mrtd_message.announce_count = 0; + + if(MSTREAM_CAN_READ(s) < 2) { + syslog(LOG_ERR, "process_mrtd_bgp_update: MRTD BGP Update message too short -- %d", MSTREAM_CAN_READ(s)); + return 0; + } + + MSTREAM_GETW(s, &withdraw_len); + len = withdraw_len; + if (len != 0) { + if(len > MSTREAM_CAN_READ(s)) { + syslog(LOG_ERR, "process_mrtd_bgp_update: unfeasible withdraw size -- %d", len); + return 0; + } + entry->body.mrtd_message.withdraw_count = + read_prefix_list(s, len, AFI_IP, &entry->body.mrtd_message.withdraw, NULL); + } else + entry->body.mrtd_message.withdraw_count = 0; + process_attr_init(entry); + + /* Where are we? */ + attr_ptr = s->position; + process_attr_read(s, entry->attr, NULL); + + if(entry->attr->trunc) { /* truncated attributes? */ + syslog(LOG_WARNING, "process_mrtd_bgp_update: attributes truncated -- %d", entry->attr->trunc_len); + return 0; + } + + /* Sanity check in case there are malformed attributes */ + if (s->position != (attr_ptr + entry->attr->len + 2) ) { + syslog(LOG_ERR, "process_mrtd_bgp_update: attributes length sanity check failed"); + return 0; + } + + len = MSTREAM_CAN_READ(s); + if (!len) /* no announcements */ + return 1; + + entry->body.mrtd_message.announce_count = + read_prefix_list(s, len, AFI_IP, &entry->body.mrtd_message.announce, NULL); + + return 1; +} + int process_mrtd_bgp(struct mstream *s,BGPDUMP_ENTRY *entry) { - syslog(LOG_WARNING, "process_mrtd_bgp: record type not implemented"); - return 0; + + if (MSTREAM_CAN_READ(s) > 4096 ) { /* basic sanity check */ + syslog(LOG_ERR, "bgpdump_mrtd_bgp: message length (%d bytes) exceeds BGP maximum", MSTREAM_CAN_READ(s)); + return 0; + } + + switch(entry->subtype) { + case BGPDUMP_SUBTYPE_MRTD_BGP_UPDATE: + return process_mrtd_bgp_update(s,entry); + case BGPDUMP_SUBTYPE_MRTD_BGP_KEEPALIVE: + return process_mrtd_bgp_keepalive(s,entry); + case BGPDUMP_SUBTYPE_MRTD_BGP_STATE_CHANGE: + return process_mrtd_bgp_state_change(s,entry); + case BGPDUMP_SUBTYPE_MRTD_BGP_OPEN: + return process_mrtd_bgp_open(s,entry); + case BGPDUMP_SUBTYPE_MRTD_BGP_NOTIFY: + return process_mrtd_bgp_notify(s,entry); + case BGPDUMP_SUBTYPE_MRTD_BGP_NULL: + return 1; + case BGPDUMP_SUBTYPE_MRTD_BGP_SYNC: + case BGPDUMP_SUBTYPE_MRTD_BGP_PREF_UPDATE: + default: + syslog(LOG_WARNING, "process_mrtd_bgp: subtype not implemented/unknown %d", entry->subtype); + return 0; + } } int process_mrtd_table_dump(struct mstream *s,BGPDUMP_ENTRY *entry) { int afi = entry->subtype; - mstream_getw(s,&entry->body.mrtd_table_dump.view); - mstream_getw(s,&entry->body.mrtd_table_dump.sequence); + MSTREAM_GETW(s,&entry->body.mrtd_table_dump.view); + MSTREAM_GETW(s,&entry->body.mrtd_table_dump.sequence); switch(afi) { case AFI_IP: - mstream_get_ipv4(s, &entry->body.mrtd_table_dump.prefix.v4_addr.s_addr); + MSTREAM_GET_IPV4(s, &entry->body.mrtd_table_dump.prefix.v4_addr.s_addr); break; #ifdef BGPDUMP_HAVE_IPV6 case AFI_IP6: @@ -307,17 +481,17 @@ syslog(LOG_WARNING, "process_mrtd_table_dump: unknown AFI %d", afi); return 0; } - mstream_getc(s,&entry->body.mrtd_table_dump.mask); - mstream_getc(s,&entry->body.mrtd_table_dump.status); - mstream_getl(s,(u_int32_t *)&entry->body.mrtd_table_dump.uptime); - if(afi == AFI_IP) - mstream_get_ipv4(s, &entry->body.mrtd_table_dump.peer_ip.v4_addr.s_addr); + MSTREAM_GETC(s,&entry->body.mrtd_table_dump.mask); + MSTREAM_GETC(s,&entry->body.mrtd_table_dump.status); + MSTREAM_GETL(s,(u_int32_t *)&entry->body.mrtd_table_dump.uptime); + if(afi == AFI_IP) { + MSTREAM_GET_IPV4(s, &entry->body.mrtd_table_dump.peer_ip.v4_addr.s_addr); + } #ifdef BGPDUMP_HAVE_IPV6 else if(afi == AFI_IP6) mstream_get(s, &entry->body.mrtd_table_dump.peer_ip.v6_addr.s6_addr, 16); #endif - - mstream_getw(s,&entry->body.mrtd_table_dump.peer_as); + MSTREAM_GETW(s,&entry->body.mrtd_table_dump.peer_as); process_attr_init(entry); process_attr_read(s, entry->attr, NULL); @@ -341,20 +515,22 @@ } } - int -process_zebra_bgp_state_change(struct mstream *s,BGPDUMP_ENTRY *entry) { - mstream_getw(s,&entry->body.zebra_state_change.source_as); - mstream_getw(s,&entry->body.zebra_state_change.destination_as); +process_zebra_bgp_state_change(struct mstream *s, BGPDUMP_ENTRY *entry) { + MSTREAM_GETW(s,&entry->body.zebra_state_change.source_as); + MSTREAM_GETW(s,&entry->body.zebra_state_change.destination_as); /* 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) { + z_off_t offset; + + offset = gztell( ((BGPDUMP *)(s->ptr))->f ); syslog(LOG_NOTICE, - "process_zebra_bgp_state_change: 8-byte state change (zebra bug?)"); + "process_zebra_bgp_state_change: 8-byte state change (zebra bug?)- offset: %x", (int) offset); - mstream_getw(s,&entry->body.zebra_state_change.old_state); - mstream_getw(s,&entry->body.zebra_state_change.new_state); + MSTREAM_GETW(s,&entry->body.zebra_state_change.old_state); + MSTREAM_GETW(s,&entry->body.zebra_state_change.new_state); /* Fill in with dummy values */ entry->body.zebra_state_change.interface_index = 0; @@ -365,8 +541,8 @@ return 1; } - mstream_getw(s,&entry->body.zebra_state_change.interface_index); - mstream_getw(s,&entry->body.zebra_state_change.address_family); + MSTREAM_GETW(s,&entry->body.zebra_state_change.interface_index); + MSTREAM_GETW(s,&entry->body.zebra_state_change.address_family); switch(entry->body.zebra_state_change.address_family) { case AFI_IP: @@ -376,8 +552,8 @@ return 0; } - mstream_get_ipv4(s,&entry->body.zebra_state_change.source_ip.v4_addr.s_addr); - mstream_get_ipv4(s,&entry->body.zebra_state_change.destination_ip.v4_addr.s_addr); + MSTREAM_GET_IPV4(s,&entry->body.zebra_state_change.source_ip.v4_addr.s_addr); + MSTREAM_GET_IPV4(s,&entry->body.zebra_state_change.destination_ip.v4_addr.s_addr); break; #ifdef BGPDUMP_HAVE_IPV6 case AFI_IP6: @@ -396,8 +572,8 @@ entry->body.zebra_state_change.address_family); return 0; } - mstream_getw(s,&entry->body.zebra_state_change.old_state); - mstream_getw(s,&entry->body.zebra_state_change.new_state); + MSTREAM_GETW(s,&entry->body.zebra_state_change.old_state); + MSTREAM_GETW(s,&entry->body.zebra_state_change.new_state); return 1; } @@ -405,15 +581,19 @@ int process_zebra_bgp_message(struct mstream *s,BGPDUMP_ENTRY *entry) { u_char marker[16]; /* BGP marker */ - mstream_getw(s,&entry->body.zebra_message.source_as); - mstream_getw(s,&entry->body.zebra_message.destination_as); - mstream_getw(s,&entry->body.zebra_message.interface_index); - mstream_getw(s,&entry->body.zebra_message.address_family); + MSTREAM_GETW(s,&entry->body.zebra_message.source_as); + MSTREAM_GETW(s,&entry->body.zebra_message.destination_as); + MSTREAM_GETW(s,&entry->body.zebra_message.interface_index); + MSTREAM_GETW(s,&entry->body.zebra_message.address_family); /* Initialize announce and withdraw arrays: if there is a * parse error, they will not be free()d, and we will not segfault. */ entry->body.zebra_message.withdraw = NULL; entry->body.zebra_message.announce = NULL; + entry->body.zebra_message.withdraw_count = 0; + entry->body.zebra_message.announce_count = 0; + entry->body.zebra_message.withdraw_trunc = 0; + entry->body.zebra_message.announce_trunc = 0; entry->body.zebra_message.opt_len = 0; entry->body.zebra_message.opt_data = NULL; @@ -422,23 +602,32 @@ switch(entry->body.zebra_message.address_family) { case AFI_IP: - mstream_get_ipv4(s,&entry->body.zebra_message.source_ip.v4_addr.s_addr); - mstream_get_ipv4(s,&entry->body.zebra_message.destination_ip.v4_addr.s_addr); - mstream_get (s, marker, 16); + MSTREAM_GET_IPV4(s,&entry->body.zebra_message.source_ip.v4_addr.s_addr); + MSTREAM_GET_IPV4(s,&entry->body.zebra_message.destination_ip.v4_addr.s_addr); + if ( ((BGPDUMP *)(s->ptr))->option_flags & BGPDUMP_CHECK_MARKER ) + mstream_get (s, marker, 16); + else + s->position += 16; break; #ifdef BGPDUMP_HAVE_IPV6 case AFI_IP6: mstream_get(s,&entry->body.zebra_message.source_ip.v6_addr.s6_addr, 16); mstream_get(s,&entry->body.zebra_message.destination_ip.v6_addr.s6_addr, 16); - mstream_get (s, marker, 16); + if ( ((BGPDUMP *)(s->ptr))->option_flags & BGPDUMP_CHECK_MARKER ) + mstream_get (s, marker, 16); + else + s->position += 16; break; #endif case 0xFFFF: /* Zebra doesn't dump ifindex or src/dest IPs in OPEN * messages. Work around it. */ if (entry->body.zebra_message.interface_index == 0xFFFF) { - memset(marker, 0xFF, 4); - mstream_get (s, marker + 4, 12); + if ( ((BGPDUMP *)(s->ptr))->option_flags & BGPDUMP_CHECK_MARKER ) { + memset(marker, 0xFF, 4); + mstream_get (s, marker + 4, 12); + } else + s->position += 12; entry->body.zebra_message.interface_index = 0; entry->body.zebra_message.address_family = AFI_IP; entry->body.zebra_message.source_ip.v4_addr.s_addr = 0; @@ -454,19 +643,21 @@ return 0; } - if(memcmp(marker, "\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377", 16) != 0) { + if ( ((BGPDUMP *)(s->ptr))->option_flags & BGPDUMP_CHECK_MARKER ) { + 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, - "bgp_message: bad marker: %02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x.%02x", + "process_zebra_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); + 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); + entry->body.zebra_message.cut_bytes = entry->body.zebra_message.size - 19 - MSTREAM_CAN_READ(s); switch(entry->body.zebra_message.type) { case BGP_MSG_OPEN: @@ -480,22 +671,22 @@ return 1; case BGP_MSG_ROUTE_REFRESH_01: /* Not implemented yet */ - syslog(LOG_WARNING, "bgp_message: MSG_ROUTE_REFRESH_01 not implemented yet"); + syslog(LOG_WARNING, "process_zebra_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"); + syslog(LOG_WARNING, "process_zebra_bgp_message: MSG_ROUTE_REFRESH not implemented yet"); return 0; default: - syslog(LOG_WARNING, "bgp_message: unknown BGP message type %d", - entry->body.zebra_message.type); + syslog(LOG_WARNING, "process_zebra_bgp_message: unknown Zebra BGP message type %d, size %d, cut_bytes %d", + entry->body.zebra_message.type, entry->body.zebra_message.size, entry->body.zebra_message.cut_bytes ); return 0; } } int process_zebra_bgp_message_notify(struct mstream *s, BGPDUMP_ENTRY *entry) { - mstream_getc(s, &entry->body.zebra_message.error_code); - mstream_getc(s, &entry->body.zebra_message.sub_error_code); + MSTREAM_GETC(s, &entry->body.zebra_message.error_code); + MSTREAM_GETC(s, &entry->body.zebra_message.sub_error_code); entry->body.zebra_message.notify_len = entry->body.zebra_message.size - 21; if(entry->body.zebra_message.notify_len > 0) { @@ -507,11 +698,11 @@ } int process_zebra_bgp_message_open(struct mstream *s, BGPDUMP_ENTRY *entry) { - mstream_getc(s, &entry->body.zebra_message.version); - mstream_getw(s, &entry->body.zebra_message.my_as); - mstream_getw(s, &entry->body.zebra_message.hold_time); - mstream_get_ipv4(s, &entry->body.zebra_message.bgp_id.s_addr); - mstream_getc(s, &entry->body.zebra_message.opt_len); + MSTREAM_GETC(s, &entry->body.zebra_message.version); + MSTREAM_GETW(s, &entry->body.zebra_message.my_as); + MSTREAM_GETW(s, &entry->body.zebra_message.hold_time); + MSTREAM_GET_IPV4(s, &entry->body.zebra_message.bgp_id.s_addr); + MSTREAM_GETC(s, &entry->body.zebra_message.opt_len); if(entry->body.zebra_message.opt_len) { entry->body.zebra_message.opt_data = malloc(entry->body.zebra_message.opt_len); @@ -522,30 +713,42 @@ } int process_zebra_bgp_message_update(struct mstream *s, BGPDUMP_ENTRY *entry) { - int withdraw_len; - int announce_len; - int attr_pos; + u_int16_t withdraw_len; + int len; + u_char *attr_ptr; 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, - &entry->body.zebra_message.incomplete); + MSTREAM_GETW(s, &withdraw_len); + len = withdraw_len; + if (len != 0) { + if(len > MSTREAM_CAN_READ(s)) + entry->body.zebra_message.withdraw_trunc = 1; + if(len > 4080) { + syslog(LOG_WARNING, "process_zebra_bgp_message_update: unfeasible withdraw size -- %d", len); + return 0; + } + entry->body.zebra_message.withdraw_count = + read_prefix_list(s, len, AFI_IP, &entry->body.zebra_message.withdraw, &entry->body.zebra_message.incomplete); + } + + process_attr_init(entry); /* Where are we? */ - attr_pos = s->position; + attr_ptr = s->position; - process_attr_init(entry); process_attr_read(s, entry->attr, &entry->body.zebra_message.incomplete); /* 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; - - announce_len = entry->body.zebra_message.size - 23 - withdraw_len - entry->attr->len; + s->position = attr_ptr + entry->attr->len + 2; + if(s->position >= s->end) /* truncated message, no announcements */ + return 1; + + len = entry->body.zebra_message.size - 23 - len - entry->attr->len; + if(len > MSTREAM_CAN_READ(s)) /* see if announcements have been truncated */ + entry->body.zebra_message.announce_trunc = 1; entry->body.zebra_message.announce_count = - read_prefix_list(s, announce_len, AFI_IP, &entry->body.zebra_message.announce, + read_prefix_list(s, len, AFI_IP, &entry->body.zebra_message.announce, &entry->body.zebra_message.incomplete); return 1; @@ -563,10 +766,8 @@ void process_attr_init(BGPDUMP_ENTRY *entry) { - entry->attr = malloc(sizeof(struct attr)); + entry->attr = calloc(1,sizeof(struct attr)); - entry->attr->refcnt = 0; - entry->attr->flag = 0; entry->attr->origin = -1; entry->attr->nexthop.s_addr = -1; entry->attr->med = -1; @@ -574,85 +775,90 @@ entry->attr->aggregator_as = -1; entry->attr->aggregator_addr.s_addr = -1; entry->attr->weight = -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; } void process_attr_read(struct mstream *s, struct attr *attr, struct zebra_incomplete *incomplete) { u_char flag; u_char type; - u_int32_t len, pos, end; + u_int32_t len; + u_char *end; u_int32_t truelen; struct unknown_attr *unknown; - mstream_getw(s, &attr->len); - attr->data=malloc(attr->len); + /* Check if attribute len truncated */ + if(sizeof(attr->len) > MSTREAM_CAN_READ(s)) { + attr->trunc = 1; + attr->trunc_len = 0; + return; + } + MSTREAM_GETW(s, &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); + if(attr->len > MSTREAM_CAN_READ(s)) { + attr->trunc = 1; + truelen = attr->trunc_len = MSTREAM_CAN_READ(s); } else { truelen = attr->len; } - memcpy(attr->data, &s->start[s->position], truelen); + if ( ((BGPDUMP *)(s->ptr))->option_flags & BGPDUMP_COPY_ATTR ) { + attr->data=malloc(truelen); + memcpy(attr->data, s->position, truelen); + } + + if (attr->trunc) /* don't bother with truncated attributes for now */ + return; /* since IPv4 announcements will be missing as well */ end = s->position + truelen; while(s->position < end) { - mstream_getc(s,&flag); - mstream_getc(s,&type); + 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); + if(flag & BGP_ATTR_FLAG_EXTLEN) { + u_int16_t ext_len; + MSTREAM_GETW(s,&ext_len); + len = ext_len; + } else { + u_char small_len; + MSTREAM_GETC(s,&small_len); + len = small_len; + } switch(type) { case BGP_ATTR_ORIGIN: attr->flag = attr->flag | ATTR_FLAG_BIT (BGP_ATTR_ORIGIN); - mstream_getc(s,&attr->origin); + MSTREAM_GETC(s,&attr->origin); break; case BGP_ATTR_AS_PATH: attr->flag = attr->flag | ATTR_FLAG_BIT (BGP_ATTR_AS_PATH); attr->aspath = malloc(sizeof(struct aspath)); - attr->aspath->refcnt = 0; + attr->aspath->count = attr->aspath->refcnt = 0; attr->aspath->length = len; - attr->aspath->count = 0; attr->aspath->data = malloc(len); mstream_get(s,attr->aspath->data,len); attr->aspath->str = NULL; - process_attr_aspath_string(attr->aspath); + if ( ((BGPDUMP *)(s->ptr))->option_flags & BGPDUMP_PROCESS_ASPATH ) + process_attr_aspath_string(attr->aspath); break; case BGP_ATTR_NEXT_HOP: attr->flag = attr->flag | ATTR_FLAG_BIT (BGP_ATTR_NEXT_HOP); - mstream_get_ipv4(s,&attr->nexthop.s_addr); + MSTREAM_GET_IPV4(s,&attr->nexthop.s_addr); break; case BGP_ATTR_MULTI_EXIT_DISC: attr->flag = attr->flag | ATTR_FLAG_BIT (BGP_ATTR_MULTI_EXIT_DISC); - mstream_getl(s,&attr->med); + MSTREAM_GETL(s,&attr->med); break; case BGP_ATTR_LOCAL_PREF: attr->flag = attr->flag | ATTR_FLAG_BIT (BGP_ATTR_LOCAL_PREF); - mstream_getl(s,&attr->local_pref); + MSTREAM_GETL(s,&attr->local_pref); break; case BGP_ATTR_ATOMIC_AGGREGATE: attr->flag = attr->flag | ATTR_FLAG_BIT (BGP_ATTR_ATOMIC_AGGREGATE); break; case BGP_ATTR_AGGREGATOR: attr->flag = attr->flag | ATTR_FLAG_BIT (BGP_ATTR_AGGREGATOR); - mstream_getw(s,&attr->aggregator_as); - mstream_get_ipv4(s,&attr->aggregator_addr.s_addr); + MSTREAM_GETW(s,&attr->aggregator_as); + MSTREAM_GET_IPV4(s,&attr->aggregator_addr.s_addr); break; case BGP_ATTR_COMMUNITIES: attr->flag = attr->flag | ATTR_FLAG_BIT (BGP_ATTR_COMMUNITIES); @@ -662,7 +868,8 @@ attr->community->val = malloc(len); mstream_get(s,attr->community->val,len); attr->community->str = NULL; - process_attr_community_string(attr->community); + if ( ((BGPDUMP *)(s->ptr))->option_flags & BGPDUMP_PROCESS_COMMUNITY ) + process_attr_community_string(attr->community); break; case BGP_ATTR_MP_REACH_NLRI: attr->flag = attr->flag | ATTR_FLAG_BIT (BGP_ATTR_MP_REACH_NLRI); @@ -924,8 +1131,8 @@ u_int8_t snpa_len; struct mp_nlri *mp_nlri; - mstream_getw(s, &afi); - mstream_getc(s, &safi); + MSTREAM_GETW(s, &afi); + MSTREAM_GETC(s, &safi); len -= 3; /* Do we know about this address family? */ @@ -951,12 +1158,12 @@ info->announce[afi][safi] = mp_nlri; /* Get next hop */ - mstream_getc(s, &mp_nlri->nexthop_len); + MSTREAM_GETC(s, &mp_nlri->nexthop_len); len--; switch(afi) { case AFI_IP: - mstream_get_ipv4(s, &mp_nlri->nexthop.v4_addr.s_addr); + 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 @@ -978,14 +1185,14 @@ len -= mp_nlri->nexthop_len; /* Skip over SNPAs */ - mstream_getc(s, &num_snpa); + 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_GETC(s, &snpa_len); mstream_get(s, NULL, snpa_len); len -= snpa_len; num_snpa--; @@ -1001,8 +1208,8 @@ u_int8_t safi; struct mp_nlri *mp_nlri; - mstream_getw(s, &afi); - mstream_getc(s, &safi); + MSTREAM_GETW(s, &afi); + MSTREAM_GETC(s, &safi); len -= 3; /* Do we know about this address family? */ @@ -1044,24 +1251,33 @@ return 0; } - while(len > 0 && mstream_can_read(s) > 0) { + while(len > 0 && MSTREAM_CAN_READ(s) > 0) { /* Prefix length in bits */ - p_len = mstream_getc(s,NULL); len--; + MSTREAM_GETC(s,&p_len); len--; + if (afi == AFI_IP && p_len > 32) { + syslog(LOG_WARNING, "read_prefix_list: AFI %d - prefix length too long %d", afi, p_len); + mstream_get(s, NULL, MSTREAM_CAN_READ(s)); + break; + } else if (afi == AFI_IP6 && p_len > 128) { + syslog(LOG_WARNING, "read_prefix_list: AFI %d - prefix length too long %d", afi, p_len); + mstream_get(s, NULL, MSTREAM_CAN_READ(s)); + break; + } /* 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(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)); + 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)); + mstream_get(s, NULL, MSTREAM_CAN_READ(s)); } /* In either case, don't put it in the prefix array */ break; diff -r -U 3 libbgpdump-1.4/bgpdump_lib.h libbgpdump-new/bgpdump_lib.h --- libbgpdump-1.4/bgpdump_lib.h 2004-07-29 15:48:19.000000000 +0200 +++ libbgpdump-new/bgpdump_lib.h 2005-04-28 21:34:59.000000000 +0200 @@ -1,4 +1,4 @@ -/* $Id: bgpdump_lib.h,v 1.1.1.1 2004/07/29 13:48:19 james Exp $ */ +/* $Id: bgpdump_lib.h,v 1.2 2005/04/28 19:34:59 ljb Exp $ */ /* Copyright (c) 2002 RIPE NCC @@ -64,6 +64,14 @@ #define BGPDUMP_MAX_FILE_LEN 1024 #define BGPDUMP_MAX_AS_PATH_LEN 2000 +#define BGPDUMP_MAX_MRT_LEN 5000 + +/* flags to enable different levels of processing */ +#define BGPDUMP_COPY_ATTR 0x1 /* flag to copy attribute data */ +#define BGPDUMP_PROCESS_COMMUNITY 0x2 /* flag to asciify communities */ +#define BGPDUMP_PROCESS_ASPATH 0x4 /* flag to asciify AS path */ +#define BGPDUMP_CHECK_MARKER 0x8 /* flag to check marker field in BGP messages */ +#define BGPDUMP_ALL_FLAGS 0xF /* all flags */ typedef struct struct_BGPDUMP { gzFile *f; @@ -71,11 +79,13 @@ char filename[BGPDUMP_MAX_FILE_LEN]; int parsed; int parsed_ok; + int option_flags; } BGPDUMP; /* prototypes */ BGPDUMP *bgpdump_open_dump(char *filename); +BGPDUMP *new_bgpdump_open_dump(char *filename, int option_flags); void bgpdump_close_dump(BGPDUMP *dump); BGPDUMP_ENTRY* bgpdump_read_next(BGPDUMP *dump); diff -r -U 3 libbgpdump-1.4/bgpdump_mstream.c libbgpdump-new/bgpdump_mstream.c --- libbgpdump-1.4/bgpdump_mstream.c 2004-07-29 15:48:19.000000000 +0200 +++ libbgpdump-new/bgpdump_mstream.c 2005-01-22 07:32:35.000000000 +0100 @@ -1,4 +1,4 @@ -static char RCSID[] = "$Id: bgpdump_mstream.c,v 1.1.1.1 2004/07/29 13:48:19 james Exp $"; +static char RCSID[] = "$Id: bgpdump_mstream.c,v 1.2 2005/01/22 06:32:35 ljb Exp $"; /* Copyright (c) 2002 RIPE NCC @@ -56,65 +56,66 @@ #include #include -void mstream_init(struct mstream *s, u_char *buffer, u_int32_t len) { +void mstream_init(struct mstream *s, u_char *buffer, u_int32_t len, void *ptr) { s->start=buffer; - s->position=0; - s->len=len; + s->position=buffer; + s->end=buffer + len; + s->ptr=ptr; } -u_char mstream_getc(struct mstream *s, u_char *d) { - u_char data; +void mstream_getc(struct mstream *s, u_char *d) { - mstream_get(s, &data, sizeof(data)); - if(d!=NULL) memcpy(d,&data,sizeof(data)); - return data; + if ((s->end - s->position) >= sizeof(u_char)) { + *d = *(s->position); + s->position += sizeof(u_char); + } + return; } -u_int16_t mstream_getw(struct mstream *s, u_int16_t *d) { - u_int16_t data; +void mstream_getw(struct mstream *s, u_int16_t *d) { - mstream_get(s, &data, sizeof(data)); - data=ntohs(data); - if(d!=NULL) memcpy(d,&data,sizeof(data)); - return data; + if ((s->end - s->position) >= sizeof(u_int16_t)) { + memcpy(d, s->position, sizeof(u_int16_t)); + *d = ntohs(*d); + s->position += sizeof(u_int16_t); + } + return; } -u_int32_t mstream_getl(struct mstream *s, u_int32_t *d) { - u_int32_t data; +void mstream_getl(struct mstream *s, u_int32_t *d) { - mstream_get(s, &data, sizeof(data)); - data=ntohl(data); - if(d!=NULL) memcpy(d,&data,sizeof(data)); - return data; + if ((s->end - s->position) >= sizeof(u_int32_t)) { + memcpy(d, s->position, sizeof(u_int32_t)); + *d = ntohl(*d); + s->position += sizeof(u_int32_t); + } + return; } -u_int32_t mstream_get_ipv4(struct mstream *s, u_int32_t *d) { - u_int32_t data; +void mstream_get_ipv4(struct mstream *s, u_int32_t *d) { - mstream_get(s, &data, sizeof(data)); - if(d!=NULL) memcpy(d,&data,sizeof(data)); - return data; + if ((s->end - s->position) >= sizeof(u_int32_t)) { + memcpy(d,s->position,sizeof(u_int32_t)); + s->position += sizeof(u_int32_t); + } + return; } -u_int32_t mstream_can_read(struct mstream *s) { - return s->len - s->position; -} - -u_int32_t mstream_get (struct mstream *s, void *d, u_int32_t len) { - int room = mstream_can_read(s); +void mstream_get (struct mstream *s, void *d, u_int32_t len) { + int room = MSTREAM_CAN_READ(s); if(room >= len) { - if(d) memcpy(d, s->start + s->position, len); + if(d) memcpy(d, s->position, len); s->position += len; - return len; + return; } else { /* Reading past end of buffer! Zero out extra bytes and set position to end of buffer */ if(d) { - memcpy(d, s->start + s->position, room); + memcpy(d, s->position, room); memset((char *)d + room, 0, len - room); } - s->position = s->len; - return room; + s->position = s->end; + return; } } diff -r -U 3 libbgpdump-1.4/bgpdump_mstream.h libbgpdump-new/bgpdump_mstream.h --- libbgpdump-1.4/bgpdump_mstream.h 2004-07-29 15:48:19.000000000 +0200 +++ libbgpdump-new/bgpdump_mstream.h 2005-01-22 07:32:35.000000000 +0100 @@ -1,4 +1,4 @@ -/* $Id: bgpdump_mstream.h,v 1.1.1.1 2004/07/29 13:48:19 james Exp $ */ +/* $Id: bgpdump_mstream.h,v 1.2 2005/01/22 06:32:35 ljb Exp $ */ /* Copyright (c) 2002 RIPE NCC @@ -54,19 +54,26 @@ #include #include +#include struct mstream { u_char *start; - u_int16_t position; - u_int32_t len; + u_char *position; + u_char *end; + void *ptr; }; - 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); + void mstream_init(struct mstream *s, u_char *buffer,u_int32_t len, void *ptr); + void mstream_getc(struct mstream *s, u_char *d); + void mstream_getw(struct mstream *s, u_int16_t *d); + void mstream_getl(struct mstream *s, u_int32_t *d); + void mstream_get_ipv4(struct mstream *s, u_int32_t *d); + void mstream_get (struct mstream *s, void *d, u_int32_t len); + +#define MSTREAM_GETC(s,d) { assert( (s)->end-(s)->position >= sizeof(u_char) ); *(d) = *((s)->position); (s)->position++; } +#define MSTREAM_GETW(s,d) { assert( (s)->end-(s)->position >= sizeof(u_int16_t)); memcpy(d, (s)->position, sizeof(u_int16_t)); *(d) = ntohs(*(d)); (s)->position+=sizeof(u_int16_t); } +#define MSTREAM_GETL(s,d) { assert( (s)->end-(s)->position >= sizeof(u_int32_t)); memcpy(d, (s)->position, sizeof(u_int32_t)); *(d) = ntohl(*(d)); (s)->position+=sizeof(u_int32_t); } +#define MSTREAM_GET_IPV4(s,d) { assert( (s)->end-(s)->position >= sizeof(u_int32_t)); memcpy(d, (s)->position, sizeof(u_int32_t)); (s)->position+=sizeof(u_int32_t); } +#define MSTREAM_CAN_READ(s) ((s)->end - (s)->position) #endif Only in libbgpdump-1.4/: bootstrap.sh Only in libbgpdump-new/: configure Only in libbgpdump-1.4/: configure.in diff -r -U 3 libbgpdump-1.4/test.c libbgpdump-new/test.c --- libbgpdump-1.4/test.c 2004-07-29 15:48:19.000000000 +0200 +++ libbgpdump-new/test.c 2005-05-20 22:30:12.000000000 +0200 @@ -1,4 +1,4 @@ -static char RCSID[] = "$Id: test.c,v 1.1.1.1 2004/07/29 13:48:19 james Exp $"; +static char RCSID[] = "$Id: test.c,v 1.2 2005/05/20 20:30:12 ljb Exp $"; /* Copyright (c) 2002 RIPE NCC