Browse Source

Merge upstream version 1.6.0

Christoph Biedl 1 year ago
parent
commit
10b741f9d4
9 changed files with 193 additions and 37 deletions
  1. 2 2
      .hg_archival.txt
  2. 1 0
      .hgtags
  3. 11 0
      ChangeLog
  4. 99 28
      bgpdump.c
  5. 9 0
      bgpdump_attr.h
  6. 1 1
      bgpdump_formats.h
  7. 68 4
      bgpdump_lib.c
  8. 1 1
      bgpdump_mstream.h
  9. 1 1
      configure.in

+ 2 - 2
.hg_archival.txt

@@ -1,4 +1,4 @@
 repo: fc85b5d83c23266299237988401380dcb3d3c4f3
-node: a8ca3180d6d46836b4d4f3f66696b7ed1f7884ee
+node: 6be858c0cc9e14607c6bb1dd6015df536dd642c5
 branch: default
-tag: 1.5.0
+tag: 1.6.0

+ 1 - 0
.hgtags

@@ -8,3 +8,4 @@ b8e3ed2b370ca220f46bfa59193665dfdee5d5ef 1.4.99.13
 c4c53146f09af40a0068992d67a345a05ac54514 1.4.99.14
 d8e8bcf60eb4c7ce065b2744d6a32003c728d8b2 1.4.99.15
 601292759e414fd15a59332928956012b3dc3ddb 1.5.00.00
+a8ca3180d6d46836b4d4f3f66696b7ed1f7884ee 1.5.0

+ 11 - 0
ChangeLog

@@ -8,6 +8,17 @@ PLEASE DO NOT E-MAIL INDIVIDUAL DEVELOPERS ABOUT
 ISSUES, AS YOUR E-MAIL MAY BE LOST
 ==========================================================
 
+2018-09-26 Colin Petrie <cpetrie@ripe.net> v1.6.0
+	* Fix overflow for large records
+	* Add basic '-q' quiet mode
+	* fix off-by-one in peer index assert
+	* fix MyAS handling in open message
+	* version bump as structs have new fields and sizes,
+	  apps should be recompiled
+
+2017-01-15 Colin Petrie <cpetrie@ripe.net>
+	* Add support for BGP Large Communities
+
 2016-09-15 Colin Petrie <cpetrie@ripe.net> v1.5.0
 	* Many security fixes, crashes, segfaults, memory leaks fixed.
 	* Many fixes provided by Christoph Biedl from Debian port

+ 99 - 28
bgpdump.c

@@ -146,6 +146,7 @@ static const char* get_bgp_state_name(u_int16_t state) {
 static int mode=0;
 static int timetype=0;
 static int show_packet_index = 0;
+static int show_large_comms = 0;
 static int packet_index = 0;
 
 static const char USAGE[] = "\
@@ -162,11 +163,13 @@ Common options:\n\
     -O <file>  output to <file> instead of STDOUT\n\
     -s         log to syslog (the default)\n\
     -v         log to STDERR\n\
+    -q         quiet\n\
 \n\
 Options for -m and -M modes:\n\
     -t dump    timestamps for RIB dumps reflect the time of the dump (the default)\n\
     -t change  timestamps for RIB dumps reflect the last route modification\n\
     -p         show packet index at second position\n\
+    -l         show large communities field after regular communities\n\
 \n\
 Special options:\n\
     -T         run unit tests and exit\n\
@@ -181,10 +184,11 @@ int main(int argc, char *argv[]) {
     int fd;
     bool usage_error = false;
     bool use_syslog = true;
+    bool quiet = false;
  
     log_to_stderr();
     
-    while ((c=getopt(argc,argv,"if:o:t:mMHO:svTp"))!=-1)
+    while ((c=getopt(argc,argv,"if:o:t:mMHO:svTplq"))!=-1)
 	switch(c)
 	{
        case 'H':
@@ -232,6 +236,13 @@ int main(int argc, char *argv[]) {
         case 'p':
                 show_packet_index = 1;
                 break;
+        case 'l':
+                show_large_comms = 1;
+                break;
+        case 'q':
+                quiet = true;
+                break;
+
         case '?':
         default:
                 usage_error = true;
@@ -240,7 +251,8 @@ int main(int argc, char *argv[]) {
     argv += optind;
     
     if(use_syslog) {
-        debug("logging to syslog");
+        if(!quiet)
+            debug("logging to syslog");
         log_to_syslog();
     }
     
@@ -1372,6 +1384,10 @@ void show_attr(attributes_t *attr) {
 	    } 
 	    if( (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES) ) !=0)	
 		    printf("COMMUNITY:%s\n",attr->community->str);
+
+        if( (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES) ) !=0)    
+            printf("LARGE_COMMUNITY:%s\n",attr->lcommunity->str);
+       
     }
  
 }
