bgp improvements.
authoritojun <itojun@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 11 Nov 1999 21:08:52 +0000 (21:08 +0000)
committeritojun <itojun@f5534014-38df-0310-8fa8-9805f1628bb7>
Thu, 11 Nov 1999 21:08:52 +0000 (21:08 +0000)
- a few more tree types
- RFC1771 NLRI printed on advertisements
- AS_PATH parsing
- lots of small cleanup on printing "byte" vs "bytes"

From: Greg Hankins <gregh@cc.gatech.edu>

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@1015 f5534014-38df-0310-8fa8-9805f1628bb7

packet-bgp.c
packet-bgp.h
packet.h

index c51f58ed3a9138d8628540ea640b4d7c8c880647..2a71e839c5c23271ecc6a1d37d8ccdbe940bbd38 100644 (file)
@@ -2,7 +2,7 @@
  * Routines for BGP packet dissection.
  * Copyright 1999, Jun-ichiro itojun Hagino <itojun@itojun.org>
  *
- * $Id: packet-bgp.c,v 1.8 1999/11/06 01:28:49 itojun Exp $
+ * $Id: packet-bgp.c,v 1.9 1999/11/11 21:08:51 itojun Exp $
  * 
  * Supports:
  * RFC1771 A Border Gateway Protocol 4 (BGP-4)
@@ -63,6 +63,7 @@
 #include "packet.h"
 #include "packet-bgp.h"
 #include "packet-ipv6.h"
