├── .gitignore ├── README.md ├── build.gradle └── src ├── main ├── java │ └── org │ │ └── icmp4j │ │ ├── AsyncCallback.java │ │ ├── Icmp4jUtil.java │ │ ├── IcmpPingRequest.java │ │ ├── IcmpPingResponse.java │ │ ├── IcmpPingUtil.java │ │ ├── IcmpTraceRouteRequest.java │ │ ├── IcmpTraceRouteResponse.java │ │ ├── IcmpTraceRouteUtil.java │ │ ├── constants │ │ └── OsFamilyCode.java │ │ ├── exception │ │ └── AssertRuntimeException.java │ │ ├── logger │ │ ├── Logger.java │ │ ├── LoggerAdapter.java │ │ ├── LoggerListener.java │ │ ├── PrintStreamLogger.java │ │ └── constants │ │ │ ├── LogLevel.java │ │ │ └── LogLevelName.java │ │ ├── platform │ │ ├── NativeBridge.java │ │ ├── android │ │ │ └── AndroidNativeBridge.java │ │ ├── java │ │ │ └── JavaNativeBridge.java │ │ ├── unix │ │ │ ├── LinuxProcessNativeBridge.java │ │ │ ├── MacProcessNativeBridge.java │ │ │ ├── ProcessNativeBridgeFactory.java │ │ │ ├── UnixNativeBridge.java │ │ │ ├── jna │ │ │ │ ├── IcmpLibrary.java │ │ │ │ ├── LibraryUtil.java │ │ │ │ └── UnixJnaNativeBridge.java │ │ │ └── jni │ │ │ │ ├── Icmp4jJNI.java │ │ │ │ └── UnixJniNativeBridge.java │ │ └── windows │ │ │ ├── WindowsNativeBridge.java │ │ │ └── jna │ │ │ ├── IcmpLibrary.java │ │ │ ├── LibraryUtil.java │ │ │ └── Winsock2Library.java │ │ ├── tool │ │ ├── Ping.java │ │ └── Sample.java │ │ └── util │ │ ├── ArgUtil.java │ │ ├── ExceptionUtil.java │ │ ├── FileUtil.java │ │ ├── IoUtil.java │ │ ├── JnaUtil.java │ │ ├── JniUtil.java │ │ ├── PlatformUtil.java │ │ ├── ProcessUtil.java │ │ ├── ResourceUtil.java │ │ ├── StringUtil.java │ │ ├── SystemUtil.java │ │ └── TimeUtil.java └── resources │ └── platform │ └── unix │ ├── release │ ├── libicmp4jJNA.dylib │ ├── libicmp4jJNA_32bit.so │ ├── libicmp4jJNA_64bit.so │ ├── libicmp4jJNI.dylib │ ├── libicmp4jJNI_32bit.so │ └── libicmp4jJNI_64bit.so │ └── source │ ├── icmp4j.c │ ├── icmp4j.h │ ├── icmp4jJNI.c │ ├── icmp4jJNI.h │ └── makefile └── test └── java └── org └── icmp4j └── platform ├── IcmpPingUtilTest.java ├── IcmpTraceRouteUtilTest.java ├── android └── AndroidNativeBridgeTest.java └── linux └── LinuxNativeBridgeTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | /build/ 2 | /bin/ 3 | 4 | .gradle 5 | 6 | # Eclipse project files 7 | .classpath 8 | .project 9 | .settings 10 | 11 | # commun annoying files 12 | .DS_Store 13 | Thumbs.db 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # icmp4j 2 | 3 | # Not latest and not maintained ! 4 | this is an old copy of [icmp4j](https://sourceforge.net/projects/icmp4j/?source=typ_redirect) 5 | 6 | *** 7 | 8 | 9 | 10 | Sample code: 11 | import org.icmp4j.IcmpPingUtil; 12 | import org.icmp4j.IcmpPingRequest; 13 | import org.icmp4j.IcmpPingResponse; 14 | 15 | // request - use IcmpPingUtil.createIcmpPingRequest () to create a request with defaults 16 | final IcmpPingRequest request = IcmpPingUtil.createIcmpPingRequest (); 17 | request.setHost ("www.google.com"); 18 | 19 | // delegate 20 | final IcmpPingResponse response = IcmpPingUtil.executePingRequest (request); 21 | 22 | // log 23 | final String formattedResponse = IcmpPingUtil.formatResponse (response); 24 | System.out.println (formattedResponse); 25 | 26 | See it in action: 27 | http://www.everyping.com/ 28 | 29 | Compilers: 30 | Built with Sun Java 1.7.0_55-b13, with a source/target combination of 1.6 31 | Apache Ant 1.9.2 32 | 33 | Binaries: 34 | jna-3.5.1.jar (677 KB) 35 | platform-3.5.1.jar (931 KB) 36 | icmp4j.jar (23 KB) 37 | 38 | Tested platforms: 39 | Windows 8.1 64-bit 40 | Windows Server 2008r2 64-bit 41 | Windows 7 Pro 64-bit (ver 6.1.7601) 42 | Windows XP Pro 32-bit 43 | Debian 6 44 | Mint17 45 | ArchLinux 46 | OSX 10.11.3 47 | Ubuntu 15.10 (kernel 4.2.0) 64 bit 48 | Ubuntu 15.10 (kernel 4.2.0) 32 bit 49 | 50 | Running from the command line: 51 | 1. mkdir c:\temp\icmp4j 52 | 2. cd c:\temp\icmp4j 53 | 3. Place icmp4j-project.zip in c:\temp\icmp4j 54 | 4. Expand icmp4j-project.zip in place 55 | 5. cd c:\temp\icmp4j\trunk\icmp4j\output\tool 56 | 4. java -cp * org.icmp4j.tool.Ping www.google.com 57 | -or, if the above does not work: 58 | 4. java -cp jna-3.5.1.jar;platform-3.5.1.jar;icmp4j.jar org.icmp4j.tool.Ping www.google.com 59 | 60 | Using icmp4j with native libraries on unix platforms: 61 | ICMP EchoReply native access can be done either using JNI or JNA calls. 62 | icmp4j-project.zip contains compiled dynamic libraries for OSX 10.11 and Linux (32 and 64 bit) 63 | 64 | 1. Expand icmp4j-project.zip to the directory of your choice 65 | 2. in the trunk/platform/linux/release, look for the library matching your architecture. 66 | - for linux distribution (32 bit) copy libicmp4jJNI_32bit.so and libicmp4jJNA_32bit.so to your deployment directory. 67 | Rename libicmp4jJNI_32bit.so to libicmp4jJNI.so and libicmp4jJNA_32bit.so to libicmp4jJNA.so 68 | 69 | - for linux distribution (64 bit) copy libicmp4jJNI_64bit.so and libicmp4jJNA_64bit.so to your deployment directory. 70 | Rename libicmp4jJNI_64bit.so to libicmp4jJNI.so and libicmp4jJNA_64bit.so to libicmp4jJNA.so 71 | 72 | - for OSX copy libicmp4jJNA.dylib to your deployment directory 73 | 74 | 3.JNI mode 75 | java -cp icmp4j.jar -Djava.libraty.path= org.icmp4j.tool.Ping www.google.com 76 | 77 | JNA mode 78 | java -cp jna-3.5.1.jar;platform-3.5.1.jar;icmp4j.jar -Djna.library.path= org.icmp4j.tool.Ping www.google.com 79 | 80 | Recompiling native librairies: 81 | You can recompile the libraries for your own platform. 82 | The source code and the makefile are located in trunk/platform/unix/source in the icmp4j-project.zip file. 83 | 84 | 85 | Credits: 86 | 1. shortpasta-icmp, the predecessors of icmp4j 87 | 2. Haiming Zhang, 64-bit versions of the dll (most recent build) 88 | 3. Tiberius Pircalabu, 64-bit versions of the dll (initial builds) 89 | 4. Damian Fernandez, reported bug with shortpasta-icmp.dll and sping.exe that can generate the GPF when running in non-administrative mode 90 | 5. Jun Kwang, help with testing IcmpPingTool 91 | 6. Kevin Shih: Help with testing and integration 92 | 7. Nucly: add Mint17 and ArchLinux support 93 | 8. Dekker: cooperate on Android support 94 | 9. Daifeisg8: Icmp4jUtil.nativeBridge initialization bug 95 | 10. Laurent Buhler: *nix and mac platform native implementations 96 | -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | import org.gradle.internal.os.OperatingSystem; 2 | allprojects { 3 | apply plugin: 'java' 4 | } 5 | 6 | sourceCompatibility = 1.6 7 | version = '1.0' 8 | jar { 9 | manifest { 10 | attributes 'Implementation-Title': 'Icmp4j', 11 | 'Implementation-Version': version 12 | } 13 | } 14 | 15 | repositories { 16 | mavenCentral() 17 | } 18 | 19 | dependencies { 20 | compile group: 'net.java.dev.jna', name: 'jna', version: '4.2.1' 21 | compile group: 'net.java.dev.jna', name: 'platform', version: '3.5.2' 22 | testCompile group: 'junit', name: 'junit', version: '4.+' 23 | } 24 | 25 | test { 26 | testLogging { 27 | events 'started', 'passed' 28 | } 29 | exclude 'org/icmp4j/platform/linux/LinuxNativeBridgeTest.class' 30 | } 31 | 32 | // Test Structure 33 | 34 | task runTestsRoot(type: Test, dependsOn: testClasses) { 35 | testLogging { 36 | events 'started', 'passed' 37 | } 38 | 39 | include 'org/icmp4j/platform/linux/*.class' 40 | 41 | executable = 'sudo' 42 | } 43 | 44 | uploadArchives { 45 | repositories { 46 | flatDir { 47 | dirs 'repos' 48 | } 49 | } 50 | } 51 | 52 | task lol { 53 | println System.getenv("JAVA_HOME") 54 | println System.properties['java.home'] 55 | def jdkHome = System.getenv("JAVA_HOME") 56 | println System.properties['java.home'] 57 | doLast { 58 | if (OperatingSystem.current().isMacOsX()) { 59 | println("running on OSX") 60 | } else if (OperatingSystem.current().isLinux()) { 61 | println("running onLinux"); 62 | } 63 | } 64 | } 65 | task fullJar(type: Jar) { 66 | baseName = project.name + '-all' 67 | sourceSets { 68 | main { 69 | java { 70 | srcDir 'src/main/java' 71 | } 72 | resources { 73 | srcDir 'src/main/resources/platform/unix/release/' 74 | include '*.so' 75 | include '*.dylib' 76 | } 77 | } 78 | } 79 | destinationDir = file("${buildDir}/libs") 80 | from sourceSets.main.output 81 | } 82 | 83 | task androidJar(type: Jar) { 84 | description 'minimal jar for android' 85 | baseName = project.name + '-android' 86 | destinationDir = file("${buildDir}/libs") 87 | from sourceSets.main.output 88 | exclude 'org/icmp4j/platform/java' 89 | exclude 'org/icmp4j/platform/unix' 90 | exclude 'org/icmp4j/platform/windows' 91 | exclude '*.dylib' 92 | exclude '*.so' 93 | } 94 | 95 | jar { 96 | from sourceSets.main.output 97 | exclude '*.dylib' 98 | exclude '*.so' 99 | } 100 | 101 | task runRoot (type: Exec, dependsOn: jar) { 102 | executable 'sudo' 103 | args '-l "java -cp junit-4.12.jar:hamcrest-core-1.3.jar:icmp4j.jar -Djava.library.path=. org.junit.runner.JUnitCore org.icmp4j.platform.IcmpTraceRouteUtilTest"' 104 | } 105 | -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/AsyncCallback.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j; 2 | 3 | /** 4 | * icmp4j 5 | * http://www.icmp4j.org 6 | * Copyright 2009 and beyond, Sal Ingrilli at the icmp4j 7 | *

8 | * This is free software; you can redistribute it and/or modify it 9 | * under the terms of the GNU Lesser General Public License version 3 10 | * as published by the Free Software Foundation as long as: 11 | * 1. You credit the original author somewhere within your product or website 12 | * 2. The credit is easily reachable and not burried deep 13 | * 3. Your end-user can easily see it 14 | * 4. You register your name (optional) and company/group/org name (required) 15 | * at http://www.icmp4j.org 16 | * 5. You do all of the above within 4 weeks of integrating this software 17 | * 6. You contribute feedback, fixes, and requests for features 18 | *

19 | * If/when you derive a commercial gain from using this software 20 | * please donate at http://www.icmp4j.org 21 | *

22 | * If prefer or require, contact the author specified above to: 23 | * 1. Release you from the above requirements 24 | * 2. Acquire a commercial license 25 | * 3. Purchase a support contract 26 | * 4. Request a different license 27 | * 5. Anything else 28 | *

29 | * This software is distributed in the hope that it will be useful, 30 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 31 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 32 | * to how this is described in the GNU Lesser General Public License. 33 | *

