Print this page
Split |
Close |
Expand all |
Collapse all |
--- old/src/windows/native/java/net/NetworkInterface_winXP.c
+++ new/src/windows/native/java/net/NetworkInterface_winXP.c
1 1 /*
2 2 * Copyright 2003-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
43 43 extern int enumAddresses_win(JNIEnv *env, netif *netifP, netaddr **netaddrPP);
44 44 int getAddrsFromAdapter(IP_ADAPTER_ADDRESSES *ptr, netaddr **netaddrPP);
45 45
46 46 /* IP helper library routines */
47 47 int (PASCAL FAR *GetIpAddrTable_fn)();
48 48 int (PASCAL FAR *GetIfTable_fn)();
49 49 int (PASCAL FAR *GetFriendlyIfIndex_fn)();
50 50 int (PASCAL FAR *GetAdaptersAddresses_fn)();
51 51 int (PASCAL FAR *GetAdaptersInfo_fn)();
52 52 int (PASCAL FAR *GetNumberOfInterfaces_fn)();
53 53
54 54 #ifdef DEBUG
55 55 void printnif (netif *nif) {
56 56 #ifdef _WIN64
57 57 printf ("nif:0x%I64x name:%s\n", nif,nif->name);
58 58 #else
59 59 printf ("nif:0x%x name:%s\n", nif,nif->name);
60 60 #endif
61 61 if (nif->dNameIsUnicode) {
62 62 printf ("dName:%S index:%d ", nif->displayName,nif->index);
63 63 } else {
64 64 printf ("dName:%s index:%d ", nif->displayName,nif->index);
65 65 }
66 66 printf ("naddrs:%d\n", nif->naddrs);
67 67 }
68 68
69 69 void printnifs (netif *netifPP, char *str) {
70 70 netif *nif;
71 71 printf ("%s\n", str);
72 72 for (nif=netifPP; nif!=NULL; nif=nif->next) {
73 73 printnif (nif);
74 74 }
75 75 printf("-----------------\n");
76 76 }
77 77
78 78 #endif
79 79
80 80 static int bufsize = 1024;
81 81
82 82 /*
83 83 * return an array of IP_ADAPTER_ADDRESSES containing one element
84 84 * for each apdapter on the system. Returned in *adapters.
85 85 * Buffer is malloc'd and must be freed (unless error returned)
86 86 */
87 87 static int getAdapters (JNIEnv *env, IP_ADAPTER_ADDRESSES **adapters) {
88 88 DWORD ret, flags;
89 89 IP_ADAPTER_ADDRESSES *adapterInfo;
90 90 ULONG len;
91 91 adapterInfo = (IP_ADAPTER_ADDRESSES *)malloc (bufsize);
92 92 if (adapterInfo == 0) {
93 93 return -1;
94 94 }
95 95 len = bufsize;
96 96 flags = GAA_FLAG_SKIP_DNS_SERVER;
97 97 flags |= GAA_FLAG_SKIP_MULTICAST;
98 98 flags |= GAA_FLAG_INCLUDE_PREFIX;
99 99 ret = (*GetAdaptersAddresses_fn) (AF_UNSPEC, flags, NULL, adapterInfo, &len);
100 100 if (ret == ERROR_BUFFER_OVERFLOW) {
101 101 adapterInfo = (IP_ADAPTER_ADDRESSES *) realloc (adapterInfo, len);
102 102 if (adapterInfo == 0) {
103 103 return -1;
104 104 }
105 105 bufsize = len;
106 106 ret = (*GetAdaptersAddresses_fn) (AF_UNSPEC, flags, NULL, adapterInfo, &len);
107 107 }
108 108 if (ret != ERROR_SUCCESS) {
109 109 free (adapterInfo);
110 110 JNU_ThrowByName(env, "java/lang/Error",
111 111 "IP Helper Library GetAdaptersAddresses function failed");
112 112 return -1;
113 113 }
114 114 *adapters = adapterInfo;
115 115 return ERROR_SUCCESS;
116 116 }
117 117
118 118 /*
119 119 * return an array of IP_ADAPTER_ADDRESSES containing one element
120 120 * for each apdapter on the system. Returned in *adapters.
121 121 * Buffer is malloc'd and must be freed (unless error returned)
122 122 */
123 123 IP_ADAPTER_ADDRESSES *getAdapter (JNIEnv *env, jint index) {
124 124 DWORD flags, val;
125 125 IP_ADAPTER_ADDRESSES *adapterInfo, *ptr, *ret;
126 126 ULONG len;
127 127 adapterInfo = (IP_ADAPTER_ADDRESSES *)malloc (bufsize);
128 128 if (adapterInfo == 0) {
129 129 JNU_ThrowByName(env, "java/lang/OutOfMemoryError", 0);
130 130 return NULL;
131 131 }
132 132 len = bufsize;
133 133 flags = GAA_FLAG_SKIP_DNS_SERVER;
134 134 flags |= GAA_FLAG_SKIP_MULTICAST;
135 135 flags |= GAA_FLAG_INCLUDE_PREFIX;
136 136 val = (*GetAdaptersAddresses_fn) (AF_UNSPEC, flags, NULL, adapterInfo, &len);
137 137 if (val == ERROR_BUFFER_OVERFLOW) {
138 138 adapterInfo = (IP_ADAPTER_ADDRESSES *) realloc (adapterInfo, len);
139 139 if (adapterInfo == 0) {
140 140 JNU_ThrowByName(env, "java/lang/OutOfMemoryError", 0);
141 141 return NULL;
142 142 }
143 143 bufsize = len;
144 144 val = (*GetAdaptersAddresses_fn) (AF_UNSPEC, flags, NULL, adapterInfo, &len);
145 145 }
146 146 if (val != ERROR_SUCCESS) {
147 147 free (adapterInfo);
148 148 JNU_ThrowByName(env, "java/lang/Error",
149 149 "IP Helper Library GetAdaptersAddresses function failed");
150 150 return NULL;
151 151 }
152 152 ptr = adapterInfo;
153 153 ret = NULL;
154 154 while (ptr != NULL) {
155 155 // IPv4 interface
156 156 if (ptr->Ipv6IfIndex == index) {
157 157 ret = (IP_ADAPTER_ADDRESSES *) malloc(sizeof(IP_ADAPTER_ADDRESSES));
158 158 memcpy(ret, ptr, sizeof(IP_ADAPTER_ADDRESSES));
159 159 }
160 160 ptr=ptr->Next;
161 161 }
162 162 free(adapterInfo);
163 163 return ret;
164 164 }
165 165
166 166 static int ipinflen = 2048;
167 167
168 168 /*
169 169 */
170 170 int getAllInterfacesAndAddresses (JNIEnv *env, netif **netifPP)
171 171 {
172 172 DWORD ret;
173 173 IP_ADAPTER_ADDRESSES *ptr, *adapters=0;
174 174 ULONG len=ipinflen, count=0;
175 175 netif *nif=0, *dup_nif, *last=0, *loopif=0, *curr;
176 176 int tun=0, net=0;
177 177
178 178 *netifPP = 0;
179 179
180 180 /*
181 181 * Get the IPv4 interfaces. This information is the same
182 182 * as what previous JDK versions would return.
183 183 */
184 184
185 185 ret = enumInterfaces_win (env, netifPP);
186 186 if (ret == -1) {
187 187 return -1;
188 188 } else {
189 189 count = ret;
190 190 }
191 191
192 192 /* locate the loopback (and the last) interface */
193 193 for (nif=*netifPP, last=nif; nif!=0; nif=nif->next) {
194 194 if (nif->ifType == MIB_IF_TYPE_LOOPBACK) {
195 195 loopif = nif;
196 196 }
197 197 last = nif;
198 198 }
199 199
200 200 // Retrieve IPv4 addresses with the IP Helper API
201 201 curr = *netifPP;
202 202 while (curr != NULL) {
203 203 netaddr *netaddrP;
204 204 ret = enumAddresses_win(env, curr, &netaddrP);
205 205 if ((*env)->ExceptionOccurred(env)) {
206 206 free_netaddr(netaddrP);
207 207 return -1;
208 208 }
209 209 curr->addrs = netaddrP;
210 210 curr->naddrs += ret;
211 211 curr = curr->next;
212 212 }
213 213
214 214 ret = getAdapters (env, &adapters);
215 215 if (ret != ERROR_SUCCESS) {
216 216 goto err;
217 217 }
218 218
219 219 /* Now get the IPv6 information. This includes:
220 220 * (a) IPv6 information associated with interfaces already found
221 221 * (b) IPv6 information for IPv6 only interfaces (probably tunnels)
222 222 *
223 223 * For compatibility with previous releases we use the naming
224 224 * information gotten from enumInterfaces_win() for (a) entries
225 225 * However, the index numbers are taken from the new API.
226 226 *
227 227 * The procedure is to go through the list of adapters returned
228 228 * by the new API looking for entries that correspond to IPv4 interfaces
229 229 * already found.
230 230 */
231 231
232 232 ptr = adapters;
233 233 while (ptr != NULL) {
234 234 int c;
235 235 netif *nif0;
236 236 if (ptr->IfType == IF_TYPE_SOFTWARE_LOOPBACK && (loopif != NULL)) {
237 237 c = getAddrsFromAdapter(ptr, &loopif->addrs);
238 238 if (c == -1) {
239 239 goto err;
240 240 }
241 241 loopif->naddrs += c;
242 242 } else {
243 243 int index = ptr->IfIndex;
244 244 if (index != 0) {
245 245 /* This entry is associated with an IPv4 interface */
246 246 for (nif=*netifPP; nif!=0; nif=nif->next) {
247 247 if (nif->index == index) {
248 248 /* found the interface entry
249 249 * set the index to the IPv6 index and add the
250 250 * IPv6 addresses
251 251 */
252 252 nif->index = ptr->Ipv6IfIndex;
253 253 c = getAddrsFromAdapter(ptr, &nif->addrs);
254 254 nif->naddrs += c;
255 255 break;
256 256 }
257 257 }
258 258 } else {
259 259 /* This entry is IPv6 only */
260 260 char newname [128];
261 261 int c;
262 262
263 263 /* Windows allocates duplicate adapter entries
264 264 * for tunnel interfaces when there are multiple
265 265 * physical adapters. Need to check
266 266 * if this is a duplicate (ipv6Index is the same)
267 267 */
268 268 dup_nif = 0;
269 269 for (nif0=*netifPP; nif0!=0; nif0=nif0->next) {
270 270 if (nif0->hasIpv6Address &&
271 271 ptr->Ipv6IfIndex == nif0->ipv6Index) {
272 272 dup_nif = nif0;
273 273 break;
274 274 }
275 275 }
276 276 if (dup_nif == 0) {
277 277 /* new interface */
278 278 nif = (netif *) calloc (1, sizeof(netif));
279 279 if (nif == 0) {
280 280 goto err;
281 281 }
282 282 if (ptr->IfType == IF_TYPE_TUNNEL) {
283 283 sprintf (newname, "tun%d", tun);
284 284 tun ++;
285 285 } else {
286 286 sprintf (newname, "net%d", net);
287 287 net ++;
288 288 }
289 289 nif->name = malloc (strlen(newname)+1);
290 290 nif->displayName = malloc (wcslen(ptr->FriendlyName)*2+2);
291 291 if (nif->name == 0 || nif->displayName == 0) {
292 292 goto err;
293 293 }
294 294 strcpy (nif->name, newname);
295 295 wcscpy ((PWCHAR)nif->displayName, ptr->FriendlyName);
296 296 nif->dNameIsUnicode = TRUE;
297 297 nif->index = ptr->Ipv6IfIndex;
298 298 nif->ipv6Index = ptr->Ipv6IfIndex;
299 299 nif->hasIpv6Address = TRUE;
300 300
301 301 last->next = nif;
302 302 last = nif;
303 303 count++;
304 304 c = getAddrsFromAdapter(ptr, &nif->addrs);
305 305 if (c == -1) {
306 306 goto err;
307 307 }
308 308 nif->naddrs += c;
309 309 } else {
310 310 /* add the addresses from this adapter to the
311 311 * original (dup_nif)
312 312 */
313 313 c = getAddrsFromAdapter(ptr, &dup_nif->addrs);
314 314 if (c == -1) {
315 315 goto err;
316 316 }
317 317 dup_nif->naddrs += c;
318 318 }
319 319 }
320 320 }
321 321 ptr=ptr->Next;
322 322 }
323 323
324 324 free (adapters);
325 325 return count;
326 326
327 327 err:
328 328 if (*netifPP) {
329 329 free_netif (*netifPP);
330 330 }
331 331 if (adapters) {
332 332 free (adapters);
333 333 }
334 334 return -1;
335 335 }
336 336
337 337 /* If *netaddrPP is null, then the addresses are allocated and the beginning
338 338 * of the allocated chain is returned in *netaddrPP.
339 339 * If *netaddrPP is not null, then the addresses allocated here are appended
340 340 * to the existing chain.
341 341 *
342 342 * Returns count of addresses or -1 on error.
343 343 */
344 344
345 345 static int getAddrsFromAdapter(IP_ADAPTER_ADDRESSES *ptr, netaddr **netaddrPP) {
346 346 LPSOCKADDR sock;
347 347 int count = 0;
348 348 netaddr *curr, *start=0, *prev=0;
349 349 PIP_ADAPTER_UNICAST_ADDRESS uni_addr;
350 350 PIP_ADAPTER_ANYCAST_ADDRESS any_addr;
351 351 PIP_ADAPTER_PREFIX prefix;
352 352
353 353 /* If chain passed in, find end */
354 354 if (*netaddrPP != NULL) {
355 355 for (start=*netaddrPP; start->next!=NULL; start=start->next) {
356 356 }
357 357 prev=start;
358 358 }
359 359
360 360 prefix = ptr->FirstPrefix;
361 361 /* Unicast */
362 362 uni_addr = ptr->FirstUnicastAddress;
363 363 while (uni_addr != NULL) {
364 364 /* address is only usable if dad state is preferred or deprecated */
365 365 if (uni_addr->DadState == IpDadStateDeprecated ||
366 366 uni_addr->DadState == IpDadStatePreferred) {
367 367 sock = uni_addr->Address.lpSockaddr;
368 368
369 369 // IPv4 addresses already retrieved with enumAddresses_win
370 370 if (sock->sa_family == AF_INET) {
371 371 uni_addr = uni_addr->Next;
372 372 continue;
373 373 }
374 374
375 375 curr = (netaddr *)calloc (1, sizeof (netaddr));
376 376 if (curr == 0) {
377 377 return -1;
378 378 }
379 379 if (start == NULL) {
380 380 start = curr;
381 381 }
382 382 if (prev != NULL) {
383 383 prev->next = curr;
384 384 }
385 385 prev = curr;
386 386 SOCKETADDRESS_COPY (&curr->addr, sock);
387 387 if (prefix != NULL) {
388 388 curr->mask = (short)prefix->PrefixLength;
389 389 prefix = prefix->Next;
390 390 }
391 391 count ++;
392 392 }
393 393 uni_addr = uni_addr->Next;
394 394 }
395 395 /* Anycast */
396 396 any_addr = ptr->FirstAnycastAddress;
397 397 while (any_addr != NULL) {
398 398 curr = (netaddr *)calloc (1, sizeof (netaddr));
399 399 if (curr == 0) {
400 400 return -1;
401 401 }
402 402 if (start == NULL) {
403 403 start = curr;
404 404 }
405 405 if (prev != NULL) {
406 406 prev->next = curr;
407 407 }
408 408 prev = curr;
409 409 sock = any_addr->Address.lpSockaddr;
410 410 SOCKETADDRESS_COPY (&curr->addr, sock);
411 411 count ++;
412 412 any_addr = any_addr->Next;
413 413 }
414 414 if (*netaddrPP == NULL) {
415 415 *netaddrPP = start;
416 416 }
417 417 return count;
418 418 }
419 419
420 420 /*
421 421 * Create a NetworkInterface object, populate the name and index, and
422 422 * populate the InetAddress array based on the IP addresses for this
423 423 * interface.
424 424 */
425 425 static jobject createNetworkInterfaceXP(JNIEnv *env, netif *ifs)
426 426 {
427 427 jobject netifObj;
428 428 jobject name, displayName;
↓ open down ↓ |
428 lines elided |
↑ open up ↑ |
429 429 jobjectArray addrArr, bindsArr, childArr;
430 430 netaddr *addrs;
431 431 jint addr_index;
432 432 int netaddrCount=ifs->naddrs;
433 433 netaddr *netaddrP=ifs->addrs;
434 434 jint bind_index;
435 435
436 436 /*
437 437 * Create a NetworkInterface object and populate it
438 438 */
439 - netifObj = (*env)->NewObject(env, ni_class, ni_ctor);
439 + netifObj = (*env)->NewObject(env, ni_class, ni_ctrID);
440 440 name = (*env)->NewStringUTF(env, ifs->name);
441 441 if (ifs->dNameIsUnicode) {
442 442 displayName = (*env)->NewString(env, (PWCHAR)ifs->displayName, wcslen ((PWCHAR)ifs->displayName));
443 443 } else {
444 444 displayName = (*env)->NewStringUTF(env, ifs->displayName);
445 445 }
446 446 if (netifObj == NULL || name == NULL || displayName == NULL) {
447 447 return NULL;
448 448 }
449 449 (*env)->SetObjectField(env, netifObj, ni_nameID, name);
450 450 (*env)->SetObjectField(env, netifObj, ni_displayNameID, displayName);
451 451 (*env)->SetIntField(env, netifObj, ni_indexID, ifs->index);
452 452
453 453 /*
454 454 * Get the IP addresses for this interface if necessary
↓ open down ↓ |
5 lines elided |
↑ open up ↑ |
455 455 * Note that 0 is a valid number of addresses.
456 456 */
457 457 if (netaddrCount < 0) {
458 458 netaddrCount = enumAddresses_win(env, ifs, &netaddrP);
459 459 if ((*env)->ExceptionOccurred(env)) {
460 460 free_netaddr(netaddrP);
461 461 return NULL;
462 462 }
463 463 }
464 464
465 - addrArr = (*env)->NewObjectArray(env, netaddrCount, ni_iacls, NULL);
465 + addrArr = (*env)->NewObjectArray(env, netaddrCount, ia_class, NULL);
466 466 if (addrArr == NULL) {
467 467 return NULL;
468 468 }
469 469
470 470 bindsArr = (*env)->NewObjectArray(env, netaddrCount, ni_ibcls, NULL);
471 471 if (bindsArr == NULL) {
472 472 free_netaddr(netaddrP);
473 473 return NULL;
474 474 }
475 475
476 476 addrs = netaddrP;
477 477 addr_index = 0;
478 478 bind_index = 0;
479 479 while (addrs != NULL) {
480 480 jobject iaObj, ia2Obj;
481 481 jobject ibObj = NULL;
482 482 if (addrs->addr.him.sa_family == AF_INET) {
483 - iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4Ctor);
483 + iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
484 484 if (iaObj == NULL) {
485 485 return NULL;
486 486 }
487 487 /* default ctor will set family to AF_INET */
488 488
489 - (*env)->SetIntField(env, iaObj, ni_iaAddr, ntohl(addrs->addr.him4.sin_addr.s_addr));
489 + (*env)->SetIntField(env, iaObj, ia_addressID, ntohl(addrs->addr.him4.sin_addr.s_addr));
490 490
491 491 ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
492 492 if (ibObj == NULL) {
493 493 free_netaddr(netaddrP);
494 494 return NULL;
495 495 }
496 496 (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
497 - ia2Obj = (*env)->NewObject(env, ni_ia4cls, ni_ia4Ctor);
497 + ia2Obj = (*env)->NewObject(env, ia4_class, ia4_ctrID);
498 498 if (ia2Obj == NULL) {
499 499 free_netaddr(netaddrP);
500 500 return NULL;
501 501 }
502 - (*env)->SetIntField(env, ia2Obj, ni_iaAddr,
502 + (*env)->SetIntField(env, ia2Obj, ia_addressID,
503 503 ntohl(addrs->brdcast.him4.sin_addr.s_addr));
504 504 (*env)->SetObjectField(env, ibObj, ni_ibbroadcastID, ia2Obj);
505 505 (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
506 506 (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
507 507 } else /* AF_INET6 */ {
508 508 int scope;
509 - iaObj = (*env)->NewObject(env, ni_ia6cls, ni_ia6ctrID);
509 + iaObj = (*env)->NewObject(env, ia6_class, ia6_ctrID);
510 510 if (iaObj) {
511 511 jbyteArray ipaddress = (*env)->NewByteArray(env, 16);
512 512 if (ipaddress == NULL) {
513 513 return NULL;
514 514 }
515 515 (*env)->SetByteArrayRegion(env, ipaddress, 0, 16,
516 516 (jbyte *)&(addrs->addr.him6.sin6_addr.s6_addr));
517 517 scope = addrs->addr.him6.sin6_scope_id;
518 518 if (scope != 0) { /* zero is default value, no need to set */
519 519 (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope);
520 520 (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE);
521 521 (*env)->SetObjectField(env, iaObj, ia6_scopeifnameID, netifObj);
522 522 }
523 - (*env)->SetObjectField(env, iaObj, ni_ia6ipaddressID, ipaddress);
523 + (*env)->SetObjectField(env, iaObj, ia6_ipaddressID, ipaddress);
524 524 ibObj = (*env)->NewObject(env, ni_ibcls, ni_ibctrID);
525 525 if (ibObj == NULL) {
526 526 free_netaddr(netaddrP);
527 527 return NULL;
528 528 }
529 529 (*env)->SetObjectField(env, ibObj, ni_ibaddressID, iaObj);
530 530 (*env)->SetShortField(env, ibObj, ni_ibmaskID, addrs->mask);
531 531 (*env)->SetObjectArrayElement(env, bindsArr, bind_index++, ibObj);
532 532 }
533 533 }
534 534 (*env)->SetObjectArrayElement(env, addrArr, addr_index, iaObj);
535 535 addrs = addrs->next;
536 536 addr_index++;
537 537 }
538 538 (*env)->SetObjectField(env, netifObj, ni_addrsID, addrArr);
539 539 (*env)->SetObjectField(env, netifObj, ni_bindsID, bindsArr);
540 540
541 541 /*
542 542 * Windows doesn't have virtual interfaces, so child array
543 543 * is always empty.
544 544 */
545 545 childArr = (*env)->NewObjectArray(env, 0, ni_class, NULL);
546 546 if (childArr == NULL) {
547 547 return NULL;
548 548 }
549 549 (*env)->SetObjectField(env, netifObj, ni_childsID, childArr);
550 550
551 551 /* return the NetworkInterface */
552 552 return netifObj;
553 553 }
554 554
555 555 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByName0_XP
556 556 (JNIEnv *env, jclass cls, jstring name)
557 557 {
558 558 netif *ifList, *curr;
559 559 jboolean isCopy;
560 560 const char *name_utf;
561 561 jobject netifObj = NULL;
562 562
563 563 if (getAllInterfacesAndAddresses (env, &ifList) < 0) {
564 564 return NULL;
565 565 }
566 566
567 567 /* get the name as a C string */
568 568 name_utf = (*env)->GetStringUTFChars(env, name, &isCopy);
569 569
570 570 /* Search by name */
571 571 curr = ifList;
572 572 while (curr != NULL) {
573 573 if (strcmp(name_utf, curr->name) == 0) {
574 574 break;
575 575 }
576 576 curr = curr->next;
577 577 }
578 578
579 579 /* if found create a NetworkInterface */
580 580 if (curr != NULL) {;
581 581 netifObj = createNetworkInterfaceXP(env, curr);
582 582 }
583 583
584 584 /* release the UTF string */
585 585 (*env)->ReleaseStringUTFChars(env, name, name_utf);
586 586
587 587 /* release the interface list */
588 588 free_netif(ifList);
589 589
590 590 return netifObj;
591 591 }
592 592
593 593 /*
594 594 * Class: NetworkInterface
595 595 * Method: getByIndex0_XP
596 596 * Signature: (I)LNetworkInterface;
597 597 */
598 598 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByIndex0_XP
599 599 (JNIEnv *env, jclass cls, jint index)
600 600 {
601 601 netif *ifList, *curr;
602 602 jobject netifObj = NULL;
603 603
604 604 if (getAllInterfacesAndAddresses (env, &ifList) < 0) {
605 605 return NULL;
606 606 }
607 607
608 608 /* search by index */
609 609 curr = ifList;
610 610 while (curr != NULL) {
611 611 if (index == curr->index) {
612 612 break;
613 613 }
614 614 curr = curr->next;
615 615 }
616 616
617 617 /* if found create a NetworkInterface */
618 618 if (curr != NULL) {
619 619 netifObj = createNetworkInterfaceXP(env, curr);
620 620 }
621 621
622 622 /* release the interface list */
623 623 free_netif(ifList);
624 624
625 625 return netifObj;
626 626 }
627 627
628 628 /*
629 629 * Class: java_net_NetworkInterface
630 630 * Method: getByInetAddress0
631 631 * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface;
632 632 */
633 633 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0_XP
634 634 (JNIEnv *env, jclass cls, jobject iaObj)
635 635 {
636 636 netif *ifList, *curr;
637 637 jobject netifObj = NULL;
638 638
639 639 /* get the list of interfaces */
640 640 if (getAllInterfacesAndAddresses (env, &ifList) < 0) {
641 641 return NULL;
642 642 }
643 643
644 644 /*
645 645 * Enumerate the addresses on each interface until we find a
646 646 * matching address.
647 647 */
648 648 curr = ifList;
649 649 while (curr != NULL) {
650 650 netaddr *addrList = curr->addrs;
651 651 netaddr *addrP;
652 652
653 653 /* iterate through each address */
654 654 addrP = addrList;
655 655
656 656 while (addrP != NULL) {
657 657 if (NET_SockaddrEqualsInetAddress(env,
658 658 (struct sockaddr*)&addrP->addr, iaObj)) {
659 659 break;
660 660 }
661 661 addrP = addrP->next;
662 662 }
663 663
664 664 /*
665 665 * Address matched so create NetworkInterface for this interface
666 666 * and address list.
667 667 */
668 668 if (addrP != NULL) {
669 669 netifObj = createNetworkInterfaceXP(env, curr);
670 670 break;
671 671 }
672 672
673 673 /* on next interface */
674 674 curr = curr->next;
675 675 }
676 676
677 677 /* release the interface list */
678 678 free_netif(ifList);
679 679
680 680 return netifObj;
681 681 }
682 682
683 683 /*
684 684 * Class: java_net_NetworkInterface
685 685 * Method: getAll
686 686 * Signature: ()[Ljava/net/NetworkInterface;
687 687 */
688 688 JNIEXPORT jobjectArray JNICALL Java_java_net_NetworkInterface_getAll_XP
689 689 (JNIEnv *env, jclass cls)
690 690 {
691 691 int count;
692 692 netif *ifList, *curr;
693 693 jobjectArray netIFArr;
694 694 jint arr_index;
695 695
696 696 /*
697 697 * Get list of interfaces
698 698 */
699 699 count = getAllInterfacesAndAddresses (env, &ifList);
700 700 if (count < 0) {
701 701 return NULL;
702 702 }
703 703
704 704 /* allocate a NetworkInterface array */
705 705 netIFArr = (*env)->NewObjectArray(env, count, cls, NULL);
706 706 if (netIFArr == NULL) {
707 707 return NULL;
708 708 }
709 709
710 710 /*
711 711 * Iterate through the interfaces, create a NetworkInterface instance
712 712 * for each array element and populate the object.
713 713 */
714 714 curr = ifList;
715 715 arr_index = 0;
716 716 while (curr != NULL) {
717 717 jobject netifObj;
718 718
719 719 netifObj = createNetworkInterfaceXP(env, curr);
720 720 if (netifObj == NULL) {
721 721 return NULL;
722 722 }
723 723
724 724 /* put the NetworkInterface into the array */
725 725 (*env)->SetObjectArrayElement(env, netIFArr, arr_index++, netifObj);
726 726 curr = curr->next;
727 727 }
728 728
729 729 /* release the interface list */
730 730 free_netif(ifList);
731 731
732 732 return netIFArr;
733 733 }
734 734
735 735 /*
736 736 * Class: java_net_NetworkInterface
737 737 * Method: supportsMulticast0
738 738 * Signature: (Ljava/lang/String;I)Z
739 739 */
740 740 JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_supportsMulticast0_XP
741 741 (JNIEnv *env, jclass cls, jstring name, jint index) {
742 742 IP_ADAPTER_ADDRESSES *ptr;
743 743 jboolean val = JNI_TRUE;
744 744
745 745 ptr = getAdapter(env, index);
746 746 if (ptr != NULL) {
747 747 val = ptr->Flags & IP_ADAPTER_NO_MULTICAST ? JNI_FALSE : JNI_TRUE;
748 748 free(ptr);
749 749 }
750 750 return val;
751 751 }
752 752
753 753 /*
754 754 * Class: java_net_NetworkInterface
755 755 * Method: isUp0
756 756 * Signature: (Ljava/lang/String;I)Z
757 757 */
758 758 JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isUp0_XP
759 759 (JNIEnv *env, jclass cls, jstring name, jint index) {
760 760 IP_ADAPTER_ADDRESSES *ptr;
761 761 jboolean val = JNI_FALSE;
762 762
763 763 ptr = getAdapter(env, index);
764 764 if (ptr != NULL) {
765 765 val = ptr->OperStatus == IfOperStatusUp ? JNI_TRUE : JNI_FALSE;
766 766 free(ptr);
767 767 }
768 768 return val;
769 769 }
770 770
771 771 /*
772 772 * Class: java_net_NetworkInterface
773 773 * Method: getMacAddr0
774 774 * Signature: (Ljava/lang/String;I)Z
775 775 */
776 776 JNIEXPORT jbyteArray JNICALL Java_java_net_NetworkInterface_getMacAddr0_XP
777 777 (JNIEnv *env, jclass cls, jstring name, jint index) {
778 778 IP_ADAPTER_ADDRESSES *ptr;
779 779 jbyteArray ret = NULL;
780 780 int len;
781 781
782 782 ptr = getAdapter(env, index);
783 783 if (ptr != NULL) {
784 784 len = ptr->PhysicalAddressLength;
785 785 ret = (*env)->NewByteArray(env, len);
786 786 if (!IS_NULL(ret)) {
787 787 (*env)->SetByteArrayRegion(env, ret, 0, len,
788 788 (jbyte*) ptr->PhysicalAddress);
789 789 }
790 790 free(ptr);
791 791 }
792 792 return ret;
793 793 }
794 794
795 795 /*
796 796 * Class: java_net_NetworkInterface
797 797 * Method: getMTU0
798 798 * Signature: ([bLjava/lang/String;I)I
799 799 */
800 800 JNIEXPORT jint JNICALL Java_java_net_NetworkInterface_getMTU0_XP
801 801 (JNIEnv *env, jclass cls, jstring name, jint index) {
802 802 IP_ADAPTER_ADDRESSES *ptr;
803 803 jint ret = -1;
804 804
805 805 ptr = getAdapter(env, index);
806 806 if (ptr != NULL) {
807 807 ret = ptr->Mtu;
808 808 free(ptr);
809 809 }
810 810 return ret;
811 811 }
812 812
813 813 /*
814 814 * Class: java_net_NetworkInterface
815 815 * Method: isLoopback0
816 816 * Signature: (Ljava/lang/String;I)Z
817 817 */
818 818 JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isLoopback0_XP
819 819 (JNIEnv *env, jclass cls, jstring name, jint index) {
820 820 IP_ADAPTER_ADDRESSES *ptr;
821 821 jboolean val = JNI_FALSE;
822 822
823 823 ptr = getAdapter(env, index);
824 824 if (ptr != NULL) {
825 825 val = ptr->IfType == IF_TYPE_SOFTWARE_LOOPBACK ? JNI_TRUE : JNI_FALSE;
826 826 free(ptr);
827 827 }
828 828 return val;
829 829 }
830 830
831 831 /*
832 832 * Class: java_net_NetworkInterface
833 833 * Method: isP2P0
834 834 * Signature: (Ljava/lang/String;I)Z
835 835 */
836 836 JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_isP2P0_XP
837 837 (JNIEnv *env, jclass cls, jstring name, jint index) {
838 838 IP_ADAPTER_ADDRESSES *ptr;
839 839 jboolean val = JNI_FALSE;
840 840
841 841 ptr = getAdapter(env, index);
842 842 if (ptr != NULL) {
843 843 if (ptr->IfType == IF_TYPE_PPP || ptr->IfType == IF_TYPE_SLIP ||
844 844 ptr->IfType == IF_TYPE_TUNNEL) {
845 845 val = JNI_TRUE;
846 846 }
847 847 free(ptr);
848 848 }
849 849 return val;
850 850 }
↓ open down ↓ |
317 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX