harmony-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ghar...@apache.org
Subject svn commit: r406644 - in /incubator/harmony/enhanced/classlib/trunk: modules/luni/src/main/java/java/net/ modules/luni/src/main/java/org/apache/harmony/luni/platform/ modules/luni/src/test/java/tests/api/java/net/ native-src/linux.IA32/luni/ native-src...
Date Mon, 15 May 2006 14:50:33 GMT
Author: gharley
Date: Mon May 15 07:50:31 2006
New Revision: 406644

URL: http://svn.apache.org/viewcvs?rev=406644&view=rev
Log:
HARMONY 327 : Java 5 Enhancement: 2 new methods in java.net.java.net.InetAddress

Modified:
    incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/InetAddress.java
    incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/NetworkInterface.java
    incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java
    incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
    incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/net/InetAddressTest.java
    incubator/harmony/enhanced/classlib/trunk/native-src/linux.IA32/luni/OSNetworkSystemLinux.c
    incubator/harmony/enhanced/classlib/trunk/native-src/linux.IA32/luni/libhyluni.exp
    incubator/harmony/enhanced/classlib/trunk/native-src/shared/luni/OSNetworkSystem.h
    incubator/harmony/enhanced/classlib/trunk/native-src/win.IA32/luni/OSNetworkSystemWin32.c
    incubator/harmony/enhanced/classlib/trunk/native-src/win.IA32/luni/hyluni.def

Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/InetAddress.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/InetAddress.java?rev=406644&r1=406643&r2=406644&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/InetAddress.java
(original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/InetAddress.java
Mon May 15 07:50:31 2006
@@ -16,6 +16,7 @@
 package java.net;
 
 
+import java.io.FileDescriptor;
 import java.io.IOException;
 import java.io.ObjectInputStream;
 import java.io.ObjectOutputStream;
@@ -24,8 +25,12 @@
 import java.io.Serializable;
 import java.security.AccessController;
 import java.util.ArrayList;
+import java.util.Enumeration;
 import java.util.StringTokenizer;
 
+import org.apache.harmony.luni.net.NetUtil;
+import org.apache.harmony.luni.platform.INetworkSystem;
+import org.apache.harmony.luni.platform.Platform;
 import org.apache.harmony.luni.util.Inet6Util;
 import org.apache.harmony.luni.util.Msg;
 import org.apache.harmony.luni.util.PriviAction;
@@ -42,13 +47,23 @@
 	final static byte[] localhost_bytes = { 127, 0, 0, 1 };
 
 	static InetAddress ANY = new Inet4Address(any_bytes);
+    
+    private final static INetworkSystem NETIMPL = Platform.getNetworkSystem(); 
 
 	final static InetAddress LOOPBACK = new Inet4Address(localhost_bytes,
 			"localhost");
+    
+    private static final String ERRMSG_CONNECTION_REFUSED = "Connection refused"; //$NON-NLS-1$
 
 	private static final long serialVersionUID = 3286316764910316507L;
 
 	String hostName;
+	
+    private Object waitReachable = new Object();
+    
+    private boolean reached = false;
+    
+    private int addrCount;
 
 	int family = 2;
 
@@ -705,6 +720,152 @@
 	public boolean isAnyLocalAddress() {
 		return false;
 	}
+	
+	   
+    /**
+     * Tries to see if the InetAddress is reachable. This method first tries to
+     * use ICMP(ICMP ECHO REQUEST). When first step fails, the TCP connection on
+     * port 7 (Echo) shall be lauched.
+     * 
+     * @param timeout
+     *            timeout in milliseconds
+     * @return true if address is reachable
+     * @throws IOException
+     *             if I/O operation meets error
+     * @throws IllegalArgumentException
+     *             if timeout is less than zero
+     */
+    public boolean isReachable(int timeout) throws IOException {
+        return isReachable(null, 0, timeout);
+    }
+
+    /**
+     * Tries to see if the InetAddress is reachable. This method first tries to
+     * use ICMP(ICMP ECHO REQUEST). When first step fails, the TCP connection on
+     * port 7 (Echo) shall be lauched.
+     * 
+     * @param netif
+     *            the network interface through which to connect
+     * @param ttl
+     *            max hops to live
+     * @param timeout
+     *            timeout in milliseconds
+     * @return true if address is reachable
+     * @throws IOException
+     *             if I/O operation meets error
+     * @throws IllegalArgumentException
+     *             if ttl or timeout is less than zero
+     */
+    public boolean isReachable(NetworkInterface netif, final int ttl,
+            final int timeout) throws IOException {
+        if (0 > ttl || 0 > timeout) {
+            throw new IllegalArgumentException(Msg.getString("K0051"));
+        }
+        boolean reachable = false;
+        if (null == netif) {
+            // network interface is null, binds to no address
+            reachable = NETIMPL.isReachableByICMP(this, null, ttl, timeout);
+            if (!reachable) {
+                reachable = isReachableByTCP(this, null, timeout);
+            }
+        } else {
+            // binds to all address on this NetworkInterface, tries ICMP ping
+            // first
+            reachable = isReachableByICMPUseMultiThread(netif, ttl, timeout);
+            if (!reachable) {
+                // tries TCP echo if ICMP ping fails
+                reachable = isReachableByTCPUseMultiThread(netif, ttl, timeout);
+            }
+        }
+        return reachable;
+    }
+
+    /*
+     * uses multi-Thread to try if isReachable, returns true if any of threads
+     * returns in time
+     */
+    private boolean isReachableByMultiThread(NetworkInterface netif,
+            final int ttl, final int timeout, final boolean isICMP)
+            throws IOException {
+        Enumeration addresses = netif.getInetAddresses();
+        reached = false;
+        addrCount = netif.addresses.length;
+        while (addresses.hasMoreElements()) {
+            final InetAddress addr = (InetAddress) addresses.nextElement();
+            new Thread() {
+                public void run() {
+                    boolean threadReached = false;
+                    // if isICMP, tries ICMP ping, else TCP echo
+                    if (isICMP) {
+                        threadReached = NETIMPL.isReachableByICMP(addr,
+                                InetAddress.this, ttl, timeout);
+                    } else {
+                        try {
+                            threadReached = isReachableByTCP(addr,
+                                    InetAddress.this, timeout);
+                        } catch (IOException e) {
+                            // do nothing
+                        }
+                    }
+
+                    synchronized (waitReachable) {
+                        if (threadReached) {
+                            // if thread reached this address, sets reached to
+                            // true and notifies main thread
+                            reached = true;
+                            waitReachable.notifyAll();
+                        } else {
+                            addrCount--;
+                            if (0 == addrCount) {
+                                // if count equals zero, all thread
+                                // expired,notifies main thread
+                                waitReachable.notifyAll();
+                            }
+                        }
+                    }
+                }
+            }.start();
+        }
+        synchronized (waitReachable) {
+            try {
+                // wait for notification
+                waitReachable.wait();
+            } catch (InterruptedException e) {
+                // do nothing
+            }
+            return reached;
+        }
+    }    
+
+    private boolean isReachableByICMPUseMultiThread(NetworkInterface netif, int ttl, int
timeout) throws IOException{
+        return isReachableByMultiThread(netif, ttl, timeout, true);
+    }
+    
+    private boolean isReachableByTCPUseMultiThread(NetworkInterface netif, int ttl, int timeout)
throws IOException{
+        return isReachableByMultiThread(netif, ttl, timeout, false);
+    }    
+    
+    private boolean isReachableByTCP(InetAddress dest, InetAddress source,
+            int timeout) throws IOException {
+        FileDescriptor fd = new FileDescriptor();
+        // define traffic only for parameter
+        int traffic = 0;
+        boolean reached = false;
+        NETIMPL.createSocket(fd, NetUtil.preferIPv4Stack());
+        try {
+            if (null != source) {
+                NETIMPL.bind(fd, 0, source);
+            }
+            NETIMPL.connectStreamWithTimeoutSocket(fd, 7, timeout, traffic, dest);
+            reached = true;
+        } catch (IOException e) {
+            if (ERRMSG_CONNECTION_REFUSED.equals(e.getMessage())) {
+                // Connection refused means the IP is reachable
+                reached = true;
+            }
+        }
+        return reached;
+    }
 
 	/**
 	 * Answers the InetAddress corresponding to the array of bytes. In the case

Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/NetworkInterface.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/NetworkInterface.java?rev=406644&r1=406643&r2=406644&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/NetworkInterface.java
(original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/java/net/NetworkInterface.java
Mon May 15 07:50:31 2006
@@ -1,4 +1,4 @@
-/* Copyright 2005, 2005 The Apache Software Foundation or its licensors, as applicable
+/* Copyright 2005, 2006 The Apache Software Foundation or its licensors, as applicable
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -38,7 +38,7 @@
 
 	private String displayName = null;
 
-	private InetAddress addresses[] = null;
+	InetAddress addresses[] = null;
 
 	// The interface index is a positive integer which is non-negative. Where
 	// value is zero then we do not have an index for the interface (which

Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java?rev=406644&r1=406643&r2=406644&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java
(original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/INetworkSystem.java
Mon May 15 07:50:31 2006
@@ -197,5 +197,6 @@
 			throws UnknownHostException;
 
 	public void setInetAddress(InetAddress sender, byte[] address);
-
+	
+	public boolean isReachableByICMP(InetAddress dest,InetAddress source,int ttl,int timeout);
   
 }

Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java?rev=406644&r1=406643&r2=406644&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
(original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/main/java/org/apache/harmony/luni/platform/OSNetworkSystem.java
Mon May 15 07:50:31 2006
@@ -39,6 +39,8 @@
 	private static final int ERRORCODE_SOCKET_TIMEOUT = -209;
 
 	private static OSNetworkSystem ref = new OSNetworkSystem();
+    
+    private static final int INETADDR_REACHABLE = 0;
 
 	// ----------------------------------------------------
 	// Class Constructor
@@ -226,6 +228,12 @@
 			throws SocketException {
 		listenStreamSocketImpl(aFD, backlog);
 	}
+    
+    public boolean isReachableByICMP(final InetAddress dest,
+            InetAddress source, final int ttl, final int timeout) {
+        return INETADDR_REACHABLE == isReachableByICMPImpl(dest, source, ttl,
+                timeout);
+    }
 
 	/*
 	 * 
@@ -659,5 +667,8 @@
 			boolean preferIPv6Addresses) throws UnknownHostException;
 
 	native void setInetAddressImpl(InetAddress sender, byte[] address);
+
+    native int isReachableByICMPImpl(InetAddress addr, InetAddress local,
+            int ttl, int timeout);
 
 }

Modified: incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/net/InetAddressTest.java
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/net/InetAddressTest.java?rev=406644&r1=406643&r2=406644&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/net/InetAddressTest.java
(original)
+++ incubator/harmony/enhanced/classlib/trunk/modules/luni/src/test/java/tests/api/java/net/InetAddressTest.java
Mon May 15 07:50:31 2006
@@ -1,4 +1,4 @@
-/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+/* Copyright 1998, 2006 The Apache Software Foundation or its licensors, as applicable
  * 
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -16,8 +16,13 @@
 package tests.api.java.net;
 
 import java.net.DatagramSocket;
+import java.net.Inet4Address;
 import java.net.InetAddress;
+import java.net.NetworkInterface;
 import java.net.UnknownHostException;
+import java.security.Permission;
+
+import junit.framework.AssertionFailedError;
 
 import tests.support.Support_Configuration;
 
@@ -440,6 +445,63 @@
 		}
 
 	}
+	
+	/**
+     * @tests java.net.InetAddress#isReachableI
+     */
+    public void test_isReachableI() throws Exception {
+        InetAddress ia = Inet4Address.getByName("127.0.0.1");
+        assertTrue(ia.isReachable(10000));
+        ia = Inet4Address.getByName("127.0.0.1");
+        try {
+            ia.isReachable(-1);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // correct
+        }
+    }
+
+    /**
+     * @tests java.net.InetAddress#isReachableLjava_net_NetworkInterfaceII
+     */
+    public void test_isReachableLjava_net_NetworkInterfaceII() throws Exception {
+        // tests local address
+        InetAddress ia = Inet4Address.getByName("127.0.0.1");
+        assertTrue(ia.isReachable(null, 0, 10000));
+        ia = Inet4Address.getByName("127.0.0.1");
+        try {
+            ia.isReachable(null, -1, 10000);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // correct
+        }
+        try {
+            ia.isReachable(null, 0, -1);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // correct
+        }
+        try {
+            ia.isReachable(null, -1, -1);
+            fail("Should throw IllegalArgumentException");
+        } catch (IllegalArgumentException e) {
+            // correct
+        }
+        // tests nowhere
+        ia = Inet4Address.getByName("1.1.1.1");
+        assertFalse(ia.isReachable(1000));
+        assertFalse(ia.isReachable(null, 0, 1000));
+        // tests www.apache.org
+        try {
+            ia = InetAddress.getByName("www.apache.org");//$NON-NLS-1$
+            assertTrue(ia.isReachable(10000));
+            assertTrue(ia.isReachable(NetworkInterface.getByName("eth0"), 0,
+                    10000));
+        } catch (AssertionFailedError e) {
+            System.err
+                    .println("isReachableLjava_net_NetworkInterfaceII test may fail for network
issue, please check.");
+        } 
+    } 
 
 	/**
 	 * Sets up the fixture, for example, open a network connection. This method

Modified: incubator/harmony/enhanced/classlib/trunk/native-src/linux.IA32/luni/OSNetworkSystemLinux.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/native-src/linux.IA32/luni/OSNetworkSystemLinux.c?rev=406644&r1=406643&r2=406644&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/native-src/linux.IA32/luni/OSNetworkSystemLinux.c
(original)
+++ incubator/harmony/enhanced/classlib/trunk/native-src/linux.IA32/luni/OSNetworkSystemLinux.c
Mon May 15 07:50:31 2006
@@ -1,4 +1,4 @@
-/* Copyright 1998, 2005 The Apache Software Foundation or its licensors, as applicable
+/* Copyright 1998, 2006 The Apache Software Foundation or its licensors, as applicable
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -13,11 +13,22 @@
  * limitations under the License.
  */
 
+#include<netinet/ip.h>
+#include<netinet/ip_icmp.h>
+#include<netinet/in_systm.h>
 #include "nethelp.h"
 #include "jclglob.h"
 #include "portsock.h"
 #include "hyport.h"
 #include "OSNetworkSystem.h"
+#define NOPRIVILEGE -1
+#define UNREACHABLE -2
+#define REACHABLE 0
+#define INVALID_SOCKET -1
+#define SOCKET_ERROR -1
+
+unsigned short ip_checksum(unsigned short * buffer, int size);
+void set_icmp_packet(struct icmp * icmp_hdr, int packet_size);
 
 //Alternative Select function
 int
@@ -43,6 +54,124 @@
   return result;
 }
 
+JNIEXPORT jint JNICALL Java_org_apache_harmony_luni_platform_OSNetworkSystem_isReachableByICMPImpl
+  (JNIEnv * env, jobject clz, jobject address, jobject localaddr,  jint ttl, jint timeout){
+  struct sockaddr_in dest,source,local;
+  struct icmp * send_buf = 0;
+  struct ip * recv_buf = 0;
+  int size = sizeof(struct icmp);
+  int result,ret=UNREACHABLE;
+  struct timeval timeP;
+  fd_set * fdset_read;
+  int sockadd_size = sizeof (source);
+  jbyte host[HYSOCK_INADDR6_LEN];
+  U_32 length =  (*env)->GetArrayLength (env,address);
+
+  int sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
+  if (INVALID_SOCKET == sock){
+	return NOPRIVILEGE;
+  }
+  setuid(getuid());
+  if (0 < ttl){
+	  if (0 > setsockopt(sock, IPPROTO_ICMP, IP_TTL, (char*)&ttl,
+	          sizeof(ttl))) {
+	        return NOPRIVILEGE;
+	  }
+  }
+  
+  memset(&dest, 0, sizeof(dest));
+
+  // set address
+  netGetJavaNetInetAddressValue (env, address,(U_8 *)host, &length);
+  memset(&dest, 0, sizeof(dest));	  
+  memcpy (&dest.sin_addr.s_addr,(U_8 *)host, length);
+  dest.sin_family = AF_INET;
+
+  if(NULL != localaddr){
+    memset(&local, 0, sizeof(local));
+    netGetJavaNetInetAddressValue (env, localaddr,(U_8 *)host, &length);
+    memcpy (&local.sin_addr.s_addr,(U_8 *)host, length);
+    bind(sock, (struct sockaddr *)& local, sizeof(local));
+  }
+
+  send_buf = (struct icmp*)malloc(sizeof(char)*ICMP_SIZE);
+  recv_buf = (struct ip*)malloc(sizeof(char)*PACKET_SIZE);
+  if (NULL == send_buf || NULL == recv_buf){
+	  return NOPRIVILEGE;
+  }
+  set_icmp_packet(send_buf, ICMP_SIZE);
+
+  if(SOCKET_ERROR == sendto(sock, (char*)send_buf, ICMP_SIZE, 0,
+            (struct sockaddr*)&dest, sizeof(dest))){
+            goto cleanup;
+  }
+  //set select timeout, change millisecond to usec
+  memset (&timeP, 0, sizeof (struct timeval));    
+  timeP.tv_sec = timeout/1000;
+  timeP.tv_usec = timeout%1000*1000;
+  result = select (sock+1, fdset_read, NULL, NULL,&timeP);
+  fdset_read = (fd_set *)malloc(sizeof (fd_set));
+  FD_ZERO (fdset_read);
+  FD_SET (sock, fdset_read);
+  result = select (sock+1, fdset_read, NULL, NULL,&timeP);
+  if (SOCKET_ERROR == result || 0 == result){
+  	goto cleanup;
+  }  
+  result = recvfrom(sock, (char*)recv_buf,
+            PACKET_SIZE, 0,
+            (struct sockaddr*)&source, &sockadd_size);
+
+  if (SOCKET_ERROR == result){
+  	goto cleanup;
+  }  
+			    
+  unsigned short header_len = recv_buf->ip_hl << 2;
+  struct icmp* icmphdr = (struct icmp*)((char*)recv_buf + header_len);
+  if ((result < header_len + ICMP_SIZE)||
+	(icmphdr->icmp_type != ICMP_ECHO_REPLY)||
+	(icmphdr->icmp_id != getpid())) {	
+	if (!(icmphdr->icmp_type == ICMP_ECHO_REQUEST && icmphdr->icmp_seq == 0))
+		goto cleanup;
+  }
+  ret = REACHABLE;
+cleanup:
+  free(fdset_read);
+  free(send_buf);
+  free(recv_buf);
+  return ret;
+}
+
+// typical ip checksum
+unsigned short ip_checksum(unsigned short* buffer, int size)
+{
+	register unsigned short * buf = buffer;
+    register int bufleft = size;
+    register unsigned long sum = 0;
+    
+    while (bufleft > 1) {
+        sum = sum + (*buf++);
+        bufleft = bufleft - sizeof(unsigned short );
+    }
+    if (bufleft) {
+        sum = sum + (*(unsigned char*)buf);
+    }
+    sum = (sum >> 16) + (sum & 0xffff);
+    sum += (sum >> 16);
+   
+    return (unsigned short )(~sum);
+}
+
+void set_icmp_packet(struct icmp* icmp_hdr, int packet_size)
+{
+    icmp_hdr->icmp_type = ICMP_ECHO_REQUEST;
+    icmp_hdr->icmp_code = 0;
+    icmp_hdr->icmp_cksum = 0;
+    icmp_hdr->icmp_id = getpid();
+    icmp_hdr->icmp_seq = 0;
+
+    // Calculate a checksum on the result
+    icmp_hdr->icmp_cksum = ip_checksum((unsigned short*)icmp_hdr, packet_size);
+}
 
 /*
  * Class:     org_apache_harmony_luni_platform_OSNetworkSystem
@@ -132,3 +261,4 @@
   /* return both correct and error result, let java code handle	the exception*/
   return result;
 };
