1 /* |
1 /* |
2 * Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved. |
2 * Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 * |
4 * |
5 * This code is free software; you can redistribute it and/or modify it |
5 * This code is free software; you can redistribute it and/or modify it |
6 * under the terms of the GNU General Public License version 2 only, as |
6 * under the terms of the GNU General Public License version 2 only, as |
7 * published by the Free Software Foundation. Oracle designates this |
7 * published by the Free Software Foundation. Oracle designates this |
23 * questions. |
23 * questions. |
24 */ |
24 */ |
25 #include "net_util.h" |
25 #include "net_util.h" |
26 #include "NetworkInterface.h" |
26 #include "NetworkInterface.h" |
27 |
27 |
|
28 #include "java_net_InetAddress.h" |
28 #include "java_net_NetworkInterface.h" |
29 #include "java_net_NetworkInterface.h" |
29 |
30 |
30 /* |
31 /* |
31 * Windows implementation of the java.net.NetworkInterface native methods. |
32 * Windows implementation of the java.net.NetworkInterface native methods. |
32 * This module provides the implementations of getAll, getByName, getByIndex, |
33 * This module provides the implementations of getAll, getByName, getByIndex, |
345 } |
346 } |
346 |
347 |
347 /* |
348 /* |
348 * Free the interface table and return the interface list |
349 * Free the interface table and return the interface list |
349 */ |
350 */ |
350 if (tableP) { |
351 if (tableP != NULL) { |
351 free(tableP); |
352 free(tableP); |
352 } |
353 } |
353 *netifPP = netifP; |
354 *netifPP = netifP; |
354 return count; |
355 return count; |
355 } |
356 } |
356 |
357 |
357 /* |
358 /* |
358 * Enumerate the IP addresses on an interface using the IP helper library |
359 * Enumerate all addresses using the IP helper library |
359 * routine GetIfAddrTable and matching based on the index name. There are |
360 */ |
360 * more efficient routines but we use GetIfAddrTable because it's avaliable |
361 int lookupIPAddrTable(JNIEnv *env, MIB_IPADDRTABLE **tablePP) |
361 * on 98 and NT. |
|
362 * |
|
363 * Returns the count of addresses, or -1 if error. If no error occurs then |
|
364 * netaddrPP will return a list of netaddr structures with the IP addresses. |
|
365 */ |
|
366 int enumAddresses_win(JNIEnv *env, netif *netifP, netaddr **netaddrPP) |
|
367 { |
362 { |
368 MIB_IPADDRTABLE *tableP; |
363 MIB_IPADDRTABLE *tableP; |
369 ULONG size; |
364 ULONG size; |
370 DWORD ret; |
365 DWORD ret; |
371 DWORD i; |
|
372 netaddr *netaddrP; |
|
373 int count = 0; |
|
374 unsigned long mask; |
|
375 |
|
376 /* |
366 /* |
377 * Use GetIpAddrTable to enumerate the IP Addresses |
367 * Use GetIpAddrTable to enumerate the IP Addresses |
378 */ |
368 */ |
379 size = sizeof(MIB_IPADDRTABLE); |
369 size = sizeof(MIB_IPADDRTABLE); |
380 tableP = (MIB_IPADDRTABLE *)malloc(size); |
370 tableP = (MIB_IPADDRTABLE *)malloc(size); |
394 tableP = newTableP; |
384 tableP = newTableP; |
395 |
385 |
396 ret = GetIpAddrTable(tableP, &size, FALSE); |
386 ret = GetIpAddrTable(tableP, &size, FALSE); |
397 } |
387 } |
398 if (ret != NO_ERROR) { |
388 if (ret != NO_ERROR) { |
399 if (tableP) { |
389 if (tableP != NULL) { |
400 free(tableP); |
390 free(tableP); |
401 } |
391 } |
402 JNU_ThrowByName(env, "java/lang/Error", |
392 JNU_ThrowByName(env, "java/lang/Error", |
403 "IP Helper Library GetIpAddrTable function failed"); |
393 "IP Helper Library GetIpAddrTable function failed"); |
404 // this different error code is to handle the case when we call |
394 // this different error code is to handle the case when we call |
405 // GetIpAddrTable in pure IPv6 environment |
395 // GetIpAddrTable in pure IPv6 environment |
406 return -2; |
396 return -2; |
407 } |
397 } |
|
398 *tablePP = tableP; |
|
399 return 0; |
|
400 } |
|
401 |
|
402 /* |
|
403 * Enumerate the IP addresses on an interface, given an IP address table |
|
404 * and matching based on index. |
|
405 * |
|
406 * Returns the count of addresses, or -1 if error. If no error occurs then |
|
407 * netaddrPP will return a list of netaddr structures with the IP addresses. |
|
408 */ |
|
409 int enumAddresses_win_ipaddrtable(JNIEnv *env, netif *netifP, netaddr **netaddrPP, MIB_IPADDRTABLE *tableP) |
|
410 { |
|
411 DWORD i; |
|
412 netaddr *netaddrP; |
|
413 int count = 0; |
|
414 unsigned long mask; |
408 |
415 |
409 /* |
416 /* |
410 * Iterate through the table to find the addresses with the |
417 * Iterate through the table to find the addresses with the |
411 * matching dwIndex. Ignore 0.0.0.0 addresses. |
418 * matching dwIndex. Ignore 0.0.0.0 addresses. |
412 */ |
419 */ |
|
420 if (tableP == NULL) |
|
421 return 0; |
413 count = 0; |
422 count = 0; |
414 netaddrP = NULL; |
423 netaddrP = NULL; |
415 |
424 |
416 i = 0; |
425 i = 0; |
417 while (i<tableP->dwNumEntries) { |
426 while (i < tableP->dwNumEntries) { |
418 if (tableP->table[i].dwIndex == netifP->dwIndex && |
427 if (tableP->table[i].dwIndex == netifP->dwIndex && |
419 tableP->table[i].dwAddr != 0) { |
428 tableP->table[i].dwAddr != 0) { |
420 |
429 |
421 netaddr *curr = (netaddr *)malloc(sizeof(netaddr)); |
430 netaddr *curr = (netaddr *)malloc(sizeof(netaddr)); |
422 if (curr == NULL) { |
431 if (curr == NULL) { |
435 case MIB_IF_TYPE_ETHERNET: |
444 case MIB_IF_TYPE_ETHERNET: |
436 case MIB_IF_TYPE_TOKENRING: |
445 case MIB_IF_TYPE_TOKENRING: |
437 case MIB_IF_TYPE_FDDI: |
446 case MIB_IF_TYPE_FDDI: |
438 case MIB_IF_TYPE_LOOPBACK: |
447 case MIB_IF_TYPE_LOOPBACK: |
439 case IF_TYPE_IEEE80211: |
448 case IF_TYPE_IEEE80211: |
440 /** |
449 /** |
441 * Contrary to what it seems to indicate, dwBCastAddr doesn't |
450 * Contrary to what it seems to indicate, dwBCastAddr doesn't |
442 * contain the broadcast address but 0 or 1 depending on whether |
451 * contain the broadcast address but 0 or 1 depending on whether |
443 * the broadcast address should set the bits of the host part |
452 * the broadcast address should set the bits of the host part |
444 * to 0 or 1. |
453 * to 0 or 1. |
445 * Yes, I know it's stupid, but what can I say, it's MSFTs API. |
454 * Yes, I know it's stupid, but what can I say, it's MSFTs API. |
446 */ |
455 */ |
447 curr->brdcast.sa4.sin_family = AF_INET; |
456 curr->brdcast.sa4.sin_family = AF_INET; |
448 if (tableP->table[i].dwBCastAddr == 1) |
457 if (tableP->table[i].dwBCastAddr == 1) |
449 curr->brdcast.sa4.sin_addr.s_addr = (tableP->table[i].dwAddr & tableP->table[i].dwMask) | (0xffffffff ^ tableP->table[i].dwMask); |
458 curr->brdcast.sa4.sin_addr.s_addr = (tableP->table[i].dwAddr & tableP->table[i].dwMask) | (0xffffffff ^ tableP->table[i].dwMask); |
450 else |
459 else |
451 curr->brdcast.sa4.sin_addr.s_addr = (tableP->table[i].dwAddr & tableP->table[i].dwMask); |
460 curr->brdcast.sa4.sin_addr.s_addr = (tableP->table[i].dwAddr & tableP->table[i].dwMask); |
452 mask = ntohl(tableP->table[i].dwMask); |
461 mask = ntohl(tableP->table[i].dwMask); |
453 curr->mask = 0; |
462 curr->mask = 0; |
454 while (mask) { |
463 while (mask) { |
455 mask <<= 1; |
464 mask <<= 1; |
456 curr->mask++; |
465 curr->mask++; |
457 } |
466 } |
458 break; |
467 break; |
459 case MIB_IF_TYPE_PPP: |
468 case MIB_IF_TYPE_PPP: |
460 case MIB_IF_TYPE_SLIP: |
469 case MIB_IF_TYPE_SLIP: |
461 default: |
470 default: |
462 /** |
471 /** |
463 * these don't have broadcast/subnet |
472 * these don't have broadcast/subnet |
464 */ |
473 */ |
465 curr->mask = -1; |
474 curr->mask = -1; |
466 break; |
475 break; |
467 } |
476 } |
468 |
477 |
469 curr->next = netaddrP; |
478 curr->next = netaddrP; |
470 netaddrP = curr; |
479 netaddrP = curr; |
471 count++; |
480 count++; |
472 } |
481 } |
473 i++; |
482 i++; |
474 } |
483 } |
475 |
484 |
476 *netaddrPP = netaddrP; |
485 *netaddrPP = netaddrP; |
|
486 return count; |
|
487 } |
|
488 |
|
489 |
|
490 /* |
|
491 * Enumerate the IP addresses on an interface, using an IP address table |
|
492 * retrieved using GetIPAddrTable and matching based on index. |
|
493 * |
|
494 * Returns the count of addresses, or -1 if error. If no error occurs then |
|
495 * netaddrPP will return a list of netaddr structures with the IP addresses. |
|
496 */ |
|
497 int enumAddresses_win(JNIEnv *env, netif *netifP, netaddr **netaddrPP) { |
|
498 MIB_IPADDRTABLE *tableP; |
|
499 int count; |
|
500 int ret = lookupIPAddrTable(env, &tableP); |
|
501 if (ret < 0) { |
|
502 return NULL; |
|
503 } |
|
504 count = enumAddresses_win_ipaddrtable(env, netifP, netaddrPP, tableP); |
477 free(tableP); |
505 free(tableP); |
478 return count; |
506 return count; |
479 } |
507 } |
|
508 |
480 |
509 |
481 /* |
510 /* |
482 * Class: java_net_NetworkInterface |
511 * Class: java_net_NetworkInterface |
483 * Method: init |
512 * Method: init |
484 * Signature: ()V |
513 * Signature: ()V |
756 free_netif(ifList); |
785 free_netif(ifList); |
757 |
786 |
758 return netifObj; |
787 return netifObj; |
759 } |
788 } |
760 |
789 |
|
790 |
|
791 /* |
|
792 * Class: java_net_NetworkInterface |
|
793 * Method: boundInetAddress0 |
|
794 * Signature: (Ljava/net/InetAddress;)Z |
|
795 */ |
|
796 JNIEXPORT jboolean JNICALL Java_java_net_NetworkInterface_boundInetAddress0 |
|
797 (JNIEnv *env, jclass cls, jobject iaObj) |
|
798 { |
|
799 jobject netifObj = NULL; |
|
800 DWORD i; |
|
801 |
|
802 int family = getInetAddress_family(env, iaObj); |
|
803 JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE); |
|
804 |
|
805 if (family == java_net_InetAddress_IPv6) { |
|
806 if (!ipv6_available()) |
|
807 return JNI_FALSE; |
|
808 return Java_java_net_NetworkInterface_getByInetAddress0_XP(env, cls, iaObj) != NULL; |
|
809 } else if (family == java_net_InetAddress_IPv4) { |
|
810 jint addr = getInetAddress_addr(env, iaObj); |
|
811 JNU_CHECK_EXCEPTION_RETURN(env, JNI_FALSE); |
|
812 |
|
813 jboolean found = JNI_FALSE; |
|
814 MIB_IPADDRTABLE *tableP; |
|
815 if (lookupIPAddrTable(env, &tableP) >= 0 && tableP != NULL) { |
|
816 for (i = 0; i < tableP->dwNumEntries; i++) { |
|
817 if (tableP->table[i].dwAddr != 0 && |
|
818 (unsigned long)addr == ntohl(tableP->table[i].dwAddr)) { |
|
819 found = JNI_TRUE; |
|
820 break; |
|
821 } |
|
822 } |
|
823 } |
|
824 if (tableP != NULL) { |
|
825 free(tableP); |
|
826 } |
|
827 return found; |
|
828 } else { |
|
829 // Unknown address family |
|
830 return JNI_FALSE; |
|
831 } |
|
832 } |
|
833 |
761 /* |
834 /* |
762 * Class: java_net_NetworkInterface |
835 * Class: java_net_NetworkInterface |
763 * Method: getByInetAddress0 |
836 * Method: getByInetAddress0 |
764 * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface; |
837 * Signature: (Ljava/net/InetAddress;)Ljava/net/NetworkInterface; |
765 */ |
838 */ |
766 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0 |
839 JNIEXPORT jobject JNICALL Java_java_net_NetworkInterface_getByInetAddress0 |
767 (JNIEnv *env, jclass cls, jobject iaObj) |
840 (JNIEnv *env, jclass cls, jobject iaObj) |
768 { |
841 { |
769 netif *ifList, *curr; |
842 netif *ifList, *curr; |
|
843 MIB_IPADDRTABLE *tableP; |
770 jobject netifObj = NULL; |
844 jobject netifObj = NULL; |
771 jint addr = getInetAddress_addr(env, iaObj); |
845 jint addr = getInetAddress_addr(env, iaObj); |
772 JNU_CHECK_EXCEPTION_RETURN(env, NULL); |
846 JNU_CHECK_EXCEPTION_RETURN(env, NULL); |
773 |
847 |
774 // Retained for now to support IPv4 only stack, java.net.preferIPv4Stack |
|
775 if (ipv6_available()) { |
848 if (ipv6_available()) { |
776 return Java_java_net_NetworkInterface_getByInetAddress0_XP (env, cls, iaObj); |
849 return Java_java_net_NetworkInterface_getByInetAddress0_XP (env, cls, iaObj); |
777 } |
850 } |
778 |
851 |
779 /* get the list of interfaces */ |
852 /* get the list of interfaces */ |
783 |
856 |
784 /* |
857 /* |
785 * Enumerate the addresses on each interface until we find a |
858 * Enumerate the addresses on each interface until we find a |
786 * matching address. |
859 * matching address. |
787 */ |
860 */ |
788 curr = ifList; |
861 tableP = NULL; |
789 while (curr != NULL) { |
862 if (lookupIPAddrTable(env, &tableP) >= 0) { |
790 int count; |
863 curr = ifList; |
791 netaddr *addrList; |
864 while (curr != NULL) { |
792 netaddr *addrP; |
865 int count; |
793 |
866 netaddr *addrList; |
794 /* enumerate the addresses on this interface */ |
867 netaddr *addrP; |
795 count = enumAddresses_win(env, curr, &addrList); |
868 |
796 if (count < 0) { |
869 /* enumerate the addresses on this interface */ |
797 free_netif(ifList); |
870 count = enumAddresses_win_ipaddrtable(env, curr, &addrList, tableP); |
798 return NULL; |
871 if (count < 0) { |
799 } |
872 free_netif(ifList); |
800 |
873 free(tableP); |
801 /* iterate through each address */ |
874 return NULL; |
802 addrP = addrList; |
875 } |
803 |
876 |
804 while (addrP != NULL) { |
877 /* iterate through each address */ |
805 if ((unsigned long)addr == ntohl(addrP->addr.sa4.sin_addr.s_addr)) { |
878 addrP = addrList; |
|
879 |
|
880 while (addrP != NULL) { |
|
881 if ((unsigned long)addr == ntohl(addrP->addr.sa4.sin_addr.s_addr)) { |
|
882 break; |
|
883 } |
|
884 addrP = addrP->next; |
|
885 } |
|
886 |
|
887 /* |
|
888 * Address matched so create NetworkInterface for this interface |
|
889 * and address list. |
|
890 */ |
|
891 if (addrP != NULL) { |
|
892 /* createNetworkInterface will free addrList */ |
|
893 netifObj = createNetworkInterface(env, curr, count, addrList); |
806 break; |
894 break; |
807 } |
895 } |
808 addrP = addrP->next; |
896 |
809 } |
897 /* on next interface */ |
810 |
898 curr = curr->next; |
811 /* |
899 } |
812 * Address matched so create NetworkInterface for this interface |
900 } |
813 * and address list. |
901 |
814 */ |
902 /* release the IP address table */ |
815 if (addrP != NULL) { |
903 if (tableP != NULL) |
816 /* createNetworkInterface will free addrList */ |
904 free(tableP); |
817 netifObj = createNetworkInterface(env, curr, count, addrList); |
|
818 break; |
|
819 } |
|
820 |
|
821 /* on next interface */ |
|
822 curr = curr->next; |
|
823 } |
|
824 |
905 |
825 /* release the interface list */ |
906 /* release the interface list */ |
826 free_netif(ifList); |
907 free_netif(ifList); |
827 |
908 |
828 return netifObj; |
909 return netifObj; |