mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			
		
			
				
	
	
		
			398 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			398 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C
		
	
	
	
/* VMInetAddress.c - Native methods for InetAddress class
 | 
						|
   Copyright (C) 1998, 2002, 2005, 2006  Free Software Foundation, Inc.
 | 
						|
 | 
						|
This file is part of GNU Classpath.
 | 
						|
 | 
						|
GNU Classpath is free software; you can redistribute it and/or modify
 | 
						|
it under the terms of the GNU General Public License as published by
 | 
						|
the Free Software Foundation; either version 2, or (at your option)
 | 
						|
any later version.
 | 
						|
 
 | 
						|
GNU Classpath is distributed in the hope that it will be useful, but
 | 
						|
WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | 
						|
General Public License for more details.
 | 
						|
 | 
						|
You should have received a copy of the GNU General Public License
 | 
						|
along with GNU Classpath; see the file COPYING.  If not, write to the
 | 
						|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 | 
						|
02110-1301 USA.
 | 
						|
 | 
						|
Linking this library statically or dynamically with other modules is
 | 
						|
making a combined work based on this library.  Thus, the terms and
 | 
						|
conditions of the GNU General Public License cover the whole
 | 
						|
combination.
 | 
						|
 | 
						|
As a special exception, the copyright holders of this library give you
 | 
						|
permission to link this library with independent modules to produce an
 | 
						|
executable, regardless of the license terms of these independent
 | 
						|
modules, and to copy and distribute the resulting executable under
 | 
						|
terms of your choice, provided that you also meet, for each linked
 | 
						|
independent module, the terms and conditions of the license of that
 | 
						|
module.  An independent module is a module which is not derived from
 | 
						|
or based on this library.  If you modify this library, you may extend
 | 
						|
this exception to your version of the library, but you are not
 | 
						|
obligated to do so.  If you do not wish to do so, delete this
 | 
						|
exception statement from your version. */
 | 
						|
 | 
						|
/* do not move; needed here because of some macro definitions */
 | 
						|
#include <config.h>
 | 
						|
 | 
						|
#include <stdlib.h>
 | 
						|
#include <stdio.h>
 | 
						|
#include <string.h>
 | 
						|
 | 
						|
#include <jni.h>
 | 
						|
#include <jcl.h>
 | 
						|
 | 
						|
#include "cpnative.h"
 | 
						|
#include "cpnet.h"
 | 
						|
#include "javanet.h"
 | 
						|
 | 
						|
#include "java_net_VMInetAddress.h"
 | 
						|
 | 
						|
/*************************************************************************/
 | 
						|
 | 
						|
/*
 | 
						|
 * Function to return the local hostname
 | 
						|
 */
 | 
						|
JNIEXPORT jstring JNICALL
 | 
						|
Java_java_net_VMInetAddress_getLocalHostname (JNIEnv * env,
 | 
						|
					      jclass class
 | 
						|
					      __attribute__ ((__unused__)))
 | 
						|
{
 | 
						|
  char hostname[256];
 | 
						|
  int result;
 | 
						|
  jstring retval;
 | 
						|
 | 
						|
#ifndef WITHOUT_NETWORK
 | 
						|
  result = cpnet_getHostname (env, hostname, sizeof (hostname));
 | 
						|
  if (result != CPNATIVE_OK)
 | 
						|
    {
 | 
						|
      strcpy (hostname, "localhost");
 | 
						|
    }
 | 
						|
#else /* not WITHOUT_NETWORK */
 | 
						|
  strcpy (hostname, "localhost");
 | 
						|
#endif /* not WITHOUT_NETWORK */
 | 
						|
 | 
						|
  retval = (*env)->NewStringUTF (env, hostname);
 | 
						|
 | 
						|
  return (retval);
 | 
						|
}
 | 
						|
 | 
						|
/*************************************************************************/
 | 
						|
 | 
						|
/*
 | 
						|
 * Returns the value of the special IP address INADDR_ANY 
 | 
						|
 */
 | 
						|
JNIEXPORT jarray JNICALL
 | 
						|
