55 56 /* 57 * Inet6AddressImpl 58 */ 59 60 /* 61 * Class: java_net_Inet6AddressImpl 62 * Method: getLocalHostName 63 * Signature: ()Ljava/lang/String; 64 */ 65 JNIEXPORT jstring JNICALL 66 Java_java_net_Inet6AddressImpl_getLocalHostName (JNIEnv *env, jobject this) { 67 char hostname [256]; 68 69 if (gethostname (hostname, sizeof (hostname)) == -1) { 70 strcpy (hostname, "localhost"); 71 } 72 return JNU_NewStringPlatform (env, hostname); 73 } 74 75 static jclass ni_iacls; 76 static jclass ni_ia4cls; 77 static jclass ni_ia6cls; 78 static jmethodID ni_ia4ctrID; 79 static jmethodID ni_ia6ctrID; 80 static jfieldID ni_iaaddressID; 81 static jfieldID ni_iahostID; 82 static jfieldID ni_iafamilyID; 83 static jfieldID ni_ia6ipaddressID; 84 static int initialized = 0; 85 86 JNIEXPORT jobjectArray JNICALL 87 Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, 88 jstring host) { 89 const char *hostname; 90 jobjectArray ret = 0; 91 int retLen = 0; 92 jboolean preferIPv6Address; 93 94 int error=0; 95 struct addrinfo hints, *res, *resNew = NULL; 96 97 if (!initialized) { 98 ni_iacls = (*env)->FindClass(env, "java/net/InetAddress"); 99 ni_iacls = (*env)->NewGlobalRef(env, ni_iacls); 100 ni_ia4cls = (*env)->FindClass(env, "java/net/Inet4Address"); 101 ni_ia4cls = (*env)->NewGlobalRef(env, ni_ia4cls); 102 ni_ia6cls = (*env)->FindClass(env, "java/net/Inet6Address"); 103 ni_ia6cls = (*env)->NewGlobalRef(env, ni_ia6cls); 104 ni_ia4ctrID = (*env)->GetMethodID(env, ni_ia4cls, "<init>", "()V"); 105 ni_ia6ctrID = (*env)->GetMethodID(env, ni_ia6cls, "<init>", "()V"); 106 ni_iaaddressID = (*env)->GetFieldID(env, ni_iacls, "address", "I"); 107 ni_iafamilyID = (*env)->GetFieldID(env, ni_iacls, "family", "I"); 108 ni_iahostID = (*env)->GetFieldID(env, ni_iacls, "hostName", "Ljava/lang/String;"); 109 ni_ia6ipaddressID = (*env)->GetFieldID(env, ni_ia6cls, "ipaddress", "[B"); 110 initialized = 1; 111 } 112 if (IS_NULL(host)) { 113 JNU_ThrowNullPointerException(env, "host is null"); 114 return 0; 115 } 116 hostname = JNU_GetStringPlatformChars(env, host, JNI_FALSE); 117 CHECK_NULL_RETURN(hostname, NULL); 118 119 if (NET_addrtransAvailable()) { 120 static jfieldID ia_preferIPv6AddressID; 121 if (ia_preferIPv6AddressID == NULL) { 122 jclass c = (*env)->FindClass(env,"java/net/InetAddress"); 123 if (c) { 124 ia_preferIPv6AddressID = 125 (*env)->GetStaticFieldID(env, c, "preferIPv6Address", "Z"); 126 } 127 if (ia_preferIPv6AddressID == NULL) { 128 JNU_ReleaseStringPlatformChars(env, host, hostname); 129 return NULL; 130 } 131 } 132 /* get the address preference */ 133 preferIPv6Address 134 = (*env)->GetStaticBooleanField(env, ia_class, ia_preferIPv6AddressID); 135 136 /* Try once, with our static buffer. */ 137 memset(&hints, 0, sizeof(hints)); 138 hints.ai_flags = AI_CANONNAME; 139 hints.ai_family = AF_UNSPEC; 140 141 error = (*getaddrinfo_ptr)(hostname, NULL, &hints, &res); 142 143 if (error) { 144 /* report error */ 145 JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException", 146 (char *)hostname); 147 JNU_ReleaseStringPlatformChars(env, host, hostname); 148 return NULL; 149 } else { 150 int i = 0; 151 int inetCount = 0, inet6Count = 0, inetIndex, inet6Index; 205 memcpy(next, iterator, sizeof(struct addrinfo)); 206 next->ai_next = NULL; 207 if (resNew == NULL) { 208 resNew = next; 209 } else { 210 last->ai_next = next; 211 } 212 last = next; 213 i++; 214 if (iterator->ai_family == AF_INET) { 215 inetCount ++; 216 } else if (iterator->ai_family == AF_INET6) { 217 inet6Count ++; 218 } 219 } 220 iterator = iterator->ai_next; 221 } 222 retLen = i; 223 iterator = resNew; 224 i = 0; 225 ret = (*env)->NewObjectArray(env, retLen, ni_iacls, NULL); 226 227 if (IS_NULL(ret)) { 228 /* we may have memory to free at the end of this */ 229 goto cleanupAndReturn; 230 } 231 232 if (preferIPv6Address) { 233 inetIndex = inet6Count; 234 inet6Index = 0; 235 } else { 236 inetIndex = 0; 237 inet6Index = inetCount; 238 } 239 240 while (iterator != NULL) { 241 if (iterator->ai_family == AF_INET) { 242 jobject iaObj = (*env)->NewObject(env, ni_ia4cls, ni_ia4ctrID); 243 if (IS_NULL(iaObj)) { 244 ret = NULL; 245 goto cleanupAndReturn; 246 } 247 (*env)->SetIntField(env, iaObj, ni_iaaddressID, 248 ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr)); 249 (*env)->SetObjectField(env, iaObj, ni_iahostID, host); 250 (*env)->SetObjectArrayElement(env, ret, inetIndex, iaObj); 251 inetIndex ++; 252 } else if (iterator->ai_family == AF_INET6) { 253 jint scope = 0; 254 jbyteArray ipaddress; 255 jobject iaObj = (*env)->NewObject(env, ni_ia6cls, ni_ia6ctrID); 256 if (IS_NULL(iaObj)) { 257 ret = NULL; 258 goto cleanupAndReturn; 259 } 260 ipaddress = (*env)->NewByteArray(env, 16); 261 if (IS_NULL(ipaddress)) { 262 ret = NULL; 263 goto cleanupAndReturn; 264 } 265 (*env)->SetByteArrayRegion(env, ipaddress, 0, 16, 266 (jbyte *)&(((struct sockaddr_in6*)iterator->ai_addr)->sin6_addr)); 267 scope = ((struct sockaddr_in6*)iterator->ai_addr)->sin6_scope_id; 268 if (scope != 0) { /* zero is default value, no need to set */ 269 (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope); 270 (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE); 271 } 272 (*env)->SetObjectField(env, iaObj, ni_ia6ipaddressID, ipaddress); 273 (*env)->SetObjectField(env, iaObj, ni_iahostID, host); 274 (*env)->SetObjectArrayElement(env, ret, inet6Index, iaObj); 275 inet6Index ++; 276 } 277 iterator = iterator->ai_next; 278 } 279 } 280 } 281 282 cleanupAndReturn: 283 { 284 struct addrinfo *iterator, *tmp; 285 iterator = resNew; 286 while (iterator != NULL) { 287 tmp = iterator; 288 iterator = iterator->ai_next; 289 free(tmp); 290 } 291 JNU_ReleaseStringPlatformChars(env, host, hostname); 292 } 293 | 55 56 /* 57 * Inet6AddressImpl 58 */ 59 60 /* 61 * Class: java_net_Inet6AddressImpl 62 * Method: getLocalHostName 63 * Signature: ()Ljava/lang/String; 64 */ 65 JNIEXPORT jstring JNICALL 66 Java_java_net_Inet6AddressImpl_getLocalHostName (JNIEnv *env, jobject this) { 67 char hostname [256]; 68 69 if (gethostname (hostname, sizeof (hostname)) == -1) { 70 strcpy (hostname, "localhost"); 71 } 72 return JNU_NewStringPlatform (env, hostname); 73 } 74 75 76 JNIEXPORT jobjectArray JNICALL 77 Java_java_net_Inet6AddressImpl_lookupAllHostAddr(JNIEnv *env, jobject this, 78 jstring host) { 79 const char *hostname; 80 jobjectArray ret = 0; 81 int retLen = 0; 82 jboolean preferIPv6Address; 83 84 int error=0; 85 struct addrinfo hints, *res, *resNew = NULL; 86 87 init(env); 88 89 if (IS_NULL(host)) { 90 JNU_ThrowNullPointerException(env, "host is null"); 91 return 0; 92 } 93 hostname = JNU_GetStringPlatformChars(env, host, JNI_FALSE); 94 CHECK_NULL_RETURN(hostname, NULL); 95 96 if (NET_addrtransAvailable()) { 97 /* get the address preference */ 98 preferIPv6Address 99 = (*env)->GetStaticBooleanField(env, ia_class, ia_preferIPv6AddressID); 100 101 /* Try once, with our static buffer. */ 102 memset(&hints, 0, sizeof(hints)); 103 hints.ai_flags = AI_CANONNAME; 104 hints.ai_family = AF_UNSPEC; 105 106 error = (*getaddrinfo_ptr)(hostname, NULL, &hints, &res); 107 108 if (error) { 109 /* report error */ 110 JNU_ThrowByName(env, JNU_JAVANETPKG "UnknownHostException", 111 (char *)hostname); 112 JNU_ReleaseStringPlatformChars(env, host, hostname); 113 return NULL; 114 } else { 115 int i = 0; 116 int inetCount = 0, inet6Count = 0, inetIndex, inet6Index; 170 memcpy(next, iterator, sizeof(struct addrinfo)); 171 next->ai_next = NULL; 172 if (resNew == NULL) { 173 resNew = next; 174 } else { 175 last->ai_next = next; 176 } 177 last = next; 178 i++; 179 if (iterator->ai_family == AF_INET) { 180 inetCount ++; 181 } else if (iterator->ai_family == AF_INET6) { 182 inet6Count ++; 183 } 184 } 185 iterator = iterator->ai_next; 186 } 187 retLen = i; 188 iterator = resNew; 189 i = 0; 190 ret = (*env)->NewObjectArray(env, retLen, ia_class, NULL); 191 192 if (IS_NULL(ret)) { 193 /* we may have memory to free at the end of this */ 194 goto cleanupAndReturn; 195 } 196 197 if (preferIPv6Address) { 198 inetIndex = inet6Count; 199 inet6Index = 0; 200 } else { 201 inetIndex = 0; 202 inet6Index = inetCount; 203 } 204 205 while (iterator != NULL) { 206 if (iterator->ai_family == AF_INET) { 207 jobject iaObj = (*env)->NewObject(env, ia4_class, ia4_ctrID); 208 if (IS_NULL(iaObj)) { 209 ret = NULL; 210 goto cleanupAndReturn; 211 } 212 (*env)->SetIntField(env, iaObj, ia_addressID, 213 ntohl(((struct sockaddr_in*)iterator->ai_addr)->sin_addr.s_addr)); 214 (*env)->SetObjectField(env, iaObj, ia_hostNameID, host); 215 (*env)->SetObjectArrayElement(env, ret, inetIndex, iaObj); 216 inetIndex ++; 217 } else if (iterator->ai_family == AF_INET6) { 218 jint scope = 0; 219 jbyteArray ipaddress; 220 jobject iaObj = (*env)->NewObject(env, ia6_class, ia6_ctrID); 221 if (IS_NULL(iaObj)) { 222 ret = NULL; 223 goto cleanupAndReturn; 224 } 225 ipaddress = (*env)->NewByteArray(env, 16); 226 if (IS_NULL(ipaddress)) { 227 ret = NULL; 228 goto cleanupAndReturn; 229 } 230 (*env)->SetByteArrayRegion(env, ipaddress, 0, 16, 231 (jbyte *)&(((struct sockaddr_in6*)iterator->ai_addr)->sin6_addr)); 232 scope = ((struct sockaddr_in6*)iterator->ai_addr)->sin6_scope_id; 233 if (scope != 0) { /* zero is default value, no need to set */ 234 (*env)->SetIntField(env, iaObj, ia6_scopeidID, scope); 235 (*env)->SetBooleanField(env, iaObj, ia6_scopeidsetID, JNI_TRUE); 236 } 237 (*env)->SetObjectField(env, iaObj, ia6_ipaddressID, ipaddress); 238 (*env)->SetObjectField(env, iaObj, ia_hostNameID, host); 239 (*env)->SetObjectArrayElement(env, ret, inet6Index, iaObj); 240 inet6Index ++; 241 } 242 iterator = iterator->ai_next; 243 } 244 } 245 } 246 247 cleanupAndReturn: 248 { 249 struct addrinfo *iterator, *tmp; 250 iterator = resNew; 251 while (iterator != NULL) { 252 tmp = iterator; 253 iterator = iterator->ai_next; 254 free(tmp); 255 } 256 JNU_ReleaseStringPlatformChars(env, host, hostname); 257 } 258 |