This source file includes following definitions.
- pmix_net_isaddr
- hostname_cleanup
- get_hostname_buffer
- pmix_net_init
- pmix_net_finalize
- pmix_net_prefix2netmask
- pmix_net_islocalhost
- pmix_net_samenetwork
- pmix_net_addr_isipv4public
- pmix_net_get_hostname
- pmix_net_get_port
- pmix_net_init
- pmix_net_finalize
- pmix_net_prefix2netmask
- pmix_net_islocalhost
- pmix_net_samenetwork
- pmix_net_addr_isipv4public
- pmix_net_get_hostname
- pmix_net_get_port
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 #include "pmix_config.h"
26 #include "pmix_common.h"
27
28 #include <stdio.h>
29 #include <string.h>
30 #ifdef HAVE_UNISTD_H
31 #include <unistd.h>
32 #endif
33 #include <errno.h>
34 #ifdef HAVE_SYS_TYPES_H
35 #include <sys/types.h>
36 #endif
37 #ifdef HAVE_SYS_SOCKET_H
38 #include <sys/socket.h>
39 #endif
40 #ifdef HAVE_SYS_SOCKIO_H
41 #include <sys/sockio.h>
42 #endif
43 #ifdef HAVE_SYS_IOCTL_H
44 #include <sys/ioctl.h>
45 #endif
46 #ifdef HAVE_NETINET_IN_H
47 #include <netinet/in.h>
48 #endif
49 #ifdef HAVE_ARPA_INET_H
50 #include <arpa/inet.h>
51 #endif
52 #ifdef HAVE_NET_IF_H
53 #include <net/if.h>
54 #endif
55 #ifdef HAVE_NETDB_H
56 #include <netdb.h>
57 #endif
58 #ifdef HAVE_IFADDRS_H
59 #include <ifaddrs.h>
60 #endif
61
62 #include "src/util/net.h"
63 #include "src/util/output.h"
64 #include "src/util/argv.h"
65 #include "src/util/show_help.h"
66 #include "src/threads/tsd.h"
67 #include "src/runtime/pmix_rte.h"
68
69
70 bool pmix_net_isaddr(const char *name)
71 {
72 struct addrinfo hint, *res = NULL;
73
74
75 memset(&hint, '\0', sizeof hint);
76
77
78 hint.ai_family = PF_UNSPEC;
79 hint.ai_flags = AI_NUMERICHOST;
80
81 if (0 != getaddrinfo(name, NULL, &hint, &res)) {
82
83 return false;
84 }
85
86
87
88 freeaddrinfo(res);
89 return true;
90 }
91
92 #ifdef HAVE_STRUCT_SOCKADDR_IN
93
94 typedef struct private_ipv4_t {
95 in_addr_t addr;
96 uint32_t netmask_bits;
97 } private_ipv4_t;
98
99 static private_ipv4_t* private_ipv4 = NULL;
100
101 static pmix_tsd_key_t hostname_tsd_key;
102
103
104 static void
105 hostname_cleanup(void *value)
106 {
107 if (NULL != value) free(value);
108 }
109
110
111 static char*
112 get_hostname_buffer(void)
113 {
114 void *buffer;
115 int ret;
116
117 ret = pmix_tsd_getspecific(hostname_tsd_key, &buffer);
118 if (PMIX_SUCCESS != ret) return NULL;
119
120 if (NULL == buffer) {
121 buffer = (void*) malloc((NI_MAXHOST + 1) * sizeof(char));
122 ret = pmix_tsd_setspecific(hostname_tsd_key, buffer);
123 }
124
125 return (char*) buffer;
126 }
127
128 int
129 pmix_net_init(void)
130 {
131 char **args, *arg;
132 uint32_t a, b, c, d, bits, addr;
133 int i, count, found_bad = 0;
134
135 args = pmix_argv_split(pmix_net_private_ipv4, ';');
136 if( NULL != args ) {
137 count = pmix_argv_count(args);
138 private_ipv4 = (private_ipv4_t*)malloc( (count + 1) * sizeof(private_ipv4_t));
139 if( NULL == private_ipv4 ) {
140 pmix_output(0, "Unable to allocate memory for the private addresses array" );
141 pmix_argv_free(args);
142 goto do_local_init;
143 }
144 for( i = 0; i < count; i++ ) {
145 arg = args[i];
146
147 (void)sscanf( arg, "%u.%u.%u.%u/%u", &a, &b, &c, &d, &bits );
148
149 if( (a > 255) || (b > 255) || (c > 255) ||
150 (d > 255) || (bits > 32) ) {
151 if (0 == found_bad) {
152 pmix_show_help("help-pmix-runtime.txt",
153 "malformed net_private_ipv4",
154 true, args[i]);
155 found_bad = 1;
156 }
157 continue;
158 }
159 addr = (a << 24) | (b << 16) | (c << 8) | d;
160 private_ipv4[i].addr = htonl(addr);
161 private_ipv4[i].netmask_bits = bits;
162 }
163 private_ipv4[i].addr = 0;
164 private_ipv4[i].netmask_bits = 0;
165 pmix_argv_free(args);
166 }
167
168 do_local_init:
169 return pmix_tsd_key_create(&hostname_tsd_key, hostname_cleanup);
170 }
171
172
173 int
174 pmix_net_finalize()
175 {
176 free(private_ipv4);
177 private_ipv4 = NULL;
178
179 return PMIX_SUCCESS;
180 }
181
182
183
184 uint32_t
185 pmix_net_prefix2netmask(uint32_t prefixlen)
186 {
187 return htonl (((1 << prefixlen) - 1) << (32 - prefixlen));
188 }
189
190
191 bool
192 pmix_net_islocalhost(const struct sockaddr *addr)
193 {
194 switch (addr->sa_family) {
195 case AF_INET:
196 {
197 const struct sockaddr_in *inaddr = (struct sockaddr_in*) addr;
198
199
200 if (0x7F000000 == (0x7F000000 & ntohl(inaddr->sin_addr.s_addr))) {
201 return true;
202 }
203 return false;
204 }
205 break;
206
207 case AF_INET6:
208 {
209 const struct sockaddr_in6 *inaddr = (struct sockaddr_in6*) addr;
210 if (IN6_IS_ADDR_LOOPBACK (&inaddr->sin6_addr)) {
211 return true;
212 }
213 return false;
214 }
215 break;
216
217 default:
218 pmix_output(0, "unhandled sa_family %d passed to pmix_net_islocalhost",
219 addr->sa_family);
220 return false;
221 break;
222 }
223 }
224
225
226 bool
227 pmix_net_samenetwork(const struct sockaddr *addr1,
228 const struct sockaddr *addr2,
229 uint32_t plen)
230 {
231 uint32_t prefixlen;
232
233 if(addr1->sa_family != addr2->sa_family) {
234 return false;
235 }
236
237 switch (addr1->sa_family) {
238 case AF_INET:
239 {
240 if (0 == plen) {
241 prefixlen = 32;
242 } else {
243 prefixlen = plen;
244 }
245 struct sockaddr_in inaddr1, inaddr2;
246
247
248 memcpy(&inaddr1, addr1, sizeof(inaddr1));
249 memcpy(&inaddr2, addr2, sizeof(inaddr2));
250 uint32_t netmask = pmix_net_prefix2netmask (prefixlen);
251
252 if((inaddr1.sin_addr.s_addr & netmask) ==
253 (inaddr2.sin_addr.s_addr & netmask)) {
254 return true;
255 }
256 return false;
257 }
258 break;
259
260 case AF_INET6:
261 {
262 struct sockaddr_in6 inaddr1, inaddr2;
263
264
265 memcpy(&inaddr1, addr1, sizeof(inaddr1));
266 memcpy(&inaddr2, addr2, sizeof(inaddr2));
267 struct in6_addr *a6_1 = (struct in6_addr*) &inaddr1.sin6_addr;
268 struct in6_addr *a6_2 = (struct in6_addr*) &inaddr2.sin6_addr;
269
270 if (0 == plen) {
271 prefixlen = 64;
272 } else {
273 prefixlen = plen;
274 }
275 if (64 == prefixlen) {
276
277
278
279
280
281 if (((const uint32_t *) (a6_1))[0] ==
282 ((const uint32_t *) (a6_2))[0] &&
283 ((const uint32_t *) (a6_1))[1] ==
284 ((const uint32_t *) (a6_2))[1]) {
285 return true;
286 }
287 }
288 return false;
289 }
290 break;
291
292 default:
293 pmix_output(0, "unhandled sa_family %d passed to pmix_samenetwork",
294 addr1->sa_family);
295 }
296
297 return false;
298 }
299
300
301
302
303
304 bool
305 pmix_net_addr_isipv4public(const struct sockaddr *addr)
306 {
307 switch (addr->sa_family) {
308 case AF_INET6:
309 return false;
310
311 case AF_INET:
312 {
313 const struct sockaddr_in *inaddr = (struct sockaddr_in*) addr;
314 int i;
315
316 if( NULL == private_ipv4 ) {
317 return true;
318 }
319
320 for( i = 0; private_ipv4[i].addr != 0; i++ ) {
321 if( private_ipv4[i].addr == (inaddr->sin_addr.s_addr &
322 pmix_net_prefix2netmask(private_ipv4[i].netmask_bits)) )
323 return false;
324 }
325
326 }
327 return true;
328 default:
329 pmix_output (0,
330 "unhandled sa_family %d passed to pmix_net_addr_isipv4public\n",
331 addr->sa_family);
332 }
333
334 return false;
335 }
336
337
338 char*
339 pmix_net_get_hostname(const struct sockaddr *addr)
340 {
341 char *name = get_hostname_buffer();
342 int error;
343 socklen_t addrlen;
344 char *p;
345
346 if (NULL == name) {
347 pmix_output(0, "pmix_sockaddr2str: malloc() failed\n");
348 return NULL;
349 }
350 memset(name, 0, sizeof(*name));
351
352 switch (addr->sa_family) {
353 case AF_INET:
354 addrlen = sizeof (struct sockaddr_in);
355 break;
356 case AF_INET6:
357 #if defined( __NetBSD__)
358
359
360 if(NULL == inet_ntop(AF_INET6, &((struct sockaddr_in6*) addr)->sin6_addr,
361 name, NI_MAXHOST)) {
362 pmix_output(0, "pmix_sockaddr2str failed with error code %d", errno);
363 free(name);
364 return NULL;
365 }
366 return name;
367 #else
368 addrlen = sizeof (struct sockaddr_in6);
369 #endif
370 break;
371 default:
372 free(name);
373 return NULL;
374 }
375
376 error = getnameinfo(addr, addrlen,
377 name, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
378
379 if (error) {
380 int err = errno;
381 pmix_output (0, "pmix_sockaddr2str failed:%s (return code %i)\n",
382 gai_strerror(err), error);
383 free (name);
384 return NULL;
385 }
386
387 if (NULL != (p = strrchr(name, '%'))) {
388 *p = '\0';
389 }
390 return name;
391 }
392
393
394 int
395 pmix_net_get_port(const struct sockaddr *addr)
396 {
397 switch (addr->sa_family) {
398 case AF_INET:
399 return ntohs(((struct sockaddr_in*) addr)->sin_port);
400 break;
401
402 case AF_INET6:
403 return ntohs(((struct sockaddr_in6*) addr)->sin6_port);
404 break;
405 }
406
407 return -1;
408 }
409
410
411 #else
412
413 int
414 pmix_net_init()
415 {
416 return PMIX_SUCCESS;
417 }
418
419
420 int
421 pmix_net_finalize()
422 {
423 return PMIX_SUCCESS;
424 }
425
426
427 uint32_t
428 pmix_net_prefix2netmask(uint32_t prefixlen)
429 {
430 return 0;
431 }
432
433
434 bool
435 pmix_net_islocalhost(const struct sockaddr *addr)
436 {
437 return false;
438 }
439
440
441 bool
442 pmix_net_samenetwork(const struct sockaddr *addr1,
443 const struct sockaddr *addr2,
444 uint32_t prefixlen)
445 {
446 return false;
447 }
448
449
450 bool
451 pmix_net_addr_isipv4public(const struct sockaddr *addr)
452 {
453 return false;
454 }
455
456
457 char*
458 pmix_net_get_hostname(const struct sockaddr *addr)
459 {
460 return NULL;
461 }
462
463
464 int
465 pmix_net_get_port(const struct sockaddr *addr)
466 {
467 return -1;
468 }
469
470 #endif