Java_java_net_VMInetAddress_lookupInaddrAny (JNIEnv * env,
 | 
						|
					     jclass class
 | 
						|
					     __attribute__ ((__unused__)))
 | 
						|
{
 | 
						|
  jarray IParray;
 | 
						|
  cpnet_address *addr;
 | 
						|
  jbyte *octets;
 | 
						|
 | 
						|
  /* Allocate an array for the IP address */
 | 
						|
  IParray = (*env)->NewByteArray (env, 4);
 | 
						|
  if (IParray == NULL)
 | 
						|
    {
 | 
						|
      JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
 | 
						|
      return (jarray) NULL;
 | 
						|
    }
 | 
						|
 | 
						|
  /* Copy in the values */
 | 
						|
  octets = (*env)->GetByteArrayElements (env, IParray, 0);
 | 
						|
 | 
						|
#ifndef WITHOUT_NETWORK
 | 
						|
  addr = cpnet_newIPV4Address (env);
 | 
						|
  cpnet_setIPV4Any (addr);
 | 
						|
  cpnet_IPV4AddressToBytes (addr, octets);
 | 
						|
  cpnet_freeAddress (env, addr);
 | 
						|
#else /* not WITHOUT_NETWORK */
 | 
						|
  octets[0] = 0;
 | 
						|
  octets[1] = 0;
 | 
						|
  octets[2] = 0;
 | 
						|
  octets[3] = 0;
 | 
						|
#endif /* not WITHOUT_NETWORK */
 | 
						|
 | 
						|
  (*env)->ReleaseByteArrayElements (env, IParray, octets, 0);
 | 
						|
 | 
						|
  return (IParray);
 | 
						|
}
 | 
						|
 | 
						|
/*************************************************************************/
 | 
						|
 | 
						|
/*
 | 
						|
 * Function to return the canonical hostname for a given IP address passed
 | 
						|
 * in as a byte array
 | 
						|
 */
 | 
						|
JNIEXPORT jstring JNICALL
 | 
						|
Java_java_net_VMInetAddress_getHostByAddr (JNIEnv * env,
 | 
						|
					   jclass class
 | 
						|
					   __attribute__ ((__unused__)),
 | 
						|
					   jarray arr)
 | 
						|
{
 | 
						|
#ifndef WITHOUT_NETWORK
 | 
						|
  jbyte *octets;
 | 
						|
  jsize len;
 | 
						|
  cpnet_address *addr;
 | 
						|
  char hostname[255];
 | 
						|
  int result;
 | 
						|
  jstring retval;
 | 
						|
 | 
						|
  /* Grab the byte[] array with the IP out of the input data */
 | 
						|
  len = (*env)->GetArrayLength (env, arr);
 | 
						|
  if (len != 4 && len != 16)
 | 
						|
    {
 | 
						|
      JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address");
 | 
						|
      return (jstring) NULL;
 | 
						|
    }
 | 
						|
 | 
						|
  octets = (*env)->GetByteArrayElements (env, arr, 0);
 | 
						|
  if (!octets)
 | 
						|
    {
 | 
						|
      JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address");
 | 
						|
      return (jstring) NULL;
 | 
						|
    }
 | 
						|
 | 
						|
  switch (len)
 | 
						|
    {
 | 
						|
    case 4:
 | 
						|
      addr = cpnet_newIPV4Address(env);
 | 
						|
      cpnet_bytesToIPV4Address (addr, octets);      
 | 
						|
      break;
 | 
						|
#ifdef HAVE_INET6
 | 
						|
    case 16:
 | 
						|
      addr = cpnet_newIPV6Address(env);
 | 
						|
      cpnet_bytesToIPV6Address (addr, octets);
 | 
						|
      break;
 | 
						|
#endif
 | 
						|
    default:
 | 
						|
      JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Bad IP Address");
 | 
						|
      return (jstring) NULL;
 | 
						|
 | 
						|
   }
 | 
						|
 | 
						|
  /* Release some memory */
 | 
						|
  (*env)->ReleaseByteArrayElements (env, arr, octets, 0);
 | 
						|
 | 
						|
  /* Resolve the address and return the name */
 | 
						|
  result = cpnet_getHostByAddr (env, addr, hostname, sizeof (hostname));
 | 
						|
  cpnet_freeAddress (env, addr);
 | 
						|
  if (result != CPNATIVE_OK)
 | 
						|
    {
 | 
						|
      JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION,
 | 
						|
			  cpnative_getErrorString (result));
 | 
						|
      return (jstring) NULL;
 | 
						|
    }
 | 
						|
 | 
						|
  retval = (*env)->NewStringUTF (env, hostname);
 | 
						|
 | 
						|
  return (retval);
 | 
						|
#else /* not WITHOUT_NETWORK */
 | 
						|
  return (jstring) NULL;
 | 
						|
#endif /* not WITHOUT_NETWORK */
 | 
						|
}
 | 
						|
 | 
						|
/*************************************************************************/
 | 
						|
 | 
						|
JNIEXPORT jobjectArray JNICALL
 | 
						|
Java_java_net_VMInetAddress_getHostByName (JNIEnv * env,
 | 
						|
					   jclass class
 | 
						|
					   __attribute__ ((__unused__)),
 | 
						|
					   jstring host)
 | 
						|
{
 | 
						|
#ifndef WITHOUT_NETWORK
 | 
						|
  const char *hostname;
 | 
						|
  cpnet_address **addresses;
 | 
						|
  jsize addresses_count;
 | 
						|
  int result;
 | 
						|
  jclass arr_class;
 | 
						|
  jobjectArray addrs;
 | 
						|
  jint i;
 | 
						|
  jbyte *octets;
 | 
						|
  jarray ret_octets;
 | 
						|
 | 
						|
  /* Grab the hostname string */
 | 
						|
  hostname = (*env)->GetStringUTFChars (env, host, 0);
 | 
						|
  if (!hostname)
 | 
						|
    {
 | 
						|
      JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Null hostname");
 | 
						|
      return (jobjectArray) NULL;
 | 
						|
    }
 | 
						|
 | 
						|
  result = cpnet_getHostByName (env, hostname, &addresses, &addresses_count);
 | 
						|
  if (result != CPNATIVE_OK || addresses_count == 0)
 | 
						|
    {
 | 
						|
      JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, hostname);
 | 
						|
      return (jobjectArray) NULL;
 | 
						|
    }
 | 
						|
  (*env)->ReleaseStringUTFChars (env, host, hostname);
 | 
						|
 | 
						|
  arr_class = (*env)->FindClass (env, "[B");
 | 
						|
  if (!arr_class)
 | 
						|
    {
 | 
						|
      JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
 | 
						|
      return (jobjectArray) NULL;
 | 
						|
    }
 | 
						|
 | 
						|
  addrs = (*env)->NewObjectArray (env, addresses_count, arr_class, 0);
 | 
						|
  if (!addrs)
 | 
						|
    {
 | 
						|
      JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
 | 
						|
      return (jobjectArray) NULL;
 | 
						|
    }
 | 
						|
 | 
						|
  /* Now loop and copy in each address */
 | 
						|
  for (i = 0; i < addresses_count; i++)
 | 
						|
    {
 | 
						|
      if (cpnet_isIPV4Address (addresses[i]))
 | 
						|
	{
 | 
						|
	  ret_octets = (*env)->NewByteArray (env, 4);
 | 
						|
 | 
						|
	  if (!ret_octets)
 | 
						|
	    {
 | 
						|
	      JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
 | 
						|
	      cpnet_freeAddresses (env, addresses, addresses_count);
 | 
						|
	      return (jobjectArray) NULL;
 | 
						|
	    }
 | 
						|
	  
 | 
						|
	  octets = (*env)->GetByteArrayElements (env, ret_octets, 0);
 | 
						|
 | 
						|
	  cpnet_IPV4AddressToBytes (addresses[i], octets);
 | 
						|
 | 
						|
	  (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0);
 | 
						|
 | 
						|
	  (*env)->SetObjectArrayElement (env, addrs, i, ret_octets);
 | 
						|
	}
 | 
						|
#ifdef HAVE_INET6
 | 
						|
      else if (cpnet_isIPV6Address (addresses[i]))
 | 
						|
	{
 | 
						|
	  ret_octets = (*env)->NewByteArray (env, 16);
 | 
						|
 | 
						|
	  if (!ret_octets)
 | 
						|
	    {
 | 
						|
	      JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
 | 
						|
	      cpnet_freeAddresses (env, addresses, addresses_count);
 | 
						|
	      return (jobjectArray) NULL;
 | 
						|
	    }
 | 
						|
	  
 | 
						|
	  octets = (*env)->GetByteArrayElements (env, ret_octets, 0);
 | 
						|
 | 
						|
	  cpnet_IPV6AddressToBytes (addresses[i], octets);
 | 
						|
 | 
						|
	  (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0);
 | 
						|
 | 
						|
	  (*env)->SetObjectArrayElement (env, addrs, i, ret_octets);
 | 
						|
	}
 | 
						|
#endif
 | 
						|
      else
 | 
						|
	{
 | 
						|
	  JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
 | 
						|
	  cpnet_freeAddresses (env, addresses, addresses_count);
 | 
						|
	  return (jobjectArray) NULL;
 | 
						|
	}
 | 
						|
    }
 | 
						|
 | 
						|
  cpnet_freeAddresses (env, addresses, addresses_count);
 | 
						|
 | 
						|
  return (addrs);
 | 
						|
