This source file includes following definitions.
- opal_ifnametoaddr
- opal_ifnametoindex
- opal_ifnametokindex
- opal_ifindextokindex
- opal_ifaddrtoname
- opal_ifaddrtokindex
- opal_ifcount
- opal_ifbegin
- opal_ifnext
- opal_ifindextoaddr
- opal_ifkindextoaddr
- opal_ifindextomask
- opal_ifindextomac
- opal_ifindextomtu
- opal_ifindextoflags
- opal_ifindextoname
- opal_ifkindextoname
- opal_ifislocal
- parse_ipv4_dots
- opal_iftupletoaddr
- opal_ifisloopback
- opal_ifmatches
- opal_ifgetaliases
- opal_ifnametoaddr
- opal_ifaddrtoname
- opal_ifnametoindex
- opal_ifnametokindex
- opal_ifindextokindex
- opal_ifcount
- opal_ifbegin
- opal_ifnext
- opal_ifindextoname
- opal_ifkindextoname
- opal_ifindextoaddr
- opal_ifindextomask
- opal_ifislocal
- opal_iftupletoaddr
- opal_ifmatches
- opal_ifgetaliases
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
26
27
28 #include "opal_config.h"
29
30 #include <string.h>
31 #ifdef HAVE_UNISTD_H
32 #include <unistd.h>
33 #endif
34 #include <errno.h>
35 #ifdef HAVE_SYS_TYPES_H
36 #include <sys/types.h>
37 #endif
38 #ifdef HAVE_SYS_SOCKET_H
39 #include <sys/socket.h>
40 #endif
41 #ifdef HAVE_SYS_SOCKIO_H
42 #include <sys/sockio.h>
43 #endif
44 #ifdef HAVE_SYS_IOCTL_H
45 #include <sys/ioctl.h>
46 #endif
47 #ifdef HAVE_NETINET_IN_H
48 #include <netinet/in.h>
49 #endif
50 #ifdef HAVE_ARPA_INET_H
51 #include <arpa/inet.h>
52 #endif
53 #ifdef HAVE_NET_IF_H
54 #include <net/if.h>
55 #endif
56 #ifdef HAVE_NETDB_H
57 #include <netdb.h>
58 #endif
59 #ifdef HAVE_IFADDRS_H
60 #include <ifaddrs.h>
61 #endif
62 #include <ctype.h>
63
64 #include "opal/class/opal_list.h"
65 #include "opal/util/if.h"
66 #include "opal/util/net.h"
67 #include "opal/util/output.h"
68 #include "opal/util/argv.h"
69 #include "opal/util/show_help.h"
70 #include "opal/util/string_copy.h"
71 #include "opal/constants.h"
72
73 #include "opal/mca/if/base/base.h"
74
75 #ifdef HAVE_STRUCT_SOCKADDR_IN
76
77 #ifndef MIN
78 # define MIN(a,b) ((a) < (b) ? (a) : (b))
79 #endif
80
81
82
83
84
85
86 int opal_ifnametoaddr(const char* if_name, struct sockaddr* addr, int length)
87 {
88 opal_if_t* intf;
89
90 OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
91 if (strcmp(intf->if_name, if_name) == 0) {
92 memcpy(addr, &intf->if_addr, length);
93 return OPAL_SUCCESS;
94 }
95 }
96 return OPAL_ERROR;
97 }
98
99
100
101
102
103
104
105 int opal_ifnametoindex(const char* if_name)
106 {
107 opal_if_t* intf;
108
109 OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
110 if (strcmp(intf->if_name, if_name) == 0) {
111 return intf->if_index;
112 }
113 }
114 return -1;
115 }
116
117
118
119
120
121
122
123 int opal_ifnametokindex(const char* if_name)
124 {
125 opal_if_t* intf;
126
127 OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
128 if (strcmp(intf->if_name, if_name) == 0) {
129 return intf->if_kernel_index;
130 }
131 }
132 return -1;
133 }
134
135
136
137
138
139
140
141 int opal_ifindextokindex(int if_index)
142 {
143 opal_if_t* intf;
144
145 OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
146 if (if_index == intf->if_index) {
147 return intf->if_kernel_index;
148 }
149 }
150 return -1;
151 }
152
153
154
155
156
157
158
159 int opal_ifaddrtoname(const char* if_addr, char* if_name, int length)
160 {
161 opal_if_t* intf;
162 int error;
163 struct addrinfo hints, *res = NULL, *r;
164
165
166 if (opal_if_do_not_resolve) {
167
168
169
170 return OPAL_ERR_NOT_FOUND;
171 }
172
173 memset(&hints, 0, sizeof(hints));
174 hints.ai_family = PF_UNSPEC;
175 hints.ai_socktype = SOCK_STREAM;
176 error = getaddrinfo(if_addr, NULL, &hints, &res);
177
178 if (error) {
179 if (NULL != res) {
180 freeaddrinfo (res);
181 }
182 return OPAL_ERR_NOT_FOUND;
183 }
184
185 for (r = res; r != NULL; r = r->ai_next) {
186 OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
187 if (AF_INET == r->ai_family) {
188 struct sockaddr_in ipv4;
189 struct sockaddr_in *inaddr;
190
191 inaddr = (struct sockaddr_in*) &intf->if_addr;
192 memcpy (&ipv4, r->ai_addr, r->ai_addrlen);
193
194 if (inaddr->sin_addr.s_addr == ipv4.sin_addr.s_addr) {
195 opal_string_copy(if_name, intf->if_name, length);
196 freeaddrinfo (res);
197 return OPAL_SUCCESS;
198 }
199 }
200 #if OPAL_ENABLE_IPV6
201 else {
202 if (IN6_ARE_ADDR_EQUAL(&((struct sockaddr_in6*) &intf->if_addr)->sin6_addr,
203 &((struct sockaddr_in6*) r->ai_addr)->sin6_addr)) {
204 opal_string_copy(if_name, intf->if_name, length);
205 freeaddrinfo (res);
206 return OPAL_SUCCESS;
207 }
208 }
209 #endif
210 }
211 }
212 if (NULL != res) {
213 freeaddrinfo (res);
214 }
215
216
217 return OPAL_ERR_NOT_FOUND;
218 }
219
220
221
222
223
224
225 int opal_ifaddrtokindex(const char* if_addr)
226 {
227 opal_if_t* intf;
228 int error;
229 struct addrinfo hints, *res = NULL, *r;
230 int if_kernel_index;
231 size_t len;
232
233 memset(&hints, 0, sizeof(hints));
234 hints.ai_family = PF_UNSPEC;
235 hints.ai_socktype = SOCK_STREAM;
236 error = getaddrinfo(if_addr, NULL, &hints, &res);
237
238 if (error) {
239 if (NULL != res) {
240 freeaddrinfo (res);
241 }
242 return OPAL_ERR_NOT_FOUND;
243 }
244
245 for (r = res; r != NULL; r = r->ai_next) {
246 OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
247 if (AF_INET == r->ai_family && AF_INET == intf->af_family) {
248 struct sockaddr_in ipv4;
249 len = (r->ai_addrlen < sizeof(struct sockaddr_in)) ? r->ai_addrlen : sizeof(struct sockaddr_in);
250 memcpy(&ipv4, r->ai_addr, len);
251 if (opal_net_samenetwork((struct sockaddr*)&ipv4, (struct sockaddr*)&intf->if_addr, intf->if_mask)) {
252 if_kernel_index = intf->if_kernel_index;
253 freeaddrinfo (res);
254 return if_kernel_index;
255 }
256 }
257 #if OPAL_ENABLE_IPV6
258 else if (AF_INET6 == r->ai_family && AF_INET6 == intf->af_family) {
259 struct sockaddr_in6 ipv6;
260 len = (r->ai_addrlen < sizeof(struct sockaddr_in6)) ? r->ai_addrlen : sizeof(struct sockaddr_in6);
261 memcpy(&ipv6, r->ai_addr, len);
262 if (opal_net_samenetwork((struct sockaddr*)((struct sockaddr_in6*)&intf->if_addr),
263 (struct sockaddr*)&ipv6, intf->if_mask)) {
264 if_kernel_index = intf->if_kernel_index;
265 freeaddrinfo (res);
266 return if_kernel_index;
267 }
268 }
269 #endif
270 }
271 }
272 if (NULL != res) {
273 freeaddrinfo (res);
274 }
275 return OPAL_ERR_NOT_FOUND;
276 }
277
278
279
280
281
282 int opal_ifcount(void)
283 {
284 return opal_list_get_size(&opal_if_list);
285 }
286
287
288
289
290
291
292
293 int opal_ifbegin(void)
294 {
295 opal_if_t *intf;
296
297 intf = (opal_if_t*)opal_list_get_first(&opal_if_list);
298 if (NULL != intf)
299 return intf->if_index;
300 return (-1);
301 }
302
303
304
305
306
307
308
309
310 int opal_ifnext(int if_index)
311 {
312 opal_if_t *intf;
313
314 OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
315 if (intf->if_index == if_index) {
316 do {
317 opal_if_t* if_next = (opal_if_t*)opal_list_get_next(intf);
318 opal_if_t* if_end = (opal_if_t*)opal_list_get_end(&opal_if_list);
319 if (if_next == if_end) {
320 return -1;
321 }
322 intf = if_next;
323 } while(intf->if_index == if_index);
324 return intf->if_index;
325 }
326 }
327 return (-1);
328 }
329
330
331
332
333
334
335
336 int opal_ifindextoaddr(int if_index, struct sockaddr* if_addr, unsigned int length)
337 {
338 opal_if_t* intf;
339
340 OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
341 if (intf->if_index == if_index) {
342 memcpy(if_addr, &intf->if_addr, MIN(length, sizeof (intf->if_addr)));
343 return OPAL_SUCCESS;
344 }
345 }
346 return OPAL_ERROR;
347 }
348
349
350
351
352
353
354 int opal_ifkindextoaddr(int if_kindex, struct sockaddr* if_addr, unsigned int length)
355 {
356 opal_if_t* intf;
357
358 OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
359 if (intf->if_kernel_index == if_kindex) {
360 memcpy(if_addr, &intf->if_addr, MIN(length, sizeof (intf->if_addr)));
361 return OPAL_SUCCESS;
362 }
363 }
364 return OPAL_ERROR;
365 }
366
367
368
369
370
371
372
373 int opal_ifindextomask(int if_index, uint32_t* if_mask, int length)
374 {
375 opal_if_t* intf;
376
377 OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
378 if (intf->if_index == if_index) {
379 memcpy(if_mask, &intf->if_mask, length);
380 return OPAL_SUCCESS;
381 }
382 }
383 return OPAL_ERROR;
384 }
385
386
387
388
389
390
391 int opal_ifindextomac(int if_index, uint8_t mac[6])
392 {
393 opal_if_t* intf;
394
395 OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
396 if (intf->if_index == if_index) {
397 memcpy(mac, &intf->if_mac, 6);
398 return OPAL_SUCCESS;
399 }
400 }
401 return OPAL_ERROR;
402 }
403
404
405
406
407
408
409 int opal_ifindextomtu(int if_index, int *mtu)
410 {
411 opal_if_t* intf;
412
413 OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
414 if (intf->if_index == if_index) {
415 *mtu = intf->ifmtu;
416 return OPAL_SUCCESS;
417 }
418 }
419 return OPAL_ERROR;
420 }
421
422
423
424
425
426
427 int opal_ifindextoflags(int if_index, uint32_t* if_flags)
428 {
429 opal_if_t* intf;
430
431 OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
432 if (intf->if_index == if_index) {
433 memcpy(if_flags, &intf->if_flags, sizeof(uint32_t));
434 return OPAL_SUCCESS;
435 }
436 }
437 return OPAL_ERROR;
438 }
439
440
441
442
443
444
445
446
447 int opal_ifindextoname(int if_index, char* if_name, int length)
448 {
449 opal_if_t *intf;
450
451 OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
452 if (intf->if_index == if_index) {
453 opal_string_copy(if_name, intf->if_name, length);
454 return OPAL_SUCCESS;
455 }
456 }
457 return OPAL_ERROR;
458 }
459
460
461
462
463
464
465
466 int opal_ifkindextoname(int if_kindex, char* if_name, int length)
467 {
468 opal_if_t *intf;
469
470 OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
471 if (intf->if_kernel_index == if_kindex) {
472 opal_string_copy(if_name, intf->if_name, length);
473 return OPAL_SUCCESS;
474 }
475 }
476 return OPAL_ERROR;
477 }
478
479
480 #define ADDRLEN 100
481 bool
482 opal_ifislocal(const char *hostname)
483 {
484 #if OPAL_ENABLE_IPV6
485 char addrname[NI_MAXHOST];
486
487 #else
488 char addrname[ADDRLEN + 1];
489 #endif
490
491 if (OPAL_SUCCESS == opal_ifaddrtoname(hostname, addrname, ADDRLEN)) {
492 return true;
493 }
494
495 return false;
496 }
497
498 static int parse_ipv4_dots(const char *addr, uint32_t* net, int* dots)
499 {
500 const char *start = addr, *end;
501 uint32_t n[]={0,0,0,0};
502 int i;
503
504
505 for( i = 0; i < 4; i++ ) {
506 n[i] = strtoul(start, (char**)&end, 10);
507 if( end == start ) {
508
509
510
511
512
513 break;
514 }
515
516 if( n[i] > 255 ) {
517 return OPAL_ERR_NETWORK_NOT_PARSEABLE;
518 }
519
520 for( start = end; '\0' != *start; start++ )
521 if( '.' != *start ) break;
522 }
523 *dots = i;
524 *net = OPAL_IF_ASSEMBLE_NETWORK(n[0], n[1], n[2], n[3]);
525 return OPAL_SUCCESS;
526 }
527
528 int
529 opal_iftupletoaddr(const char *inaddr, uint32_t *net, uint32_t *mask)
530 {
531 int pval, dots, rc = OPAL_SUCCESS;
532 const char *ptr;
533
534
535 if (NULL != mask) {
536
537 *mask = 0xFFFFFFFF;
538
539
540 if (NULL != (ptr = strchr(inaddr, '/'))) {
541 ptr = ptr + 1;
542
543 if (NULL != strchr(ptr, '.')) {
544
545 rc = parse_ipv4_dots(ptr, mask, &dots);
546 } else {
547
548
549
550 pval = strtol(ptr, NULL, 10);
551 if ((pval > 31) || (pval < 1)) {
552 opal_output(0, "opal_iftupletoaddr: unknown mask");
553 return OPAL_ERR_NETWORK_NOT_PARSEABLE;
554 }
555 *mask = 0xFFFFFFFF << (32 - pval);
556 }
557 } else {
558
559 for (ptr = inaddr, pval = 0; '\0'!= *ptr; ptr++) {
560 if ('.' == *ptr) {
561 pval++;
562 }
563 }
564
565
566
567
568 if (3 == pval) {
569 *mask = 0xFFFFFFFF;
570 } else if (2 == pval) {
571 *mask = 0xFFFFFF00;
572 } else if (1 == pval) {
573 *mask = 0xFFFF0000;
574 } else if (0 == pval) {
575 *mask = 0xFF000000;
576 } else {
577 opal_output(0, "opal_iftupletoaddr: unknown mask");
578 return OPAL_ERR_NETWORK_NOT_PARSEABLE;
579 }
580 }
581 }
582
583
584 if (NULL != net) {
585
586 rc = parse_ipv4_dots(inaddr, net, &dots);
587 }
588
589 return rc;
590 }
591
592
593
594
595
596 bool opal_ifisloopback(int if_index)
597 {
598 opal_if_t* intf;
599
600 OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
601 if (intf->if_index == if_index) {
602 if ((intf->if_flags & IFF_LOOPBACK) != 0) {
603 return true;
604 }
605 }
606 }
607 return false;
608 }
609
610
611
612
613
614 int opal_ifmatches(int kidx, char **nets)
615 {
616 bool named_if;
617 int i, rc;
618 size_t j;
619 int kindex;
620 struct sockaddr_in inaddr;
621 uint32_t addr, netaddr, netmask;
622
623
624 if (OPAL_SUCCESS != (rc = opal_ifkindextoaddr(kidx, (struct sockaddr*)&inaddr, sizeof(inaddr)))) {
625 return rc;
626 }
627 addr = ntohl(inaddr.sin_addr.s_addr);
628
629 for (i=0; NULL != nets[i]; i++) {
630
631
632
633 named_if = false;
634 for (j=0; j < strlen(nets[i]); j++) {
635 if (isalpha(nets[i][j]) && '.' != nets[i][j]) {
636 named_if = true;
637 break;
638 }
639 }
640 if (named_if) {
641 if (0 > (kindex = opal_ifnametokindex(nets[i]))) {
642 continue;
643 }
644 if (kindex == kidx) {
645 return OPAL_SUCCESS;
646 }
647 } else {
648 if (OPAL_SUCCESS != (rc = opal_iftupletoaddr(nets[i], &netaddr, &netmask))) {
649 opal_show_help("help-opal-util.txt", "invalid-net-mask", true, nets[i]);
650 return rc;
651 }
652 if (netaddr == (addr & netmask)) {
653 return OPAL_SUCCESS;
654 }
655 }
656 }
657
658 return OPAL_ERR_NOT_FOUND;
659 }
660
661 void opal_ifgetaliases(char ***aliases)
662 {
663 opal_if_t* intf;
664 char ipv4[INET_ADDRSTRLEN];
665 struct sockaddr_in *addr;
666 #if OPAL_ENABLE_IPV6
667 char ipv6[INET6_ADDRSTRLEN];
668 struct sockaddr_in6 *addr6;
669 #endif
670
671
672 *aliases = NULL;
673
674 OPAL_LIST_FOREACH(intf, &opal_if_list, opal_if_t) {
675 addr = (struct sockaddr_in*) &intf->if_addr;
676
677 if ((intf->if_flags & IFF_LOOPBACK) != 0) {
678 continue;
679 }
680 if (addr->sin_family == AF_INET) {
681 inet_ntop(AF_INET, &(addr->sin_addr.s_addr), ipv4, INET_ADDRSTRLEN);
682 opal_argv_append_nosize(aliases, ipv4);
683 }
684 #if OPAL_ENABLE_IPV6
685 else {
686 addr6 = (struct sockaddr_in6*) &intf->if_addr;
687 inet_ntop(AF_INET6, &(addr6->sin6_addr), ipv6, INET6_ADDRSTRLEN);
688 opal_argv_append_nosize(aliases, ipv6);
689 }
690 #endif
691 }
692 }
693
694 #else
695
696
697
698
699 int
700 opal_ifnametoaddr(const char* if_name,
701 struct sockaddr* if_addr, int size)
702 {
703 return OPAL_ERR_NOT_SUPPORTED;
704 }
705
706 int
707 opal_ifaddrtoname(const char* if_addr,
708 char* if_name, int size)
709 {
710 return OPAL_ERR_NOT_SUPPORTED;
711 }
712
713 int
714 opal_ifnametoindex(const char* if_name)
715 {
716 return OPAL_ERR_NOT_SUPPORTED;
717 }
718
719 int
720 opal_ifnametokindex(const char* if_name)
721 {
722 return OPAL_ERR_NOT_SUPPORTED;
723 }
724
725 int
726 opal_ifindextokindex(int if_index)
727 {
728 return OPAL_ERR_NOT_SUPPORTED;
729 }
730
731 int
732 opal_ifcount(void)
733 {
734 return OPAL_ERR_NOT_SUPPORTED;
735 }
736
737 int
738 opal_ifbegin(void)
739 {
740 return OPAL_ERR_NOT_SUPPORTED;
741 }
742
743 int
744 opal_ifnext(int if_index)
745 {
746 return OPAL_ERR_NOT_SUPPORTED;
747 }
748
749 int
750 opal_ifindextoname(int if_index, char* if_name, int length)
751 {
752 return OPAL_ERR_NOT_SUPPORTED;
753 }
754
755 int
756 opal_ifkindextoname(int kif_index, char* if_name, int length)
757 {
758 return OPAL_ERR_NOT_SUPPORTED;
759 }
760
761 int
762 opal_ifindextoaddr(int if_index, struct sockaddr* if_addr, unsigned int length)
763 {
764 return OPAL_ERR_NOT_SUPPORTED;
765 }
766
767 int
768 opal_ifindextomask(int if_index, uint32_t* if_addr, int length)
769 {
770 return OPAL_ERR_NOT_SUPPORTED;
771 }
772
773 bool
774 opal_ifislocal(const char *hostname)
775 {
776 return false;
777 }
778
779 int
780 opal_iftupletoaddr(const char *inaddr, uint32_t *net, uint32_t *mask)
781 {
782 return 0;
783 }
784
785 int opal_ifmatches(int idx, char **nets)
786 {
787 return OPAL_ERR_NOT_SUPPORTED;
788 }
789
790 void opal_ifgetaliases(char ***aliases)
791 {
792
793 *aliases = NULL;
794 }
795
796 #endif
797