This source file includes following definitions.
- prefix
- if_posix_open
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 #include "pmix_config.h"
16 #include "pmix_common.h"
17
18 #include <string.h>
19 #ifdef HAVE_UNISTD_H
20 #include <unistd.h>
21 #endif
22 #include <errno.h>
23 #ifdef HAVE_SYS_TYPES_H
24 #include <sys/types.h>
25 #endif
26 #ifdef HAVE_SYS_SOCKET_H
27 #include <sys/socket.h>
28 #endif
29 #ifdef HAVE_SYS_SOCKIO_H
30 #include <sys/sockio.h>
31 #endif
32 #ifdef HAVE_SYS_IOCTL_H
33 #include <sys/ioctl.h>
34 #endif
35 #ifdef HAVE_NETINET_IN_H
36 #include <netinet/in.h>
37 #endif
38 #ifdef HAVE_ARPA_INET_H
39 #include <arpa/inet.h>
40 #endif
41 #ifdef HAVE_NET_IF_H
42 #include <net/if.h>
43 #endif
44 #ifdef HAVE_NETDB_H
45 #include <netdb.h>
46 #endif
47 #ifdef HAVE_IFADDRS_H
48 #include <ifaddrs.h>
49 #endif
50
51 #include "src/util/output.h"
52 #include "src/util/pif.h"
53 #include "src/mca/pif/pif.h"
54 #include "src/mca/pif/base/base.h"
55
56 static int if_posix_open(void);
57
58
59
60
61 pmix_pif_base_component_t mca_pif_posix_ipv4_component = {
62
63
64 .base = {
65 PMIX_PIF_BASE_VERSION_2_0_0,
66
67
68 "posix_ipv4",
69 PMIX_MAJOR_VERSION,
70 PMIX_MINOR_VERSION,
71 PMIX_RELEASE_VERSION,
72
73
74 if_posix_open,
75 NULL
76 },
77 .data = {
78
79 PMIX_MCA_BASE_METADATA_PARAM_CHECKPOINT
80 },
81 };
82
83
84 static int prefix (uint32_t netmask)
85 {
86 uint32_t mask = ntohl(netmask);
87 int plen = 0;
88
89 if (0 == mask) {
90 plen = 32;
91 } else {
92 while ((mask % 2) == 0) {
93 plen += 1;
94 mask /= 2;
95 }
96 }
97
98 return (32 - plen);
99 }
100
101
102 static int if_posix_open(void)
103 {
104 int sd;
105 int lastlen, rem;
106 char *ptr;
107 struct ifconf ifconf;
108 int ifc_len;
109 bool successful_locate = false;
110
111
112
113
114 if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
115 pmix_output(0, "pmix_ifinit: socket() failed with errno=%d\n",
116 errno);
117 return PMIX_ERROR;
118 }
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137 lastlen = 0;
138 ifc_len = sizeof(struct ifreq) * DEFAULT_NUMBER_INTERFACES;
139 do {
140 ifconf.ifc_len = ifc_len;
141 ifconf.ifc_req = malloc(ifc_len);
142 if (NULL == ifconf.ifc_req) {
143 close(sd);
144 return PMIX_ERROR;
145 }
146
147
148
149
150
151 memset(ifconf.ifc_req, 0, ifconf.ifc_len);
152
153 if (ioctl(sd, SIOCGIFCONF, &ifconf) < 0) {
154
155
156
157 if (errno != EINVAL && lastlen != 0) {
158 pmix_output(0, "pmix_ifinit: ioctl(SIOCGIFCONF) \
159 failed with errno=%d",
160 errno);
161 free(ifconf.ifc_req);
162 close(sd);
163 return PMIX_ERROR;
164 }
165 } else {
166
167
168
169 if (ifconf.ifc_len == lastlen && ifconf.ifc_len > 0) {
170
171 successful_locate = true;
172 break;
173 }
174 lastlen = ifconf.ifc_len;
175 }
176
177
178
179 free(ifconf.ifc_req);
180 ifc_len = (ifc_len == 0) ? 1 : ifc_len * 2;
181 } while (ifc_len < MAX_PIFCONF_SIZE);
182 if (!successful_locate) {
183 pmix_output(0, "pmix_ifinit: unable to find network interfaces.");
184 close(sd);
185 return PMIX_ERROR;
186 }
187
188
189
190
191 ptr = (char*) ifconf.ifc_req;
192 rem = ifconf.ifc_len;
193
194
195 while (rem > 0) {
196 struct ifreq* ifr = (struct ifreq*) ptr;
197 pmix_pif_t *intf;
198 int length;
199
200
201 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
202 length = sizeof(struct sockaddr);
203
204 if (ifr->ifr_addr.sa_len > length) {
205 length = ifr->ifr_addr.sa_len;
206 }
207
208 length += sizeof(ifr->ifr_name);
209 #else
210 length = sizeof(struct ifreq);
211 #endif
212
213 rem -= length;
214 ptr += length;
215
216
217 if (AF_INET != ifr->ifr_addr.sa_family) {
218 continue;
219 }
220
221 if (ioctl(sd, SIOCGIFFLAGS, ifr) < 0) {
222 pmix_output(0, "pmix_ifinit: ioctl(SIOCGIFFLAGS) failed with errno=%d", errno);
223 continue;
224 }
225 if ((ifr->ifr_flags & IFF_UP) == 0) {
226 continue;
227 }
228 #ifdef IFF_SLAVE
229
230
231 if ((ifr->ifr_flags & IFF_SLAVE) != 0) {
232 continue;
233 }
234 #endif
235 #if 0
236 if (!pmix_if_retain_loopback && (ifr->ifr_flags & IFF_LOOPBACK) != 0) {
237 continue;
238 }
239 #endif
240
241 intf = PMIX_NEW(pmix_pif_t);
242 if (NULL == intf) {
243 pmix_output(0, "pmix_ifinit: unable to allocated %lu bytes\n", (unsigned long)sizeof(pmix_pif_t));
244 free(ifconf.ifc_req);
245 close(sd);
246 return PMIX_ERR_OUT_OF_RESOURCE;
247 }
248 intf->af_family = AF_INET;
249
250
251 memset(intf->if_name, 0, sizeof(intf->if_name));
252 pmix_strncpy(intf->if_name, ifr->ifr_name, sizeof(intf->if_name) - 1);
253 intf->if_flags = ifr->ifr_flags;
254
255
256 intf->if_index = pmix_list_get_size(&pmix_if_list)+1;
257
258 pmix_output_verbose(1, pmix_pif_base_framework.framework_output,
259 "found interface %s", intf->if_name);
260
261
262 #ifndef SIOCGIFINDEX
263 intf->if_kernel_index = intf->if_index;
264 #else
265 if (ioctl(sd, SIOCGIFINDEX, ifr) < 0) {
266 pmix_output(0,"pmix_ifinit: ioctl(SIOCGIFINDEX) failed with errno=%d", errno);
267 PMIX_RELEASE(intf);
268 continue;
269 }
270 #if defined(ifr_ifindex)
271 intf->if_kernel_index = ifr->ifr_ifindex;
272 #elif defined(ifr_index)
273 intf->if_kernel_index = ifr->ifr_index;
274 #else
275 intf->if_kernel_index = -1;
276 #endif
277 #endif
278
279
280
281 if (ioctl(sd, SIOCGIFADDR, ifr) < 0) {
282 pmix_output(0, "pmix_ifinit: ioctl(SIOCGIFADDR) failed with errno=%d", errno);
283 PMIX_RELEASE(intf);
284 break;
285 }
286 if (AF_INET != ifr->ifr_addr.sa_family) {
287 PMIX_RELEASE(intf);
288 continue;
289 }
290
291
292 memcpy(&intf->if_addr, &ifr->ifr_addr, sizeof(struct sockaddr_in));
293
294 if (ioctl(sd, SIOCGIFNETMASK, ifr) < 0) {
295 pmix_output(0, "pmix_ifinit: ioctl(SIOCGIFNETMASK) failed with errno=%d", errno);
296 PMIX_RELEASE(intf);
297 continue;
298 }
299
300
301 intf->if_mask = prefix(((struct sockaddr_in*) &ifr->ifr_addr)->sin_addr.s_addr);
302
303 #if defined(SIOCGIFHWADDR) && defined(HAVE_STRUCT_IFREQ_IFR_HWADDR)
304
305 if (ioctl(sd, SIOCGIFHWADDR, ifr) < 0) {
306 pmix_output(0, "pmix_ifinit: ioctl(SIOCGIFHWADDR) failed with errno=%d", errno);
307 break;
308 }
309 memcpy(intf->if_mac, ifr->ifr_hwaddr.sa_data, 6);
310 #endif
311
312 #if defined(SIOCGIFMTU) && defined(HAVE_STRUCT_IFREQ_IFR_MTU)
313
314 if (ioctl(sd, SIOCGIFMTU, ifr) < 0) {
315 pmix_output(0, "pmix_ifinit: ioctl(SIOCGIFMTU) failed with errno=%d", errno);
316 break;
317 }
318 intf->ifmtu = ifr->ifr_mtu;
319 #endif
320 pmix_output_verbose(1, pmix_pif_base_framework.framework_output,
321 "adding interface %s", intf->if_name);
322 pmix_list_append(&pmix_if_list, &(intf->super));
323 }
324 free(ifconf.ifc_req);
325 close(sd);
326
327 return PMIX_SUCCESS;
328 }