#else /* not WITHOUT_NETWORK */
 | 
						|
  return (jobjectArray) NULL;
 | 
						|
#endif /* not WITHOUT_NETWORK */
 | 
						|
}
 | 
						|
 | 
						|
/*************************************************************************/
 | 
						|
 | 
						|
/*
 | 
						|
 * Return the IP address represented by a literal address.
 | 
						|
 * Will return null if the literal address is not valid.
 | 
						|
 */
 | 
						|
JNIEXPORT jbyteArray JNICALL
 | 
						|
Java_java_net_VMInetAddress_aton (JNIEnv *env,
 | 
						|
				  jclass class
 | 
						|
				  __attribute__ ((__unused__)),
 | 
						|
				  jstring host)
 | 
						|
{
 | 
						|
#ifndef WITHOUT_NETWORK
 | 
						|
  const char *hostname;
 | 
						|
  cpnet_address *address;
 | 
						|
  int result;
 | 
						|
  jbyte *octets;
 | 
						|
  jbyteArray ret_octets;
 | 
						|
 | 
						|
  hostname = (*env)->GetStringUTFChars (env, host, 0);
 | 
						|
  if (!hostname)
 | 
						|
    {
 | 
						|
      JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Null hostname");
 | 
						|
      return (jbyteArray) NULL;
 | 
						|
    }
 | 
						|
 | 
						|
  result = cpnet_aton (env, hostname, &address);
 | 
						|
  (*env)->ReleaseStringUTFChars (env, host, hostname);
 | 
						|
  if (result != CPNATIVE_OK)
 | 
						|
    {
 | 
						|
      JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
 | 
						|
      if (address)
 | 
						|
	cpnet_freeAddress (env, address);
 | 
						|
      return (jbyteArray) NULL;
 | 
						|
    }
 | 
						|
  if (!address)
 | 
						|
    return (jbyteArray) NULL;
 | 
						|
 | 
						|
  if (cpnet_isIPV4Address (address))
 | 
						|
    {
 | 
						|
      ret_octets = (jbyteArray) (*env)->NewByteArray (env, 4);
 | 
						|
 | 
						|
      if (!ret_octets)
 | 
						|
	{
 | 
						|
	  JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
 | 
						|
	  cpnet_freeAddress (env, address);
 | 
						|
	  return (jbyteArray) NULL;
 | 
						|
	}
 | 
						|
	  
 | 
						|
      octets = (*env)->GetByteArrayElements (env, ret_octets, 0);
 | 
						|
 | 
						|
      cpnet_IPV4AddressToBytes (address, octets);
 | 
						|
 | 
						|
      (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0);
 | 
						|
    }
 | 
						|
#ifdef HAVE_INET6
 | 
						|
  else if (cpnet_isIPV6Address (address))
 | 
						|
    {
 | 
						|
      ret_octets = (jbyteArray) (*env)->NewByteArray (env, 16);
 | 
						|
 | 
						|
      if (!ret_octets)
 | 
						|
	{
 | 
						|
	  JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
 | 
						|
	  cpnet_freeAddress (env, address);
 | 
						|
	  return (jbyteArray) NULL;
 | 
						|
	}
 | 
						|
	  
 | 
						|
      octets = (*env)->GetByteArrayElements (env, ret_octets, 0);
 | 
						|
 | 
						|
      cpnet_IPV6AddressToBytes (address, octets);
 | 
						|
 | 
						|
      (*env)->ReleaseByteArrayElements (env, ret_octets, octets, 0);
 | 
						|
    }
 | 
						|
#endif
 | 
						|
  else
 | 
						|
    {
 | 
						|
      JCL_ThrowException (env, UNKNOWN_HOST_EXCEPTION, "Internal Error");
 | 
						|
      cpnet_freeAddress (env, address);
 | 
						|
      return (jbyteArray) NULL;
 | 
						|
    }
 | 
						|
 | 
						|
  cpnet_freeAddress (env, address);
 | 
						|
 | 
						|
  return (ret_octets);
 | 
						|
  
 | 
						|
#else /* not WITHOUT_NETWORK */
 | 
						|
  return (jbyteArray) NULL;
 | 
						|
#endif /* not WITHOUT_NETWORK */
 | 
						|
}
 | 
						|
 | 
						|
/* end of file */
 |