+

Modified: incubator/harmony/enhanced/classlib/trunk/native-src/linux.IA32/luni/libhyluni.exp
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/native-src/linux.IA32/luni/libhyluni.exp?rev=406644&r1=406643&r2=406644&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/native-src/linux.IA32/luni/libhyluni.exp (original)
+++ incubator/harmony/enhanced/classlib/trunk/native-src/linux.IA32/luni/libhyluni.exp Mon
May 15 07:50:31 2006
@@ -218,5 +218,6 @@
 		Java_org_apache_harmony_luni_platform_OSNetworkSystem_getHostByAddrImpl;
 		Java_org_apache_harmony_luni_platform_OSNetworkSystem_getHostByNameImpl;
 		Java_org_apache_harmony_luni_platform_OSNetworkSystem_setInetAddressImpl;
+        Java_org_apache_harmony_luni_platform_OSNetworkSystem_isReachableByICMPImpl;
 	local : *;
 };

Modified: incubator/harmony/enhanced/classlib/trunk/native-src/shared/luni/OSNetworkSystem.h
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/native-src/shared/luni/OSNetworkSystem.h?rev=406644&r1=406643&r2=406644&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/native-src/shared/luni/OSNetworkSystem.h (original)
+++ incubator/harmony/enhanced/classlib/trunk/native-src/shared/luni/OSNetworkSystem.h Mon
May 15 07:50:31 2006
@@ -1,4 +1,4 @@
-/* Copyright 2004, 2005 The Apache Software Foundation or its licensors, as applicable
+/* Copyright 2004, 2006 The Apache Software Foundation or its licensors, as applicable
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,6 +22,37 @@
 #define SOCKET_OP_WRITE 2
 #define SOCKET_READ_WRITE 3
 
+// const of ICMP value
+#define ICMP_ECHO_REPLY 0  
+#define ICMP_DEST_UNREACH 3
+#define ICMP_TTL_EXPIRE 11
+#define ICMP_ECHO_REQUEST 8
+#define ICMP_SIZE 8
+#define PACKET_SIZE 1024
+
+// IP header
+struct IPHeader {
+    unsigned char h_len:4;           // default 4
+    unsigned char version:4;         // that is IP v4
+    unsigned char tos;               // Type of service
+    unsigned short total_len;       // Length of the packet in dwords
+    unsigned short ident;           // unique identifier
+    unsigned short flags;           
+    unsigned char ttl;               // Time to live
+    unsigned char proto;             // Protocol number (TCP, UDP etc)
+    unsigned short checksum;        // IP checksum
+    unsigned long source_ip;
+    unsigned long dest_ip;
+};
+
+// ICMP header
+struct ICMPHeader {
+    unsigned char type;          // ICMP packet type
+    unsigned char code;          // Type sub code
+    unsigned short checksum;
+    unsigned short id;
+    unsigned short seq;
+};
 
 #ifndef _Included_org_apache_harmony_luni_platform_OSNetworkSystem
 #define _Included_org_apache_harmony_luni_platform_OSNetworkSystem
@@ -358,6 +389,14 @@
 
 JNIEXPORT jobject JNICALL Java_org_apache_harmony_luni_platform_OSNetworkSystem_getHostByNameImpl
   (JNIEnv *, jclass,jstring,jboolean);
+  
+/*
+ * Class:     org_apache_harmony_luni_platform_OSNetworkSystem
+ * Method:    isReachableByICMPImpl
+ * Signature: ([BII)I
+ */
+JNIEXPORT jint JNICALL Java_org_apache_harmony_luni_platform_OSNetworkSystem_isReachableByICMPImpl
+  (JNIEnv *, jobject, jobject, jobject, jint, jint);
 
 #ifdef __cplusplus
 }

