This source file includes following definitions.
- if_solaris_ipv6_open
1
2
3
4
5
6
7
8
9
10
11
12
13
14 #include "pmix_config.h"
15 #include "pmix_common.h"
16
17 #include <string.h>
18 #ifdef HAVE_UNISTD_H
19 #include <unistd.h>
20 #endif
21 #include <errno.h>
22 #ifdef HAVE_SYS_TYPES_H
23 #include <sys/types.h>
24 #endif
25 #ifdef HAVE_SYS_SOCKET_H
26 #include <sys/socket.h>
27 #endif
28 #ifdef HAVE_SYS_SOCKIO_H
29 #include <sys/sockio.h>
30 #endif
31 #ifdef HAVE_SYS_IOCTL_H
32 #include <sys/ioctl.h>
33 #endif
34 #ifdef HAVE_NETINET_IN_H
35 #include <netinet/in.h>
36 #endif
37 #ifdef HAVE_ARPA_INET_H
38 #include <arpa/inet.h>
39 #endif
40 #ifdef HAVE_NET_IF_H
41 #if defined(__APPLE__) && defined(_LP64)
42
43
44
45
46
47
48
49
50
51
52 #pragma pack(push,4)
53 #endif
54 #include <net/if.h>
55 #if defined(__APPLE__) && defined(_LP64)
56 #pragma pack(pop)
57 #endif
58 #endif
59 #ifdef HAVE_NETDB_H
60 #include <netdb.h>
61 #endif
62 #ifdef HAVE_IFADDRS_H
63 #include <ifaddrs.h>
64 #endif
65
66 #include "src/util/output.h"
67 #include "src/util/pif.h"
68 #include "src/mca/pif/pif.h"
69 #include "src/mca/pif/base/base.h"
70
71 static int if_solaris_ipv6_open(void);
72
73
74 pmix_pif_base_component_t mca_pif_solaris_ipv6_component = {
75
76
77 .base = {
78 PMIX_PIF_BASE_VERSION_2_0_0,
79
80
81 "solaris_ipv6",
82 PMIX_MAJOR_VERSION,
83 PMIX_MINOR_VERSION,
84 PMIX_RELEASE_VERSION,
85
86
87 if_solaris_ipv6_open,
88 NULL
89 },
90 .data = {
91
92 PMIX_MCA_BASE_METADATA_PARAM_CHECKPOINT
93 },
94 };
95
96
97 static int if_solaris_ipv6_open(void)
98 {
99 int i;
100 int sd;
101 int error;
102 uint16_t kindex;
103 struct lifnum lifnum;
104 struct lifconf lifconf;
105 struct lifreq *lifreq, lifquery;
106
107 sd = socket (AF_INET6, SOCK_DGRAM, 0);
108 if (sd < 0) {
109 pmix_output (0, "pmix_ifinit: unable to open IPv6 socket\n");
110 return PMIX_ERROR;
111 }
112
113
114 lifnum.lifn_family = AF_INET6;
115 lifnum.lifn_flags = 0;
116 lifnum.lifn_count = 0;
117
118
119 error = ioctl (sd, SIOCGLIFNUM, &lifnum);
120 if (error < 0) {
121 pmix_output (0,
122 "pmix_ifinit: ioctl SIOCGLIFNUM failed with errno=%d\n", errno);
123 return PMIX_ERROR;
124 }
125
126 memset (&lifconf, 0, sizeof (struct lifconf));
127 memset (&lifquery, 0, sizeof (struct lifreq));
128 lifconf.lifc_family = AF_INET6;
129 lifconf.lifc_flags = 0;
130 lifconf.lifc_len = lifnum.lifn_count * sizeof (struct lifreq) * 2;
131 lifconf.lifc_buf = malloc (lifconf.lifc_len);
132 if (NULL == lifconf.lifc_buf) {
133 pmix_output (0, "pmix_ifinit: IPv6 discovery: malloc() failed\n");
134 return PMIX_ERR_OUT_OF_RESOURCE;
135 }
136
137 memset (lifconf.lifc_buf, 0, lifconf.lifc_len);
138
139 error = ioctl (sd, SIOCGLIFCONF, &lifconf);
140 if (error < 0) {
141 pmix_output (0,
142 "pmix_ifinit: IPv6 SIOCGLIFCONF failed with errno=%d\n", errno);
143 }
144
145 for (i = 0; i + sizeof (struct lifreq) <= lifconf.lifc_len;
146 i += sizeof (*lifreq)) {
147
148 lifreq = (struct lifreq *)((caddr_t)lifconf.lifc_buf + i);
149 pmix_strncpy (lifquery.lifr_name, lifreq->lifr_name,
150 sizeof (lifquery.lifr_name)-1);
151
152
153 error = ioctl (sd, SIOCGLIFINDEX, &lifquery);
154 if (error < 0) {
155 pmix_output (0,
156 "pmix_ifinit: SIOCGLIFINDEX failed with errno=%d\n", errno);
157 return PMIX_ERROR;
158 }
159 kindex = lifquery.lifr_index;
160
161
162 error = ioctl (sd, SIOCGLIFFLAGS, &lifquery);
163 if (error < 0) {
164 pmix_output (0,
165 "pmix_ifinit: SIOCGLIFFLAGS failed with errno=%d\n", errno);
166 return PMIX_ERROR;
167 }
168
169 if (AF_INET6 == lifreq->lifr_addr.ss_family) {
170 struct sockaddr_in6* my_addr = (struct sockaddr_in6*) &lifreq->lifr_addr;
171
172
173
174
175
176
177
178
179 if ( (!pmix_if_retain_loopback && !IN6_IS_ADDR_LOOPBACK (&my_addr->sin6_addr)) &&
180 (! IN6_IS_ADDR_LINKLOCAL (&my_addr->sin6_addr))) {
181
182 pmix_pif_t *intf;
183
184 intf = PMIX_NEW(pmix_pif_t);
185 if (NULL == intf) {
186 pmix_output (0,
187 "pmix_ifinit: unable to allocate %d bytes\n",
188 sizeof (pmix_pif_t));
189 return PMIX_ERR_OUT_OF_RESOURCE;
190 }
191 intf->af_family = AF_INET6;
192
193 pmix_strncpy (intf->if_name, lifreq->lifr_name, IF_NAMESIZE-1);
194 intf->if_index = pmix_list_get_size(&pmix_if_list)+1;
195 memcpy(&intf->if_addr, my_addr, sizeof (*my_addr));
196 intf->if_mask = 64;
197
198 intf->if_flags =
199 (uint32_t)(0x00000000ffffffff) & lifquery.lifr_flags;
200
201
202 pmix_list_append (&pmix_if_list, &(intf->super));
203 }
204 }
205 }
206
207 if (NULL != lifconf.lifc_buf) {
208 free (lifconf.lifc_buf);
209 }
210
211 return PMIX_SUCCESS;
212 }