+#include <arpa/inet.h>
 
 static const value_string bgptypevals[] = {
     { BGP_OPEN, "OPEN Message" },
@@ -178,6 +179,9 @@ static const value_string afnumber[] = {
 
 static int proto_bgp = -1;
 
+/*
+ * Decode an IPv4 prefix.
+ */
 static int
 decode_prefix4(const u_char *pd, char *buf, int buflen)
 {
@@ -196,6 +200,9 @@ decode_prefix4(const u_char *pd, char *buf, int buflen)
     return 1 + (plen + 7) / 8;
 }
 
+/*
+ * Decode an IPv6 prefix.
+ */
 static int
 decode_prefix6(const u_char *pd, char *buf, int buflen)
 {
@@ -220,8 +227,8 @@ decode_prefix6(const u_char *pd, char *buf, int buflen)
 static void
 dissect_bgp_open(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
 {
-    struct bgp_open bgpo;          /* BGP OPEN message   */
-    int hlen;                      /* message length     */
+    struct bgp_open bgpo;   /* BGP OPEN message   */
+    int hlen;               /* message length     */
 
     /* snarf OPEN message */
     memcpy(&bgpo, &pd[offset], sizeof(bgpo));
@@ -251,64 +258,58 @@ dissect_bgp_open(const u_char *pd, int offset, frame_data *fd, proto_tree *tree)
     }
 }
 
-/* NOTE: caller needs to free() the returned value. */
-static char *
-dissect_bgp_aspath(const u_char *pd, int len)
-{
-    char *msg;
-    int j, n;
-    char *q;
-
-    if (len % 2)
-       return NULL;
-    msg = malloc(len / 2 * 6 + 10);
-    if (!msg)
-       return NULL;
-
-    q = msg;
-    for (j = 0; j < len; j += 2) {
-       n = sprintf(q, "%u ", ntohs(*(guint16 *)&pd[j]));
-       q += n;
-    }
-
-    /* remove the last blank */
-    q--;
-    *q = '\0';
-
-    return msg;
-}
-
+/*
+ * Dissect a BGP UPDATE message.
+ */
 static void
 dissect_bgp_update(const u_char *pd, int offset, frame_data *fd,
     proto_tree *tree)
 {
-    struct bgp bgp;
+    struct bgp      bgp;
     struct bgp_attr bgpa;
-    int hlen;
-    const u_char *p;
-    int len;
-    proto_item *ti;
-    proto_tree *subtree, *subtree2, *subtree3;
-    int i;
-
+    int             hlen;
+    const u_char    *p;
+    const u_char    *q;
+    const u_char    *end;
+    int             len;
+    proto_item      *ti;
+    proto_tree      *subtree;     
+    proto_tree      *subtree2; 
+    proto_tree      *subtree3;
+    int             i;
+    int             j;
+    guint8          length;
+    guint8          type;
+    struct in_addr  prefix;
+    char            *as_path_str = NULL;
+    char junk_buf[10];
+
+    /* snarf UPDATE message */
     memcpy(&bgp, &pd[offset], sizeof(bgp));
     hlen = ntohs(bgp.bgp_len);
-
     p = &pd[offset + BGP_HEADER_SIZE]; /*XXX*/
+
+    /* check for withdrawals */
+    len = ntohs(*(guint16 *)p);
     proto_tree_add_text(tree, p - pd, 2, 
-       "Unfeasible routes length: %d", len = ntohs(*(guint16 *)p));
-    ti = proto_tree_add_text(tree, p - pd, len,
-           "Withdrawn routes (%u bytes)", len);
-    if (len) {
-       subtree = proto_item_add_subtree(ti, ETT_BGP);
+       "Unfeasible routes length: %u %s", len, (len == 1) ? "byte" : "bytes");
+    if (len > 0) {
+        ti = proto_tree_add_text(tree, p - pd, len, "Withdrawn routes:");
+        /* TODO: unfeasible */
+       subtree = proto_item_add_subtree(ti, ETT_BGP_UNFEAS);
     }
     p += 2 + len;
-    proto_tree_add_text(tree, p - pd, 2, 
-       "Total path attribute length: %d", len = ntohs(*(guint16 *)p));
-    ti = proto_tree_add_text(tree, p - pd + 2, len,
-           "Path attributes (%u bytes)", len);
-    if (len) {
-       subtree = proto_item_add_subtree(ti, ETT_BGP);
+
+    /* check for advertisements */
+    len = ntohs(*(guint16 *)p);
+    proto_tree_add_text(tree, p - pd, 2, "Total path attribute length: %u %s", 
+            len, (len == 1) ? "byte" : "bytes");
+
+    /* path attributes */
+/* --- move --- */
+    if (len > 0) {
+        ti = proto_tree_add_text(tree, p - pd + 2, len, "Path attributes");
+       subtree = proto_item_add_subtree(ti, ETT_BGP_ATTRS);
        i = 2;
        while (i < len) {
            int alen, aoff;
@@ -317,7 +318,7 @@ dissect_bgp_update(const u_char *pd, int offset, frame_data *fd,
            int off, snpa;
 
            memcpy(&bgpa, &p[i], sizeof(bgpa));
-           if (bgpa.bgpa_flags & 0x10) {
+           if (bgpa.bgpa_flags & BGP_ATTR_FLAG_EXTENDED_LENGTH) {
                alen = ntohs(*(guint16 *)&p[i + sizeof(bgpa)]);
                aoff = sizeof(bgpa) + 2;
            } else {
@@ -335,135 +336,167 @@ dissect_bgp_update(const u_char *pd, int offset, frame_data *fd,
                    goto default_attribute_top;
                msg = val_to_str(p[i + aoff], bgpattr_origin, "Unknown");
                ti = proto_tree_add_text(subtree, p - pd + i, alen + aoff,
-                       "Attribute: %s: %s (%u bytes)",
+                       "%s: %s (%u %s)",
                        val_to_str(bgpa.bgpa_type, bgpattr_type, "Unknown"),
-                       msg, alen + aoff);
+                       msg, alen + aoff, (alen + aoff == 1) ? "byte" : 
+                        "bytes");
                break;
            case BGPTYPE_AS_PATH:
-               if (alen % 2)
-                   goto default_attribute_top;
-               msg = dissect_bgp_aspath(p + i + aoff, alen);
-               if (msg == NULL)
+                /* (p + i + 3) =
+                   (p + current attribute + 3 bytes to first tuple) */ 
+                end = p + alen + i + 3;
+                q = p + i + 3;
+                /* must be freed by second case                           */
+                /* "alen * 6" (5 digits + space) should be a good estimate
+                   of how long the AS path string could be                 */
+                as_path_str = malloc(alen * 6);
+                memset(as_path_str, '\0', alen * 6);
+                if (as_path_str == NULL) break;
+   
+                /* snarf each AS path */
+                while (q < end) {
+                    type = *q++;
+                    if (type == AS_SET) {
+                        sprintf(as_path_str, "{");
+                    }
+                    length = *q++;
+
+                    /* snarf each value in path */
+                    for (j = 0; j < length; j++) {
+                        sprintf(junk_buf, "%u%c", pntohs(q), 
+                                (type == AS_SET) ? ',' : ' ');
+                        strcat(as_path_str, junk_buf);
+                        q += 2;
+                    }
+                   
+                    /* cleanup end of string */
+                    if (type == AS_SET) {
+                        as_path_str[strlen(as_path_str) - 1] = '}';
+                        as_path_str[strlen(as_path_str) + 1] = '\0';
+                    }
+                    else {
+                        as_path_str[strlen(as_path_str) - 1] = '\0';
+                    }
+                }
+
+               if (as_path_str[0] == '\0')
                    goto default_attribute_top;
                ti = proto_tree_add_text(subtree, p - pd + i, alen + aoff,
-                       "Attribute: %s: %s (%u bytes)",
+                       "%s: %s (%u %s)",
                        val_to_str(bgpa.bgpa_type, bgpattr_type, "Unknown"),
-                       msg, alen + aoff);
-               free(msg);
+                       as_path_str, alen + aoff, (alen + aoff == 1) ? "byte" :
+                        "bytes");
                break;
            case BGPTYPE_NEXT_HOP:
                if (alen != 4)
                    goto default_attribute_top;
                ti = proto_tree_add_text(subtree, p - pd + i, alen + aoff,
-                       "Attribute: %s: %s (%u bytes)",
+                       "%s: %s (%u %s)",
                        val_to_str(bgpa.bgpa_type, bgpattr_type, "Unknown"),
-                       ip_to_str(&p[i + aoff]), alen + aoff);
+                       ip_to_str(&p[i + aoff]), alen + aoff, (alen + aoff == 1)
+                        ? "byte" : "bytes");
                break;
            case BGPTYPE_MULTI_EXIT_DISC:
                if (alen != 4)
                    goto default_attribute_top;
                ti = proto_tree_add_text(subtree, p - pd + i, alen + aoff,
-                       "Attribute: %s: %u (%u bytes)",
+                       "%s: %u (%u %s)",
                        val_to_str(bgpa.bgpa_type, bgpattr_type, "Unknown"),
-                       ntohl(*(guint32 *)&p[i + aoff]),
-                       alen + aoff);
+                       ntohl(*(guint32 *)&p[i + aoff]), alen + aoff, 
+                        (alen + aoff == 1) ? "byte" : "bytes");
                break;
            case BGPTYPE_LOCAL_PREF:
                if (alen != 4)
                    goto default_attribute_top;
                ti = proto_tree_add_text(subtree, p - pd + i, alen + aoff,
-                       "Attribute: %s: %u (%u bytes)",
+                       "%s: %u (%u %s)",
                        val_to_str(bgpa.bgpa_type, bgpattr_type, "Unknown"),
-                       ntohl(*(guint32 *)&p[i + aoff]),
-                       alen + aoff);
+                       ntohl(*(guint32 *)&p[i + aoff]), alen + aoff,
+                        (alen + aoff == 1) ? "byte" : "bytes");
                break;
-           case BGPTYPE_AGGREGATOR:
-               if (alen != 6)
+            case BGPTYPE_ATOMIC_AGGREGATE:
+                if (alen != 0) 
                    goto default_attribute_top;
                ti = proto_tree_add_text(subtree, p - pd + i, alen + aoff,
-                       "Attribute: %s: AS %u, origin %s (%u bytes)",
+                       "%s: (%u %s)",
                        val_to_str(bgpa.bgpa_type, bgpattr_type, "Unknown"),
-                       ntohs(*(guint16 *)&p[i + aoff]),
-                       ip_to_str(&p[i + aoff + 2]), alen + aoff);
+                       alen + aoff, (alen + aoff == 1) ? "byte" : "bytes");
                break;
            default:
            default_attribute_top:
                ti = proto_tree_add_text(subtree, p - pd + i, alen + aoff,
-                       "Attribute: %s (%u bytes)",
+                       "%s (%u %s)",
                        val_to_str(bgpa.bgpa_type, bgpattr_type, "Unknown"),
-                       alen + aoff);
+                       alen + aoff, (alen + aoff == 1) ? "byte" : "bytes");
            }
-           subtree2 = proto_item_add_subtree(ti, ETT_BGP);
+           subtree2 = proto_item_add_subtree(ti, ETT_BGP_ATTR);
 
+            /* figure out flags */
            ti = proto_tree_add_text(subtree2,
                    p - pd + i + offsetof(struct bgp_attr, bgpa_flags), 1,
                    "Flags: 0x%02x", bgpa.bgpa_flags);
-           subtree3 = proto_item_add_subtree(ti, ETT_BGP);
+           subtree3 = proto_item_add_subtree(ti, ETT_BGP_ATTR_FLAGS);
            proto_tree_add_text(subtree3,
                    p - pd + i + offsetof(struct bgp_attr, bgpa_flags), 1,
                    "%s", decode_boolean_bitfield(bgpa.bgpa_flags,
-                       0x80, 8, "Optional", "not Optional"));
+                       BGP_ATTR_FLAG_OPTIONAL, 8, "Optional", "Well-known"));
            proto_tree_add_text(subtree3,
                    p - pd + i + offsetof(struct bgp_attr, bgpa_flags), 1,
                    "%s", decode_boolean_bitfield(bgpa.bgpa_flags,
-                       0x40, 8, "Transitive", "not Transitive"));
+                       BGP_ATTR_FLAG_TRANSITIVE, 8, "Transitive", 
+                        "Non-transitive"));
            proto_tree_add_text(subtree3,
                    p - pd + i + offsetof(struct bgp_attr, bgpa_flags), 1,
                    "%s", decode_boolean_bitfield(bgpa.bgpa_flags,
-                       0x20, 8, "Partial", "not Partial"));
+                       BGP_ATTR_FLAG_PARTIAL, 8, "Partial", "Complete"));
            proto_tree_add_text(subtree3,
                    p - pd + i + offsetof(struct bgp_attr, bgpa_flags), 1,
                    "%s", decode_boolean_bitfield(bgpa.bgpa_flags,
-                       0x10, 8, "Extended length", "not Extended length"));
+                       BGP_ATTR_FLAG_EXTENDED_LENGTH, 8, "Extended length", 
+                        "Regular length"));
 
            proto_tree_add_text(subtree2,
                    p - pd + i + offsetof(struct bgp_attr, bgpa_type), 1,
-                   "Type code: %s (0x%02x)",
+                   "Type code: %s (%u)",
                    val_to_str(bgpa.bgpa_type, bgpattr_type, "Unknown"),
                    bgpa.bgpa_type);
