jdk/src/solaris/native/java/net/NetworkInterface.c
changeset 22597 7515a991bb37
parent 21409 246ccfb4a0f0
child 22605 dba3d6b22818
equal deleted inserted replaced
22596:62542b8be764 22597:7515a991bb37
     1 /*
     1 /*
     2  * Copyright (c) 2000, 2012, Oracle and/or its affiliates. All rights reserved.
     2  * Copyright (c) 2000, 2013, 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
    48 #ifdef __linux__
    48 #ifdef __linux__
    49 #include <sys/ioctl.h>
    49 #include <sys/ioctl.h>
    50 #include <bits/ioctls.h>
    50 #include <bits/ioctls.h>
    51 #include <sys/utsname.h>
    51 #include <sys/utsname.h>
    52 #include <stdio.h>
    52 #include <stdio.h>
       
    53 #endif
       
    54 
       
    55 #if defined(_AIX)
       
    56 #include <sys/ioctl.h>
       
    57 #include <netinet/in6_var.h>
       
    58 #include <sys/ndd_var.h>
       
    59 #include <sys/kinfo.h>
    53 #endif
    60 #endif
    54 
    61 
    55 #ifdef __linux__
    62 #ifdef __linux__
    56 #define _PATH_PROCNET_IFINET6           "/proc/net/if_inet6"
    63 #define _PATH_PROCNET_IFINET6           "/proc/net/if_inet6"
    57 #endif
    64 #endif
  1039 
  1046 
  1040     return sock;
  1047     return sock;
  1041 }
  1048 }
  1042 
  1049 
  1043 
  1050 
  1044 /** Linux **/
  1051 /** Linux, AIX **/
  1045 #ifdef __linux__
  1052 #if defined(__linux__) || defined(_AIX)
  1046 /* Open socket for further ioct calls, try v4 socket first and
  1053 /* Open socket for further ioct calls, try v4 socket first and
  1047  * if it falls return v6 socket
  1054  * if it falls return v6 socket
  1048  */
  1055  */
  1049 
  1056 
  1050 #ifdef AF_INET6
  1057 #ifdef AF_INET6
  1078 #endif
  1085 #endif
  1079 
  1086 
  1080 static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) {
  1087 static netif *enumIPv4Interfaces(JNIEnv *env, int sock, netif *ifs) {
  1081     struct ifconf ifc;
  1088     struct ifconf ifc;
  1082     struct ifreq *ifreqP;
  1089     struct ifreq *ifreqP;
  1083     char *buf;
  1090     char *buf = NULL;
  1084     int numifs;
  1091     int numifs;
  1085     unsigned i;
  1092     unsigned i;
  1086 
  1093     int siocgifconfRequest = SIOCGIFCONF;
  1087 
  1094 
       
  1095 
       
  1096 #if defined(__linux__)
  1088     /* need to do a dummy SIOCGIFCONF to determine the buffer size.
  1097     /* need to do a dummy SIOCGIFCONF to determine the buffer size.
  1089      * SIOCGIFCOUNT doesn't work
  1098      * SIOCGIFCOUNT doesn't work
  1090      */
  1099      */
  1091     ifc.ifc_buf = NULL;
  1100     ifc.ifc_buf = NULL;
  1092     if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
  1101     if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
  1093         NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGIFCONF failed");
  1102         NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGIFCONF failed");
  1094         return ifs;
  1103         return ifs;
  1095     }
  1104     }
       
  1105 #elif defined(_AIX)
       
  1106     ifc.ifc_buf = NULL;
       
  1107     if (ioctl(sock, SIOCGSIZIFCONF, &(ifc.ifc_len)) < 0) {
       
  1108         NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGSIZIFCONF failed");
       
  1109         return ifs;
       
  1110     }
       
  1111 #endif /* __linux__ */
  1096 
  1112 
  1097     CHECKED_MALLOC3(buf,char *, ifc.ifc_len);
  1113     CHECKED_MALLOC3(buf,char *, ifc.ifc_len);
  1098 
  1114 
  1099     ifc.ifc_buf = buf;
  1115     ifc.ifc_buf = buf;
  1100     if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
  1116 #if defined(_AIX)
       
  1117     siocgifconfRequest = CSIOCGIFCONF;
       
  1118 #endif
       
  1119     if (ioctl(sock, siocgifconfRequest, (char *)&ifc) < 0) {
  1101         NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGIFCONF failed");
  1120         NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException", "ioctl SIOCGIFCONF failed");
  1102         (void) free(buf);
  1121         (void) free(buf);
  1103         return ifs;
  1122         return ifs;
  1104     }
  1123     }
  1105 
  1124 
  1106     /*
  1125     /*
  1107      * Iterate through each interface
  1126      * Iterate through each interface
  1108      */
  1127      */
  1109     ifreqP = ifc.ifc_req;
  1128     ifreqP = ifc.ifc_req;
  1110     for (i=0; i<ifc.ifc_len/sizeof (struct ifreq); i++, ifreqP++) {
  1129     for (i=0; i<ifc.ifc_len/sizeof (struct ifreq); i++, ifreqP++) {
       
  1130 #if defined(_AIX)
       
  1131         if (ifreqP->ifr_addr.sa_family != AF_INET) continue;
       
  1132 #endif
  1111         /*
  1133         /*
  1112          * Add to the list
  1134          * Add to the list
  1113          */
  1135          */
  1114         ifs = addif(env, sock, ifreqP->ifr_name, ifs, (struct sockaddr *) & (ifreqP->ifr_addr), AF_INET, 0);
  1136         ifs = addif(env, sock, ifreqP->ifr_name, ifs, (struct sockaddr *) & (ifreqP->ifr_addr), AF_INET, 0);
  1115 
  1137 
  1133 
  1155 
  1134 /*
  1156 /*
  1135  * Enumerates and returns all IPv6 interfaces on Linux
  1157  * Enumerates and returns all IPv6 interfaces on Linux
  1136  */
  1158  */
  1137 
  1159 
  1138 #ifdef AF_INET6
  1160 #if defined(AF_INET6) && defined(__linux__)
  1139 static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) {
  1161 static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) {
  1140     FILE *f;
  1162     FILE *f;
  1141     char addr6[40], devname[21];
  1163     char addr6[40], devname[21];
  1142     char addr6p[8][5];
  1164     char addr6p[8][5];
  1143     int plen, scope, dad_status, if_idx;
  1165     int plen, scope, dad_status, if_idx;
  1177     return ifs;
  1199     return ifs;
  1178 }
  1200 }
  1179 #endif
  1201 #endif
  1180 
  1202 
  1181 
  1203 
       
  1204 /*
       
  1205  * Enumerates and returns all IPv6 interfaces on AIX
       
  1206  */
       
  1207 
       
  1208 #if defined(AF_INET6) && defined(_AIX)
       
  1209 static netif *enumIPv6Interfaces(JNIEnv *env, int sock, netif *ifs) {
       
  1210     struct ifconf ifc;
       
  1211     struct ifreq *ifreqP;
       
  1212     char *buf;
       
  1213     int numifs;
       
  1214     unsigned i;
       
  1215     unsigned bufsize;
       
  1216     char *cp, *cplimit;
       
  1217 
       
  1218     /* use SIOCGSIZIFCONF to get size for  SIOCGIFCONF */
       
  1219 
       
  1220     ifc.ifc_buf = NULL;
       
  1221     if (ioctl(sock, SIOCGSIZIFCONF, &(ifc.ifc_len)) < 0) {
       
  1222         NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException",
       
  1223                         "ioctl SIOCGSIZIFCONF failed");
       
  1224         return ifs;
       
  1225     }
       
  1226     bufsize = ifc.ifc_len;
       
  1227 
       
  1228     buf = (char *)malloc(bufsize);
       
  1229     if (!buf) {
       
  1230         JNU_ThrowOutOfMemoryError(env, "Network interface native buffer allocation failed");
       
  1231         return ifs;
       
  1232     }
       
  1233     ifc.ifc_len = bufsize;
       
  1234     ifc.ifc_buf = buf;
       
  1235     if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) {
       
  1236         NET_ThrowByNameWithLastError(env , JNU_JAVANETPKG "SocketException",
       
  1237                        "ioctl CSIOCGIFCONF failed");
       
  1238         free(buf);
       
  1239         return ifs;
       
  1240     }
       
  1241 
       
  1242     /*
       
  1243      * Iterate through each interface
       
  1244      */
       
  1245     ifreqP = ifc.ifc_req;
       
  1246     cp = (char *)ifc.ifc_req;
       
  1247     cplimit = cp + ifc.ifc_len;
       
  1248 
       
  1249     for ( ; cp < cplimit; cp += (sizeof(ifreqP->ifr_name) + MAX((ifreqP->ifr_addr).sa_len, sizeof(ifreqP->ifr_addr)))) {
       
  1250         ifreqP = (struct ifreq *)cp;
       
  1251         struct ifreq if2;
       
  1252 
       
  1253         memset((char *)&if2, 0, sizeof(if2));
       
  1254         strcpy(if2.ifr_name, ifreqP->ifr_name);
       
  1255 
       
  1256         /*
       
  1257          * Skip interface that aren't UP
       
  1258          */
       
  1259         if (ioctl(sock, SIOCGIFFLAGS, (char *)&if2) >= 0) {
       
  1260             if (!(if2.ifr_flags & IFF_UP)) {
       
  1261                 continue;
       
  1262             }
       
  1263         }
       
  1264 
       
  1265         if (ifreqP->ifr_addr.sa_family != AF_INET6)
       
  1266             continue;
       
  1267 
       
  1268         /*
       
  1269          * Add to the list
       
  1270          */
       
  1271         ifs = addif(env, sock, ifreqP->ifr_name, ifs,
       
  1272                     (struct sockaddr *)&(ifreqP->ifr_addr),
       
  1273                      AF_INET6, 0);
       
  1274 
       
  1275         /*
       
  1276          * If an exception occurred then free the list
       
  1277          */
       
  1278         if ((*env)->ExceptionOccurred(env)) {
       
  1279             free(buf);
       
  1280             freeif(ifs);
       
  1281             return NULL;
       
  1282         }
       
  1283     }
       
  1284 
       
  1285     /*
       
  1286      * Free socket and buffer
       
  1287      */
       
  1288     free(buf);
       
  1289     return ifs;
       
  1290 }
       
  1291 #endif
       
  1292 
       
  1293 
  1182 static int getIndex(int sock, const char *name){
  1294 static int getIndex(int sock, const char *name){
  1183      /*
  1295      /*
  1184       * Try to get the interface index
  1296       * Try to get the interface index
  1185       * (Not supported on Solaris 2.6 or 7)
       
  1186       */
  1297       */
       
  1298 #if defined(_AIX)
       
  1299     return if_nametoindex(name);
       
  1300 #else
  1187     struct ifreq if2;
  1301     struct ifreq if2;
  1188     strcpy(if2.ifr_name, name);
  1302     strcpy(if2.ifr_name, name);
  1189 
  1303 
  1190     if (ioctl(sock, SIOCGIFINDEX, (char *)&if2) < 0) {
  1304     if (ioctl(sock, SIOCGIFINDEX, (char *)&if2) < 0) {
  1191         return -1;
  1305         return -1;
  1192     }
  1306     }
  1193 
  1307 
  1194     return if2.ifr_ifindex;
  1308     return if2.ifr_ifindex;
       
  1309 #endif
  1195 }
  1310 }
  1196 
  1311 
  1197 /**
  1312 /**
  1198  * Returns the IPv4 broadcast address of a named interface, if it exists.
  1313  * Returns the IPv4 broadcast address of a named interface, if it exists.
  1199  * Returns 0 if it doesn't have one.
  1314  * Returns 0 if it doesn't have one.
  1256  * Get the Hardware address (usually MAC address) for the named interface.
  1371  * Get the Hardware address (usually MAC address) for the named interface.
  1257  * return puts the data in buf, and returns the length, in byte, of the
  1372  * return puts the data in buf, and returns the length, in byte, of the
  1258  * MAC address. Returns -1 if there is no hardware address on that interface.
  1373  * MAC address. Returns -1 if there is no hardware address on that interface.
  1259  */
  1374  */
  1260 static int getMacAddress(JNIEnv *env, int sock, const char* ifname, const struct in_addr* addr, unsigned char *buf) {
  1375 static int getMacAddress(JNIEnv *env, int sock, const char* ifname, const struct in_addr* addr, unsigned char *buf) {
       
  1376 #if defined (_AIX)
       
  1377     int size;
       
  1378     struct kinfo_ndd *nddp;
       
  1379     void *end;
       
  1380 
       
  1381     size = getkerninfo(KINFO_NDD, 0, 0, 0);
       
  1382     if (size == 0) {
       
  1383         return -1;
       
  1384     }
       
  1385 
       
  1386     if (size < 0) {
       
  1387         perror("getkerninfo 1");
       
  1388         return -1;
       
  1389     }
       
  1390 
       
  1391     nddp = (struct kinfo_ndd *)malloc(size);
       
  1392 
       
  1393     if (!nddp) {
       
  1394         return -1;
       
  1395     }
       
  1396 
       
  1397     if (getkerninfo(KINFO_NDD, nddp, &size, 0) < 0) {
       
  1398         perror("getkerninfo 2");
       
  1399         return -1;
       
  1400     }
       
  1401 
       
  1402     end = (void *)nddp + size;
       
  1403     while ((void *)nddp < end) {
       
  1404         if (!strcmp(nddp->ndd_alias, ifname) ||
       
  1405                 !strcmp(nddp->ndd_name, ifname)) {
       
  1406             bcopy(nddp->ndd_addr, buf, 6);
       
  1407             return 6;
       
  1408         } else {
       
  1409             nddp++;
       
  1410         }
       
  1411     }
       
  1412 
       
  1413     return -1;
       
  1414 
       
  1415 #elif defined(__linux__)
  1261     static struct ifreq ifr;
  1416     static struct ifreq ifr;
  1262     int i;
  1417     int i;
  1263 
  1418 
  1264     strcpy(ifr.ifr_name, ifname);
  1419     strcpy(ifr.ifr_name, ifname);
  1265     if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) {
  1420     if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0) {
  1277         if (buf[i] != 0)
  1432         if (buf[i] != 0)
  1278             return IFHWADDRLEN;
  1433             return IFHWADDRLEN;
  1279     }
  1434     }
  1280 
  1435 
  1281     return -1;
  1436     return -1;
       
  1437 #endif
  1282 }
  1438 }
  1283 
  1439 
  1284 static int getMTU(JNIEnv *env, int sock,  const char *ifname) {
  1440 static int getMTU(JNIEnv *env, int sock,  const char *ifname) {
  1285     struct ifreq if2;
  1441     struct ifreq if2;
  1286 
  1442