mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-07-09 13:18:52 +00:00
lib: prefix2sockunion, prefix_common_bits helper functions
prefix2sockunion converts a struct prefix* to a union sockunion *; prefix_common_bits counts the number of common bits in the prefix's address part.
This commit is contained in:
parent
681b84e8f5
commit
17e52061ba
54
lib/prefix.c
54
lib/prefix.c
@ -181,6 +181,46 @@ prefix_cmp (const struct prefix *p1, const struct prefix *p2)
|
|||||||
return 0;
|
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. */
|
/* Return prefix family type string. */
|
||||||
const char *
|
const char *
|
||||||
prefix_family_str (const struct prefix *p)
|
prefix_family_str (const struct prefix *p)
|
||||||
@ -570,6 +610,20 @@ sockunion2hostprefix (const union sockunion *su)
|
|||||||
return NULL;
|
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
|
int
|
||||||
prefix_blen (const struct prefix *p)
|
prefix_blen (const struct prefix *p)
|
||||||
{
|
{
|
||||||
|
@ -157,12 +157,14 @@ extern int prefix2str (const struct prefix *, char *, int);
|
|||||||
extern int prefix_match (const struct prefix *, const struct prefix *);
|
extern int prefix_match (const struct prefix *, const struct prefix *);
|
||||||
extern int prefix_same (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_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 prefix_copy (struct prefix *dest, const struct prefix *src);
|
||||||
extern void apply_mask (struct prefix *);
|
extern void apply_mask (struct prefix *);
|
||||||
|
|
||||||
extern struct prefix *sockunion2prefix (const union sockunion *dest,
|
extern struct prefix *sockunion2prefix (const union sockunion *dest,
|
||||||
const union sockunion *mask);
|
const union sockunion *mask);
|
||||||
extern struct prefix *sockunion2hostprefix (const union sockunion *);
|
extern struct prefix *sockunion2hostprefix (const union sockunion *);
|
||||||
|
extern void prefix2sockunion (const struct prefix *, union sockunion *);
|
||||||
|
|
||||||
extern struct prefix_ipv4 *prefix_ipv4_new (void);
|
extern struct prefix_ipv4 *prefix_ipv4_new (void);
|
||||||
extern void prefix_ipv4_free (struct prefix_ipv4 *);
|
extern void prefix_ipv4_free (struct prefix_ipv4 *);
|
||||||
|
Loading…
Reference in New Issue
Block a user