-
-           if (bgpa.bgpa_flags & 0x10) {
+            
+            /* check for the Extended Length bit */
+           if (bgpa.bgpa_flags & BGP_ATTR_FLAG_EXTENDED_LENGTH) {
                proto_tree_add_text(subtree2,
                        p - pd + i + sizeof(bgpa), aoff - sizeof(bgpa),
-                       "Attribute length: %d", alen);
+                       "Length: %d %s", alen, 
+                        (alen == 1) ? "byte" : "bytes");
            } else {
                proto_tree_add_text(subtree2,
                        p - pd + i + sizeof(bgpa), aoff - sizeof(bgpa),
-                       "Attribute length: %d", alen);
+                       "Length: %d %s", alen,
+                        (alen == 1) ? "byte" : "bytes");
            }
 
            switch (bgpa.bgpa_type) {
            case BGPTYPE_ORIGIN:
                if (alen != 1) {
                    proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
-                           "Origin: Invalid (%d bytes)", alen);
+                           "Origin (invalid): %u %s", alen,
+                             (alen == 1) ? "byte" : "bytes");
                } else {
                    msg = val_to_str(p[i + aoff], bgpattr_origin, "Unknown");
                    proto_tree_add_text(subtree2, p - pd + i + aoff, 1,
-                           "Origin: %s (0x%02x)", msg, p[i + aoff]);
+                           "Origin: %s (%u)", msg, p[i + aoff]);
                }
                break;
            case BGPTYPE_AS_PATH:
