summaryrefslogtreecommitdiff
path: root/usr.sbin/bgpd/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'usr.sbin/bgpd/util.c')
-rw-r--r--usr.sbin/bgpd/util.c108
1 files changed, 106 insertions, 2 deletions
diff --git a/usr.sbin/bgpd/util.c b/usr.sbin/bgpd/util.c
index b361b8c3a7c..3db16447dbf 100644
--- a/usr.sbin/bgpd/util.c
+++ b/usr.sbin/bgpd/util.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.c,v 1.6 2009/06/12 16:42:53 claudio Exp $ */
+/* $OpenBSD: util.c,v 1.7 2009/12/01 14:28:05 claudio Exp $ */
/*
* Copyright (c) 2006 Claudio Jeker <claudio@openbsd.org>
@@ -33,7 +33,7 @@ log_addr(const struct bgpd_addr *addr)
{
static char buf[48];
- if (inet_ntop(addr->af, &addr->ba, buf, sizeof(buf)) == NULL)
+ if (inet_ntop(aid2af(addr->aid), &addr->ba, buf, sizeof(buf)) == NULL)
return ("?");
else
return (buf);
@@ -276,3 +276,107 @@ inet6applymask(struct in6_addr *dest, const struct in6_addr *src, int prefixlen)
for (i = 0; i < 16; i++)
dest->s6_addr[i] = src->s6_addr[i] & mask.s6_addr[i];
}
+
+/* address family translation functions */
+const struct aid aid_vals[AID_MAX] = AID_VALS;
+
+int
+aid2afi(u_int8_t aid, u_int16_t *afi, u_int8_t *safi)
+{
+ if (aid < AID_MAX) {
+ *afi = aid_vals[aid].afi;
+ *safi = aid_vals[aid].safi;
+ return (0);
+ }
+ return (-1);
+}
+
+int
+afi2aid(u_int16_t afi, u_int8_t safi, u_int8_t *aid)
+{
+ u_int8_t i;
+
+ for (i = 0; i < AID_MAX; i++)
+ if (aid_vals[i].afi == afi && aid_vals[i].safi == safi) {
+ *aid = i;
+ return (0);
+ }
+
+ return (-1);
+}
+
+sa_family_t
+aid2af(u_int8_t aid)
+{
+ if (aid < AID_MAX)
+ return (aid_vals[aid].af);
+ return (AF_UNSPEC);
+}
+
+int
+af2aid(sa_family_t af, u_int8_t safi, u_int8_t *aid)
+{
+ u_int8_t i;
+
+ if (safi == 0) /* default to unicast subclass */
+ safi = SAFI_UNICAST;
+
+ for (i = 0; i < AID_MAX; i++)
+ if (aid_vals[i].af == af && aid_vals[i].safi == safi) {
+ *aid = i;
+ return (0);
+ }
+
+ return (-1);
+}
+
+struct sockaddr *
+addr2sa(struct bgpd_addr *addr, u_int16_t port)
+{
+ static struct sockaddr_storage ss;
+ struct sockaddr_in *sa_in = (struct sockaddr_in *)&ss;
+ struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)&ss;
+
+ if (addr->aid == AID_UNSPEC)
+ return (NULL);
+
+ bzero(&ss, sizeof(ss));
+ switch (addr->aid) {
+ case AID_INET:
+ sa_in->sin_family = AF_INET;
+ sa_in->sin_len = sizeof(struct sockaddr_in);
+ sa_in->sin_addr.s_addr = addr->v4.s_addr;
+ sa_in->sin_port = htons(port);
+ break;
+ case AID_INET6:
+ sa_in6->sin6_family = AF_INET6;
+ sa_in6->sin6_len = sizeof(struct sockaddr_in6);
+ memcpy(&sa_in6->sin6_addr, &addr->v6,
+ sizeof(sa_in6->sin6_addr));
+ sa_in6->sin6_port = htons(port);
+ sa_in6->sin6_scope_id = addr->scope_id;
+ break;
+ }
+
+ return ((struct sockaddr *)&ss);
+}
+
+void
+sa2addr(struct sockaddr *sa, struct bgpd_addr *addr)
+{
+ struct sockaddr_in *sa_in = (struct sockaddr_in *)sa;
+ struct sockaddr_in6 *sa_in6 = (struct sockaddr_in6 *)sa;
+
+ bzero(addr, sizeof(*addr));
+ switch (sa->sa_family) {
+ case AF_INET:
+ addr->aid = AID_INET;
+ memcpy(&addr->v4, &sa_in->sin_addr, sizeof(addr->v4));
+ break;
+ case AF_INET6:
+ addr->aid = AID_INET6;
+ memcpy(&addr->v6, &sa_in6->sin6_addr, sizeof(addr->v6));
+ addr->scope_id = sa_in6->sin6_scope_id; /* I hate v6 */
+ break;
+ }
+}