summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Mares <mj@ucw.cz>2000-04-17 12:18:55 +0200
committerMartin Mares <mj@ucw.cz>2000-04-17 12:18:55 +0200
commitc6add07fa6ca8366fbdcfcd9bc2872c129378366 (patch)
tree326030c1a1798b35c68ef11428461dd7a60e02cd
parentafc54517db6946e9cfb62bbdc855954316152c62 (diff)
downloadbird-c6add07fa6ca8366fbdcfcd9bc2872c129378366.tar
bird-c6add07fa6ca8366fbdcfcd9bc2872c129378366.zip
Printing of AS paths and community sets.
-rw-r--r--nest/a-path.c45
-rw-r--r--nest/a-set.c28
-rw-r--r--nest/attrs.h8
-rw-r--r--nest/route.h1
-rw-r--r--nest/rt-attr.c28
5 files changed, 100 insertions, 10 deletions
diff --git a/nest/a-path.c b/nest/a-path.c
index 557f29c..ca39e29 100644
--- a/nest/a-path.c
+++ b/nest/a-path.c
@@ -9,8 +9,10 @@
#include "nest/bird.h"
#include "nest/route.h"
+#include "nest/attrs.h"
#include "lib/resource.h"
#include "lib/unaligned.h"
+#include "lib/string.h"
struct adata *
as_path_prepend(struct linpool *pool, struct adata *olda, int as)
@@ -36,3 +38,46 @@ as_path_prepend(struct linpool *pool, struct adata *olda, int as)
put_u16(newa->data+2, as);
return newa;
}
+
+void
+as_path_format(struct adata *path, byte *buf, unsigned int size)
+{
+ byte *p = path->data;
+ byte *e = p + path->length - 8;
+ byte *end = buf + size;
+ int sp = 1;
+ int l, type, isset, as;
+
+ while (p < e)
+ {
+ if (buf > end)
+ {
+ strcpy(buf, " ...");
+ return;
+ }
+ isset = (*p++ == AS_PATH_SET);
+ l = *p++;
+ if (isset)
+ {
+ if (!sp)
+ *buf++ = ' ';
+ *buf++ = '{';
+ sp = 0;
+ }
+ while (l-- && buf <= end)
+ {
+ if (!sp)
+ *buf++ = ' ';
+ buf += bsprintf(buf, "%d", get_u16(p));
+ p += 2;
+ sp = 0;
+ }
+ if (isset)
+ {
+ *buf++ = ' ';
+ *buf++ = '}';
+ sp = 0;
+ }
+ }
+ *buf = 0;
+}
diff --git a/nest/a-set.c b/nest/a-set.c
index 7c7d689..deef5df 100644
--- a/nest/a-set.c
+++ b/nest/a-set.c
@@ -9,4 +9,32 @@
#include "nest/bird.h"
#include "nest/route.h"
+#include "nest/attrs.h"
#include "lib/resource.h"
+#include "lib/string.h"
+
+void
+int_set_format(struct adata *set, byte *buf, unsigned int size)
+{
+ u32 *z = (u32 *) set->data;
+ int l = set->length / 4;
+ int sp = 1;
+ byte *end = buf + size - 16;
+
+ while (l--)
+ {
+ if (sp)
+ {
+ sp = 0;
+ *buf++ = ' ';
+ }
+ if (buf > end)
+ {
+ strcpy(buf, "...");
+ return;
+ }
+ buf += bsprintf(buf, "%d:%d", *z/65536, *z & 0xffff);
+ z++;
+ }
+ *buf = 0;
+}
diff --git a/nest/attrs.h b/nest/attrs.h
index c1a96f9..fc960fb 100644
--- a/nest/attrs.h
+++ b/nest/attrs.h
@@ -12,5 +12,13 @@
/* a-path.c */
struct adata *as_path_prepend(struct linpool *pool, struct adata *olda, int as);
+void as_path_format(struct adata *path, byte *buf, unsigned int size);
+
+#define AS_PATH_SET 1 /* Types of path segments */
+#define AS_PATH_SEQUENCE 2
+
+/* a-set.c */
+
+void int_set_format(struct adata *set, byte *buf, unsigned int size);
#endif
diff --git a/nest/route.h b/nest/route.h
index 6aa035d..a7879c1 100644
--- a/nest/route.h
+++ b/nest/route.h
@@ -325,6 +325,7 @@ void ea_merge(ea_list *from, ea_list *to); /* Merge sub-lists to allocated buffe
int ea_same(ea_list *x, ea_list *y); /* Test whether two ea_lists are identical */
unsigned int ea_hash(ea_list *e); /* Calculate 16-bit hash value */
void ea_format(eattr *e, byte *buf);
+#define EA_FORMAT_BUF_SIZE 256
void rta_init(void);
rta *rta_lookup(rta *); /* Get rta equivalent to this one, uc++ */
diff --git a/nest/rt-attr.c b/nest/rt-attr.c
index 97cd70b..c16d08b 100644
--- a/nest/rt-attr.c
+++ b/nest/rt-attr.c
@@ -13,6 +13,7 @@
#include "nest/protocol.h"
#include "nest/iface.h"
#include "nest/cli.h"
+#include "nest/attrs.h"
#include "lib/resource.h"
#include "lib/string.h"
@@ -240,8 +241,9 @@ ea_format(eattr *e, byte *buf)
{
struct protocol *p;
int status = GA_UNKNOWN;
- unsigned int i, l;
+ unsigned int i;
struct adata *ad = (e->type & EAF_EMBEDDED) ? NULL : e->u.ptr;
+ byte *end = buf + EA_FORMAT_BUF_SIZE - 1;
if (p = attr_class_to_protocol[EA_PROTO(e->id)])
{
@@ -264,15 +266,17 @@ ea_format(eattr *e, byte *buf)
bsprintf(buf, "%d", e->u.data);
break;
case EAF_TYPE_OPAQUE:
- l = (ad->length < 16) ? ad->length : 16;
- for(i=0; i<l; i++)
+ for(i=0; i<ad->length; i++)
{
- buf += bsprintf(buf, "%02x", ad->data[i]);
- if (i < l)
+ if (buf > end - 8)
+ {
+ strcpy(buf, " ...");
+ break;
+ }
+ if (i)
*buf++ = ' ';
+ buf += bsprintf(buf, "%02x", ad->data[i]);
}
- if (l < ad->length)
- strcpy(buf, "...");
break;
case EAF_TYPE_IP_ADDRESS:
bsprintf(buf, "%I", *(ip_addr *) ad->data);
@@ -280,8 +284,12 @@ ea_format(eattr *e, byte *buf)
case EAF_TYPE_ROUTER_ID:
bsprintf(buf, "%08x", e->u.data); /* FIXME: Better printing of router ID's */
break;
- case EAF_TYPE_AS_PATH: /* FIXME */
- case EAF_TYPE_INT_SET: /* FIXME */
+ case EAF_TYPE_AS_PATH:
+ as_path_format(ad, buf, end - buf);
+ break;
+ case EAF_TYPE_INT_SET:
+ int_set_format(ad, buf, end - buf);
+ break;
case EAF_TYPE_UNDEF:
default:
bsprintf(buf, "<type %02x>", e->type);
@@ -542,7 +550,7 @@ rta_show(struct cli *c, rta *a)
static char *cast_names[] = { "unicast", "broadcast", "multicast", "anycast" };
ea_list *eal;
int i;
- byte buf[256];
+ byte buf[EA_FORMAT_BUF_SIZE];
cli_printf(c, -1008, "\tType: %s %s %s", src_names[a->source], cast_names[a->cast], ip_scope_text(a->scope));
for(eal=a->eattrs; eal; eal=eal->next)