-               if (alen % 2) {
-                   proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
-                           "AS path: Invalid (%d bytes)", alen);
-               } else {
-                   msg = dissect_bgp_aspath(p + i + aoff, alen);
-                   if (msg == NULL) {
-                       proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
-                               "AS path (%d bytes)", alen);
-                   } else {
-                       proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
-                               "AS path: %s (%d ASes, %d bytes)",
-                               msg, alen / 2, alen);
-                       free(msg);
-                   }
-               }
+               proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
+                        "AS path: %s (%u %s)", as_path_str, alen, 
+                        (alen == 1) ? "byte" : "bytes");
+                free(as_path_str);
                break;
            case BGPTYPE_NEXT_HOP:
                if (alen != 4) {
                    proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
-                           "Next hop: Invalid (%d bytes)", alen);
+                           "Next hop (invalid): %u %s", alen,
+                            (alen == 1) ? "byte" : "bytes");
                } else {
                    proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
                            "Next hop: %s", ip_to_str(&p[i + aoff]));
@@ -472,8 +505,8 @@ dissect_bgp_update(const u_char *pd, int offset, frame_data *fd,
            case BGPTYPE_MULTI_EXIT_DISC:
                if (alen != 4) {
                    proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
-                           "Multi exit discriminator: Invalid (%d bytes)",
-                           alen);
+                           "Multi exit discriminator (invalid): %u %s",
+                           alen, (alen == 1) ? "byte" : "bytes");
                } else {
                    proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
                            "Multi exit discriminator: %u",
@@ -483,7 +516,8 @@ dissect_bgp_update(const u_char *pd, int offset, frame_data *fd,
            case BGPTYPE_LOCAL_PREF:
                if (alen != 4) {
                    proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
-                           "Local preference: Invalid (%d bytes)", alen);
+                           "Local preference (invalid): %u %s", alen,
+                             (alen == 1) ? "byte" : "bytes");
                } else {
                    proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
                            "Local preference: %u",
@@ -493,7 +527,8 @@ dissect_bgp_update(const u_char *pd, int offset, frame_data *fd,
            case BGPTYPE_ATOMIC_AGGREGATE:
                if (alen != 0) {
                    proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
-                           "Atomic aggregate: Invalid (%d bytes)", alen);
+                           "Atomic aggregate (invalid): %u %s", alen,
+                            (alen == 1) ? "byte" : "bytes");
                } else {
                    proto_tree_add_text(subtree2, p - pd + i + aoff, 0,
                            "Atomic aggregate");
@@ -502,7 +537,8 @@ dissect_bgp_update(const u_char *pd, int offset, frame_data *fd,
            case BGPTYPE_AGGREGATOR:
                if (alen != 6) {
                    proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
-                           "Aggregator: Invalid (%d bytes)", alen);
+                           "Aggregator (invalid): %u %s", alen,
+                            (alen == 1) ? "byte" : "bytes");
                } else {
                    proto_tree_add_text(subtree2, p - pd + i + aoff, 2,
                            "Aggregator AS: %u",
@@ -523,13 +559,14 @@ dissect_bgp_update(const u_char *pd, int offset, frame_data *fd,
                        p[i + aoff + 2] >= 128 ? "Vendor specific" : "Unknown"),
                    p[i + aoff + 2]);
                ti = proto_tree_add_text(subtree2, p - pd + i + aoff + 3, 1,
-                       "Next hop network address (%d bytes)",
-                       p[i + aoff + 3]);
+                       "Next hop network address (%d %s)",
+                       p[i + aoff + 3], (p[i + aoff + 3] == 1) ? "byte" : 
+                        "bytes");
                if (af == AFNUM_INET || af == AFNUM_INET6) {
                    int j, advance;
                    const char *s;
 
-                   subtree3 = proto_item_add_subtree(ti, ETT_BGP);
+                   subtree3 = proto_item_add_subtree(ti, ETT_BGP_MP_REACH_NLRI);
 
                    j = 0;
                    while (j < p[i + aoff + 3]) {
@@ -563,24 +600,25 @@ dissect_bgp_update(const u_char *pd, int offset, frame_data *fd,
                        "Subnetwork points of attachment: %u", snpa);
                off++;
                if (snpa)
-                   subtree3 = proto_item_add_subtree(ti, ETT_BGP);
+                   subtree3 = proto_item_add_subtree(ti, ETT_BGP_MP_REACH_NLRI);
                for (/*nothing*/; snpa > 0; snpa--) {
                    proto_tree_add_text(subtree3, p - pd + i + aoff + off, 1,
                        "SNPA length: ", p[i + aoff + off]);
                    off++;
                    proto_tree_add_text(subtree3, p - pd + i + aoff + off,
                        p[i + aoff + off - 1],
-                       "SNPA (%u bytes)", p[i + aoff + off - 1]);
+                       "SNPA (%u %s)", p[i + aoff + off - 1],
+                        (p[i + aoff + off - 1] == 1) ? "byte" : "bytes");
                    off += p[i + aoff + off - 1];
                }
 
                alen -= off;
                aoff += off;
                ti = proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
-                       "Network Layer Reachability Information (%u bytes)",
-                       alen);
+                       "Network Layer Reachability Information (%u %s)",
+                       alen, (alen == 1) ? "byte" : "bytes");
                if (alen)
