#include #include #include #include #include #include #include #include #ifndef SIOCGIFCONF /* whatever works */ #include #endif #include "hassalen.h" #include "byte.h" #include "ip.h" #include "ipalloc.h" #include "stralloc.h" #include "ipme.h" /** @file ipme.c @brief ipme_is4, ipme_is6, ipme_is46, ipme_init */ static int ipmeok = 0; ipalloc ipme = {0}; int ipme_is4(struct ip4_address *ip) { int i; if (ipme_init() != 1) return -1; for (i = 0; i < ipme.len; ++i) if (ipme.ix[i].af == AF_INET && byte_equal(&ipme.ix[i].addr,4,ip)) return 1; return 0; } int ipme_is6(struct ip6_address *ip) { int i; if (ipme_init() != 1) return -1; for (i = 0; i < ipme.len; ++i) if (ipme.ix[i].af == AF_INET6 && byte_equal(&ipme.ix[i].addr,16,ip)) return 1; return 0; } int ipme_is(struct ip_mx *mxip) { switch (mxip->af) { case AF_INET: return ipme_is4(&mxip->addr.ip4); case AF_INET6: return ipme_is6(&mxip->addr.ip6); } return 0; } /* @brief ipme_init uses now getifaddrs() instead of ioctl calls */ int ipme_init() { struct ifaddrs *ifap, *ifa; struct sockaddr_in *sin; struct sockaddr_in6 *sin6; struct ip_mx ix; if (ipmeok) return 1; if (!ipalloc_readyplus(&ipme,0)) return 0; ipme.len = 0; ix.pref = 0; if (getifaddrs(&ifap)) return 0; for (ifa = ifap; ifa; ifa = ifa->ifa_next) if (ifa->ifa_addr) { if (ifa->ifa_addr->sa_family == AF_INET) { sin = (struct sockaddr_in *) ifa->ifa_addr; byte_copy(&ix.addr.ip4,4,&sin->sin_addr); ix.af = AF_INET; if (!ipalloc_append(&ipme,&ix)) return 0; } if (ifa->ifa_addr->sa_family == AF_INET6) { sin6 = (struct sockaddr_in6 *) ifa->ifa_addr; byte_copy(&ix.addr.ip6,16,&sin6->sin6_addr); ix.af = AF_INET6; if (!ipalloc_append(&ipme,&ix)) return 0; } } freeifaddrs(ifap); ipmeok = 1; return 1; }