From 3991d84e8fa9118a43149d4d3304726eb786bd46 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Sat, 1 Apr 2000 10:19:47 +0000 Subject: Changed initialization of protocol list -- now we call proto_build() instead of calling the protocols manually. Implemented printing of dynamic attributes in `show route all'. Each protocol can now register its own attribute class (protocol->attr_class, set to EAP_xxx) and also a callback for naming and formatting of attributes. The callback can return one of the following results: GA_UNKNOWN Attribute not recognized. GA_NAME Attribute name recognized and put to the buffer, generic code should format the value. GA_FULL Both attribute name and value put to the buffer. Please update protocols generating dynamic attributes to provide the attr_class and formatting hook. --- nest/rt-attr.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 65 insertions(+), 1 deletion(-) (limited to 'nest/rt-attr.c') diff --git a/nest/rt-attr.c b/nest/rt-attr.c index 63f596e..57c98b2 100644 --- a/nest/rt-attr.c +++ b/nest/rt-attr.c @@ -19,6 +19,8 @@ static slab *rta_slab; static pool *rta_pool; +struct protocol *attr_class_to_protocol[EAP_MAX]; + /* * Extended Attributes */ @@ -233,6 +235,60 @@ ea_list_copy(ea_list *o) return n; } +void +ea_format(eattr *e, byte *buf) +{ + struct protocol *p; + int status = GA_UNKNOWN; + unsigned int i, l; + struct adata *ad = (e->type & EAF_EMBEDDED) ? NULL : e->u.ptr; + + if (p = attr_class_to_protocol[EA_PROTO(e->id)]) + { + buf += bsprintf(buf, "%s.", p->name); + if (p->get_attr) + status = p->get_attr(e, buf); + buf += strlen(buf); + } + else if (EA_PROTO(e->id)) + buf += bsprintf(buf, "%02x.", EA_PROTO(e->id)); + if (status < GA_NAME) + buf += bsprintf(buf, "%02x", EA_ID(e->id)); + if (status < GA_FULL) + { + *buf++ = ':'; + *buf++ = ' '; + switch (e->type & EAF_TYPE_MASK) + { + case EAF_TYPE_INT: + bsprintf(buf, "%d", e->u.data); + break; + case EAF_TYPE_OPAQUE: + l = (ad->length < 16) ? ad->length : 16; + for(i=0; idata[i]); + if (i < l) + *buf++ = ' '; + } + if (l < ad->length) + strcpy(buf, "..."); + break; + case EAF_TYPE_IP_ADDRESS: + bsprintf(buf, "%I", *(ip_addr *) ad->data); + break; + 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_UNDEF: + default: + bsprintf(buf, "", e->type); + } + } +} + void ea_dump(ea_list *e) { @@ -484,9 +540,17 @@ rta_show(struct cli *c, rta *a) "RIP", "RIP-ext", "OSPF", "OSPF-ext", "OSPF-IA", "OSPF-boundary", "BGP" }; static char *cast_names[] = { "unicast", "broadcast", "multicast", "anycast" }; + ea_list *eal; + int i; + byte buf[256]; cli_printf(c, -1008, "\tType: %s %s %s", src_names[a->source], cast_names[a->cast], ip_scope_text(a->scope)); - /* FIXME: Here we probably should print the dynamic attributes... */ + for(eal=a->eattrs; eal; eal=eal->next) + for(i=0; icount; i++) + { + ea_format(&eal->attrs[i], buf); + cli_printf(c, -1012, "\t%s", buf); + } } void -- cgit v1.2.3