-                   subtree3 = proto_item_add_subtree(ti, ETT_BGP);
+                   subtree3 = proto_item_add_subtree(ti, ETT_BGP_MP_UNREACH_NLRI);
                while (alen > 0) {
                    int advance;
                    char buf[256];
@@ -616,12 +654,13 @@ dissect_bgp_update(const u_char *pd, int offset, frame_data *fd,
                        p[i + aoff + 2] >= 128 ? "Vendor specific" : "Unknown"),
                    p[i + aoff + 2]);
                ti = proto_tree_add_text(subtree2, p - pd + i + aoff + 3,
-                       alen - 3, "Withdrawn Routes (%u bytes)", alen - 3);
+                       alen - 3, "Withdrawn Routes (%u %s)", alen - 3,
+                        (alen - 3 == 1) ? "byte" : "bytes");
 
                alen -= 3;
                aoff += 3;
                if (alen > 0)
-                   subtree3 = proto_item_add_subtree(ti, ETT_BGP);
+                   subtree3 = proto_item_add_subtree(ti, ETT_BGP_MP_UNREACH_NLRI);
                while (alen > 0) {
                    int advance;
                    char buf[256];
@@ -648,19 +687,40 @@ dissect_bgp_update(const u_char *pd, int offset, frame_data *fd,
                break;
            default:
                proto_tree_add_text(subtree2, p - pd + i + aoff, alen,
-                       "Unknown (%d bytes)", alen);
+                       "Unknown (%d %s)", alen, (alen == 1) ? "byte" : 
+                        "bytes");
                break;
            }
 
            i += alen + aoff;
        }
