]> The Tcpdump Group git mirrors - tcpdump/commitdiff
from Anantharamu Suryanarayana: add 4-byte AS support to the BGP printer
authorHannes Gredler <[email protected]>
Tue, 20 Jan 2009 20:40:22 +0000 (21:40 +0100)
committerHannes Gredler <[email protected]>
Tue, 20 Jan 2009 20:40:22 +0000 (21:40 +0100)
interface.h
netdissect.h
print-bgp.c
tcpdump.c

index a27d00204fd2c1d7e61a97d7c620b61da2415e91..40067ed46cc5f4af3307b8d80b7e0c404181bd12 100644 (file)
@@ -363,6 +363,7 @@ extern void bpf_dump(const struct bpf_program *, int);
 #ifndef NETDISSECT_REWORKED
 extern netdissect_options *gndo;
 
+#define bflag gndo->ndo_bflag 
 #define eflag gndo->ndo_eflag 
 #define fflag gndo->ndo_fflag 
 #define Kflag gndo->ndo_Kflag 
index 3a70661ef8c36cc0d5af54c119f69514c2703360..8b5c8420ef7d7d874f8b1ede368ae9def69f02a3 100644 (file)
@@ -84,6 +84,7 @@ typedef struct netdissect_options netdissect_options;
 
 struct netdissect_options {
   int ndo_aflag;               /* translate network and broadcast addresses */
+  int ndo_bflag;               /* print 4 byte ASes in ASDOT notation */
   int ndo_eflag;               /* print ethernet header */
   int ndo_fflag;               /* don't translate "foreign" IP address */
   int ndo_Kflag;               /* don't check TCP checksums */
index b20ce590a67f9ad83bf3090551739f612a348744..d77802dd734b14476744479aac1589de73a9ad36 100644 (file)
@@ -465,6 +465,29 @@ static struct tok bgp_extd_comm_ospf_rtype_values[] = {
   { 0, NULL },
 };
 
+#define TOKBUFSIZE 128
+static char astostr[20];
+
+/*
+ * as_printf
+ *
+ * Convert an AS number into a string and return string pointer.
+ *
+ * Bepending on bflag is set or not, AS number is converted into ASDOT notation
+ * or plain number notation.
+ *
+ */
+static char *
+as_printf (char *str, int size, u_int asnum)
+{
+       if (!bflag || asnum <= 0xFFFF) {
+               snprintf(str, size, "%u", asnum);
+       } else {
+               snprintf(str, size, "%u.%u", asnum >> 16, asnum & 0xFFFF);
+       }
+       return str;
+}
+
 int
 decode_prefix4(const u_char *pptr, char *buf, u_int buflen)
 {
@@ -657,9 +680,10 @@ bgp_vpn_rd_print (const u_char *pptr) {
 
         /* 4-byte-AS:number fmt*/
     case 2:
-        snprintf(pos, sizeof(rd) - (pos - rd), "%u:%u (%u.%u.%u.%u:%u)",
-            EXTRACT_32BITS(pptr+2), EXTRACT_16BITS(pptr+6),
-            *(pptr+2), *(pptr+3), *(pptr+4), *(pptr+5), EXTRACT_16BITS(pptr+6));
+       snprintf(pos, sizeof(rd) - (pos - rd), "%s:%u (%u.%u.%u.%u:%u)",
+           as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(pptr+2)),
+           EXTRACT_16BITS(pptr+6), *(pptr+2), *(pptr+3), *(pptr+4),
+           *(pptr+5), EXTRACT_16BITS(pptr+6));
         break;
     default:
         snprintf(pos, sizeof(rd) - (pos - rd), "unknown RD format");
@@ -697,9 +721,9 @@ decode_rt_routing_info(const u_char *pptr, char *buf, u_int buflen)
                ((u_char *)&route_target)[(plen + 7) / 8 - 1] &=
                        ((0xff00 >> (plen % 8)) & 0xff);
        }
-       snprintf(buf, buflen, "origin AS: %u, route target %s",
-                 EXTRACT_32BITS(pptr+1),
-                 bgp_vpn_rd_print((u_char *)&route_target));
+       snprintf(buf, buflen, "origin AS: %s, route target %s",
+           as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(pptr+1)),
+           bgp_vpn_rd_print((u_char *)&route_target));
 
        return 5 + (plen + 7) / 8;
 
