From b732a73bc773789894466b0e5320b2f1fe42c7e9 Mon Sep 17 00:00:00 2001 From: John Denker Date: Fri, 1 Jun 2012 18:58:45 -0700 Subject: original, as downloaded from http://www.qmail.org/netqmail-1.06.tar.gz --- ipme.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 ipme.c (limited to 'ipme.c') diff --git a/ipme.c b/ipme.c new file mode 100644 index 0000000..3c86127 --- /dev/null +++ b/ipme.c @@ -0,0 +1,100 @@ +#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" + +static int ipmeok = 0; +ipalloc ipme = {0}; + +int ipme_is(ip) +struct ip_address *ip; +{ + int i; + if (ipme_init() != 1) return -1; + for (i = 0;i < ipme.len;++i) + if (byte_equal(&ipme.ix[i].ip,4,ip)) + return 1; + return 0; +} + +static stralloc buf = {0}; + +int ipme_init() +{ + struct ifconf ifc; + char *x; + struct ifreq *ifr; + struct sockaddr_in *sin; + int len; + int s; + struct ip_mx ix; + + if (ipmeok) return 1; + if (!ipalloc_readyplus(&ipme,0)) return 0; + ipme.len = 0; + ix.pref = 0; + + /* 0.0.0.0 is a special address which always refers to + * "this host, this network", according to RFC 1122, Sec. 3.2.1.3a. + */ + byte_copy(&ix.ip,4,"\0\0\0\0"); + if (!ipalloc_append(&ipme,&ix)) { return 0; } + if ((s = socket(AF_INET,SOCK_STREAM,0)) == -1) return -1; + + len = 256; + for (;;) { + if (!stralloc_ready(&buf,len)) { close(s); return 0; } + buf.len = 0; + ifc.ifc_buf = buf.s; + ifc.ifc_len = len; + if (ioctl(s,SIOCGIFCONF,&ifc) >= 0) /* > is for System V */ + if (ifc.ifc_len + sizeof(*ifr) + 64 < len) { /* what a stupid interface */ + buf.len = ifc.ifc_len; + break; + } + if (len > 200000) { close(s); return -1; } + len += 100 + (len >> 2); + } + x = buf.s; + while (x < buf.s + buf.len) { + ifr = (struct ifreq *) x; +#ifdef HASSALEN + len = sizeof(ifr->ifr_name) + ifr->ifr_addr.sa_len; + if (len < sizeof(*ifr)) + len = sizeof(*ifr); + if (ifr->ifr_addr.sa_family == AF_INET) { + sin = (struct sockaddr_in *) &ifr->ifr_addr; + byte_copy(&ix.ip,4,&sin->sin_addr); + if (ioctl(s,SIOCGIFFLAGS,x) == 0) + if (ifr->ifr_flags & IFF_UP) + if (!ipalloc_append(&ipme,&ix)) { close(s); return 0; } + } +#else + len = sizeof(*ifr); + if (ioctl(s,SIOCGIFFLAGS,x) == 0) + if (ifr->ifr_flags & IFF_UP) + if (ioctl(s,SIOCGIFADDR,x) == 0) + if (ifr->ifr_addr.sa_family == AF_INET) { + sin = (struct sockaddr_in *) &ifr->ifr_addr; + byte_copy(&ix.ip,4,&sin->sin_addr); + if (!ipalloc_append(&ipme,&ix)) { close(s); return 0; } + } +#endif + x += len; + } + close(s); + ipmeok = 1; + return 1; +} -- cgit v1.2.3