-    }
-    p += 2 + len;
-    len = hlen - (p - &pd[offset]);
-    ti = proto_tree_add_text(tree, p - pd, len,
-           "Network layer reachability information (%d bytes)", len);
-    if (len) {
-       subtree = proto_item_add_subtree(ti, ETT_BGP);
+/* --- move --- */
+        p += 2 + len;
+
+        /* NLRI */
+        len = hlen - (p - &pd[offset]);
+        ti = proto_tree_add_text(tree, p - pd, len,
+                "Network layer reachability information: %u %s", len,
+                (len == 1) ? "byte" : "bytes");
+
+        if (len > 0) {
+           subtree = proto_item_add_subtree(ti, ETT_BGP_NLRI);
+
+            /* parse prefixes */
+            end = p + len;
+            while (p < end) {
+                memset(&prefix, 0, sizeof(prefix));
+                /* snarf length */
+                length = *p;
+                i = convert_prefix(length);
+                p++;
+                /* snarf prefix */
+                memcpy(&prefix, p, i);
+                proto_tree_add_text(subtree, p - pd - 1, i + 1, "%s/%d", 
+                        inet_ntoa(prefix), length);
+                p += i;
+            }
+        }
     }
 }
 
index 620003557d00870e5acad13f5809124bc8963a70..2239aecbbedc1b22f70829f24783229292d5ef05 100644 (file)
@@ -1,7 +1,7 @@
 /* packet-bgp.c
  * Definitions for BGP packet disassembly structures and routine
  *
- * $Id: packet-bgp.h,v 1.3 1999/11/06 01:28:50 itojun Exp $
+ * $Id: packet-bgp.h,v 1.4 1999/11/11 21:08:52 itojun Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@unicom.net>
@@ -25,9 +25,6 @@
 #ifndef __PACKET_BGP_H__
 #define __PACKET_BGP_H__
 
-#include "packet.h"
-#include "packet-ipv6.h"
-
 /* some handy things to know */
 #define BGP_MAX_PACKET_SIZE            4096
 #define BGP_MARKER_SIZE                        16
