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 "opal_config.h"
16
17 #include <stdlib.h>
18 #include <string.h>
19
20 #include "opal/constants.h"
21 #include "opal/util/output.h"
22 #include "opal/util/string_copy.h"
23 #include "opal/mca/if/if.h"
24 #include "opal/mca/if/base/base.h"
25
26 static int if_posix_open(void);
27
28
29
30
31 opal_if_base_component_t mca_if_posix_ipv4_component = {
32
33
34 {
35 OPAL_IF_BASE_VERSION_2_0_0,
36
37
38 "posix_ipv4",
39 OPAL_MAJOR_VERSION,
40 OPAL_MINOR_VERSION,
41 OPAL_RELEASE_VERSION,
42
43
44 if_posix_open,
45 NULL
46 },
47 {
48
49 MCA_BASE_METADATA_PARAM_CHECKPOINT
50 },
51 };
52
53
54 static int prefix (uint32_t netmask)
55 {
56 uint32_t mask = ntohl(netmask);
57 int plen = 0;
58
59 if (0 == mask) {
60 plen = 32;
61 } else {
62 while ((mask % 2) == 0) {
63 plen += 1;
64 mask /= 2;
65 }
66 }
67
68 return (32 - plen);
69 }
70
71
72 static int if_posix_open(void)
73 {
74 int sd;
75 int lastlen, rem;
76 char *ptr;
77 struct ifconf ifconf;
78 int ifc_len;
79 bool successful_locate = false;
80
81
82
83
84 if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
85 opal_output(0, "opal_ifinit: socket() failed with errno=%d\n",
86 errno);
87 return OPAL_ERROR;
88 }
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107 lastlen = 0;
108 ifc_len = sizeof(struct ifreq) * DEFAULT_NUMBER_INTERFACES;
109 do {
110 ifconf.ifc_len = ifc_len;
111 ifconf.ifc_req = malloc(ifc_len);
112 if (NULL == ifconf.ifc_req) {
113 close(sd);
114 return OPAL_ERROR;
115 }
116
117
118
119
120
121 memset(ifconf.ifc_req, 0, ifconf.ifc_len);
122
123 if (ioctl(sd, SIOCGIFCONF, &ifconf) < 0) {
124
125
126
127 if (errno != EINVAL && lastlen != 0) {
128 opal_output(0, "opal_ifinit: ioctl(SIOCGIFCONF) \
129 failed with errno=%d",
130 errno);
131 free(ifconf.ifc_req);
132 close(sd);
133 return OPAL_ERROR;
134 }
135 } else {
136
137
138
139 if (ifconf.ifc_len == lastlen && ifconf.ifc_len > 0) {
140
141 successful_locate = true;
142 break;
143 }
144 lastlen = ifconf.ifc_len;
145 }
146
147
148
149 free(ifconf.ifc_req);
150 ifc_len = (ifc_len == 0) ? 1 : ifc_len * 2;
151 } while (ifc_len < MAX_IFCONF_SIZE);
152 if (!successful_locate) {
153 opal_output(0, "opal_ifinit: unable to find network interfaces.");
154 close(sd);
155 return OPAL_ERR_FATAL;
156 }
157
158
159
160
161 ptr = (char*) ifconf.ifc_req;
162 rem = ifconf.ifc_len;
163
164
165 while (rem > 0) {
166 struct ifreq* ifr = (struct ifreq*) ptr;
167 opal_if_t *intf;
168 int length;
169
170
171 #ifdef HAVE_STRUCT_SOCKADDR_SA_LEN
172 length = sizeof(struct sockaddr);
173
174 if (ifr->ifr_addr.sa_len > length) {
175 length = ifr->ifr_addr.sa_len;
176 }
177
178 length += sizeof(ifr->ifr_name);
179 #else
180 length = sizeof(struct ifreq);
181 #endif
182
183 rem -= length;
184 ptr += length;
185
186
187 if (AF_INET != ifr->ifr_addr.sa_family) {
188 continue;
189 }
190
191 if (ioctl(sd, SIOCGIFFLAGS, ifr) < 0) {
192 opal_output(0, "opal_ifinit: ioctl(SIOCGIFFLAGS) failed with errno=%d", errno);
193 continue;
194 }
195 if ((ifr->ifr_flags & IFF_UP) == 0) {
196 continue;
197 }
198 #ifdef IFF_SLAVE
199
200
201 if ((ifr->ifr_flags & IFF_SLAVE) != 0) {
202 continue;
203 }
204 #endif
205 #if 0
206 if (!opal_if_retain_loopback && (ifr->ifr_flags & IFF_LOOPBACK) != 0) {
207 continue;
208 }
209 #endif
210
211 intf = OBJ_NEW(opal_if_t);
212 if (NULL == intf) {
213 opal_output(0, "opal_ifinit: unable to allocated %lu bytes\n", (unsigned long)sizeof(opal_if_t));
214 free(ifconf.ifc_req);
215 close(sd);
216 return OPAL_ERR_OUT_OF_RESOURCE;
217 }
218 intf->af_family = AF_INET;
219
220
221 memset(intf->if_name, 0, sizeof(intf->if_name));
222 opal_string_copy(intf->if_name, ifr->ifr_name, sizeof(intf->if_name));
223 intf->if_flags = ifr->ifr_flags;
224
225
226 intf->if_index = opal_list_get_size(&opal_if_list)+1;
227
228 opal_output_verbose(1, opal_if_base_framework.framework_output,
229 "found interface %s", intf->if_name);
230
231
232 #ifndef SIOCGIFINDEX
233 intf->if_kernel_index = intf->if_index;
234 #else
235 if (ioctl(sd, SIOCGIFINDEX, ifr) < 0) {
236 opal_output(0,"opal_ifinit: ioctl(SIOCGIFINDEX) failed with errno=%d", errno);
237 OBJ_RELEASE(intf);
238 continue;
239 }
240 #if defined(ifr_ifindex)
241 intf->if_kernel_index = ifr->ifr_ifindex;
242 #elif defined(ifr_index)
243 intf->if_kernel_index = ifr->ifr_index;
244 #else
245 intf->if_kernel_index = -1;
246 #endif
247 #endif
248
249
250
251 if (ioctl(sd, SIOCGIFADDR, ifr) < 0) {
252 opal_output(0, "opal_ifinit: ioctl(SIOCGIFADDR) failed with errno=%d", errno);
253 OBJ_RELEASE(intf);
254 break;
255 }
256 if (AF_INET != ifr->ifr_addr.sa_family) {
257 OBJ_RELEASE(intf);
258 continue;
259 }
260
261
262 memcpy(&intf->if_addr, &ifr->ifr_addr, sizeof(struct sockaddr_in));
263
264 if (ioctl(sd, SIOCGIFNETMASK, ifr) < 0) {
265 opal_output(0, "opal_ifinit: ioctl(SIOCGIFNETMASK) failed with errno=%d", errno);
266 OBJ_RELEASE(intf);
267 continue;
268 }
269
270
271 intf->if_mask = prefix(((struct sockaddr_in*) &ifr->ifr_addr)->sin_addr.s_addr);
272
273 #if defined(SIOCGIFHWADDR) && defined(HAVE_STRUCT_IFREQ_IFR_HWADDR)
274
275 if (ioctl(sd, SIOCGIFHWADDR, ifr) < 0) {
276 opal_output(0, "opal_ifinit: ioctl(SIOCGIFHWADDR) failed with errno=%d", errno);
277 break;
278 }
279 memcpy(intf->if_mac, ifr->ifr_hwaddr.sa_data, 6);
280 #endif
281
282 #if defined(SIOCGIFMTU) && defined(HAVE_STRUCT_IFREQ_IFR_MTU)
283
284 if (ioctl(sd, SIOCGIFMTU, ifr) < 0) {
285 opal_output(0, "opal_ifinit: ioctl(SIOCGIFMTU) failed with errno=%d", errno);
286 break;
287 }
288 intf->ifmtu = ifr->ifr_mtu;
289 #endif
290
291 opal_list_append(&opal_if_list, &(intf->super));
292 }
293 free(ifconf.ifc_req);
294 close(sd);
295
296 return OPAL_SUCCESS;
297 }
298
299