diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-03-12 15:34:48 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-03-12 15:34:48 +0000 |
commit | c4141a343c927e2df8819dbbd9ddffab92901265 (patch) | |
tree | d50fe5ad6143cd4adeb8b66394a9e2c0122b0e6a /src/libutil/addr.c | |
parent | fe68df49f6cdd499f82c4edd320c9a9d20e2c0c0 (diff) | |
download | rspamd-c4141a343c927e2df8819dbbd9ddffab92901265.tar.gz rspamd-c4141a343c927e2df8819dbbd9ddffab92901265.zip |
Add more utility functions required.
Diffstat (limited to 'src/libutil/addr.c')
-rw-r--r-- | src/libutil/addr.c | 93 |
1 files changed, 93 insertions, 0 deletions
diff --git a/src/libutil/addr.c b/src/libutil/addr.c index 6877ce87c..645c22d31 100644 --- a/src/libutil/addr.c +++ b/src/libutil/addr.c @@ -863,3 +863,96 @@ rspamd_inet_address_from_sa (const struct sockaddr *sa, socklen_t slen) return addr; } +void +rspamd_inet_address_apply_mask (rspamd_inet_addr_t *addr, guint mask) +{ + guint32 umsk, *p; + + if (mask > 0 && addr != NULL) { + if (addr->af == AF_INET && mask <= 32) { + umsk = htonl (G_MAXUINT32 << (32 - mask)); + addr->u.in.addr.s4.sin_addr.s_addr &= umsk; + } + else if (addr->af == AF_INET && mask <= 128) { + p = (uint32_t *)&addr->u.in.addr.s6.sin6_addr; + p += 3; + while (mask > 0) { + umsk = htonl (G_MAXUINT32 << (32 - (mask > 32 ? 32 : mask))); + *p &= umsk; + p --; + mask -= 32; + } + } + } +} + +static gint +rspamd_inet_address_af_order (const rspamd_inet_addr_t *addr) +{ + int ret; + + switch (addr->af) { + case AF_UNIX: + ret = 2; + break; + case AF_INET: + ret = 1; + break; + default: + ret = 0; + break; + } + + return ret; +} + +gint +rspamd_inet_address_compare (const rspamd_inet_addr_t *a1, + const rspamd_inet_addr_t *a2) +{ + g_assert (a1 != NULL); + g_assert (a2 != NULL); + + if (a1->af != a2->af) { + return (rspamd_inet_address_af_order (a1) - + rspamd_inet_address_af_order (a2)); + } + else { + switch (a1->af) { + case AF_INET: + return memcmp (&a1->u.in.addr.s4.sin_addr, + &a2->u.in.addr.s4.sin_addr, sizeof (struct in_addr)); + case AF_INET6: + return memcmp (&a1->u.in.addr.s6.sin6_addr, + &a2->u.in.addr.s6.sin6_addr, sizeof (struct in6_addr)); + case AF_UNIX: + return strncmp (a1->u.un->addr.sun_path, + a2->u.un->addr.sun_path, sizeof (a1->u.un->addr.sun_path)); + default: + return memcmp (&a1->u.in, &a2->u.in, sizeof (a1->u.in)); + } + } + + return 0; +} + +rspamd_inet_addr_t * +rspamd_inet_address_copy (const rspamd_inet_addr_t *addr) +{ + rspamd_inet_addr_t *n; + + if (addr == NULL) { + return NULL; + } + + n = rspamd_inet_addr_create (addr->af); + + if (n->af == AF_UNIX) { + memcpy (n->u.un, addr->u.un, sizeof (*addr->u.un)); + } + else { + memcpy (&n->u.in, &addr->u.in, sizeof (addr->u.in)); + } + + return n; +} |