1. ripencc
  2. bgpdump

Commits

Comments (0)

Files changed (4)

File ChangeLog Modified

View file
  • Ignore whitespace
  • Hide word diff
 ISSUES, AS YOUR E-MAIL MAY BE LOST
 ==========================================================
 
+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

File bgpdump.c Modified

View file
  • Ignore whitespace
  • Hide word diff
 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[] = "\
     -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\
  
     log_to_stderr();
     
-    while ((c=getopt(argc,argv,"if:o:t:mMHO:svTp"))!=-1)
+    while ((c=getopt(argc,argv,"if:o:t:mMHO:svTpl"))!=-1)
 	switch(c)
 	{
        case 'H':
         case 'p':
                 show_packet_index = 1;
                 break;
+        case 'l':
+                show_large_comms = 1;
+                break;
+               
         case '?':
         default:
                 usage_error = true;
 	    } 
 	    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);
+       
     }
  
 }
 {
 	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++)
 	{
 			    
 			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
 {
 	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++)
 	{
                 
 				//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 
 			    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)
 	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++)
 	{
                 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)
 {
 	
 	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) {
 		   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));
             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

File bgpdump_attr.h Modified

View file
  • Ignore whitespace
  • Hide word diff
 #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))
   struct aspath 	*aspath;
   struct community 	*community;
   struct ecommunity 	*ecommunity;
+  struct lcommunity   *lcommunity;
   struct transit 	*transit;
   
   /* libbgpdump additions */
   char			*str;
 };
 
+struct lcommunity
+{
+  int       size;
+  u_int32_t *val;
+  char      *str;
+};
+
 struct cluster_list
 {
   int			length;

File bgpdump_lib.c Modified

View file
  • Ignore whitespace
  • Hide word diff
 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);
 		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);
 
 
     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) {
             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);
     }
 }
 
+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));