/* 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 */