34 | * User: Sal Ingrilli 35 | * Date: May 25, 2014 36 | * Time: 10:02:25 PM 37 | */ 38 | public interface AsyncCallback { 39 | 40 | /** 41 | * The AsyncCallback interface 42 | * Invoked to handle the return value of the given async invocation 43 | * @param t 44 | */ 45 | void onSuccess (final T t); 46 | 47 | /** 48 | * The AsyncCallback interface 49 | * Invoked to handle the failure for the given async invocation 50 | * @param throwable 51 | */ 52 | void onFailure (final Throwable throwable); 53 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/Icmp4jUtil.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j; 2 | 3 | import org.icmp4j.platform.NativeBridge; 4 | import org.icmp4j.util.PlatformUtil; 5 | import org.icmp4j.constants.OsFamilyCode; 6 | 7 | /** 8 | * icmp4j 9 | * http://www.icmp4j.org 10 | * Copyright 2009 and beyond, Sal Ingrilli at the icmp4j 11 | *

12 | * This is free software; you can redistribute it and/or modify it 13 | * under the terms of the GNU Lesser General Public License version 3 14 | * as published by the Free Software Foundation as long as: 15 | * 1. You credit the original author somewhere within your product or website 16 | * 2. The credit is easily reachable and not burried deep 17 | * 3. Your end-user can easily see it 18 | * 4. You register your name (optional) and company/group/org name (required) 19 | * at http://www.icmp4j.org 20 | * 5. You do all of the above within 4 weeks of integrating this software 21 | * 6. You contribute feedback, fixes, and requests for features 22 | *

23 | * If/when you derive a commercial gain from using this software 24 | * please donate at http://www.icmp4j.org 25 | *

26 | * If prefer or require, contact the author specified above to: 27 | * 1. Release you from the above requirements 28 | * 2. Acquire a commercial license 29 | * 3. Purchase a support contract 30 | * 4. Request a different license 31 | * 5. Anything else 32 | *

33 | * This software is distributed in the hope that it will be useful, 34 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 35 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 36 | * to how this is described in the GNU Lesser General Public License. 37 | *

38 | * User: Sal Ingrilli 39 | * Date: Dec 23, 2014 40 | * Time: 10:51:44 PM 41 | */ 42 | public class Icmp4jUtil { 43 | 44 | // my attributes 45 | private static NativeBridge nativeBridge; 46 | 47 | // my attributes 48 | public static void setNativeBridge (final NativeBridge nativeBridge) { 49 | Icmp4jUtil.nativeBridge = nativeBridge; 50 | } 51 | public static NativeBridge getNativeBridge () { return nativeBridge; } 52 | 53 | /** 54 | * Uniformly initializes the Icmp subsystem 55 | * This is in an explicit method and NOT a static initializer so that the caller gets the full stack trace 56 | */ 57 | public static void initialize () { 58 | 59 | // already initialized? 60 | if (nativeBridge != null) { 61 | return; 62 | } 63 | 64 | // support concurrency 65 | synchronized (Icmp4jUtil.class) { 66 | 67 | // already initialized? 68 | if (nativeBridge != null) { 69 | return; 70 | } 71 | 72 | // handle exceptions 73 | try { 74 | 75 | // initialize other components 76 | PlatformUtil.initialize (); 77 | 78 | final int osFamilyCode = PlatformUtil.getOsFamilyCode (); 79 | // osFamilyCode-specific processing 80 | // WARNING: do NOT include these classes otherwise when we build the platform-specific jars 81 | // like icmp4j-android.jar, it will not run because android complains that it includes 82 | // DLL references... 83 | //final int osFamilyCode = PlatformUtil.getOsFamilyCode (); 84 | final String nativeBridgeClassName = 85 | osFamilyCode == OsFamilyCode.ANDROID ? "org.icmp4j.platform.android.AndroidNativeBridge" : 86 | osFamilyCode == OsFamilyCode.LINUX ? "org.icmp4j.platform.unix.UnixNativeBridge" : 87 | osFamilyCode == OsFamilyCode.MAC ? "org.icmp4j.platform.unix.UnixNativeBridge" : 88 | osFamilyCode == OsFamilyCode.WINDOWS ? "org.icmp4j.platform.windows.WindowsNativeBridge" : 89 | "org.icmp4j.platform.java.JavaNativeBridge"; 90 | 91 | // objectify on the stack 92 | // warning: Wed 8/12/2015, bug report by daifeisg8@users.sf.net 93 | // this used to objectify directly onto nativeBridge and, as pointed out by it could cause threads 94 | // to enter initialize () and find a nativeBridge reference that has not yet been initialized! 95 | final Class nativeBridgeClass = (Class) Class.forName (nativeBridgeClassName); 96 | final NativeBridge nativeBridge = nativeBridgeClass.newInstance (); 97 | 98 | // track 99 | Icmp4jUtil.nativeBridge = nativeBridge; 100 | 101 | nativeBridge.initialize (); 102 | } 103 | catch (final Exception e) { 104 | 105 | // propagate 106 | throw new RuntimeException (e); 107 | } 108 | } 109 | } 110 | 111 | /** 112 | * Uniformly destroys the Icmp subsystem 113 | */ 114 | public static void destroy () { 115 | 116 | // delegate 117 | if (nativeBridge != null) { 118 | nativeBridge.destroy (); 119 | nativeBridge = null; 120 | } 121 | } 122 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/IcmpPingRequest.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j; 2 | 3 | /** 4 | * Internet Control Message Protocol for Java (ICMP4J) 5 | * http://www.icmp4j.org 6 | * Copyright 2009 and beyond, icmp4j 7 | *

8 | * This is free software; you can redistribute it and/or modify it 9 | * under the terms of the GNU Lesser General Public License version 3 10 | * as published by the Free Software Foundation as long as: 11 | * 1. You credit the original author somewhere within your product or website 12 | * 2. The credit is easily reachable and not burried deep 13 | * 3. Your end-user can easily see it 14 | * 4. You register your name (optional) and company/group/org name (required) 15 | * at http://www.icmp4j.org 16 | * 5. You do all of the above within 4 weeks of integrating this software 17 | * 6. You contribute feedback, fixes, and requests for features 18 | *

19 | * If/when you derive a commercial gain from using this software 20 | * please donate at http://www.icmp4j.org 21 | *

22 | * If prefer or require, contact the author specified above to: 23 | * 1. Release you from the above requirements 24 | * 2. Acquire a commercial license 25 | * 3. Purchase a support contract 26 | * 4. Request a different license 27 | * 5. Anything else 28 | *

29 | * This software is distributed in the hope that it will be useful, 30 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 31 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 32 | * to how this is described in the GNU Lesser General Public License. 33 | *

34 | * User: Sal Ingrilli 35 | * Date: May 23, 2014 36 | * Time: 6:55:22 PM 37 | */ 38 | public class IcmpPingRequest { 39 | 40 | // my attributes 41 | private String host; 42 | private int ttl; 43 | private int packetSize; 44 | private long timeout; 45 | 46 | // my attributes 47 | public void setHost (final String host) { this.host = host; } 48 | public String getHost () { return host; } 49 | 50 | public void setTtl (final int ttl) { this.ttl = ttl; } 51 | public int getTtl () { return ttl; } 52 | 53 | public void setPacketSize (final int packetSize) { this.packetSize = packetSize; } 54 | public int getPacketSize () { return packetSize; } 55 | 56 | public void setTimeout (final long timeout) { this.timeout = timeout; } 57 | public long getTimeout () { return timeout; } 58 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/IcmpPingResponse.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j; 2 | 3 | /** 4 | * Internet Control Message Protocol for Java (ICMP4J) 5 | * http://www.icmp4j.org 6 | * Copyright 2009 and beyond, icmp4j 7 | *

8 | * This is free software; you can redistribute it and/or modify it 9 | * under the terms of the GNU Lesser General Public License version 3 10 | * as published by the Free Software Foundation as long as: 11 | * 1. You credit the original author somewhere within your product or website 12 | * 2. The credit is easily reachable and not burried deep 13 | * 3. Your end-user can easily see it 14 | * 4. You register your name (optional) and company/group/org name (required) 15 | * at http://www.icmp4j.org 16 | * 5. You do all of the above within 4 weeks of integrating this software 17 | * 6. You contribute feedback, fixes, and requests for features 18 | *

19 | * If/when you derive a commercial gain from using this software 20 | * please donate at http://www.icmp4j.org 21 | *

22 | * If prefer or require, contact the author specified above to: 23 | * 1. Release you from the above requirements 24 | * 2. Acquire a commercial license 25 | * 3. Purchase a support contract 26 | * 4. Request a different license 27 | * 5. Anything else 28 | *

29 | * This software is distributed in the hope that it will be useful, 30 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 31 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 32 | * to how this is described in the GNU Lesser General Public License. 33 | *

34 | * User: Sal Ingrilli 35 | * Date: May 23, 2014 36 | * Time: 7:08:09 PM 37 | */ 38 | public class IcmpPingResponse { 39 | 40 | // my attributes 41 | private boolean successFlag; 42 | private boolean timeoutFlag; 43 | private String errorMessage; 44 | private Throwable throwable; 45 | private String host; 46 | private int size; 47 | private int rtt; 48 | private int ttl; 49 | private long duration; 50 | 51 | // my attributes 52 | public void setSuccessFlag (final boolean successFlag) { this.successFlag = successFlag; } 53 | public boolean getSuccessFlag () { return successFlag; } 54 | 55 | public void setTimeoutFlag (final boolean timeoutFlag) { this.timeoutFlag = timeoutFlag; } 56 | public boolean getTimeoutFlag () { return timeoutFlag; } 57 | 58 | public void setErrorMessage (final String errorMessage) { this.errorMessage = errorMessage; } 59 | public String getErrorMessage () { return errorMessage; } 60 | 61 | public void setThrowable (final Throwable throwable) { this.throwable = throwable; } 62 | public Throwable getThrowable () { return throwable; } 63 | 64 | public void setHost (final String host) { this.host = host; } 65 | public String getHost () { return host; } 66 | 67 | public void setSize (final int size) { this.size = size; } 68 | public int getSize () { return size; } 69 | 70 | public void setRtt (final int rtt) { this.rtt = rtt; } 71 | public int getRtt () { return rtt; } 72 | 73 | public void setTtl (final int ttl) { this.ttl = ttl; } 74 | public int getTtl () { return ttl; } 75 | 76 | public void setDuration (final long duration) { this.duration = duration; } 77 | public long getDuration () { return duration; } 78 | 79 | /** 80 | * The Object interface 81 | * @return String 82 | */ 83 | @Override 84 | public String toString () { 85 | 86 | return 87 | "[" + 88 | "hashCode: " + super.hashCode () + ", " + 89 | "successFlag: " + successFlag + ", " + 90 | "timeoutFlag: " + timeoutFlag + ", " + 91 | "errorMessage: " + errorMessage + ", " + 92 | "throwable: " + throwable + ", " + 93 | "host: " + host + ", " + 94 | "size: " + size + ", " + 95 | "rtt: " + rtt + ", " + 96 | "ttl: " + ttl + ", " + 97 | "duration: " + duration + 98 | "]"; 99 | } 100 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/IcmpPingUtil.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j; 2 | 3 | import java.util.concurrent.atomic.AtomicInteger; 4 | import java.util.List; 5 | import java.util.ArrayList; 6 | 7 | import org.icmp4j.platform.NativeBridge; 8 | 9 | /** 10 | * Internet Control Message Protocol for Java (ICMP4J) 11 | * http://www.icmp4j.org 12 | * Copyright 2009 and beyond, icmp4j 13 | *

14 | * This is free software; you can redistribute it and/or modify it 15 | * under the terms of the GNU Lesser General Public License version 3 16 | * as published by the Free Software Foundation as long as: 17 | * 1. You credit the original author somewhere within your product or website 18 | * 2. The credit is easily reachable and not burried deep 19 | * 3. Your end-user can easily see it 20 | * 4. You register your name (optional) and company/group/org name (required) 21 | * at http://www.icmp4j.org 22 | * 5. You do all of the above within 4 weeks of integrating this software 23 | * 6. You contribute feedback, fixes, and requests for features 24 | *

25 | * If/when you derive a commercial gain from using this software 26 | * please donate at http://www.icmp4j.org 27 | *

28 | * If prefer or require, contact the author specified above to: 29 | * 1. Release you from the above requirements 30 | * 2. Acquire a commercial license 31 | * 3. Purchase a support contract 32 | * 4. Request a different license 33 | * 5. Anything else 34 | *

35 | * This software is distributed in the hope that it will be useful, 36 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 37 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 38 | * to how this is described in the GNU Lesser General Public License. 39 | *

40 | * User: Sal Ingrilli 41 | * Date: May 23, 2014 42 | * Time: 6:11:59 PM 43 | */ 44 | public class IcmpPingUtil { 45 | 46 | // my attributes 47 | private static final AtomicInteger nextId = new AtomicInteger (); 48 | 49 | /** 50 | * Returns a new IcmpEchoRequest filled with all default values 51 | * These values can change over time 52 | * @return IcmpEchoRequest 53 | */ 54 | public static IcmpPingRequest createIcmpPingRequest () { 55 | 56 | final IcmpPingRequest request = new IcmpPingRequest (); 57 | request.setHost ("localhost"); 58 | request.setPacketSize (32); 59 | request.setTimeout (5000); 60 | request.setTtl (255); 61 | 62 | // done 63 | return request; 64 | } 65 | 66 | /** 67 | * Returns a new IcmpPingResponse filled with all default values to indicate a timeout 68 | * These values can change over time 69 | * @param duration 70 | * @return IcmpEchoRequest 71 | */ 72 | public static IcmpPingResponse createTimeoutIcmpPingResponse (final long duration) { 73 | 74 | // objectify 75 | final IcmpPingResponse response = new IcmpPingResponse (); 76 | response.setErrorMessage ("Timeout reached after " + duration + " msecs"); 77 | response.setSuccessFlag (false); 78 | response.setTimeoutFlag (true); 79 | 80 | // done 81 | return response; 82 | } 83 | 84 | /** 85 | * Executes the given icmp ECHO request 86 | * This call blocks until a response is received or a timeout is reached 87 | * 88 | * The jna implementation adapted from: 89 | * http://hp.vector.co.jp/authors/VA033015/jnasamples.html 90 | * 91 | * @param request 92 | * @return IcmpEchoResponse 93 | */ 94 | public static IcmpPingResponse executePingRequest (final IcmpPingRequest request) { 95 | 96 | // jit-initialize 97 | Icmp4jUtil.initialize (); 98 | 99 | // assert preconditions 100 | { 101 | final String host = request.getHost (); 102 | if (host == null) { 103 | throw new RuntimeException ("host must be specified"); 104 | } 105 | } 106 | 107 | // assert preconditions 108 | { 109 | final int packetSize = request.getPacketSize (); 110 | if (packetSize == 0) { 111 | throw new RuntimeException ("packetSize must be > 0: " + packetSize); 112 | } 113 | } 114 | 115 | // delegate 116 | final NativeBridge nativeBridge = Icmp4jUtil.getNativeBridge (); 117 | final IcmpPingResponse response = nativeBridge.executePingRequest (request); 118 | 119 | // postconditions: rtt should not be a crazy value 120 | final int rtt = response.getRtt (); 121 | if (rtt == Integer.MAX_VALUE) { 122 | throw new RuntimeException ("rtt should not be MAX_VALUE: " + rtt); 123 | } 124 | 125 | // postconditions: rtt should not be > timeout 126 | final long timeout = request.getTimeout (); 127 | if (timeout > 0 && rtt > timeout) { 128 | throw new RuntimeException ("rtt should not be > timeout: " + rtt + " / " + timeout); 129 | } 130 | 131 | // done 132 | return response; 133 | } 134 | 135 | /** 136 | * Executes the given icmp ECHO request asynchronously 137 | * 138 | * This call returns immediately 139 | * When a response is available, a timeout takes place, or an exception is thrown, the given AsyncCallback is invoked 140 | * 141 | * @param request 142 | * @param asyncCallback 143 | */ 144 | public static void executePingRequest ( 145 | final IcmpPingRequest request, 146 | final AsyncCallback asyncCallback) { 147 | 148 | // create thread 149 | final Runnable runnable = new Runnable () { 150 | 151 | public void run () { 152 | 153 | // handle exceptions 154 | try { 155 | 156 | // delegate & propagate response 157 | final IcmpPingResponse response = executePingRequest (request); 158 | asyncCallback.onSuccess (response); 159 | } 160 | catch (final Throwable throwable) { 161 | 162 | // propagate failure 163 | asyncCallback.onFailure (throwable); 164 | } 165 | } 166 | }; 167 | 168 | // delegate 169 | final int id = nextId.incrementAndGet (); 170 | final String name = "executePingRequest:id=" + id; 171 | final Thread thread = new Thread (runnable, name); 172 | thread.setDaemon (true); 173 | thread.setPriority (Thread.MIN_PRIORITY); 174 | thread.start (); 175 | } 176 | 177 | /** 178 | * Executes the given icmp ECHO request 179 | * See executeIcmpPingRequest (IcmpPingRequest) 180 | * @param host 181 | * @param packetSize 182 | * @param timeout 183 | * @return IcmpPingResponse 184 | */ 185 | public static IcmpPingResponse executePingRequest ( 186 | final String host, 187 | final int packetSize, 188 | final long timeout) { 189 | 190 | // delegate 191 | final IcmpPingRequest request = IcmpPingUtil.createIcmpPingRequest (); 192 | request.setHost (host); 193 | request.setPacketSize (packetSize); 194 | request.setTimeout (timeout); 195 | return executePingRequest (request); 196 | } 197 | 198 | /** 199 | * Executes multiple ping requests 200 | * @param request 201 | * @param packetCount 202 | * @return List 203 | */ 204 | public static List executePingRequests ( 205 | final IcmpPingRequest request, 206 | final int packetCount) { 207 | 208 | // delegate 209 | final List responseList = new ArrayList (packetCount); 210 | for (int i = 1; i < packetCount; i++) { 211 | 212 | // delegate 213 | final IcmpPingResponse response = executePingRequest (request); 214 | 215 | // track 216 | responseList.add(response); 217 | } 218 | 219 | // done 220 | return responseList; 221 | } 222 | 223 | /** 224 | * Uniformly formats the given response into a presentable message 225 | * @param response 226 | * @return String 227 | */ 228 | public static String formatResponse (final IcmpPingResponse response) { 229 | 230 | // request 231 | final boolean successFlag = response.getSuccessFlag (); 232 | final String address = response.getHost (); 233 | final String message = response.getErrorMessage (); 234 | final int size = response.getSize (); 235 | final int rtt = response.getRtt (); 236 | final int ttl = response.getTtl (); 237 | 238 | // format windows style: 239 | // ping google.com 240 | // Reply from 74.125.224.46: bytes=32 time=33ms TTL=56 241 | // ping google.com.asd 242 | // Ping request could not find host google.com.asd. Please check the name and try again. 243 | return successFlag ? 244 | "Reply from " + address + ": bytes=" + size + " time=" + rtt + "ms TTL=" + ttl : 245 | "Error: " + message; 246 | } 247 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/IcmpTraceRouteRequest.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j; 2 | 3 | /** 4 | * ShortPasta Foundation 5 | * http://www.shortpasta.org 6 | * Copyright 2009 and beyond, Sal Ingrilli at the ShortPasta Software Foundation 7 | *

8 | * This is free software; you can redistribute it and/or modify it 9 | * under the terms of the GNU Lesser General Public License version 3 10 | * as published by the Free Software Foundation as long as: 11 | * 1. You credit the original author somewhere within your product or website 12 | * 2. The credit is easily reachable and not burried deep 13 | * 3. Your end-user can easily see it 14 | * 4. You register your name (optional) and company/group/org name (required) 15 | * at http://www.shortpasta.org 16 | * 5. You do all of the above within 4 weeks of integrating this software 17 | * 6. You contribute feedback, fixes, and requests for features 18 | *

19 | * If/when you derive a commercial gain from using this software 20 | * please donate at http://www.shortpasta.org 21 | *

22 | * If prefer or require, contact the author specified above to: 23 | * 1. Release you from the above requirements 24 | * 2. Acquire a commercial license 25 | * 3. Purchase a support contract 26 | * 4. Request a different license 27 | * 5. Anything else 28 | *

29 | * This software is distributed in the hope that it will be useful, 30 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 31 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 32 | * to how this is described in the GNU Lesser General Public License. 33 | *

34 | * User: Sal Ingrilli 35 | * Date: Oct 10, 2014 36 | * Time: 12:41:13 AM 37 | */ 38 | public class IcmpTraceRouteRequest { 39 | 40 | // my attributes 41 | private String host; 42 | private int ttl; 43 | private int packetSize; 44 | private long timeout; 45 | 46 | // my attributes 47 | public void setHost (final String host) { this.host = host; } 48 | public String getHost () { return host; } 49 | 50 | public void setTtl (final int ttl) { this.ttl = ttl; } 51 | public int getTtl () { return ttl; } 52 | 53 | public void setPacketSize (final int packetSize) { this.packetSize = packetSize; } 54 | public int getPacketSize () { return packetSize; } 55 | 56 | public void setTimeout (final long timeout) { this.timeout = timeout; } 57 | public long getTimeout () { return timeout; } 58 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/IcmpTraceRouteResponse.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j; 2 | 3 | import java.util.TreeMap; 4 | 5 | import org.icmp4j.util.StringUtil; 6 | 7 | /** 8 | * ShortPasta Foundation 9 | * http://www.shortpasta.org 10 | * Copyright 2009 and beyond, Sal Ingrilli at the ShortPasta Software Foundation 11 | *

12 | * This is free software; you can redistribute it and/or modify it 13 | * under the terms of the GNU Lesser General Public License version 3 14 | * as published by the Free Software Foundation as long as: 15 | * 1. You credit the original author somewhere within your product or website 16 | * 2. The credit is easily reachable and not burried deep 17 | * 3. Your end-user can easily see it 18 | * 4. You register your name (optional) and company/group/org name (required) 19 | * at http://www.shortpasta.org 20 | * 5. You do all of the above within 4 weeks of integrating this software 21 | * 6. You contribute feedback, fixes, and requests for features 22 | *

23 | * If/when you derive a commercial gain from using this software 24 | * please donate at http://www.shortpasta.org 25 | *

26 | * If prefer or require, contact the author specified above to: 27 | * 1. Release you from the above requirements 28 | * 2. Acquire a commercial license 29 | * 3. Purchase a support contract 30 | * 4. Request a different license 31 | * 5. Anything else 32 | *

33 | * This software is distributed in the hope that it will be useful, 34 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 35 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 36 | * to how this is described in the GNU Lesser General Public License. 37 | *

38 | * User: Sal Ingrilli 39 | * Date: Oct 10, 2014 40 | * Time: 12:41:46 AM 41 | */ 42 | public class IcmpTraceRouteResponse { 43 | 44 | // my attributes 45 | private TreeMap ttlToResponseMap; 46 | 47 | // my attributes 48 | public void setTtlToResponseMap (final TreeMap ttlToResponseMap) { this.ttlToResponseMap = ttlToResponseMap; } 49 | public TreeMap getTtlToResponseMap () { return ttlToResponseMap; } 50 | 51 | /** 52 | * The Object interface 53 | * @return String 54 | */ 55 | @Override 56 | public String toString () { 57 | 58 | String string = "["; 59 | for (final int ttl : ttlToResponseMap.keySet ()) { 60 | 61 | final IcmpPingResponse response = ttlToResponseMap.get (ttl); 62 | if (string.length () > 0) { 63 | string += StringUtil.getNewLine (); 64 | } 65 | string += "ttl: " + ttl + ", response: " + response; 66 | } 67 | 68 | string += StringUtil.getNewLine (); 69 | string += "]"; 70 | 71 | // done 72 | return string; 73 | } 74 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/IcmpTraceRouteUtil.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j; 2 | 3 | import java.util.concurrent.CountDownLatch; 4 | import java.util.TreeMap; 5 | 6 | /** 7 | * ShortPasta Foundation 8 | * http://www.shortpasta.org 9 | * Copyright 2009 and beyond, Sal Ingrilli at the ShortPasta Software Foundation 10 | *

11 | * This is free software; you can redistribute it and/or modify it 12 | * under the terms of the GNU Lesser General Public License version 3 13 | * as published by the Free Software Foundation as long as: 14 | * 1. You credit the original author somewhere within your product or website 15 | * 2. The credit is easily reachable and not burried deep 16 | * 3. Your end-user can easily see it 17 | * 4. You register your name (optional) and company/group/org name (required) 18 | * at http://www.shortpasta.org 19 | * 5. You do all of the above within 4 weeks of integrating this software 20 | * 6. You contribute feedback, fixes, and requests for features 21 | *

22 | * If/when you derive a commercial gain from using this software 23 | * please donate at http://www.shortpasta.org 24 | *

25 | * If prefer or require, contact the author specified above to: 26 | * 1. Release you from the above requirements 27 | * 2. Acquire a commercial license 28 | * 3. Purchase a support contract 29 | * 4. Request a different license 30 | * 5. Anything else 31 | *

32 | * This software is distributed in the hope that it will be useful, 33 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 34 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 35 | * to how this is described in the GNU Lesser General Public License. 36 | *

37 | * User: Sal Ingrilli 38 | * Date: Oct 10, 2014 39 | * Time: 12:40:53 AM 40 | */ 41 | public class IcmpTraceRouteUtil { 42 | 43 | /** 44 | * This is what a tracert looks like from the command line: 45 | * C:\Users\sal>tracert www.google.com 46 | * Tracing route to www.google.com [74.125.224.52] 47 | * over a maximum of 30 hops: 48 | * 1 7 ms 9 ms 1 ms 10.142.222.1 49 | * 2 10 ms 5 ms 3 ms 10.0.0.1 50 | * 3 12 ms 10 ms 9 ms 10.6.44.1 51 | * 4 28 ms 14 ms 15 ms ip68-4-12-22.oc.oc.cox.net [68.4.12.22] 52 | * 5 24 ms 30 ms 98 ms ip68-4-11-98.oc.oc.cox.net [68.4.11.98] 53 | * 6 22 ms 19 ms 19 ms 68.1.5.137 54 | * 7 18 ms 19 ms 19 ms langbbrj01-ge050000804.r2.la.cox.net [68.105.30.181] 55 | * 8 17 ms 29 ms 21 ms 216.239.46.40 56 | * 9 22 ms 27 ms 20 ms 209.85.252.149 57 | * 10 28 ms 19 ms 27 ms lax17s01-in-f20.1e100.net [74.125.224.52] 58 | * Trace complete. 59 | * 60 | * This is what a tracert looks like with this library: 61 | * [junit] response: [ 62 | * [junit] ttl: 1, response: [hashCode: 15186923, successFlag: false, timeoutFlag: false, errorMessage: IP_TTL_EXPIRED_TRANSIT, throwable: null, host: 10.142.222.1, size: 0, rtt: 3, ttl: 64] 63 | * [junit] ttl: 2, response: [hashCode: 31615954, successFlag: false, timeoutFlag: false, errorMessage: IP_TTL_EXPIRED_TRANSIT, throwable: null, host: 10.0.0.1, size: 0, rtt: 13, ttl: 63] 64 | * [junit] ttl: 3, response: [hashCode: 1367891, successFlag: false, timeoutFlag: false, errorMessage: IP_TTL_EXPIRED_TRANSIT, throwable: null, host: 10.6.44.1, size: 0, rtt: 23, ttl: 253] 65 | * [junit] ttl: 4, response: [hashCode: 5370470, successFlag: false, timeoutFlag: false, errorMessage: IP_TTL_EXPIRED_TRANSIT, throwable: null, host: 68.4.12.20, size: 0, rtt: 23, ttl: 252] 66 | * [junit] ttl: 5, response: [hashCode: 73029, successFlag: false, timeoutFlag: false, errorMessage: IP_TTL_EXPIRED_TRANSIT, throwable: null, host: 68.4.11.96, size: 0, rtt: 27, ttl: 251] 67 | * [junit] ttl: 6, response: [hashCode: 19446204, successFlag: false, timeoutFlag: false, errorMessage: IP_TTL_EXPIRED_TRANSIT, throwable: null, host: 68.1.0.136, size: 0, rtt: 33, ttl: 247] 68 | * [junit] ttl: 7, response: [hashCode: 12193604, successFlag: false, timeoutFlag: false, errorMessage: IP_TTL_EXPIRED_TRANSIT, throwable: null, host: 68.105.30.181, size: 0, rtt: 33, ttl: 247] 69 | * [junit] ttl: 8, response: [hashCode: 20995753, successFlag: false, timeoutFlag: false, errorMessage: IP_TTL_EXPIRED_TRANSIT, throwable: null, host: 64.233.174.238, size: 0, rtt: 29, ttl: 248] 70 | * [junit] ttl: 9, response: [hashCode: 17219963, successFlag: false, timeoutFlag: false, errorMessage: IP_TTL_EXPIRED_TRANSIT, throwable: null, host: 72.14.236.13, size: 0, rtt: 33, ttl: 247] 71 | * [junit] ttl: 10, response: [hashCode: 8947790, successFlag: true, timeoutFlag: false, errorMessage: SUCCESS, throwable: null, host: 74.125.224.212, size: 32, rtt: 28, ttl: 55] 72 | * [junit] ttl: 11, response: [hashCode: 28106261, successFlag: true, timeoutFlag: false, errorMessage: SUCCESS, throwable: null, host: 74.125.224.212, size: 32, rtt: 31, ttl: 55] 73 | * [junit] ttl: 12, response: [hashCode: 2651170, successFlag: true, timeoutFlag: false, errorMessage: SUCCESS, throwable: null, host: 74.125.224.212, size: 32, rtt: 30, ttl: 55] 74 | * [junit] ttl: 13, response: [hashCode: 31485310, successFlag: true, timeoutFlag: false, errorMessage: SUCCESS, throwable: null, host: 74.125.224.212, size: 32, rtt: 29, ttl: 55] 75 | * [junit] ttl: 14, response: [hashCode: 20216452, successFlag: true, timeoutFlag: false, errorMessage: SUCCESS, throwable: null, host: 74.125.224.212, size: 32, rtt: 31, ttl: 55] 76 | * [junit] ttl: 15, response: [hashCode: 5746246, successFlag: true, timeoutFlag: false, errorMessage: SUCCESS, throwable: null, host: 74.125.224.212, size: 32, rtt: 17, ttl: 55] 77 | * [junit] ttl: 16, response: [hashCode: 7514401, successFlag: true, timeoutFlag: false, errorMessage: SUCCESS, throwable: null, host: 74.125.224.212, size: 32, rtt: 32, ttl: 55] 78 | * ... 79 | * [junit] ttl: 29, response: [hashCode: 29892897, successFlag: true, timeoutFlag: false, errorMessage: SUCCESS, throwable: null, host: 74.125.224.212, size: 32, rtt: 29, ttl: 55] 80 | * [junit] ttl: 30, response: [hashCode: 32973925, successFlag: true, timeoutFlag: false, errorMessage: SUCCESS, throwable: null, host: 74.125.224.212, size: 32, rtt: 29, ttl: 55] 81 | * [junit] ] 82 | */ 83 | 84 | /** 85 | * Executes the given TraceRoute request 86 | * @param request 87 | * @return IcmpTraceRouteResponse 88 | */ 89 | public static IcmpTraceRouteResponse executeTraceRoute (final IcmpTraceRouteRequest request) { 90 | 91 | // request 92 | final int maxTtl; 93 | { 94 | final int requestTtl = request.getTtl (); 95 | maxTtl = requestTtl > 0 ? 96 | requestTtl : 97 | 30; 98 | } 99 | final CountDownLatch countDownLatch = new CountDownLatch (maxTtl); 100 | 101 | // start one ping request for each TTL 102 | // note that the first 10 requests are expected to timeout with an error code of IP_TTL_EXPIRED_TRANSIT 103 | // because it takes more than 10 hops to get to google.com 104 | // track responses by ttl 105 | final TreeMap ttlToResponseMap = new TreeMap (); 106 | for (int ttl = 1; ttl <= maxTtl; ttl ++) { 107 | 108 | // response 109 | final int finalTtl = ttl; 110 | final AsyncCallback asyncCallback = new AsyncCallback () { 111 | 112 | public void onSuccess (final IcmpPingResponse response) { 113 | 114 | // track 115 | synchronized (ttlToResponseMap) { 116 | ttlToResponseMap.put (finalTtl, response); 117 | } 118 | 119 | // signal main thread 120 | countDownLatch.countDown (); 121 | } 122 | 123 | public void onFailure (final Throwable throwable) { 124 | 125 | // objectify 126 | final IcmpPingResponse response = new IcmpPingResponse (); 127 | response.setSuccessFlag (false); 128 | response.setThrowable (throwable); 129 | 130 | // track 131 | synchronized (ttlToResponseMap) { 132 | ttlToResponseMap.put (finalTtl, response); 133 | } 134 | 135 | // signal main thread 136 | countDownLatch.countDown (); 137 | } 138 | }; 139 | 140 | // request 141 | final IcmpPingRequest icmpPingRequest = IcmpPingUtil.createIcmpPingRequest (); 142 | icmpPingRequest.setHost (request.getHost ()); 143 | icmpPingRequest.setPacketSize (request.getPacketSize ()); 144 | icmpPingRequest.setTtl (ttl); 145 | icmpPingRequest.setTimeout (request.getTimeout ()); 146 | 147 | // delegate 148 | IcmpPingUtil.executePingRequest (icmpPingRequest, asyncCallback); 149 | } 150 | 151 | // handle exceptions 152 | try { 153 | 154 | // wait for all to finish 155 | countDownLatch.await (); 156 | 157 | // response 158 | final IcmpTraceRouteResponse response = new IcmpTraceRouteResponse (); 159 | response.setTtlToResponseMap (ttlToResponseMap); 160 | 161 | // done 162 | return response; 163 | } 164 | catch (final InterruptedException e) { 165 | 166 | // propagate 167 | Thread.currentThread ().interrupt (); 168 | throw new RuntimeException (e); 169 | } 170 | } 171 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/constants/OsFamilyCode.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.constants; 2 | 3 | /** 4 | * icmp4j 5 | * http://www.icmp4j.org 6 | * Copyright 2009 and beyond, Sal Ingrilli at the icmp4j 7 | *

8 | * This is free software; you can redistribute it and/or modify it 9 | * under the terms of the GNU Lesser General Public License version 3 10 | * as published by the Free Software Foundation as long as: 11 | * 1. You credit the original author somewhere within your product or website 12 | * 2. The credit is easily reachable and not burried deep 13 | * 3. Your end-user can easily see it 14 | * 4. You register your name (optional) and company/group/org name (required) 15 | * at http://www.icmp4j.org 16 | * 5. You do all of the above within 4 weeks of integrating this software 17 | * 6. You contribute feedback, fixes, and requests for features 18 | *

19 | * If/when you derive a commercial gain from using this software 20 | * please donate at http://www.icmp4j.org 21 | *

22 | * If prefer or require, contact the author specified above to: 23 | * 1. Release you from the above requirements 24 | * 2. Acquire a commercial license 25 | * 3. Purchase a support contract 26 | * 4. Request a different license 27 | * 5. Anything else 28 | *

29 | * This software is distributed in the hope that it will be useful, 30 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 31 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 32 | * to how this is described in the GNU Lesser General Public License. 33 | *

34 | * User: Sal Ingrilli 35 | * Date: Dec 23, 2014 36 | * Time: 10:47:52 PM 37 | */ 38 | public interface OsFamilyCode { 39 | 40 | int ZERO = 0; 41 | int WINDOWS = 1; 42 | int LINUX = 2; 43 | int MAC = 3; 44 | int ANDROID = 4; 45 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/exception/AssertRuntimeException.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.exception; 2 | 3 | /** 4 | * ShortPasta Foundation 5 | * http://www.shortpasta.org 6 | * Copyright 2009 and beyond, Sal Ingrilli at the ShortPasta Software Foundation 7 | *

8 | * This is free software; you can redistribute it and/or modify it 9 | * under the terms of the GNU Lesser General Public License version 3 10 | * as published by the Free Software Foundation as long as: 11 | * 1. You credit the original author somewhere within your product or website 12 | * 2. The credit is easily reachable and not burried deep 13 | * 3. Your end-user can easily see it 14 | * 4. You register your name (optional) and company/group/org name (required) 15 | * at http://www.shortpasta.org 16 | * 5. You do all of the above within 4 weeks of integrating this software 17 | * 6. You contribute feedback, fixes, and requests for features 18 | *

19 | * If/when you derive a commercial gain from using this software 20 | * please donate at http://www.shortpasta.org 21 | *

22 | * If prefer or require, contact the author specified above to: 23 | * 1. Release you from the above requirements 24 | * 2. Acquire a commercial license 25 | * 3. Purchase a support contract 26 | * 4. Request a different license 27 | * 5. Anything else 28 | *

29 | * This software is distributed in the hope that it will be useful, 30 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 31 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 32 | * to how this is described in the GNU Lesser General Public License. 33 | *

34 | * User: Sal Ingrilli 35 | * Date: Nov 22, 2009 36 | * Time: 10:36:13 AM 37 | */ 38 | public class AssertRuntimeException extends RuntimeException { 39 | 40 | /** 41 | * Def ctor 42 | */ 43 | public AssertRuntimeException () { 44 | } 45 | 46 | /** 47 | * Def ctor 48 | * @param message 49 | */ 50 | public AssertRuntimeException (final String message) { 51 | 52 | super (message); 53 | } 54 | 55 | /** 56 | * Def ctor 57 | * @param message 58 | * @param t 59 | */ 60 | public AssertRuntimeException (final String message, final Throwable t) { 61 | 62 | super (message, t); 63 | } 64 | 65 | /** 66 | * Def ctor 67 | * @param t 68 | */ 69 | public AssertRuntimeException (final Throwable t) { 70 | 71 | super (t); 72 | } 73 | 74 | /** 75 | * Asserts the given expression, throwing a new AssertRuntimeException if the given expression is false 76 | * @param expression 77 | * @throws AssertRuntimeException 78 | */ 79 | public static void assertExpression (final boolean expression) 80 | throws AssertRuntimeException { 81 | 82 | if (!expression) { 83 | throw new AssertRuntimeException (); 84 | } 85 | } 86 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/logger/Logger.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.logger; 2 | 3 | import java.util.Map; 4 | import java.util.HashMap; 5 | 6 | import org.icmp4j.logger.constants.LogLevel; 7 | import org.icmp4j.logger.constants.LogLevelName; 8 | 9 | /** 10 | * ShortPasta Foundation 11 | * http://www.shortpasta.org 12 | * Copyright 2009 and beyond, Sal Ingrilli at the ShortPasta Software Foundation 13 | *

14 | * This is free software; you can redistribute it and/or modify it 15 | * under the terms of the GNU Lesser General Public License version 3 16 | * as published by the Free Software Foundation as long as: 17 | * 1. You credit the original author somewhere within your product or website 18 | * 2. The credit is easily reachable and not burried deep 19 | * 3. Your end-user can easily see it 20 | * 4. You register your name (optional) and company/group/org name (required) 21 | * at http://www.shortpasta.org 22 | * 5. You do all of the above within 4 weeks of integrating this software 23 | * 6. You contribute feedback, fixes, and requests for features 24 | *

25 | * If/when you derive a commercial gain from using this software 26 | * please donate at http://www.shortpasta.org 27 | *

28 | * If prefer or require, contact the author specified above to: 29 | * 1. Release you from the above requirements 30 | * 2. Acquire a commercial license 31 | * 3. Purchase a support contract 32 | * 4. Request a different license 33 | * 5. Anything else 34 | *

35 | * This software is distributed in the hope that it will be useful, 36 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 37 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 38 | * to how this is described in the GNU Lesser General Public License. 39 | *

40 | * User: Sal Ingrilli 41 | * Date: Jan 27, 2016 42 | * Time: 10:12:06 PM 43 | */ 44 | public abstract class Logger { 45 | 46 | // my attributes 47 | private static Class loggerClass; 48 | private static final Map categoryToLoggerMap = new HashMap (); 49 | private Object category; 50 | 51 | // my attributes 52 | public static void setLoggerClass (final Class loggerClass) { 53 | Logger.loggerClass = loggerClass; 54 | } 55 | 56 | public void setCategory (final Object category) { this.category = category; } 57 | public Object getCategory () { return category; } 58 | 59 | /** 60 | * 61 | * @param category 62 | * @return Logger 63 | */ 64 | public static Logger getLogger (final Object category) { 65 | 66 | // already cached? 67 | { 68 | final Logger logger = categoryToLoggerMap.get (category); 69 | if (logger != null) { 70 | return logger; 71 | } 72 | } 73 | 74 | // not cached: cache it 75 | synchronized (Logger.class) { 76 | 77 | // already cached? 78 | { 79 | final Logger logger = categoryToLoggerMap.get (category); 80 | if (logger != null) { 81 | return logger; 82 | } 83 | } 84 | 85 | // the specified category does not have an associated Logger: instantiate the Logger 86 | // handle exceptions 87 | Logger logger; 88 | try { 89 | 90 | // if you specified loggerClass 91 | if (loggerClass != null) { 92 | logger = loggerClass.newInstance (); 93 | } 94 | else { 95 | logger = new PrintStreamLogger (System.out); 96 | } 97 | } 98 | catch (final Exception e) { 99 | 100 | // log 101 | System.out.println (" <>"); 102 | e.printStackTrace (); 103 | 104 | // creating a specifing Logger failed, resort to good-old System.out calls 105 | logger = new PrintStreamLogger (System.out); 106 | } 107 | 108 | // uniformly initialize the Logger 109 | logger.setCategory (category); 110 | 111 | // cache & recurse to ensure proper caching 112 | categoryToLoggerMap.put (category, logger); 113 | return getLogger (category); 114 | } 115 | } 116 | 117 | /** 118 | * The Logger interface 119 | * @param object 120 | */ 121 | public void trace (final Object object) { 122 | 123 | // delegate 124 | final Throwable t = null; 125 | log (LogLevel.TRACE, object, t); 126 | } 127 | 128 | /** 129 | * The Logger interface 130 | * @param object 131 | * @param t 132 | */ 133 | public void trace (final Object object, final Throwable t) { 134 | 135 | // delegate 136 | log (LogLevel.TRACE, object, t); 137 | } 138 | 139 | /** 140 | * The Logger interface 141 | * @param t 142 | */ 143 | public void trace (final Throwable t) { 144 | 145 | // delegate 146 | final Object object = null; 147 | log (LogLevel.TRACE, object, t); 148 | } 149 | 150 | /** 151 | * The Logger interface 152 | * @param object 153 | */ 154 | public void debug (final Object object) { 155 | 156 | // delegate 157 | final Throwable t = null; 158 | log (LogLevel.DEBUG, object, t); 159 | } 160 | 161 | /** 162 | * The Logger interface 163 | * @param object 164 | * @param t 165 | */ 166 | public void debug (final Object object, final Throwable t) { 167 | 168 | // delegate 169 | log (LogLevel.DEBUG, object, t); 170 | } 171 | 172 | /** 173 | * The Logger interface 174 | * @param t 175 | */ 176 | public void debug (final Throwable t) { 177 | 178 | // delegate 179 | final Object object = null; 180 | log (LogLevel.DEBUG, object, t); 181 | } 182 | 183 | /** 184 | * @param object 185 | */ 186 | public void info (final Object object) { 187 | 188 | // delegate 189 | final Throwable t = null; 190 | log (LogLevel.INFO, object, t); 191 | } 192 | 193 | /** 194 | * @param t 195 | */ 196 | public void info (final Throwable t) { 197 | 198 | // delegate 199 | final Object object = null; 200 | log (LogLevel.INFO, object, t); 201 | } 202 | 203 | /** 204 | * The Logger interface 205 | * @param object 206 | */ 207 | public void warn (final Object object) { 208 | 209 | // delegate 210 | final Throwable t = null; 211 | log (LogLevel.WARN, object, t); 212 | } 213 | 214 | /** 215 | * The Logger interface 216 | * @param object 217 | * @param t 218 | */ 219 | public void warn (final Object object, final Throwable t) { 220 | 221 | // delegate 222 | log (LogLevel.WARN, object, t); 223 | } 224 | 225 | /** 226 | * The Logger interface 227 | * @param t 228 | */ 229 | public void warn (final Throwable t) { 230 | 231 | // delegate 232 | final Object object = null; 233 | log (LogLevel.WARN, object, t); 234 | } 235 | 236 | /** 237 | * The Logger interface 238 | * @param object 239 | */ 240 | public void error (final Object object) { 241 | 242 | // delegate 243 | final Throwable t = null; 244 | log (LogLevel.ERROR, object, t); 245 | } 246 | 247 | /** 248 | * The Logger interface 249 | * @param object 250 | * @param t 251 | */ 252 | public void error (final Object object, final Throwable t) { 253 | 254 | // delegate 255 | log (LogLevel.ERROR, object, t); 256 | } 257 | 258 | /** 259 | * The Logger interface 260 | * @param t 261 | */ 262 | public void error (final Throwable t) { 263 | 264 | // delegate 265 | final Object object = null; 266 | log (LogLevel.ERROR, object, t); 267 | } 268 | 269 | /** 270 | * The Logger interface 271 | * @param object 272 | */ 273 | public void fatal (final Object object) { 274 | 275 | // delegate 276 | final Throwable t = null; 277 | log (LogLevel.FATAL, object, t); 278 | } 279 | 280 | /** 281 | * The Logger interface 282 | * @param object 283 | * @param t 284 | */ 285 | public void fatal (final Object object, final Throwable t) { 286 | 287 | // delegate 288 | log (LogLevel.FATAL, object, t); 289 | } 290 | 291 | /** 292 | * The Logger interface 293 | * @param t 294 | */ 295 | public void fatal (final Throwable t) { 296 | 297 | // delegate 298 | final Object object = null; 299 | log (LogLevel.FATAL, object, t); 300 | } 301 | 302 | /** 303 | * The Logger interface 304 | * Invoked to log the given object 305 | * @param logLevel 306 | * @param object 307 | * @param t 308 | * @noinspection LoopStatementThatDoesntLoop 309 | */ 310 | protected void log ( 311 | final int logLevel, 312 | final Object object, 313 | final Throwable t) { 314 | 315 | // delegate 316 | log2 ( 317 | logLevel, 318 | object, 319 | t); 320 | } 321 | 322 | /** 323 | * The Logger interface 324 | * Invoked to log the given object 325 | * @param logLevel 326 | * @param object 327 | * @param t 328 | */ 329 | protected void log2 ( 330 | final int logLevel, 331 | final Object object, 332 | final Throwable t) { 333 | 334 | } 335 | 336 | /** 337 | * The Logger interface 338 | * Invoked to determine if the given log level is enabled 339 | * @return boolean 340 | */ 341 | public abstract boolean isDebugEnabled (); 342 | 343 | /** 344 | * The Logger interface 345 | * Invoked to determine if the given log level is enabled 346 | * @return boolean 347 | */ 348 | public abstract boolean isInfoEnabled (); 349 | 350 | /** 351 | * The Logger interface 352 | * Invoked to determine if the given log level is enabled 353 | * @return boolean 354 | */ 355 | public abstract boolean isTraceEnabled (); 356 | 357 | /** 358 | * Returns the log level text for the given logLevel 359 | * @param logLevel 360 | * @return String 361 | */ 362 | public static String getLogLevelText (final int logLevel) { 363 | 364 | // translate logLevel 365 | return 366 | logLevel == LogLevel.FATAL ? LogLevelName.FATAL : 367 | logLevel == LogLevel.ERROR ? LogLevelName.ERROR : 368 | logLevel == LogLevel.WARN ? LogLevelName.WARN : 369 | logLevel == LogLevel.INFO ? LogLevelName.INFO : 370 | logLevel == LogLevel.DEBUG ? LogLevelName.DEBUG : 371 | logLevel == LogLevel.TRACE ? LogLevelName.TRACE : 372 | String.valueOf (logLevel); 373 | } 374 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/logger/LoggerAdapter.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.logger; 2 | 3 | import java.util.List; 4 | import java.util.LinkedList; 5 | import java.util.Date; 6 | import java.text.SimpleDateFormat; 7 | import java.io.StringWriter; 8 | import java.io.PrintWriter; 9 | 10 | import org.icmp4j.logger.constants.LogLevel; 11 | 12 | /** 13 | * ShortPasta Foundation 14 | * http://www.shortpasta.org 15 | * Copyright 2009 and beyond, Sal Ingrilli at the ShortPasta Software Foundation 16 | *

17 | * This is free software; you can redistribute it and/or modify it 18 | * under the terms of the GNU Lesser General Public License version 3 19 | * as published by the Free Software Foundation as long as: 20 | * 1. You credit the original author somewhere within your product or website 21 | * 2. The credit is easily reachable and not burried deep 22 | * 3. Your end-user can easily see it 23 | * 4. You register your name (optional) and company/group/org name (required) 24 | * at http://www.shortpasta.org 25 | * 5. You do all of the above within 4 weeks of integrating this software 26 | * 6. You contribute feedback, fixes, and requests for features 27 | *

28 | * If/when you derive a commercial gain from using this software 29 | * please donate at http://www.shortpasta.org 30 | *

31 | * If prefer or require, contact the author specified above to: 32 | * 1. Release you from the above requirements 33 | * 2. Acquire a commercial license 34 | * 3. Purchase a support contract 35 | * 4. Request a different license 36 | * 5. Anything else 37 | *

38 | * This software is distributed in the hope that it will be useful, 39 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 40 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 41 | * to how this is described in the GNU Lesser General Public License. 42 | *

43 | * User: Sal Ingrilli 44 | * Date: Jan 21, 2010 45 | * Time: 9:37:23 AM 46 | */ 47 | public class LoggerAdapter extends Logger { 48 | 49 | // my constants 50 | public static final String DEBUG = "DEBUG"; 51 | public static final String INFO = "INFO"; 52 | public static final String ERROR = "ERROR"; 53 | public static final String FATAL = "FATAL"; 54 | public static final String WARN = "WARN"; 55 | public static final String TRACE = "TRACE"; 56 | 57 | // my static attributes 58 | private static int logLevel = LogLevel.DEBUG; 59 | private static final List loggerList = new LinkedList (); 60 | 61 | // my static attributes 62 | public static void addLogger (final Logger logger) { 63 | synchronized (LoggerAdapter.loggerList) { 64 | LoggerAdapter.loggerList.add (logger); 65 | } 66 | } 67 | public static void removeLogger (final Logger logger) { 68 | synchronized (LoggerAdapter.loggerList) { 69 | LoggerAdapter.loggerList.remove (logger); 70 | } 71 | } 72 | 73 | /** 74 | * Explicitly set the default log level. 75 | * @param logLevelString 76 | */ 77 | public static void setLoglevel (final String logLevelString) { 78 | logLevel = 79 | logLevelString.equalsIgnoreCase (TRACE) ? LogLevel.TRACE : 80 | logLevelString.equalsIgnoreCase (DEBUG) ? LogLevel.DEBUG : 81 | logLevelString.equalsIgnoreCase (INFO) ? LogLevel.INFO : 82 | logLevelString.equalsIgnoreCase (ERROR) ? LogLevel.ERROR : 83 | logLevelString.equalsIgnoreCase (WARN) ? LogLevel.WARN : 84 | logLevelString.equalsIgnoreCase (FATAL) ? LogLevel.FATAL : 85 | logLevel; 86 | } 87 | 88 | // my attributes 89 | private final SimpleDateFormat simpleDateFormat = new SimpleDateFormat ("yyyy-MM-dd HH:mm:ss"); 90 | private Object category; 91 | 92 | // my attributes 93 | @Override 94 | public void setCategory (final Object category) { this.category = category; } 95 | public Object getCategory () { return category; } 96 | 97 | /** 98 | * Def ctor 99 | */ 100 | public LoggerAdapter () { 101 | } 102 | 103 | /** 104 | * Def ctor 105 | * @param category 106 | */ 107 | public LoggerAdapter (final Object category) { 108 | this.category = category; 109 | } 110 | 111 | /** 112 | * The Logger interface 113 | * Invoked to log the given message 114 | * @param logLevel 115 | * @param object 116 | * @param t 117 | * @noinspection LoopStatementThatDoesntLoop,ConstantConditions 118 | */ 119 | @Override 120 | protected void log2 ( 121 | final int logLevel, 122 | final Object object, 123 | final Throwable t) { 124 | 125 | // handle exceptions 126 | try { 127 | 128 | // generate the log line 129 | final StringBuilder sb = new StringBuilder (); 130 | 131 | // <2010-01-21 09:34:00> 132 | sb.append ('<'); 133 | sb.append (simpleDateFormat.format (new Date ())); 134 | sb.append ('>'); 135 | 136 | // <2010-01-21 09:34:00> 137 | sb.append (" <"); 138 | sb.append (getLogLevelText (logLevel)); 139 | sb.append ('>'); 140 | 141 | // <2010-01-21 09:34:00> 142 | final String categoryName = category instanceof Class ? 143 | ((Class) category).getSimpleName () : 144 | category.toString (); 145 | sb.append (" <"); 146 | sb.append (categoryName); 147 | sb.append ('>'); 148 | 149 | // <2010-01-21 09:34:00> '); 164 | 165 | // delegate 166 | synchronized (LoggerAdapter.loggerList) { 167 | for (final Logger logger : LoggerAdapter.loggerList) { 168 | logger.log2 (logLevel, object, t); 169 | } 170 | } 171 | 172 | // delegate 173 | final String line = sb.toString (); 174 | printLine (logLevel, line); 175 | } 176 | catch (final Exception e) { 177 | 178 | // just print it 179 | final String string = object == null ? 180 | "null" : 181 | object.toString (); 182 | printLine (logLevel, string); 183 | } 184 | } 185 | 186 | /** 187 | * The LoggerAdapter interface 188 | * Invoked to log the given message 189 | * @param logLevel 190 | * @param line 191 | */ 192 | protected void printLine ( 193 | final int logLevel, 194 | final String line) { 195 | 196 | } 197 | 198 | @Override 199 | public boolean isDebugEnabled () { return LogLevel.DEBUG >= logLevel; } 200 | @Override 201 | public boolean isInfoEnabled () { return LogLevel.INFO >= logLevel; } 202 | @Override 203 | public boolean isTraceEnabled () { return LogLevel.TRACE >= logLevel;} 204 | 205 | /** 206 | * Helper to minimize dependencies 207 | * @param t 208 | * @return String 209 | */ 210 | protected static String getStackTrace (final Throwable t) { 211 | 212 | final StringWriter sw = new StringWriter (); 213 | final PrintWriter pw = new PrintWriter (sw); 214 | t.printStackTrace (pw); 215 | return sw.toString (); 216 | } 217 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/logger/LoggerListener.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.logger; 2 | 3 | import java.util.Date; 4 | 5 | /** 6 | * ShortPasta Foundation 7 | * http://www.shortpasta.org 8 | * Copyright 2009 and beyond, Sal Ingrilli at the ShortPasta Software Foundation 9 | *

10 | * This is free software; you can redistribute it and/or modify it 11 | * under the terms of the GNU Lesser General Public License version 3 12 | * as published by the Free Software Foundation as long as: 13 | * 1. You credit the original author somewhere within your product or website 14 | * 2. The credit is easily reachable and not burried deep 15 | * 3. Your end-user can easily see it 16 | * 4. You register your name (optional) and company/group/org name (required) 17 | * at http://www.shortpasta.org 18 | * 5. You do all of the above within 4 weeks of integrating this software 19 | * 6. You contribute feedback, fixes, and requests for features 20 | *

21 | * If/when you derive a commercial gain from using this software 22 | * please donate at http://www.shortpasta.org 23 | *

24 | * If prefer or require, contact the author specified above to: 25 | * 1. Release you from the above requirements 26 | * 2. Acquire a commercial license 27 | * 3. Purchase a support contract 28 | * 4. Request a different license 29 | * 5. Anything else 30 | *

31 | * This software is distributed in the hope that it will be useful, 32 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 33 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 34 | * to how this is described in the GNU Lesser General Public License. 35 | *

36 | * User: Sal Ingrilli 37 | * Date: Jan 5, 2010 38 | * Time: 7:04:44 PM 39 | */ 40 | public interface LoggerListener { 41 | 42 | /** 43 | * The LoggerListener interface 44 | * @param date 45 | * @param className 46 | * @param logLevel 47 | * @param logLevelText 48 | * @param message 49 | * @param t 50 | */ 51 | void log ( 52 | final Date date, 53 | final String className, 54 | final int logLevel, 55 | final String logLevelText, 56 | final String message, 57 | final Throwable t); 58 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/logger/PrintStreamLogger.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.logger; 2 | 3 | import java.io.PrintStream; 4 | 5 | import org.icmp4j.logger.constants.LogLevel; 6 | import org.icmp4j.logger.constants.LogLevelName; 7 | 8 | /** 9 | * ShortPasta Foundation 10 | * http://www.shortpasta.org 11 | * Copyright 2009 and beyond, Sal Ingrilli at the ShortPasta Software Foundation 12 | *

13 | * This is free software; you can redistribute it and/or modify it 14 | * under the terms of the GNU Lesser General Public License version 3 15 | * as published by the Free Software Foundation as long as: 16 | * 1. You credit the original author somewhere within your product or website 17 | * 2. The credit is easily reachable and not burried deep 18 | * 3. Your end-user can easily see it 19 | * 4. You register your name (optional) and company/group/org name (required) 20 | * at http://www.shortpasta.org 21 | * 5. You do all of the above within 4 weeks of integrating this software 22 | * 6. You contribute feedback, fixes, and requests for features 23 | *

24 | * If/when you derive a commercial gain from using this software 25 | * please donate at http://www.shortpasta.org 26 | *

27 | * If prefer or require, contact the author specified above to: 28 | * 1. Release you from the above requirements 29 | * 2. Acquire a commercial license 30 | * 3. Purchase a support contract 31 | * 4. Request a different license 32 | * 5. Anything else 33 | *

34 | * This software is distributed in the hope that it will be useful, 35 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 36 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 37 | * to how this is described in the GNU Lesser General Public License. 38 | *

39 | * User: Sal Ingrilli 40 | * Date: Nov 22, 2009 41 | * Time: 10:36:13 AM 42 | */ 43 | public class PrintStreamLogger extends LoggerAdapter { 44 | 45 | // my attributes 46 | private static int loglevel = LogLevel.DEBUG; 47 | private PrintStream ps; 48 | 49 | // my attributes 50 | public static void setLogLevel (final String logLevelString) { 51 | if (logLevelString.equalsIgnoreCase (LogLevelName.TRACE)) { 52 | loglevel = LogLevel.TRACE; 53 | } 54 | else if (logLevelString.equalsIgnoreCase (LogLevelName.DEBUG)) { 55 | loglevel = LogLevel.DEBUG; 56 | } 57 | else if (logLevelString.equalsIgnoreCase (LogLevelName.INFO)) { 58 | loglevel = LogLevel.INFO; 59 | } 60 | else if (logLevelString.equalsIgnoreCase (LogLevelName.ERROR)) { 61 | loglevel = LogLevel.ERROR; 62 | } 63 | else if (logLevelString.equalsIgnoreCase (LogLevelName.WARN)) { 64 | loglevel = LogLevel.WARN; 65 | } 66 | else if (logLevelString.equalsIgnoreCase (LogLevelName.FATAL)) { 67 | loglevel = LogLevel.FATAL; 68 | } 69 | } 70 | 71 | /** 72 | * Def ctor 73 | * Needed so that Logger can instantiate this via PrintStreamLogger.class.newInstance! 74 | */ 75 | public PrintStreamLogger () { 76 | this (System.out); 77 | } 78 | 79 | /** 80 | * Def ctor 81 | * @param ps 82 | */ 83 | public PrintStreamLogger (final PrintStream ps) { 84 | this.ps = ps; 85 | } 86 | 87 | @Override 88 | public boolean isDebugEnabled () { return LogLevel.DEBUG >= loglevel; } 89 | @Override 90 | public boolean isInfoEnabled () { return LogLevel.INFO >= loglevel; } 91 | @Override 92 | public boolean isTraceEnabled () { return LogLevel.TRACE >= loglevel;} 93 | 94 | /** 95 | * The Logger interface 96 | * Invoked to log the given message 97 | * @param logLevel 98 | * @param object 99 | * @param t 100 | * @noinspection LoopStatementThatDoesntLoop,ConstantConditions 101 | */ 102 | @Override 103 | protected void log2 ( 104 | final int logLevel, 105 | final Object object, 106 | final Throwable t) { 107 | 108 | // discriminate by logLevel 109 | if (logLevel < PrintStreamLogger.loglevel) { 110 | return; 111 | } 112 | 113 | // propagate 114 | super.log2 ( 115 | logLevel, 116 | object, 117 | t); 118 | } 119 | 120 | /** 121 | * The LoggerAdapter interface 122 | * Invoked to log the given message 123 | * @param logLevel 124 | * @param line 125 | */ 126 | protected void printLine ( 127 | final int logLevel, 128 | final String line) { 129 | 130 | // 131 | ps.println (line); 132 | } 133 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/logger/constants/LogLevel.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.logger.constants; 2 | 3 | /** 4 | * ShortPasta Foundation 5 | * http://www.shortpasta.org 6 | * Copyright 2009 and beyond, Sal Ingrilli at the ShortPasta Software Foundation 7 | *

8 | * This is free software; you can redistribute it and/or modify it 9 | * under the terms of the GNU Lesser General Public License version 3 10 | * as published by the Free Software Foundation as long as: 11 | * 1. You credit the original author somewhere within your product or website 12 | * 2. The credit is easily reachable and not burried deep 13 | * 3. Your end-user can easily see it 14 | * 4. You register your name (optional) and company/group/org name (required) 15 | * at http://www.shortpasta.org 16 | * 5. You do all of the above within 4 weeks of integrating this software 17 | * 6. You contribute feedback, fixes, and requests for features 18 | *

19 | * If/when you derive a commercial gain from using this software 20 | * please donate at http://www.shortpasta.org 21 | *

22 | * If prefer or require, contact the author specified above to: 23 | * 1. Release you from the above requirements 24 | * 2. Acquire a commercial license 25 | * 3. Purchase a support contract 26 | * 4. Request a different license 27 | * 5. Anything else 28 | *

29 | * This software is distributed in the hope that it will be useful, 30 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 31 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 32 | * to how this is described in the GNU Lesser General Public License. 33 | *

34 | * User: Sal Ingrilli 35 | * Date: Jan 21, 2010 36 | * Time: 9:52:39 AM 37 | */ 38 | public interface LogLevel { 39 | 40 | // my constants 41 | int TRACE = 1; 42 | int DEBUG = 2; 43 | int INFO = 3; 44 | int ERROR = 4; 45 | int WARN = 5; 46 | int FATAL = 6; 47 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/logger/constants/LogLevelName.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.logger.constants; 2 | 3 | /** 4 | * ShortPasta Foundation 5 | * http://www.shortpasta.org 6 | * Copyright 2009 and beyond, Sal Ingrilli at the ShortPasta Software Foundation 7 | *

8 | * This is free software; you can redistribute it and/or modify it 9 | * under the terms of the GNU Lesser General Public License version 3 10 | * as published by the Free Software Foundation as long as: 11 | * 1. You credit the original author somewhere within your product or website 12 | * 2. The credit is easily reachable and not burried deep 13 | * 3. Your end-user can easily see it 14 | * 4. You register your name (optional) and company/group/org name (required) 15 | * at http://www.shortpasta.org 16 | * 5. You do all of the above within 4 weeks of integrating this software 17 | * 6. You contribute feedback, fixes, and requests for features 18 | *

19 | * If/when you derive a commercial gain from using this software 20 | * please donate at http://www.shortpasta.org 21 | *

22 | * If prefer or require, contact the author specified above to: 23 | * 1. Release you from the above requirements 24 | * 2. Acquire a commercial license 25 | * 3. Purchase a support contract 26 | * 4. Request a different license 27 | * 5. Anything else 28 | *

29 | * This software is distributed in the hope that it will be useful, 30 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 31 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 32 | * to how this is described in the GNU Lesser General Public License. 33 | *

34 | * User: Sal Ingrilli 35 | * Date: Jan 15, 2014 36 | * Time: 4:32:25 PM 37 | */ 38 | public interface LogLevelName { 39 | 40 | // my constants 41 | String DEBUG = "DEBUG"; 42 | String INFO = "INFO"; 43 | String ERROR = "ERROR"; 44 | String FATAL = "FATAL"; 45 | String WARN = "WARN"; 46 | String TRACE = "TRACE"; 47 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/platform/NativeBridge.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.platform; 2 | 3 | import org.icmp4j.IcmpPingResponse; 4 | import org.icmp4j.logger.Logger; 5 | import org.icmp4j.IcmpPingRequest; 6 | 7 | /** 8 | * Internet Control Message Protocol for Java (ICMP4J) 9 | * http://www.icmp4j.org 10 | * Copyright 2009 and beyond, icmp4j 11 | *

12 | * This is free software; you can redistribute it and/or modify it 13 | * under the terms of the GNU Lesser General Public License version 3 14 | * as published by the Free Software Foundation as long as: 15 | * 1. You credit the original author somewhere within your product or website 16 | * 2. The credit is easily reachable and not burried deep 17 | * 3. Your end-user can easily see it 18 | * 4. You register your name (optional) and company/group/org name (required) 19 | * at http://www.icmp4j.org 20 | * 5. You do all of the above within 4 weeks of integrating this software 21 | * 6. You contribute feedback, fixes, and requests for features 22 | *

23 | * If/when you derive a commercial gain from using this software 24 | * please donate at http://www.icmp4j.org 25 | *

26 | * If prefer or require, contact the author specified above to: 27 | * 1. Release you from the above requirements 28 | * 2. Acquire a commercial license 29 | * 3. Purchase a support contract 30 | * 4. Request a different license 31 | * 5. Anything else 32 | *

33 | * This software is distributed in the hope that it will be useful, 34 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 35 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 36 | * to how this is described in the GNU Lesser General Public License. 37 | *

38 | * User: Sal Ingrilli 39 | * Date: May 23, 2014 40 | * Time: 8:59:11 PM 41 | */ 42 | public abstract class NativeBridge { 43 | 44 | // my attributes 45 | protected final Logger logger = Logger.getLogger (NativeBridge.class); 46 | 47 | /** 48 | * The NativeBridge interface 49 | * Invoked to initialize this object 50 | */ 51 | public void initialize () { 52 | 53 | } 54 | 55 | /** 56 | * The NativeBridge interface 57 | * Invoked to destroy this object 58 | */ 59 | public void destroy () { 60 | 61 | } 62 | 63 | /** 64 | * The NativeBridge interface 65 | * 66 | * Executes the given icmp ECHO request 67 | * This call blocks until a response is received or a timeout is reached 68 | * 69 | * The jna implementation adapted from: 70 | * http://hp.vector.co.jp/authors/VA033015/jnasamples.html 71 | * 72 | * @param request 73 | * @return IcmpEchoResponse 74 | */ 75 | public abstract IcmpPingResponse executePingRequest (final IcmpPingRequest request); 76 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/platform/android/AndroidNativeBridge.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.platform.android; 2 | 3 | import java.util.List; 4 | 5 | import org.icmp4j.platform.NativeBridge; 6 | import org.icmp4j.IcmpPingResponse; 7 | import org.icmp4j.IcmpPingRequest; 8 | import org.icmp4j.IcmpPingUtil; 9 | import org.icmp4j.util.ProcessUtil; 10 | import org.icmp4j.util.StringUtil; 11 | 12 | /** 13 | * icmp4j 14 | * http://www.icmp4j.org 15 | * Copyright 2009 and beyond, Sal Ingrilli at the icmp4j 16 | *

17 | * This is free software; you can redistribute it and/or modify it 18 | * under the terms of the GNU Lesser General Public License version 3 19 | * as published by the Free Software Foundation as long as: 20 | * 1. You credit the original author somewhere within your product or website 21 | * 2. The credit is easily reachable and not burried deep 22 | * 3. Your end-user can easily see it 23 | * 4. You register your name (optional) and company/group/org name (required) 24 | * at http://www.icmp4j.org 25 | * 5. You do all of the above within 4 weeks of integrating this software 26 | * 6. You contribute feedback, fixes, and requests for features 27 | *

28 | * If/when you derive a commercial gain from using this software 29 | * please donate at http://www.icmp4j.org 30 | *

31 | * If prefer or require, contact the author specified above to: 32 | * 1. Release you from the above requirements 33 | * 2. Acquire a commercial license 34 | * 3. Purchase a support contract 35 | * 4. Request a different license 36 | * 5. Anything else 37 | *

38 | * This software is distributed in the hope that it will be useful, 39 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 40 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 41 | * to how this is described in the GNU Lesser General Public License. 42 | *

43 | * User: Sal Ingrilli 44 | * Date: Dec 23, 2014 45 | * Time: 10:57:59 PM 46 | */ 47 | public class AndroidNativeBridge extends NativeBridge { 48 | 49 | /** 50 | * The NativeBridge interface 51 | * 52 | * Executes the given icmp ECHO request 53 | * This call blocks until a response is received or a timeout is reached 54 | * 55 | * @param request 56 | * @return IcmpEchoResponse 57 | */ 58 | @Override 59 | public IcmpPingResponse executePingRequest (final IcmpPingRequest request) { 60 | 61 | // handle exceptions 62 | try { 63 | 64 | // request 65 | final String host = request.getHost (); 66 | final int timeout = new Long (request.getTimeout ()).intValue (); 67 | final int timeoutAsSeconds = timeout / 1000; 68 | final int timeoutAsSeconds2 = timeoutAsSeconds > 0 ? 69 | timeoutAsSeconds : 70 | 1; 71 | final int packetSize = request.getPacketSize (); 72 | 73 | // execute the ping command 74 | final String command = "ping -c 1 -s " + packetSize + " -w " + timeoutAsSeconds2 + " " + host; 75 | final long icmpSendEchoStartTime = System.currentTimeMillis (); 76 | final List stringList = ProcessUtil.executeProcessAndGetOutputAsStringList (command); 77 | final long icmpSendEchoDuration = System.currentTimeMillis () - icmpSendEchoStartTime; 78 | 79 | // check for timeout 80 | final boolean timeoutFlag = icmpSendEchoDuration >= timeout; 81 | if (timeoutFlag) { 82 | return IcmpPingUtil.createTimeoutIcmpPingResponse (icmpSendEchoDuration); 83 | } 84 | 85 | // delegate to a method that can be unit tested 86 | return executePingRequest (stringList); 87 | } 88 | catch (final Exception e) { 89 | 90 | // propagate 91 | throw new RuntimeException (e); 92 | } 93 | } 94 | 95 | /** 96 | * Executes the given request 97 | * @param stringList 98 | * @return IcmpEchoResponse 99 | */ 100 | IcmpPingResponse executePingRequest (final List stringList) { 101 | 102 | // look for the first line with some output 103 | // sample output from DEBIAN 6 104 | // ping existing host 105 | // root@database:~# ping -c 1 -s 32 -w 5 www.google.com 106 | // PING www.google.com (74.125.224.211) 32(60) bytes of data. 107 | // 40 bytes from lax02s02-in-f19.1e100.net (74.125.224.211): icmp_req=1 ttl=56 time=47.2 ms 108 | // 109 | // ping existing host by dekker on sf.net: 110 | // ping google.com 111 | // 64 bytes from 173.194.113.207: icmp_seq=1 ttl=59 time=237 112 | // 113 | // ping existing host by sal on android: 114 | // u0_a188@afyonltetmo:/ $ping -c 1 -s 32 -w 5 www.google.com 115 | // 40 bytes from lax17s04-in-f4.1e100.net (216.58.219.36): icmp_seq=1 ttl=55 time=40.7 ms 116 | // 117 | // ping non-existing host 118 | // ping -c 1 -s 32 -w 5 www.googgle.com 119 | // ping: unknown host www.googgle.com 120 | for (final String string : stringList) { 121 | 122 | // discriminate against non-ping lines 123 | final int icmpReqIndex = string.indexOf ("icmp_req="); 124 | final int icmpSeqIndex = string.indexOf ("icmp_seq="); 125 | if (icmpReqIndex < 0 && icmpSeqIndex < 0) { 126 | continue; 127 | } 128 | 129 | // parse response 130 | int size = 0; 131 | { 132 | final int bytesIndex = string.indexOf (" bytes"); 133 | if (bytesIndex > 0) { 134 | final String sizeAsString = string.substring (0, bytesIndex); 135 | size = Integer.parseInt (sizeAsString); 136 | } 137 | } 138 | final String responseAddress = StringUtil.parseString ( 139 | string, 140 | "from ", 141 | " "); 142 | final String ttlAsString = StringUtil.parseString ( 143 | string, 144 | "ttl=", 145 | " "); 146 | final int ttl = Integer.parseInt (ttlAsString); 147 | final String rttAsString = StringUtil.parseString ( 148 | string, 149 | "time=", 150 | "ms"); 151 | final String rttAsString2 = rttAsString.trim (); 152 | final Float rttAsFloat = Float.parseFloat (rttAsString2); 153 | final int rtt = rttAsFloat.intValue (); 154 | 155 | // objectify 156 | final IcmpPingResponse response = new IcmpPingResponse (); 157 | response.setHost (responseAddress); 158 | response.setErrorMessage (null); 159 | response.setRtt (rtt); 160 | response.setSize (size); 161 | response.setSuccessFlag (true); 162 | response.setTtl (ttl); 163 | 164 | // done 165 | return response; 166 | } 167 | 168 | // not found - if there is at least one line, use that as the error message 169 | // noinspection LoopStatementThatDoesntLoop 170 | for (final String string : stringList) { 171 | 172 | // objectify 173 | final IcmpPingResponse response = new IcmpPingResponse (); 174 | response.setErrorMessage (string); 175 | response.setSuccessFlag (false); 176 | 177 | // done 178 | return response; 179 | } 180 | 181 | // no results found 182 | { 183 | // objectify 184 | final IcmpPingResponse response = new IcmpPingResponse (); 185 | response.setErrorMessage ("No results could be parsed"); 186 | response.setSuccessFlag (false); 187 | 188 | // done 189 | return response; 190 | } 191 | } 192 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/platform/java/JavaNativeBridge.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.platform.java; 2 | 3 | import java.net.InetAddress; 4 | 5 | import org.icmp4j.IcmpPingResponse; 6 | import org.icmp4j.IcmpPingRequest; 7 | import org.icmp4j.IcmpPingUtil; 8 | import org.icmp4j.platform.NativeBridge; 9 | 10 | /** 11 | * Internet Control Message Protocol for Java (ICMP4J) 12 | * http://www.icmp4j.org 13 | * Copyright 2009 and beyond, icmp4j 14 | *

15 | * This is free software; you can redistribute it and/or modify it 16 | * under the terms of the GNU Lesser General Public License version 3 17 | * as published by the Free Software Foundation as long as: 18 | * 1. You credit the original author somewhere within your product or website 19 | * 2. The credit is easily reachable and not burried deep 20 | * 3. Your end-user can easily see it 21 | * 4. You register your name (optional) and company/group/org name (required) 22 | * at http://www.icmp4j.org 23 | * 5. You do all of the above within 4 weeks of integrating this software 24 | * 6. You contribute feedback, fixes, and requests for features 25 | *

26 | * If/when you derive a commercial gain from using this software 27 | * please donate at http://www.icmp4j.org 28 | *

29 | * If prefer or require, contact the author specified above to: 30 | * 1. Release you from the above requirements 31 | * 2. Acquire a commercial license 32 | * 3. Purchase a support contract 33 | * 4. Request a different license 34 | * 5. Anything else 35 | *

36 | * This software is distributed in the hope that it will be useful, 37 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 38 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 39 | * to how this is described in the GNU Lesser General Public License. 40 | *

41 | * User: Sal Ingrilli 42 | * Date: May 23, 2014 43 | * Time: 9:03:37 PM 44 | */ 45 | public class JavaNativeBridge extends NativeBridge { 46 | 47 | /** 48 | * The NativeBridge interface 49 | * 50 | * Executes the given icmp ECHO request 51 | * This call blocks until a response is received or a timeout is reached 52 | * 53 | * The jna implementation adapted from: 54 | * http://hp.vector.co.jp/authors/VA033015/jnasamples.html 55 | * 56 | * @param request 57 | * @return IcmpEchoResponse 58 | */ 59 | @Override 60 | public IcmpPingResponse executePingRequest (final IcmpPingRequest request) { 61 | 62 | // handle exceptions 63 | try { 64 | 65 | // delegate 66 | final String host = request.getHost (); 67 | final InetAddress address = InetAddress.getByName (host); 68 | final int timeout = new Long (request.getTimeout ()).intValue (); 69 | final long pingStartNanoTime = System.nanoTime (); 70 | final long icmpSendEchoStartTime = System.currentTimeMillis (); 71 | final boolean successFlag = address.isReachable (timeout); 72 | final long icmpSendEchoDuration = System.currentTimeMillis () - icmpSendEchoStartTime; 73 | final long rttNanos = System.nanoTime () - pingStartNanoTime; 74 | final int rtt = new Long (rttNanos / (1000 * 1000)).intValue (); 75 | 76 | // check for timeout 77 | final boolean timeoutFlag = icmpSendEchoDuration >= timeout; 78 | if (timeoutFlag) { 79 | return IcmpPingUtil.createTimeoutIcmpPingResponse (icmpSendEchoDuration); 80 | } 81 | 82 | // objectify 83 | final IcmpPingResponse response = new IcmpPingResponse (); 84 | response.setHost (null); 85 | response.setErrorMessage (null); 86 | response.setRtt (rtt); 87 | response.setSize (0); 88 | response.setSuccessFlag (successFlag); 89 | response.setTtl (0); 90 | 91 | // done 92 | return response; 93 | } 94 | catch (final Exception e) { 95 | 96 | // propagate 97 | throw new RuntimeException (e); 98 | } 99 | } 100 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/platform/unix/LinuxProcessNativeBridge.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.platform.unix; 2 | 3 | import java.util.List; 4 | 5 | import org.icmp4j.IcmpPingResponse; 6 | import org.icmp4j.IcmpPingRequest; 7 | import org.icmp4j.IcmpPingUtil; 8 | import org.icmp4j.util.ProcessUtil; 9 | import org.icmp4j.util.StringUtil; 10 | import org.icmp4j.platform.NativeBridge; 11 | 12 | /** 13 | * Internet Control Message Protocol for Java (ICMP4J) 14 | * http://www.icmp4j.org 15 | * Copyright 2009 and beyond, icmp4j 16 | *

17 | * This is free software; you can redistribute it and/or modify it 18 | * under the terms of the GNU Lesser General Public License version 3 19 | * as published by the Free Software Foundation as long as: 20 | * 1. You credit the original author somewhere within your product or website 21 | * 2. The credit is easily reachable and not burried deep 22 | * 3. Your end-user can easily see it 23 | * 4. You register your name (optional) and company/group/org name (required) 24 | * at http://www.icmp4j.org 25 | * 5. You do all of the above within 4 weeks of integrating this software 26 | * 6. You contribute feedback, fixes, and requests for features 27 | *

28 | * If/when you derive a commercial gain from using this software 29 | * please donate at http://www.icmp4j.org 30 | *

31 | * If prefer or require, contact the author specified above to: 32 | * 1. Release you from the above requirements 33 | * 2. Acquire a commercial license 34 | * 3. Purchase a support contract 35 | * 4. Request a different license 36 | * 5. Anything else 37 | *

38 | * This software is distributed in the hope that it will be useful, 39 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 40 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 41 | * to how this is described in the GNU Lesser General Public License. 42 | *

43 | * User: Sal Ingrilli 44 | * Date: May 23, 2014 45 | * Time: 9:38:18 PM 46 | */ 47 | public class LinuxProcessNativeBridge extends NativeBridge { 48 | 49 | /** 50 | * The NativeBridge interface 51 | * 52 | * Executes the given icmp ECHO request 53 | * This call blocks until a response is received or a timeout is reached 54 | * 55 | * The jna implementation adapted from: 56 | * http://hp.vector.co.jp/authors/VA033015/jnasamples.html 57 | * 58 | * @param request 59 | * @return IcmpEchoResponse 60 | */ 61 | @Override 62 | public IcmpPingResponse executePingRequest (final IcmpPingRequest request) { 63 | 64 | // handle exceptions 65 | try { 66 | 67 | // request 68 | final String host = request.getHost (); 69 | final int timeout = new Long (request.getTimeout ()).intValue (); 70 | final int timeoutAsSeconds = timeout / 1000; 71 | final int timeoutAsSeconds2 = timeoutAsSeconds > 0 ? 72 | timeoutAsSeconds : 73 | 1; 74 | final int packetSize = request.getPacketSize (); 75 | 76 | // execute the ping command 77 | final String command = "ping -c 1 -s " + packetSize + " -w " + timeoutAsSeconds2 + " " + host; 78 | final long icmpSendEchoStartTime = System.currentTimeMillis (); 79 | final List stringList = ProcessUtil.executeProcessAndGetOutputAsStringList (command); 80 | final long icmpSendEchoDuration = System.currentTimeMillis () - icmpSendEchoStartTime; 81 | 82 | // check for timeout 83 | final boolean timeoutFlag = icmpSendEchoDuration >= timeout; 84 | if (timeoutFlag) { 85 | return IcmpPingUtil.createTimeoutIcmpPingResponse (icmpSendEchoDuration); 86 | } 87 | 88 | // delegate to a method that can be unit tested 89 | return executePingRequest (stringList); 90 | } 91 | catch (final Exception e) { 92 | 93 | // propagate 94 | throw new RuntimeException (e); 95 | } 96 | } 97 | 98 | /** 99 | * Executes the given request 100 | * @param stringList 101 | * @return IcmpEchoResponse 102 | */ 103 | public IcmpPingResponse executePingRequest (final List stringList) { 104 | 105 | // look for the first line with some output 106 | // sample output from DEBIAN 6 107 | // ping existing host 108 | // root@database:~# ping -c 1 -s 32 -w 5 www.google.com 109 | // PING www.google.com (74.125.224.211) 32(60) bytes of data. 110 | // 40 bytes from lax02s02-in-f19.1e100.net (74.125.224.211): icmp_req=1 ttl=56 time=47.2 ms 111 | // 112 | // ping non-existing host 113 | // ping -c 1 -s 32 -w 5 www.googgle.com 114 | // ping: unknown host www.googgle.com 115 | for (final String string : stringList) { 116 | 117 | // discriminate against non-ping lines 118 | final int icmpReqIndex = string.indexOf ("icmp_req="); 119 | final int icmpSeqIndex = string.indexOf ("icmp_seq="); 120 | if (icmpReqIndex < 0 && icmpSeqIndex < 0) { 121 | continue; 122 | } 123 | 124 | // parse response 125 | int size = 0; 126 | { 127 | final int bytesIndex = string.indexOf (" bytes"); 128 | if (bytesIndex > 0) { 129 | final String sizeAsString = string.substring (0, bytesIndex); 130 | size = Integer.parseInt (sizeAsString); 131 | } 132 | } 133 | final String responseAddress = StringUtil.parseString ( 134 | string, 135 | "from ", 136 | " "); 137 | final String ttlAsString = StringUtil.parseString ( 138 | string, 139 | "ttl=", 140 | " "); 141 | final int ttl = Integer.parseInt (ttlAsString); 142 | final String rttAsString = StringUtil.parseString ( 143 | string, 144 | "time=", 145 | "ms"); 146 | final String rttAsString2 = rttAsString.trim (); 147 | final Float rttAsFloat = Float.parseFloat (rttAsString2); 148 | final int rtt = rttAsFloat.intValue (); 149 | 150 | // objectify 151 | final IcmpPingResponse response = new IcmpPingResponse (); 152 | response.setHost (responseAddress); 153 | response.setErrorMessage (null); 154 | response.setRtt (rtt); 155 | response.setSize (size); 156 | response.setSuccessFlag (true); 157 | response.setTtl (ttl); 158 | 159 | // done 160 | return response; 161 | } 162 | 163 | // not found - if there is at least one line, use that as the error message 164 | // noinspection LoopStatementThatDoesntLoop 165 | for (final String string : stringList) { 166 | 167 | // objectify 168 | final IcmpPingResponse response = new IcmpPingResponse (); 169 | response.setErrorMessage (string); 170 | response.setSuccessFlag (false); 171 | 172 | // done 173 | return response; 174 | } 175 | 176 | // no results found 177 | { 178 | // objectify 179 | final IcmpPingResponse response = new IcmpPingResponse (); 180 | response.setErrorMessage ("No results could be parsed"); 181 | response.setSuccessFlag (false); 182 | 183 | // done 184 | return response; 185 | } 186 | } 187 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/platform/unix/MacProcessNativeBridge.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.platform.unix; 2 | 3 | import java.util.List; 4 | 5 | import org.icmp4j.IcmpPingResponse; 6 | import org.icmp4j.IcmpPingRequest; 7 | import org.icmp4j.IcmpPingUtil; 8 | import org.icmp4j.util.ProcessUtil; 9 | import org.icmp4j.util.StringUtil; 10 | import org.icmp4j.platform.NativeBridge; 11 | 12 | /** 13 | * icmp4j 14 | * http://www.icmp4j.org 15 | * Copyright 2009 and beyond, Sal Ingrilli at the icmp4j 16 | *

17 | * This is free software; you can redistribute it and/or modify it 18 | * under the terms of the GNU Lesser General Public License version 3 19 | * as published by the Free Software Foundation as long as: 20 | * 1. You credit the original author somewhere within your product or website 21 | * 2. The credit is easily reachable and not burried deep 22 | * 3. Your end-user can easily see it 23 | * 4. You register your name (optional) and company/group/org name (required) 24 | * at http://www.icmp4j.org 25 | * 5. You do all of the above within 4 weeks of integrating this software 26 | * 6. You contribute feedback, fixes, and requests for features 27 | *

28 | * If/when you derive a commercial gain from using this software 29 | * please donate at http://www.icmp4j.org 30 | *

31 | * If prefer or require, contact the author specified above to: 32 | * 1. Release you from the above requirements 33 | * 2. Acquire a commercial license 34 | * 3. Purchase a support contract 35 | * 4. Request a different license 36 | * 5. Anything else 37 | *

38 | * This software is distributed in the hope that it will be useful, 39 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 40 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 41 | * to how this is described in the GNU Lesser General Public License. 42 | *

43 | * User: Laurent Buhler 44 | * Date: Jan 08, 2015 45 | * Time: 10:51:44 PM 46 | */ 47 | public class MacProcessNativeBridge extends NativeBridge { 48 | 49 | /** 50 | * The NativeBridge interface 51 | * 52 | * Executes the given icmp ECHO request 53 | * This call blocks until a response is received or a timeout is reached 54 | * 55 | * The jna implementation adapted from: 56 | * http://hp.vector.co.jp/authors/VA033015/jnasamples.html 57 | * 58 | * @param request 59 | * @return IcmpEchoResponse 60 | */ 61 | @Override 62 | public IcmpPingResponse executePingRequest (final IcmpPingRequest request) { 63 | 64 | // handle exceptions 65 | try { 66 | 67 | // request 68 | final String host = request.getHost (); 69 | final int timeout = new Long (request.getTimeout ()).intValue (); 70 | final int timeoutAsSeconds = timeout / 1000; 71 | final int timeoutAsSeconds2 = timeoutAsSeconds > 0 ? 72 | timeoutAsSeconds : 73 | 1; 74 | final int packetSize = request.getPacketSize (); 75 | 76 | // execute the ping command 77 | final String command = "ping -c 1 -s " + packetSize + " -t " + timeoutAsSeconds2 + " " + host; 78 | final long icmpSendEchoStartTime = System.currentTimeMillis (); 79 | final List stringList = ProcessUtil.executeProcessAndGetOutputAsStringList (command); 80 | final long icmpSendEchoDuration = System.currentTimeMillis () - icmpSendEchoStartTime; 81 | 82 | // check for timeout 83 | final boolean timeoutFlag = icmpSendEchoDuration >= timeout; 84 | if (timeoutFlag) { 85 | return IcmpPingUtil.createTimeoutIcmpPingResponse (icmpSendEchoDuration); 86 | } 87 | 88 | // delegate to a method that can be unit tested 89 | return executePingRequest (stringList); 90 | } 91 | catch (final Exception e) { 92 | 93 | // propagate 94 | throw new RuntimeException (e); 95 | } 96 | } 97 | 98 | /** 99 | * Executes the given request 100 | * @param stringList 101 | * @return IcmpEchoResponse 102 | */ 103 | IcmpPingResponse executePingRequest (final List stringList) { 104 | 105 | // look for the first line with some output 106 | // sample output from DEBIAN 6 107 | // ping existing host 108 | // root@database:~# ping -c 1 -s 32 -w 5 www.google.com 109 | // PING www.google.com (74.125.224.211) 32(60) bytes of data. 110 | // 40 bytes from lax02s02-in-f19.1e100.net (74.125.224.211): icmp_req=1 ttl=56 time=47.2 ms 111 | // 112 | // ping non-existing host 113 | // ping -c 1 -s 32 -w 5 www.googgle.com 114 | // ping: unknown host www.googgle.com 115 | for (final String string : stringList) { 116 | 117 | // discriminate against non-ping lines 118 | final int icmpReqIndex = string.indexOf ("icmp_req="); 119 | final int icmpSeqIndex = string.indexOf ("icmp_seq="); 120 | if (icmpReqIndex < 0 && icmpSeqIndex < 0) { 121 | continue; 122 | } 123 | 124 | // parse response 125 | int size = 0; 126 | { 127 | final int bytesIndex = string.indexOf (" bytes"); 128 | if (bytesIndex > 0) { 129 | final String sizeAsString = string.substring (0, bytesIndex); 130 | size = Integer.parseInt (sizeAsString); 131 | } 132 | } 133 | final String responseAddress = StringUtil.parseString ( 134 | string, 135 | "from ", 136 | " "); 137 | final String ttlAsString = StringUtil.parseString ( 138 | string, 139 | "ttl=", 140 | " "); 141 | final int ttl = Integer.parseInt (ttlAsString); 142 | final String rttAsString = StringUtil.parseString ( 143 | string, 144 | "time=", 145 | "ms"); 146 | final String rttAsString2 = rttAsString.trim (); 147 | final Float rttAsFloat = Float.parseFloat (rttAsString2); 148 | final int rtt = rttAsFloat.intValue (); 149 | 150 | // objectify 151 | final IcmpPingResponse response = new IcmpPingResponse (); 152 | response.setHost (responseAddress); 153 | response.setErrorMessage (null); 154 | response.setRtt (rtt); 155 | response.setSize (size); 156 | response.setSuccessFlag (true); 157 | response.setTtl (ttl); 158 | 159 | // done 160 | return response; 161 | } 162 | 163 | // not found - if there is at least one line, use that as the error message 164 | // noinspection LoopStatementThatDoesntLoop 165 | for (final String string : stringList) { 166 | 167 | // objectify 168 | final IcmpPingResponse response = new IcmpPingResponse (); 169 | response.setErrorMessage (string); 170 | response.setSuccessFlag (false); 171 | 172 | // done 173 | return response; 174 | } 175 | 176 | // no results found 177 | { 178 | // objectify 179 | final IcmpPingResponse response = new IcmpPingResponse (); 180 | response.setErrorMessage ("No results could be parsed"); 181 | response.setSuccessFlag (false); 182 | 183 | // done 184 | return response; 185 | } 186 | } 187 | } 188 | 189 | 190 | 191 | -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/platform/unix/ProcessNativeBridgeFactory.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.platform.unix; 2 | 3 | import org.icmp4j.constants.OsFamilyCode; 4 | import org.icmp4j.platform.NativeBridge; 5 | import org.icmp4j.util.PlatformUtil; 6 | 7 | /** 8 | * icmp4j 9 | * http://www.icmp4j.org 10 | * Copyright 2009 and beyond, Sal Ingrilli at the icmp4j 11 | *

12 | * This is free software; you can redistribute it and/or modify it 13 | * under the terms of the GNU Lesser General Public License version 3 14 | * as published by the Free Software Foundation as long as: 15 | * 1. You credit the original author somewhere within your product or website 16 | * 2. The credit is easily reachable and not burried deep 17 | * 3. Your end-user can easily see it 18 | * 4. You register your name (optional) and company/group/org name (required) 19 | * at http://www.icmp4j.org 20 | * 5. You do all of the above within 4 weeks of integrating this software 21 | * 6. You contribute feedback, fixes, and requests for features 22 | *

23 | * If/when you derive a commercial gain from using this software 24 | * please donate at http://www.icmp4j.org 25 | *

26 | * If prefer or require, contact the author specified above to: 27 | * 1. Release you from the above requirements 28 | * 2. Acquire a commercial license 29 | * 3. Purchase a support contract 30 | * 4. Request a different license 31 | * 5. Anything else 32 | *

33 | * This software is distributed in the hope that it will be useful, 34 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 35 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 36 | * to how this is described in the GNU Lesser General Public License. 37 | *

38 | * User: Laurent Buhler 39 | * Date: Jan 30, 2016 40 | * Time: 10:51:44 PM 41 | */ 42 | public class ProcessNativeBridgeFactory { 43 | 44 | public static NativeBridge createNativeBridge () { 45 | 46 | final int osFamilyCode = PlatformUtil.getOsFamilyCode (); 47 | if ( osFamilyCode == OsFamilyCode.MAC ) { 48 | return new MacProcessNativeBridge (); 49 | } else { 50 | return new LinuxProcessNativeBridge (); 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/platform/unix/UnixNativeBridge.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.platform.unix; 2 | 3 | import org.icmp4j.IcmpPingRequest; 4 | import org.icmp4j.IcmpPingResponse; 5 | import org.icmp4j.exception.AssertRuntimeException; 6 | import org.icmp4j.platform.NativeBridge; 7 | import org.icmp4j.platform.unix.jna.UnixJnaNativeBridge; 8 | import org.icmp4j.platform.unix.jni.UnixJniNativeBridge; 9 | import org.icmp4j.util.ExceptionUtil; 10 | 11 | /** 12 | * icmp4j 13 | * http://www.icmp4j.org 14 | * Copyright 2009 and beyond, Sal Ingrilli at the icmp4j 15 | *

16 | * This is free software; you can redistribute it and/or modify it 17 | * under the terms of the GNU Lesser General Public License version 3 18 | * as published by the Free Software Foundation as long as: 19 | * 1. You credit the original author somewhere within your product or website 20 | * 2. The credit is easily reachable and not burried deep 21 | * 3. Your end-user can easily see it 22 | * 4. You register your name (optional) and company/group/org name (required) 23 | * at http://www.icmp4j.org 24 | * 5. You do all of the above within 4 weeks of integrating this software 25 | * 6. You contribute feedback, fixes, and requests for features 26 | *

27 | * If/when you derive a commercial gain from using this software 28 | * please donate at http://www.icmp4j.org 29 | *

30 | * If prefer or require, contact the author specified above to: 31 | * 1. Release you from the above requirements 32 | * 2. Acquire a commercial license 33 | * 3. Purchase a support contract 34 | * 4. Request a different license 35 | * 5. Anything else 36 | *

37 | * This software is distributed in the hope that it will be useful, 38 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 39 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 40 | * to how this is described in the GNU Lesser General Public License. 41 | *

42 | * User: Laurent Buhler 43 | * Date: Jan 30, 2016 44 | * Time: 10:51:44 PM 45 | */ 46 | 47 | public class UnixNativeBridge extends NativeBridge { 48 | 49 | // my attributes 50 | private NativeBridge nativeBridge; 51 | 52 | /** 53 | * The NativeBridge interface 54 | * Invoked to initialize this object 55 | */ 56 | @Override 57 | public void initialize () { 58 | 59 | // helpers 60 | logger.debug ("initialize ()"); 61 | 62 | // try JNI 63 | try { 64 | 65 | logger.debug ("trying delegate UnixJniNativeBridge"); 66 | final NativeBridge nativeBridge = new UnixJniNativeBridge (); 67 | nativeBridge.initialize (); 68 | this.nativeBridge = nativeBridge; 69 | return; 70 | } 71 | catch (final Throwable t) { 72 | 73 | // log 74 | logger.warn ("delegate UnixJniNativeBridge not avilable: " + ExceptionUtil.getMessage (t)); 75 | } 76 | 77 | // try JNA 78 | try { 79 | 80 | logger.debug ("trying delegate UnixJnaNativeBridge"); 81 | final NativeBridge nativeBridge = new UnixJnaNativeBridge (); 82 | nativeBridge.initialize (); 83 | this.nativeBridge = nativeBridge; 84 | return; 85 | } 86 | catch (final Throwable t) { 87 | 88 | // log 89 | logger.warn ("delegate UnixJnaNativeBridge not avilable: " + ExceptionUtil.getMessage (t)); 90 | } 91 | 92 | // fallback to the process execution 93 | // as of build 1019, this initialization should ALWAYS work because nothing happens in their initialize () 94 | try { 95 | 96 | logger.debug ("trying delegate *ProcessNativeBridge"); 97 | final NativeBridge nativeBridge = ProcessNativeBridgeFactory.createNativeBridge (); 98 | nativeBridge.initialize (); 99 | this.nativeBridge = nativeBridge; 100 | return; 101 | } 102 | catch (final Throwable t) { 103 | 104 | // log 105 | logger.warn ("delegate *ProcessNativeBridge not avilable: " + ExceptionUtil.getMessage (t)); 106 | } 107 | 108 | // all failed - this should not happen because the *ProcessNativeBridge should always work 109 | throw new AssertRuntimeException ("all delegates failed"); 110 | } 111 | 112 | /** 113 | * The NativeBridge interface 114 | * 115 | * Executes the given icmp ECHO request 116 | * This call blocks until a response is received or a timeout is reached 117 | * 118 | * The jna implementation adapted from: 119 | * http://hp.vector.co.jp/authors/VA033015/jnasamples.html 120 | * 121 | * @param request 122 | * @return IcmpEchoResponse 123 | */ 124 | @Override 125 | public IcmpPingResponse executePingRequest(IcmpPingRequest request) { 126 | 127 | // delegate 128 | return nativeBridge.executePingRequest(request); 129 | } 130 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/platform/unix/jna/IcmpLibrary.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.platform.unix.jna; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | import com.sun.jna.Library; 7 | import com.sun.jna.NativeLong; 8 | import com.sun.jna.Pointer; 9 | import com.sun.jna.Structure; 10 | import com.sun.jna.ptr.PointerByReference; 11 | 12 | public interface IcmpLibrary extends Library { 13 | 14 | public void icmp4j_exist(PointerByReference val); 15 | public void icmp4j_exist_free(Pointer p); 16 | 17 | public static class Icmp4jStruct extends Structure { 18 | public static class ByReference extends Icmp4jStruct implements Structure.ByReference {} 19 | 20 | public String host; 21 | public int ttl; 22 | public int packetSize; 23 | public NativeLong timeOut; 24 | 25 | public int retCode; 26 | public int hasTimeout; 27 | public int bytes; 28 | public int returnTtl; 29 | public int rtt; 30 | public String address; 31 | public String errorMsg; 32 | public int errno; 33 | 34 | @Override 35 | protected List getFieldOrder() { 36 | return Arrays.asList (new String[] {"host", "ttl", "packetSize", "timeOut", "retCode", "hasTimeout", 37 | "bytes", "returnTtl", "rtt", "address", "errorMsg", "errno"}); 38 | } 39 | } 40 | public void icmp4j_start(Icmp4jStruct.ByReference sval); 41 | public void icmp4j_free(Icmp4jStruct.ByReference sval); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/platform/unix/jna/LibraryUtil.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.platform.unix.jna; 2 | 3 | 4 | import org.icmp4j.util.JnaUtil; 5 | 6 | public class LibraryUtil { 7 | // my attributes 8 | private static IcmpLibrary icmpLibrary; 9 | 10 | public static IcmpLibrary getIcmpLibrary () { return icmpLibrary; } 11 | 12 | /** 13 | * Uniformly initializes this object 14 | * This is in an explicit method and NOT a static initializer so that the caller gets the full stack trace 15 | */ 16 | public static void initialize () { 17 | 18 | // delegate 19 | if (icmpLibrary == null) { 20 | icmpLibrary = (IcmpLibrary) JnaUtil.loadLibraryBestEffort( 21 | "icmp4jJNA", 22 | IcmpLibrary.class); 23 | } 24 | if (icmpLibrary == null) { 25 | throw new UnsatisfiedLinkError("unnable to find icmp4jJNA"); 26 | } 27 | } 28 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/platform/unix/jna/UnixJnaNativeBridge.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.platform.unix.jna; 2 | 3 | import org.icmp4j.Icmp4jUtil; 4 | import org.icmp4j.IcmpPingRequest; 5 | import org.icmp4j.IcmpPingResponse; 6 | import org.icmp4j.platform.NativeBridge; 7 | 8 | import com.sun.jna.NativeLong; 9 | import com.sun.jna.Pointer; 10 | import com.sun.jna.ptr.PointerByReference; 11 | 12 | /** 13 | * Internet Control Message Protocol for Java (ICMP4J) 14 | * http://www.icmp4j.org 15 | * Copyright 2009 and beyond, icmp4j 16 | *

17 | * This is free software; you can redistribute it and/or modify it 18 | * under the terms of the GNU Lesser General Public License version 3 19 | * as published by the Free Software Foundation as long as: 20 | * 1. You credit the original author somewhere within your product or website 21 | * 2. The credit is easily reachable and not burried deep 22 | * 3. Your end-user can easily see it 23 | * 4. You register your name (optional) and company/group/org name (required) 24 | * at http://www.icmp4j.org 25 | * 5. You do all of the above within 4 weeks of integrating this software 26 | * 6. You contribute feedback, fixes, and requests for features 27 | *

28 | * If/when you derive a commercial gain from using this software 29 | * please donate at http://www.icmp4j.org 30 | *

31 | * If prefer or require, contact the author specified above to: 32 | * 1. Release you from the above requirements 33 | * 2. Acquire a commercial license 34 | * 3. Purchase a support contract 35 | * 4. Request a different license 36 | * 5. Anything else 37 | *

38 | * This software is distributed in the hope that it will be useful, 39 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 40 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 41 | * to how this is described in the GNU Lesser General Public License. 42 | *

43 | * User: Laurent Buhler 44 | * Date: Jan 08, 2015 45 | * Time: 8:59:11 PM 46 | */ 47 | public class UnixJnaNativeBridge extends NativeBridge { 48 | 49 | /** 50 | * The NativeBridge interface 51 | * Invoked to initialize this object 52 | */ 53 | @Override 54 | public void initialize () { 55 | 56 | // delegate 57 | LibraryUtil.initialize (); 58 | final IcmpLibrary icmpLibrary = LibraryUtil.getIcmpLibrary (); 59 | 60 | PointerByReference ptrRef = new PointerByReference (); 61 | icmpLibrary.icmp4j_exist (ptrRef); 62 | Pointer p = ptrRef.getValue (); 63 | String version = p.getString (0); 64 | logger.info ("using icmp4jJNA v " + version); 65 | icmpLibrary.icmp4j_exist_free (p); 66 | } 67 | 68 | 69 | @Override 70 | public IcmpPingResponse executePingRequest(IcmpPingRequest request) { 71 | 72 | final IcmpLibrary icmpLibrary = LibraryUtil.getIcmpLibrary (); 73 | 74 | IcmpLibrary.Icmp4jStruct.ByReference ref = new IcmpLibrary.Icmp4jStruct.ByReference (); 75 | ref.host = request.getHost (); 76 | ref.ttl = request.getTtl (); 77 | ref.packetSize = request.getPacketSize (); 78 | ref.timeOut = new NativeLong (request.getTimeout ()); 79 | 80 | final long icmpSendEchoStartNanoTime = System.nanoTime (); 81 | 82 | final IcmpPingResponse response = new IcmpPingResponse (); 83 | 84 | icmpLibrary.icmp4j_start (ref); 85 | 86 | final long icmpSendEchoNanoDuration = System.nanoTime () - icmpSendEchoStartNanoTime; 87 | final long icmpSendEchoDuration = icmpSendEchoNanoDuration / 1000 / 1000; 88 | 89 | response.setSuccessFlag ( ref.retCode == 1 ); 90 | response.setTimeoutFlag ( ref.hasTimeout == 1 ); 91 | response.setErrorMessage ( ref.errorMsg ); 92 | response.setHost ( ref.address ); 93 | response.setSize ( ref.bytes ); 94 | response.setRtt ( ref.rtt ); 95 | response.setTtl ( ref.ttl ); 96 | icmpLibrary.icmp4j_free ( ref ); 97 | 98 | response.setDuration ( icmpSendEchoDuration ); 99 | return response; 100 | } 101 | 102 | } 103 | -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/platform/unix/jni/Icmp4jJNI.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.platform.unix.jni; 2 | 3 | /** 4 | * icmp4j 5 | * http://www.icmp4j.org 6 | * Copyright 2009 and beyond, Sal Ingrilli at the icmp4j 7 | *

8 | * This is free software; you can redistribute it and/or modify it 9 | * under the terms of the GNU Lesser General Public License version 3 10 | * as published by the Free Software Foundation as long as: 11 | * 1. You credit the original author somewhere within your product or website 12 | * 2. The credit is easily reachable and not burried deep 13 | * 3. Your end-user can easily see it 14 | * 4. You register your name (optional) and company/group/org name (required) 15 | * at http://www.icmp4j.org 16 | * 5. You do all of the above within 4 weeks of integrating this software 17 | * 6. You contribute feedback, fixes, and requests for features 18 | *

19 | * If/when you derive a commercial gain from using this software 20 | * please donate at http://www.icmp4j.org 21 | *

22 | * If prefer or require, contact the author specified above to: 23 | * 1. Release you from the above requirements 24 | * 2. Acquire a commercial license 25 | * 3. Purchase a support contract 26 | * 4. Request a different license 27 | * 5. Anything else 28 | *

29 | * This software is distributed in the hope that it will be useful, 30 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 31 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 32 | * to how this is described in the GNU Lesser General Public License. 33 | *

34 | * User: Laurent Buhler 35 | * Date: Jan 08, 2015 36 | * Time: 10:51:44 PM 37 | */ 38 | public class Icmp4jJNI { 39 | public String host; 40 | public int ttl; 41 | public int packetSize; 42 | public long timeOut; 43 | public int retCode; 44 | public int hasTimeout; 45 | public int bytes; 46 | public int returnTtl; 47 | public int rtt; 48 | public String address; 49 | public String errorMsg; 50 | public int errno; 51 | 52 | public native void icmp_start (); 53 | 54 | public native String icmp_test (); 55 | 56 | // Test Driver 57 | public static void main (String args[]) { 58 | Icmp4jJNI test = new Icmp4jJNI (); 59 | test.host = "google.com"; 60 | test.ttl = 50; 61 | test.packetSize = 64; 62 | test.timeOut = 9876; 63 | test.icmp_start (); 64 | System.out.println ("retCode: " + test.retCode); 65 | System.out.println ("errorMsg: " + test.errorMsg); 66 | System.out.println ("ttl: " + test.returnTtl); 67 | System.out.println ("rtt: " + test.rtt); 68 | System.out.println ("bytes: " + test.bytes); 69 | System.out.println ("address is: " + test.address); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/platform/unix/jni/UnixJniNativeBridge.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.platform.unix.jni; 2 | 3 | import org.icmp4j.IcmpPingRequest; 4 | import org.icmp4j.IcmpPingResponse; 5 | import org.icmp4j.platform.NativeBridge; 6 | import org.icmp4j.util.JniUtil; 7 | 8 | 9 | 10 | /** 11 | * icmp4j 12 | * http://www.icmp4j.org 13 | * Copyright 2009 and beyond, Sal Ingrilli at the icmp4j 14 | *

15 | * This is free software; you can redistribute it and/or modify it 16 | * under the terms of the GNU Lesser General Public License version 3 17 | * as published by the Free Software Foundation as long as: 18 | * 1. You credit the original author somewhere within your product or website 19 | * 2. The credit is easily reachable and not burried deep 20 | * 3. Your end-user can easily see it 21 | * 4. You register your name (optional) and company/group/org name (required) 22 | * at http://www.icmp4j.org 23 | * 5. You do all of the above within 4 weeks of integrating this software 24 | * 6. You contribute feedback, fixes, and requests for features 25 | *

26 | * If/when you derive a commercial gain from using this software 27 | * please donate at http://www.icmp4j.org 28 | *

29 | * If prefer or require, contact the author specified above to: 30 | * 1. Release you from the above requirements 31 | * 2. Acquire a commercial license 32 | * 3. Purchase a support contract 33 | * 4. Request a different license 34 | * 5. Anything else 35 | *

36 | * This software is distributed in the hope that it will be useful, 37 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 38 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 39 | * to how this is described in the GNU Lesser General Public License. 40 | *

41 | * User: Laurent Buhler 42 | * Date: Jan 08, 2015 43 | * Time: 10:51:44 PM 44 | */ 45 | public class UnixJniNativeBridge extends NativeBridge { 46 | 47 | /** 48 | * The NativeBridge interface 49 | * Invoked to initialize this object 50 | */ 51 | @Override 52 | public void initialize () { 53 | JniUtil.loadLibraryBestEffort ("icmp4jJNI"); 54 | final Icmp4jJNI jniRequest = new Icmp4jJNI (); 55 | String version = jniRequest.icmp_test (); 56 | logger.info ("using icmp4jJNI v " + version ); 57 | } 58 | 59 | 60 | @Override 61 | public IcmpPingResponse executePingRequest (IcmpPingRequest request) { 62 | final IcmpPingResponse response = new IcmpPingResponse (); 63 | final Icmp4jJNI jniRequest = new Icmp4jJNI (); 64 | jniRequest.host = request.getHost (); 65 | jniRequest.ttl = request.getTtl (); 66 | jniRequest.packetSize = request.getPacketSize (); 67 | jniRequest.timeOut = (int) request.getTimeout (); 68 | 69 | final long icmpSendEchoStartNanoTime = System.nanoTime (); 70 | 71 | jniRequest.icmp_start (); 72 | 73 | final long icmpSendEchoNanoDuration = System.nanoTime () - icmpSendEchoStartNanoTime; 74 | final long icmpSendEchoDuration = icmpSendEchoNanoDuration / 1000 / 1000; 75 | 76 | response.setDuration (icmpSendEchoDuration); 77 | response.setSuccessFlag (jniRequest.retCode == 1); 78 | response.setTimeoutFlag (jniRequest.hasTimeout == 1); 79 | response.setErrorMessage (jniRequest.errorMsg); 80 | response.setHost (jniRequest.address); 81 | response.setSize (jniRequest.bytes); 82 | response.setRtt (jniRequest.rtt); 83 | response.setTtl (jniRequest.ttl); 84 | return response; 85 | } 86 | 87 | } 88 | -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/platform/windows/WindowsNativeBridge.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.platform.windows; 2 | 3 | import java.net.InetAddress; 4 | 5 | import org.icmp4j.IcmpPingResponse; 6 | import org.icmp4j.IcmpPingRequest; 7 | import org.icmp4j.IcmpPingUtil; 8 | import org.icmp4j.platform.NativeBridge; 9 | import org.icmp4j.platform.windows.jna.Winsock2Library; 10 | import org.icmp4j.platform.windows.jna.LibraryUtil; 11 | import org.icmp4j.platform.windows.jna.IcmpLibrary; 12 | 13 | import com.sun.jna.Pointer; 14 | import com.sun.jna.Memory; 15 | import com.sun.jna.platform.win32.Kernel32; 16 | 17 | /** 18 | * Internet Control Message Protocol for Java (ICMP4J) 19 | * http://www.icmp4j.org 20 | * Copyright 2009 and beyond, icmp4j 21 | *

22 | * This is free software; you can redistribute it and/or modify it 23 | * under the terms of the GNU Lesser General Public License version 3 24 | * as published by the Free Software Foundation as long as: 25 | * 1. You credit the original author somewhere within your product or website 26 | * 2. The credit is easily reachable and not burried deep 27 | * 3. Your end-user can easily see it 28 | * 4. You register your name (optional) and company/group/org name (required) 29 | * at http://www.icmp4j.org 30 | * 5. You do all of the above within 4 weeks of integrating this software 31 | * 6. You contribute feedback, fixes, and requests for features 32 | *

33 | * If/when you derive a commercial gain from using this software 34 | * please donate at http://www.icmp4j.org 35 | *

36 | * If prefer or require, contact the author specified above to: 37 | * 1. Release you from the above requirements 38 | * 2. Acquire a commercial license 39 | * 3. Purchase a support contract 40 | * 4. Request a different license 41 | * 5. Anything else 42 | *

43 | * This software is distributed in the hope that it will be useful, 44 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 45 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 46 | * to how this is described in the GNU Lesser General Public License. 47 | *

48 | * User: Sal Ingrilli 49 | * Date: May 23, 2014 50 | * Time: 9:00:08 PM 51 | */ 52 | public class WindowsNativeBridge extends NativeBridge { 53 | 54 | /** 55 | * The NativeBridge interface 56 | * Invoked to initialize this object 57 | */ 58 | @Override 59 | public void initialize () { 60 | 61 | // delegate 62 | LibraryUtil.initialize (); 63 | 64 | // initialize winsock2 65 | final Winsock2Library winsock2Library = LibraryUtil.getWinsock2Library (); 66 | final Winsock2Library.WSAData wsadata = new Winsock2Library.WSAData (); 67 | if (winsock2Library.WSAStartup ((short) 2, wsadata) != 0 ){ 68 | throw new RuntimeException ("WSAStartup failed"); 69 | } 70 | } 71 | 72 | /** 73 | * The NativeBridge interface 74 | * Invoked to destroy this object 75 | */ 76 | @Override 77 | public void destroy () { 78 | 79 | // destroy winsock2 80 | final Winsock2Library winsock2Library = LibraryUtil.getWinsock2Library (); 81 | if (winsock2Library != null) { 82 | winsock2Library.WSACleanup (); 83 | } 84 | } 85 | 86 | /** 87 | * The NativeBridge interface 88 | * 89 | * Executes the given icmp ECHO request 90 | * This call blocks until a response is received or a timeout is reached 91 | * 92 | * The jna implementation adapted from: 93 | * http://hp.vector.co.jp/authors/VA033015/jnasamples.html 94 | * 95 | * WARNING: this method is synchronized because if multiple threads call 96 | * IcmpLibrary.IcmpSendEcho (), then the results are corrupted!!! 97 | * So for now we have no choice other than figure out how to call IcmpSendEcho2, 98 | * or call ping.exe 99 | * 100 | * @param request 101 | * @return IcmpEchoResponse 102 | */ 103 | @Override 104 | public synchronized IcmpPingResponse executePingRequest (final IcmpPingRequest request) { 105 | 106 | // helpers 107 | final IcmpLibrary icmpLibrary = LibraryUtil.getIcmpLibrary (); 108 | final String host = request.getHost (); 109 | final int ttl = request.getTtl (); 110 | final int size = request.getPacketSize (); 111 | final int timeout = new Long (request.getTimeout ()).intValue (); 112 | 113 | // handle exceptions 114 | Pointer hIcmp = null; 115 | try { 116 | 117 | // request 118 | final InetAddress address = InetAddress.getByName (host); 119 | final byte[] ipAddressAsByteArray = address.getAddress (); 120 | 121 | final IcmpLibrary.IpAddrByVal ipaddr = new IcmpLibrary.IpAddrByVal (); 122 | ipaddr.bytes = ipAddressAsByteArray; 123 | 124 | final int replyDataSize = size + (new IcmpLibrary.IcmpEchoReply ().size ()); 125 | final Pointer sendData = new Memory (size); 126 | final Pointer replyData = new Memory (replyDataSize); 127 | final IcmpLibrary.IpOptionInformationByRef ipOption = new IcmpLibrary.IpOptionInformationByRef (); 128 | ipOption.ttl = (byte) ttl; 129 | ipOption.tos = (byte) 0; 130 | ipOption.flags = (byte) 0; 131 | ipOption.optionsSize = (byte) 0; 132 | ipOption.optionsData = null; 133 | 134 | // delegate 135 | hIcmp = icmpLibrary.IcmpCreateFile (); 136 | final long icmpSendEchoStartNanoTime = System.nanoTime (); 137 | final int returnCode = icmpLibrary.IcmpSendEcho ( 138 | hIcmp, 139 | ipaddr, 140 | sendData, 141 | (short) size, 142 | ipOption, 143 | replyData, 144 | replyDataSize, 145 | timeout); 146 | final long icmpSendEchoNanoDuration = System.nanoTime () - icmpSendEchoStartNanoTime; 147 | final long icmpSendEchoDuration = icmpSendEchoNanoDuration / 1000 / 1000; 148 | 149 | // immediately check for timeout - whether the IcmpSendEcho call returns 0 or something else, 150 | // a last error of 11010 means that the call timed out, so return a proper response to indicate 151 | // that the call timed out 152 | final int lastError = Kernel32.INSTANCE.GetLastError (); 153 | if (lastError == 11010) { 154 | return IcmpPingUtil.createTimeoutIcmpPingResponse (icmpSendEchoDuration); 155 | } 156 | 157 | // check for failure 158 | if (returnCode == 0) { 159 | 160 | // call failed 161 | final String errorMessage = "Last error: " + lastError; 162 | 163 | // objectify 164 | final IcmpPingResponse response = new IcmpPingResponse (); 165 | response.setErrorMessage (errorMessage); 166 | response.setSuccessFlag (false); 167 | 168 | // done 169 | return response; 170 | } 171 | 172 | // the operation worked: check for success 173 | final IcmpLibrary.IcmpEchoReply icmpEchoReply = new IcmpLibrary.IcmpEchoReply (replyData); 174 | final boolean successFlag = icmpEchoReply.status == 0; 175 | final String responseAddress = String.format ("%d.%d.%d.%d", 176 | icmpEchoReply.address.bytes[0] & 0xff, 177 | icmpEchoReply.address.bytes[1] & 0xff, 178 | icmpEchoReply.address.bytes[2] & 0xff, 179 | icmpEchoReply.address.bytes[3] & 0xff 180 | ); 181 | final String message = getStatusText (icmpEchoReply.status); 182 | 183 | // objectify 184 | final IcmpPingResponse response = new IcmpPingResponse (); 185 | response.setDuration (icmpSendEchoDuration); 186 | response.setHost (responseAddress); 187 | response.setErrorMessage (message); 188 | response.setRtt (icmpEchoReply.roundTripTime); 189 | response.setSize (icmpEchoReply.dataSize); 190 | response.setSuccessFlag (successFlag); 191 | response.setTtl (icmpEchoReply.options.ttl & 0xff); 192 | 193 | // done 194 | return response; 195 | } 196 | catch (final Exception e) { 197 | 198 | // propagate 199 | throw new RuntimeException (e); 200 | } 201 | finally { 202 | 203 | // cleanup 204 | if (hIcmp != null) { 205 | icmpLibrary.IcmpCloseHandle (hIcmp); 206 | } 207 | } 208 | } 209 | 210 | /** 211 | * Returns the text for the given status 212 | * @param status 213 | * @return String 214 | */ 215 | private static String getStatusText (final int status) { 216 | switch (status){ 217 | case 0 : return "SUCCESS"; 218 | case 11000 : return "IP_SUCCESS"; 219 | case 11001 : return "IP_BUF_TOO_SMALL"; 220 | case 11002 : return "IP_DEST_NET_UNREACHABLE"; 221 | case 11003 : return "IP_DEST_HOST_UNREACHABLE"; 222 | case 11004 : return "IP_DEST_PROT_UNREACHABLE"; 223 | case 11005 : return "IP_DEST_PORT_UNREACHABLE"; 224 | case 11006 : return "IP_NO_RESOURCES"; 225 | case 11007 : return "IP_BAD_OPTION"; 226 | case 11008 : return "IP_HW_ERROR"; 227 | case 11009 : return "IP_PACKET_TOO_BIG"; 228 | case 11010 : return "IP_REQ_TIMED_OUT"; 229 | case 11011 : return "IP_BAD_REQ"; 230 | case 11012 : return "IP_BAD_ROUTE"; 231 | case 11013 : return "IP_TTL_EXPIRED_TRANSIT"; 232 | case 11014 : return "IP_TTL_EXPIRED_REASSEM"; 233 | case 11015 : return "IP_PARAM_PROBLEM"; 234 | case 11016 : return "IP_SOURCE_QUENCH"; 235 | case 11017 : return "IP_OPTION_TOO_BIG"; 236 | case 11018 : return "IP_BAD_DESTINATION"; 237 | case 11050 : return "IP_GENERAL_FAILURE"; 238 | } 239 | return "UNKNOWN_STATUS"; 240 | } 241 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/platform/windows/jna/IcmpLibrary.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.platform.windows.jna; 2 | 3 | import java.util.Arrays; 4 | import java.util.List; 5 | 6 | import com.sun.jna.Library; 7 | import com.sun.jna.Structure; 8 | import com.sun.jna.Structure.ByValue; 9 | import com.sun.jna.Structure.ByReference; 10 | import com.sun.jna.Pointer; 11 | 12 | /** 13 | * Internet Control Message Protocol for Java (ICMP4J) 14 | * http://www.icmp4j.org 15 | * Copyright 2009 and beyond, icmp4j 16 | *

17 | * This is free software; you can redistribute it and/or modify it 18 | * under the terms of the GNU Lesser General Public License version 3 19 | * as published by the Free Software Foundation as long as: 20 | * 1. You credit the original author somewhere within your product or website 21 | * 2. The credit is easily reachable and not burried deep 22 | * 3. Your end-user can easily see it 23 | * 4. You register your name (optional) and company/group/org name (required) 24 | * at http://www.icmp4j.org 25 | * 5. You do all of the above within 4 weeks of integrating this software 26 | * 6. You contribute feedback, fixes, and requests for features 27 | *

28 | * If/when you derive a commercial gain from using this software 29 | * please donate at http://www.icmp4j.org 30 | *

31 | * If prefer or require, contact the author specified above to: 32 | * 1. Release you from the above requirements 33 | * 2. Acquire a commercial license 34 | * 3. Purchase a support contract 35 | * 4. Request a different license 36 | * 5. Anything else 37 | *

38 | * This software is distributed in the hope that it will be useful, 39 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 40 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 41 | * to how this is described in the GNU Lesser General Public License. 42 | *

43 | * User: Sal Ingrilli 44 | * Date: May 23, 2014 45 | * Time: 6:02:09 PM 46 | */ 47 | public interface IcmpLibrary extends Library { 48 | 49 | /** 50 | * 51 | */ 52 | public static class IpAddr extends Structure { 53 | 54 | public byte[] bytes = new byte[4]; 55 | 56 | @Override 57 | protected List getFieldOrder() { 58 | return Arrays.asList (new String[] {"bytes"}); 59 | } 60 | } 61 | 62 | /** 63 | * 64 | */ 65 | public static class IpAddrByVal extends IpAddr implements ByValue { 66 | 67 | @Override 68 | protected List getFieldOrder() { 69 | return Arrays.asList (new String[] {"bytes"}); 70 | } 71 | } 72 | 73 | /** 74 | * 75 | */ 76 | public static class IpOptionInformation extends Structure { 77 | public byte ttl; 78 | public byte tos; 79 | public byte flags; 80 | public byte optionsSize; 81 | public Pointer optionsData; 82 | 83 | @Override 84 | protected List getFieldOrder() { 85 | return Arrays.asList (new String[] {"ttl", "tos", "flags", "optionsSize", "optionsData"}); 86 | } 87 | } 88 | 89 | /** 90 | * 91 | */ 92 | public static class IpOptionInformationByVal 93 | extends IpOptionInformation implements ByValue { 94 | } 95 | 96 | /** 97 | * 98 | */ 99 | public static class IpOptionInformationByRef 100 | extends IpOptionInformation implements ByReference { 101 | } 102 | 103 | /** 104 | * 105 | */ 106 | public static class IcmpEchoReply extends Structure { 107 | public IpAddrByVal address; 108 | public int status; 109 | public int roundTripTime; 110 | public short dataSize; 111 | public short reserved; 112 | public Pointer data; 113 | public IpOptionInformationByVal options; 114 | 115 | public IcmpEchoReply(){ 116 | } 117 | 118 | public IcmpEchoReply(Pointer p){ 119 | useMemory(p); 120 | read(); 121 | } 122 | 123 | @Override 124 | protected List getFieldOrder() { 125 | return Arrays.asList (new String[] {"address", "status", "roundTripTime", "dataSize", "reserved", "data", "options"}); 126 | } 127 | } 128 | 129 | public Pointer IcmpCreateFile(); 130 | 131 | public boolean IcmpCloseHandle(Pointer hIcmp); 132 | 133 | public int IcmpSendEcho( 134 | Pointer hIcmp, 135 | IpAddrByVal destinationAddress, 136 | Pointer requestData, 137 | short requestSize, 138 | IpOptionInformationByRef requestOptions, 139 | Pointer replyBuffer, 140 | int replySize, 141 | int timeout 142 | ); 143 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/platform/windows/jna/LibraryUtil.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.platform.windows.jna; 2 | 3 | import org.icmp4j.util.JnaUtil; 4 | 5 | /** 6 | * Internet Control Message Protocol for Java (ICMP4J) 7 | * http://www.icmp4j.org 8 | * Copyright 2009 and beyond, icmp4j 9 | *

10 | * This is free software; you can redistribute it and/or modify it 11 | * under the terms of the GNU Lesser General Public License version 3 12 | * as published by the Free Software Foundation as long as: 13 | * 1. You credit the original author somewhere within your product or website 14 | * 2. The credit is easily reachable and not burried deep 15 | * 3. Your end-user can easily see it 16 | * 4. You register your name (optional) and company/group/org name (required) 17 | * at http://www.icmp4j.org 18 | * 5. You do all of the above within 4 weeks of integrating this software 19 | * 6. You contribute feedback, fixes, and requests for features 20 | *

21 | * If/when you derive a commercial gain from using this software 22 | * please donate at http://www.icmp4j.org 23 | *

24 | * If prefer or require, contact the author specified above to: 25 | * 1. Release you from the above requirements 26 | * 2. Acquire a commercial license 27 | * 3. Purchase a support contract 28 | * 4. Request a different license 29 | * 5. Anything else 30 | *

31 | * This software is distributed in the hope that it will be useful, 32 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 33 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 34 | * to how this is described in the GNU Lesser General Public License. 35 | *

36 | * User: Sal Ingrilli 37 | * Date: May 23, 2014 38 | * Time: 6:44:08 PM 39 | */ 40 | public class LibraryUtil { 41 | 42 | // my attributes 43 | private static IcmpLibrary icmpLibrary; 44 | private static Winsock2Library winsock2Library; 45 | 46 | // my attributes 47 | public static IcmpLibrary getIcmpLibrary () { return icmpLibrary; } 48 | public static Winsock2Library getWinsock2Library () { return winsock2Library; } 49 | 50 | /** 51 | * Uniformly initializes this object 52 | * This is in an explicit method and NOT a static initializer so that the caller gets the full stack trace 53 | */ 54 | public static void initialize () { 55 | 56 | // delegate 57 | if (icmpLibrary == null) { 58 | icmpLibrary = (IcmpLibrary) JnaUtil.loadLibrary ( 59 | "icmp", 60 | IcmpLibrary.class); 61 | } 62 | 63 | // delegate 64 | if (winsock2Library == null) { 65 | winsock2Library = (Winsock2Library) JnaUtil.loadLibrary ( 66 | "ws2_32", 67 | Winsock2Library.class); 68 | } 69 | } 70 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/platform/windows/jna/Winsock2Library.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.platform.windows.jna; 2 | 3 | import java.util.List; 4 | import java.util.Arrays; 5 | 6 | import com.sun.jna.Library; 7 | import com.sun.jna.Structure; 8 | import com.sun.jna.Pointer; 9 | 10 | /** 11 | * Internet Control Message Protocol for Java (ICMP4J) 12 | * http://www.icmp4j.org 13 | * Copyright 2009 and beyond, icmp4j 14 | *

15 | * This is free software; you can redistribute it and/or modify it 16 | * under the terms of the GNU Lesser General Public License version 3 17 | * as published by the Free Software Foundation as long as: 18 | * 1. You credit the original author somewhere within your product or website 19 | * 2. The credit is easily reachable and not burried deep 20 | * 3. Your end-user can easily see it 21 | * 4. You register your name (optional) and company/group/org name (required) 22 | * at http://www.icmp4j.org 23 | * 5. You do all of the above within 4 weeks of integrating this software 24 | * 6. You contribute feedback, fixes, and requests for features 25 | *

26 | * If/when you derive a commercial gain from using this software 27 | * please donate at http://www.icmp4j.org 28 | *

29 | * If prefer or require, contact the author specified above to: 30 | * 1. Release you from the above requirements 31 | * 2. Acquire a commercial license 32 | * 3. Purchase a support contract 33 | * 4. Request a different license 34 | * 5. Anything else 35 | *

36 | * This software is distributed in the hope that it will be useful, 37 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 38 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 39 | * to how this is described in the GNU Lesser General Public License. 40 | *

41 | * User: Sal Ingrilli 42 | * Date: May 23, 2014 43 | * Time: 6:14:50 PM 44 | */ 45 | public interface Winsock2Library extends Library { 46 | 47 | public static class WSAData extends Structure { 48 | public short version; 49 | public short highVersion; 50 | public byte[] description = new byte[256+1]; 51 | public byte[] systemStatus = new byte[256+1]; 52 | public short maxSockets; 53 | public short maxUdpDg; 54 | public Pointer vendorInfo; 55 | 56 | @Override 57 | protected List getFieldOrder() { 58 | return Arrays.asList (new String[] {"version", "highVersion", "description", "systemStatus", "maxSockets", "maxUdpDg", "vendorInfo"}); 59 | } 60 | } 61 | 62 | public static class Hostent extends Structure { 63 | public Pointer name; 64 | public Pointer aliases; 65 | public short addrType; 66 | public short length; 67 | public Pointer addressList; 68 | 69 | @Override 70 | protected List getFieldOrder() { 71 | return Arrays.asList (new String[] {"name", "aliases", "addrType", "length", "addressList"}); 72 | } 73 | } 74 | 75 | int WSAStartup(short versionRequested, WSAData wsadata); 76 | 77 | int WSACleanup(); 78 | 79 | Hostent gethostbyname(String name); 80 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/tool/Ping.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.tool; 2 | 3 | import org.icmp4j.IcmpPingUtil; 4 | import org.icmp4j.IcmpPingRequest; 5 | import org.icmp4j.IcmpPingResponse; 6 | import org.icmp4j.util.ArgUtil; 7 | 8 | /** 9 | * Internet Control Message Protocol for Java (ICMP4J) 10 | * http://www.icmp4j.org 11 | * Copyright 2009 and beyond, icmp4j 12 | *

13 | * This is free software; you can redistribute it and/or modify it 14 | * under the terms of the GNU Lesser General Public License version 3 15 | * as published by the Free Software Foundation as long as: 16 | * 1. You credit the original author somewhere within your product or website 17 | * 2. The credit is easily reachable and not burried deep 18 | * 3. Your end-user can easily see it 19 | * 4. You register your name (optional) and company/group/org name (required) 20 | * at http://www.icmp4j.org 21 | * 5. You do all of the above within 4 weeks of integrating this software 22 | * 6. You contribute feedback, fixes, and requests for features 23 | *

24 | * If/when you derive a commercial gain from using this software 25 | * please donate at http://www.icmp4j.org 26 | *

27 | * If prefer or require, contact the author specified above to: 28 | * 1. Release you from the above requirements 29 | * 2. Acquire a commercial license 30 | * 3. Purchase a support contract 31 | * 4. Request a different license 32 | * 5. Anything else 33 | *

34 | * This software is distributed in the hope that it will be useful, 35 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 36 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 37 | * to how this is described in the GNU Lesser General Public License. 38 | *

39 | * User: Sal Ingrilli 40 | * Date: May 23, 2014 41 | * Time: 6:43:43 PM 42 | */ 43 | public class Ping { 44 | 45 | /** 46 | * The Java interface 47 | * 48 | * To test: 49 | * cd c:\dev\icmp4j\trunk\icmp4j\output\tool 50 | * java -cp * -Djava.library.path=. org.icmp4j.tool.Ping www.google.com 51 | * 52 | * @param args 53 | */ 54 | public static void main (final String[] args){ 55 | 56 | // handle exceptions 57 | try { 58 | 59 | // extract request parameters 60 | // -t: windows ping.exe repeats until stopped, otherwise default to 4 61 | final String host = args.length > 0 ? 62 | args [args.length - 1] : 63 | "google.com"; 64 | final int maxCount = ArgUtil.findArgument (args, "-t") ? 65 | Integer.MAX_VALUE : 66 | 4; 67 | 68 | // request 69 | final IcmpPingRequest request = IcmpPingUtil.createIcmpPingRequest (); 70 | request.setHost (host); 71 | 72 | // repeat 4 times by default 73 | for (int count = 1; count <= maxCount; count ++) { 74 | 75 | // delegate 76 | final IcmpPingResponse response = IcmpPingUtil.executePingRequest (request); 77 | 78 | // log 79 | final String formattedResponse = IcmpPingUtil.formatResponse (response); 80 | System.out.println (formattedResponse); 81 | 82 | // rest 83 | Thread.sleep (1000); 84 | } 85 | } 86 | catch (final Throwable t){ 87 | 88 | // log 89 | t.printStackTrace (); 90 | } 91 | } 92 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/tool/Sample.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.tool; 2 | 3 | import org.icmp4j.IcmpPingUtil; 4 | import org.icmp4j.IcmpPingRequest; 5 | import org.icmp4j.IcmpPingResponse; 6 | 7 | // Sample class, copyright 2009 and beyond, icmp4j 8 | public class Sample { 9 | 10 | // the java entry point 11 | public static void main (final String[] args) 12 | throws Exception { 13 | 14 | // request 15 | final IcmpPingRequest request = IcmpPingUtil.createIcmpPingRequest (); 16 | request.setHost ("www.google.org"); 17 | 18 | // repeat a few times 19 | for (int count = 1; count <= 4; count ++) { 20 | 21 | // delegate 22 | final IcmpPingResponse response = IcmpPingUtil.executePingRequest (request); 23 | 24 | // log 25 | final String formattedResponse = IcmpPingUtil.formatResponse (response); 26 | System.out.println (formattedResponse); 27 | 28 | // rest 29 | Thread.sleep (1000); 30 | } 31 | } 32 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/util/ArgUtil.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.util; 2 | 3 | /** 4 | * Internet Control Message Protocol for Java (ICMP4J) 5 | * http://www.icmp4j.org 6 | * Copyright 2009 and beyond, icmp4j 7 | *

8 | * This is free software; you can redistribute it and/or modify it 9 | * under the terms of the GNU Lesser General Public License version 3 10 | * as published by the Free Software Foundation as long as: 11 | * 1. You credit the original author somewhere within your product or website 12 | * 2. The credit is easily reachable and not burried deep 13 | * 3. Your end-user can easily see it 14 | * 4. You register your name (optional) and company/group/org name (required) 15 | * at http://www.icmp4j.org 16 | * 5. You do all of the above within 4 weeks of integrating this software 17 | * 6. You contribute feedback, fixes, and requests for features 18 | *

19 | * If/when you derive a commercial gain from using this software 20 | * please donate at http://www.icmp4j.org 21 | *

22 | * If prefer or require, contact the author specified above to: 23 | * 1. Release you from the above requirements 24 | * 2. Acquire a commercial license 25 | * 3. Purchase a support contract 26 | * 4. Request a different license 27 | * 5. Anything else 28 | *

29 | * This software is distributed in the hope that it will be useful, 30 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 31 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 32 | * to how this is described in the GNU Lesser General Public License. 33 | *

34 | * User: Sal Ingrilli 35 | * Date: May 23, 2014 36 | * Time: 7:52:21 PM 37 | */ 38 | public class ArgUtil { 39 | 40 | /** 41 | * Returns true if the given arg is found 42 | * @param args 43 | * @param arg 44 | * @return boolean 45 | */ 46 | public static boolean findArgument ( 47 | final String[] args, 48 | final String arg) { 49 | 50 | for (int argIndex = 0; argIndex < args.length; argIndex++) { 51 | if (args[argIndex].equals (arg)) { 52 | return true; 53 | } 54 | } 55 | return false; 56 | } 57 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/util/ExceptionUtil.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.util; 2 | 3 | /** 4 | * ShortPasta Foundation 5 | * http://www.shortpasta.org 6 | * Copyright 2009 and beyond, Sal Ingrilli at the ShortPasta Software Foundation 7 | *

8 | * This is free software; you can redistribute it and/or modify it 9 | * under the terms of the GNU Lesser General Public License version 3 10 | * as published by the Free Software Foundation as long as: 11 | * 1. You credit the original author somewhere within your product or website 12 | * 2. The credit is easily reachable and not burried deep 13 | * 3. Your end-user can easily see it 14 | * 4. You register your name (optional) and company/group/org name (required) 15 | * at http://www.shortpasta.org 16 | * 5. You do all of the above within 4 weeks of integrating this software 17 | * 6. You contribute feedback, fixes, and requests for features 18 | *

19 | * If/when you derive a commercial gain from using this software 20 | * please donate at http://www.shortpasta.org 21 | *

22 | * If prefer or require, contact the author specified above to: 23 | * 1. Release you from the above requirements 24 | * 2. Acquire a commercial license 25 | * 3. Purchase a support contract 26 | * 4. Request a different license 27 | * 5. Anything else 28 | *

29 | * This software is distributed in the hope that it will be useful, 30 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 31 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 32 | * to how this is described in the GNU Lesser General Public License. 33 | *

34 | * User: Sal Ingrilli 35 | * Date: Feb 14, 2012 36 | * Time: 4:22:15 AM 37 | */ 38 | public class ExceptionUtil { 39 | 40 | /** 41 | * Returns the first available message for the given exception 42 | * @param t 43 | * @return String 44 | */ 45 | public static String getMessage (final Throwable t) { 46 | 47 | // lookup the message in this class and all nested classes 48 | { 49 | final String message = lookupMessage (t); 50 | if (!StringUtil.isSameAsEmpty (message)) { 51 | return message; 52 | } 53 | } 54 | 55 | // message not found: default to something 56 | return t.getClass ().getName (); 57 | } 58 | 59 | /** 60 | * Looks for the message in the given exception 61 | * If not found, it looks in the next nested exception, recursively 62 | * If not found, returns null 63 | * @param t 64 | * @return String 65 | */ 66 | private static String lookupMessage (final Throwable t) { 67 | 68 | // lookup message 69 | { 70 | final String message = t.getMessage (); 71 | if (!StringUtil.isSameAsEmpty (message)) { 72 | return message; 73 | } 74 | } 75 | 76 | // message not found: lookup message in the nested exception 77 | { 78 | final Throwable cause = t.getCause (); 79 | if (cause != null) { 80 | 81 | final String message = getMessage (cause); 82 | if (!StringUtil.isSameAsEmpty (message)) { 83 | return message; 84 | } 85 | } 86 | } 87 | 88 | // message not found anywhere 89 | return null; 90 | } 91 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/util/FileUtil.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.util; 2 | 3 | import java.io.File; 4 | import java.io.InputStream; 5 | import java.io.FileOutputStream; 6 | 7 | /** 8 | * ShortPasta Foundation 9 | * http://www.shortpasta.org 10 | * Copyright 2009 and beyond, Sal Ingrilli at the ShortPasta Software Foundation 11 | *

12 | * This is free software; you can redistribute it and/or modify it 13 | * under the terms of the GNU Lesser General Public License version 3 14 | * as published by the Free Software Foundation as long as: 15 | * 1. You credit the original author somewhere within your product or website 16 | * 2. The credit is easily reachable and not burried deep 17 | * 3. Your end-user can easily see it 18 | * 4. You register your name (optional) and company/group/org name (required) 19 | * at http://www.shortpasta.org 20 | * 5. You do all of the above within 4 weeks of integrating this software 21 | * 6. You contribute feedback, fixes, and requests for features 22 | *

23 | * If/when you derive a commercial gain from using this software 24 | * please donate at http://www.shortpasta.org 25 | *

26 | * If prefer or require, contact the author specified above to: 27 | * 1. Release you from the above requirements 28 | * 2. Acquire a commercial license 29 | * 3. Purchase a support contract 30 | * 4. Request a different license 31 | * 5. Anything else 32 | *

33 | * This software is distributed in the hope that it will be useful, 34 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 35 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 36 | * to how this is described in the GNU Lesser General Public License. 37 | *

38 | * User: Sal Ingrilli 39 | * Date: Jan 28, 2016 40 | * Time: 3:14:33 PM 41 | */ 42 | public class FileUtil { 43 | 44 | // my attributes 45 | private static final int defaultBufferSize = 64 * 1024; 46 | 47 | /** 48 | * Reads all bytes from the given inputStream and writes them to the given File using 49 | * a default buffer size 50 | * @param file 51 | * @param inputStream 52 | */ 53 | public static void writeFile ( 54 | final File file, 55 | final InputStream inputStream) { 56 | 57 | // handle exceptions 58 | FileOutputStream fileOutputStream = null; 59 | try { 60 | 61 | fileOutputStream = new FileOutputStream (file); 62 | IoUtil.chain ( 63 | inputStream, 64 | fileOutputStream, 65 | defaultBufferSize); 66 | } 67 | catch (final Exception e) { 68 | 69 | // propagate 70 | throw new RuntimeException (e); 71 | } 72 | finally { 73 | 74 | // cleanup 75 | IoUtil.close (fileOutputStream); 76 | } 77 | } 78 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/util/IoUtil.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.util; 2 | 3 | import java.io.InputStream; 4 | import java.io.OutputStream; 5 | import java.io.IOException; 6 | 7 | import org.icmp4j.logger.Logger; 8 | 9 | /** 10 | * ShortPasta Foundation 11 | * http://www.shortpasta.org 12 | * Copyright 2009 and beyond, Sal Ingrilli at the ShortPasta Software Foundation 13 | *

14 | * This is free software; you can redistribute it and/or modify it 15 | * under the terms of the GNU Lesser General Public License version 3 16 | * as published by the Free Software Foundation as long as: 17 | * 1. You credit the original author somewhere within your product or website 18 | * 2. The credit is easily reachable and not burried deep 19 | * 3. Your end-user can easily see it 20 | * 4. You register your name (optional) and company/group/org name (required) 21 | * at http://www.shortpasta.org 22 | * 5. You do all of the above within 4 weeks of integrating this software 23 | * 6. You contribute feedback, fixes, and requests for features 24 | *

25 | * If/when you derive a commercial gain from using this software 26 | * please donate at http://www.shortpasta.org 27 | *

28 | * If prefer or require, contact the author specified above to: 29 | * 1. Release you from the above requirements 30 | * 2. Acquire a commercial license 31 | * 3. Purchase a support contract 32 | * 4. Request a different license 33 | * 5. Anything else 34 | *

35 | * This software is distributed in the hope that it will be useful, 36 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 37 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 38 | * to how this is described in the GNU Lesser General Public License. 39 | *

40 | * User: Sal Ingrilli 41 | * Date: Nov 22, 2009 42 | * Time: 10:36:13 AM 43 | */ 44 | public class IoUtil { 45 | 46 | // my variables 47 | private static Logger logger = Logger.getLogger (IoUtil.class); 48 | 49 | 50 | /** 51 | * Chains an input to an output with the given buffer size 52 | * @param inputStream 53 | * @param outputStream 54 | * @param bufferSize 55 | * @throws IOException 56 | */ 57 | public static void chain ( 58 | final InputStream inputStream, 59 | final OutputStream outputStream, 60 | final int bufferSize) 61 | throws IOException { 62 | 63 | // allocate a single buffer 64 | final byte[] buffer = new byte [bufferSize]; 65 | 66 | // forever 67 | while (true) { 68 | 69 | // read next chunk 70 | final int bytesRead = inputStream.read (buffer); 71 | 72 | // done? 73 | if (bytesRead == -1) { 74 | break; 75 | } 76 | 77 | // write 78 | outputStream.write (buffer, 0, bytesRead); 79 | } 80 | } 81 | 82 | /** 83 | * Closes the given OutputStream 84 | * @param outputStream 85 | */ 86 | public static void close (final OutputStream outputStream) { 87 | 88 | // support null 89 | if (outputStream == null) { 90 | return; 91 | } 92 | 93 | // handle exception 94 | try { 95 | 96 | // delegate 97 | outputStream.close (); 98 | } 99 | catch (final IOException e) { 100 | 101 | logger.warn (null, e); 102 | } 103 | } 104 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/util/JnaUtil.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.util; 2 | 3 | import java.util.Map; 4 | import java.util.HashMap; 5 | import java.io.File; 6 | 7 | import com.sun.jna.Native; 8 | 9 | import org.icmp4j.logger.Logger; 10 | 11 | /** 12 | * ShortPasta Foundation 13 | * http://www.shortpasta.org 14 | * Copyright 2009 and beyond, Sal Ingrilli at the ShortPasta Software Foundation 15 | *

16 | * This is free software; you can redistribute it and/or modify it 17 | * under the terms of the GNU Lesser General Public License version 3 18 | * as published by the Free Software Foundation as long as: 19 | * 1. You credit the original author somewhere within your product or website 20 | * 2. The credit is easily reachable and not burried deep 21 | * 3. Your end-user can easily see it 22 | * 4. You register your name (optional) and company/group/org name (required) 23 | * at http://www.shortpasta.org 24 | * 5. You do all of the above within 4 weeks of integrating this software 25 | * 6. You contribute feedback, fixes, and requests for features 26 | *

27 | * If/when you derive a commercial gain from using this software 28 | * please donate at http://www.shortpasta.org 29 | *

30 | * If prefer or require, contact the author specified above to: 31 | * 1. Release you from the above requirements 32 | * 2. Acquire a commercial license 33 | * 3. Purchase a support contract 34 | * 4. Request a different license 35 | * 5. Anything else 36 | *

37 | * This software is distributed in the hope that it will be useful, 38 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 39 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 40 | * to how this is described in the GNU Lesser General Public License. 41 | *

42 | * User: Sal Ingrilli 43 | * Date: Feb 4, 2014 44 | * Time: 5:02:49 PM 45 | */ 46 | public class JnaUtil { 47 | 48 | // my attributes 49 | private static final Logger logger = Logger.getLogger (JnaUtil.class); 50 | private static final Map libraryMap = new HashMap (); 51 | 52 | /** 53 | * Loads the given library 54 | * Returns the library 55 | * 56 | * This method loads the library natively via Native.loadLibrary (). 57 | * If that fails, this method looks for the library as a resource (meaning inside jars, wars, ...), 58 | * extracts it, and then loads it. 59 | * If that fails as well, this throws a RuntimeException 60 | * 61 | * @param libraryName 62 | * @param libraryClass 63 | * @return Object 64 | */ 65 | public static Object loadLibrary ( 66 | final String libraryName, 67 | final Class libraryClass) { 68 | 69 | // already loaded? 70 | synchronized (libraryMap) { 71 | 72 | final Object library = libraryMap.get (libraryName); 73 | if (library != null) { 74 | return library; 75 | } 76 | } 77 | 78 | // the library has not yet been loaded: load it 79 | // support concurrency 80 | synchronized (JnaUtil.class) { 81 | 82 | // try to load from the java.library.path 83 | Object library; 84 | { 85 | final String strategy = "native via java.library.path"; 86 | library = loadLibraryNoException (strategy, libraryName, libraryClass); 87 | } 88 | 89 | if (library == null) { 90 | final String resourceName = ResourceUtil.buildLibraryName(libraryName); 91 | final File resourceFile = ResourceUtil.findResourceAsFile (resourceName); 92 | if (resourceFile != null) { 93 | final String strategy = "native via resource lookup"; 94 | final String path = resourceFile.getAbsolutePath (); 95 | library = loadLibraryNoException (strategy, path, libraryClass); 96 | } 97 | } 98 | 99 | if (library == null) { 100 | final String resourceName = ResourceUtil.buildLibraryName(libraryName); 101 | final String strategy = "as-resource"; 102 | final File file = SystemUtil.extractLibraryByResource (resourceName); 103 | final String path = file.getAbsolutePath (); 104 | library = loadLibraryNoException (strategy, path, libraryClass); 105 | } 106 | 107 | if (library == null) { 108 | throw new RuntimeException ("Failed to load library "); 109 | } 110 | 111 | 112 | // track with the original libraryName! 113 | synchronized (libraryMap) { 114 | libraryMap.put (libraryName, library); 115 | } 116 | } 117 | 118 | // recurse to ensure proper caching 119 | return loadLibrary ( 120 | libraryName, 121 | libraryClass); 122 | } 123 | public static Object loadLibraryBestEffort (final String libraryName, final Class libraryClass) { 124 | try { 125 | return loadLibrary(libraryName, libraryClass); 126 | } catch (RuntimeException e) { 127 | logger.warn(e.getMessage()); 128 | return null; 129 | } 130 | } 131 | 132 | /** 133 | * Uniformly loads the given library 134 | * @param strategy 135 | * @param libraryName 136 | * @param libraryClass 137 | * @return Object 138 | */ 139 | private static Object loadLibraryNoException ( 140 | final String strategy, 141 | final String libraryName, 142 | final Class libraryClass) { 143 | 144 | // handle exceptions 145 | try { 146 | 147 | // try to load from the java.library.path 148 | logger.info ("loadLibrary2 ()"); 149 | logger.info (" strategy: " + strategy); 150 | logger.info (" libraryName: " + libraryName); 151 | logger.info (" libraryClass: " + libraryClass.getName ()); 152 | return Native.loadLibrary (libraryName, libraryClass); 153 | } 154 | catch (final Throwable t) { 155 | 156 | // log 157 | logger.warn ( 158 | "loadLibraryNoException (). Native.loadLibrary () failed. " + 159 | "exception " + t.getClass ().getName () + ", " + 160 | "errorMessage: " + ExceptionUtil.getMessage (t)); 161 | 162 | // done 163 | return null; 164 | } 165 | } 166 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/util/JniUtil.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.util; 2 | 3 | import java.util.Set; 4 | import java.util.HashSet; 5 | import java.io.File; 6 | 7 | import org.icmp4j.exception.AssertRuntimeException; 8 | import org.icmp4j.logger.Logger; 9 | 10 | /** 11 | * ShortPasta Foundation 12 | * http://www.shortpasta.org 13 | * Copyright 2009 and beyond, Sal Ingrilli at the ShortPasta Software Foundation 14 | *

15 | * This is free software; you can redistribute it and/or modify it 16 | * under the terms of the GNU Lesser General Public License version 3 17 | * as published by the Free Software Foundation as long as: 18 | * 1. You credit the original author somewhere within your product or website 19 | * 2. The credit is easily reachable and not burried deep 20 | * 3. Your end-user can easily see it 21 | * 4. You register your name (optional) and company/group/org name (required) 22 | * at http://www.shortpasta.org 23 | * 5. You do all of the above within 4 weeks of integrating this software 24 | * 6. You contribute feedback, fixes, and requests for features 25 | *

26 | * If/when you derive a commercial gain from using this software 27 | * please donate at http://www.shortpasta.org 28 | *

29 | * If prefer or require, contact the author specified above to: 30 | * 1. Release you from the above requirements 31 | * 2. Acquire a commercial license 32 | * 3. Purchase a support contract 33 | * 4. Request a different license 34 | * 5. Anything else 35 | *

36 | * This software is distributed in the hope that it will be useful, 37 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 38 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 39 | * to how this is described in the GNU Lesser General Public License. 40 | *

41 | * User: Laurent Buhler 42 | * Date: Feb 1, 2016 43 | * Time: 5:02:49 PM 44 | */ 45 | public class JniUtil { 46 | // my attributes 47 | private static final Logger logger = Logger.getLogger (JniUtil.class); 48 | private static final Set librarySet = new HashSet(); 49 | 50 | /** 51 | * Loads the given library 52 | * 53 | * This method loads the library natively via System.loadLibrary (). 54 | * If that fails, this method looks for the library as a resource (meaning inside jars, wars, ...), 55 | * extracts it, and then loads it. 56 | * If that fails as well, this throws a UnsatisfiedLinkError 57 | * 58 | * @param libraryName : name of the library to load without prefix or extension 59 | */ 60 | public static synchronized void loadLibraryBestEffort (final String libraryName) 61 | throws UnsatisfiedLinkError { 62 | 63 | // already loaded? 64 | if ( librarySet.contains(libraryName)) 65 | return; 66 | 67 | // the library has not yet been loaded: load it 68 | boolean isLoaded = false; 69 | 70 | // try to load from the java.library.path 71 | logger.info ("loadLibrary trying to load " + libraryName + " from java.library.path"); 72 | try { 73 | System.loadLibrary (libraryName); 74 | isLoaded = true; 75 | } catch (UnsatisfiedLinkError e) { 76 | logger.warn ("loadLibrary can't load " + libraryName + " from java.library.path " + 77 | "exception " + e.getClass ().getName () + ", " + 78 | "errorMessage: " + ExceptionUtil.getMessage (e)); 79 | } 80 | 81 | if ( isLoaded == false ) { 82 | try { 83 | final String libraryNameInJar = ResourceUtil.buildLibraryName(libraryName); 84 | final File file = SystemUtil.extractLibraryByResource(libraryNameInJar); 85 | final String path = file.getAbsolutePath(); 86 | logger.info("extracted lib in : " + path); 87 | try { 88 | System.load(path); 89 | isLoaded = true; 90 | } catch (UnsatisfiedLinkError e) { 91 | logger.warn ("loadLibrary can't load " + libraryName + " from " + path +" " + 92 | "exception " + e.getClass ().getName () + ", " + 93 | "errorMessage: " + ExceptionUtil.getMessage (e)); 94 | } 95 | } catch (AssertRuntimeException e) { 96 | logger.warn(e.getMessage()); 97 | 98 | } 99 | } 100 | 101 | if ( isLoaded == false ) { 102 | final UnsatisfiedLinkError e = new UnsatisfiedLinkError ("Failed to load library " + libraryName); 103 | throw e; 104 | } 105 | librarySet.add (libraryName); 106 | } 107 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/util/PlatformUtil.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.util; 2 | 3 | import org.icmp4j.constants.OsFamilyCode; 4 | 5 | /** 6 | * icmp4j 7 | * http://www.icmp4j.org 8 | * Copyright 2009 and beyond, Sal Ingrilli at the icmp4j 9 | *

10 | * This is free software; you can redistribute it and/or modify it 11 | * under the terms of the GNU Lesser General Public License version 3 12 | * as published by the Free Software Foundation as long as: 13 | * 1. You credit the original author somewhere within your product or website 14 | * 2. The credit is easily reachable and not burried deep 15 | * 3. Your end-user can easily see it 16 | * 4. You register your name (optional) and company/group/org name (required) 17 | * at http://www.icmp4j.org 18 | * 5. You do all of the above within 4 weeks of integrating this software 19 | * 6. You contribute feedback, fixes, and requests for features 20 | *

21 | * If/when you derive a commercial gain from using this software 22 | * please donate at http://www.icmp4j.org 23 | *

24 | * If prefer or require, contact the author specified above to: 25 | * 1. Release you from the above requirements 26 | * 2. Acquire a commercial license 27 | * 3. Purchase a support contract 28 | * 4. Request a different license 29 | * 5. Anything else 30 | *

31 | * This software is distributed in the hope that it will be useful, 32 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 33 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 34 | * to how this is described in the GNU Lesser General Public License. 35 | *

36 | * User: Sal Ingrilli 37 | * Date: Dec 23, 2014 38 | * Time: 10:47:09 PM 39 | */ 40 | public class PlatformUtil { 41 | 42 | // my attributes 43 | private static int osFamilyCode = OsFamilyCode.ZERO; 44 | 45 | // my attributes 46 | public static void setOsFamilyCode (final int osFamilyCode) { PlatformUtil.osFamilyCode = osFamilyCode; } 47 | public static int getOsFamilyCode () { return osFamilyCode; } 48 | 49 | /** 50 | * Initializes this component 51 | */ 52 | public static void initialize () { 53 | 54 | // detect the OS type 55 | // according to http://mindprod.com/jgloss/properties.html 56 | // Here are the values Sun uses for the os.name property to identify various platforms: 57 | // os.name 58 | // AIX 59 | // Digital Unix 60 | // FreeBSD 61 | // HP UX 62 | // Irix 63 | // Linux 64 | // Mac OS 65 | // Mac OS X 66 | // MPE/iX 67 | // Netware 4.11 68 | // OS/2 69 | // Solaris 70 | // Windows 2000 71 | // Windows 95 72 | // Windows 98 73 | // Windows NT 74 | // Windows Vista 75 | // Windows XP 76 | // 77 | // on Dekker's Android 2.3.3 (Samsung S6802): 78 | // final String osName = System.getProperty ("os.name") 79 | // outputs 80 | // Android 2.3.3 81 | if (osFamilyCode == OsFamilyCode.ZERO) { 82 | 83 | // osName-specific processing 84 | final String osName = System.getProperty ("os.name"); 85 | // System.out.println (" "); 86 | final int osCode; 87 | if (osName.equals ("Android")) { 88 | osCode = OsFamilyCode.ANDROID; 89 | } 90 | else if (osName.equals ("Linux")) { 91 | osCode = OsFamilyCode.LINUX; 92 | } 93 | else if (osName.startsWith ("Mac OS")) { 94 | osCode = OsFamilyCode.MAC; 95 | } 96 | else if (osName.startsWith ("Windows")) { 97 | osCode = OsFamilyCode.WINDOWS; 98 | } 99 | else { 100 | osCode = OsFamilyCode.ZERO; 101 | } 102 | setOsFamilyCode (osCode); 103 | } 104 | else { 105 | 106 | // log for now 107 | System.out.println (" "); 108 | } 109 | } 110 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/util/ProcessUtil.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.util; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.InputStreamReader; 5 | import java.io.InputStream; 6 | import java.util.List; 7 | import java.util.LinkedList; 8 | 9 | /** 10 | * Internet Control Message Protocol for Java (ICMP4J) 11 | * http://www.icmp4j.org 12 | * Copyright 2009 and beyond, icmp4j 13 | *

14 | * This is free software; you can redistribute it and/or modify it 15 | * under the terms of the GNU Lesser General Public License version 3 16 | * as published by the Free Software Foundation as long as: 17 | * 1. You credit the original author somewhere within your product or website 18 | * 2. The credit is easily reachable and not burried deep 19 | * 3. Your end-user can easily see it 20 | * 4. You register your name (optional) and company/group/org name (required) 21 | * at http://www.icmp4j.org 22 | * 5. You do all of the above within 4 weeks of integrating this software 23 | * 6. You contribute feedback, fixes, and requests for features 24 | *

25 | * If/when you derive a commercial gain from using this software 26 | * please donate at http://www.icmp4j.org 27 | *

28 | * If prefer or require, contact the author specified above to: 29 | * 1. Release you from the above requirements 30 | * 2. Acquire a commercial license 31 | * 3. Purchase a support contract 32 | * 4. Request a different license 33 | * 5. Anything else 34 | *

35 | * This software is distributed in the hope that it will be useful, 36 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 37 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 38 | * to how this is described in the GNU Lesser General Public License. 39 | *

40 | * User: Sal Ingrilli 41 | * Date: May 23, 2014 42 | * Time: 9:41:55 PM 43 | */ 44 | public class ProcessUtil { 45 | 46 | /** 47 | * Executes the given command 48 | * Returns the output of the process as a List of strings 49 | * @param command 50 | * @return List 51 | */ 52 | public static List executeProcessAndGetOutputAsStringList (final String command) { 53 | 54 | // handle exceptions 55 | try { 56 | 57 | // delegate 58 | final Runtime runtime = Runtime.getRuntime(); 59 | final Process process = runtime.exec (command); 60 | 61 | // extract output 62 | final InputStream inputStream = process.getInputStream (); 63 | final InputStreamReader inputStreamReader = new InputStreamReader (inputStream); 64 | final BufferedReader bufferedReader = new BufferedReader (inputStreamReader); 65 | final List stringList = new LinkedList (); 66 | while (true) { 67 | 68 | // next line 69 | final String string = bufferedReader.readLine (); 70 | if (string == null) { 71 | break; 72 | } 73 | 74 | // track 75 | stringList.add (string); 76 | } 77 | 78 | // done 79 | return stringList; 80 | } 81 | catch (final Exception e) { 82 | 83 | // propagate 84 | throw new RuntimeException (e); 85 | } 86 | } 87 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/util/ResourceUtil.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.util; 2 | 3 | import java.io.File; 4 | import java.net.URL; 5 | import java.net.URI; 6 | import java.net.URISyntaxException; 7 | 8 | import org.icmp4j.constants.OsFamilyCode; 9 | import org.icmp4j.exception.AssertRuntimeException; 10 | import org.icmp4j.logger.Logger; 11 | 12 | /** 13 | * ShortPasta Foundation 14 | * http://www.shortpasta.org 15 | * Copyright 2009 and beyond, Sal Ingrilli at the ShortPasta Software Foundation 16 | *

17 | * This is free software; you can redistribute it and/or modify it 18 | * under the terms of the GNU Lesser General Public License version 3 19 | * as published by the Free Software Foundation as long as: 20 | * 1. You credit the original author somewhere within your product or website 21 | * 2. The credit is easily reachable and not burried deep 22 | * 3. Your end-user can easily see it 23 | * 4. You register your name (optional) and company/group/org name (required) 24 | * at http://www.shortpasta.org 25 | * 5. You do all of the above within 4 weeks of integrating this software 26 | * 6. You contribute feedback, fixes, and requests for features 27 | *

28 | * If/when you derive a commercial gain from using this software 29 | * please donate at http://www.shortpasta.org 30 | *

31 | * If prefer or require, contact the author specified above to: 32 | * 1. Release you from the above requirements 33 | * 2. Acquire a commercial license 34 | * 3. Purchase a support contract 35 | * 4. Request a different license 36 | * 5. Anything else 37 | *

38 | * This software is distributed in the hope that it will be useful, 39 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 40 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 41 | * to how this is described in the GNU Lesser General Public License. 42 | *

43 | * User: Sal Ingrilli 44 | * Date: Nov 22, 2009 45 | * Time: 11:01:45 AM 46 | */ 47 | public class ResourceUtil { 48 | 49 | // my attributes 50 | private static final Logger logger = Logger.getLogger (ResourceUtil.class); 51 | 52 | /** 53 | * Returns a File to the given resource 54 | * Returns null if not found 55 | * @param resourceName 56 | * @throws AssertRuntimeException if the resource is found, but its file is not 57 | * @return InputStream 58 | */ 59 | public static File findResourceAsFile ( 60 | final String resourceName) 61 | throws AssertRuntimeException { 62 | 63 | // delegate 64 | final URL urlObject = findResourceAsURL (resourceName); 65 | if (urlObject == null) { 66 | return null; 67 | } 68 | 69 | // handle exceptions 70 | try { 71 | 72 | // convert to file 73 | // note that because of the following java-bug, we cannot just use url.getFile () 74 | // because it returns encoded paths that can only be decoded by the following URI workaround: 75 | // http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4466485 76 | // 77 | // WARNING: on Sun 3/30/3014 at ~3 PM, with FF 19 and Java 1.7, suddently fileUri.getPath () started 78 | // returning null! so i had to add a check for it... 79 | final String url = urlObject.toString (); 80 | logger.debug ("url: " + url); 81 | 82 | final URI fileUri = new URI (url); 83 | logger.debug ("fileUri: " + fileUri); 84 | 85 | final String decodedFilePath = fileUri.getPath (); 86 | logger.debug ("decodedFilePath: " + decodedFilePath); 87 | if (decodedFilePath == null) { 88 | logger.warn ("findResourceAsFile (). resourceName: " + resourceName + ", decodedFilePath is null: returning null"); 89 | return null; 90 | } 91 | 92 | // lookup 93 | final File file = new File (decodedFilePath); 94 | if (!file.exists ()) { 95 | throw new AssertRuntimeException ( 96 | "resourceName " + resourceName + " " + 97 | "found in url " + url + " but " + 98 | "file does not exist: " + file.getAbsolutePath ()); 99 | } 100 | 101 | // done 102 | return file; 103 | } 104 | catch (final URISyntaxException e) { 105 | 106 | // log 107 | logger.error ("resourceName: " + resourceName); 108 | logger.error (e); 109 | 110 | // done 111 | return null; 112 | } 113 | } 114 | 115 | /** 116 | * @param resourceName 117 | * @return InputStream 118 | */ 119 | private static URL findResourceAsURL (final String resourceName) { 120 | 121 | // lookup as is 122 | { 123 | final URL url = ResourceUtil.class.getResource (resourceName); 124 | if (url != null) { 125 | return url; 126 | } 127 | } 128 | 129 | // lookup as an absolute path 130 | final String fullPath = 131 | (resourceName.startsWith("/") ? "" : "/") + 132 | resourceName; 133 | return ResourceUtil.class.getResource (fullPath); 134 | } 135 | /** 136 | * return the library name as needed for the current architecture. 137 | * ie lib[name].so for linux, lib[name].dylib for osx .. 138 | * @param libraryName 139 | * @return 140 | */ 141 | public static String buildLibraryName (final String libraryName) { 142 | final StringBuilder sb; 143 | 144 | int os = PlatformUtil.getOsFamilyCode(); 145 | switch (os) { 146 | case OsFamilyCode.WINDOWS: 147 | sb = new StringBuilder().append(libraryName).append(".dll"); 148 | return sb.toString(); 149 | case OsFamilyCode.MAC: 150 | sb = new StringBuilder().append("lib").append(libraryName) 151 | .append(".dylib"); 152 | return sb.toString(); 153 | case OsFamilyCode.LINUX: 154 | // assuming that we run a JVM matching the architecture 155 | String arch = System.getProperty("os.arch"); 156 | if (arch.contains("64")) 157 | arch = "64bit"; 158 | else 159 | arch = "32bit"; 160 | sb = new StringBuilder().append("lib").append(libraryName) 161 | .append("_").append(arch).append(".so"); 162 | return sb.toString(); 163 | } 164 | throw new UnsupportedOperationException("architecture not handle"); 165 | } 166 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/util/StringUtil.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.util; 2 | 3 | /** 4 | * Internet Control Message Protocol for Java (ICMP4J) 5 | * http://www.icmp4j.org 6 | * Copyright 2009 and beyond, icmp4j 7 | *

8 | * This is free software; you can redistribute it and/or modify it 9 | * under the terms of the GNU Lesser General Public License version 3 10 | * as published by the Free Software Foundation as long as: 11 | * 1. You credit the original author somewhere within your product or website 12 | * 2. The credit is easily reachable and not burried deep 13 | * 3. Your end-user can easily see it 14 | * 4. You register your name (optional) and company/group/org name (required) 15 | * at http://www.icmp4j.org 16 | * 5. You do all of the above within 4 weeks of integrating this software 17 | * 6. You contribute feedback, fixes, and requests for features 18 | *

19 | * If/when you derive a commercial gain from using this software 20 | * please donate at http://www.icmp4j.org 21 | *

22 | * If prefer or require, contact the author specified above to: 23 | * 1. Release you from the above requirements 24 | * 2. Acquire a commercial license 25 | * 3. Purchase a support contract 26 | * 4. Request a different license 27 | * 5. Anything else 28 | *

29 | * This software is distributed in the hope that it will be useful, 30 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 31 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 32 | * to how this is described in the GNU Lesser General Public License. 33 | *

34 | * User: Sal Ingrilli 35 | * Date: May 23, 2014 36 | * Time: 10:24:30 PM 37 | */ 38 | public class StringUtil { 39 | 40 | // my attributes 41 | private static String newLine; 42 | 43 | // my attributes 44 | public static void setNewLine (final String newLine) { StringUtil.newLine = newLine; } 45 | public static String getNewLine () { return newLine; } 46 | 47 | // static initializer 48 | static 49 | { 50 | newLine = System.getProperty ("line.separator"); 51 | } 52 | 53 | /** 54 | * Returns true if the given string is null or if size == 0 when trimmed 55 | * 56 | * @param value 57 | * @return boolean 58 | */ 59 | public static boolean isSameAsEmpty (final String value) { 60 | 61 | return 62 | value == null || 63 | value.trim ().length () == 0; 64 | } 65 | 66 | /** 67 | * Extracts and returns the string between beginDelimiter and endDelimiter. For example: 68 | * string : "64 bytes from 66.102.7.99: icmp_seq=0 ttl=56 time=27.252 ms" 69 | * beginDelimiter: "from " 70 | * endDelimiter: ":" 71 | * return: "66.102.7.99" 72 | * @param string 73 | * @param beginDelimiter 74 | * @param endDelimiter 75 | * @return String 76 | */ 77 | public static String parseString ( 78 | final String string, 79 | final String beginDelimiter, 80 | final String endDelimiter) { 81 | 82 | // look for the beginning of the string to extract 83 | final int beginDelimiterIndex = string.indexOf (beginDelimiter); 84 | if (beginDelimiterIndex < 0) { 85 | return null; 86 | } 87 | 88 | // look for the end of the string to extract 89 | final int fromIndex = beginDelimiterIndex + beginDelimiter.length (); 90 | final int endDelimiterIndex = string.indexOf ( 91 | endDelimiter, 92 | fromIndex); 93 | if (endDelimiterIndex < 0) { 94 | return null; 95 | } 96 | 97 | // extract 98 | return string.substring (fromIndex, endDelimiterIndex); 99 | } 100 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/util/SystemUtil.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.util; 2 | 3 | import java.io.File; 4 | import java.io.InputStream; 5 | import java.util.concurrent.atomic.AtomicInteger; 6 | 7 | import org.icmp4j.logger.Logger; 8 | import org.icmp4j.exception.AssertRuntimeException; 9 | 10 | /** 11 | * ShortPasta Foundation 12 | * http://www.shortpasta.org 13 | * Copyright 2009 and beyond, Sal Ingrilli at the ShortPasta Software Foundation 14 | *

15 | * This is free software; you can redistribute it and/or modify it 16 | * under the terms of the GNU Lesser General Public License version 3 17 | * as published by the Free Software Foundation as long as: 18 | * 1. You credit the original author somewhere within your product or website 19 | * 2. The credit is easily reachable and not burried deep 20 | * 3. Your end-user can easily see it 21 | * 4. You register your name (optional) and company/group/org name (required) 22 | * at http://www.shortpasta.org 23 | * 5. You do all of the above within 4 weeks of integrating this software 24 | * 6. You contribute feedback, fixes, and requests for features 25 | *

26 | * If/when you derive a commercial gain from using this software 27 | * please donate at http://www.shortpasta.org 28 | *

29 | * If prefer or require, contact the author specified above to: 30 | * 1. Release you from the above requirements 31 | * 2. Acquire a commercial license 32 | * 3. Purchase a support contract 33 | * 4. Request a different license 34 | * 5. Anything else 35 | *

36 | * This software is distributed in the hope that it will be useful, 37 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 38 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 39 | * to how this is described in the GNU Lesser General Public License. 40 | *

41 | * User: Sal Ingrilli 42 | * Date: Jan 28, 2016 43 | * Time: 3:13:27 PM 44 | */ 45 | public class SystemUtil { 46 | 47 | // my variables 48 | private static final Logger logger = Logger.getLogger (SystemUtil.class); 49 | private static final AtomicInteger nextLibraryId = new AtomicInteger (); 50 | 51 | /** 52 | * Looks for the given library as a resource, meaning on the file system AND jars. 53 | * When found, the library is extracted to the temp directory. 54 | * For example, in Windows, when running as an applet: 55 | * 56 | * Returns a File representing the extracted library 57 | * @param libraryName 58 | * @return File 59 | */ 60 | public static File extractLibraryByResource (final String libraryName) { 61 | 62 | // load the library from within the jar 63 | final InputStream inputStream = findLibraryAsStream (libraryName); 64 | if (inputStream == null) { 65 | throw new AssertRuntimeException ("resource not found: " + libraryName); 66 | } 67 | 68 | // create a managed temp directory where to save the library. 69 | // this is simply a standard and easy way for us to find it. 70 | // when creating the library file, tell Java to delete it on exit so we do not have to deal with cleanup 71 | final File appHomeDirectory = getAppHomeDirectoryDirectory (); 72 | final File loadLibraryDirectory = new File (appHomeDirectory, "loadLibrary-" + libraryName); 73 | if (!loadLibraryDirectory.exists ()) { 74 | logger.debug ("creating temp directory: " + loadLibraryDirectory.getAbsolutePath ()); 75 | if (!loadLibraryDirectory.mkdirs ()) { 76 | throw new AssertRuntimeException ("failed to create loadLibraryDirectory: " + loadLibraryDirectory.getAbsolutePath ()); 77 | } 78 | } 79 | final int libraryId = nextLibraryId.incrementAndGet (); 80 | final String uniqueLibraryName = 81 | TimeUtil.formatDateAsFileSystemName () + 82 | "_" + String.valueOf (libraryId); 83 | final File uniqueLibraryFile = new File (loadLibraryDirectory, uniqueLibraryName); 84 | uniqueLibraryFile.deleteOnExit (); 85 | 86 | // save to the users's temp directory 87 | final String uniqueLibraryPath = uniqueLibraryFile.getAbsolutePath (); 88 | logger.debug ("creating temp library: " + uniqueLibraryPath); 89 | FileUtil.writeFile ( 90 | uniqueLibraryFile, 91 | inputStream); 92 | 93 | // don 94 | return uniqueLibraryFile; 95 | } 96 | 97 | /** 98 | * Helper: uniformly looks for the given library within this jar 99 | * Returns null if not found 100 | * @param libraryName 101 | * @return InputStream 102 | */ 103 | private static InputStream findLibraryAsStream (final String libraryName) { 104 | 105 | final String resourcePath = "/" + libraryName; 106 | final InputStream inputStream = SystemUtil.class.getResourceAsStream (resourcePath); 107 | final String message = inputStream == null ? 108 | "findResourceAsStream (): resource " + resourcePath + " not found" : 109 | "findResourceAsStream (): resource " + resourcePath + " found"; 110 | logger.debug (message); 111 | return inputStream; 112 | } 113 | 114 | /** 115 | * Returns the "icmp4j" directory located in "user.home". 116 | * On XP Pro: C:\Documents and Settings\Sal\icmp4j 117 | * @return File 118 | */ 119 | private static File getAppHomeDirectoryDirectory () { 120 | 121 | // delegate 122 | final File userHomeDirectory = new File (System.getProperty ("user.home")); 123 | return new File (userHomeDirectory, "icmp4j"); 124 | } 125 | } -------------------------------------------------------------------------------- /src/main/java/org/icmp4j/util/TimeUtil.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.util; 2 | 3 | import java.util.Date; 4 | import java.text.SimpleDateFormat; 5 | 6 | /** 7 | * ShortPasta Foundation 8 | * http://www.shortpasta.org 9 | * Copyright 2009 and beyond, Sal Ingrilli at the ShortPasta Software Foundation 10 | *

11 | * This is free software; you can redistribute it and/or modify it 12 | * under the terms of the GNU Lesser General Public License version 3 13 | * as published by the Free Software Foundation as long as: 14 | * 1. You credit the original author somewhere within your product or website 15 | * 2. The credit is easily reachable and not burried deep 16 | * 3. Your end-user can easily see it 17 | * 4. You register your name (optional) and company/group/org name (required) 18 | * at http://www.shortpasta.org 19 | * 5. You do all of the above within 4 weeks of integrating this software 20 | * 6. You contribute feedback, fixes, and requests for features 21 | *

22 | * If/when you derive a commercial gain from using this software 23 | * please donate at http://www.shortpasta.org 24 | *

25 | * If prefer or require, contact the author specified above to: 26 | * 1. Release you from the above requirements 27 | * 2. Acquire a commercial license 28 | * 3. Purchase a support contract 29 | * 4. Request a different license 30 | * 5. Anything else 31 | *

32 | * This software is distributed in the hope that it will be useful, 33 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 34 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 35 | * to how this is described in the GNU Lesser General Public License. 36 | *

37 | * User: Sal Ingrilli 38 | * Date: Nov 22, 2009 39 | * Time: 10:36:13 AM 40 | */ 41 | public class TimeUtil { 42 | 43 | /** 44 | * Creates an offset version of the current time 45 | * @return Date 46 | */ 47 | public static Date createDate () { 48 | 49 | // return new Date (getCurrentTimeMillis ()); 50 | return new Date (); 51 | } 52 | 53 | /** 54 | * Returns a date formatted in the standard syncvoice format 55 | * @return String 56 | */ 57 | public static String formatDateAsFileSystemName () { 58 | 59 | final Date date = createDate (); 60 | return formatDate (date, "yyyy-MM-dd_HH-mm-ss"); 61 | } 62 | 63 | /** 64 | * Returns a date formatted in the given format 65 | * @param date 66 | * @param format 67 | * @return String 68 | */ 69 | public static String formatDate (final Date date, final String format) { 70 | final SimpleDateFormat simpleDateFormat = new SimpleDateFormat (format); 71 | return simpleDateFormat.format (date); 72 | } 73 | } -------------------------------------------------------------------------------- /src/main/resources/platform/unix/release/libicmp4jJNA.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laurentbh/icmp4j/f8ae0452f465fa9d9799540350f08fec6ccb881a/src/main/resources/platform/unix/release/libicmp4jJNA.dylib -------------------------------------------------------------------------------- /src/main/resources/platform/unix/release/libicmp4jJNA_32bit.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laurentbh/icmp4j/f8ae0452f465fa9d9799540350f08fec6ccb881a/src/main/resources/platform/unix/release/libicmp4jJNA_32bit.so -------------------------------------------------------------------------------- /src/main/resources/platform/unix/release/libicmp4jJNA_64bit.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laurentbh/icmp4j/f8ae0452f465fa9d9799540350f08fec6ccb881a/src/main/resources/platform/unix/release/libicmp4jJNA_64bit.so -------------------------------------------------------------------------------- /src/main/resources/platform/unix/release/libicmp4jJNI.dylib: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laurentbh/icmp4j/f8ae0452f465fa9d9799540350f08fec6ccb881a/src/main/resources/platform/unix/release/libicmp4jJNI.dylib -------------------------------------------------------------------------------- /src/main/resources/platform/unix/release/libicmp4jJNI_32bit.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laurentbh/icmp4j/f8ae0452f465fa9d9799540350f08fec6ccb881a/src/main/resources/platform/unix/release/libicmp4jJNI_32bit.so -------------------------------------------------------------------------------- /src/main/resources/platform/unix/release/libicmp4jJNI_64bit.so: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/laurentbh/icmp4j/f8ae0452f465fa9d9799540350f08fec6ccb881a/src/main/resources/platform/unix/release/libicmp4jJNI_64bit.so -------------------------------------------------------------------------------- /src/main/resources/platform/unix/source/icmp4j.h: -------------------------------------------------------------------------------- 1 | // 2 | // icmp4j.h 3 | // icmp4j 4 | // 5 | // Created by laurentb on 12/21/15. 6 | // 7 | // This software is distributed in the hope that it will be useful, 8 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 10 | // to how this is described in the GNU Lesser General Public License. 11 | 12 | // https://sourceforge.net/projects/icmp4j/ 13 | 14 | #ifndef icmp4j_h 15 | #define icmp4j_h 16 | 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #define ERR_MAX_LEN 5 * 1024 26 | #define ICMP4J_VER "1.0.1" 27 | 28 | struct Icmp4jStruct { 29 | char* host; 30 | int ttl; 31 | int packetSize; 32 | long timeout; 33 | 34 | int retCode; 35 | int hasTimeout; 36 | int bytes; 37 | int returnTtl; 38 | int rtt; 39 | char* address; 40 | char* errorMsg; 41 | int errorNo; 42 | }; 43 | 44 | #define MAX_DUP_CHK (8 * 128) 45 | // basically all the global 46 | struct pingStruct { 47 | __uint16_t seq; 48 | int options; 49 | struct sockaddr_in whereto; /* who to ping */ 50 | int datalen; 51 | int maxpayload; 52 | int s; /* socket file descriptor */ 53 | u_char outpackhdr[IP_MAXPACKET], 54 | *outpack; 55 | char DOT; 56 | char *hostname; 57 | char *shostname; 58 | long ident; /* process id to identify our packets */ 59 | int uid; /* cached uid for micro-optimization */ 60 | u_char icmp_type; 61 | u_char icmp_type_rsp; 62 | int phdr_len; 63 | int send_len; 64 | 65 | /* counters */ 66 | long nreceived; /* # of packets we got back */ 67 | long ntransmitted; /* sequence # for outbound packets = #sent */ 68 | 69 | /* timing */ 70 | int timing; /* flag to do timing */ 71 | } ; 72 | 73 | void icmp4j_exist(char** argVersion); 74 | void icmp4j_exist_free(char* argVersion); 75 | void icmp4j_start(struct Icmp4jStruct* icmp4j); 76 | void icmp4j_free(struct Icmp4jStruct* icmp4); 77 | #endif /* icmp4j_h */ -------------------------------------------------------------------------------- /src/main/resources/platform/unix/source/icmp4jJNI.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "icmp4j.h" 6 | #include "icmp4jJNI.h" 7 | 8 | 9 | static void makeIcmp4jStr(struct Icmp4jStruct *str, JNIEnv *env, jobject Obj) { 10 | jclass thisClass = (*env)->GetObjectClass(env, Obj); 11 | 12 | jfieldID fidHost = (*env)->GetFieldID(env, thisClass, "host", "Ljava/lang/String;"); 13 | jstring host = (*env)->GetObjectField(env, Obj, fidHost); 14 | const char *nativeString = (*env)->GetStringUTFChars(env, host, 0); 15 | //printf("[%s] %d %lu\n", nativeString, (*env)->GetStringLength(env, host), sizeof(nativeString)); 16 | //fflush(stdout); 17 | str->host = (char*) malloc(sizeof(char) * (1 + (*env)->GetStringLength(env, host))); 18 | memset(str->host, 0, 1+ (*env)->GetStringLength(env, host)); 19 | memcpy(str->host, nativeString, (*env)->GetStringLength(env, host)); 20 | (*env)->ReleaseStringUTFChars(env, host, nativeString); 21 | 22 | jfieldID jField = (*env)->GetFieldID(env, thisClass, "ttl", "I"); 23 | jint number = (*env)->GetIntField(env, Obj, jField); 24 | str->ttl = (int)number; 25 | 26 | jField = (*env)->GetFieldID(env, thisClass, "packetSize", "I"); 27 | number = (*env)->GetIntField(env, Obj, jField); 28 | str->packetSize = (int)number; 29 | 30 | jField = (*env)->GetFieldID(env, thisClass, "timeOut", "J"); 31 | number = (*env)->GetIntField(env, Obj, jField); 32 | str->timeout = (int)number; 33 | } 34 | 35 | JNIEXPORT jstring JNICALL Java_org_icmp4j_platform_unix_jni_Icmp4jJNI_icmp_1test (JNIEnv *env, jobject thisObj) { 36 | 37 | jstring retString; 38 | char *version; 39 | icmp4j_exist(&version); 40 | retString = (*env)->NewStringUTF(env, version); 41 | icmp4j_exist_free(version); 42 | 43 | return retString; 44 | } 45 | 46 | JNIEXPORT void JNICALL Java_org_icmp4j_platform_unix_jni_Icmp4jJNI_icmp_1start 47 | (JNIEnv *env, jobject thisObj) { 48 | struct Icmp4jStruct str; 49 | struct Icmp4jStruct *ptr; 50 | ptr = (struct Icmp4jStruct *) malloc(sizeof(struct Icmp4jStruct )); 51 | 52 | // make an Icmp4jStruct from the obj 53 | makeIcmp4jStr(ptr, env, thisObj); 54 | 55 | // pass it to the pinger 56 | icmp4j_start(ptr); 57 | 58 | jclass thisClass = (*env)->GetObjectClass(env, thisObj); 59 | 60 | jfieldID jField = (*env)->GetFieldID(env, thisClass, "retCode", "I"); 61 | (*env)->SetIntField(env, thisObj, jField, (jint)ptr->retCode); 62 | 63 | jField = (*env)->GetFieldID(env, thisClass, "hasTimeout", "I"); 64 | (*env)->SetIntField(env, thisObj, jField, (jint)ptr->hasTimeout); 65 | 66 | jField = (*env)->GetFieldID(env, thisClass, "bytes", "I"); 67 | (*env)->SetIntField(env, thisObj, jField, (jint)ptr->bytes); 68 | 69 | jField = (*env)->GetFieldID(env, thisClass, "returnTtl", "I"); 70 | (*env)->SetIntField(env, thisObj, jField, (jint)ptr->returnTtl); 71 | 72 | jField = (*env)->GetFieldID(env, thisClass, "rtt", "I"); 73 | (*env)->SetIntField(env, thisObj, jField, (jint)ptr->rtt); 74 | 75 | jstring tmpStr; 76 | jstring tmpStr2; 77 | if (ptr->address != NULL) { 78 | jField = (*env)->GetFieldID(env, thisClass, "address", "Ljava/lang/String;"); 79 | tmpStr = (*env)->GetObjectField(env, thisObj, jField); 80 | tmpStr = (*env)->NewStringUTF(env, ptr->address); 81 | (*env)->SetObjectField(env, thisObj, jField, tmpStr); 82 | } 83 | if (ptr->errorMsg != NULL) { 84 | jField = (*env)->GetFieldID(env, thisClass, "errorMsg", "Ljava/lang/String;"); 85 | tmpStr2 = (*env)->GetObjectField(env, thisObj, jField); 86 | tmpStr2 = (*env)->NewStringUTF(env, ptr->errorMsg); 87 | (*env)->SetObjectField(env, thisObj, jField, tmpStr2); 88 | } 89 | 90 | jField = (*env)->GetFieldID(env, thisClass, "errno", "I"); 91 | (*env)->SetIntField(env, thisObj, jField, (jint)ptr->errorNo); 92 | 93 | icmp4j_free(ptr); 94 | free(ptr); 95 | return; 96 | } 97 | -------------------------------------------------------------------------------- /src/main/resources/platform/unix/source/icmp4jJNI.h: -------------------------------------------------------------------------------- 1 | /* DO NOT EDIT THIS FILE - it is machine generated */ 2 | #include 3 | /* Header for class org_icmp4j_platform_unix_jni_Icmp4jJNI */ 4 | 5 | #ifndef _Included_org_icmp4j_platform_unix_jni_Icmp4jJNI 6 | #define _Included_org_icmp4j_platform_unix_jni_Icmp4jJNI 7 | #ifdef __cplusplus 8 | extern "C" { 9 | #endif 10 | /* 11 | * Class: org_icmp4j_platform_unix_jni_Icmp4jJNI 12 | * Method: icmp_start 13 | * Signature: ()J 14 | */ 15 | JNIEXPORT void JNICALL Java_org_icmp4j_platform_unix_jni_Icmp4jJNI_icmp_1start 16 | (JNIEnv *, jobject); 17 | 18 | /* 19 | * Class: org_icmp4j_platform_unix_jni_Icmp4jJNI 20 | * Method: icmp_test 21 | * Signature: ()Ljava/lang/String; 22 | */ 23 | JNIEXPORT jstring JNICALL Java_org_icmp4j_platform_unix_jni_Icmp4jJNI_icmp_1test 24 | (JNIEnv *, jobject); 25 | #ifdef __cplusplus 26 | } 27 | #endif 28 | #endif 29 | -------------------------------------------------------------------------------- /src/main/resources/platform/unix/source/makefile: -------------------------------------------------------------------------------- 1 | CC :=gcc 2 | CFLAGS := -c -D_REENTRANT -pthread 3 | #-Wall 4 | LDFLAGS := -shared 5 | 6 | NAMEJNA := icmp4jJNA 7 | NAMEJNI := icmp4jJNI 8 | 9 | OS := $(shell uname) 10 | ifeq ($(OS),Darwin) 11 | EXT := dylib 12 | JNI := -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/darwin 13 | else 14 | EXT := so 15 | JNI := -I$(JAVA_HOME)/../include -I$(JAVA_HOME)/../include/linux 16 | endif 17 | 18 | all: libJNA libJNI test 19 | 20 | libJNA: lib$(NAMEJNA).$(EXT) 21 | 22 | libJNI: lib$(NAMEJNI).$(EXT) 23 | 24 | lib$(NAMEJNA).$(EXT): icmp4j.o 25 | $(CC) $(LDFLAGS) -o lib$(NAMEJNA).$(EXT) $^ -o $@ 26 | 27 | lib$(NAMEJNI).$(EXT): icmp4j.o icmp4jJNI.o 28 | $(CC) $(LDFLAGS) -o lib$(NAMEJNI).$(EXT) $^ -o $@ 29 | 30 | icmp4j.o: icmp4j.c 31 | $(CC) $(CFLAGS) -fpic icmp4j.c 32 | 33 | icmp4jJNI.o: icmp4jJNI.c 34 | $(CC) $(JNI) $(CFLAGS) -fpic icmp4jJNI.c 35 | 36 | test: main.o 37 | $(CC) main.o -o test -L. -licmp4jJNA 38 | 39 | main.o: main.c 40 | $(CC) $(CFLAGS) main.c 41 | 42 | clean: 43 | rm *.o test lib$(NAMEJNA).$(EXT) lib$(NAMEJNI).$(EXT) 44 | -------------------------------------------------------------------------------- /src/test/java/org/icmp4j/platform/IcmpTraceRouteUtilTest.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.platform; 2 | 3 | import junit.framework.TestCase; 4 | import org.icmp4j.IcmpTraceRouteRequest; 5 | import org.icmp4j.IcmpTraceRouteUtil; 6 | import org.icmp4j.IcmpTraceRouteResponse; 7 | 8 | /** 9 | * ShortPasta Foundation 10 | * http://www.shortpasta.org 11 | * Copyright 2009 and beyond, Sal Ingrilli at the ShortPasta Software Foundation 12 | *

13 | * This is free software; you can redistribute it and/or modify it 14 | * under the terms of the GNU Lesser General Public License version 3 15 | * as published by the Free Software Foundation as long as: 16 | * 1. You credit the original author somewhere within your product or website 17 | * 2. The credit is easily reachable and not burried deep 18 | * 3. Your end-user can easily see it 19 | * 4. You register your name (optional) and company/group/org name (required) 20 | * at http://www.shortpasta.org 21 | * 5. You do all of the above within 4 weeks of integrating this software 22 | * 6. You contribute feedback, fixes, and requests for features 23 | *

24 | * If/when you derive a commercial gain from using this software 25 | * please donate at http://www.shortpasta.org 26 | *

27 | * If prefer or require, contact the author specified above to: 28 | * 1. Release you from the above requirements 29 | * 2. Acquire a commercial license 30 | * 3. Purchase a support contract 31 | * 4. Request a different license 32 | * 5. Anything else 33 | *

34 | * This software is distributed in the hope that it will be useful, 35 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 36 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 37 | * to how this is described in the GNU Lesser General Public License. 38 | *

39 | * User: Sal Ingrilli 40 | * Date: Oct 10, 2014 41 | * Time: 12:57:24 AM 42 | */ 43 | public class IcmpTraceRouteUtilTest extends TestCase { 44 | 45 | /** 46 | * Tests the normal trace route 47 | */ 48 | public void test_executeTraceRoute_www_google_com () { 49 | 50 | // request 51 | final IcmpTraceRouteRequest request = new IcmpTraceRouteRequest (); 52 | request.setHost ("www.goodbyeftp.com"); 53 | request.setPacketSize (32); 54 | request.setTimeout (5 * 1000); 55 | request.setTtl (30); 56 | 57 | // delegate 58 | final IcmpTraceRouteResponse response = IcmpTraceRouteUtil.executeTraceRoute (request); 59 | System.out.println ("response: " + response); 60 | } 61 | 62 | /** 63 | * Tests the normal trace route 64 | */ 65 | public void test_executeTraceRoute_www_google_com_100 () { 66 | 67 | // delegate 68 | for (int index = 0; index < 100; index ++) { 69 | System.out.println ("Running test " + index); 70 | test_executeTraceRoute_www_google_com (); 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /src/test/java/org/icmp4j/platform/android/AndroidNativeBridgeTest.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.platform.android; 2 | 3 | import java.util.List; 4 | import java.util.LinkedList; 5 | 6 | import junit.framework.TestCase; 7 | import org.icmp4j.platform.android.AndroidNativeBridge; 8 | import org.icmp4j.IcmpPingResponse; 9 | 10 | /** 11 | * icmp4j 12 | * http://www.icmp4j.org 13 | * Copyright 2009 and beyond, Sal Ingrilli at the icmp4j 14 | *

15 | * This is free software; you can redistribute it and/or modify it 16 | * under the terms of the GNU Lesser General Public License version 3 17 | * as published by the Free Software Foundation as long as: 18 | * 1. You credit the original author somewhere within your product or website 19 | * 2. The credit is easily reachable and not burried deep 20 | * 3. Your end-user can easily see it 21 | * 4. You register your name (optional) and company/group/org name (required) 22 | * at http://www.icmp4j.org 23 | * 5. You do all of the above within 4 weeks of integrating this software 24 | * 6. You contribute feedback, fixes, and requests for features 25 | *

26 | * If/when you derive a commercial gain from using this software 27 | * please donate at http://www.icmp4j.org 28 | *

29 | * If prefer or require, contact the author specified above to: 30 | * 1. Release you from the above requirements 31 | * 2. Acquire a commercial license 32 | * 3. Purchase a support contract 33 | * 4. Request a different license 34 | * 5. Anything else 35 | *

36 | * This software is distributed in the hope that it will be useful, 37 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 38 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 39 | * to how this is described in the GNU Lesser General Public License. 40 | *

41 | * User: Sal Ingrilli 42 | * Date: Dec 23, 2014 43 | * Time: 11:24:23 PM 44 | */ 45 | public class AndroidNativeBridgeTest extends TestCase { 46 | 47 | /** 48 | * Tests executePingRequest () 49 | */ 50 | public void test_executePingRequest_normal () { 51 | 52 | final List stringList = new LinkedList (); 53 | stringList.add ("PING www.google.com (216.58.219.36) 32(60) bytes of data."); 54 | stringList.add ("40 bytes from lax17s04-in-f4.1e100.net (216.58.219.36): icmp_seq=1 ttl=55 time=45.7 ms"); 55 | debug ("output:"); 56 | for (final String string : stringList) { 57 | debug ("string: " + string); 58 | } 59 | 60 | final AndroidNativeBridge AndroidNativeBridge = new AndroidNativeBridge (); 61 | final IcmpPingResponse response = AndroidNativeBridge.executePingRequest (stringList); 62 | 63 | { 64 | final String errorMessage = response.getErrorMessage (); 65 | debug ("errorMessage: " + errorMessage); 66 | assertEquals ( 67 | null + " == " + errorMessage, 68 | null, 69 | errorMessage); 70 | } 71 | 72 | { 73 | final String host = response.getHost (); 74 | debug ("host: " + host); 75 | assertEquals ( 76 | "lax17s04-in-f4.1e100.net == " + host, 77 | "lax17s04-in-f4.1e100.net", 78 | host); 79 | } 80 | 81 | { 82 | final int rtt = response.getRtt (); 83 | debug ("rtt: " + rtt); 84 | assertEquals ( 85 | 45 + " == " + rtt, 86 | 45, 87 | rtt); 88 | } 89 | 90 | { 91 | final int size = response.getSize (); 92 | debug ("size: " + size); 93 | assertEquals ( 94 | 40 + " == " + size, 95 | 40, 96 | size); 97 | } 98 | 99 | { 100 | final int ttl = response.getTtl (); 101 | debug ("ttl: " + ttl); 102 | assertEquals ( 103 | 55 + " == " + ttl, 104 | 55, 105 | ttl); 106 | } 107 | 108 | { 109 | final boolean successFlag = response.getSuccessFlag (); 110 | debug ("successFlag: " + successFlag); 111 | assertEquals ( 112 | true + " == " + successFlag, 113 | true, 114 | successFlag); 115 | } 116 | } 117 | 118 | /** 119 | * Tests executePingRequest () 120 | * WARNING: the difference with these Android distributions is that for the sequence number 121 | * they use "icmp_seq" and NOT "icmp_req" 122 | */ 123 | public void test_executePingRequest_Mint17_and_ArchAndroid () { 124 | 125 | final List stringList = new LinkedList (); 126 | stringList.add ("PING www.google.com (74.125.224.211) 32(60) bytes of data."); 127 | stringList.add ("40 bytes from lax02s02-in-f19.1e100.net (74.125.224.211): icmp_seq=1 ttl=56 time=47.2 ms"); 128 | debug ("output:"); 129 | for (final String string : stringList) { 130 | debug ("string: " + string); 131 | } 132 | 133 | final AndroidNativeBridge AndroidNativeBridge = new AndroidNativeBridge (); 134 | final IcmpPingResponse response = AndroidNativeBridge.executePingRequest (stringList); 135 | 136 | { 137 | final String errorMessage = response.getErrorMessage (); 138 | debug ("errorMessage: " + errorMessage); 139 | assertEquals ( 140 | null + " == " + errorMessage, 141 | null, 142 | errorMessage); 143 | } 144 | 145 | { 146 | final String host = response.getHost (); 147 | debug ("host: " + host); 148 | assertEquals ( 149 | "lax02s02-in-f19.1e100.net == " + host, 150 | "lax02s02-in-f19.1e100.net", 151 | host); 152 | } 153 | 154 | { 155 | final int rtt = response.getRtt (); 156 | debug ("rtt: " + rtt); 157 | assertEquals ( 158 | 47 + " == " + rtt, 159 | 47, 160 | rtt); 161 | } 162 | 163 | { 164 | final int size = response.getSize (); 165 | debug ("size: " + size); 166 | assertEquals ( 167 | 40 + " == " + size, 168 | 40, 169 | size); 170 | } 171 | 172 | { 173 | final boolean successFlag = response.getSuccessFlag (); 174 | debug ("successFlag: " + successFlag); 175 | assertEquals ( 176 | true + " == " + successFlag, 177 | true, 178 | successFlag); 179 | } 180 | 181 | { 182 | final int ttl = response.getTtl (); 183 | debug ("ttl: " + ttl); 184 | assertEquals ( 185 | 56 + " == " + ttl, 186 | 56, 187 | ttl); 188 | } 189 | } 190 | 191 | /** 192 | * Tests executePingRequest () 193 | */ 194 | public void test_executePingRequest_unknownHost () { 195 | 196 | final List stringList = new LinkedList (); 197 | stringList.add ("ping: unknown host www.googgle.com"); 198 | debug ("output:"); 199 | for (final String string : stringList) { 200 | debug ("string: " + string); 201 | } 202 | 203 | final AndroidNativeBridge AndroidNativeBridge = new AndroidNativeBridge (); 204 | final IcmpPingResponse response = AndroidNativeBridge.executePingRequest (stringList); 205 | 206 | { 207 | final String errorMessage = response.getErrorMessage (); 208 | debug ("errorMessage: " + errorMessage); 209 | assertEquals ( 210 | "ping: unknown host www.googgle.com" + " == " + errorMessage, 211 | "ping: unknown host www.googgle.com", 212 | errorMessage); 213 | } 214 | 215 | { 216 | final boolean successFlag = response.getSuccessFlag (); 217 | debug ("successFlag: " + successFlag); 218 | assertEquals ( 219 | false + " == " + successFlag, 220 | false, 221 | successFlag); 222 | } 223 | } 224 | 225 | /** 226 | * Uniformly logs the given debug string 227 | * @param string 228 | */ 229 | private void debug (final String string) { 230 | 231 | System.out.println (" <" + string + ">"); 232 | } 233 | } -------------------------------------------------------------------------------- /src/test/java/org/icmp4j/platform/linux/LinuxNativeBridgeTest.java: -------------------------------------------------------------------------------- 1 | package org.icmp4j.platform.linux; 2 | 3 | import java.util.List; 4 | import java.util.LinkedList; 5 | 6 | import org.icmp4j.IcmpPingResponse; 7 | import org.icmp4j.platform.unix.LinuxProcessNativeBridge; 8 | 9 | import junit.framework.TestCase; 10 | 11 | /** 12 | * Internet Control Message Protocol for Java (ICMP4J) 13 | * http://www.icmp4j.org 14 | * Copyright 2009 and beyond, icmp4j 15 | *

16 | * This is free software; you can redistribute it and/or modify it 17 | * under the terms of the GNU Lesser General Public License version 3 18 | * as published by the Free Software Foundation as long as: 19 | * 1. You credit the original author somewhere within your product or website 20 | * 2. The credit is easily reachable and not burried deep 21 | * 3. Your end-user can easily see it 22 | * 4. You register your name (optional) and company/group/org name (required) 23 | * at http://www.icmp4j.org 24 | * 5. You do all of the above within 4 weeks of integrating this software 25 | * 6. You contribute feedback, fixes, and requests for features 26 | *

27 | * If/when you derive a commercial gain from using this software 28 | * please donate at http://www.icmp4j.org 29 | *

30 | * If prefer or require, contact the author specified above to: 31 | * 1. Release you from the above requirements 32 | * 2. Acquire a commercial license 33 | * 3. Purchase a support contract 34 | * 4. Request a different license 35 | * 5. Anything else 36 | *

37 | * This software is distributed in the hope that it will be useful, 38 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 39 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, similarly 40 | * to how this is described in the GNU Lesser General Public License. 41 | *

42 | * User: Sal Ingrilli 43 | * Date: May 23, 2014 44 | * Time: 10:46:34 PM 45 | */ 46 | public class LinuxNativeBridgeTest extends TestCase { 47 | 48 | /** 49 | * Tests executePingRequest () 50 | */ 51 | public void test_executePingRequest_normal () { 52 | 53 | final List stringList = new LinkedList (); 54 | stringList.add ("PING www.google.com (74.125.224.211) 32(60) bytes of data."); 55 | stringList.add ("40 bytes from lax02s02-in-f19.1e100.net (74.125.224.211): icmp_req=1 ttl=56 time=47.2 ms"); 56 | debug ("output:"); 57 | for (final String string : stringList) { 58 | debug ("string: " + string); 59 | } 60 | 61 | final LinuxProcessNativeBridge linuxProcessNativeBridge = new LinuxProcessNativeBridge (); 62 | final IcmpPingResponse response = linuxProcessNativeBridge.executePingRequest (stringList); 63 | 64 | { 65 | final String errorMessage = response.getErrorMessage (); 66 | debug ("errorMessage: " + errorMessage); 67 | assertEquals ( 68 | null + " == " + errorMessage, 69 | null, 70 | errorMessage); 71 | } 72 | 73 | { 74 | final String host = response.getHost (); 75 | debug ("host: " + host); 76 | assertEquals ( 77 | "lax02s02-in-f19.1e100.net == " + host, 78 | "lax02s02-in-f19.1e100.net", 79 | host); 80 | } 81 | 82 | { 83 | final int rtt = response.getRtt (); 84 | debug ("rtt: " + rtt); 85 | assertEquals ( 86 | 47 + " == " + rtt, 87 | 47, 88 | rtt); 89 | } 90 | 91 | { 92 | final int size = response.getSize (); 93 | debug ("size: " + size); 94 | assertEquals ( 95 | 40 + " == " + size, 96 | 40, 97 | size); 98 | } 99 | 100 | { 101 | final boolean successFlag = response.getSuccessFlag (); 102 | debug ("successFlag: " + successFlag); 103 | assertEquals ( 104 | true + " == " + successFlag, 105 | true, 106 | successFlag); 107 | } 108 | 109 | { 110 | final int ttl = response.getTtl (); 111 | debug ("ttl: " + ttl); 112 | assertEquals ( 113 | 56 + " == " + ttl, 114 | 56, 115 | ttl); 116 | } 117 | } 118 | 119 | /** 120 | * Tests executePingRequest () 121 | * WARNING: the difference with these Linux distributions is that for the sequence number 122 | * they use "icmp_seq" and NOT "icmp_req" 123 | */ 124 | public void test_executePingRequest_Mint17_and_ArchLinux () { 125 | 126 | final List stringList = new LinkedList (); 127 | stringList.add ("PING www.google.com (74.125.224.211) 32(60) bytes of data."); 128 | stringList.add ("40 bytes from lax02s02-in-f19.1e100.net (74.125.224.211): icmp_seq=1 ttl=56 time=47.2 ms"); 129 | debug ("output:"); 130 | for (final String string : stringList) { 131 | debug ("string: " + string); 132 | } 133 | 134 | final LinuxProcessNativeBridge linuxProcessNativeBridge = new LinuxProcessNativeBridge (); 135 | final IcmpPingResponse response = linuxProcessNativeBridge.executePingRequest (stringList); 136 | 137 | { 138 | final String errorMessage = response.getErrorMessage (); 139 | debug ("errorMessage: " + errorMessage); 140 | assertEquals ( 141 | null + " == " + errorMessage, 142 | null, 143 | errorMessage); 144 | } 145 | 146 | { 147 | final String host = response.getHost (); 148 | debug ("host: " + host); 149 | assertEquals ( 150 | "lax02s02-in-f19.1e100.net == " + host, 151 | "lax02s02-in-f19.1e100.net", 152 | host); 153 | } 154 | 155 | { 156 | final int rtt = response.getRtt (); 157 | debug ("rtt: " + rtt); 158 | assertEquals ( 159 | 47 + " == " + rtt, 160 | 47, 161 | rtt); 162 | } 163 | 164 | { 165 | final int size = response.getSize (); 166 | debug ("size: " + size); 167 | assertEquals ( 168 | 40 + " == " + size, 169 | 40, 170 | size); 171 | } 172 | 173 | { 174 | final boolean successFlag = response.getSuccessFlag (); 175 | debug ("successFlag: " + successFlag); 176 | assertEquals ( 177 | true + " == " + successFlag, 178 | true, 179 | successFlag); 180 | } 181 | 182 | { 183 | final int ttl = response.getTtl (); 184 | debug ("ttl: " + ttl); 185 | assertEquals ( 186 | 56 + " == " + ttl, 187 | 56, 188 | ttl); 189 | } 190 | } 191 | 192 | /** 193 | * Tests executePingRequest () 194 | */ 195 | public void test_executePingRequest_unknownHost () { 196 | 197 | final List stringList = new LinkedList (); 198 | stringList.add ("ping: unknown host www.googgle.com"); 199 | debug ("output:"); 200 | for (final String string : stringList) { 201 | debug ("string: " + string); 202 | } 203 | 204 | final LinuxProcessNativeBridge linuxProcessNativeBridge = new LinuxProcessNativeBridge (); 205 | final IcmpPingResponse response = linuxProcessNativeBridge.executePingRequest (stringList); 206 | 207 | { 208 | final String errorMessage = response.getErrorMessage (); 209 | debug ("errorMessage: " + errorMessage); 210 | assertEquals ( 211 | "ping: unknown host www.googgle.com" + " == " + errorMessage, 212 | "ping: unknown host www.googgle.com", 213 | errorMessage); 214 | } 215 | 216 | { 217 | final boolean successFlag = response.getSuccessFlag (); 218 | debug ("successFlag: " + successFlag); 219 | assertEquals ( 220 | false + " == " + successFlag, 221 | false, 222 | successFlag); 223 | } 224 | } 225 | 226 | /** 227 | * Uniformly logs the given debug string 228 | * @param string 229 | */ 230 | private void debug (final String string) { 231 | 232 | System.out.println (" <" + string + ">"); 233 | } 234 | } --------------------------------------------------------------------------------