@@ -75,6 +72,16 @@ struct bgp_attr {
     guint8 bgpa_type;
 };
 
+/* attribute flags, from RFC 1771 */
+#define BGP_ATTR_FLAG_OPTIONAL        0x80
+#define BGP_ATTR_FLAG_TRANSITIVE      0x40
+#define BGP_ATTR_FLAG_PARTIAL         0x20
+#define BGP_ATTR_FLAG_EXTENDED_LENGTH 0x10
+
+/* AS_PATH segment types, from RFC 1771 */
+#define AS_SET      1
+#define AS_SEQUENCE 2
+
 #define BGPTYPE_ORIGIN            1   /* RFC1771          */
 #define BGPTYPE_AS_PATH           2   /* RFC1771          */
 #define BGPTYPE_NEXT_HOP          3   /* RFC1771          */
@@ -118,4 +125,9 @@ do {                                \
 #define offsetof(type, member)  ((size_t)(&((type *)0)->member))
 #endif
 
+/*
+ * Convert prefix length into number of guint8s needed for prefix.
+ */
+#define convert_prefix(p) (((p) + 7) / (8))
+
 #endif
index 75242963831a2befda4183c76b00b58557b8b4a1..526af23b3fb062d5125d3f63d76eee7f84fd79c2 100644 (file)
--- a/packet.h
+++ b/packet.h
@@ -1,7 +1,7 @@
 /* packet.h
  * Definitions for packet disassembly structures and routines
  *
- * $Id: packet.h,v 1.134 1999/11/11 08:35:10 guy Exp $
+ * $Id: packet.h,v 1.135 1999/11/11 21:08:52 itojun Exp $
  *
  * Ethereal - Network traffic analyzer
  * By Gerald Combs <gerald@zing.org>
@@ -285,7 +285,11 @@ enum {
        ETT_BGP_NOTIFICATION,
        ETT_BGP_ATTRS,
        ETT_BGP_ATTR,
+       ETT_BGP_ATTR_FLAGS,
+       ETT_BGP_UNFEAS,
        ETT_BGP_NLRI,
+       ETT_BGP_MP_REACH_NLRI,
+       ETT_BGP_MP_UNREACH_NLRI,
        ETT_CLNP,
        ETT_COTP,
        ETT_VINES_FRP,