From c6add07fa6ca8366fbdcfcd9bc2872c129378366 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Mon, 17 Apr 2000 10:18:55 +0000 Subject: [PATCH] Printing of AS paths and community sets. --- nest/a-path.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ nest/a-set.c | 28 ++++++++++++++++++++++++++++ nest/attrs.h | 8 ++++++++ nest/route.h | 1 + nest/rt-attr.c | 28 ++++++++++++++++++---------- 5 files changed, 100 insertions(+), 10 deletions(-) diff --git a/nest/a-path.c b/nest/a-path.c index 557f29c2..ca39e296 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 7c7d6894..deef5df8 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 c1a96f95..fc960fb5 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 6aa035db..a7879c14 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 97cd70bc..c16d08ba 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; ilength; 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, "", 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)