jdk/src/java.base/unix/native/libnet/NetworkInterface.c
changeset 38885 42d2c26ffdf3
parent 38563 3ab5f00bd5a3
child 39318 2006d1d41c8b
equal deleted inserted replaced
38884:48a0335cdadc 38885:42d2c26ffdf3
   133 #ifdef AF_INET6
   133 #ifdef AF_INET6
   134 static netif  *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs);
   134 static netif  *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs);
   135 #endif
   135 #endif
   136 
   136 
   137 static netif  *addif(JNIEnv *env, int sock, const char *if_name, netif *ifs,
   137 static netif  *addif(JNIEnv *env, int sock, const char *if_name, netif *ifs,
   138                      struct sockaddr *ifr_addrP, int family, short prefix);
   138                      struct sockaddr *ifr_addrP, struct sockaddr *ifr_broadaddrP,
       
   139                      struct sockaddr *ifr_subnetaddrP, int family, short prefix);
   139 static void    freeif(netif *ifs);
   140 static void    freeif(netif *ifs);
   140 
   141 
   141 static int     openSocket(JNIEnv *env, int proto);
   142 static int     openSocket(JNIEnv *env, int proto);
   142 static int     openSocketWithFallback(JNIEnv *env, const char *ifname);
   143 static int     openSocketWithFallback(JNIEnv *env, const char *ifname);
   143 
   144 
   144 
   145 
   145 static struct  sockaddr *getBroadcast(JNIEnv *env, int sock, const char *name,
   146 static struct  sockaddr *getBroadcast(JNIEnv *env, int sock, const char *name,
   146                                       struct sockaddr *brdcast_store);
   147                                       struct sockaddr *brdcast_store);
   147 static short   getSubnet(JNIEnv *env, int sock, const char *ifname);
   148 static short   getSubnet(JNIEnv *env, int sock, const char *ifname);
       
   149 static short   computeMaskFromAddress(struct sockaddr *ifr_subnetaddrP);
   148 static int     getIndex(int sock, const char *ifname);
   150 static int     getIndex(int sock, const char *ifname);
   149 
   151 
   150 static int     getFlags(int sock, const char *ifname, int *flags);
   152 static int     getFlags(int sock, const char *ifname, int *flags);
   151 static int     getMacAddress(JNIEnv *env, int sock,  const char *ifname,
   153 static int     getMacAddress(JNIEnv *env, int sock,  const char *ifname,
   152                              const struct in_addr *addr, unsigned char *buf);
   154                              const struct in_addr *addr, unsigned char *buf);
   862         currif = ifs;
   864         currif = ifs;
   863     }
   865     }
   864 }
   866 }
   865 
   867 
   866 netif *addif(JNIEnv *env, int sock, const char *if_name, netif *ifs,
   868 netif *addif(JNIEnv *env, int sock, const char *if_name, netif *ifs,
   867              struct sockaddr *ifr_addrP, int family, short prefix)
   869              struct sockaddr *ifr_addrP, struct sockaddr *ifr_broadaddrP,
       
   870              struct sockaddr *ifr_subnetaddrP, int family, short prefix)
   868 {
   871 {
   869     netif *currif = ifs, *parent;
   872     netif *currif = ifs, *parent;
   870     netaddr *addrP;
   873     netaddr *addrP;
   871 
   874 
   872 #ifdef LIFNAMSIZ
   875 #ifdef LIFNAMSIZ
   910     addrP->family = family;
   913     addrP->family = family;
   911     addrP->brdcast = NULL;
   914     addrP->brdcast = NULL;
   912     addrP->mask = prefix;
   915     addrP->mask = prefix;
   913     addrP->next = 0;
   916     addrP->next = 0;
   914     if (family == AF_INET) {
   917     if (family == AF_INET) {
   915        // Deal with broadcast addr & subnet mask
   918         // Deal with broadcast addr & subnet mask
   916        struct sockaddr *brdcast_to =
   919         if (ifr_broadaddrP != NULL) {  // just set it, if already known
   917               (struct sockaddr *) ((char *)addrP + sizeof(netaddr) + addr_size);
   920             addrP->brdcast =
   918        addrP->brdcast = getBroadcast(env, sock, name, brdcast_to);
   921                 (struct sockaddr *)((char *)addrP + sizeof(netaddr) + addr_size);
   919        if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
   922             memcpy(addrP->brdcast, ifr_broadaddrP, addr_size);
   920            return ifs;
   923         } else {  // otherwise look it up
   921        }
   924             struct sockaddr *brdcast_to =
   922        if ((mask = getSubnet(env, sock, name)) != -1) {
   925                 (struct sockaddr *)((char *)addrP + sizeof(netaddr) + addr_size);
   923            addrP->mask = mask;
   926             addrP->brdcast = getBroadcast(env, sock, name, brdcast_to);
   924        } else if((*env)->ExceptionCheck(env)) {
   927             if ((*env)->ExceptionCheck(env) == JNI_TRUE) {
   925            return ifs;
   928                 return ifs;
   926        }
   929             }
   927      }
   930         }
       
   931 
       
   932         if (ifr_subnetaddrP != NULL) {  // just compute the mask, if already known
       
   933             addrP->mask = computeMaskFromAddress(ifr_subnetaddrP);
       
   934         } else {   // otherwise look it up
       
   935             if ((mask = getSubnet(env, sock, name)) != -1) {
       
   936                 addrP->mask = mask;
       
   937             } else if((*env)->ExceptionCheck(env)) {
       
   938                 return ifs;
       
   939             }
       
   940         }
       
   941     }
   928 
   942 
   929     // Deal with virtual interface with colon notation e.g. eth0:1
   943     // Deal with virtual interface with colon notation e.g. eth0:1
   930     name_colonP = strchr(name, ':');
   944     name_colonP = strchr(name, ':');
   931     if (name_colonP != NULL) {
   945     if (name_colonP != NULL) {
   932         // This is a virtual interface. If we are able to access the parent
   946         // This is a virtual interface. If we are able to access the parent
  1021     }
  1035     }
  1022 
  1036 
  1023     return ifs;
  1037     return ifs;
  1024 }
  1038 }
  1025 
  1039 
       
  1040 static short computeMaskFromAddress(struct sockaddr *ifr_subnetaddrP) {
       
  1041     short ret = 0;
       
  1042     unsigned int mask;
       
  1043 
       
  1044     mask = ntohl(((struct sockaddr_in*)ifr_subnetaddrP)->sin_addr.s_addr);
       
  1045 
       
  1046     while (mask) {
       
  1047        mask <<= 1;
       
  1048        ret++;
       
  1049     }
       
  1050 
       
  1051     return ret;
       
  1052 }
       
  1053 
  1026 /*
  1054 /*
  1027  * Opens a socket for further ioct calls. proto is one of AF_INET or AF_INET6.
  1055  * Opens a socket for further ioct calls. proto is one of AF_INET or AF_INET6.
  1028  */
  1056  */
  1029 static int openSocket(JNIEnv *env, int proto) {
  1057 static int openSocket(JNIEnv *env, int proto) {
  1030     int sock;
  1058     int sock;
  1120         return ifs;
  1148         return ifs;
  1121     }
  1149     }
  1122 
  1150 
  1123     // Iterate through each interface
  1151     // Iterate through each interface
  1124     ifreqP = ifc.ifc_req;
  1152     ifreqP = ifc.ifc_req;
       
  1153     struct sockaddr addr, broadaddr, netmask;
  1125     for (i = 0; i < ifc.ifc_len / sizeof(struct ifreq); i++, ifreqP++) {
  1154     for (i = 0; i < ifc.ifc_len / sizeof(struct ifreq); i++, ifreqP++) {
       
  1155         struct sockaddr* broadaddrP = NULL;
       
  1156         struct sockaddr* subnetaddrP = NULL;
       
  1157 
       
  1158         // Ignore non IPv4 Interfaces
       
  1159         if ((struct sockaddr *)&(ifreqP->ifr_addr) != NULL &&
       
  1160             ((struct sockaddr *)&(ifreqP->ifr_addr))->sa_family != AF_INET) {
       
  1161             continue;
       
  1162         }
       
  1163 
       
  1164         memcpy(&addr, &(ifreqP->ifr_addr), sizeof(struct sockaddr));
       
  1165 
       
  1166         // set broadaddrP, if applicable
       
  1167         if ((ifreqP->ifr_flags & IFF_POINTOPOINT) == 0 &&
       
  1168             ifreqP->ifr_flags & IFF_BROADCAST) {
       
  1169 
       
  1170             if (ioctl(sock, SIOCGIFBRDADDR, ifreqP) == 0) {
       
  1171                 memcpy(&broadaddr, &(ifreqP->ifr_broadaddr), sizeof(struct sockaddr));
       
  1172                 broadaddrP = &broadaddr;
       
  1173             }
       
  1174             // restore the address, for subsequent calls
       
  1175             memcpy(&(ifreqP->ifr_addr), &addr, sizeof(struct sockaddr));
       
  1176         }
       
  1177 
       
  1178         if (ioctl(sock, SIOCGIFNETMASK, ifreqP) == 0) {
  1126 #if defined(_AIX)
  1179 #if defined(_AIX)
  1127         if (ifreqP->ifr_addr.sa_family != AF_INET) continue;
  1180             memcpy(&netmask, &(ifreqP->ifr_addr), sizeof(struct sockaddr));
  1128 #endif
  1181 #else
       
  1182             memcpy(&netmask, &(ifreqP->ifr_netmask), sizeof(struct sockaddr));
       
  1183 #endif
       
  1184             subnetaddrP = &netmask;
       
  1185         }
       
  1186 
  1129         // Add to the list
  1187         // Add to the list
  1130         ifs = addif(env, sock, ifreqP->ifr_name, ifs,
  1188         ifs = addif(env, sock, ifreqP->ifr_name, ifs,
  1131                     (struct sockaddr *)&(ifreqP->ifr_addr), AF_INET, 0);
  1189                     &addr, broadaddrP, subnetaddrP, AF_INET, 0);
  1132 
  1190 
  1133         // If an exception occurred then free the list
  1191         // If an exception occurred then free the list
  1134         if ((*env)->ExceptionOccurred(env)) {
  1192         if ((*env)->ExceptionOccurred(env)) {
  1135             free(buf);
  1193             free(buf);
  1136             freeif(ifs);
  1194             freeif(ifs);
  1175             memcpy((void*)addr.sin6_addr.s6_addr, (const void*)ipv6addr, 16);
  1233             memcpy((void*)addr.sin6_addr.s6_addr, (const void*)ipv6addr, 16);
  1176 
  1234 
  1177             addr.sin6_scope_id = if_idx;
  1235             addr.sin6_scope_id = if_idx;
  1178 
  1236 
  1179             ifs = addif(env, sock, devname, ifs, (struct sockaddr *)&addr,
  1237             ifs = addif(env, sock, devname, ifs, (struct sockaddr *)&addr,
  1180                         AF_INET6, (short)prefix);
  1238                         NULL, NULL, AF_INET6, (short)prefix);
  1181 
  1239 
  1182             // If an exception occurred then return the list as is.
  1240             // If an exception occurred then return the list as is.
  1183             if ((*env)->ExceptionOccurred(env)) {
  1241             if ((*env)->ExceptionOccurred(env)) {
  1184                 fclose(f);
  1242                 fclose(f);
  1185                 return ifs;
  1243                 return ifs;
  1259             s6->sin6_scope_id = if2.ifr_site6;
  1317             s6->sin6_scope_id = if2.ifr_site6;
  1260         }
  1318         }
  1261 
  1319 
  1262         // Add to the list
  1320         // Add to the list
  1263         ifs = addif(env, sock, ifreqP->ifr_name, ifs,
  1321         ifs = addif(env, sock, ifreqP->ifr_name, ifs,
  1264                     (struct sockaddr *)&(ifreqP->ifr_addr), AF_INET6, 0);
  1322                     (struct sockaddr *)&(ifreqP->ifr_addr),
       
  1323                     NULL, NULL, AF_INET6, 0);
  1265 
  1324 
  1266         // If an exception occurred then free the list
  1325         // If an exception occurred then free the list
  1267         if ((*env)->ExceptionOccurred(env)) {
  1326         if ((*env)->ExceptionOccurred(env)) {
  1268             free(buf);
  1327             free(buf);
  1269             freeif(ifs);
  1328             freeif(ifs);
  1344         NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
  1403         NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
  1345                                      "ioctl SIOCGIFNETMASK failed");
  1404                                      "ioctl SIOCGIFNETMASK failed");
  1346         return -1;
  1405         return -1;
  1347     }
  1406     }
  1348 
  1407 
  1349     mask = ntohl(((struct sockaddr_in*)&(if2.ifr_addr))->sin_addr.s_addr);
  1408     return computeMaskFromAddress(&(if2.ifr_addr));
  1350     ret = 0;
       
  1351     while (mask) {
       
  1352        mask <<= 1;
       
  1353        ret++;
       
  1354     }
       
  1355 
       
  1356     return ret;
       
  1357 }
  1409 }
  1358 
  1410 
  1359 /*
  1411 /*
  1360  * Gets the Hardware address (usually MAC address) for the named interface.
  1412  * Gets the Hardware address (usually MAC address) for the named interface.
  1361  * On return puts the data in buf, and returns the length, in byte, of the
  1413  * On return puts the data in buf, and returns the length, in byte, of the
  1593         }
  1645         }
  1594 #endif
  1646 #endif
  1595 
  1647 
  1596         // add to the list
  1648         // add to the list
  1597         ifs = addif(env, sock,ifr->lifr_name, ifs,
  1649         ifs = addif(env, sock,ifr->lifr_name, ifs,
  1598                     (struct sockaddr *)&(ifr->lifr_addr), family,
  1650                     (struct sockaddr *)&(ifr->lifr_addr),
  1599                     (short)ifr->lifr_addrlen);
  1651                     NULL, NULL, family, (short)ifr->lifr_addrlen);
  1600 
  1652 
  1601         // If an exception occurred we return immediately
  1653         // If an exception occurred we return immediately
  1602         if ((*env)->ExceptionOccurred(env)) {
  1654         if ((*env)->ExceptionOccurred(env)) {
  1603             free(buf);
  1655             free(buf);
  1604             return ifs;
  1656             return ifs;
  1672         NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
  1724         NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
  1673                                      "ioctl SIOCGLIFNETMASK failed");
  1725                                      "ioctl SIOCGLIFNETMASK failed");
  1674         return -1;
  1726         return -1;
  1675     }
  1727     }
  1676 
  1728 
  1677     mask = ntohl(((struct sockaddr_in*)&(if2.lifr_addr))->sin_addr.s_addr);
  1729     return computeMaskFromAddress(&(if2.lifr_addr));
  1678     ret = 0;
       
  1679 
       
  1680     while (mask) {
       
  1681        mask <<= 1;
       
  1682        ret++;
       
  1683     }
       
  1684 
       
  1685     return ret;
       
  1686 }
  1730 }
  1687 
  1731 
  1688 
  1732 
  1689 #define DEV_PREFIX  "/dev/"
  1733 #define DEV_PREFIX  "/dev/"
  1690 
  1734 
  1887                                      "getifaddrs() function failed");
  1931                                      "getifaddrs() function failed");
  1888         return ifs;
  1932         return ifs;
  1889     }
  1933     }
  1890 
  1934 
  1891     for (ifa = origifa; ifa != NULL; ifa = ifa->ifa_next) {
  1935     for (ifa = origifa; ifa != NULL; ifa = ifa->ifa_next) {
       
  1936         struct sockaddr* ifa_broadaddr = NULL;
  1892 
  1937 
  1893         // Skip non-AF_INET entries.
  1938         // Skip non-AF_INET entries.
  1894         if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET)
  1939         if (ifa->ifa_addr == NULL || ifa->ifa_addr->sa_family != AF_INET)
  1895             continue;
  1940             continue;
  1896 
  1941 
       
  1942         // set ifa_broadaddr, if there is one
       
  1943         if ((ifa->ifa_flags & IFF_POINTOPOINT) == 0 &&
       
  1944             ifa->ifa_flags & IFF_BROADCAST) {
       
  1945             ifa_broadaddr = ifa->ifa_broadaddr;
       
  1946         }
       
  1947 
  1897         // Add to the list.
  1948         // Add to the list.
  1898         ifs = addif(env, sock, ifa->ifa_name, ifs, ifa->ifa_addr, AF_INET, 0);
  1949         ifs = addif(env, sock, ifa->ifa_name, ifs, ifa->ifa_addr,
       
  1950                     ifa_broadaddr, ifa->ifa_netmask, AF_INET, 0);
  1899 
  1951 
  1900         // If an exception occurred then free the list.
  1952         // If an exception occurred then free the list.
  1901         if ((*env)->ExceptionOccurred(env)) {
  1953         if ((*env)->ExceptionOccurred(env)) {
  1902             freeifaddrs(origifa);
  1954             freeifaddrs(origifa);
  1903             freeif(ifs);
  1955             freeif(ifs);
  1969             return NULL;
  2021             return NULL;
  1970         }
  2022         }
  1971 
  2023 
  1972         // Add to the list.
  2024         // Add to the list.
  1973         sin6 = (struct sockaddr_in6 *)&ifr6.ifr_addr;
  2025         sin6 = (struct sockaddr_in6 *)&ifr6.ifr_addr;
  1974         ifs = addif(env, sock, ifa->ifa_name, ifs, ifa->ifa_addr, AF_INET6,
  2026         ifs = addif(env, sock, ifa->ifa_name, ifs, ifa->ifa_addr, NULL, NULL,
  1975             (short)prefix(&sin6->sin6_addr, sizeof(struct in6_addr)));
  2027                     AF_INET6,
       
  2028                     (short)prefix(&sin6->sin6_addr, sizeof(struct in6_addr)));
  1976 
  2029 
  1977         // If an exception occurred then free the list.
  2030         // If an exception occurred then free the list.
  1978         if ((*env)->ExceptionOccurred(env)) {
  2031         if ((*env)->ExceptionOccurred(env)) {
  1979             freeifaddrs(origifa);
  2032             freeifaddrs(origifa);
  1980             freeif(ifs);
  2033             freeif(ifs);
  2057         NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
  2110         NET_ThrowByNameWithLastError(env, JNU_JAVANETPKG "SocketException",
  2058                                      "ioctl SIOCGIFNETMASK failed");
  2111                                      "ioctl SIOCGIFNETMASK failed");
  2059         return -1;
  2112         return -1;
  2060     }
  2113     }
  2061 
  2114 
  2062     mask = ntohl(((struct sockaddr_in*)&(if2.ifr_addr))->sin_addr.s_addr);
  2115     return computeMaskFromAddress(&(if2.ifr_addr));
  2063     ret = 0;
       
  2064     while (mask) {
       
  2065        mask <<= 1;
       
  2066        ret++;
       
  2067     }
       
  2068 
       
  2069     return ret;
       
  2070 }
  2116 }
  2071 
  2117 
  2072 /*
  2118 /*
  2073  * Gets the Hardware address (usually MAC address) for the named interface.
  2119  * Gets the Hardware address (usually MAC address) for the named interface.
  2074  * return puts the data in buf, and returns the length, in byte, of the
  2120  * return puts the data in buf, and returns the length, in byte, of the