Modified: incubator/harmony/enhanced/classlib/trunk/native-src/win.IA32/luni/OSNetworkSystemWin32.c
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/native-src/win.IA32/luni/OSNetworkSystemWin32.c?rev=406644&r1=406643&r2=406644&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/native-src/win.IA32/luni/OSNetworkSystemWin32.c
(original)
+++ incubator/harmony/enhanced/classlib/trunk/native-src/win.IA32/luni/OSNetworkSystemWin32.c
Mon May 15 07:50:31 2006
@@ -13,9 +13,21 @@
  * limitations under the License.
  */
 
+
+#include "jcl.h"
+#include "helpers.h"
+#include "jclprots.h"
+#include "socket.h"
+#include "jclglob.h"
 #include "OSNetworkSystem.h"
 #include "nethelp.h"
 #include "portsock.h"
+#define NOPRIVILEGE -1
+#define UNREACHABLE -2
+#define REACHABLE 0
+
+unsigned short ip_checksum(unsigned short* buffer, int size);
+void set_icmp_packet(struct ICMPHeader * icmp_hdr, int packet_size);
 
 /*
  * Class:     org_apache_harmony_luni_platform_OSNetworkSystem
@@ -183,3 +195,141 @@
   hymem_free_memory(fdset_read);
   return result;
 }
+
+/*
+ * Class:     org_apache_harmony_luni_platform_OSNetworkSystem
+ * Method:    isReachableByICMPImpl
+ * Signature: ([BII)I
+ */
+JNIEXPORT jint JNICALL Java_org_apache_harmony_luni_platform_OSNetworkSystem_isReachableByICMPImpl
+  (JNIEnv * env, jobject clz, jobject address,jobject localaddr, jint ttl, jint timeout){
+  struct sockaddr_in dest,source,local;
+  struct ICMPHeader* send_buf = 0;
+  struct IPHeader* recv_buf = 0;
+  int size = sizeof(struct ICMPHeader);
+  int result;
+  struct timeval timeP;
+  fd_set * fdset_read;
+  SOCKET sock;
+  unsigned short header_len;
+  int sockadd_size = sizeof (source);
+  jbyte host[HYSOCK_INADDR6_LEN];
+  struct ICMPHeader* icmphdr;
+  struct WSAData wsaData;
+  int ret = UNREACHABLE;
+  U_32 length =  (*env)->GetArrayLength (env,address);
+	      
+  // start raw socket, return -1 for privilege can not be obtained
+  if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
+	  if (WSAStartup (MAKEWORD (1, 1), &wsaData) != 0){
+	        return NOPRIVILEGE;
+	  }
+  }  
+  sock = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP);
+  if (INVALID_SOCKET == sock){
+      return NOPRIVILEGE;
+  }
+  
+  if(0 < ttl){
+	  if (SOCKET_ERROR == setsockopt(sock, IPPROTO_IP, IP_TTL, (const char*)&ttl,
+	          sizeof(ttl))) {
+	      return NOPRIVILEGE;
+	  }
+  }
+
+  // set address
+  netGetJavaNetInetAddressValue (env, address,(U_8 *)host, &length);
+  memset(&dest, 0, sizeof(dest));	  
+  memcpy (&dest.sin_addr.s_addr,(U_8 *)host, length);
+  dest.sin_family = AF_INET;
+
+  if(NULL != localaddr){
+    memset(&local, 0, sizeof(local));
+    netGetJavaNetInetAddressValue (env, localaddr,(U_8 *)host, &length);
+    memcpy (&local.sin_addr.s_addr,(U_8 *)host, length);
+    bind(sock, (struct sockaddr *)& local, sizeof(local));
+  }
+  
+  // set basic send and recv buf
+  send_buf = (struct ICMPHeader*)malloc(sizeof(char)*ICMP_SIZE);
+  recv_buf = (struct IPHeader*)malloc(sizeof(char)*PACKET_SIZE);
+  if (NULL == send_buf || NULL == recv_buf){
+	  goto cleanup;
+  }
+  set_icmp_packet(send_buf, ICMP_SIZE);
+
+  if(SOCKET_ERROR == sendto(sock, (char*)send_buf, ICMP_SIZE, 0,
+            (struct sockaddr*)&dest, sizeof(dest))){
+	  goto cleanup;
+  }
+  fdset_read = (fd_set *)malloc(sizeof (struct fd_set));
+  if (NULL == fdset_read){
+  	  goto cleanup;
+  }
+  FD_ZERO (fdset_read);
+  FD_SET (sock, fdset_read);
+
+  //set select timeout, change millisecond to usec
+  memset (&timeP, 0, sizeof (struct timeval));    
+  timeP.tv_sec = timeout/1000;
+  timeP.tv_usec = (timeout%1000)*1000;
+  result = select (sock+1, fdset_read, NULL, NULL,&timeP);
+  if (SOCKET_ERROR == result || 0 == result){
+	  goto cleanup;
+  }
+  result = recvfrom(sock, (char*)recv_buf,
+            PACKET_SIZE, 0,
+            (struct sockaddr*)&source, &sockadd_size);
+  if (SOCKET_ERROR == result){
+	  goto cleanup;
+  }  
+  // data analysis  
+  header_len = recv_buf->h_len << 2;
+  icmphdr = (struct ICMPHeader*)((char*)recv_buf + header_len);
+  if ((result < header_len + ICMP_SIZE)||
+	  (icmphdr->type != ICMP_ECHO_REPLY)||
+	  (icmphdr->id != (unsigned short )GetCurrentProcessId())) {
+	  goto cleanup;
+  }
+  ret = REACHABLE;
+cleanup:
+  free(fdset_read);
+  free(send_buf);
+  free(recv_buf);
+  WSACleanup();	 
+  return ret;
+}
+
+// typical ip checksum
+unsigned short ip_checksum(unsigned short * buffer, int size)
+{
+	register unsigned short * buf = buffer;
+    register int bufleft = size;
+    register unsigned long sum = 0;
+    
+    while (bufleft > 1) {
+        sum = sum + (*buf++);
+        bufleft = bufleft - sizeof(unsigned short );
+    }
+    if (bufleft) {
+        sum = sum + (*(unsigned char*)buf);
+    }
+    sum = (sum >> 16) + (sum & 0xffff);
+    sum += (sum >> 16);
+   
+    return (unsigned short )(~sum);
+}
+
+//set ICMP packet to send, head only, no data
+void set_icmp_packet(struct ICMPHeader* icmp_hdr, int packet_size)
+{
+    icmp_hdr->type = ICMP_ECHO_REQUEST;
+    icmp_hdr->code = 0;
+    icmp_hdr->checksum = 0;
+    icmp_hdr->id = (unsigned short )GetCurrentProcessId();
+    icmp_hdr->seq = 0;
+
+    // Calculate a checksum on the result
+    icmp_hdr->checksum = ip_checksum((unsigned short *)icmp_hdr, packet_size);
+}
+

Modified: incubator/harmony/enhanced/classlib/trunk/native-src/win.IA32/luni/hyluni.def
URL: http://svn.apache.org/viewcvs/incubator/harmony/enhanced/classlib/trunk/native-src/win.IA32/luni/hyluni.def?rev=406644&r1=406643&r2=406644&view=diff
==============================================================================
--- incubator/harmony/enhanced/classlib/trunk/native-src/win.IA32/luni/hyluni.def (original)
+++ incubator/harmony/enhanced/classlib/trunk/native-src/win.IA32/luni/hyluni.def Mon May
15 07:50:31 2006
@@ -211,4 +211,4 @@
 	Java_org_apache_harmony_luni_util_FloatingPointParser_parseDblImpl
 	Java_org_apache_harmony_luni_util_FloatingPointParser_parseFltImpl
 	Java_org_apache_harmony_luni_util_NumberConverter_bigIntDigitGeneratorInstImpl
-
+	Java_org_apache_harmony_luni_platform_OSNetworkSystem_isReachableByICMPImpl



Mime
View raw message