Commit | Line | Data |
---|---|---|
2117e02e MW |
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 | } |