Hello,
I have a multi-homed Linux machine, i.e. a machine that has more than one interface connected to a network (a wifi and a mobile broadband NIC in this particular case). What I want to do is to constantly ping a certain remote host via each of these adapters simultaneously to see which one's got the lowest RTT.
With 'ping' I could simply specify the '-I <adapter>' argument to specify the network interface to emit the echo request and using java TCP-sockets I can do a bind() before a connect() to choose the desired outbound interface. However I'd like to have a similar thing using icmp4j. How can I get there?
Thanks in advance!
Best
Thomas
Last edit: Thomas 2016-09-19
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thomas,
Icmp4j doesn't have this option!
There is a lot of work to do in order to have it under every implementation!
Which implementation you are using or planning to use ? (JNI/JNA/Java)
L.
Last edit: laurent buhler 2016-09-19
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I join to the Thomas question - i need to execute(in windows) command like "ping -S someSourceIP someHostP" programmatically, and after superficially learning the sample of how to using, i didn't find mentioned feature. Is it so hard to realize? it's very often used and necessary thing in everyday needs. I'm planning to use java.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
ICMP4J has a WindowsProcessNativeBridge that spawsn ping.exe.
I can make the changes to pass in the source address and include it in ping.exe.
1. Will this work for you?
2. What platforms can you to test on? XP Pro 32-bit, XP Pro 64-bit, Win7, Win8, WinX, ...?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Pinging 192.168.0.238 from 192.168.0.77 with 32 bytes of data:
Reply from 192.168.0.238: bytes=32 time=4ms TTL=64
Ping statistics for 192.168.0.238:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 4ms, Maximum = 4ms, Average = 4ms
In case, when i'm trying to ping my interesting host address 192.168.0.238
everything works fine, but when i'm trying to ping www.google.com there some problems
C:\Users\ADM>ping -n 1 -l 32 -w 1 -S 192.168.0.77 www.google.com
Pinging www.google.com [74.125.232.209] from 192.168.0.77 with 32 bytes of data:
PING: transmit failed.
Ping statistics for 74.125.232.209:
Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hey Dimitri,
Can you get a more precise error message when you do ping -n 1 -l 32 -w 1 -S 192.168.0.77 www.google.com
I am suprised it worked for ping -n 1 -l 32 -w 1 -S 192.168.0.77 192.168.0.238
On OSX, the -S option is pretty strict; following is the description of the option from the man pages
Use the following IP address as the source address in outgoing packets. On hosts with more than one IP address, this option can be used to force
the source address to be something other than the IP address of the interface the probe packet is sent on. If the IP address is not one of this
machine's interface addresses, an error is returned and nothing is sent.
and you get error like:
bind:Can'tassignrequestedaddress
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
It's good idea to add the method mentioned above like: request.setSource(sourceIp); - it will help me for my purposes and other developers. I think that adding that feature will very increase the good of your library.
Last edit: Dmitry Ilyushko 2017-03-27
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Okay, i have dowloaded your attachement and extracted archive. I have linked files icmp4j-all.jar, jna-3.5.1.jar, platform-3.5.1.jar from "\1021rc1\icmp4j-project\trunk\icmp4j\output\tool" and "\1021rc1\icmp4j-project\trunk\icmp4j\output\lib"(for the icmp4j.jar file) directories. to the my Netbeans project and rebuilt the code and try to lauch my code with your recomendations below:
Rather than looking for some strings in the result, you should use the response flags
if (!response.getSuccessFlag() {
// check if it timed out
if (response.getTimeoutFlag()) {
System.out.println("time out!");
}
else {
System.out.println(response.getErrorMessage());
}
From your screen shot, looks you have a 4 to 9 ms round trip, so you should set time out accordingly, for example 10 ms
request.setTimeout(10000);
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I tried to run my another custom ping method and everything fine:
// Use this method to ping hosts on Windows or other platforms, withrespond timeout of 3 secs
public static boolean ping2(String sourceIp, String hostIp) throws IOException, InterruptedException {
while (!Thread.currentThread().isInterrupted()) {
boolean isWindows = System.getProperty("os.name").toLowerCase().contains("win");
//ProcessBuilder processBuilder = new ProcessBuilder("ping", "-S", sourceIp, hostIp, "-w 1000");
ProcessBuilder processBuilder = new ProcessBuilder("ping", isWindows ? "-S" : "-I", sourceIp, hostIp);
final Process proc = processBuilder.start();
long str = System.currentTimeMillis();
proc.waitFor();
InputStream is = proc.getInputStream();
InputStreamReader isr = new InputStreamReader(is, "CP866");
BufferedReader br = new BufferedReader(isr);
String line;
while ((line = br.readLine()) != null) {
if (line.contains("TTL")) {
System.out.println("Host " + hostIp + " available from ip " + sourceIp);
long end = System.currentTimeMillis();
System.out.println("process elapsed time = " + (float) (end - str) + " ms");
System.out.println("------------------------------------------------------------");
return true;
}
}
}
return false;
}
Output:
Host www.google.com available from ip 192.168.1.3
process elapsed time = 3063.0 ms
It's taken from the error output:
command: "C:\windows\system32\ping.exe" -n 1 -l 32 -w 1000 -S 192.168.1.3 www.google.com
Host ip :www.google.com IS NOT RESPONDED from source ip: 192.168.1.3
And there's a question - how i can get access to the notorious "command" from the code
I don't want to set some parameters for the native ping, for example i don't want to set parameter "-w 1" or "-w 1000" How can i change the sended packet from my code?
Last edit: Dmitry Ilyushko 2017-03-28
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
final NativeBridge nativeBridge = new WindowsProcessNativeBridge ();
nativeBridge.initialize ();
Icmp4jUtil.setNativeBridge (nativeBridge);
Icmp4jUtil.initialize ();
// request
final IcmpPingRequest request = IcmpPingUtil.createIcmpPingRequest ();
request.setCharsetName ("CP866");
request.setHost ("www.google.com");
request.setSource ("192.168.1.3");
request.setTimeout (30000);
// ping
final IcmpPingResponse response = IcmpPingUtil.executePingRequest (request);
final String formattedResponse = IcmpPingUtil.formatResponse (response);
System.out.println (formattedResponse);
// print the command and its output
final String command = response.getCommand ();
System.out.println ("command: " + command);
final String output = response.getOutput ();
System.out.println ("<output>");
System.out.println (output);
System.out.println ("</output>");
I tested with the ping output that you gave earlier, and the parsing works.
So if this does not work for you, give me the full output of this test.
BTW, I think your test failed because you set a timeout of 1000 msecs, and that may not be enough in your case.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Sal,
I have tested your new update, and it works in my case, even if doing request.setTimeout (1000);
not: request.setTimeout (30000);
Thank you very much!
Last edit: Dmitry Ilyushko 2017-03-29
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hello,
I have a multi-homed Linux machine, i.e. a machine that has more than one interface connected to a network (a wifi and a mobile broadband NIC in this particular case). What I want to do is to constantly ping a certain remote host via each of these adapters simultaneously to see which one's got the lowest RTT.
With 'ping' I could simply specify the '-I <adapter>' argument to specify the network interface to emit the echo request and using java TCP-sockets I can do a bind() before a connect() to choose the desired outbound interface. However I'd like to have a similar thing using icmp4j. How can I get there?
Thanks in advance!
Best
Thomas
Last edit: Thomas 2016-09-19
Thomas,
Icmp4j doesn't have this option!
There is a lot of work to do in order to have it under every implementation!
Which implementation you are using or planning to use ? (JNI/JNA/Java)
L.
Last edit: laurent buhler 2016-09-19
I join to the Thomas question - i need to execute(in windows) command like "ping -S someSourceIP someHostP" programmatically, and after superficially learning the sample of how to using, i didn't find mentioned feature. Is it so hard to realize? it's very often used and necessary thing in everyday needs. I'm planning to use java.
ICMP4J has a WindowsProcessNativeBridge that spawsn ping.exe.
I can make the changes to pass in the source address and include it in ping.exe.
1. Will this work for you?
2. What platforms can you to test on? XP Pro 32-bit, XP Pro 64-bit, Win7, Win8, WinX, ...?
Thanks for you reply, Sal Ingrilli. Maybe i I spoke too abstractly. Let i explain you what i need. I have method in my code:
but i can't assign the sourceIP, what you can reccomend ?
I use Windows 8.1 x64
Last edit: Dmitry Ilyushko 2017-03-27
I may be able to add something like this:
request.setSource(sourceIp);
Please run this command from a command prompt, and give me the full output:
ping -n 1 -l 32 -w 1 -S <YOUR_SOURCE_IP> www.google.com
C:\Users\ADM>ping -n 1 -l 32 -w 1 -S 192.168.0.77 192.168.0.238
Pinging 192.168.0.238 from 192.168.0.77 with 32 bytes of data:
Reply from 192.168.0.238: bytes=32 time=4ms TTL=64
Ping statistics for 192.168.0.238:
Packets: Sent = 1, Received = 1, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
Minimum = 4ms, Maximum = 4ms, Average = 4ms
In case, when i'm trying to ping my interesting host address 192.168.0.238
everything works fine, but when i'm trying to ping www.google.com there some problems
C:\Users\ADM>ping -n 1 -l 32 -w 1 -S 192.168.0.77 www.google.com
Pinging www.google.com [74.125.232.209] from 192.168.0.77 with 32 bytes of data:
PING: transmit failed.
Ping statistics for 74.125.232.209:
Packets: Sent = 1, Received = 0, Lost = 1 (100% loss),
Hey Dimitri,
Can you get a more precise error message when you do
ping -n 1 -l 32 -w 1 -S 192.168.0.77 www.google.com
I am suprised it worked for ping -n 1 -l 32 -w 1 -S 192.168.0.77 192.168.0.238
On OSX, the -S option is pretty strict; following is the description of the option from the man pages
and you get error like:
It's good idea to add the method mentioned above like: request.setSource(sourceIp); - it will help me for my purposes and other developers. I think that adding that feature will very increase the good of your library.
Last edit: Dmitry Ilyushko 2017-03-27
Sorry it's okay https://yadi.sk/i/NlEepAVS3GQBNQ
Dmitry, please try this beta build of 1021:
http://secure.fileprotocol.com/dl?guid=932ECC05-9203-E594-00AD-0F9E23D7B0AE
Make sure that you initialize icmp4j with this:
This tells icmp4j to use the Windows ping.exe to issue the ping, and you will be able to set the source via:
request.setSource (source);
Please test on Windows 8.1 x64, and any other OS you can get your hands on...
Okay, i have dowloaded your attachement and extracted archive. I have linked files icmp4j-all.jar, jna-3.5.1.jar, platform-3.5.1.jar from "\1021rc1\icmp4j-project\trunk\icmp4j\output\tool" and "\1021rc1\icmp4j-project\trunk\icmp4j\output\lib"(for the icmp4j.jar file) directories. to the my Netbeans project and rebuilt the code and try to lauch my code with your recomendations below:
The output is:
~~~
<2017-03-28 12:59:20> <INFO> <JnaUtil> <loadLibrary2 ()="">
<2017-03-28 12:59:20> <INFO> <JnaUtil> < strategy: native via java.library.path>
<2017-03-28 12:59:20> <INFO> <JnaUtil> < libraryName: icmp>
<2017-03-28 12:59:20> <INFO> <JnaUtil> < libraryClass: org.icmp4j.platform.windows.jna.IcmpLibrary>
<2017-03-28 12:59:20> <INFO> <JnaUtil> <loadLibrary2 ()="">
<2017-03-28 12:59:20> <INFO> <JnaUtil> < strategy: native via java.library.path>
<2017-03-28 12:59:20> <INFO> <JnaUtil> < libraryName: ws2_32>
<2017-03-28 12:59:20> <INFO> <JnaUtil> < libraryClass: org.icmp4j.platform.windows.jna.Winsock2Library>
<2017-03-28 12:59:20> <DEBUG> <WindowsProcessUtil> <findWindowsRootDirectory ():="" looking="" up="" env="" var="" SystemRoot:="" C:\\windows="">
command: "C:\windows\system32\ping.exe" -n 1 -l 32 -w 1000 -S 192.168.1.3 www.google.com
Host ip :www.google.com IS NOT RESPONDED from source ip: 192.168.1.3
Error:
~~~
if i try to do the same thing in win console and i have got the positive result(See the picture)
I use the Netbeans 8 IDE, Windows 8.1 x64
Last edit: Dmitry Ilyushko 2017-03-28
Rather than looking for some strings in the result, you should use the response flags
From your screen shot, looks you have a 4 to 9 ms round trip, so you should set time out accordingly, for example 10 ms
laurent buhler,
you right, parsing the output - is bad solution, I'll take your advice, thanks
I tried to run my another custom ping method and everything fine:
// Use this method to ping hosts on Windows or other platforms, withrespond timeout of 3 secs
Output:
It's taken from the error output:
command: "C:\windows\system32\ping.exe" -n 1 -l 32 -w 1000 -S 192.168.1.3 www.google.com
Host ip :www.google.com IS NOT RESPONDED from source ip: 192.168.1.3
And there's a question - how i can get access to the notorious "command" from the code
I don't want to set some parameters for the native ping, for example i don't want to set parameter "-w 1" or "-w 1000" How can i change the sended packet from my code?
Last edit: Dmitry Ilyushko 2017-03-28
Dmitry,
Here are some more changes:
http://secure.fileprotocol.com/dl?guid=0F5C2869-F5EF-4714-16DD-A63AAF4DFCCF
Please test it with something similar to this:
I tested with the ping output that you gave earlier, and the parsing works.
So if this does not work for you, give me the full output of this test.
BTW, I think your test failed because you set a timeout of 1000 msecs, and that may not be enough in your case.
Sal,
I have tested your new update, and it works in my case, even if doing
request.setTimeout (1000);
not:
request.setTimeout (30000);
Thank you very much!
Last edit: Dmitry Ilyushko 2017-03-29