diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-01-03 11:35:45 +0000 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2016-01-03 11:35:45 +0000 |
commit | 32dda672d0d2013f8bc4e0730296e8a9ddaa2401 (patch) | |
tree | e402d39caf4e5c68af70413eceda7f793bbd3658 | |
parent | 49d6edee1079c2f4938d0cf724c051fecabb5541 (diff) | |
download | rspamd-32dda672d0d2013f8bc4e0730296e8a9ddaa2401.tar.gz rspamd-32dda672d0d2013f8bc4e0730296e8a9ddaa2401.zip |
Add method to check if IP is local
-rw-r--r-- | src/libutil/addr.c | 43 | ||||
-rw-r--r-- | src/libutil/addr.h | 5 |
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_ */ |