@@ -839,9 +863,10 @@ decode_multicast_vpn(const u_char *pptr, char *buf, u_int buflen)
         case BGP_MULTICAST_VPN_ROUTE_TYPE_INTER_AS_I_PMSI:
             TCHECK2(pptr[0], BGP_VPN_RD_LEN + 4);
             offset = strlen(buf);
-            snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %u",
-                     bgp_vpn_rd_print(pptr),
-                     EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN));
+           snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s",
+               bgp_vpn_rd_print(pptr),
+               as_printf(astostr, sizeof(astostr),
+               EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN)));
             break;
 
         case BGP_MULTICAST_VPN_ROUTE_TYPE_S_PMSI:
@@ -874,9 +899,10 @@ decode_multicast_vpn(const u_char *pptr, char *buf, u_int buflen)
         case BGP_MULTICAST_VPN_ROUTE_TYPE_SOURCE_TREE_JOIN:
             TCHECK2(pptr[0], BGP_VPN_RD_LEN);
             offset = strlen(buf);
-            snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %u",
-                     bgp_vpn_rd_print(pptr),
-                     EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN));
+           snprintf(buf + offset, buflen - offset, ", RD: %s, Source-AS %s",
+               bgp_vpn_rd_print(pptr),
+               as_printf(astostr, sizeof(astostr),
+               EXTRACT_32BITS(pptr + BGP_VPN_RD_LEN)));
             pptr += BGP_VPN_RD_LEN;
 
             bgp_vpn_sg_print(pptr, buf, buflen);
@@ -1272,9 +1298,11 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len)
                                                tokbuf, sizeof(tokbuf)));
                         for (i = 0; i < tptr[1] * as_size; i += as_size) {
                             TCHECK2(tptr[2 + i], as_size);
-                            printf("%u ",
-                                   as_size == 2 ?  EXTRACT_16BITS(&tptr[2 + i]) :
-                                                   EXTRACT_32BITS(&tptr[2 + i]));
+                           printf("%s ",
+                               as_printf(astostr, sizeof(astostr),
+                               as_size == 2 ? 
+                               EXTRACT_16BITS(&tptr[2 + i]) :
+                               EXTRACT_32BITS(&tptr[2 + i])));
                         }
                        TCHECK(tptr[0]);
                         printf("%s", tok2strbuf(bgp_as_path_segment_close_values,
@@ -1305,23 +1333,36 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len)
                if (len != 0)
                        printf("invalid len");
                break;
-       case BGPTYPE_AGGREGATOR:
-               if (len != 6) {
-                       printf("invalid len");
-                       break;
-               }
-               TCHECK2(tptr[0], 6);
-               printf(" AS #%u, origin %s", EXTRACT_16BITS(tptr),
+        case BGPTYPE_AGGREGATOR:
+
+                /*
+                 * Depending on the AS encoded is of 2 bytes or of 4 bytes,
+                 * the length of this PA can be either 6 bytes or 8 bytes.
+                 */
+                if (len != 6 && len != 8) {
+                    printf("invalid len");
+                    break;
+                }
+                TCHECK2(tptr[0], len);
+                if (len == 6) {
+                   printf(" AS #%s, origin %s",
+                       as_printf(astostr, sizeof(astostr), EXTRACT_16BITS(tptr)),
                        getname(tptr + 2));
-               break;
+                } else {
+                   printf(" AS #%s, origin %s",
+                       as_printf(astostr, sizeof(astostr),
+                       EXTRACT_32BITS(tptr)), getname(tptr + 4));
+                }
+                break;
        case BGPTYPE_AGGREGATOR4:
                if (len != 8) {
                        printf("invalid len");
                        break;
                }
                TCHECK2(tptr[0], 8);
-               printf(" AS #%u, origin %s", EXTRACT_32BITS(tptr),
-                       getname(tptr + 4));
+               printf(" AS #%s, origin %s",
+                   as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(tptr)),
+                   getname(tptr + 4));
                break;
        case BGPTYPE_COMMUNITIES:
                if (len % 4) {
@@ -1843,6 +1884,15 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len)
                         else
                             printf("\n\t      %s", buf);
                         break;                                   
+                   case (AFNUM_INET<<8 | SAFNUM_MDT):
+                     advance = decode_mdt_vpn_nlri(tptr, buf, sizeof(buf));
+                     if (advance == -1)
+                            printf("\n\t    (illegal prefix length)");
+                        else if (advance == -2)
+                            goto trunc;
+                        else
+                            printf("\n\t      %s", buf);
+                      break;
                     case (AFNUM_INET<<8 | SAFNUM_MULTICAST_VPN): /* fall through */
                     case (AFNUM_INET6<<8 | SAFNUM_MULTICAST_VPN):
                         advance = decode_multicast_vpn(tptr, buf, sizeof(buf));
@@ -1903,10 +1953,10 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len)
                         break;
                     case BGP_EXT_COM_RT_2:
                     case BGP_EXT_COM_RO_2:
-                        printf(": %u:%u",
-                               EXTRACT_32BITS(tptr+2),
-                               EXTRACT_16BITS(tptr+6));
-                        break;
+                       printf(": %s:%u",
+                           as_printf(astostr, sizeof(astostr),
+                           EXTRACT_32BITS(tptr+2)), EXTRACT_16BITS(tptr+6));
+                       break;
                     case BGP_EXT_COM_LINKBAND:
                        bw.i = EXTRACT_32BITS(tptr+2);
                         printf(": bandwidth: %.3f Mbps",
@@ -2013,8 +2063,9 @@ bgp_attr_print(const struct bgp_attr *attr, const u_char *pptr, int len)
         }
         case BGPTYPE_ATTR_SET:
                 TCHECK2(tptr[0], 4);
-                printf("\n\t    Origin AS: %u", EXTRACT_32BITS(tptr));
-                tptr+=4;
+               printf("\n\t    Origin AS: %s",
+                   as_printf(astostr, sizeof(astostr), EXTRACT_32BITS(tptr)));
+               tptr+=4;
                 len -=4;
 
                 while (len >= 2 ) {
@@ -2084,7 +2135,8 @@ bgp_open_print(const u_char *dat, int length)
        memcpy(&bgpo, dat, BGP_OPEN_SIZE);
 
        printf("\n\t  Version %d, ", bgpo.bgpo_version);
-       printf("my AS %u, ", ntohs(bgpo.bgpo_myas));
+       printf("my AS %s, ",
+           as_printf(astostr, sizeof(astostr), ntohs(bgpo.bgpo_myas)));
        printf("Holdtime %us, ", ntohs(bgpo.bgpo_holdtime));
        printf("ID %s", getname((u_char *)&bgpo.bgpo_id));
        printf("\n\t  Optional parameters, length: %u", bgpo.bgpo_optlen);
@@ -2160,6 +2212,18 @@ bgp_open_print(const u_char *dat, int length)
                     case BGP_CAPCODE_RR:
                     case BGP_CAPCODE_RR_CISCO:
                         break;
+                    case BGP_CAPCODE_AS_NEW:
+
+                        /*
+                         * Extract the 4 byte AS number encoded.
+                         */
+                        TCHECK2(opt[i + BGP_OPT_SIZE + 2], cap_len);
+                        if (cap_len == 4) {
+                           printf("\n\t\t 4 Byte AS %s",
+                               as_printf(astostr, sizeof(astostr),
+                               EXTRACT_32BITS(opt + i + BGP_OPT_SIZE + 2)));
+                        }
+                        break;
                     default:
                         TCHECK2(opt[i+BGP_OPT_SIZE+2],cap_len);
                         printf("\n\t\tno decoder for Capability %u",
index 625e5df65a37e79b4c81aa783add8cfb6cc747c0..ba8b702b64b5c816982d305bc25756b9675e3c37 100644 (file)
--- a/tcpdump.c
+++ b/tcpdump.c
@@ -545,6 +545,9 @@ main(int argc, char **argv)
                case 'A':
                        ++Aflag;
                        break;
+               case 'b':
+                       ++bflag;
+                       break;
 
 #if defined(HAVE_PCAP_CREATE) || defined(WIN32)
                case 'B':