aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-01-03 11:35:45 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2016-01-03 11:35:45 +0000
commit32dda672d0d2013f8bc4e0730296e8a9ddaa2401 (patch)
treee402d39caf4e5c68af70413eceda7f793bbd3658
parent49d6edee1079c2f4938d0cf724c051fecabb5541 (diff)
downloadrspamd-32dda672d0d2013f8bc4e0730296e8a9ddaa2401.tar.gz
rspamd-32dda672d0d2013f8bc4e0730296e8a9ddaa2401.zip
Add method to check if IP is local
-rw-r--r--src/libutil/addr.c43
-rw-r--r--src/libutil/addr.h5
2 files changed, 48 insertions, 0 deletions
diff --git a/src/libutil/addr.c b/src/libutil/addr.c
index e87fa5261..747ac869e 100644
--- a/src/libutil/addr.c
+++ b/src/libutil/addr.c
@@ -1314,3 +1314,46 @@ rspamd_inet_address_equal (gconstpointer a, gconstpointer b)
return rspamd_inet_address_compare (a1, a2) == 0;
}
+
+#ifndef IN6_IS_ADDR_LOOPBACK
+#define IN6_IS_ADDR_LOOPBACK(a) \
+ ((*(const __uint32_t *)(const void *)(&(a)->s6_addr[0]) == 0) && \
+ (*(const __uint32_t *)(const void *)(&(a)->s6_addr[4]) == 0) && \
+ (*(const __uint32_t *)(const void *)(&(a)->s6_addr[8]) == 0) && \
+ (*(const __uint32_t *)(const void *)(&(a)->s6_addr[12]) == ntohl(1)))
+#endif
+#ifndef IN6_IS_ADDR_LINKLOCAL
+#define IN6_IS_ADDR_LINKLOCAL(a) \
+ (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0x80))
+#endif
+#ifndef IN6_IS_ADDR_SITELOCAL
+#define IN6_IS_ADDR_SITELOCAL(a) \
+ (((a)->s6_addr[0] == 0xfe) && (((a)->s6_addr[1] & 0xc0) == 0xc0))
+#endif
+
+gboolean
+rspamd_inet_address_is_local (const rspamd_inet_addr_t *addr)
+{
+ g_assert (addr != NULL);
+
+ if (addr->af == AF_UNIX) {
+ /* Always true for unix sockets */
+ return TRUE;
+ }
+ else {
+ if (addr->af == AF_INET) {
+ if (addr->u.in.addr.s4.sin_addr.s_addr == INADDR_LOOPBACK) {
+ return TRUE;
+ }
+ }
+ else if (addr->af == AF_INET6) {
+ if (IN6_IS_ADDR_LOOPBACK (&addr->u.in.addr.s6.sin6_addr) ||
+ IN6_IS_ADDR_LINKLOCAL (&addr->u.in.addr.s6.sin6_addr) ||
+ IN6_IS_ADDR_SITELOCAL (&addr->u.in.addr.s6.sin6_addr)) {
+ return TRUE;
+ }
+ }
+ }
+
+ return FALSE;
+}
diff --git a/src/libutil/addr.h b/src/libutil/addr.h
index fa2e4e65b..36f9910fd 100644
--- a/src/libutil/addr.h
+++ b/src/libutil/addr.h
@@ -260,4 +260,9 @@ guint rspamd_inet_address_hash (gconstpointer a);
*/
gboolean rspamd_inet_address_equal (gconstpointer a, gconstpointer b);
+/**
+ * Returns TRUE if an address belongs to some local address
+ */
+gboolean rspamd_inet_address_is_local (const rspamd_inet_addr_t *addr);
+
#endif /* ADDR_H_ */