diff options
Diffstat (limited to 'usr.sbin/bgpd')
-rw-r--r-- | usr.sbin/bgpd/rde.h | 7 | ||||
-rw-r--r-- | usr.sbin/bgpd/rde_attr.c | 104 |
2 files changed, 107 insertions, 4 deletions
diff --git a/usr.sbin/bgpd/rde.h b/usr.sbin/bgpd/rde.h index 5ef22236f3a..877161dfaa8 100644 --- a/usr.sbin/bgpd/rde.h +++ b/usr.sbin/bgpd/rde.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rde.h,v 1.24 2004/02/16 12:53:15 claudio Exp $ */ +/* $OpenBSD: rde.h,v 1.25 2004/02/16 12:58:45 claudio Exp $ */ /* * Copyright (c) 2003, 2004 Claudio Jeker <claudio@openbsd.org> and @@ -211,7 +211,7 @@ void rde_send_nexthop(struct bgpd_addr *, int); void rde_generate_updates(struct prefix *, struct prefix *); u_int16_t rde_local_as(void); -/* rde_rib.c */ +/* rde_attr.c */ void attr_init(struct attr_flags *); int attr_parse(u_char *, u_int16_t, struct attr_flags *, int, u_int16_t); @@ -239,7 +239,10 @@ u_int16_t aspath_count(struct aspath *); u_int16_t aspath_neighbour(struct aspath *); u_int32_t aspath_hash(struct aspath *); int aspath_compare(struct aspath *, struct aspath *); +int aspath_snprint(char *, size_t, void *, u_int16_t); +size_t aspath_strlen(void *, u_int16_t); +/* rde_rib.c */ void path_init(u_int32_t); void path_update(struct rde_peer *, struct attr_flags *, struct bgpd_addr *, int); diff --git a/usr.sbin/bgpd/rde_attr.c b/usr.sbin/bgpd/rde_attr.c index 57839c68ff1..3e7879d9b1d 100644 --- a/usr.sbin/bgpd/rde_attr.c +++ b/usr.sbin/bgpd/rde_attr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rde_attr.c,v 1.3 2004/02/16 12:53:15 claudio Exp $ */ +/* $OpenBSD: rde_attr.c,v 1.4 2004/02/16 12:58:45 claudio Exp $ */ /* * Copyright (c) 2004 Claudio Jeker <claudio@openbsd.org> @@ -20,6 +20,7 @@ #include <sys/queue.h> #include <stdlib.h> +#include <stdio.h> #include <string.h> #include "bgpd.h" @@ -393,7 +394,7 @@ attr_optadd(struct attr_flags *attr, u_int8_t flags, u_int8_t type, void attr_optfree(struct attr_flags *attr) { - struct attr *a, *xa; + struct attr *a; while ((a = TAILQ_FIRST(&attr->others)) != NULL) { TAILQ_REMOVE(&attr->others, a, attr_l); @@ -665,3 +666,102 @@ aspath_compare(struct aspath *a1, struct aspath *a2) return 0; } +int +aspath_snprint(char *buf, size_t size, void *data, u_int16_t len) +{ +#define UPDATE() \ + do { \ + if (r == -1) \ + return (1); \ + total_size += r; \ + if ((unsigned int)r < size) { \ + size -= r; \ + buf += r; \ + } else { \ + buf += size; \ + size = 0; \ + } \ + } while (0) + u_int8_t *seg; + int r, total_size; + u_int16_t seg_size; + u_int8_t i, seg_type, seg_len; + + total_size = 0; + seg = data; + for (; len > 0; len -= seg_size, seg += seg_size) { + seg_type = seg[0]; + seg_len = seg[1]; + ENSURE(seg_type == AS_SET || seg_type == AS_SEQUENCE); + seg_size = 2 + 2 * seg_len; + + if (seg_type == AS_SET) { + r = snprintf(buf, size, "{ "); + UPDATE(); + } else if (total_size != 0) { + r = snprintf(buf, size, " "); + UPDATE(); + } + + ENSURE(seg_size <= len); + for (i = 0; i < seg_len; i++) { + r = snprintf(buf, size, "%hu", aspath_extract(seg, i)); + UPDATE(); + if (i + 1 < seg_len) { + r = snprintf(buf, size, " "); + UPDATE(); + } + } + if (seg_type == AS_SET) { + r = snprintf(buf, size, " }"); + UPDATE(); + } + } + return total_size; +#undef UPDATE +} + +size_t +aspath_strlen(void *data, u_int16_t len) +{ + u_int8_t *seg; + int total_size; + u_int16_t as, seg_size; + u_int8_t i, seg_type, seg_len; + + total_size = 0; + seg = data; + for (; len > 0; len -= seg_size, seg += seg_size) { + seg_type = seg[0]; + seg_len = seg[1]; + ENSURE(seg_type == AS_SET || seg_type == AS_SEQUENCE); + seg_size = 2 + 2 * seg_len; + + if (seg_type == AS_SET) + total_size += 2; + else if (total_size != 0) + total_size += 1; + + ENSURE(seg_size <= len); + for (i = 0; i < seg_len; i++) { + as = aspath_extract(seg, i); + if (as >= 10000) + total_size += 5; + else if (as >= 1000) + total_size += 4; + else if (as >= 100) + total_size += 3; + else if (as >= 10) + total_size += 2; + else + total_size += 1; + + if (i + 1 < seg_len) + total_size += 1; + } + + if (seg_type == AS_SET) + total_size += 2; + } + return total_size; +} |