diff options
| author | manuel <manuel@mausz.at> | 2013-02-04 00:08:53 +0100 |
|---|---|---|
| committer | manuel <manuel@mausz.at> | 2013-02-04 00:08:53 +0100 |
| commit | 69aec538b456402170dc723af417ba5c05389c32 (patch) | |
| tree | e6f34c543f17c6392447ea337b2e2868212424d1 /ipme.c | |
| download | qmail-69aec538b456402170dc723af417ba5c05389c32.tar.gz qmail-69aec538b456402170dc723af417ba5c05389c32.tar.bz2 qmail-69aec538b456402170dc723af417ba5c05389c32.zip | |
qmail 1.03 import
Diffstat (limited to 'ipme.c')
| -rw-r--r-- | ipme.c | 95 |
1 files changed, 95 insertions, 0 deletions
| @@ -0,0 +1,95 @@ | |||
| 1 | #include <sys/types.h> | ||
| 2 | #include <sys/param.h> | ||
| 3 | #include <sys/time.h> | ||
| 4 | #include <sys/ioctl.h> | ||
| 5 | #include <sys/socket.h> | ||
| 6 | #include <net/if.h> | ||
| 7 | #include <netinet/in.h> | ||
| 8 | #ifndef SIOCGIFCONF /* whatever works */ | ||
| 9 | #include <sys/sockio.h> | ||
| 10 | #endif | ||
| 11 | #include "hassalen.h" | ||
| 12 | #include "byte.h" | ||
| 13 | #include "ip.h" | ||
| 14 | #include "ipalloc.h" | ||
| 15 | #include "stralloc.h" | ||
| 16 | #include "ipme.h" | ||
| 17 | |||
| 18 | static int ipmeok = 0; | ||
| 19 | ipalloc ipme = {0}; | ||
| 20 | |||
| 21 | int ipme_is(ip) | ||
| 22 | struct ip_address *ip; | ||
| 23 | { | ||
| 24 | int i; | ||
| 25 | if (ipme_init() != 1) return -1; | ||
| 26 | for (i = 0;i < ipme.len;++i) | ||
| 27 | if (byte_equal(&ipme.ix[i].ip,4,ip)) | ||
| 28 | return 1; | ||
| 29 | return 0; | ||
| 30 | } | ||
| 31 | |||
| 32 | static stralloc buf = {0}; | ||
| 33 | |||
| 34 | int ipme_init() | ||
| 35 | { | ||
| 36 | struct ifconf ifc; | ||
| 37 | char *x; | ||
| 38 | struct ifreq *ifr; | ||
| 39 | struct sockaddr_in *sin; | ||
| 40 | int len; | ||
| 41 | int s; | ||
| 42 | struct ip_mx ix; | ||
| 43 | |||
| 44 | if (ipmeok) return 1; | ||
| 45 | if (!ipalloc_readyplus(&ipme,0)) return 0; | ||
| 46 | ipme.len = 0; | ||
| 47 | ix.pref = 0; | ||
| 48 | |||
| 49 | if ((s = socket(AF_INET,SOCK_STREAM,0)) == -1) return -1; | ||
| 50 | |||
| 51 | len = 256; | ||
| 52 | for (;;) { | ||
| 53 | if (!stralloc_ready(&buf,len)) { close(s); return 0; } | ||
| 54 | buf.len = 0; | ||
| 55 | ifc.ifc_buf = buf.s; | ||
| 56 | ifc.ifc_len = len; | ||
| 57 | if (ioctl(s,SIOCGIFCONF,&ifc) >= 0) /* > is for System V */ | ||
| 58 | if (ifc.ifc_len + sizeof(*ifr) + 64 < len) { /* what a stupid interface */ | ||
| 59 | buf.len = ifc.ifc_len; | ||
| 60 | break; | ||
| 61 | } | ||
| 62 | if (len > 200000) { close(s); return -1; } | ||
| 63 | len += 100 + (len >> 2); | ||
| 64 | } | ||
| 65 | x = buf.s; | ||
| 66 | while (x < buf.s + buf.len) { | ||
| 67 | ifr = (struct ifreq *) x; | ||
| 68 | #ifdef HASSALEN | ||
| 69 | len = sizeof(ifr->ifr_name) + ifr->ifr_addr.sa_len; | ||
| 70 | if (len < sizeof(*ifr)) | ||
| 71 | len = sizeof(*ifr); | ||
| 72 | if (ifr->ifr_addr.sa_family == AF_INET) { | ||
| 73 | sin = (struct sockaddr_in *) &ifr->ifr_addr; | ||
| 74 | byte_copy(&ix.ip,4,&sin->sin_addr); | ||
| 75 | if (ioctl(s,SIOCGIFFLAGS,x) == 0) | ||
| 76 | if (ifr->ifr_flags & IFF_UP) | ||
| 77 | if (!ipalloc_append(&ipme,&ix)) { close(s); return 0; } | ||
| 78 | } | ||
| 79 | #else | ||
| 80 | len = sizeof(*ifr); | ||
| 81 | if (ioctl(s,SIOCGIFFLAGS,x) == 0) | ||
| 82 | if (ifr->ifr_flags & IFF_UP) | ||
| 83 | if (ioctl(s,SIOCGIFADDR,x) == 0) | ||
| 84 | if (ifr->ifr_addr.sa_family == AF_INET) { | ||
| 85 | sin = (struct sockaddr_in *) &ifr->ifr_addr; | ||
| 86 | byte_copy(&ix.ip,4,&sin->sin_addr); | ||
| 87 | if (!ipalloc_append(&ipme,&ix)) { close(s); return 0; } | ||
| 88 | } | ||
| 89 | #endif | ||
| 90 | x += len; | ||
| 91 | } | ||
| 92 | close(s); | ||
| 93 | ipmeok = 1; | ||
| 94 | return 1; | ||
| 95 | } | ||
