/*
** Caramel - Core Java Toolbox
** Copyright (c) 2001, 2002, 2003 by Gerald Bauer
**
** This program is free software.
**
** You may redistribute it and/or modify it under the terms of the GNU
** General Public License as published by the Free Software Foundation.
** Version 2 of the license should be included with this distribution in
** the file LICENSE, as well as License.html. If the license is not
** included with this distribution, you may find a copy at the FSF web
** site at 'www.gnu.org' or 'www.fsf.org', or you may write to the
** Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139 USA.
**
** THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND,
** NOT EVEN THE IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR
** OF THIS SOFTWARE, ASSUMES _NO_ RESPONSIBILITY FOR ANY
** CONSEQUENCE RESULTING FROM THE USE, MODIFICATION, OR
** REDISTRIBUTION OF THIS SOFTWARE.
**
*/

package caramel.util;

import java.net.*;
import houston.*;

public class NetUtils
{
   /**
    *  cache local host name
    */
   private static String _localHostName = null;

   public static char getIpClass( InetAddress ip )
   {
      // source published in O'Reilly Java Network Programming
      //   p178

      byte address[] = ip.getAddress();
      if( address.length != 4 )
         throw new IllegalArgumentException( "address has more than 4 bytes; possibly IPv6 address" );

      int firstByte = address[0];
      if( ( firstByte & 0x80 ) == 0 )
         return 'A';
      else if( ( firstByte & 0xC0 ) == 0x80 )
         return 'B';
      else if( ( firstByte & 0xE0 ) == 0xC0 )
         return 'C';
      else if( ( firstByte & 0xF0 ) == 0xE0 )
         return 'D';
      else if( ( firstByte & 0xF8 ) == 0xF0 )
         return 'E';
      else
         return 'F';
   }

   public static String getLocalHostName()
   {
      if( _localHostName == null )
      {
         try
         {
            _localHostName = InetAddress.getLocalHost().getHostName();
         }
         catch( UnknownHostException e )
         {
            Status.error( "*** failed to get local host name: " + e.toString() );
            // use loopback host address if all else fails
            _localHostName = "127.0.0.1";
         }
      }

      return _localHostName;
   }

   public static boolean isHostName( String host )
   {
      // check if hostName is really a host name and not an host address
      //  that is, 127.0.0.1, for example

      char s[] = host.toCharArray();
      // if we see a character that is neither a digit nor a period
      //  then host is probably a host name

      for( int i = 0; i < s.length; i++ )
      {
         if( !Character.isDigit( s[i] ) && s[i] != '.' )
            return true;
      }
      return false;
   }

   public static boolean isLoopbackIp( InetAddress ip )
   {
      byte address[] = ip.getAddress();

      if( address[0] == 127
             && address[1] == 0
             && address[2] == 0
             && address[3] == 1 )
         return true;

      return false;
   }

   public static boolean isPrivateIp( InetAddress ip )
   {
      // private network space ip ranges defined by RFC 1918
      //
      //  10.0.0.0 through 10.255.255.255 (class A)
      //  172.16.0.0 through 172.31.255.255 (class B)
      //  192.168.0.0 through 192.168.255.255 (class C)

      byte address[] = ip.getAddress();

      // note: a byte is signed!
      // byte values from 128 to 255 are negative numbers!
      //  to make it easier convert it to an unsigned byte
      int firstQuad = address[0] < 0 ? address[0] + 256 : address[0];
      int secondQuad = address[1] < 0 ? address[1] + 256 : address[1];
      int thirdQuad = address[2] < 0 ? address[2] + 256 : address[2];
      int fourthQuad = address[3] < 0 ? address[3] + 256 : address[3];

      // check 10.0.0.0 through 10.255.255.255 (class A)
      if( firstQuad == 10 )
         return true;

      //  check 172.16.0.0 through 172.31.255.255 (class B)
      if( firstQuad == 172 )
      {
         if( secondQuad >= 16 && secondQuad <= 31 )
            return true;
      }

      //  192.168.0.0 through 192.168.255.255 (class C)
      if( firstQuad == 192 && secondQuad == 168 )
         return true;

      return false;
   }

}