From: Vsevolod Stakhov Date: Thu, 12 Mar 2015 15:34:48 +0000 (+0000) Subject: Add more utility functions required. X-Git-Tag: 0.9.0~512^2~12 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=c4141a343c927e2df8819dbbd9ddffab92901265;p=rspamd.git Add more utility functions required. --- 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; +} diff --git a/src/libutil/addr.h b/src/libutil/addr.h index d3778f6a7..dd5b6adb6 100644 --- a/src/libutil/addr.h +++ b/src/libutil/addr.h @@ -174,6 +174,33 @@ gboolean rspamd_parse_host_port (const gchar *str, GPtrArray **addrs, gchar **name, guint default_port, rspamd_mempool_t *pool); +/** + * Destroy the specified IP address + * @param addr + */ void rspamd_inet_address_destroy (rspamd_inet_addr_t *addr); +/** + * Apply the specified mask to an address (ignored for AF_UNIX) + * @param addr + * @param mask + */ +void rspamd_inet_address_apply_mask (rspamd_inet_addr_t *addr, guint mask); + +/** + * Compare a1 and a2 and return value >0, ==0 and <0 if a1 is more, equal or less than a2 correspondingly + * @param a1 + * @param a2 + * @return + */ +gint rspamd_inet_address_compare (const rspamd_inet_addr_t *a1, + const rspamd_inet_addr_t *a2); + +/** + * Performs deep copy of rspamd inet addr + * @param addr + * @return + */ +rspamd_inet_addr_t *rspamd_inet_address_copy (const rspamd_inet_addr_t *addr); + #endif /* ADDR_H_ */