@@ -1488,14 +1504,14 @@ static void table_line_announce(struct prefix *prefix,int count,BGPDUMP_ENTRY *e
 {
 	int idx  ;
 	char buf[128];
-	char tmp2[20];
+	char aggregate[20];
 	unsigned int npref;
 	unsigned int nmed;
 
 	if (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
-		sprintf(tmp2,"AG");
+		sprintf(aggregate,"AG");
 	else
-		sprintf(tmp2,"NAG");
+		sprintf(aggregate,"NAG");
 
 	for (idx=0;idx<count;idx++)
 	{
@@ -1533,10 +1549,19 @@ static void table_line_announce(struct prefix *prefix,int count,BGPDUMP_ENTRY *e
 			    
 			printf("%s|%u|%u|",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);
-				
+		    	printf("%s|",entry->attr->community->str+1);
+            else
+                printf("|");
+
+            if (show_large_comms) {
+                if( (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES) ) !=0) 
+                    printf("%s|",entry->attr->lcommunity->str+1);
+                else
+                    printf("|");
+            }
+
+		    printf("%s|", aggregate); /* AG/NAG */
+
 			if (entry->attr->aggregator_addr.s_addr != -1)
 				printf("%u %s|\n",entry->attr->aggregator_as,inet_ntoa(entry->attr->aggregator_addr));
 			else
@@ -1573,14 +1598,14 @@ static void table_line_announce_1(struct mp_nlri *prefix,int count,BGPDUMP_ENTRY
 {
 	int idx  ;
 	char buf[128];
-	char tmp2[20];
+	char aggregate[20];
 	unsigned int npref;
 	unsigned int nmed;
 
 	if (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
-		sprintf(tmp2,"AG");
+		sprintf(aggregate,"AG");
 	else
-		sprintf(tmp2,"NAG");
+		sprintf(aggregate,"NAG");
 
 	for (idx=0;idx<count;idx++)
 	{
@@ -1625,9 +1650,18 @@ static void table_line_announce_1(struct mp_nlri *prefix,int count,BGPDUMP_ENTRY
                 
 				//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);
+		    		printf("%s|",entry->attr->community->str+1);
 				else
-					printf("|%s|",tmp2);
+					printf("|");
+
+                if (show_large_comms) {
+                    if( (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES) ) !=0) 
+                        printf("%s|",entry->attr->lcommunity->str+1);
+                    else
+                        printf("|");
+                }
+
+                printf("%s|", aggregate); /* AG/NAG */
 
 			}
 			else 
@@ -1668,10 +1702,18 @@ static void table_line_announce_1(struct mp_nlri *prefix,int count,BGPDUMP_ENTRY
 			    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);
+		    		printf("%s|",entry->attr->community->str+1);
 				else
-					printf("|%s|",tmp2);
+					printf("|");
 
+                if (show_large_comms) {
+                    if( (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES) ) !=0) 
+                        printf("%s|",entry->attr->lcommunity->str+1);
+                    else
+                        printf("|");
+                }
+
+                printf("%s|",aggregate); /* AG/NAG */
 
 			}
 			if (entry->attr->aggregator_addr.s_addr != -1)
@@ -1713,14 +1755,14 @@ static void table_line_announce6(struct mp_nlri *prefix,int count,BGPDUMP_ENTRY
 	char buf[128];
 	char buf1[128];
 	char buf2[128];
-	char tmp2[20];
+	char aggregate[20];
 	unsigned int npref;
 	unsigned int nmed;
 
 	if (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
-		sprintf(tmp2,"AG");
+		sprintf(aggregate,"AG");
 	else
-		sprintf(tmp2,"NAG");
+		sprintf(aggregate,"NAG");
 
 	for (idx=0;idx<count;idx++)
 	{
@@ -1772,9 +1814,19 @@ static void table_line_announce6(struct mp_nlri *prefix,int count,BGPDUMP_ENTRY
                 printf("%s|%s|%s|%u|%u|", attr_aspath(entry->attr),describe_origin(entry->attr->origin),fmt_ipv6(prefix->nexthop,buf),npref,nmed);
 
 			if( (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES) ) !=0)	
-		    		printf("%s|%s|",entry->attr->community->str+1,tmp2);
+		    		printf("%s|",entry->attr->community->str+1);
 			else
-				printf("|%s|",tmp2);
+				printf("|");
+
+            if (show_large_comms) {
+                if( (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES) ) !=0) 
+                    printf("%s|",entry->attr->lcommunity->str+1);
+                else
+                    printf("|");
+
+            }
+
+            printf("%s|", aggregate); /* AG/NAG */
 
 
 			if (entry->attr->aggregator_addr.s_addr != -1)
@@ -1816,16 +1868,16 @@ static void table_line_mrtd_route(BGPDUMP_MRTD_TABLE_DUMP *route,BGPDUMP_ENTRY *
 {
 	
 	struct tm *date = NULL;
-	char tmp2[20];	
+	char aggregate[20];	
 	unsigned int npref;
 	unsigned int nmed;
 	char  time_str[20];
         char peer[BGPDUMP_ADDRSTRLEN], prefix[BGPDUMP_ADDRSTRLEN], nexthop[BGPDUMP_ADDRSTRLEN];
 
 	if (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_ATOMIC_AGGREGATE))
-		sprintf(tmp2,"AG");
+		sprintf(aggregate,"AG");
 	else
-		sprintf(tmp2,"NAG");
+		sprintf(aggregate,"NAG");
 
     time_t *t;
     if (timetype==0) {
@@ -1880,9 +1932,19 @@ static void table_line_mrtd_route(BGPDUMP_MRTD_TABLE_DUMP *route,BGPDUMP_ENTRY *
 		   printf("%s|%u|%u|",nexthop,npref,nmed);
 
 		   if( (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES) ) !=0)	
-		    		printf("%s|%s|",entry->attr->community->str+1,tmp2);
+		    		printf("%s|",entry->attr->community->str+1);
 			else
-				printf("|%s|",tmp2);
+				printf("|");
+
+            if (show_large_comms) {
+                if( (entry->attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES) ) !=0)  
+                    printf("%s|",entry->attr->lcommunity->str+1);
+                else
+                    printf("|");
+
+            }
+
+            printf("%s|",aggregate); /* AG/NAG */
 				
 			if (entry->attr->aggregator_addr.s_addr != -1)
 				printf("%u %s|\n",entry->attr->aggregator_as,inet_ntoa(entry->attr->aggregator_addr));
@@ -1997,10 +2059,19 @@ static void table_line_dump_v2_prefix(BGPDUMP_TABLE_DUMP_V2_PREFIX *e,BGPDUMP_EN
             printf("%s|%u|%u|",nexthop,npref,nmed);
             
             if( (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_COMMUNITIES) ) !=0)	
-                printf("%s|%s|",attr->community->str+1,aggregate);
+                printf("%s|",attr->community->str+1);
             else
-                printf("|%s|",aggregate);
+                printf("|");
+
+            if (show_large_comms) {
+                if( (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_LARGE_COMMUNITIES) ) !=0)    
+                    printf("%s|",attr->lcommunity->str+1);
+                else
+                    printf("|");
+            }
             
+            printf("%s|",aggregate);
+
             if (attr->aggregator_addr.s_addr != -1)
                 printf("%u %s|\n",attr->aggregator_as,inet_ntoa(attr->aggregator_addr));
             else

+ 9 - 0
bgpdump_attr.h

@@ -56,6 +56,7 @@ Original Author: Dan Ardelean (dan@ripe.net)
 #define BGP_ATTR_EXT_COMMUNITIES          16
 #define BGP_ATTR_NEW_AS_PATH              17
 #define BGP_ATTR_NEW_AGGREGATOR           18
+#define BGP_ATTR_LARGE_COMMUNITIES        32
 
 /* Flag macro */
 #define ATTR_FLAG_BIT(X)  (1 << ((X) - 1))
@@ -129,6 +130,7 @@ struct attr
   struct aspath 	*aspath;
   struct community 	*community;
   struct ecommunity 	*ecommunity;
+  struct lcommunity   *lcommunity;
   struct transit 	*transit;
   
   /* libbgpdump additions */
@@ -156,6 +158,13 @@ struct community
   char			*str;
 };
 
+struct lcommunity
+{
+  int       size;
+  u_int32_t *val;
+  char      *str;
+};
+
 struct cluster_list
 {
   int			length;

+ 1 - 1
bgpdump_formats.h

@@ -79,7 +79,7 @@ Original Author: Dan Ardelean (dan@ripe.net)
 #define BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_LOCAL	6  /* BGP4MP_MESSAGE_LOCAL */
 #define BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_AS4_LOCAL	7  /* BGP4MP_MESSAGE_AS4_LOCAL */
 
-/* draft-petrie-grow-mrt-add-paths-00 */
+/* RFC8050 add-path extensions */
 #define BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_ADDPATH            8   /* BGP4MP_MESSAGE_ADDPATH */
 #define BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_AS4_ADDPATH        9   /* BGP4MP_MESSAGE_AS4_ADDPATH */
 #define BGPDUMP_SUBTYPE_ZEBRA_BGP_MESSAGE_LOCAL_ADDPATH      10  /* BGP4MP_MESSAGE_LOCAL_ADDPATH */

+ 68 - 4
bgpdump_lib.c

@@ -64,6 +64,7 @@ static    attributes_t *process_attributes(struct mstream *s, u_int8_t asn_len,
 static    void process_attr_aspath_string(struct aspath *as);
 static    char aspath_delimiter_char (u_char type, u_char which);
 static    void process_attr_community_string(struct community *com);
+static    void process_attr_lcommunity_string(struct lcommunity *lcom);
 
 static    void process_mp_announce(struct mstream *s, struct mp_info *info, struct zebra_incomplete *incomplete, int is_addp);
 static    void process_mp_withdraw(struct mstream *s, struct mp_info *info, struct zebra_incomplete *incomplete, int is_addp);
@@ -258,7 +259,7 @@ static void bgpdump_free_mp_info(struct mp_info *info) {
     u_int8_t safi;
 
     for(afi = 1; afi <= BGPDUMP_MAX_AFI; afi++) {
-	for(safi = 1; safi < BGPDUMP_MAX_SAFI; safi++) {
+	for(safi = 1; safi <= BGPDUMP_MAX_SAFI; safi++) {
 	    if(info->announce[afi][safi])
 		free(info->announce[afi][safi]);
 		info->announce[afi][safi] = NULL;
@@ -355,6 +356,16 @@ void bgpdump_free_attr(attributes_t *attr){
 		free(attr->community);
 	    }
 
+        if(attr->lcommunity != NULL) {
+            if(attr->lcommunity->val != NULL)
+                free(attr->lcommunity->val);
+
+            if(attr->lcommunity->str != NULL)
+                free(attr->lcommunity->str);
+
+        free(attr->lcommunity);
+        }
+
 	    if(attr->data != NULL)
 		free(attr->data);
 
@@ -622,7 +633,7 @@ int process_mrtd_table_dump_v2_ipv4_unicast(struct mstream *s, BGPDUMP_ENTRY *en
 		e = &prefixdata->entries[i];
 
 		mstream_getw(s, &e->peer_index);
-		assert(e->peer_index <= entry->dump->table_dump_v2_peer_index_table->peer_count);
+		assert(e->peer_index < entry->dump->table_dump_v2_peer_index_table->peer_count);
 		e->peer = &entry->dump->table_dump_v2_peer_index_table->entries[e->peer_index];
 		mstream_getl(s, &e->originated_time);
 
@@ -672,7 +683,7 @@ int process_mrtd_table_dump_v2_ipv6_unicast(struct mstream *s, BGPDUMP_ENTRY *en
 		e = &prefixdata->entries[i];
 
 		mstream_getw(s, &e->peer_index);
-		assert(e->peer_index <= entry->dump->table_dump_v2_peer_index_table->peer_count);
+		assert(e->peer_index < entry->dump->table_dump_v2_peer_index_table->peer_count);
 		e->peer = &entry->dump->table_dump_v2_peer_index_table->entries[e->peer_index];
 		mstream_getl(s, &e->originated_time);
 
@@ -926,7 +937,8 @@ int process_zebra_bgp_message_notify(struct mstream *s, BGPDUMP_ENTRY *entry) {
 
 int process_zebra_bgp_message_open(struct mstream *s, BGPDUMP_ENTRY *entry, u_int8_t asn_len) {
     mstream_getc(s, &entry->body.zebra_message.version);
-    entry->body.zebra_message.my_as = read_asn(s, asn_len);
+    // my_as in open is always 16bits, regardless of MRT subtype
+    entry->body.zebra_message.my_as = read_asn(s, ASN16_LEN);
     mstream_getw(s, &entry->body.zebra_message.hold_time);
     entry->body.zebra_message.bgp_id = mstream_get_ipv4(s);
     mstream_getc(s, &entry->body.zebra_message.opt_len);
@@ -1003,6 +1015,8 @@ static attributes_t *attr_init(struct mstream *s, int len) {
 
     attr->aspath			= NULL;
     attr->community		= NULL;
+    attr->lcommunity     = NULL;
+
     attr->transit		= NULL;
     attr->mp_info		= calloc(1, sizeof(struct mp_info));
     if(attr->mp_info == NULL) {
@@ -1121,6 +1135,23 @@ static void process_one_attr(struct mstream *outer_stream, attributes_t *attr, u
             attr->community->str	= NULL;
             process_attr_community_string(attr->community);
             break;
+         case BGP_ATTR_LARGE_COMMUNITIES:
+            assert(! attr->lcommunity);
+            if((attr->lcommunity     = malloc(sizeof(struct lcommunity))) == NULL) {
+                err("%s: out of memory", __func__);
+                exit(1); /* XXX */
+            }
+            
+            attr->lcommunity->size   = len / 12;
+            if((attr->lcommunity->val    = malloc(len)) == NULL) {
+                err("%s: out of memory", __func__);
+                exit(1); /* XXX */
+            }
+
+            mstream_get(s,attr->lcommunity->val,len);
+            attr->lcommunity->str    = NULL;
+            process_attr_lcommunity_string(attr->lcommunity);
+            break;
         case BGP_ATTR_NEW_AS_PATH:
             assert(! attr->new_aspath);
             attr->new_aspath = create_aspath(len, ASN32_LEN);
@@ -1394,6 +1425,39 @@ void process_attr_community_string(struct community *com) {
     }
 }
 
+void process_attr_lcommunity_string(struct lcommunity *lcom) {
+
+  char buf[BUFSIZ];
+  u_int32_t i;
+  u_int32_t global;
+  u_int32_t local1;
+  u_int32_t local2;
+
+  memset (buf, 0, BUFSIZ);
+
+  for (i = 0; i < lcom->size; i++)
+    {
+        memcpy (&global, lcom->val + (i * 3), sizeof (u_int32_t));
+        memcpy (&local1, lcom->val + (i * 3) + 1, sizeof (u_int32_t));
+        memcpy (&local2, lcom->val + (i * 3) + 2, sizeof (u_int32_t));
+
+        global = ntohl (global);
+        local1 = ntohl (local1);
+        local2 = ntohl (local2);
+
+        snprintf (buf + strlen (buf), BUFSIZ - strlen (buf),
+            " %u:%u:%u", global, local1, local2);
+    }
+
+    if((lcom->str = malloc(strlen(buf)+1)) != NULL) {
+        strcpy(lcom->str, buf);
+    } else {
+        err("%s: out of memory", __func__);
+        exit(1); /* XXX */
+    }
+
+}
+
 static struct mp_nlri *get_nexthop(struct mstream *s) {
     struct mp_nlri *nlri = calloc(1, sizeof(struct mp_nlri));
     

+ 1 - 1
bgpdump_mstream.h

@@ -33,7 +33,7 @@ Original Author: Dan Ardelean (dan@ripe.net)
 
 typedef struct mstream {
     u_char	*start;
-    u_int16_t	position;
+    u_int32_t	position;
     u_int32_t	len;
 } mstream_t;
 

+ 1 - 1
configure.in

@@ -1,7 +1,7 @@
 dnl Process this file with autoconf to produce a configure script.
 AC_REVISION($Revision$)
 
-AC_INIT([libbgpdump], 1.5.0, [ris@ripe.net])
+AC_INIT([libbgpdump], 1.6.0, [ris@ripe.net])
 AC_CONFIG_SRCDIR([bgpdump_lib.c])
 AC_CONFIG_HEADERS([bgpdump-config.h])