Print this page
Split |
Close |
Expand all |
Collapse all |
--- old/src/windows/native/java/net/NetworkInterface.c
+++ new/src/windows/native/java/net/NetworkInterface.c
1 1 /*
2 2 * Copyright 2000-2008 Sun Microsystems, Inc. All Rights Reserved.
3 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 4 *
5 5 * This code is free software; you can redistribute it and/or modify it
6 6 * under the terms of the GNU General Public License version 2 only, as
7 7 * published by the Free Software Foundation. Sun designates this
8 8 * particular file as subject to the "Classpath" exception as provided
9 9 * by Sun in the LICENSE file that accompanied this code.
10 10 *
11 11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 14 * version 2 for more details (a copy is included in the LICENSE file that
15 15 * accompanied this code).
16 16 *
17 17 * You should have received a copy of the GNU General Public License version
18 18 * 2 along with this work; if not, write to the Free Software Foundation,
19 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 20 *
21 21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 23 * have any questions.
24 24 */
25 25
26 26 #include <stdlib.h>
27 27 #include <windows.h>
28 28 #include <winsock2.h> /* needed for htonl */
29 29 #include <iprtrmib.h>
30 30 #include <assert.h>
31 31
32 32 #include "java_net_NetworkInterface.h"
33 33 #include "jni_util.h"
34 34
35 35 #include "NetworkInterface.h"
36 36
37 37 /*
38 38 * Windows implementation of the java.net.NetworkInterface native methods.
39 39 * This module provides the implementations of getAll, getByName, getByIndex,
40 40 * and getByAddress.
41 41 *
42 42 * Interfaces and addresses are enumerated using the IP helper routines
43 43 * GetIfTable, GetIfAddrTable resp. These routines are available on Windows
44 44 * 98, NT SP+4, 2000, and XP. They are also available on Windows 95 if
45 45 * IE is upgraded to 5.x.
46 46 *
47 47 * Windows does not have any standard for device names so we are forced
48 48 * to use our own convention which is based on the normal Unix naming
49 49 * convention ("lo" for the loopback, eth0, eth1, .. for ethernet devices,
50 50 * tr0, tr1, .. for token ring, and so on). This convention gives us
51 51 * consistency across multiple Windows editions and also consistency with
52 52 * Solaris/Linux device names. Note that we always enumerate in index
53 53 * order and this ensures consistent device number across invocations.
54 54 */
55 55
56 56
57 57 /* IP helper library routines */
58 58 int (PASCAL FAR *GetIpAddrTable_fn)();
59 59 int (PASCAL FAR *GetIfTable_fn)();
60 60 int (PASCAL FAR *GetFriendlyIfIndex_fn)();
61 61 int (PASCAL FAR *GetAdaptersAddresses_fn)();
62 62 int (PASCAL FAR *GetAdaptersInfo_fn)();
63 63 int (PASCAL FAR *GetNumberOfInterfaces_fn)();
64 64
65 65 /* Enumeration routines */
66 66 typedef int (*EnumerateNetInterfaces)(JNIEnv *, netif **);
67 67 typedef int(*EnumerateNetAddresses)(JNIEnv *, netif *, netaddr **);
68 68
69 69 static EnumerateNetInterfaces enumInterfaces_fn;
70 70 static EnumerateNetAddresses enumAddresses_fn;
71 71
72 72 /* Windows 9x routines are external (not needed on 64-bit) */
73 73 #ifndef _WIN64
74 74 extern int enumInterfaces_win9x(JNIEnv *, netif **);
75 75 extern int enumAddresses_win9x(JNIEnv *, netif *, netaddr **);
76 76 extern int init_win9x(void);
77 77 #endif
78 78
79 79
↓ open down ↓ |
79 lines elided |
↑ open up ↑ |
80 80 /* Windows 95/98/ME running */
81 81 static jboolean isW9x;
82 82
83 83 /* Windows version supports */
84 84 static jboolean os_supports_ipv6;
85 85
86 86 /* various JNI ids */
87 87
88 88 jclass ni_class; /* NetworkInterface */
89 89
90 -jmethodID ni_ctor; /* NetworkInterface() */
90 +jmethodID ni_ctrID; /* NetworkInterface() */
91 91
92 92 jfieldID ni_indexID; /* NetworkInterface.index */
93 93 jfieldID ni_addrsID; /* NetworkInterface.addrs */
94 94 jfieldID ni_bindsID; /* NetworkInterface.bindings */
95 95 jfieldID ni_nameID; /* NetworkInterface.name */
96 96 jfieldID ni_displayNameID; /* NetworkInterface.displayName */
97 97 jfieldID ni_childsID; /* NetworkInterface.childs */
98 -jclass ni_iacls; /* InetAddress */
99 -jfieldID ni_iaAddr; /* InetAddress.address */
100 98
101 -jclass ni_ia4cls; /* Inet4Address */
102 -jmethodID ni_ia4Ctor; /* Inet4Address() */
103 -
104 -jclass ni_ia6cls; /* Inet6Address */
105 -jmethodID ni_ia6ctrID; /* Inet6Address() */
106 -jfieldID ni_ia6ipaddressID;
107 -jfieldID ni_ia6ipaddressID;
108 -
109 99 jclass ni_ibcls; /* InterfaceAddress */
110 100 jmethodID ni_ibctrID; /* InterfaceAddress() */
111 101 jfieldID ni_ibaddressID; /* InterfaceAddress.address */
112 102 jfieldID ni_ibbroadcastID; /* InterfaceAddress.broadcast */
113 103 jfieldID ni_ibmaskID; /* InterfaceAddress.maskLength */
114 104
115 105 /*
116 106 * Support routines to free netif and netaddr lists
117 107 */
118 108 void free_netif(netif *netifP) {
119 109 netif *curr = netifP;
120 110 while (curr != NULL) {
121 111 if (curr->name != NULL)
122 112 free(curr->name);
123 113 if (curr->displayName != NULL)
124 114 free(curr->displayName);
125 115 if (curr->addrs != NULL)
126 116 free_netaddr (curr->addrs);
127 117 netifP = netifP->next;
128 118 free(curr);
129 119 curr = netifP;
130 120 }
131 121 }
132 122
133 123 void free_netaddr(netaddr *netaddrP) {
134 124 netaddr *curr = netaddrP;
135 125 while (curr != NULL) {
136 126 netaddrP = netaddrP->next;
137 127 free(curr);
138 128 curr = netaddrP;
139 129 }
140 130 }
141 131
142 132 /*
143 133 * Returns the interface structure from the table with the matching index.
144 134 */
145 135 MIB_IFROW *getIF(jint index) {
146 136 MIB_IFTABLE *tableP;
147 137 MIB_IFROW *ifrowP, *ret = NULL;
148 138 ULONG size;
149 139 DWORD i, count;
150 140 jint ifindex;
151 141
152 142 /*
153 143 * Ask the IP Helper library to enumerate the adapters
154 144 */
155 145 size = sizeof(MIB_IFTABLE);
156 146 tableP = (MIB_IFTABLE *)malloc(size);
157 147 count = (*GetIfTable_fn)(tableP, &size, TRUE);
158 148 if (count == ERROR_INSUFFICIENT_BUFFER || count == ERROR_BUFFER_OVERFLOW) {
159 149 tableP = (MIB_IFTABLE *)realloc(tableP, size);
160 150 count = (*GetIfTable_fn)(tableP, &size, TRUE);
161 151 }
162 152
163 153 if (count != NO_ERROR) {
164 154 if (tableP != NULL)
165 155 free(tableP);
166 156 return NULL;
167 157 }
168 158
169 159 if (tableP != NULL) {
170 160 ifrowP = tableP->table;
171 161 for (i=0; i<tableP->dwNumEntries; i++) {
172 162 /*
173 163 * Warning the real index is obtained by GetFriendlyIfIndex()
174 164 */
175 165 ifindex = (*GetFriendlyIfIndex_fn)(ifrowP->dwIndex);
176 166 if (ifindex == index) {
177 167 /*
178 168 * Create a copy of the entry so that we can free the table.
179 169 */
180 170 ret = (MIB_IFROW *) malloc(sizeof(MIB_IFROW));
181 171 memcpy(ret, ifrowP, sizeof(MIB_IFROW));
182 172 break;
183 173 }
184 174
185 175 /* onto the next interface */
186 176 ifrowP++;
187 177 }
188 178 free(tableP);
189 179 }
190 180 return ret;
191 181 }
192 182
193 183 /*
194 184 * Enumerate network interfaces using IP Helper Library routine GetIfTable.
195 185 * We use GetIfTable rather than other IP helper routines because it's
196 186 * available on 98 & NT SP4+.
197 187 *
198 188 * Returns the number of interfaces found or -1 if error. If no error
199 189 * occurs then netifPP be returned as list of netif structures or NULL
200 190 * if no interfaces are found.
201 191 */
202 192 int enumInterfaces_win(JNIEnv *env, netif **netifPP)
203 193 {
204 194 MIB_IFTABLE *tableP;
205 195 MIB_IFROW *ifrowP;
206 196 ULONG size;
207 197 DWORD ret;
208 198 int count;
209 199 netif *netifP;
210 200 DWORD i;
211 201 int lo=0, eth=0, tr=0, fddi=0, ppp=0, sl=0, net=0;
212 202
213 203 /*
214 204 * Ask the IP Helper library to enumerate the adapters
215 205 */
216 206 size = sizeof(MIB_IFTABLE);
217 207 tableP = (MIB_IFTABLE *)malloc(size);
218 208 ret = (*GetIfTable_fn)(tableP, &size, TRUE);
219 209 if (ret == ERROR_INSUFFICIENT_BUFFER || ret == ERROR_BUFFER_OVERFLOW) {
220 210 tableP = (MIB_IFTABLE *)realloc(tableP, size);
221 211 ret = (*GetIfTable_fn)(tableP, &size, TRUE);
222 212 }
223 213
224 214 if (ret != NO_ERROR) {
225 215 if (tableP != NULL)
226 216 free(tableP);
227 217
228 218 #ifndef _WIN64
229 219 if (isW9x && ret == ERROR_NOT_SUPPORTED) {
230 220 /*
231 221 * If ERROR_NOT_SUPPORTED is returned on Windows 98 it means that
232 222 * IE5.0 has been installed. In this case we revert to the Windows 95
233 223 * approach and avoid using the IP Helper Library.
234 224 * See: http://support.microsoft.com/support/kb/articles/q234/5/73.asp
235 225 */
236 226 enumInterfaces_fn = enumInterfaces_win9x;
237 227 enumAddresses_fn = enumAddresses_win9x;
238 228 init_win9x();
239 229
240 230 return (*enumInterfaces_fn)(env, netifPP);
241 231 }
242 232 #endif
243 233
244 234 JNU_ThrowByName(env, "java/lang/Error",
245 235 "IP Helper Library GetIfTable function failed");
246 236
247 237 return -1;
248 238 }
249 239
250 240 /*
251 241 * Iterate through the list of adapters
252 242 */
253 243 count = 0;
254 244 netifP = NULL;
255 245
256 246 ifrowP = tableP->table;
257 247 for (i=0; i<tableP->dwNumEntries; i++) {
258 248 char dev_name[8];
259 249 netif *curr;
260 250
261 251 /*
262 252 * Generate a name for the device as Windows doesn't have any
263 253 * real concept of a device name.
264 254 */
265 255 switch (ifrowP->dwType) {
266 256 case MIB_IF_TYPE_ETHERNET:
267 257 sprintf(dev_name, "eth%d", eth++);
268 258 break;
269 259
270 260 case MIB_IF_TYPE_TOKENRING:
271 261 sprintf(dev_name, "tr%d", tr++);
272 262 break;
273 263
274 264 case MIB_IF_TYPE_FDDI:
275 265 sprintf(dev_name, "fddi%d", fddi++);
276 266 break;
277 267
278 268 case MIB_IF_TYPE_LOOPBACK:
279 269 /* There should only be only IPv4 loopback address */
280 270 if (lo > 0) {
281 271 continue;
282 272 }
283 273 strcpy(dev_name, "lo");
284 274 lo++;
285 275 break;
286 276
287 277 case MIB_IF_TYPE_PPP:
288 278 sprintf(dev_name, "ppp%d", ppp++);
289 279 break;
290 280
291 281 case MIB_IF_TYPE_SLIP:
292 282 sprintf(dev_name, "sl%d", sl++);
293 283 break;
294 284
295 285 default:
296 286 sprintf(dev_name, "net%d", net++);
297 287 }
298 288
299 289 /*
300 290 * Allocate a netif structure and space for the name and
301 291 * display name (description in this case).
302 292 */
303 293 curr = (netif *)calloc(1, sizeof(netif));
304 294 if (curr != NULL) {
305 295 curr->name = (char *)malloc(strlen(dev_name) + 1);
306 296 curr->displayName = (char *)malloc(ifrowP->dwDescrLen + 1);
307 297
308 298 if (curr->name == NULL || curr->displayName == NULL) {
309 299 if (curr->name) free(curr->name);
310 300 if (curr->displayName) free(curr->displayName);
311 301 curr = NULL;
312 302 }
313 303 }
314 304 if (curr == NULL) {
315 305 JNU_ThrowOutOfMemoryError(env, "heap allocation failure");
316 306 free_netif(netifP);
317 307 free(tableP);
318 308 return -1;
319 309 }
320 310
321 311 /*
322 312 * Populate the interface. Note that we need to convert the
323 313 * index into its "friendly" value as otherwise we will expose
324 314 * 32-bit numbers as index values.
325 315 */
326 316 strcpy(curr->name, dev_name);
327 317 strncpy(curr->displayName, ifrowP->bDescr, ifrowP->dwDescrLen);
328 318 curr->displayName[ifrowP->dwDescrLen] = '\0';
329 319 curr->dwIndex = ifrowP->dwIndex;
330 320 curr->ifType = ifrowP->dwType;
331 321 curr->index = (*GetFriendlyIfIndex_fn)(ifrowP->dwIndex);
332 322
333 323 /*
334 324 * Put the interface at tail of list as GetIfTable(,,TRUE) is
335 325 * returning the interfaces in index order.
336 326 */
337 327 count++;
338 328 if (netifP == NULL) {
339 329 netifP = curr;
340 330 } else {
341 331 netif *tail = netifP;
342 332 while (tail->next != NULL) {
343 333 tail = tail->next;
344 334 }
345 335 tail->next = curr;
346 336 }
347 337
348 338 /* onto the next interface */
349 339 ifrowP++;
350 340 }
351 341
352 342 /*
353 343 * Free the interface table and return the interface list
354 344 */
355 345 if (tableP) {
356 346 free(tableP);
357 347 }
358 348 *netifPP = netifP;
359 349 return count;
360 350 }
361 351
362 352 /*
363 353 * Enumerate the IP addresses on an interface using the IP helper library
364 354 * routine GetIfAddrTable and matching based on the index name. There are
365 355 * more efficient routines but we use GetIfAddrTable because it's avaliable
366 356 * on 98 and NT.
367 357 *
368 358 * Returns the count of addresses, or -1 if error. If no error occurs then
369 359 * netaddrPP will return a list of netaddr structures with the IP addresses.
370 360 */
371 361 int enumAddresses_win(JNIEnv *env, netif *netifP, netaddr **netaddrPP)
372 362 {
373 363 MIB_IPADDRTABLE *tableP;
374 364 ULONG size;
375 365 DWORD ret;
376 366 DWORD i;
377 367 netaddr *netaddrP;
378 368 int count = 0;
379 369 unsigned long mask;
380 370
381 371 /*
382 372 * Use GetIpAddrTable to enumerate the IP Addresses
383 373 */
384 374 size = sizeof(MIB_IPADDRTABLE);
385 375 tableP = (MIB_IPADDRTABLE *)malloc(size);
386 376
387 377 ret = (*GetIpAddrTable_fn)(&tableP, &size, FALSE);
388 378 if (ret == ERROR_INSUFFICIENT_BUFFER || ret == ERROR_BUFFER_OVERFLOW) {
389 379 tableP = (MIB_IPADDRTABLE *)realloc(tableP, size);
390 380 ret = (*GetIpAddrTable_fn)(tableP, &size, FALSE);
391 381 }
392 382 if (ret != NO_ERROR) {
393 383 if (tableP) {
394 384 free(tableP);
395 385 }
396 386 JNU_ThrowByName(env, "java/lang/Error",
397 387 "IP Helper Library GetIpAddrTable function failed");
398 388 return -1;
399 389 }
400 390
401 391 /*
402 392 * Iterate through the table to find the addresses with the
403 393 * matching dwIndex. Ignore 0.0.0.0 addresses.
404 394 */
405 395 count = 0;
406 396 netaddrP = NULL;
407 397
408 398 i = 0;
409 399 while (i<tableP->dwNumEntries) {
410 400 if (tableP->table[i].dwIndex == netifP->dwIndex &&
411 401 tableP->table[i].dwAddr != 0) {
412 402
413 403 netaddr *curr = (netaddr *)malloc(sizeof(netaddr));
414 404 if (curr == NULL) {
415 405 JNU_ThrowOutOfMemoryError(env, "heap allocation failure");
416 406 free_netaddr(netaddrP);
417 407 free(tableP);
418 408 return -1;
419 409 }
420 410
421 411 curr->addr.him4.sin_family = AF_INET;
422 412 curr->addr.him4.sin_addr.s_addr = tableP->table[i].dwAddr;
423 413 /*
424 414 * Get netmask / broadcast address
425 415 */
426 416 switch (netifP->ifType) {
427 417 case MIB_IF_TYPE_ETHERNET:
428 418 case MIB_IF_TYPE_TOKENRING:
429 419 case MIB_IF_TYPE_FDDI:
430 420 case MIB_IF_TYPE_LOOPBACK:
431 421 /**
432 422 * Contrary to what it seems to indicate, dwBCastAddr doesn't
433 423 * contain the broadcast address but 0 or 1 depending on whether
434 424 * the broadcast address should set the bits of the host part
435 425 * to 0 or 1.
436 426 * Yes, I know it's stupid, but what can I say, it's MSFTs API.
437 427 */
438 428 curr->brdcast.him4.sin_family = AF_INET;
439 429 if (tableP->table[i].dwBCastAddr == 1)
440 430 curr->brdcast.him4.sin_addr.s_addr = (tableP->table[i].dwAddr & tableP->table[i].dwMask) | (0xffffffff ^ tableP->table[i].dwMask);
441 431 else
442 432 curr->brdcast.him4.sin_addr.s_addr = (tableP->table[i].dwAddr & tableP->table[i].dwMask);
443 433 mask = ntohl(tableP->table[i].dwMask);
444 434 curr->mask = 0;
445 435 while (mask) {
446 436 mask <<= 1;
447 437 curr->mask++;
448 438 }
449 439 break;
450 440 case MIB_IF_TYPE_PPP:
451 441 case MIB_IF_TYPE_SLIP:
452 442 default:
453 443 /**
454 444 * these don't have broadcast/subnet
455 445 */
456 446 curr->mask = -1;
457 447 break;
458 448 }
459 449
460 450 curr->next = netaddrP;
461 451 netaddrP = curr;
462 452 count++;
463 453 }
464 454 i++;
465 455 }
466 456
467 457 *netaddrPP = netaddrP;
468 458 free(tableP);
469 459 return count;
470 460 }
471 461
472 462 /*
473 463 * Class: java_net_NetworkInterface
474 464 * Method: init
475 465 * Signature: ()V
476 466 */
477 467 JNIEXPORT void JNICALL
478 468 Java_java_net_NetworkInterface_init(JNIEnv *env, jclass cls)
479 469 {
480 470 OSVERSIONINFO ver;
481 471 HANDLE h;
482 472
483 473 /*
484 474 * First check if this is a Windows 9x machine.
485 475 */
486 476 ver.dwOSVersionInfoSize = sizeof(ver);
487 477 GetVersionEx(&ver);
488 478 if (ver.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS && ver.dwMajorVersion == 4) {
489 479 isW9x = JNI_TRUE;
490 480 }
491 481
492 482 /*
493 483 * Try to load the IP Helper Library and obtain the entry points we
494 484 * require. This will succeed on 98, NT SP4+, 2000 & XP. It will
495 485 * fail on Windows 95 (if IE hasn't been updated) and old versions
496 486 * of NT (IP helper library only appeared at SP4). If it fails on
497 487 * Windows 9x we will use the registry approach, otherwise if it
498 488 * fails we throw an Error indicating that we have an incompatible
499 489 * IP helper library.
500 490 */
501 491 h = LoadLibrary("iphlpapi.dll");
502 492 if (h != NULL) {
503 493 GetIpAddrTable_fn =
504 494 (int (PASCAL FAR *)())GetProcAddress(h, "GetIpAddrTable");
505 495 GetIfTable_fn =
506 496 (int (PASCAL FAR *)())GetProcAddress(h, "GetIfTable");
507 497 GetFriendlyIfIndex_fn =
508 498 (int (PASCAL FAR *)())GetProcAddress(h, "GetFriendlyIfIndex");
509 499 GetNumberOfInterfaces_fn =
510 500 (int (PASCAL FAR *)())GetProcAddress(h, "GetNumberOfInterfaces");
511 501 GetAdaptersAddresses_fn =
512 502 (int (PASCAL FAR *)())GetProcAddress(h, "GetAdaptersAddresses");
513 503 GetAdaptersInfo_fn =
514 504 (int (PASCAL FAR *)())GetProcAddress(h, "GetAdaptersInfo");
515 505 }
516 506
517 507 /* IPv6 is supported on Windows versions if the following APIs avail */
518 508
519 509 os_supports_ipv6 = (GetAdaptersAddresses_fn != NULL) &&
520 510 (GetNumberOfInterfaces_fn != NULL) &&
521 511 (GetAdaptersInfo_fn != NULL);
522 512
523 513 if (GetIpAddrTable_fn == NULL ||
524 514 GetIfTable_fn == NULL ||
525 515 GetFriendlyIfIndex_fn == NULL) {
526 516
527 517 #ifndef _WIN64
528 518 if (isW9x) {
529 519 /* Use Windows 9x registry approach which requires initialization */
530 520 enumInterfaces_fn = enumInterfaces_win9x;
531 521 enumAddresses_fn = enumAddresses_win9x;
532 522 init_win9x();
533 523 } else
534 524 #endif
535 525 {
536 526 JNU_ThrowByName(env, "java/lang/Error",
537 527 "Incompatible IP helper library (iphlpapi.dll)");
↓ open down ↓ |
419 lines elided |
↑ open up ↑ |
538 528 return;
539 529 }
540 530 } else {
541 531 enumInterfaces_fn = enumInterfaces_win;
542 532 enumAddresses_fn = enumAddresses_win;
543 533 }
544 534
545 535 /*
546 536 * Get the various JNI ids that we require
547 537 */
548 - ni_class = (*env)->NewGlobalRef(env, cls);
549 - ni_nameID = (*env)->GetFieldID(env, ni_class, "name", "Ljava/lang/String;");
550 - ni_displayNameID = (*env)->GetFieldID(env, ni_class, "displayName", "Ljava/lang/String;");
551 - ni_indexID = (*env)->GetFieldID(env, ni_class, "index", "I");
552 - ni_addrsID = (*env)->GetFieldID(env, ni_class, "addrs", "[Ljava/net/InetAddress;");
553 - ni_bindsID = (*env)->GetFieldID(env, ni_class, "bindings", "[Ljava/net/InterfaceAddress;");
554 - ni_childsID = (*env)->GetFieldID(env, ni_class, "childs", "[Ljava/net/NetworkInterface;");
555 - ni_ctor = (*env)->GetMethodID(env, ni_class, "<init>", "()V");
538 + if (ni_ibmaskID == NULL) {
539 + ni_class = (*env)->NewGlobalRef(env, cls);
540 + ni_nameID = (*env)->GetFieldID(env, ni_class, "name", "Ljava/lang/String;");
541 + ni_displayNameID = (*env)->GetFieldID(env, ni_class, "displayName", "Ljava/lang/String;");
542 + ni_indexID = (*env)->GetFieldID(env, ni_class, "index", "I");
543 + ni_addrsID = (*env)->GetFieldID(env, ni_class, "addrs", "[Ljava/net/InetAddress;");
544 + ni_bindsID = (*env)->GetFieldID(env, ni_class, "bindings", "[Ljava/net/InterfaceAddress;");
545 + ni_childsID = (*env)->GetFieldID(env, ni_class, "childs", "[Ljava/net/NetworkInterface;");
546 + ni_ctrID = (*env)->GetMethodID(env, ni_class, "<init>", "()V");
556 547
557 - ni_iacls = (*env)->FindClass(env, "java/net/InetAddress");
558 - ni_iacls = (*env)->NewGlobalRef(env, ni_iacls);
559 - ni_iaAddr = (*env)->GetFieldID(env, ni_iacls, "address", "I");
548 + init(env);
560 549
561 - ni_ia4cls = (*env)->FindClass(env, "java/net/Inet4Address");
562 - ni_ia4cls = (*env)->NewGlobalRef(env, ni_ia4cls);
563 - ni_ia4Ctor = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V");
564 -
565 - ni_ia6cls = (*env)->FindClass(env, "java/net/Inet6Address");
566 - ni_ia6cls = (*env)->NewGlobalRef(env, ni_ia6cls);
567 - ni_ia6ctrID = (*env)->GetMethodID(env, ni_ia6cls, "<init>", "()V");
568 - ni_ia6ipaddressID = (*env)->GetFieldID(env, ni_ia6cls, "ipaddress", "[B");
569 -
570 - ni_ibcls = (*env)->FindClass(env, "java/net/InterfaceAddress");
571 - ni_ibcls = (*env)->NewGlobalRef(env, ni_ibcls);
572 - ni_ibctrID = (*env)->GetMethodID(env, ni_ibcls, "<init>", "()V");
573 - ni_ibaddressID = (*env)->GetFieldID(env, ni_ibcls, "address", "Ljava/net/InetAddress;");
574 - ni_ibbroadcastID = (*env)->GetFieldID(env, ni_ibcls, "broadcast", "Ljava/net/Inet4Address;");
575 - ni_ibmaskID = (*env)->GetFieldID(env, ni_ibcls, "maskLength", "S");
576 -
550 + ni_ibcls = (*env)->FindClass(env, "java/net/InterfaceAddress");
551 + ni_ibcls = (*env)->NewGlobalRef(env, ni_ibcls);
552 + ni_ibctrID = (*env)->GetMethodID(env, ni_ibcls, "<init>", "()V");
553 + ni_ibaddressID = (*env)->GetFieldID(env, ni_ibcls, "address", "Ljava/net/InetAddress;");
554 + ni_ibbroadcastID = (*env)->GetFieldID(env, ni_ibcls, "broadcast", "Ljava/net/Inet4Address;");
555 + ni_ibmaskID = (*env)->GetFieldID(env, ni_ibcls, "maskLength", "S");
556 + }
577 557 }
578 558
579 559 /*
580 560 * Create a NetworkInterface object, populate the name and index, and
581 561 * populate the InetAddress array based on the IP addresses for this
582 562 * interface.
583 563 */
584 564 jobject createNetworkInterface(JNIEnv *env, netif *ifs, int netaddrCount, netaddr *netaddrP)
585 565 {
586 566 jobject netifObj;
587 567 jobject name, displayName;
588 568 jobjectArray addrArr, bindsArr, childArr;
589 569 netaddr *addrs;
590 570 jint addr_index;
591 571 jint bind_index;
592 572
593 573 /*
594 574 * Create a NetworkInterface object and populate it
595 575 */
596 - netifObj = (*env)->NewObject(env, ni_class, ni_ctor);
576 + netifObj = (*env)->NewObject(env, ni_class, ni_ctrID);
597 577 name = (*env)->NewStringUTF(env, ifs->name);
598 578 if (ifs->dNameIsUnicode) {
599 579 displayName = (*env)->NewString(env, (PWCHAR)ifs->displayName, wcslen ((PWCHAR)ifs->displayName));
600 580 } else {
601 581 displayName = (*env)->NewStringUTF(env, ifs->displayName);
602 582 }
603 583 if (netifObj == NULL || name == NULL || displayName == NULL) {
604 584 return NULL;
605 585 }
606 586 (*env)->SetObjectField(env, netifObj, ni_nameID, name);
607 587 (*env)->SetObjectField(env, netifObj, ni_displayNameID, displayName);
608 588 (*env)->SetIntField(env, netifObj, ni_indexID, ifs->index);
609 589
610 590 /*
↓ open down ↓ |
4 lines elided |
↑ open up ↑ |
611 591 * Get the IP addresses for this interface if necessary
612 592 * Note that 0 is a valid number of addresses.
613 593 */
614 594 if (netaddrCount < 0) {
615 595 netaddrCount = (*enumAddresses_fn)(env, ifs, &netaddrP);
616 596 if ((*env)->ExceptionOccurred(env)) {
617 597 free_netaddr(netaddrP);
618 598 return NULL;
619 599 }
620 600 }
621 - addrArr = (*env)->NewObjectArray(env, netaddrCount, ni_iacls, NULL);
601 + addrArr = (*env)->NewObjectArray(env, netaddrCount, ia_class, NULL);
622 602 if (addrArr == NULL) {
623 603 free_netaddr(netaddrP);
624 604 return NULL;
625 605 }
626 606
627 607 bindsArr = (*env)->NewObjectArray(env, netaddrCount, ni_ibcls, NULL);
628 608 if (bindsArr == NULL) {
629 609 free_netaddr(netaddrP);
630 610 return NULL;
631 611 }
632 612 addrs = netaddrP;
633 613 addr_index = 0;
634 614 bind_index = 0;
635 615 while (addrs != NULL) {
636 616 jobject iaObj, ia2Obj;
637 617 jobject ibObj = NULL;
638 618 if (addrs->addr.him.sa_family == AF_INET) {
639 - iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4Ctor);
619 + iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
640 620 if (iaObj == NULL) {
641 621 free_netaddr(netaddrP);
642 622 return NULL;
643 623 }
644 624 /* default ctor will set family to AF_INET */
645 625
646 - (*env)->SetIntField(env, iaObj, ni_iaAddr, ntohl(addrs->addr.him4.sin_addr.s_addr));
626 + (*env)->SetIntField(env, iaObj, ia_addressID, ntohl(addrs->addr.him4.sin_addr.s_addr));
647 627 if (addrs->mask != -1) {
648 628 ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
649 629 if (ibObj == NULL) {
650 630 free_netaddr(netaddrP);
651 631 return NULL;
652 632 }
653 633 (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
654 - ia2Obj = (*env)->NewObject(env, ni_ia4cls, ni_ia4Ctor);
634 + ia2Obj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
655 635 if (ia2Obj == NULL) {
656 636 free_netaddr(netaddrP);
657 637 return NULL;
658 638 }
659 - (*env)->SetIntField(env, ia2Obj, ni_iaAddr,
639 + (*env)->SetIntField(env, ia2Obj, ia_addressID,
660 640 ntohl(addrs->brdcast.him4.sin_addr.s_addr));
661 641 (*env)->SetObjectField(env, ibObj, ni_ibbroadcastID, ia2Obj);
662 642 (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
663 643 (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
664 644 }
665 645 } else /* AF_INET6 */ {
666 646 int scope;
667 - iaObj = (*env)->NewObject(env, ni_ia6cls, ni_ia6ctrID);
647 + iaObj = (*env)->NewObject(env, ia6_class, ia6_ctrID);
668 648 if (iaObj) {
669 649 jbyteArray ipaddress = (*env)->NewByteArray(env, 16);
670 650 if (ipaddress == NULL) {
671 651 return NULL;
672 652 }
673 653 (*env)->SetByteArrayRegion(env, ipaddress, 0, 16,
674 654 (jbyte *)&(addrs->addr.him6.sin6_addr.s6_addr));
675 655 scope = addrs->addr.him6.sin6_scope_id;
676 656 if (scope != 0) { /* zero is default value, no need to set */
677 657 (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope);
678 658 (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE);
679 659 (*env)->SetObjectField(env, iaObj, ia6_scopeifnameID, netifObj);
680 660 }
681 - (*env)->SetObjectField(env, iaObj, ni_ia6ipaddressID, ipaddress);
661 + (*env)->SetObjectField(env, iaObj, ia6_ipaddressID, ipaddress);
682 662 ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
683 663 if (ibObj == NULL) {
684 664 free_netaddr(netaddrP);
685 665 return NULL;
686 666 }
687 667 (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
688 668 (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
689 669 (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
690 670 }
691 671 }
692 672 (*env)->SetObjectArrayElement(env, addrArr, addr_index, iaObj);
693 673 addrs = addrs->next;
694 674 addr_index++;
695 675 }
696 676 (*env)->SetObjectField(env, netifObj, ni_addrsID, addrArr);
697 677 (*env)->SetObjectField(env, netifObj, ni_bindsID, bindsArr);
698 678
699 679 free_netaddr(netaddrP);
700 680
701 681 /*
702 682 * Windows doesn't have virtual interfaces, so child array
703 683 * is always empty.
704 684 */
705 685 childArr = (*env)->NewObjectArray(env, 0, ni_class, NULL);
706 686 if (childArr == NULL) {
707 687 return NULL;
708 688 }
709 689 (*env)->SetObjectField(env, netifObj, ni_childsID, childArr);
710 690
711 691 /* return the NetworkInterface */
712 692 return netifObj;
713 693 }
714 694
715 695 /*
716 696 * Class: java_net_NetworkInterface
717 697 * Method: getByName0
718 698 * Signature: (Ljava/lang/String;)Ljava/net/NetworkInterface;
719 699 */
720 700 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByName0
721 701 (JNIEnv *env, jclass cls, jstring name)
722 702 {
723 703 netif *ifList, *curr;
724 704 jboolean isCopy;
725 705 const char *name_utf;
726 706 jobject netifObj = NULL;
727 707
728 708 if (os_supports_ipv6 && ipv6_available()) {
729 709 return Java_java_net_NetworkInterface_getByName0_XP (env, cls, name);
730 710 }
731 711
732 712 /* get the list of interfaces */
733 713 if ((*enumInterfaces_fn)(env, &ifList) < 0) {
734 714 return NULL;
735 715 }
736 716
737 717 /* get the name as a C string */
738 718 name_utf = (*env)->GetStringUTFChars(env, name, &isCopy);
739 719
740 720 /* Search by name */
741 721 curr = ifList;
742 722 while (curr != NULL) {
743 723 if (strcmp(name_utf, curr->name) == 0) {
744 724 break;
745 725 }
746 726 curr = curr->next;
747 727 }
748 728
749 729 /* if found create a NetworkInterface */
750 730 if (curr != NULL) {;
751 731 netifObj = createNetworkInterface(env, curr, -1, NULL);
752 732 }
753 733
754 734 /* release the UTF string */
755 735 (*env)->ReleaseStringUTFChars(env, name, name_utf);
756 736
757 737 /* release the interface list */
758 738 free_netif(ifList);
759 739
760 740 return netifObj;
761 741 }
762 742
763 743 /*
764 744 * Class: NetworkInterface
765 745 * Method: getByIndex0
766 746 * Signature: (I)LNetworkInterface;
767 747 */
768 748 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByIndex0
769 749 (JNIEnv *env, jclass cls, jint index)
770 750 {
771 751 netif *ifList, *curr;
772 752 jobject netifObj = NULL;
773 753
774 754 if (os_supports_ipv6 && ipv6_available()) {
775 755 return Java_java_net_NetworkInterface_getByIndex0_XP (env, cls, index);
776 756 }
777 757
778 758 /* get the list of interfaces */
779 759 if ((*enumInterfaces_fn)(env, &ifList) < 0) {
780 760 return NULL;
781 761 }
782 762
783 763 /* search by index */
784 764 curr = ifList;
785 765 while (curr != NULL) {
786 766 if (index == curr->index) {
787 767 break;
788 768 }
789 769 curr = curr->next;
790 770 }
791 771
792 772 /* if found create a NetworkInterface */
793 773 if (curr != NULL) {
794 774 netifObj = createNetworkInterface(env, curr, -1, NULL);
795 775 }
796 776
797 777 /* release the interface list */
798 778 free_netif(ifList);
799 779
800 780 return netifObj;
801 781 }
↓ open down ↓ |
110 lines elided |
↑ open up ↑ |
802 782
803 783 /*
804 784 * Class: java_net_NetworkInterface
805 785 * Method: getByInetAddress0
806 786 * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface;
807 787 */
808 788 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0
809 789 (JNIEnv *env, jclass cls, jobject iaObj)
810 790 {
811 791 netif *ifList, *curr;
812 - jint addr = (*env)->GetIntField(env, iaObj, ni_iaAddr);
792 + jint addr = (*env)->GetIntField(env, iaObj, ia_addressID);
813 793 jobject netifObj = NULL;
814 794
815 795 if (os_supports_ipv6 && ipv6_available()) {
816 796 return Java_java_net_NetworkInterface_getByInetAddress0_XP (env, cls, iaObj);
817 797 }
818 798
819 799 /* get the list of interfaces */
820 800 if ((*enumInterfaces_fn)(env, &ifList) < 0) {
821 801 return NULL;
822 802 }
823 803
824 804 /*
825 805 * Enumerate the addresses on each interface until we find a
826 806 * matching address.
827 807 */
828 808 curr = ifList;
829 809 while (curr != NULL) {
830 810 int count;
831 811 netaddr *addrList;
832 812 netaddr *addrP;
833 813
834 814 /* enumerate the addresses on this interface */
835 815 count = (*enumAddresses_fn)(env, curr, &addrList);
836 816 if (count < 0) {
837 817 free_netif(ifList);
838 818 return NULL;
839 819 }
840 820
841 821 /* iterate through each address */
842 822 addrP = addrList;
843 823
844 824 while (addrP != NULL) {
845 825 if ((unsigned long)addr == ntohl(addrP->addr.him4.sin_addr.s_addr)) {
846 826 break;
847 827 }
848 828 addrP = addrP->next;
849 829 }
850 830
851 831 /*
852 832 * Address matched so create NetworkInterface for this interface
853 833 * and address list.
854 834 */
855 835 if (addrP != NULL) {
856 836 /* createNetworkInterface will free addrList */
857 837 netifObj = createNetworkInterface(env, curr, count, addrList);
858 838 break;
859 839 }
860 840
861 841 /* on next interface */
862 842 curr = curr->next;
863 843 }
864 844
865 845 /* release the interface list */
866 846 free_netif(ifList);
867 847
868 848 return netifObj;
869 849 }
870 850
871 851 /*
872 852 * Class: java_net_NetworkInterface
873 853 * Method: getAll
874 854 * Signature: ()[Ljava/net/NetworkInterface;
875 855 */
876 856 JNIEXPORT jobjectArray JNICALL Java_java_net_NetworkInterface_getAll
877 857 (JNIEnv *env, jclass cls)
878 858 {
879 859 int count;
880 860 netif *ifList, *curr;
881 861 jobjectArray netIFArr;
882 862 jint arr_index;
883 863
884 864 if (os_supports_ipv6 && ipv6_available()) {
885 865 return Java_java_net_NetworkInterface_getAll_XP (env, cls);
886 866 }
887 867
888 868 /*
889 869 * Get list of interfaces
890 870 */
891 871 count = (*enumInterfaces_fn)(env, &ifList);
892 872 if (count < 0) {
893 873 return NULL;
894 874 }
895 875
896 876 /* allocate a NetworkInterface array */
897 877 netIFArr = (*env)->NewObjectArray(env, count, cls, NULL);
898 878 if (netIFArr == NULL) {
899 879 return NULL;
900 880 }
901 881
902 882 /*
903 883 * Iterate through the interfaces, create a NetworkInterface instance
904 884 * for each array element and populate the object.
905 885 */
906 886 curr = ifList;
907 887 arr_index = 0;
908 888 while (curr != NULL) {
909 889 jobject netifObj;
910 890
911 891 netifObj = createNetworkInterface(env, curr, -1, NULL);
912 892 if (netifObj == NULL) {
913 893 return NULL;
914 894 }
915 895
916 896 /* put the NetworkInterface into the array */
917 897 (*env)->SetObjectArrayElement(env, netIFArr, arr_index++, netifObj);
918 898
919 899 curr = curr->next;
920 900 }
921 901
922 902 /* release the interface list */
923 903 free_netif(ifList);
924 904
925 905 return netIFArr;
926 906 }
927 907
928 908 /*
929 909 * Class: java_net_NetworkInterface
930 910 * Method: isUp0
931 911 * Signature: (Ljava/lang/String;)Z
932 912 */
933 913 JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isUp0
934 914 (JNIEnv *env, jclass cls, jstring name, jint index) {
935 915 jboolean ret = JNI_FALSE;
936 916
937 917 if (os_supports_ipv6 && ipv6_available()) {
938 918 return Java_java_net_NetworkInterface_isUp0_XP(env, cls, name, index);
939 919 } else {
940 920 MIB_IFROW *ifRowP;
941 921 ifRowP = getIF(index);
942 922 if (ifRowP != NULL) {
943 923 ret = ifRowP->dwAdminStatus == 1 && (ifRowP->dwOperStatus == MIB_IF_OPER_STATUS_OPERATIONAL || ifRowP->dwOperStatus == MIB_IF_OPER_STATUS_CONNECTED);
944 924 free(ifRowP);
945 925 }
946 926 }
947 927 return ret;
948 928 }
949 929
950 930 /*
951 931 * Class: java_net_NetworkInterface
952 932 * Method: isP2P0
953 933 * Signature: (Ljava/lang/String;I)Z
954 934 */
955 935 JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isP2P0(JNIEnv *env, jclass cls, jstring name, jint index) {
956 936 MIB_IFROW *ifRowP;
957 937 jboolean ret = JNI_FALSE;
958 938
959 939 if (os_supports_ipv6 && ipv6_available()) {
960 940 return Java_java_net_NetworkInterface_isP2P0_XP(env, cls, name, index);
961 941 } else {
962 942 ifRowP = getIF(index);
963 943 if (ifRowP != NULL) {
964 944 switch(ifRowP->dwType) {
965 945 case MIB_IF_TYPE_PPP:
966 946 case MIB_IF_TYPE_SLIP:
967 947 ret = JNI_TRUE;
968 948 break;
969 949 }
970 950 free(ifRowP);
971 951 }
972 952 }
973 953 return ret;
974 954 }
975 955
976 956 /*
977 957 * Class: java_net_NetworkInterface
978 958 * Method: isLoopback0
979 959 * Signature: (Ljava/lang/String;I)Z
980 960 */
981 961 JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isLoopback0
982 962 (JNIEnv *env, jclass cls, jstring name, jint index) {
983 963 MIB_IFROW *ifRowP;
984 964 jboolean ret = JNI_FALSE;
985 965
986 966 if (os_supports_ipv6 && ipv6_available()) {
987 967 return Java_java_net_NetworkInterface_isLoopback0_XP(env, cls, name, index);
988 968 } else {
989 969 ifRowP = getIF(index);
990 970 if (ifRowP != NULL) {
991 971 if (ifRowP->dwType == MIB_IF_TYPE_LOOPBACK)
992 972 ret = JNI_TRUE;
993 973 free(ifRowP);
994 974 }
995 975 return ret;
996 976 }
997 977 }
998 978
999 979 /*
1000 980 * Class: java_net_NetworkInterface
1001 981 * Method: supportsMulticast0
1002 982 * Signature: (Ljava/lang/String;I)Z
1003 983 */
1004 984 JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_supportsMulticast0
1005 985 (JNIEnv *env, jclass cls, jstring name, jint index) {
1006 986 MIB_IFROW *ifRowP;
1007 987 jboolean ret = JNI_TRUE;
1008 988
1009 989 // Let's try to use the newer API (XP & 2003 only)
1010 990 if (GetAdaptersAddresses_fn != NULL) {
1011 991 ret = Java_java_net_NetworkInterface_supportsMulticast0_XP(env, cls,
1012 992 name, index);
1013 993 return ret;
1014 994 }
1015 995 ifRowP = getIF(index);
1016 996 if (ifRowP != NULL) {
1017 997 if (ifRowP->dwType == MIB_IF_TYPE_LOOPBACK)
1018 998 ret = JNI_FALSE;
1019 999 free(ifRowP);
1020 1000 }
1021 1001 return ret;
1022 1002 }
1023 1003
1024 1004 /*
1025 1005 * Class: java_net_NetworkInterface
1026 1006 * Method: getMacAddr0
1027 1007 * Signature: ([bLjava/lang/String;I)[b
1028 1008 */
1029 1009 JNIEXPORT jbyteArray JNICALL Java_java_net_NetworkInterface_getMacAddr0(JNIEnv *env, jclass class, jbyteArray addrArray, jstring name, jint index) {
1030 1010 jbyteArray ret = NULL;
1031 1011 int len;
1032 1012 MIB_IFROW *ifRowP;
1033 1013
1034 1014 if (os_supports_ipv6 && ipv6_available()) {
1035 1015 return Java_java_net_NetworkInterface_getMacAddr0_XP(env, class, name, index);
1036 1016 } else {
1037 1017 ifRowP = getIF(index);
1038 1018 if (ifRowP != NULL) {
1039 1019 switch(ifRowP->dwType) {
1040 1020 case MIB_IF_TYPE_ETHERNET:
1041 1021 case MIB_IF_TYPE_TOKENRING:
1042 1022 case MIB_IF_TYPE_FDDI:
1043 1023 len = ifRowP->dwPhysAddrLen;
1044 1024 ret = (*env)->NewByteArray(env, len);
1045 1025 if (!IS_NULL(ret)) {
1046 1026 (*env)->SetByteArrayRegion(env, ret, 0, len, (jbyte *) ifRowP->bPhysAddr);
1047 1027 }
1048 1028 break;
1049 1029 }
1050 1030 free(ifRowP);
1051 1031 }
1052 1032 return ret;
1053 1033 }
1054 1034 }
1055 1035
1056 1036 /*
1057 1037 * Class: java_net_NetworkInterface
1058 1038 * Method: getMTU0
1059 1039 * Signature: ([bLjava/lang/String;I)I
1060 1040 */
1061 1041 JNIEXPORT jint JNICALL Java_java_net_NetworkInterface_getMTU0(JNIEnv *env, jclass class, jstring name, jint index) {
1062 1042 jint ret = -1;
1063 1043 MIB_IFROW *ifRowP;
1064 1044
1065 1045 if (os_supports_ipv6 && ipv6_available()) {
1066 1046 return Java_java_net_NetworkInterface_getMTU0_XP(env, class, name, index);
1067 1047 } else {
1068 1048 ifRowP = getIF(index);
1069 1049 if (ifRowP != NULL) {
1070 1050 ret = ifRowP->dwMtu;
1071 1051 free(ifRowP);
1072 1052 }
1073 1053 return ret;
1074 1054 }
1075 1055 }
↓ open down ↓ |
253 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX