summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorChris Hall <GMCH@hestia.halldom.com>2010-02-04 14:28:35 +0000
committerChris Hall <GMCH@hestia.halldom.com>2010-02-04 14:28:35 +0000
commitd8921b6522d8b55f3de87f90c4cdc0755acf8c7f (patch)
treeff4a9c0f119e08b4f58bce905e72ad7a05c6867d /lib
parent8f50e8a0730a3feb670da99e979ed4c415ad5543 (diff)
downloadquagga-d8921b6522d8b55f3de87f90c4cdc0755acf8c7f.tar.bz2
quagga-d8921b6522d8b55f3de87f90c4cdc0755acf8c7f.tar.xz
Review and tidy new code and comments.
Follows David Lamparter's code for update-source handling. modified: bgpd/bgp_connection.c modified: bgpd/bgp_connection.h modified: bgpd/bgp_fsm.c modified: bgpd/bgp_fsm.h modified: bgpd/bgp_msg_read.c modified: bgpd/bgp_msg_read.h modified: bgpd/bgp_notification.c modified: bgpd/bgp_notification.h modified: bgpd/bgp_peer.c modified: bgpd/bgp_peer.h modified: bgpd/bgp_session.c modified: bgpd/bgp_session.h modified: lib/prefix.c modified: lib/prefix.h
Diffstat (limited to 'lib')
-rw-r--r--lib/prefix.c54
-rw-r--r--lib/prefix.h2
2 files changed, 56 insertions, 0 deletions
diff --git a/lib/prefix.c b/lib/prefix.c
index 6399788c..7755d4e7 100644
--- a/lib/prefix.c
+++ b/lib/prefix.c
@@ -180,6 +180,46 @@ prefix_cmp (const struct prefix *p1, const struct prefix *p2)
return 0;
}
+/*
+ * Count the number of common bits in 2 prefixes. The prefix length is
+ * ignored for this function; the whole prefix is compared. If the prefix
+ * address families don't match, return -1; otherwise the return value is
+ * in range 0 ... maximum prefix length for the address family.
+ */
+int
+prefix_common_bits (const struct prefix *p1, const struct prefix *p2)
+{
+ int pos, bit;
+ int length = 0;
+ u_char xor;
+
+ /* Set both prefix's head pointer. */
+ const u_char *pp1 = (const u_char *)&p1->u.prefix;
+ const u_char *pp2 = (const u_char *)&p2->u.prefix;
+
+ if (p1->family == AF_INET)
+ length = IPV4_MAX_BYTELEN;
+#ifdef HAVE_IPV6
+ if (p1->family == AF_INET6)
+ length = IPV6_MAX_BYTELEN;
+#endif
+ if (p1->family != p2->family || !length)
+ return -1;
+
+ for (pos = 0; pos < length; pos++)
+ if (pp1[pos] != pp2[pos])
+ break;
+ if (pos == length)
+ return pos * 8;
+
+ xor = pp1[pos] ^ pp2[pos];
+ for (bit = 0; bit < 8; bit++)
+ if (xor & (1 << (7 - bit)))
+ break;
+
+ return pos * 8 + bit;
+}
+
/* Return prefix family type string. */
const char *
prefix_family_str (const struct prefix *p)
@@ -597,6 +637,19 @@ sockunion2hostprefix (const union sockunion *su)
return NULL;
}
+void
+prefix2sockunion (const struct prefix *p, union sockunion *su) {
+ memset (su, 0, sizeof (*su));
+
+ su->sa.sa_family = p->family;
+ if (p->family == AF_INET)
+ su->sin.sin_addr = p->u.prefix4;
+#ifdef HAVE_IPV6
+ if (p->family == AF_INET6)
+ memcpy (&su->sin6.sin6_addr, &p->u.prefix6, sizeof (struct in6_addr));
+#endif /* HAVE_IPV6 */
+}
+
int
prefix_blen (const struct prefix *p)
{
@@ -779,3 +832,4 @@ inet6_ntoa (struct in6_addr addr)
return buf;
}
#endif /* HAVE_IPV6 */
+
diff --git a/lib/prefix.h b/lib/prefix.h
index 9fd02ea6..74f32e94 100644
--- a/lib/prefix.h
+++ b/lib/prefix.h
@@ -162,12 +162,14 @@ extern int prefix2str (const struct prefix *, char *, int);
extern int prefix_match (const struct prefix *, const struct prefix *);
extern int prefix_same (const struct prefix *, const struct prefix *);
extern int prefix_cmp (const struct prefix *, const struct prefix *);
+extern int prefix_common_bits (const struct prefix *, const struct prefix *);
extern void prefix_copy (struct prefix *dest, const struct prefix *src);
extern void apply_mask (struct prefix *);
extern struct prefix *sockunion2prefix (const_sockunion dest,
const_sockunion mask);
extern struct prefix *sockunion2hostprefix (const_sockunion src);
+extern void prefix2sockunion (const struct prefix *, union sockunion *);
extern struct prefix_ipv4 *prefix_ipv4_new (void);
extern void prefix_ipv4_free (struct prefix_ipv4 *);