src/java.base/windows/native/libnet/NetworkInterface.c
changeset 55596 d01b345865d7
parent 53316 066d2261108f
equal deleted inserted replaced
55595:cf5a438b3c41 55596:d01b345865d7
     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;